Vereinsmeisterschaften  22aa7800eae54b428d40e835886cefe1fdefdfdf
This is a software that can be used to manage the internal competition of the swimming club Illertissen called "Vereinsmeisterschaften".
Loading...
Searching...
No Matches
CreateDocumentsViewModel.cs
1using CommunityToolkit.Mvvm.ComponentModel;
2using CommunityToolkit.Mvvm.Input;
3using MahApps.Metro.Controls.Dialogs;
4using Microsoft.Win32;
5using System.Collections.ObjectModel;
6using System.ComponentModel;
7using System.IO;
8using System.Reflection;
9using System.Resources;
10using System.Windows.Data;
11using System.Windows.Input;
21
23
27public partial class CreateDocumentsViewModel : ObservableObject, INavigationAware
28{
32 public Dictionary<DocumentCreationTypes, DocumentCreationConfig> DocumentCreationConfigPerType { get; } = new Dictionary<DocumentCreationTypes, DocumentCreationConfig>();
33
37 public Dictionary<DocumentCreationTypes, DocumentCreationStatus> DocumentCreationStatusPerType { get; } = new Dictionary<DocumentCreationTypes, DocumentCreationStatus>();
38
42 public bool IsAnyDocumentCreationRunning => DocumentCreationStatusPerType.Any(kv => kv.Value.IsDocumentCreationRunning == true);
43
44 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
45
46 private void changeDocumentCreationRunningState(DocumentCreationTypes documentType, bool isRunning)
47 => setDictionaryValue(documentType, isRunning, nameof(DocumentCreationStatus.IsDocumentCreationRunning));
48
49 private void changeDocumentCreationSuccessfulState(DocumentCreationTypes documentType, bool isSuccessful)
50 => setDictionaryValue(documentType, isSuccessful, nameof(DocumentCreationStatus.IsDocumentCreationSuccessful));
51
52 private void changeDocumentDataAvailableState(DocumentCreationTypes documentType, bool isDataAvailable)
53 => setDictionaryValue(documentType, isDataAvailable, nameof(DocumentCreationStatus.IsDocumentDataAvailable));
54
55 private void changeDocumentTemplateAvailableState(DocumentCreationTypes documentType, bool isTemplateAvailable)
56 => setDictionaryValue(documentType, isTemplateAvailable, nameof(DocumentCreationStatus.IsDocumentTemplateAvailable));
57
58 private void changeLastDocumentFilePath(DocumentCreationTypes documentType, string lastDocumentFilePath)
59 => setDictionaryValue(documentType, lastDocumentFilePath, nameof(DocumentCreationStatus.LastDocumentFilePath));
60
61 private void setDictionaryValue<T>(DocumentCreationTypes documentType, T value, string propertyName)
62 {
63 if (DocumentCreationStatusPerType.ContainsKey(documentType))
64 {
65 PropertyInfo propInfo = typeof(DocumentCreationStatus).GetProperty(propertyName);
66 propInfo?.SetValue(DocumentCreationStatusPerType[documentType], value);
67 OnPropertyChanged(nameof(DocumentCreationStatusPerType));
68 ((RelayCommand<DocumentCreationTypes>)CreateDocumentCommand).NotifyCanExecuteChanged();
69 }
70 }
71
72 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
73
74 #region Create Certificates Properties
75
76
80 [ObservableProperty]
82
83 // ----------------------------------------------------------------------------------------------------------------------------------------------
84
88 public List<Person> AvailablePersons => _personService?.GetPersons().OrderBy(p => p.Name).ToList();
89
90 // ----------------------------------------------------------------------------------------------------------------------------------------------
91
92 private List<SwimmingStyles> _availableSwimmingStyles = Enum.GetValues(typeof(SwimmingStyles)).Cast<SwimmingStyles>().Where(s => s != SwimmingStyles.Unknown).ToList();
96 public List<SwimmingStyles> AvailableSwimmingStyles => _availableSwimmingStyles;
97
98 #endregion
99
100 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
101
102 #region Create Time Forms Properties
103
107 [ObservableProperty]
108 private int _numberCreatedTimeForms = -1;
109
110 #endregion
111
112 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
113
114 #region Placeholders
115
116 private ObservableCollection<DocumentPlaceholderViewConfig> _placeholderViewConfigs = new ObservableCollection<DocumentPlaceholderViewConfig>();
120 public ObservableCollection<DocumentPlaceholderViewConfig> PlaceholderViewConfigs
121 {
122 get => _placeholderViewConfigs;
123 private set => SetProperty(ref _placeholderViewConfigs, value);
124 }
125
129 public ICollectionView PlaceholderViewConfigsView { get; private set; }
130
135 {
137 foreach(KeyValuePair<string, (string groupName, List<string> placeholders)> placeholderEntry in Placeholders.PlaceholderDict)
138 {
139 string placeholderKey = placeholderEntry.Key;
140 ResourceManager rm = new ResourceManager(typeof(Properties.PlaceholderResources));
141 string resourceStringName = rm.GetString($"PlaceholderName{placeholderKey}") ?? "?";
142 string resourceStringInfo = rm.GetString($"PlaceholderInfo{placeholderKey}") ?? "?";
143 string resourceStringGroup = rm.GetString($"PlaceholderGroup{placeholderEntry.Value.groupName}") ?? "?";
144
145 Dictionary<DocumentCreationTypes, bool> isSupportedForDocumentType = new Dictionary<DocumentCreationTypes, bool>();
146 Dictionary<DocumentCreationTypes, bool> isSupportedForTextPlaceholders = new Dictionary<DocumentCreationTypes, bool>();
147 Dictionary<DocumentCreationTypes, bool> isSupportedForTablePlaceholders = new Dictionary<DocumentCreationTypes, bool>();
148 Dictionary<DocumentCreationTypes, string> postfixNumbersSupportedForDocumentType = new Dictionary<DocumentCreationTypes, string>();
149 foreach (IDocumentStrategy strategy in _documentStrategies)
150 {
151 DocumentCreationTypes documentCreationType = strategy.DocumentType;
152 List<string> supportedPlaceholderKeys = strategy.SupportedPlaceholderKeys;
153 bool isCurrentPlaceholderSupportedForStrategy = supportedPlaceholderKeys.Contains(placeholderKey);
154 bool isCurrentPlaceholderSupportedForText = strategy.SupportTextPlaceholders || strategy.AlwaysSupportedPlaceholderKeys.Contains(placeholderKey);
155 bool isCurrentPlaceholderSupportedForTable = strategy.SupportTablePlaceholders || strategy.AlwaysSupportedPlaceholderKeys.Contains(placeholderKey);
156
157 int indexOfKey = supportedPlaceholderKeys.IndexOf(placeholderKey);
158 int postfixNumbersSupported = (indexOfKey >= 0 && indexOfKey < strategy.PostfixNumbersSupported.Count) ? strategy.PostfixNumbersSupported[indexOfKey] : 0;
159 string postfixNumbersSupportedStr = postfixNumbersSupported > 0 ? postfixNumbersSupported.ToString() : string.Empty;
160
161 if (!isSupportedForDocumentType.ContainsKey(documentCreationType))
162 {
163 isSupportedForDocumentType.Add(documentCreationType, isCurrentPlaceholderSupportedForStrategy);
164 isSupportedForTextPlaceholders.Add(documentCreationType, isCurrentPlaceholderSupportedForText);
165 isSupportedForTablePlaceholders.Add(documentCreationType, isCurrentPlaceholderSupportedForTable);
166 postfixNumbersSupportedForDocumentType.Add(documentCreationType, postfixNumbersSupportedStr);
167 }
168 else
169 {
170 isSupportedForDocumentType[documentCreationType] = isCurrentPlaceholderSupportedForStrategy;
171 isSupportedForTextPlaceholders[documentCreationType] = isCurrentPlaceholderSupportedForText;
172 isSupportedForTablePlaceholders[documentCreationType] = isCurrentPlaceholderSupportedForTable;
173 postfixNumbersSupportedForDocumentType[documentCreationType] = postfixNumbersSupportedStr;
174 }
175 }
176
178 {
179 Group = resourceStringGroup,
180 Key = placeholderKey,
181 Name = resourceStringName,
182 Info = resourceStringInfo,
183 Placeholders = string.Join(Environment.NewLine, placeholderEntry.Value.placeholders.Select(p => $"{_documentService.PlaceholderMarker}{p}{_documentService.PlaceholderMarker}")),
184 IsSupportedForDocumentType = isSupportedForDocumentType,
185 IsSupportedForTextPlaceholders = isSupportedForTextPlaceholders,
186 IsSupportedForTablePlaceholders = isSupportedForTablePlaceholders,
187 PostfixNumbersSupportedForDocumentType = postfixNumbersSupportedForDocumentType
188 };
189 PlaceholderViewConfigs.Add(placeholderViewConfig);
190 }
191 OnPropertyChanged(nameof(PlaceholderViewConfigs));
192 }
193
194 #endregion
195
196 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
197
198 private IDocumentService _documentService;
199 private IPersonService _personService;
200 private IWorkspaceService _workspaceService;
201 private IDialogCoordinator _dialogCoordinator;
202 private ShellViewModel _shellVM;
203 private IEnumerable<IDocumentStrategy> _documentStrategies;
204
214 public CreateDocumentsViewModel(IDocumentService documentService, IPersonService personService, IWorkspaceService workspaceService, IDialogCoordinator dialogCoordinator, ShellViewModel shellVM, IEnumerable<IDocumentStrategy> documentStrategies)
215 {
216 _documentService = documentService;
217 _personService = personService;
218 _workspaceService = workspaceService;
219 _dialogCoordinator = dialogCoordinator;
220 _shellVM = shellVM;
221 _documentStrategies = documentStrategies;
222
223 List<DocumentCreationTypes> availableDocumentCreationTypes = Enum.GetValues(typeof(DocumentCreationTypes)).Cast<DocumentCreationTypes>().ToList();
226 foreach (DocumentCreationTypes type in availableDocumentCreationTypes)
227 {
228 IDocumentStrategy strategy = _documentStrategies.FirstOrDefault(d => d.DocumentType == type);
229
232 {
233 DocumentStrategy = strategy,
234 AvailableItemOrderings = strategy?.AvailableItemOrderings,
235 CurrentItemOrdering = strategy?.ItemOrdering,
236 AvailableItemFilters = strategy?.AvailableItemFilters,
237 CurrentItemFilter = strategy?.ItemFilter,
238 CurrentItemFilterParameter = strategy?.ItemFilterParameter
239 });
240 }
241
242 PlaceholderViewConfigsView = CollectionViewSource.GetDefaultView(PlaceholderViewConfigs);
243 PlaceholderViewConfigsView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(DocumentPlaceholderViewConfig.Group)));
244 }
245
246 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
247
248 private ICommand _createDocumentCommand;
252 public ICommand CreateDocumentCommand => _createDocumentCommand ?? (_createDocumentCommand = new RelayCommand<DocumentCreationTypes>(async (documentType) =>
253 {
254 int numCreatedPages = 0;
255 string returnFilePath = string.Empty;
256
257 // Update the item ordering and filter for all document strategies before creating the document
258 List<DocumentCreationTypes> availableDocumentCreationTypes = Enum.GetValues(typeof(DocumentCreationTypes)).Cast<DocumentCreationTypes>().ToList();
259 foreach (DocumentCreationTypes type in availableDocumentCreationTypes)
260 {
261 IDocumentStrategy strategy = _documentStrategies.FirstOrDefault(s => s.DocumentType == type);
262 if (strategy != null)
263 {
264 strategy.ItemOrdering = DocumentCreationConfigPerType[type].CurrentItemOrdering;
265 strategy.ItemFilter = DocumentCreationConfigPerType[type].CurrentItemFilter;
266 strategy.ItemFilterParameter = DocumentCreationConfigPerType[type].CurrentItemFilterParameter;
267 }
268 }
269
270 changeDocumentCreationRunningState(documentType, true);
271 try
272 {
273 changeDocumentCreationSuccessfulState(documentType, false);
274 switch (documentType)
275 {
276 case DocumentCreationTypes.Certificates:
277 {
278 (numCreatedPages, returnFilePath) = await _documentService.CreateDocument(DocumentCreationTypes.Certificates);
279 NumberCreatedCertificates = numCreatedPages;
280 break;
281 }
282 case DocumentCreationTypes.OverviewList:
283 {
284 (numCreatedPages, returnFilePath) = await _documentService.CreateDocument(DocumentCreationTypes.OverviewList);
285 break;
286 }
287 case DocumentCreationTypes.RaceStartList:
288 {
289 (numCreatedPages, returnFilePath) = await _documentService.CreateDocument(DocumentCreationTypes.RaceStartList);
290 break;
291 }
292 case DocumentCreationTypes.TimeForms:
293 {
294 (numCreatedPages, returnFilePath) = await _documentService.CreateDocument(DocumentCreationTypes.TimeForms);
295 NumberCreatedTimeForms = numCreatedPages;
296 break;
297 }
298 case DocumentCreationTypes.ResultList:
299 {
300 (numCreatedPages, returnFilePath) = await _documentService.CreateDocument(DocumentCreationTypes.ResultList);
301 break;
302 }
303 case DocumentCreationTypes.ResultListDetail:
304 {
305 (numCreatedPages, returnFilePath) = await _documentService.CreateDocument(DocumentCreationTypes.ResultListDetail);
306 break;
307 }
308 case DocumentCreationTypes.Analytics:
309 {
310 (numCreatedPages, returnFilePath) = await _documentService.CreateDocument(DocumentCreationTypes.Analytics);
311 break;
312 }
313 default: throw new ArgumentOutOfRangeException(nameof(documentType), documentType, "Unknown document type for creation command.");
314 }
315 changeLastDocumentFilePath(documentType, returnFilePath);
316 changeDocumentCreationSuccessfulState(documentType, true);
317 }
318 catch (Exception ex)
319 {
320 await _dialogCoordinator.ShowMessageAsync(_shellVM, Resources.ErrorString, ex.Message);
321 }
322 changeDocumentCreationRunningState(documentType, false);
323 }, (documentType) => !IsAnyDocumentCreationRunning));
324
325
327 public void OnNavigatedTo(object parameter)
328 {
329 foreach(IDocumentStrategy strategy in _documentStrategies)
330 {
331 object[] items = strategy.GetItems();
332 bool isDataAvailable = items != null;
333 changeDocumentDataAvailableState(strategy.DocumentType, isDataAvailable);
334
335 bool isTemplateAvailable = !string.IsNullOrEmpty(strategy.TemplatePath) &&
336 File.Exists(strategy.TemplatePath) &&
337 Path.GetExtension(strategy.TemplatePath) == ".docx";
338 changeDocumentTemplateAvailableState(strategy.DocumentType, isTemplateAvailable);
339
340 if (!isDataAvailable || !isTemplateAvailable)
341 {
342 changeDocumentCreationRunningState(strategy.DocumentType, false);
343 changeDocumentCreationSuccessfulState(strategy.DocumentType, false);
344 }
345
346 // Find existing documents
347 string templateFileNamePostfix = _workspaceService?.Settings?.GetSettingValue<string>(WorkspaceSettings.GROUP_DOCUMENT_CREATION, WorkspaceSettings.SETTING_DOCUMENT_CREATION_TEMPLATE_FILENAME_POSTFIX) ?? string.Empty;
348 string documentOutputFolder = _workspaceService?.Settings?.GetSettingValue<string>(WorkspaceSettings.GROUP_DOCUMENT_CREATION, WorkspaceSettings.SETTING_DOCUMENT_CREATION_OUTPUT_FOLDER) ?? string.Empty;
349 documentOutputFolder = FilePathHelper.MakePathAbsolute(documentOutputFolder, _workspaceService?.PersistentPath);
350
351 string outputFileNameDocx = Path.GetFileNameWithoutExtension(strategy.TemplatePath);
352 outputFileNameDocx = outputFileNameDocx.Replace(templateFileNamePostfix, "") + ".docx";
353 string outputFilePathDocx = Path.Combine(documentOutputFolder, outputFileNameDocx);
354 string outputFilePathPdf = outputFilePathDocx.Replace(".docx", ".pdf", StringComparison.InvariantCultureIgnoreCase);
355 if(File.Exists(outputFilePathPdf))
356 {
357 changeLastDocumentFilePath(strategy.DocumentType, outputFilePathPdf);
358 changeDocumentCreationSuccessfulState(strategy.DocumentType, true); // necessary to show the path
359 }
360 else if(File.Exists(outputFilePathDocx))
361 {
362 changeLastDocumentFilePath(strategy.DocumentType, outputFilePathDocx);
363 changeDocumentCreationSuccessfulState(strategy.DocumentType, true); // necessary to show the path
364 }
365 }
366
368 }
369
371 public void OnNavigatedFrom()
372 {
373 }
374}
Class combining configuration infos used while document creation.
Class combining informations used while document creation.
Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
static string ErrorString
Sucht eine lokalisierte Zeichenfolge, die Error ähnelt.
int _numberCreatedTimeForms
Number of created time forms during the last creation process.
void OnNavigatedTo(object parameter)
OnNavigatedTo method to handle navigation to this object.
Dictionary< DocumentCreationTypes, DocumentCreationConfig > DocumentCreationConfigPerType
Dictionary to hold the for each type.
ICollectionView PlaceholderViewConfigsView
Collection view used to display the PlaceholderViewConfigs
ObservableCollection< DocumentPlaceholderViewConfig > PlaceholderViewConfigs
Collection of DocumentPlaceholderViewConfig objects that define the available placeholders for docume...
List< Person > AvailablePersons
List with all available Person objects.
List< SwimmingStyles > AvailableSwimmingStyles
List with all available SwimmingStyles
bool IsAnyDocumentCreationRunning
Indicates whether at leas one document creation process is currently running.
void OnNavigatedFrom()
OnNavigatedFrom method to handle navigation away from this object.
void initPlaceholderViewConfigs()
Initializes the PlaceholderViewConfigs collection with available placeholders.
int _numberCreatedCertificates
Number of created certificates during the last creation process.
Dictionary< DocumentCreationTypes, DocumentCreationStatus > DocumentCreationStatusPerType
Dictionary to hold the for each type.
CreateDocumentsViewModel(IDocumentService documentService, IPersonService personService, IWorkspaceService workspaceService, IDialogCoordinator dialogCoordinator, ShellViewModel shellVM, IEnumerable< IDocumentStrategy > documentStrategies)
Constructor for the CreateDocumentsViewModel class.
Configuration for document placeholders used in the UI.
ViewModel for the main shell of the application.
Interface for objects that need to handle navigation events.
Interface for a service used to create documents like certificates or start lists.
Interface for a service used to get and store a list of Person objects.
Interface for a service used to manage a workspace.
Interface for document strategies that define how to create and collect data for different types of d...
IEnumerable< Enum > AvailableItemOrderings
Array with all available orderings for the items.
IEnumerable< Enum > AvailableItemFilters
Array with all available filters for the items.
List< string > SupportedPlaceholderKeys
List of placeholder keys that are supported by this strategy.
object ItemFilterParameter
Filter parameter that can be used together with ItemFiltering.
DocumentCreationTypes DocumentType
Gets the type of document this strategy creates.
object[] GetItems()
Retrieves the items that will be used to create the document.
List< string > AlwaysSupportedPlaceholderKeys
List with placeholder keys that are always supported, no matter what the IDocumentPlaceholderResolver...
List< int > PostfixNumbersSupported
Number of postfix numbers that are supported for the placeholders.
string TemplatePath
Gets the path to the template used for creating the document.
SwimmingStyles
Available swimming styles.
DocumentCreationTypes
Different types of documents that can be created.