From 13817a3600826e2c44a111f3cdce51705ad50e4b Mon Sep 17 00:00:00 2001 From: David McMackins II Date: Wed, 30 Nov 2016 09:49:53 -0600 Subject: Add sold versus waste report --- src/com/delwink/icebox/lang/en_US.lang | 7 +- src/com/delwink/icebox/swing/MainWindow.java | 3 +- .../delwink/icebox/swing/ReportResultsDialog.java | 114 ++++++++++++++++++ .../icebox/swing/SoldVsWasteReportDialog.java | 130 +++++++++++++++++++++ 4 files changed, 252 insertions(+), 2 deletions(-) create mode 100644 src/com/delwink/icebox/swing/ReportResultsDialog.java create mode 100644 src/com/delwink/icebox/swing/SoldVsWasteReportDialog.java diff --git a/src/com/delwink/icebox/lang/en_US.lang b/src/com/delwink/icebox/lang/en_US.lang index a09571c..736e513 100644 --- a/src/com/delwink/icebox/lang/en_US.lang +++ b/src/com/delwink/icebox/lang/en_US.lang @@ -38,7 +38,12 @@ QuantityUpdate.column1=# Sold QuantityUpdate.column2=# Waste QuantityUpdate.title=New Quantity Update +Report.results=Report Results Report.soldVsWaste=Sold vs. Waste Setting.dialogTitle=Settings -Setting.setlaf=Use Native Look-And-Feel \ No newline at end of file +Setting.setlaf=Use Native Look-And-Feel + +SoldVsWaste.column0=Item +SoldVsWaste.column1=# Sold +SoldVsWaste.column2=# Waste \ No newline at end of file diff --git a/src/com/delwink/icebox/swing/MainWindow.java b/src/com/delwink/icebox/swing/MainWindow.java index b74d57a..8fe9e19 100644 --- a/src/com/delwink/icebox/swing/MainWindow.java +++ b/src/com/delwink/icebox/swing/MainWindow.java @@ -102,7 +102,8 @@ public class MainWindow extends JFrame { soldVsWaste.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { - throw new UnsupportedOperationException("Not supported yet."); + SoldVsWasteReportDialog dialog = new SoldVsWasteReportDialog(MainWindow.this, INVENTORY); + dialog.setVisible(true); } }); diff --git a/src/com/delwink/icebox/swing/ReportResultsDialog.java b/src/com/delwink/icebox/swing/ReportResultsDialog.java new file mode 100644 index 0000000..6bdd83f --- /dev/null +++ b/src/com/delwink/icebox/swing/ReportResultsDialog.java @@ -0,0 +1,114 @@ +/* + * IceBox - inventory management software for restaurants + * Copyright (C) 2016 Delwink, LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, version 3 only. + * + * 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 Affero General Public License + * along with this program. If not, see . + */ + +package com.delwink.icebox.swing; + +import com.delwink.icebox.lang.Lang; +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.List; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.table.AbstractTableModel; + +/** + * A dialog box for showing table-based report results. + * @author David McMackins II + */ +public class ReportResultsDialog extends JDialog { + private final JButton OK_BUTTON; + private final JTable TABLE; + + public ReportResultsDialog(Frame parent, Model model) { + this(parent, Lang.get("Report.results"), model); + } + + public ReportResultsDialog(Frame parent, String title, Model model) { + super(parent, title); + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + setModal(true); + + TABLE = new JTable(model); + JScrollPane tablePane = new JScrollPane(TABLE); + + OK_BUTTON = new JButton(Lang.get("ok")); + OK_BUTTON.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); + + JPanel buttonBox = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttonBox.add(OK_BUTTON); + + setLayout(new BorderLayout()); + add(tablePane, BorderLayout.CENTER); + add(buttonBox, BorderLayout.SOUTH); + + pack(); + centorOnParent(); + } + + /** + * A table model for table-based report results. + */ + public static final class Model extends AbstractTableModel { + private final List COLUMN_NAMES; + private final List> DATA; + + /** + * Creates a new model. + * @param columnNames A list of the column names. + * @param data The data of the report arranged by row and column. + */ + public Model(List columnNames, List> data) { + COLUMN_NAMES = columnNames; + DATA = data; + } + + @Override + public int getRowCount() { + return DATA.size(); + } + + @Override + public int getColumnCount() { + return COLUMN_NAMES.size(); + } + + @Override + public String getColumnName(int columnIndex) { + return COLUMN_NAMES.get(columnIndex); + } + + @Override + public Class getColumnClass(int columnIndex) { + return (DATA.isEmpty() || DATA.get(0).isEmpty()) ? String.class : DATA.get(0).get(columnIndex).getClass(); + } + + @Override + public Object getValueAt(int row, int col) { + return DATA.get(row).get(col); + } + } +} diff --git a/src/com/delwink/icebox/swing/SoldVsWasteReportDialog.java b/src/com/delwink/icebox/swing/SoldVsWasteReportDialog.java new file mode 100644 index 0000000..d3d69bf --- /dev/null +++ b/src/com/delwink/icebox/swing/SoldVsWasteReportDialog.java @@ -0,0 +1,130 @@ +/* + * IceBox - inventory management software for restaurants + * Copyright (C) 2016 Delwink, LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, version 3 only. + * + * 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 Affero General Public License + * along with this program. If not, see . + */ + +package com.delwink.icebox.swing; + +import com.delwink.icebox.Inventory; +import com.delwink.icebox.InventoryItem; +import com.delwink.icebox.QuantityUpdate; +import com.delwink.icebox.lang.Lang; +import com.github.lgooddatepicker.components.DatePicker; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JPanel; + +/** + * A dialog for building a sold versus waste report. + * @author David McMackins II + */ +public class SoldVsWasteReportDialog extends JDialog { + private final DatePicker START_DATE_FIELD, END_DATE_FIELD; + private final JButton CANCEL_BUTTON, OK_BUTTON; + + public SoldVsWasteReportDialog(final Frame parent, final Inventory inventory) { + super(parent, Lang.get("Report.soldVsWaste")); + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + setModal(true); + + START_DATE_FIELD = new DatePicker(); + START_DATE_FIELD.setDateToToday(); + + END_DATE_FIELD = new DatePicker(); + END_DATE_FIELD.setDateToToday(); + + CANCEL_BUTTON = new JButton(Lang.get("cancel")); + CANCEL_BUTTON.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); + + OK_BUTTON = new JButton(Lang.get("ok")); + OK_BUTTON.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Map items = new HashMap<>(); + for (QuantityUpdate update : inventory.getUpdates()) { + long start = START_DATE_FIELD.getDate().toEpochDay(); + long end = END_DATE_FIELD.getDate().toEpochDay(); + long actual = update.getDate().getTime() / (3600 * 24 * 1000); + + if (actual >= start && actual <= end) { + for (QuantityUpdate.Record record : update) { + if (!items.containsKey(record.getItemID())) + items.put(record.getItemID(), new Integer[] { 0, 0 }); + + Integer[] value = items.get(record.getItemID()); + value[0] += record.getSold(); + value[1] += record.getWaste(); + + items.put(record.getItemID(), value); + } + } + } + + Map sortedItems = new TreeMap<>(); + for (Integer id : items.keySet()) { + String name = inventory.getItemByID(id).getName(); + if (sortedItems.containsKey(name)) + name += " (id=" + id + ")"; + + sortedItems.put(name, items.get(id)); + } + + List columns = new ArrayList<>(); + for (int i = 0; i < 3; ++i) + columns.add(Lang.get("SoldVsWaste.column" + i)); + + List> data = new ArrayList<>(); + for (String name : sortedItems.keySet()) { + List line = new ArrayList<>(); + line.add(name); + line.addAll(Arrays.asList(sortedItems.get(name))); + + data.add(line); + } + + ReportResultsDialog dialog = new ReportResultsDialog(parent, new ReportResultsDialog.Model(columns, data)); + setVisible(false); + dialog.setVisible(true); + } + }); + + JPanel buttonBox = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttonBox.add(CANCEL_BUTTON); + buttonBox.add(OK_BUTTON); + + setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); + add(START_DATE_FIELD); + add(END_DATE_FIELD); + add(buttonBox); + + pack(); + centorOnParent(); + } +} -- cgit v1.2.3