77import java .util .Arrays ;
88import java .util .Comparator ;
99import java .util .HashMap ;
10+ import java .util .HashSet ;
1011import java .util .List ;
1112import java .util .Map ;
1213import java .util .Objects ;
5859import org .eclipse .swt .graphics .Image ;
5960import org .eclipse .swt .layout .GridData ;
6061import org .eclipse .swt .layout .GridLayout ;
62+ import org .eclipse .swt .layout .RowLayout ;
6163import org .eclipse .swt .widgets .Button ;
6264import org .eclipse .swt .widgets .Composite ;
6365import org .eclipse .swt .widgets .Display ;
@@ -194,14 +196,15 @@ public enum MediorderActiveView {
194196
195197 public Map <IStock , Integer > imageStockStates = new HashMap <IStock , Integer >();
196198 private List <IStock > filteredStocks = new ArrayList <>();
197- private List <Integer > currentFilterValue ;
199+ private List <Integer > currentFilterValue = List . of () ;
198200 private boolean filterActive = false ;
199201 private boolean isDetailsViewActive = true ;
200202
201203 private Preferences preferences = InstanceScope .INSTANCE .getNode ("ch.elexis.core.ui.mediorder" );
202204
203205 private IPatient importedPatient , selectedImportedPatient ;
204- private Button btnUseSelected , btnSelectNewPatient , btnNewPatient , btnError ;
206+ private Button btnUseSelected , btnSelectNewPatient , btnNewPatient , btnError , btnOpen , btnReady , btnFinished ;
207+ private final List <Button > filterButtons = new ArrayList <>();
205208 private Label txtImportName , txtImportFirstName , txtImportDob , txtImportSex , txtImportStreet , txtImportPostalCode ,
206209 txtImportCity , txtImportEmail , txtImportMobile ;
207210 private Label txtExistingName , txtExistingFirstName , txtExistingDob , txtExistingSex , txtExistingStreet ,
@@ -217,6 +220,17 @@ public enum MediorderActiveView {
217220 private static final String LAST_ACTIVE_TABLEVIEWER = "lastActiveView" ;
218221 private static final String ONLY_NUMBER_REGEX = "\\ d*" ;
219222
223+ private static final String FILTER_STATES_KEY = "mediorder.filterStates" ; //$NON-NLS-1$
224+
225+ private static final List <Integer > FILTER_OPEN = List .of (2 , 3 );
226+ private static final List <Integer > FILTER_READY = List .of (1 );
227+ private static final List <Integer > FILTER_FINISHED = List .of (4 );
228+
229+ private static final String LABEL_FILTER_OPEN = "Offen" ;
230+ private static final String LABEL_FILTER_READY = "Bereit" ;
231+ private static final String LABEL_FILTER_FINISHED = "Abgeschlossen" ;
232+ private static final String LABEL_FILTER_ERROR = "Fehlerhaft (%d)" ;
233+
220234 public static class PatientImportData {
221235 public IPatient patient ;
222236 public String street ;
@@ -284,18 +298,46 @@ public void reload(@UIEventTopic(ElexisEventTopics.EVENT_RELOAD) Class<?> clazz)
284298
285299 @ Override
286300 public void refresh (Map <Object , Object > filterParameters ) {
301+ refreshStockTable ();
302+
303+ getImportedPatients ();
304+ refreshImportedPatientsTable ();
305+ }
306+
307+ private void refreshStockTable () {
287308 Object firstElement = tableViewer .getStructuredSelection ().getFirstElement ();
288- List <IStock > stocks = filterActive ? MediorderPartUtil .calculateFilteredStocks (currentFilterValue )
309+ List <IStock > stocks = isStockFilterApplied () ? MediorderPartUtil .calculateFilteredStocks (currentFilterValue )
289310 : getStocksExcludingAwaitingRequests ();
290- stocks .forEach (stock -> MediorderPartUtil .updateStockImageState (imageStockStates , ( IStock ) stock ));
311+ stocks .forEach (stock -> MediorderPartUtil .updateStockImageState (imageStockStates , stock ));
291312 tableViewer .setInput (stocks );
292313 if (tableViewer .contains (firstElement )) {
293314 tableViewer .setSelection (new StructuredSelection (firstElement ));
294315 }
295316 tableViewer .refresh (true );
317+ }
296318
297- getImportedPatients ();
298- refreshImportedPatientsTable ();
319+ private boolean isStockFilterApplied () {
320+ return filterActive && currentFilterValue != null && !currentFilterValue .isEmpty ();
321+ }
322+
323+ private void showImportErrorView (boolean show ) {
324+ btnError .setSelection (show );
325+ if (show ) {
326+ filterButtons .forEach (button -> button .setSelection (false ));
327+ updateFilter (List .of (), false );
328+
329+ topStackLayout .topControl = cPatientError_table ;
330+ getImportedPatients ();
331+ refreshImportedPatientsTable ();
332+ mainSashForm .setWeights (new int [] { 100 , 0 });
333+ viewComposite .setVisible (false );
334+ } else {
335+ topStackLayout .topControl = cPatientList ;
336+ viewComposite .setVisible (true );
337+ mainSashForm .setWeights (new int [] { 50 , 50 });
338+ refreshStockTable ();
339+ }
340+ topViewComposite .layout ();
299341 }
300342
301343 @ PostConstruct
@@ -307,34 +349,24 @@ public void postConstruct(Composite parent, EMenuService menuService, IExtension
307349 medicationHistoryComparator = new MedicationHistoryComparator ();
308350
309351 Composite filterComposite = new Composite (parent , SWT .NONE );
310- filterComposite .setLayout (new GridLayout ( 4 , false ));
352+ filterComposite .setLayout (new RowLayout ( SWT . HORIZONTAL ));
311353 filterComposite .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false ));
312354
313355 getImportedPatients ();
314356
315357 btnError = new Button (filterComposite , SWT .TOGGLE );
316- btnError .setLayoutData (new GridData (SWT .LEFT , SWT .CENTER , false , false ));
317358 updateErrorButtonText ();
318- btnError .setText ("Fehlerhaft (" + (importedPatients != null ? importedPatients .size () : 0 ) + ")" );
319359 btnError .addSelectionListener (new SelectionAdapter () {
320360 @ Override
321361 public void widgetSelected (SelectionEvent e ) {
322- if (btnError .getSelection ()) {
323- topStackLayout .topControl = cPatientError_table ;
324- getImportedPatients ();
325- tableViewerImportedPatients .setInput (importedPatients );
326- tableViewerImportedPatients .refresh ();
327- mainSashForm .setWeights (new int [] { 100 , 0 });
328- viewComposite .setVisible (false );
329- } else {
330- topStackLayout .topControl = cPatientList ;
331- viewComposite .setVisible (true );
332- mainSashForm .setWeights (new int [] { 50 , 50 });
333- }
334- topViewComposite .layout ();
362+ showImportErrorView (btnError .getSelection ());
335363 }
336364 });
337365
366+ btnOpen = createFilterButton (filterComposite , LABEL_FILTER_OPEN , FILTER_OPEN );
367+ btnReady = createFilterButton (filterComposite , LABEL_FILTER_READY , FILTER_READY );
368+ btnFinished = createFilterButton (filterComposite , LABEL_FILTER_FINISHED , FILTER_FINISHED );
369+
338370 mainSashForm = new SashForm (parent , SWT .VERTICAL );
339371 mainSashForm .setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
340372 mainSashForm .setSashWidth (5 );
@@ -372,12 +404,27 @@ public void widgetSelected(SelectionEvent e) {
372404 selectedDetailStock .addChangeListener (ev -> selectionService .setSelection (selectedDetailStock .getValue ()));
373405 }
374406
407+ private Button createFilterButton (Composite parent , String text , List <Integer > states ) {
408+ Button button = new Button (parent , SWT .TOGGLE );
409+ button .setText (text );
410+ button .setData (FILTER_STATES_KEY , states );
411+ button .addSelectionListener (new SelectionAdapter () {
412+ @ Override
413+ public void widgetSelected (SelectionEvent e ) {
414+ applyStockFilter (button , states );
415+ }
416+ });
417+ filterButtons .add (button );
418+ return button ;
419+ }
420+
375421 public MediorderActiveView toggleViews (MediorderActiveView view ) {
376422 mediorderActiveView = (mediorderActiveView == view ) ? MediorderActiveView .DETAILS : view ;
377423 stackLayout .topControl = switch (mediorderActiveView ) {
378424 case DETAILS -> cDetails_table ;
379425 case HISTORY -> cHistory_table ;
380426 };
427+ isDetailsViewActive = mediorderActiveView == MediorderActiveView .DETAILS ;
381428 viewComposite .layout ();
382429 saveFilterStatus ();
383430 return mediorderActiveView ;
@@ -669,8 +716,8 @@ private void createPatientErrorViewer(Composite parent) {
669716 TableViewerColumn tvcImpDateOfBirth = new TableViewerColumn (tableViewerImportedPatients , SWT .NONE );
670717 tvcImpDateOfBirth .getColumn ().setText (Messages .Core_Enter_Birthdate );
671718 tcLayoutImport .setColumnData (tvcImpDateOfBirth .getColumn (), new ColumnWeightData (40 , 80 , true ));
672- tvcImpDateOfBirth .setLabelProvider (ColumnLabelProvider . createTextProvider (
673- e -> ((IPatient ) e ).getDateOfBirth ().format (DateTimeFormatter . ofPattern ( "dd.MM.yyyy" ) )));
719+ tvcImpDateOfBirth .setLabelProvider (
720+ ColumnLabelProvider . createTextProvider ( e -> ((IPatient ) e ).getDateOfBirth ().format (dateFormatter )));
674721
675722 TableViewerColumn tvcImpSex = new TableViewerColumn (tableViewerImportedPatients , SWT .NONE );
676723 tvcImpSex .getColumn ().setText ("Geschlecht" );
@@ -793,7 +840,7 @@ private void createPatientErrorViewer(Composite parent) {
793840 txtImportName = createDetailField (colImport , Messages .Core_Name ,
794841 selectedImportedPatient != null ? selectedImportedPatient .getLastName () : "" );
795842 txtImportFirstName = createDetailField (colImport , Messages .Core_Firstname ,
796- selectedImportedPatient != null ? selectedImportedPatient .getLastName () : "" );
843+ selectedImportedPatient != null ? selectedImportedPatient .getFirstName () : "" );
797844 txtImportDob = createDetailField (colImport , Messages .Core_Enter_Birthdate , "" );
798845 txtImportSex = createDetailField (colImport , "Geschlecht" , "" );
799846 txtImportStreet = createDetailField (colImport , Messages .AddressSearchView_Street , "" );
@@ -812,8 +859,6 @@ private void createPatientErrorViewer(Composite parent) {
812859 txtExistingPostalEmail = createDetailField (colExisting , Messages .KontaktErfassenDialog_email , "" );
813860 txtExistingPostalMobile = createDetailField (colExisting , Messages .Core_Phone , "" );
814861
815- // sashForm.setWeights(new int[] { 25, 25, 49 });
816-
817862 Composite actionBar = new Composite (detailComposite , SWT .BORDER );
818863 actionBar .setLayoutData (new GridData (SWT .FILL , SWT .BOTTOM , true , false ));
819864 actionBar .setLayout (new GridLayout (4 , false ));
@@ -1101,7 +1146,8 @@ private void clearComparisonFields() {
11011146
11021147 private void updateErrorButtonText () {
11031148 if (btnError != null ) {
1104- btnError .setText ("Fehlerhaft (" + (importedPatients != null ? importedPatients .size () : 0 ) + ")" );
1149+ btnError .setText (String .format (LABEL_FILTER_ERROR , importedPatients != null ? importedPatients .size () : 0 ));
1150+ btnError .requestLayout ();
11051151 }
11061152 }
11071153
@@ -1798,12 +1844,11 @@ private void setCompositeTitle(Composite composite, String title) {
17981844 }
17991845
18001846 public void saveFilterStatus () {
1801- String filterValue = (currentFilterValue == null || currentFilterValue .isEmpty ()) ? ""
1847+ String filterValue = (currentFilterValue == null || currentFilterValue .isEmpty ()) ? StringUtils . EMPTY
18021848 : currentFilterValue .stream ().map (String ::valueOf ).collect (Collectors .joining ("," ));
1803- boolean isFilterActive = filterValue .isEmpty () ? false : filterActive ;
18041849
18051850 preferences .put (CURRENT_FILTER_VALUE , filterValue );
1806- preferences .putBoolean (IS_FILTER_ACTIVE , isFilterActive );
1851+ preferences .putBoolean (IS_FILTER_ACTIVE , isStockFilterApplied () );
18071852 preferences .putBoolean (LAST_ACTIVE_TABLEVIEWER , isDetailsViewActive );
18081853
18091854 try {
@@ -1813,23 +1858,62 @@ public void saveFilterStatus() {
18131858 }
18141859 }
18151860
1861+ private void updateFilter (List <Integer > values , boolean active ) {
1862+ this .currentFilterValue = (values != null ) ? values : List .of ();
1863+ this .filterActive = active && !this .currentFilterValue .isEmpty ();
1864+ saveFilterStatus ();
1865+ }
1866+
1867+ @ SuppressWarnings ("unchecked" )
1868+ private void restoreFilterButtonSelection () {
1869+ filterButtons .forEach (button -> {
1870+ List <Integer > states = (List <Integer >) button .getData (FILTER_STATES_KEY );
1871+ button .setSelection (isStockFilterApplied () && containsSameStates (states , currentFilterValue ));
1872+ });
1873+ }
1874+
1875+ private static boolean containsSameStates (List <Integer > states , List <Integer > other ) {
1876+ if (states == null || other == null ) {
1877+ return false ;
1878+ }
1879+ return new HashSet <>(states ).equals (new HashSet <>(other ));
1880+ }
1881+
18161882 public void applySavedFilter () {
1817- filterActive = preferences .getBoolean (IS_FILTER_ACTIVE , false );
1883+ boolean savedFilterActive = preferences .getBoolean (IS_FILTER_ACTIVE , false );
1884+ String filterValue = preferences .get (CURRENT_FILTER_VALUE , StringUtils .EMPTY );
18181885
1819- String filterValue = preferences .get (CURRENT_FILTER_VALUE , "" );
1820- if (!filterValue .isEmpty () && filterActive ) {
1886+ if (savedFilterActive && !filterValue .isEmpty ()) {
18211887 currentFilterValue = Arrays .stream (filterValue .split ("," )).map (Integer ::parseInt )
18221888 .collect (Collectors .toList ());
1889+ filterActive = true ;
1890+ } else {
1891+ currentFilterValue = List .of ();
1892+ filterActive = false ;
18231893 }
18241894
1825- stackLayout .topControl = preferences .getBoolean (LAST_ACTIVE_TABLEVIEWER , true ) ? cDetails_table
1826- : cHistory_table ;
1895+ restoreFilterButtonSelection ();
1896+
1897+ isDetailsViewActive = preferences .getBoolean (LAST_ACTIVE_TABLEVIEWER , true );
1898+ mediorderActiveView = isDetailsViewActive ? MediorderActiveView .DETAILS : MediorderActiveView .HISTORY ;
1899+ stackLayout .topControl = isDetailsViewActive ? cDetails_table : cHistory_table ;
18271900 viewComposite .layout ();
18281901 }
18291902
1903+ private void applyStockFilter (Button source , List <Integer > states ) {
1904+ filterButtons .stream ().filter (button -> button != source ).forEach (button -> button .setSelection (false ));
1905+
1906+ if (btnError .getSelection ()) {
1907+ showImportErrorView (false );
1908+ }
1909+
1910+ boolean selected = source .getSelection ();
1911+ updateFilter (selected ? states : List .of (), selected );
1912+ refreshStockTable ();
1913+ }
1914+
18301915 public void setFilterActive (boolean active ) {
1831- this .filterActive = active ;
1832- saveFilterStatus ();
1916+ updateFilter (currentFilterValue , active );
18331917 }
18341918
18351919 public boolean isFilterActive () {
@@ -1845,8 +1929,7 @@ public List<IStock> getFilteredStocks() {
18451929 }
18461930
18471931 public void setCurrentFilterValue (List <Integer > value ) {
1848- this .currentFilterValue = value ;
1849- saveFilterStatus ();
1932+ updateFilter (value , filterActive );
18501933 }
18511934
18521935 public List <Integer > getCurrentFilterValue () {
0 commit comments