/*
* OffenePflege
* Copyright (C) 2006-2012 Torsten Löhr
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License V2 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if not, write to
* the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
* www.offene-pflege.de
* ------------------------
* Auf deutsch (freie Übersetzung. Rechtlich gilt die englische Version)
* Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License,
* wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, gemäß Version 2 der Lizenz.
*
* Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein wird, aber
* OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN
* BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.
*
* Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht,
* schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
*
*/
package op.care.med.inventory;
import com.jidesoft.pane.CollapsiblePane;
import com.jidesoft.pane.CollapsiblePanes;
import com.jidesoft.pane.event.CollapsiblePaneAdapter;
import com.jidesoft.pane.event.CollapsiblePaneEvent;
import com.jidesoft.popup.JidePopup;
import com.jidesoft.swing.JideBoxLayout;
import com.jidesoft.swing.JideButton;
import entity.EntityTools;
import entity.info.Resident;
import entity.prescription.*;
import entity.system.SYSPropsTools;
import gui.GUITools;
import gui.interfaces.DefaultCPTitle;
import op.OPDE;
import op.care.med.structure.DlgTradeForm;
import op.care.med.structure.DlgUPREditor;
import op.system.InternalClassACL;
import op.system.LogicalPrinter;
import op.system.PrinterForm;
import op.system.Validator;
import op.threads.DisplayManager;
import op.threads.DisplayMessage;
import op.tools.*;
import org.apache.commons.collections.Closure;
import org.jdesktop.swingx.JXSearchField;
import org.jdesktop.swingx.VerticalLayout;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.OptimisticLockException;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyVetoException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.*;
import java.util.List;
/**
* In OPDE gibt es eine Bestandsverwaltung für Medikamente. Bestände werden mit Hilfe von 3 Tabellen
* in der Datenbank verwaltet.
* <ul>
* <li><B>MPVorrat</B> Ein Vorrat ist wie eine Schachtel oder Schublade zu sehen, in denen
* einzelne Päckchen enthalten sind. Jetzt kann es natürlich passieren, dass verschiedene
* Präparete, die aber pharmazeutisch gleichwertig sind in derselben Schachtel enthalten
* sind. Wenn z.B. 3 verschiedene Medikamente mit demselben Wirkstoff, derselben Darreichungsform
* und in derselben Stärke vorhanden sind, dann sollten sie auch in demselben Vorrat zusammengefasst
* werden. Vorräte gehören immer einem bestimmten Bewohner.</li>
* <li><B>MPBestand</B> Ein Bestand entspricht i.d.R. einer Verpackung. Also eine Schachtel eines
* Medikamentes wäre für sich genommen ein Bestand. Aber auch z.B. wenn ein BW von zu Hause einen
* angebrochenen Blister mitbringt, dann wird dies als eigener Bestand angesehen. Bestände gehören
* immer zu einem bestimmten Vorrat. Das Eingangs-, Ausgangs und Anbruchdatum wird vermerkt. Es meistens
* einen Verweis auf eine MPID aus der Tabelle MPackung. Bei eigenen Gebinden kann dieses Feld auch
* <CODE>null</CODE> sein.</li>
* <li><B>MPBuchung</B> Eine Buchung ist ein Ein- bzw. Ausgang von einer Menge von Einzeldosen zu oder von
* einem bestimmten Bestand. Also wenn eine Packung eingebucht wird, dann wird ein Bestand erstellt und
* eine Eingangsbuchung in Höhe der Ursprünglichen Packungsgrößen (z.B. 100 Stück). Bei Vergabe von
* Medikamenten an einen Bewohner (über Abhaken in der BHP) werden die jeweiligen Mengen
* ausgebucht. In diesem Fall steht in der Spalte BHPID der Verweis zur entsprechenden Zeile in der
* Tabelle BHP.</li>
* </ul>
*
* @author tloehr
*/
public class PnlInventory extends NursingRecordsPanel {
private Resident resident;
private java.util.List<MedInventory> lstInventories;
private Map<String, CollapsiblePane> cpMap;
private Map<String, JToggleButton> mapKey2ClosedToggleButton;
private Map<String, CollapsiblePaneAdapter> cpListener;
// private Map<MedStockTransaction, JPanel> linemap;
private JScrollPane jspSearch;
private CollapsiblePanes searchPanes;
private JToggleButton tbClosedInventory; // <= only for search function
private Color[] color1, color2;
/**
* Creates new form DlgVorrat
*/
public PnlInventory(Resident resident, JScrollPane jspSearch) {
super("nursingrecords.inventory");
this.jspSearch = jspSearch;
initComponents();
initPanel();
switchResident(resident);
}
private void initPanel() {
cpMap = Collections.synchronizedMap(new HashMap<String, CollapsiblePane>());
cpListener = Collections.synchronizedMap(new HashMap<String, CollapsiblePaneAdapter>());
lstInventories = Collections.synchronizedList(new ArrayList<MedInventory>());
mapKey2ClosedToggleButton = Collections.synchronizedMap(new HashMap<String, JToggleButton>());
color1 = SYSConst.yellow1;
color2 = SYSConst.greyscale;
// linemap = Collections.synchronizedMap(new HashMap<MedStockTransaction, JPanel>());
prepareSearchArea();
}
@Override
public void switchResident(Resident resident) {
switchResident(resident, null, null);
}
private void switchResident(Resident res, MedInventory inventory, Closure afterwards) {
this.resident = EntityTools.find(Resident.class, res.getRID());
GUITools.setResidentDisplay(resident);
// only for the zebra coloring. can you believe that ?
reloadDisplay(inventory, afterwards);
}
@Override
public void cleanup() {
super.cleanup();
cpsInventory.removeAll();
synchronized (cpMap) {
SYSTools.clear(cpMap);
}
synchronized (lstInventories) {
SYSTools.clear(lstInventories);
}
synchronized (mapKey2ClosedToggleButton) {
SYSTools.clear(mapKey2ClosedToggleButton);
}
synchronized (cpListener) {
SYSTools.clear(cpListener);
}
}
@Override
public String getInternalClassID() {
return internalClassID;
}
private void prepareSearchArea() {
searchPanes = new CollapsiblePanes();
searchPanes.setLayout(new JideBoxLayout(searchPanes, JideBoxLayout.Y_AXIS));
jspSearch.setViewportView(searchPanes);
JPanel mypanel = new JPanel();
mypanel.setLayout(new VerticalLayout(3));
mypanel.setBackground(Color.WHITE);
CollapsiblePane searchPane = new CollapsiblePane(SYSTools.xx("nursingrecords.inventory"));
searchPane.setStyle(CollapsiblePane.PLAIN_STYLE);
searchPane.setCollapsible(false);
try {
searchPane.setCollapsed(false);
} catch (PropertyVetoException e) {
OPDE.error(e);
}
GUITools.addAllComponents(mypanel, addCommands());
GUITools.addAllComponents(mypanel, addFilters());
GUITools.addAllComponents(mypanel, addKey());
searchPane.setContentPane(mypanel);
searchPanes.add(searchPane);
searchPanes.addExpansion();
}
private java.util.List<Component> addFilters() {
java.util.List<Component> list = new ArrayList<Component>();
JXSearchField search = new JXSearchField(SYSTools.xx("nursingrecords.inventory.search.stockid"));
search.setFont(new Font("Arial", Font.PLAIN, 14));
search.setFocusBehavior(org.jdesktop.swingx.prompt.PromptSupport.FocusBehavior.HIGHLIGHT_PROMPT);
search.addActionListener(e -> txtSucheActionPerformed(e));
search.setInstantSearchDelay(5000);
list.add(search);
tbClosedInventory = GUITools.getNiceToggleButton(SYSTools.xx("nursingrecords.inventory.showclosedinventories"));
tbClosedInventory.addItemListener(e -> {
// synchronized (lstInventories) {
// lstInventories = tbClosedInventory.isSelected() ? MedInventoryTools.getAll(resident) : MedInventoryTools.getAll(resident);
// }
reload();
});
list.add(tbClosedInventory);
return list;
}
private java.util.List<Component> addKey() {
java.util.List<Component> list = new ArrayList<Component>();
list.add(new JSeparator());
list.add(new JLabel(SYSTools.xx("misc.msg.key")));
list.add(new JLabel(SYSTools.xx("nursingrecords.inventory.keydescription1"), SYSConst.icon22ledGreenOn, SwingConstants.LEADING));
list.add(new JLabel(SYSTools.xx("nursingrecords.inventory.keydescription2"), SYSConst.icon22ledYellowOn, SwingConstants.LEADING));
list.add(new JLabel(SYSTools.xx("nursingrecords.inventory.keydescription3"), SYSConst.icon22ledRedOn, SwingConstants.LEADING));
return list;
}
private java.util.List<Component> addCommands() {
java.util.List<Component> list = new ArrayList<Component>();
if (OPDE.getAppInfo().isAllowedTo(InternalClassACL.INSERT, "nursingrecords.inventory")) {
JideButton buchenButton = GUITools.createHyperlinkButton("nursingrecords.inventory.newstocks", SYSConst.icon22addrow, actionEvent -> {
if (!resident.isActive()) {
OPDE.getDisplayManager().addSubMessage(new DisplayMessage("misc.msg.cantChangeInactiveResident"));
return;
}
if (!resident.isCalcMediUPR1()) {
OPDE.getDisplayManager().addSubMessage(new DisplayMessage("misc.msg.inactiveCalcMed"));
return;
}
currentEditor = new DlgNewStocks(resident);
currentEditor.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
currentEditor = null;
}
});
currentEditor.setVisible(true);
reload();
});
list.add(buchenButton);
}
return list;
}
@Override
public void reload() {
reloadDisplay(null, null);
}
private void reloadDisplay(final MedInventory singleInventory, final Closure afterwards) {
/***
* _ _ ____ _ _
* _ __ ___| | ___ __ _ __| | _ \(_)___ _ __ | | __ _ _ _
* | '__/ _ \ |/ _ \ / _` |/ _` | | | | / __| '_ \| |/ _` | | | |
* | | | __/ | (_) | (_| | (_| | |_| | \__ \ |_) | | (_| | |_| |
* |_| \___|_|\___/ \__,_|\__,_|____/|_|___/ .__/|_|\__,_|\__, |
* |_| |___/
*/
// final boolean withworker = true;
cpsInventory.removeAll();
synchronized (cpMap) {
SYSTools.clear(cpMap);
}
// synchronized (linemap) {
// linemap.clear();
// }
synchronized (mapKey2ClosedToggleButton) {
mapKey2ClosedToggleButton.clear();
}
synchronized (lstInventories) {
lstInventories.clear();
if (singleInventory != null) {
lstInventories.add(singleInventory);
} else {
lstInventories = tbClosedInventory.isSelected() ? MedInventoryTools.getAll(resident) : MedInventoryTools.getAllActive(resident);
}
}
OPDE.getMainframe().setBlocked(true);
OPDE.getDisplayManager().setProgressBarMessage(new DisplayMessage(SYSTools.xx("misc.msg.wait"), -1, 100));
SwingWorker worker = new SwingWorker() {
@Override
protected Object doInBackground() throws Exception {
int progress = 0;
synchronized (lstInventories) {
OPDE.getDisplayManager().setProgressBarMessage(new DisplayMessage(SYSTools.xx("misc.msg.wait"), progress, lstInventories.size()));
for (MedInventory inventory : lstInventories) {
progress++;
createCP4(inventory);
OPDE.getDisplayManager().setProgressBarMessage(new DisplayMessage(SYSTools.xx("misc.msg.wait"), progress, lstInventories.size()));
}
}
return null;
}
@Override
protected void done() {
buildPanel(singleInventory == null);
if (afterwards != null) {
afterwards.execute(null);
}
OPDE.getDisplayManager().setProgressBarMessage(null);
OPDE.getMainframe().setBlocked(false);
}
};
worker.execute();
}
private Color getColor(int level, boolean odd) {
if (odd) {
return color1[level];
} else {
return color2[level];
}
}
private CollapsiblePane createCP4(final MedInventory inventory) {
/***
* _ ____ ____ _ _ _____ _ __
* ___ _ __ ___ __ _| |_ ___ / ___| _ \| || | / /_ _|_ ____ _____ _ __ | |_ ___ _ __ _ \ \
* / __| '__/ _ \/ _` | __/ _ \ | | |_) | || |_| | | || '_ \ \ / / _ \ '_ \| __/ _ \| '__| | | | |
* | (__| | | __/ (_| | || __/ |___| __/|__ _| | | || | | \ V / __/ | | | || (_) | | | |_| | |
* \___|_| \___|\__,_|\__\___|\____|_| |_| | ||___|_| |_|\_/ \___|_| |_|\__\___/|_| \__, | |
* \_\ |___/_/
*/
final String key = inventory.getID() + ".xinventory";
synchronized (cpMap) {
if (!cpMap.containsKey(key)) {
cpMap.put(key, new CollapsiblePane());
try {
cpMap.get(key).setCollapsed(true);
} catch (PropertyVetoException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
cpMap.get(key).setName("inventory");
// final CollapsiblePane cpInventory = cpMap.get(key);
BigDecimal sumInventory = BigDecimal.ZERO;
try {
EntityManager em = OPDE.createEM();
sumInventory = MedInventoryTools.getSum(em, inventory);
em.close();
} catch (Exception e) {
OPDE.fatal(e);
}
String title = "<html><table border=\"0\">" +
"<tr>" +
"<td width=\"520\" align=\"left\"><font size=+1>" +
inventory.getText() + "</font></td>" +
"<td width=\"200\" align=\"right\"><font size=+1>" + SYSTools.formatBigDecimal(sumInventory) + " " + DosageFormTools.getPackageText(MedInventoryTools.getForm(inventory)) + "</font></td>" +
"</tr>" +
"</table>" +
"</html>";
DefaultCPTitle cptitle = new DefaultCPTitle(title, e -> {
try {
cpMap.get(key).setCollapsed(!cpMap.get(key).isCollapsed());
} catch (PropertyVetoException pve) {
// BAH!
}
});
cpMap.get(key).setTitleLabelComponent(cptitle.getMain());
cpMap.get(key).setSlidingDirection(SwingConstants.SOUTH);
cptitle.getButton().setIcon(inventory.isClosed() ? SYSConst.icon22stopSign : null);
// https://github.com/tloehr/Offene-Pflege.de/issues/42
if (OPDE.getAppInfo().isAllowedTo(InternalClassACL.MANAGER, "nursingrecords.inventory")) {
/***
* _____ _ _ _ _ _
* | ____|__| (_) |_ | \ | | __ _ _ __ ___ ___
* | _| / _` | | __| | \| |/ _` | '_ ` _ \ / _ \
* | |__| (_| | | |_ | |\ | (_| | | | | | | __/
* |_____\__,_|_|\__| |_| \_|\__,_|_| |_| |_|\___|
*
*/
final JButton btnEditInvName = new JButton(SYSConst.icon22edit3);
btnEditInvName.setPressedIcon(SYSConst.icon22edit3);
btnEditInvName.setAlignmentX(Component.RIGHT_ALIGNMENT);
btnEditInvName.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
btnEditInvName.setContentAreaFilled(false);
btnEditInvName.setBorder(null);
btnEditInvName.setToolTipText(SYSTools.xx("nursingrecords.inventory.btnEditInvName.tooltip"));
btnEditInvName.addActionListener(actionEvent -> {
currentEditor = new DlgYesNo(SYSConst.icon48edit, answer -> {
if (answer != null) {
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
MedInventory myInventory = em.merge(inventory);
em.lock(myInventory, LockModeType.OPTIMISTIC);
em.lock(myInventory.getResident(), LockModeType.OPTIMISTIC);
myInventory.setText(answer.toString());
em.getTransaction().commit();
createCP4(myInventory);
buildPanel();
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e);
} finally {
em.close();
}
}
currentEditor = null;
}, "nursingrecords.inventory.btnEditInvName.tooltip", inventory.getText(), new Validator() {
@Override
public boolean isValid(String value) {
return !value.trim().isEmpty();
}
@Override
public Object parse(String text) {
return text;
}
});
currentEditor.setVisible(true);
});
btnEditInvName.setEnabled(!inventory.isClosed());
cptitle.getRight().add(btnEditInvName);
}
if (OPDE.getAppInfo().isAllowedTo(InternalClassACL.MANAGER, "nursingrecords.inventory")) {
/***
* ____ _ ___ _
* / ___| | ___ ___ ___|_ _|_ ____ _____ _ __ | |_ ___ _ __ _ _
* | | | |/ _ \/ __|/ _ \| || '_ \ \ / / _ \ '_ \| __/ _ \| '__| | | |
* | |___| | (_) \__ \ __/| || | | \ V / __/ | | | || (_) | | | |_| |
* \____|_|\___/|___/\___|___|_| |_|\_/ \___|_| |_|\__\___/|_| \__, |
* |___/
*/
final JButton btnCloseInventory = new JButton(SYSConst.icon22playerStop);
btnCloseInventory.setPressedIcon(SYSConst.icon22playerStopPressed);
btnCloseInventory.setAlignmentX(Component.RIGHT_ALIGNMENT);
btnCloseInventory.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
btnCloseInventory.setContentAreaFilled(false);
btnCloseInventory.setBorder(null);
btnCloseInventory.setToolTipText(SYSTools.xx("nursingrecords.inventory.btncloseinventory.tooltip"));
btnCloseInventory.addActionListener(actionEvent -> {
currentEditor = new DlgYesNo(SYSTools.xx("nursingrecords.inventory.question.close1") + "<br/><b>" + inventory.getText() + "</b>" +
"<br/>" + SYSTools.xx("nursingrecords.inventory.question.close2"), SYSConst.icon48playerStop, answer -> {
if (answer.equals(JOptionPane.YES_OPTION)) {
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
MedInventory myInventory = em.merge(inventory);
em.lock(myInventory, LockModeType.OPTIMISTIC);
em.lock(myInventory.getResident(), LockModeType.OPTIMISTIC);
// close all stocks
for (MedStock stock : MedStockTools.getAll(myInventory)) {
if (!stock.isClosed()) {
MedStock mystock = em.merge(stock);
em.lock(mystock, LockModeType.OPTIMISTIC);
mystock.setNextStock(null);
MedStockTools.close(em, mystock, SYSTools.xx("nursingrecords.inventory.stock.msg.inventory_closed"), MedStockTransactionTools.STATE_EDIT_INVENTORY_CLOSED);
}
}
// close inventory
myInventory.setTo(new Date());
em.getTransaction().commit();
createCP4(myInventory);
buildPanel();
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e);
} finally {
em.close();
}
}
currentEditor = null;
});
currentEditor.setVisible(true);
});
btnCloseInventory.setEnabled(!inventory.isClosed());
cptitle.getRight().add(btnCloseInventory);
}
if (OPDE.getAppInfo().isAllowedTo(InternalClassACL.DELETE, "nursingrecords.inventory")) {
/***
* ____ _ ___ _
* | _ \ ___| |_ _|_ ____ _____ _ __ | |_ ___ _ __ _ _
* | | | |/ _ \ || || '_ \ \ / / _ \ '_ \| __/ _ \| '__| | | |
* | |_| | __/ || || | | \ V / __/ | | | || (_) | | | |_| |
* |____/ \___|_|___|_| |_|\_/ \___|_| |_|\__\___/|_| \__, |
* |___/
*/
final JButton btnDelInventory = new JButton(SYSConst.icon22delete);
btnDelInventory.setPressedIcon(SYSConst.icon22deletePressed);
btnDelInventory.setAlignmentX(Component.RIGHT_ALIGNMENT);
btnDelInventory.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
btnDelInventory.setContentAreaFilled(false);
btnDelInventory.setBorder(null);
btnDelInventory.setToolTipText(SYSTools.xx("nursingrecords.inventory.btndelinventory.tooltip"));
btnDelInventory.addActionListener(actionEvent -> {
currentEditor = new DlgYesNo(SYSTools.xx("nursingrecords.inventory.question.delete1") + "<br/><b>" + inventory.getText() + "</b>" +
"<br/>" + SYSTools.xx("nursingrecords.inventory.question.delete2"), SYSConst.icon48delete, answer -> {
if (answer.equals(JOptionPane.YES_OPTION)) {
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
MedInventory myInventory = em.merge(inventory);
em.lock(myInventory, LockModeType.OPTIMISTIC);
em.lock(myInventory.getResident(), LockModeType.OPTIMISTIC);
em.remove(myInventory);
em.getTransaction().commit();
// lstInventories.remove(inventory);
buildPanel();
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e);
} finally {
em.close();
currentEditor = null;
}
}
});
currentEditor.setVisible(true);
});
cptitle.getRight().add(btnDelInventory);
}
final JToggleButton tbClosedStock = GUITools.getNiceToggleButton(null);
tbClosedStock.setToolTipText(SYSTools.xx("nursingrecords.inventory.showclosedstocks"));
if (!inventory.isClosed()) {
tbClosedStock.addItemListener(e -> cpMap.get(key).setContentPane(createContentPanel4(inventory, tbClosedStock.isSelected())));
}
tbClosedStock.setSelected(inventory.isClosed());
tbClosedStock.setEnabled(!inventory.isClosed());
mapKey2ClosedToggleButton.put(key, tbClosedStock);
cptitle.getRight().add(tbClosedStock);
CollapsiblePaneAdapter adapter = new CollapsiblePaneAdapter() {
@Override
public void paneExpanded(CollapsiblePaneEvent collapsiblePaneEvent) {
cpMap.get(key).setContentPane(createContentPanel4(inventory, tbClosedStock.isSelected()));
}
};
synchronized (cpListener) {
if (cpListener.containsKey(key)) {
cpMap.get(key).removeCollapsiblePaneListener(cpListener.get(key));
}
cpListener.put(key, adapter);
cpMap.get(key).addCollapsiblePaneListener(adapter);
}
if (!cpMap.get(key).isCollapsed()) {
cpMap.get(key).setContentPane(createContentPanel4(inventory, tbClosedStock.isSelected()));
}
cpMap.get(key).setHorizontalAlignment(SwingConstants.LEADING);
cpMap.get(key).setOpaque(false);
cpMap.get(key).setBackground(getColor(SYSConst.medium2, lstInventories.indexOf(inventory) % 2 != 0));
return cpMap.get(key);
}
}
private JPanel createContentPanel4(final MedInventory inventory, boolean closed2) {
final JPanel pnlContent = new JPanel(new VerticalLayout());
// Collections.sort(inventory.getMedStocks());
for (MedStock stock : MedStockTools.getAll(inventory)) {
if (closed2 || !stock.isClosed()) {
pnlContent.add(createCP4(stock));
}
}
return pnlContent;
}
private CollapsiblePane createCP4(final MedStock stock) {
/***
* _ ____ ____ _ _ __ _ _ __
* ___ _ __ ___ __ _| |_ ___ / ___| _ \| || | / /__| |_ ___ ___| | _\ \
* / __| '__/ _ \/ _` | __/ _ \ | | |_) | || |_| / __| __/ _ \ / __| |/ /| |
* | (__| | | __/ (_| | || __/ |___| __/|__ _| \__ \ || (_) | (__| < | |
* \___|_| \___|\__,_|\__\___|\____|_| |_| | |___/\__\___/ \___|_|\_\| |
* \_\ /_/
*/
final String key = stock.getID() + ".xstock";
synchronized (cpMap) {
if (!cpMap.containsKey(key)) {
cpMap.put(key, new CollapsiblePane());
try {
cpMap.get(key).setCollapsed(true);
} catch (PropertyVetoException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
cpMap.get(key).setName("stock");
BigDecimal sumStock = BigDecimal.ZERO;
try {
EntityManager em = OPDE.createEM();
sumStock = MedStockTools.getSum(em, stock);
em.close();
} catch (Exception e) {
OPDE.fatal(e);
}
String title = "<html><table border=\"0\">" +
"<tr>" +
(stock.isClosed() ? "<s>" : "") +
"<td width=\"600\" align=\"left\">" + MedStockTools.getAsHTML(stock) + "</td>" +
"<td width=\"200\" align=\"right\">" + SYSTools.formatBigDecimal(sumStock) + " " + DosageFormTools.getPackageText(MedInventoryTools.getForm(stock.getInventory())) + "</td>" +
(stock.isClosed() ? "</s>" : "") +
"</tr>" +
"</table>" +
"</html>";
DefaultCPTitle cptitle = new DefaultCPTitle(title, e -> {
try {
cpMap.get(key).setCollapsed(!cpMap.get(key).isCollapsed());
} catch (PropertyVetoException pve) {
// BAH!
}
});
cpMap.get(key).setTitleLabelComponent(cptitle.getMain());
cpMap.get(key).setSlidingDirection(SwingConstants.SOUTH);
cptitle.getRight().add(new StockPanel(stock));
if (!stock.getInventory().isClosed()) {
/***
* ____ _ _ _ _ _
* | _ \ _ __(_)_ __ | |_| | __ _| |__ ___| |
* | |_) | '__| | '_ \| __| | / _` | '_ \ / _ \ |
* | __/| | | | | | | |_| |__| (_| | |_) | __/ |
* |_| |_| |_|_| |_|\__|_____\__,_|_.__/ \___|_|
*
*/
final JButton btnPrintLabel = new JButton(SYSConst.icon22print2);
btnPrintLabel.setPressedIcon(SYSConst.icon22print2Pressed);
btnPrintLabel.setAlignmentX(Component.RIGHT_ALIGNMENT);
btnPrintLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
btnPrintLabel.setContentAreaFilled(false);
btnPrintLabel.setBorder(null);
btnPrintLabel.setToolTipText(SYSTools.xx("nursingrecords.inventory.stock.btnprintlabel.tooltip"));
btnPrintLabel.addActionListener(actionEvent -> {
LogicalPrinter logicalPrinter = OPDE.getLogicalPrinters().getMapName2LogicalPrinter().get(OPDE.getProps().getProperty(SYSPropsTools.KEY_LOGICAL_PRINTER));
PrinterForm printerForm1 = logicalPrinter.getForms().get(OPDE.getProps().getProperty(SYSPropsTools.KEY_MEDSTOCK_LABEL));
OPDE.getPrintProcessor().addPrintJob(new PrintListElement(stock, logicalPrinter, printerForm1, OPDE.getProps().getProperty(SYSPropsTools.KEY_PHYSICAL_PRINTER)));
});
btnPrintLabel.setEnabled(OPDE.getPrintProcessor().isWorking());
cptitle.getRight().add(btnPrintLabel);
}
/***
* __ __
* | \/ | ___ _ __ _ _
* | |\/| |/ _ \ '_ \| | | |
* | | | | __/ | | | |_| |
* |_| |_|\___|_| |_|\__,_|
*
*/
final JButton btnMenu = new JButton(SYSConst.icon22menu);
btnMenu.setPressedIcon(SYSConst.icon22Pressed);
btnMenu.setAlignmentX(Component.RIGHT_ALIGNMENT);
// btnMenu.setAlignmentY(Component.TOP_ALIGNMENT);
btnMenu.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
btnMenu.setContentAreaFilled(false);
btnMenu.setBorder(null);
btnMenu.addActionListener(e -> {
JidePopup popup = new JidePopup();
popup.setMovable(false);
popup.getContentPane().setLayout(new BoxLayout(popup.getContentPane(), BoxLayout.LINE_AXIS));
popup.setOwner(btnMenu);
popup.removeExcludedComponent(btnMenu);
JPanel pnl = getMenu(stock);
popup.getContentPane().add(pnl);
popup.setDefaultFocusComponent(pnl);
GUITools.showPopup(popup, SwingConstants.WEST);
});
cptitle.getRight().add(btnMenu);
CollapsiblePaneAdapter adapter = new CollapsiblePaneAdapter() {
@Override
public void paneExpanded(CollapsiblePaneEvent collapsiblePaneEvent) {
cpMap.get(key).setContentPane(createContentPanel4(stock));
}
};
synchronized (cpListener) {
if (cpListener.containsKey(key)) {
cpMap.get(key).removeCollapsiblePaneListener(cpListener.get(key));
}
cpListener.put(key, adapter);
cpMap.get(key).addCollapsiblePaneListener(adapter);
}
if (!cpMap.get(key).isCollapsed()) {
JPanel contentPane = createContentPanel4(stock);
cpMap.get(key).setContentPane(contentPane);
}
cpMap.get(key).setHorizontalAlignment(SwingConstants.LEADING);
cpMap.get(key).setOpaque(false);
cpMap.get(key).setBackground(getColor(SYSConst.light3, lstInventories.indexOf(stock.getInventory()) % 2 != 0));
return cpMap.get(key);
}
}
/**
* This inner class is responsible for the three led controls to open, close, reactivate or reclose a given stock.
*/
private class StockPanel extends JPanel {
boolean selRed, selGreen, selYellow;
JRadioButton red, green, yellow;
MedStock stock;
boolean ignoreEvent = false;
StockPanel(MedStock stock1) {
super();
this.stock = stock1;
final String key = stock.getID() + ".xstock";
final ButtonGroup bg = new ButtonGroup();
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
red = new JRadioButton(SYSConst.icon22ledRedOff);
red.setSelectedIcon(SYSConst.icon22ledRedOn);
selRed = stock.isClosed();
red.setSelected(selRed);
red.setContentAreaFilled(false);
red.setBorderPainted(false);
red.setBorder(null);
red.setOpaque(false);
bg.add(red);
yellow = new JRadioButton(SYSConst.icon22ledYellowOff);
yellow.setSelectedIcon(SYSConst.icon22ledYellowOn);
selYellow = stock.isOpened();
yellow.setSelected(selYellow);
yellow.setContentAreaFilled(false);
yellow.setBorderPainted(false);
yellow.setBorder(null);
yellow.setOpaque(false);
bg.add(yellow);
green = new JRadioButton(SYSConst.icon22ledGreenOff);
green.setSelectedIcon(SYSConst.icon22ledGreenOn);
selGreen = stock.isNew();
green.setSelected(selGreen);
green.setContentAreaFilled(false);
green.setBorderPainted(false);
green.setBorder(null);
green.setOpaque(false);
bg.add(green);
/***
* _
* _ __ ___ __| |
* | '__/ _ \/ _` |
* | | | __/ (_| |
* |_| \___|\__,_|
*
*/
red.addItemListener(ie -> {
if (ignoreEvent) return;
if (!OPDE.getAppInfo().isAllowedTo(InternalClassACL.UPDATE, "nursingrecords.inventory")) {
OPDE.getDisplayManager().addSubMessage(new DisplayMessage("misc.msg.noaccess"));
reset();
return;
}
if (ie.getStateChange() == ItemEvent.SELECTED) {
/***
* ____ _
* / ___| | ___ ___ ___
* | | | |/ _ \/ __|/ _ \
* | |___| | (_) \__ \ __/
* \____|_|\___/|___/\___|
*
*/
if (!stock.isOpened()) {
OPDE.getDisplayManager().addSubMessage(new DisplayMessage("nursingrecords.inventory.stockpanel.stockIsNotOpen1"));
reset();
return;
}
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
MedStock myStock = em.merge(stock);
em.lock(myStock, LockModeType.OPTIMISTIC);
em.lock(em.merge(myStock.getInventory().getResident()), LockModeType.OPTIMISTIC);
em.lock(em.merge(myStock.getInventory()), LockModeType.OPTIMISTIC);
myStock.setNextStock(null);
MedStockTools.close(em, myStock, SYSTools.xx("nursingrecords.inventory.stockpanel.STATE_EDIT_STOCK_CLOSED"), MedStockTransactionTools.STATE_EDIT_STOCK_CLOSED);
myStock.setState(MedStockTools.STATE_NOTHING);
em.getTransaction().commit();
// synchronized (lstInventories) {
// int index = lstInventories.indexOf(myStock.getInventory());
// lstInventories.get(index).getMedStocks().remove(stock);
// lstInventories.get(index).getMedStocks().add(myStock);
// }
// contentmap.remove(key);
createCP4(myStock.getInventory());
buildPanel();
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e);
} finally {
em.close();
}
selRed = true;
// selOrange = false;
selYellow = false;
selGreen = false;
}
});
/***
* _ _
* _ _ ___| | | _____ __
* | | | |/ _ \ | |/ _ \ \ /\ / /
* | |_| | __/ | | (_) \ V V /
* \__, |\___|_|_|\___/ \_/\_/
* |___/
*/
yellow.addItemListener(ie -> {
if (ignoreEvent) return;
if (!OPDE.getAppInfo().isAllowedTo(InternalClassACL.UPDATE, "nursingrecords.inventory")) {
OPDE.getDisplayManager().addSubMessage(new DisplayMessage("misc.msg.noaccess"));
reset();
return;
}
;
if (ie.getStateChange() == ItemEvent.SELECTED) {
if (!stock.isToBeClosedSoon()) {
MedStock openedStock = MedInventoryTools.getCurrentOpened(stock.getInventory());
if (openedStock != null) {
OPDE.getDisplayManager().addSubMessage(new DisplayMessage("nursingrecords.inventory.stockpanel.anotherStockIsOpened"));
reset();
return;
}
}
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
MedStock myStock = em.merge(stock);
em.lock(myStock, LockModeType.OPTIMISTIC);
em.lock(em.merge(myStock.getInventory().getResident()), LockModeType.OPTIMISTIC);
em.lock(em.merge(myStock.getInventory()), LockModeType.OPTIMISTIC);
if (!stock.isToBeClosedSoon()) {
if (stock.isClosed()) {
/***
* ____ _ _ _
* | _ \ ___ __ _ ___| |_(_)_ ____ _| |_ ___
* | |_) / _ \/ _` |/ __| __| \ \ / / _` | __/ _ \
* | _ < __/ (_| | (__| |_| |\ V / (_| | || __/
* |_| \_\___|\__,_|\___|\__|_| \_/ \__,_|\__\___|
*
*/
myStock.setOut(SYSConst.DATE_UNTIL_FURTHER_NOTICE);
} else {
/***
* ___
* / _ \ _ __ ___ _ __
* | | | | '_ \ / _ \ '_ \
* | |_| | |_) | __/ | | |
* \___/| .__/ \___|_| |_|
* |_|
*/
myStock.setOpened(new Date());
}
}
myStock.setState(MedStockTools.STATE_NOTHING);
myStock.setNextStock(null);
em.getTransaction().commit();
// synchronized (lstInventories) {
// int index = lstInventories.indexOf(myStock.getInventory());
// lstInventories.get(index).getMedStocks().remove(stock);
// lstInventories.get(index).getMedStocks().add(myStock);
// }
createCP4(myStock.getInventory());
buildPanel();
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e);
} finally {
em.close();
}
selRed = false;
// selOrange = false;
selYellow = true;
selGreen = false;
}
});
/***
*
* __ _ _ __ ___ ___ _ __
* / _` | '__/ _ \/ _ \ '_ \
* | (_| | | | __/ __/ | | |
* \__, |_| \___|\___|_| |_|
* |___/
*/
green.addItemListener(ie -> {
if (ignoreEvent) return;
if (!OPDE.getAppInfo().isAllowedTo(InternalClassACL.UPDATE, "nursingrecords.inventory")) {
OPDE.getDisplayManager().addSubMessage(new DisplayMessage("misc.msg.noaccess"));
reset();
return;
}
if (ie.getStateChange() == ItemEvent.SELECTED) {
/***
* _ _
* _ __ ___ __ _| | _____ _ __ _____ __ __ _ __ _ __ _(_)_ __
* | '_ ` _ \ / _` | |/ / _ \ | '_ \ / _ \ \ /\ / / / _` |/ _` |/ _` | | '_ \
* | | | | | | (_| | < __/ | | | | __/\ V V / | (_| | (_| | (_| | | | | |
* |_| |_| |_|\__,_|_|\_\___| |_| |_|\___| \_/\_/ \__,_|\__, |\__,_|_|_| |_|
* |___/
*/
if (!stock.isOpened()) {
OPDE.getDisplayManager().addSubMessage(new DisplayMessage("nursingrecords.inventory.stockpanel.stockIsNotOpen2"));
reset();
return;
}
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
MedStock myStock = em.merge(stock);
em.lock(myStock, LockModeType.OPTIMISTIC);
em.lock(em.merge(myStock.getInventory().getResident()), LockModeType.OPTIMISTIC);
em.lock(em.merge(myStock.getInventory()), LockModeType.OPTIMISTIC);
myStock.setOut(SYSConst.DATE_UNTIL_FURTHER_NOTICE);
myStock.setOpened(SYSConst.DATE_UNTIL_FURTHER_NOTICE);
myStock.setState(MedStockTools.STATE_NOTHING);
em.getTransaction().commit();
// synchronized (lstInventories) {
// int index = lstInventories.indexOf(myStock.getInventory());
// lstInventories.get(index).getMedStocks().remove(stock);
// lstInventories.get(index).getMedStocks().add(myStock);
// }
// contentmap.remove(key);
createCP4(myStock.getInventory());
buildPanel();
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e);
} finally {
em.close();
}
selRed = false;
selYellow = false;
selGreen = true;
}
});
add(green);
add(yellow);
add(red);
setOpaque(false);
}
void reset() {
ignoreEvent = true;
red.setSelected(selRed);
yellow.setSelected(selYellow);
green.setSelected(selGreen);
ignoreEvent = false;
}
}
private JPanel createContentPanel4(final MedStock stock) {
// final String key = stock.getID() + ".xstock";
// if (!contentmap.containsKey(key)) {
final JPanel pnlTX = new JPanel(new VerticalLayout());
// pnlTX.setLayout(new BoxLayout(pnlTX, BoxLayout.PAGE_AXIS));
pnlTX.setOpaque(true);
// pnlTX.setBackground(Color.white);
synchronized (lstInventories) {
pnlTX.setBackground(getColor(SYSConst.light2, lstInventories.indexOf(stock.getInventory()) % 2 != 0));
}
/***
* _ _ _ _______ __
* / \ __| | __| |_ _\ \/ /
* / _ \ / _` |/ _` | | | \ /
* / ___ \ (_| | (_| | | | / \
* /_/ \_\__,_|\__,_| |_| /_/\_\
*
*/
JideButton btnAddTX = GUITools.createHyperlinkButton("nursingrecords.inventory.newmedstocktx", SYSConst.icon22add, e -> {
currentEditor = new DlgTX(new MedStockTransaction(stock, BigDecimal.ONE, MedStockTransactionTools.STATE_EDIT_MANUAL), o -> {
if (o != null) {
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
final MedStockTransaction myTX = (MedStockTransaction) em.merge(o);
MedStock myStock = em.merge(stock);
em.lock(myStock, LockModeType.OPTIMISTIC);
em.lock(myStock.getInventory(), LockModeType.OPTIMISTIC);
em.lock(em.merge(myTX.getStock().getInventory().getResident()), LockModeType.OPTIMISTIC);
em.getTransaction().commit();
createCP4(myStock.getInventory());
buildPanel();
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e1) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e1);
} finally {
em.close();
}
}
currentEditor = null;
});
currentEditor.setVisible(true);
});
btnAddTX.setEnabled(!stock.isClosed());
pnlTX.add(btnAddTX);
/***
* ____ _ _ _ _______ __
* / ___|| |__ _____ __ __ _| | | |_ _\ \/ /___
* \___ \| '_ \ / _ \ \ /\ / / / _` | | | | | \ // __|
* ___) | | | | (_) \ V V / | (_| | | | | | / \\__ \
* |____/|_| |_|\___/ \_/\_/ \__,_|_|_| |_| /_/\_\___/
*
*/
OPDE.getMainframe().setBlocked(true);
OPDE.getDisplayManager().setProgressBarMessage(new DisplayMessage(SYSTools.xx("misc.msg.wait"), -1, 100));
SwingWorker worker = new SwingWorker() {
@Override
protected Object doInBackground() throws Exception {
int progress = 0;
List<MedStockTransaction> listTX = MedStockTransactionTools.getAll(stock);
OPDE.getDisplayManager().setProgressBarMessage(new DisplayMessage(SYSTools.xx("misc.msg.wait"), progress, listTX.size()));
BigDecimal rowsum = MedStockTools.getSum(stock);
// BigDecimal rowsum = MedStockTools.getSum(stock);
// Collections.sort(stock.getStockTransaction());
for (final MedStockTransaction tx : listTX) {
progress++;
OPDE.getDisplayManager().setProgressBarMessage(new DisplayMessage(SYSTools.xx("misc.msg.wait"), progress, listTX.size()));
String title = "<html><table border=\"0\">" +
"<tr>" +
"<td width=\"130\" align=\"left\">" + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT).format(tx.getPit())
+ "<br/>[" + tx.getID() + "]"
+ "</td>" +
"<td width=\"200\" align=\"center\">" + SYSTools.catchNull(tx.getText(), "--") + "</td>" +
"<td width=\"100\" align=\"right\">" +
SYSTools.formatBigDecimal(tx.getAmount()) +
"</td>" +
"<td width=\"100\" align=\"right\">" +
(rowsum.compareTo(BigDecimal.ZERO) < 0 ? "<font color=\"red\">" : "") +
SYSTools.formatBigDecimal(rowsum) +
(rowsum.compareTo(BigDecimal.ZERO) < 0 ? "</font>" : "") +
"</td>" +
(stock.getTradeForm().isWeightControlled() ?
"<td width=\"100\" align=\"right\">" +
SYSTools.formatBigDecimal(tx.getWeight()) + "g" +
"</td>" : "") +
"<td width=\"100\" align=\"left\">" +
SYSTools.anonymizeUser(tx.getUser().getUID()) +
"</td>" +
"</tr>" +
"</table>" +
"</font></html>";
rowsum = rowsum.subtract(tx.getAmount());
final DefaultCPTitle pnlTitle = new DefaultCPTitle(title, null);
// pnlTitle.getLeft().addMouseListener();
if (OPDE.getAppInfo().isAllowedTo(InternalClassACL.DELETE, "nursingrecords.inventory")) {
/***
* ____ _ _______ __
* | _ \ ___| |_ _\ \/ /
* | | | |/ _ \ | | | \ /
* | |_| | __/ | | | / \
* |____/ \___|_| |_| /_/\_\
*
*/
final JButton btnDelTX = new JButton(SYSConst.icon22delete);
btnDelTX.setPressedIcon(SYSConst.icon22deletePressed);
btnDelTX.setAlignmentX(Component.RIGHT_ALIGNMENT);
btnDelTX.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
btnDelTX.setContentAreaFilled(false);
btnDelTX.setBorder(null);
btnDelTX.setToolTipText(SYSTools.xx("nursingrecords.inventory.tx.btndelete.tooltip"));
btnDelTX.addActionListener(actionEvent -> {
currentEditor = new DlgYesNo(SYSTools.xx("misc.questions.delete1") + "<br/><i>" + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT).format(tx.getPit()) +
" " + tx.getUser().getUID() + "</i><br/>" + SYSTools.xx("misc.questions.delete2"), SYSConst.icon48delete, answer -> {
if (answer.equals(JOptionPane.YES_OPTION)) {
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
MedStockTransaction myTX = em.merge(tx);
MedStock myStock = em.merge(stock);
em.lock(em.merge(myTX.getStock().getInventory().getResident()), LockModeType.OPTIMISTIC);
em.lock(myStock, LockModeType.OPTIMISTIC);
em.lock(myStock.getInventory(), LockModeType.OPTIMISTIC);
em.remove(myTX);
// myStock.getStockTransaction().remove(myTX);
em.getTransaction().commit();
createCP4(myStock.getInventory());
buildPanel();
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e);
} finally {
em.close();
currentEditor = null;
}
}
});
currentEditor.setVisible(true);
});
btnDelTX.setEnabled(!stock.isClosed() && (tx.getState() == MedStockTransactionTools.STATE_DEBIT || tx.getState() == MedStockTransactionTools.STATE_EDIT_MANUAL));
pnlTitle.getRight().add(btnDelTX);
}
/***
* _ _ _ _______ __
* | | | |_ __ __| | ___ |_ _\ \/ /
* | | | | '_ \ / _` |/ _ \ | | \ /
* | |_| | | | | (_| | (_) | | | / \
* \___/|_| |_|\__,_|\___/ |_| /_/\_\
*
*/
final JButton btnUndoTX = new JButton(SYSConst.icon22undo);
btnUndoTX.setPressedIcon(SYSConst.icon22Pressed);
btnUndoTX.setAlignmentX(Component.RIGHT_ALIGNMENT);
btnUndoTX.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
btnUndoTX.setContentAreaFilled(false);
btnUndoTX.setBorder(null);
btnUndoTX.setToolTipText(SYSTools.xx("nursingrecords.inventory.tx.btnUndoTX.tooltip"));
btnUndoTX.addActionListener(actionEvent -> {
currentEditor = new DlgYesNo(SYSTools.xx("misc.questions.undo1") + "<br/><i>" + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT).format(tx.getPit()) +
" " + tx.getUser().getUID() + "</i><br/>" + SYSTools.xx("misc.questions.undo2"), SYSConst.icon48undo, answer -> {
if (answer.equals(JOptionPane.YES_OPTION)) {
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
MedStock myStock = em.merge(stock);
final MedStockTransaction myOldTX = em.merge(tx);
myOldTX.setState(MedStockTransactionTools.STATE_CANCELLED);
final MedStockTransaction myNewTX = em.merge(new MedStockTransaction(myStock, myOldTX.getAmount().negate(), MedStockTransactionTools.STATE_CANCEL_REC));
myOldTX.setText(SYSTools.xx("misc.msg.reversedBy") + ": " + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT).format(myNewTX.getPit()));
myNewTX.setText(SYSTools.xx("misc.msg.reversalFor") + ": " + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT).format(myOldTX.getPit()));
// myStock.getStockTransaction().add(myNewTX);
// myStock.getStockTransaction().remove(tx);
// myStock.getStockTransaction().add(myOldTX);
em.lock(em.merge(myNewTX.getStock().getInventory().getResident()), LockModeType.OPTIMISTIC);
em.lock(myStock, LockModeType.OPTIMISTIC);
em.lock(myStock.getInventory(), LockModeType.OPTIMISTIC);
em.getTransaction().commit();
// synchronized (lstInventories) {
// int indexInventory = lstInventories.indexOf(stock.getInventory());
// int indexStock = lstInventories.get(indexInventory).getMedStocks().indexOf(stock);
// lstInventories.get(indexInventory).getMedStocks().remove(stock);
// lstInventories.get(indexInventory).getMedStocks().add(indexStock, myStock);
// }
// synchronized (linemap) {
// linemap.remove(tx);
// }
createCP4(myStock.getInventory());
buildPanel();
// SwingUtilities.invokeLater(new Runnable() {
// @Override
// public void run() {
// synchronized (linemap) {
// GUITools.flashBackground(linemap.get(myOldTX), Color.RED, 2);
// GUITools.flashBackground(linemap.get(myNewTX), Color.YELLOW, 2);
// }
// }
// });
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e);
} finally {
em.close();
currentEditor = null;
}
}
});
currentEditor.setVisible(true);
});
btnUndoTX.setEnabled(!stock.isClosed() && (tx.getState() == MedStockTransactionTools.STATE_DEBIT || tx.getState() == MedStockTransactionTools.STATE_EDIT_MANUAL));
pnlTitle.getRight().add(btnUndoTX);
if (stock.getTradeForm().isWeightControlled() && OPDE.getAppInfo().isAllowedTo(InternalClassACL.MANAGER, "nursingrecords.inventory")) {
/***
* _ __ __ _ _ _
* ___ ___| |\ \ / /__(_) __ _| |__ | |_
* / __|/ _ \ __\ \ /\ / / _ \ |/ _` | '_ \| __|
* \__ \ __/ |_ \ V V / __/ | (_| | | | | |_
* |___/\___|\__| \_/\_/ \___|_|\__, |_| |_|\__|
* |___/
*/
final JButton btnSetWeight = new JButton(SYSConst.icon22scales);
btnSetWeight.setPressedIcon(SYSConst.icon22Pressed);
btnSetWeight.setAlignmentX(Component.RIGHT_ALIGNMENT);
btnSetWeight.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
btnSetWeight.setContentAreaFilled(false);
btnSetWeight.setBorder(null);
btnSetWeight.setToolTipText(SYSTools.xx("nursingrecords.inventory.tx.btnUndoTX.tooltip"));
btnSetWeight.addActionListener(actionEvent -> {
BigDecimal weight;
currentEditor = new DlgYesNo(SYSConst.icon48scales, o -> {
if (!SYSTools.catchNull(o).isEmpty()) {
BigDecimal weight1 = (BigDecimal) o;
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
MedStock myStock = em.merge(stock);
final MedStockTransaction myTX = em.merge(tx);
em.lock(myTX, LockModeType.OPTIMISTIC);
myTX.setWeight(weight1);
em.lock(myStock, LockModeType.OPTIMISTIC);
em.lock(myStock.getInventory(), LockModeType.OPTIMISTIC);
em.getTransaction().commit();
createCP4(myStock.getInventory());
buildPanel();
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e);
} finally {
em.close();
}
}
currentEditor = null;
}, "nursingrecords.bhp.weight", SYSTools.formatBigDecimal(tx.getWeight()), new Validator<BigDecimal>() {
@Override
public boolean isValid(String value) {
BigDecimal bd = parse(value);
return bd != null && bd.compareTo(BigDecimal.ZERO) > 0;
}
@Override
public BigDecimal parse(String text) {
return SYSTools.parseDecimal(text);
}
});
currentEditor.setVisible(true);
});
btnSetWeight.setEnabled(!stock.isClosed() && (tx.getState() == MedStockTransactionTools.STATE_DEBIT || tx.getState() == MedStockTransactionTools.STATE_CREDIT || tx.getState() == MedStockTransactionTools.STATE_EDIT_MANUAL));
pnlTitle.getRight().add(btnSetWeight);
}
pnlTX.add(pnlTitle.getMain());
}
return null;
}
@Override
protected void done() {
OPDE.getDisplayManager().setProgressBarMessage(null);
OPDE.getMainframe().setBlocked(false);
}
};
worker.execute();
return pnlTX;
}
/**
* This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the PrinterForm Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jspInventory = new JScrollPane();
cpsInventory = new CollapsiblePanes();
//======== this ========
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
//======== jspInventory ========
{
//======== cpsInventory ========
{
cpsInventory.setLayout(new BoxLayout(cpsInventory, BoxLayout.X_AXIS));
}
jspInventory.setViewportView(cpsInventory);
}
add(jspInventory);
}// </editor-fold>//GEN-END:initComponents
private void txtSucheActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtSucheActionPerformed
JXSearchField search = (JXSearchField) evt.getSource();
if (!search.getText().isEmpty() && search.getText().matches("\\d*")) {
// numbers only !
long id = Long.parseLong(search.getText());
EntityManager em = OPDE.createEM();
final MedStock stock = em.find(MedStock.class, id);
em.close();
if (stock != null) {
final String key = stock.getInventory().getID() + ".xinventory";
if (!resident.equals(stock.getInventory().getResident())) {
if (OPDE.getAppInfo().isAllowedTo(InternalClassACL.ARCHIVE, "nursingrecords.info")) {
switchResident(stock.getInventory().getResident(), stock.getInventory(), o -> {
synchronized (mapKey2ClosedToggleButton) {
mapKey2ClosedToggleButton.get(key).setSelected(true);
}
});
} else {
OPDE.getDisplayManager().addSubMessage(new DisplayMessage("misc.msg.noarchiveaccess"));
}
} else {
synchronized (mapKey2ClosedToggleButton) {
// CollapsiblePane myCP = cpMap.get(key);
if (cpMap.get(key).isCollapsed()) {
try {
cpMap.get(key).setCollapsed(false);
} catch (PropertyVetoException e) {
// bah!
}
}
}
}
} else {
OPDE.getDisplayManager().addSubMessage(new DisplayMessage("misc.msg.notfound"));
}
}
}//GEN-LAST:event_txtSucheActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private JScrollPane jspInventory;
private CollapsiblePanes cpsInventory;
// End of variables declaration//GEN-END:variables
private void buildPanel() {
buildPanel(true);
}
private void buildPanel(boolean reloadListInventory) {
cpsInventory.removeAll();
cpsInventory.setLayout(new JideBoxLayout(cpsInventory, JideBoxLayout.Y_AXIS));
synchronized (lstInventories) {
if (reloadListInventory) {
lstInventories.clear();
lstInventories = tbClosedInventory.isSelected() ? MedInventoryTools.getAll(resident) : MedInventoryTools.getAllActive(resident);
}
int row = 0;
for (MedInventory inventory : lstInventories) {
synchronized (cpMap) {
String key = inventory.getID() + ".xinventory";
// cpMap.get(key).setBackground(getColor(SYSConst.medium2, row % 2 != 0));
cpsInventory.add(cpMap.get(key));
cpMap.get(key).getContentPane().revalidate();
row++;
}
}
}
//
// boolean odd = true;
// for (Component cp : cpsInventory.getComponents()) {
// colorize(cp, 1, odd);
// odd = !odd;
// }
// }
cpsInventory.addExpansion();
}
// private void colorize(Component component, int depth, boolean odd) {
//
// if (component instanceof CollapsiblePane) {
// OPDE.debug("Depth: " + depth);
// component.setBackground(getColor(depth + 4, odd));
// }
// if (component instanceof JPanel) {
// component.setBackground(getColor(depth + 6, odd));
// }
//
// if (component instanceof Container) {
// depth++;
// for (Component comp : ((Container) component).getComponents()) {
// colorize(comp, depth, odd);
// }
// }
// }
private JPanel getMenu(final MedStock stock) {
final String key = stock.getID() + ".xstock";
JPanel pnlMenu = new JPanel(new VerticalLayout());
if (OPDE.getAppInfo().isAllowedTo(InternalClassACL.DELETE, "nursingrecords.inventory")) {
/***
* ____ _ ____ _ _
* | _ \ ___| | / ___|| |_ ___ ___| | __
* | | | |/ _ \ | \___ \| __/ _ \ / __| |/ /
* | |_| | __/ | ___) | || (_) | (__| <
* |____/ \___|_| |____/ \__\___/ \___|_|\_\
*
*/
final JButton btnDelete = GUITools.createHyperlinkButton("nursingrecords.inventory.stock.btndelete.tooltip", SYSConst.icon22delete, null);
btnDelete.addActionListener(actionEvent -> {
currentEditor = new DlgYesNo(SYSTools.xx("misc.questions.delete1") + "<br/><b>" + SYSTools.xx("nursingrecords.inventory.search.stockid") + ": " + stock.getID() + "</b>" +
"<br/>" + SYSTools.xx("misc.questions.delete2"), SYSConst.icon48delete, answer -> {
if (answer.equals(JOptionPane.YES_OPTION)) {
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
MedStock myStock = em.merge(stock);
em.lock(em.merge(myStock.getInventory().getResident()), LockModeType.OPTIMISTIC);
em.lock(em.merge(myStock.getInventory()), LockModeType.OPTIMISTIC);
// synchronized (lstInventories) {
// int index = lstInventories.indexOf(myStock.getInventory());
// lstInventories.get(index).getMedStocks().remove(myStock);
// }
em.remove(myStock);
em.getTransaction().commit();
synchronized (cpMap) {
cpMap.remove(key);
}
createCP4(myStock.getInventory());
buildPanel();
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e);
} finally {
em.close();
currentEditor = null;
}
}
});
currentEditor.setVisible(true);
});
btnDelete.setEnabled(!stock.isClosed());
pnlMenu.add(btnDelete);
}
/***
* ____ _ _____ _ ____ _
* / ___| ___| |_| ____|_ ___ __ (_)_ __ _ _| _ \ __ _| |_ ___
* \___ \ / _ \ __| _| \ \/ / '_ \| | '__| | | | | | |/ _` | __/ _ \
* ___) | __/ |_| |___ > <| |_) | | | | |_| | |_| | (_| | || __/
* |____/ \___|\__|_____/_/\_\ .__/|_|_| \__, |____/ \__,_|\__\___|
* |_| |___/
*/
final JButton btnExpiry = GUITools.createHyperlinkButton("nursingrecords.inventory.tooltip.btnSetExpiry", SYSConst.icon22gotoEnd, null);
btnExpiry.addActionListener(actionEvent -> {
final JidePopup popup = new JidePopup();
popup.setMovable(false);
PnlExpiry pnlExpiry = new PnlExpiry(stock.getExpires(), SYSTools.xx("nursingrecords.inventory.pnlExpiry.title") + ": " + stock.getID(), o -> {
popup.hidePopup();
EntityManager em = OPDE.createEM();
try {
em.getTransaction().begin();
MedStock myStock = em.merge(stock);
em.lock(em.merge(myStock.getInventory().getResident()), LockModeType.OPTIMISTIC);
em.lock(em.merge(myStock.getInventory()), LockModeType.OPTIMISTIC);
myStock.setExpires((Date) o);
em.getTransaction().commit();
synchronized (cpMap) {
cpMap.remove(key);
}
createCP4(myStock.getInventory());
buildPanel();
} catch (OptimisticLockException ole) {
OPDE.warn(ole);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (ole.getMessage().indexOf("Class> entity.info.Resident") > -1) {
OPDE.getMainframe().emptyFrame();
OPDE.getMainframe().afterLogin();
}
OPDE.getDisplayManager().addSubMessage(DisplayManager.getLockMessage());
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
OPDE.fatal(e);
} finally {
em.close();
}
});
popup.setOwner(btnExpiry);
popup.setContentPane(pnlExpiry);
popup.removeExcludedComponent(pnlExpiry);
popup.setDefaultFocusComponent(pnlExpiry);
GUITools.showPopup(popup, SwingConstants.WEST);
});
btnExpiry.setEnabled(!stock.isClosed());
pnlMenu.add(btnExpiry);
if (OPDE.getAppInfo().isAllowedTo(InternalClassACL.MANAGER, "opde.medication")) {
/***
* _____ _ _____ _____ _ _ _
* |_ _| __ __ _ __| | ___| ___|__ _ __ _ __ ___ | ____|__| (_) |_ ___ _ __
* | || '__/ _` |/ _` |/ _ \ |_ / _ \| '__| '_ ` _ \| _| / _` | | __/ _ \| '__|
* | || | | (_| | (_| | __/ _| (_) | | | | | | | | |__| (_| | | || (_) | |
* |_||_| \__,_|\__,_|\___|_| \___/|_| |_| |_| |_|_____\__,_|_|\__\___/|_|
*
*/
final JButton btnTFEditor = GUITools.createHyperlinkButton("TFEditor.tooltip", SYSConst.icon22medical, null);
btnTFEditor.addActionListener(actionEvent -> {
new DlgTradeForm(stock.getTradeForm());
reload();
});
pnlMenu.add(btnTFEditor);
/***
* _ _ ____ ____ _ _ _
* | | | | _ \| _ \ ___ __| (_) |_ ___ _ __
* | | | | |_) | |_) / _ \/ _` | | __/ _ \| '__|
* | |_| | __/| _ < __/ (_| | | || (_) | |
* \___/|_| |_| \_\___|\__,_|_|\__\___/|_|
*
*/
final JButton btnUPReditor = GUITools.createHyperlinkButton("upreditor.tooltip", SYSConst.icon22calc, null);
btnUPReditor.addActionListener(actionEvent -> new DlgUPREditor(stock.getTradeForm(), o -> reload()));
btnUPReditor.setEnabled(stock.getTradeForm().getDosageForm().isUPRn());
pnlMenu.add(btnUPReditor);
}
// if (OPDE.getAppInfo().isAllowedTo(InternalClassACL.UPDATE, internalClassID)) {
// /***
// * ____ _
// * / ___| |__ __ _ _ __ __ _ ___
// * | | | '_ \ / _` | '_ \ / _` |/ _ \
// * | |___| | | | (_| | | | | (_| | __/
// * \____|_| |_|\__,_|_| |_|\__, |\___|
// * |___/
// */
// final JButton btnChange = GUITools.createHyperlinkButton(internalClassID + ".btnChange.tooltip", SYSConst.icon22playerPlay, null);
// btnChange.setEnabled(!prescription.isClosed() && !prescription.isOnDemand() && numBHPs != 0);
// pnlMenu.add(btnChange);
return pnlMenu;
}
}