#include <TimeStamp>
+#include <Zip>
+
#include "MTGetOrder"
#include "MTGetOrderList"
#include "MTGetMyOrders"
#include <QComboBox>
#include <QDateTimeEdit>
#include <QDebug>
+#include <QDomDocument>
+#include <QDomElement>
#include <QFormLayout>
#include <QInputDialog>
#include <QLabel>
#include <QSpinBox>
#include <QStandardItemModel>
#include <QTableView>
+#include <QFileDialog>
#define ORDERNONE 0
#define ORDERALL 0xff
return QDateTime::currentDateTime().toTime_t() - (d*86400);
}
-MOrdersReport::MOrdersReport(const QList< MOOrderInfo >& orders, QWidget* parent, Qt::WindowFlags f)
- : QDialog(parent, f)
+MOrdersReport::MOrdersReport(const QList< MOOrderInfo >& aorders, QWidget* parent, Qt::WindowFlags f)
+ : QDialog(parent, f), orders(aorders)
{
setSizeGripEnabled(true);
setWindowTitle(tr("Order Report"));
setLayout(vl=new QVBoxLayout);
vl->addWidget(tab=new QTabWidget,1);
- QTableView*stable,*otable,*dtable;
//tab: sums ( #orders, # tickets, #vouchers, $money, $paid, $for tickets, ...)
tab->addTab(stable=new QTableView,tr("Sums"));
otable->setEditTriggers(QAbstractItemView::NoEditTriggers);
otable->setSelectionMode(QAbstractItemView::NoSelection);
byord->setHorizontalHeaderLabels(QStringList()
- <<tr("Order ID")<<tr("Number Tickets")<<tr("Number Vouchers")
+ <<tr("Order ID")<<tr("State")<<tr("Number Tickets")<<tr("Number Vouchers")
<<tr("Price")<<tr("Paid")<<tr("Due") );
//tab: by day
<<tr("Number Orders")<<tr("Number Tickets")<<tr("Number Vouchers")
<<tr("Price")<<tr("Paid")<<tr("Due") );
- qDebug()<<"reporting on"<<orders.size()<<"orders";
+ //tab: audit
+ if(req->hasRight(req->RGetOrderAudit)){
+ tab->addTab(atable=new QTableView,tr("Financial"));
+ atable->setModel(audit=new QStandardItemModel);
+ atable->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ atable->setSelectionMode(QAbstractItemView::NoSelection);
+ audit->setHorizontalHeaderLabels(QStringList()
+ <<tr("Order ID")<<tr("Action")<<tr("User")<<tr("Date")
+ <<tr("Price")<<tr("Paid")<<tr("Due")<<tr("Moved") );
+
+ }
+
//buttons
vl->addSpacing(10);
vl->addLayout(hl=new QHBoxLayout);
hl->addStretch(1);
QPushButton*p;
+ hl->addWidget(p=new QPushButton(tr("Save as...")));
+ connect(p,SIGNAL(clicked(bool)),this,SLOT(saveAs()));
+ hl->addSpacing(15);
hl->addWidget(p=new QPushButton(tr("Close")));
connect(p,SIGNAL(clicked(bool)),this,SLOT(accept()));
+ p->setDefault(true);
//create display
+ drawAllOrders();
+ drawDayOrders();
+ drawOrderSums();
+ drawAudit();
+}
+
+void MOrdersReport::drawAllOrders()
+{
+ byord->removeRows(0,byord->rowCount());
+ for(const MOOrderInfo&ord:orders){
+ //order table
+ const int cl=byord->rowCount();
+ byord->insertRow(cl);
+ byord->setData(byord->index(cl,0),ord.orderid().value());
+ byord->setData(byord->index(cl,1),ord.orderStatusString());
+ byord->setData(byord->index(cl,2),ord.amounttickets().value());
+ byord->setData(byord->index(cl,3),ord.amountvouchers().value());
+ byord->setData(byord->index(cl,4),ord.totalPriceString());
+ byord->setData(byord->index(cl,5),ord.amountPaidString());
+ byord->setData(byord->index(cl,6),ord.amountDueString());
+ }
+ //adjust
+ otable->resizeColumnsToContents();
+
+}
+
+void MOrdersReport::drawDayOrders()
+{
QMap<QDate,QList<MOOrderInfo>>dayorders;
+ byday->removeRows(0,byday->rowCount());
+ //sort by day
+ for(const MOOrderInfo&ord:orders){
+ const QDate date=QDateTime::fromTime_t(ord.ordertime().value()).date();
+ if(!dayorders.contains(date))dayorders.insert(date,QList<MOOrderInfo>());
+ dayorders[date].append(ord);
+ }
+ //fill date tab
+ for(const QDate&date:dayorders.keys()){
+ const int cl=byday->rowCount();
+ byday->insertRow(cl);
+ byday->setData(byday->index(cl,0),date.toString());
+ const QList<MOOrderInfo>&day=dayorders[date];
+ byday->setData(byday->index(cl,1),day.size());
+ qint64 ticks=0,vous=0,money=0,paid=0,due=0;
+ for(const MOOrderInfo&ord:day){
+ ticks+=ord.amounttickets();
+ vous+=ord.amountvouchers();
+ money+=ord.totalprice();
+ paid+=ord.amountpaid();
+ due+=ord.amountdue();
+ }
+ byday->setData(byday->index(cl,2),ticks);
+ byday->setData(byday->index(cl,3),vous);
+ byday->setData(byday->index(cl,4),cent2str(money));
+ byday->setData(byday->index(cl,5),cent2str(paid));
+ byday->setData(byday->index(cl,6),cent2str(due));
+ }
+
+ dtable->resizeColumnsToContents();
+}
+
+void MOrdersReport::drawOrderSums()
+{
qint64 sumtickets=0,sumvouchers=0,summoney=0,sumpaid=0,sumdue=0,
sumreserve=0,sumreservemoney=0,sumreservetick=0,sumreservevou=0,sumreservepaid=0,sumreservedue=0,
sumcancel=0,sumcancelmoney=0,sumcanceltick=0,sumcancelvou=0,sumcancelpaid=0,sumcanceldue=0,
sumsent=0,sumsentmoney=0,sumsenttick=0,sumsentvou=0,sumsentpaid=0,sumsentdue=0,
sumplaced=0,sumplacedmoney=0,sumplacedtick=0,sumplacedvou=0,sumplacedpaid=0,sumplaceddue=0;
+ sum->removeRows(0,sum->rowCount());
for(const MOOrderInfo&ord:orders){
//total sums
summoney+=ord.totalprice();
sumplacedpaid+=ord.amountpaid();
sumplaceddue+=ord.amountdue();
}
- //order table
- const int cl=byord->rowCount();
- byord->insertRow(cl);
- byord->setData(byord->index(cl,0),ord.orderid().value());
- byord->setData(byord->index(cl,1),ord.amounttickets().value());
- byord->setData(byord->index(cl,2),ord.amountvouchers().value());
- byord->setData(byord->index(cl,3),ord.totalPriceString());
- byord->setData(byord->index(cl,4),ord.amountPaidString());
- byord->setData(byord->index(cl,5),ord.amountDueString());
- //sort by day
- const QDate date=QDateTime::fromTime_t(ord.ordertime().value()).date();
- if(!dayorders.contains(date))dayorders.insert(date,QList<MOOrderInfo>());
- dayorders[date].append(ord);
}
//fill total sum tab
auto sumline=[&](QString title,int num,qint64 tick,qint64 vou,qint64 summ,qint64 paid,qint64 due){
sumline(tr("Cancelled"), sumcancel, sumcanceltick, sumcancelvou, sumcancelmoney, sumcancelpaid, sumcanceldue);
sumline(tr("Placed"), sumplaced, sumplacedtick, sumplacedvou, sumplacedmoney, sumplacedpaid, sumplaceddue);
sumline(tr("Sent"), sumsent, sumsenttick, sumsentvou, sumsentmoney, sumsentpaid, sumsentdue);
- //fill date tab
- for(const QDate&date:dayorders.keys()){
- const int cl=byday->rowCount();
- byday->insertRow(cl);
- byday->setData(byday->index(cl,0),date.toString());
- const QList<MOOrderInfo>&day=dayorders[date];
- byday->setData(byday->index(cl,1),day.size());
- qint64 ticks=0,vous=0,money=0,paid=0,due=0;
- for(const MOOrderInfo&ord:day){
- ticks+=ord.amounttickets();
- vous+=ord.amountvouchers();
- money+=ord.totalprice();
- paid+=ord.amountpaid();
- due+=ord.amountdue();
+
+ stable->resizeColumnsToContents();
+}
+
+void MOrdersReport::drawAudit()
+{
+ if(atable==nullptr || audit==nullptr)return;
+}
+
+
+static const QByteArray odsmetainf(
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\" manifest:version=\"1.2\">\n"
+ " <manifest:file-entry manifest:full-path=\"/\" manifest:version=\"1.2\" manifest:media-type=\"application/vnd.oasis.opendocument.spreadsheet\"/>\n"
+ " <manifest:file-entry manifest:full-path=\"content.xml\" manifest:media-type=\"text/xml\"/>\n"
+ "</manifest:manifest>"
+);
+
+static inline void exportTable(QDomDocument&doc, QDomElement&sheet, QStandardItemModel*model, QString title)
+{
+ //basics
+ QDomElement table=doc.createElement("table:table");
+ table.setAttribute("table:name",title);
+ QDomElement cols=doc.createElement("table:table-column");
+ cols.setAttribute("table:number-columns-repeated",model->columnCount());
+ table.appendChild(cols);
+ //headers
+ QDomElement row=doc.createElement("table:table-row");
+ for(int c=0;c<model->columnCount();c++){
+ QDomElement cell=doc.createElement("table:table-cell");
+ cell.setAttribute("office:value-type","string");
+ QDomElement p=doc.createElement("text:p");
+ p.appendChild(doc.createTextNode(model->headerData(c,Qt::Horizontal).toString()));
+ cell.appendChild(p);
+ row.appendChild(cell);
+ }
+ table.appendChild(row);
+ //data
+ for(int r=0;r<model->rowCount();r++){
+ row=doc.createElement("table:table-row");
+ for(int c=0;c<model->columnCount();c++){
+ QDomElement cell=doc.createElement("table:table-cell");
+ cell.setAttribute("office:value-type","string");
+ QDomElement p=doc.createElement("text:p");
+ p.appendChild(doc.createTextNode(model->data(model->index(r,c)).toString()));
+ cell.appendChild(p);
+ row.appendChild(cell);
}
- byday->setData(byday->index(cl,2),ticks);
- byday->setData(byday->index(cl,3),vous);
- byday->setData(byday->index(cl,4),cent2str(money));
- byday->setData(byday->index(cl,5),cent2str(paid));
- byday->setData(byday->index(cl,6),cent2str(due));
+ table.appendChild(row);
}
- //adjust
- stable->resizeColumnsToContents();
- dtable->resizeColumnsToContents();
- otable->resizeColumnsToContents();
+ //done
+ sheet.appendChild(table);
}
void MOrdersReport::saveAs()
{
+ QFileDialog fdlg(this,tr("Save Report"));
+ fdlg.setAcceptMode(QFileDialog::AcceptSave);
+ fdlg.setDefaultSuffix("ods");
+ fdlg.setFileMode(QFileDialog::AnyFile);
+ fdlg.setDirectory(currentDir());
+ if(!fdlg.exec())return;
+ const QString fn=fdlg.selectedFiles().value(0);
+ if(fn.isEmpty())return;
+ setCurrentDir(fn);
//TODO: use template if available
+ //create file
+ QFile fd(fn);
+ if(!fd.open(QIODevice::WriteOnly|QIODevice::Truncate)){
+ QMessageBox::warning(this,tr("Warning"),tr("Unable to create file '%1'.").arg(fn));
+ return;
+ }
+ Zip zip;
+ if(!zip.open(&fd)){
+ QMessageBox::warning(this,tr("Warning"),tr("Ooops. Unable to create ZIP structure in file '%1'.").arg(fn));
+ fd.close();
+ fd.remove();
+ return;
+ }
+ //metadata
+ zip.storeFile("mimetype",QByteArray("application/vnd.oasis.opendocument.spreadsheet"));
+ zip.storeFile("META-INF/manifest.xml",odsmetainf);
+ //generate content
+ QDomDocument doc;
+ QDomElement root=doc.createElement("office:document-content");
+ root.setAttribute("xmlns:office","urn:oasis:names:tc:opendocument:xmlns:office:1.0"); root.setAttribute("xmlns:text","urn:oasis:names:tc:opendocument:xmlns:text:1.0"); root.setAttribute("xmlns:table","urn:oasis:names:tc:opendocument:xmlns:table:1.0");
+ root.setAttribute("office:version","1.2");
+ QDomElement body=doc.createElement("office:body");
+ QDomElement sheet=doc.createElement("office:spreadsheet");
+ exportTable(doc,sheet,sum,tr("Sums"));
+ exportTable(doc,sheet,byord,tr("Orders"));
+ exportTable(doc,sheet,byday,tr("By Day"));
+ if(audit)
+ exportTable(doc,sheet,audit,tr("Financial"));
+ body.appendChild(sheet);
+ root.appendChild(body);
+ doc.appendChild(root);
+ //store
+ zip.storeFile("content.xml",doc.toByteArray());
+ zip.close();
+ fd.close();
}