Loops cannot be nested.
+<h3>Calculations</h3>
+
+Numeric variables allow some very simple calculations:
+
+<pre>
+@VARONE+11@
+@VARTWO-77@
+</pre>
+
+In the above example the first line will be replaced by the amount of VARONE plus 11 and the second line by the amount of VARTWO minus 77.<p>
+
+For integer variables this works on the plain integer value. For money values it adds/subtracts cents.
+
<hr/>
<h2>Event Summary</h2>
File name: <tt>bill.odtt</tt><p>
-Loop: <tt>TICKETS</tt> - this loop iterates over each ticket in the order.<p>
+Loops: <br>
+<tt>TICKETS</tt> - this loop iterates over each ticket in the order.<br>
+<tt>ADDRESSLINES</tt> - this loop iterates over the lines of the address.<p>
(TODO: loop for vouchers)<p>
<tr><td>@CUSTOMERID@</td><td>the ID of the customer</td></tr>
<tr><td>@ORDERID@</td><td>the ID of the order</td></tr>
<tr><td>@ADDRESS@</td><td>the address of the customer</td></tr>
+<tr><td>@FULLADDRESS@</td><td>the name and address of the customer</td></tr>
+<tr><td>@NAME@</td><td>the name of the customer</td></tr>
<tr><td>@DELIVERYADDRESS@</td><td>the address it is shipped to, if different from the customers address</td></tr>
<tr><td>@TOTALPRICE@</td><td>the total price of the order</td></tr>
<tr><td>@AMOUNTPAID@</td><td>the amount that has already been paid</td></tr>
<tr><td>@TICKETS:STARTTIME@</td><td>the date and start time of the event for this ticket</td></tr>
<tr><td>@TICKETS:ENDTIME@</td><td>the end date and time of the event for this ticket</td></tr>
<tr><td>@TICKETS:ROOM@</td><td>the room/place of the event for this ticket</td></tr>
+<tr><td>@ADDRESSLINES@</td><td>amount of lines that the address has</td></tr>
+<tr><td>@ADDRESSLINES:LINE@</td><td>current line in the address loop</td></tr>
</table>
return;
}
MOdtSignalRenderer rend(tf);
- connect(&rend,SIGNAL(getVariable(QString,QString&)),this,SLOT(getVariable(QString,QString&)));
+ connect(&rend,SIGNAL(getVariable(QString,int,QString&)),this,SLOT(getVariable(QString,int,QString&)));
connect(&rend,SIGNAL(getLoopIterations(QString,int&)),this,SLOT(getLoopIterations(QString,int&)));
- connect(&rend,SIGNAL(getLoopVariable(QString,int,QString,QString&)),this,SLOT(getLoopVariable(QString,int,QString,QString&)));
+ connect(&rend,SIGNAL(getLoopVariable(QString,int,QString,int,QString&)),this,SLOT(getLoopVariable(QString,int,QString,int,QString&)));
rend.renderToPrinter();
}
fname=fn[0];
}
MOdtSignalRenderer rend(tf);
- connect(&rend,SIGNAL(getVariable(QString,QString&)),this,SLOT(getVariable(QString,QString&)));
+ connect(&rend,SIGNAL(getVariable(QString,int,QString&)),this,SLOT(getVariable(QString,int,QString&)));
connect(&rend,SIGNAL(getLoopIterations(QString,int&)),this,SLOT(getLoopIterations(QString,int&)));
- connect(&rend,SIGNAL(getLoopVariable(QString,int,QString,QString&)),this,SLOT(getLoopVariable(QString,int,QString,QString&)));
+ connect(&rend,SIGNAL(getLoopVariable(QString,int,QString,int,QString&)),this,SLOT(getLoopVariable(QString,int,QString,int,QString&)));
rend.renderToFile(fname);
}
-void MEventSummary::getVariable(QString varname,QString&value)
+void MEventSummary::getVariable(QString varname,int av,QString&value)
{
if(varname=="TITLE")
value=title;
value=QDateTime::fromTime_t(starttime).toString(tr("yyyy-MM-dd hh:mm ap","Date+Time format for displaying event start time"));
else
if(varname=="CAPACITY")
- value=QString::number(capacity);
+ value=QString::number(capacity+av);
else
if(varname=="RESERVED")
- value=QString::number(nreserved);
+ value=QString::number(nreserved+av);
else
if(varname=="BOUGHT")
- value=QString::number(ntotaltickets);
+ value=QString::number(ntotaltickets+av);
else
if(varname=="USED"){
int nused=0;
for(int i=0;i<tickets.size();i++)nused+=tickets[i].used;
- value=QString::number(nused);
+ value=QString::number(nused+av);
}else
if(varname=="UNUSED"){
int nunused=0;
for(int i=0;i<tickets.size();i++)nunused+=tickets[i].unused;
- value=QString::number(nunused);
+ value=QString::number(nunused+av);
}else
if(varname=="CANCELLED")
- value=QString::number(ncancelled);
+ value=QString::number(ncancelled+av);
else
- if(varname=="TOTALMONEY")
- value=QString::number(ntotalmoney/100)
+ if(varname=="TOTALMONEY"){
+ int ntm=ntotalmoney+av;
+ value=QString::number(ntm/100)
+tr(".","decimal dot")
- +QString().sprintf("%02d",ntotalmoney%100);
- else
+ +QString().sprintf("%02d",ntm%100);
+ }else
if(varname=="TICKETS")
- value=QString::number(tickets.size());
+ value=QString::number(tickets.size()+av);
}
void MEventSummary::getLoopIterations(QString loopname,int&iterations)
if(loopname=="TICKETS")iterations=tickets.size();
}
-void MEventSummary::getLoopVariable(QString loopname,int iteration,QString varname,QString&value)
+void MEventSummary::getLoopVariable(QString loopname,int iteration,QString varname,int av,QString&value)
{
if(loopname!="TICKETS")return;
if(iteration<0 || iteration>=tickets.size())return;
if(varname=="PRICE"){
- int p=tickets[iteration].price;
+ int p=tickets[iteration].price+av;
value=QString::number(p/100)
+tr(".","decimal dot")
+QString().sprintf("%02d",p%100);
}else
- if(varname=="BOUGHT")value=QString::number(tickets[iteration].bought);else
- if(varname=="USED")value=QString::number(tickets[iteration].used);else
- if(varname=="UNUSED")value=QString::number(tickets[iteration].unused);
+ if(varname=="BOUGHT")value=QString::number(tickets[iteration].bought+av);else
+ if(varname=="USED")value=QString::number(tickets[iteration].used+av);else
+ if(varname=="UNUSED")value=QString::number(tickets[iteration].unused+av);
}
void saveas();
//used for ODT rendering:
- void getVariable(QString varname,QString&value);
+ void getVariable(QString varname,int,QString&value);
void getLoopIterations(QString loopname,int&iterations);
- void getLoopVariable(QString loopname,int iteration,QString varname,QString&value);
+ void getLoopVariable(QString loopname,int iteration,QString varname,int,QString&value);
private:
MWebRequest*req;
QString render(QString);
QString renderLine(QString,QString,int);
+ QString getVariable(QString varname);
+ QString getLoopVariable(QString loopname,int iteration,QString varname);
+
private:
MOdtRenderer*parent;
QUnZip temp;
{
QString ret,vname;
bool isvar=false;
- static QString vc="ABCDEFGHIJKLMNOPQRSTUVWXYZ:";
+ static QString vc="ABCDEFGHIJKLMNOPQRSTUVWXYZ:+-0123456789";
//scan characters
for(int i=0;i<line.size();i++){
//are we currently inside a variable name?
//or any loop at all...
if(loop!="" && loop==vl[0]){
//get value
- ret+=parent->getLoopVariable(loop,lpos,vl[1]);
+ ret+=getLoopVariable(loop,lpos,vl[1]);
}
}else
//this is a normal variable, get valie
- ret+=parent->getVariable(vname);
+ ret+=getVariable(vname);
}
//reset mode
isvar=false;
return ret;
}
+QString MOdtRendererPrivate::getVariable(QString varname)
+{
+ int p=varname.indexOf('+');
+ if(p>0)
+ return parent->getVariable(varname.left(p),varname.mid(p+1).toInt());
+ p=varname.indexOf('-');
+ if(p>0)
+ return parent->getVariable(varname.left(p),varname.mid(p).toInt());
+ return parent->getVariable(varname,0);
+}
+
+QString MOdtRendererPrivate::getLoopVariable(QString loopname,int iteration,QString varname)
+{
+ int p=varname.indexOf('+');
+ if(p>0)
+ return parent->getLoopVariable(loopname,iteration,varname.left(p),varname.mid(p+1).toInt());
+ p=varname.indexOf('-');
+ if(p>0)
+ return parent->getLoopVariable(loopname,iteration,varname.left(p),varname.mid(p).toInt());
+ return parent->getLoopVariable(loopname,iteration,varname,0);
+}
+
+
/********************************************************************/
MOdtSignalRenderer::MOdtSignalRenderer(QString file)
MOdtSignalRenderer::~MOdtSignalRenderer(){}
-QString MOdtSignalRenderer::getVariable(QString varname)
+QString MOdtSignalRenderer::getVariable(QString varname,int av)
{
QString ret;
- emit getVariable(varname,ret);
+ emit getVariable(varname,av,ret);
return ret;
}
return ret;
}
-QString MOdtSignalRenderer::getLoopVariable(QString loopname,int iteration,QString varname)
+QString MOdtSignalRenderer::getLoopVariable(QString loopname,int iteration,QString varname,int av)
{
QString ret;
- emit getLoopVariable(loopname,iteration,varname,ret);
+ emit getLoopVariable(loopname,iteration,varname,av,ret);
return ret;
}
protected:
friend class MOdtRendererPrivate;
/**implement this to return the value of a variable during rendering; should return empty string if the variable does not exist*/
- virtual QString getVariable(QString varname)=0;
+ virtual QString getVariable(QString varname,int addval)=0;
/**implement this to return the amount of iterations for a defined loop; should return 0 if the loop does not exist*/
virtual int getLoopIterations(QString loopname)=0;
/**implement this to return a specific instance of a loop internal variable; should return empty string if the request is not valid*/
- virtual QString getLoopVariable(QString loopname,int iteration,QString varname)=0;
+ virtual QString getLoopVariable(QString loopname,int iteration,QString varname,int addval)=0;
private:
MOdtRendererPrivate*d;
static QString officepath;
signals:
/**connect this to return the value of a variable during rendering; should return empty string if the variable does not exist*/
- void getVariable(QString varname,QString&value);
+ void getVariable(QString varname,int addval,QString&value);
/**connect this to return the amount of iterations for a defined loop; should return 0 if the loop does not exist*/
void getLoopIterations(QString loopname,int&iterations);
/**connect this to return a specific instance of a loop internal variable; should return empty string if the request is not valid*/
- void getLoopVariable(QString loopname,int iteration,QString varname,QString&value);
+ void getLoopVariable(QString loopname,int iteration,QString varname,int addval,QString&value);
protected:
- QString getVariable(QString varname);
+ QString getVariable(QString varname,int addval);
int getLoopIterations(QString loopname);
- QString getLoopVariable(QString loopname,int iteration,QString varname);
+ QString getLoopVariable(QString loopname,int iteration,QString varname,int addval);
};
#endif
return m_price;
}
-QString MOrder::totalPriceString()const
+QString MOrder::totalPriceString(int off)const
{
- return cent2string(m_price);
+ return cent2string(m_price+off);
}
int MOrder::amountPaid()const
return m_paid;
}
-QString MOrder::amountPaidString()const
+QString MOrder::amountPaidString(int off)const
{
- return cent2string(m_paid);
+ return cent2string(m_paid+off);
}
//static
return 0;
}
-QString MOrder::amountToPayStr()const
+QString MOrder::amountToPayStr(int off)const
{
- return cent2string(amountToPay());
+ return cent2string(amountToPay()+off);
}
-QString MOrder::amountToRefundStr()const
+QString MOrder::amountToRefundStr(int off)const
{
- return cent2string(amountToRefund());
+ return cent2string(amountToRefund()+off);
}
bool MOrder::isSent()const
return m_price;
}
-QString MTicket::priceString()const
+QString MTicket::priceString(int off)const
{
- return QString::number(m_price/100)+QCoreApplication::translate("MTicket",".","decimal dot")+QString().sprintf("%02d",m_price%100);
+ int mp=m_price+off;
+ return QString::number(mp/100)+QCoreApplication::translate("MTicket",".","decimal dot")+QString().sprintf("%02d",mp%100);
}
qint32 MTicket::eventID()const
int price()const;
/**returns the price of the ticket as localized string*/
- QString priceString()const;
+ QString priceString(int offsetvalue=0)const;
/**returns the amount that is to be paid for this ticket; this is identical to the price if the ticket is bought or used, it is zero otherwise*/
int amountToPay()const;
int totalPrice()const;
/**returns how much money needs to be paid in total for this order, in cents*/
- QString totalPriceString()const;
+ QString totalPriceString(int offsetvalue=0)const;
/**returns how much money has already been paid for this order, in cents*/
int amountPaid()const;
/**returns how much money has already been paid for this order, in cents*/
- QString amountPaidString()const;
+ QString amountPaidString(int offsetvalue=0)const;
/**returns whether there is anything left to pay*/
bool needsPayment()const;
int amountToPay()const;
/**returns how much there is to be paid, as localized string*/
- QString amountToPayStr()const;
+ QString amountToPayStr(int offsetvalue=0)const;
/**returns how much there is to be refunded, in cents*/
int amountToRefund()const;
/**returns how much there is to be refunded, as localized string*/
- QString amountToRefundStr()const;
+ QString amountToRefundStr(int offsetvalue=0)const;
/**returns whether the tickets of this order have already been shipped*/
bool isSent()const;
}
//print bill
MOdtSignalRenderer rend(tf);
- connect(&rend,SIGNAL(getVariable(QString,QString&)),this,SLOT(getVariable(QString,QString&)));
+ connect(&rend,SIGNAL(getVariable(QString,int,QString&)),this,SLOT(getVariable(QString,int,QString&)));
connect(&rend,SIGNAL(getLoopIterations(QString,int&)),this,SLOT(getLoopIterations(QString,int&)));
- connect(&rend,SIGNAL(getLoopVariable(QString,int,QString,QString&)),this,SLOT(getLoopVariable(QString,int,QString,QString&)));
+ connect(&rend,SIGNAL(getLoopVariable(QString,int,QString,int,QString&)),this,SLOT(getLoopVariable(QString,int,QString,int,QString&)));
rend.renderToPrinter();
}
void MOrderWindow::saveBill()
{
//get template
- QString tf=req->getTemplate("eventsummary.odtt");
+ QString tf=req->getTemplate("bill.odtt");
if(tf==""){
QMessageBox::warning(this,tr("Warning"),tr("Unable to get template file (eventsummary.odtt). Giving up."));
return;
}
//render bill
MOdtSignalRenderer rend(tf);
- connect(&rend,SIGNAL(getVariable(QString,QString&)),this,SLOT(getVariable(QString,QString&)));
+ connect(&rend,SIGNAL(getVariable(QString,int,QString&)),this,SLOT(getVariable(QString,int,QString&)));
connect(&rend,SIGNAL(getLoopIterations(QString,int&)),this,SLOT(getLoopIterations(QString,int&)));
- connect(&rend,SIGNAL(getLoopVariable(QString,int,QString,QString&)),this,SLOT(getLoopVariable(QString,int,QString,QString&)));
+ connect(&rend,SIGNAL(getLoopVariable(QString,int,QString,int,QString&)),this,SLOT(getLoopVariable(QString,int,QString,int,QString&)));
rend.renderToFile(fname);
}
-void MOrderWindow::getVariable(QString vn,QString&value)
+void MOrderWindow::getVariable(QString vn,int av,QString&value)
{
if(vn=="ORDERDATE")value=m_order.orderDateStr();else
if(vn=="ORDERDATETIME")value=m_order.orderDateTimeStr();else
if(vn=="CUSTOMERID")value=QString::number(m_order.customerID());else
if(vn=="ORDERID")value=QString::number(m_order.orderID());else
if(vn=="ADDRESS")value=m_order.customer().address();else
+ if(vn=="FULLADDRESS")value=m_order.customer().getNameAddress();else
+ if(vn=="NAME")value=m_order.customer().name();else
if(vn=="DELIVERYADDRESS")value=m_order.deliveryAddress();else
- if(vn=="TOTALPRICE")value=m_order.totalPriceString();else
- if(vn=="AMOUNTPAID")value=m_order.amountPaidString();else
+ if(vn=="TOTALPRICE")value=m_order.totalPriceString(av);else
+ if(vn=="AMOUNTPAID")value=m_order.amountPaidString(av);else
if(vn=="SELLER")value=m_order.seller();else
if(vn=="COMMENT")value=m_order.comment();else
- if(vn=="AMOUNTTOPAY")value=m_order.amountToPayStr();else
- if(vn=="AMOUNTTOREFUND")value=m_order.amountToRefundStr();else
- if(vn=="TICKETS")value=QString::number(m_ticketmodel->rowCount());
+ if(vn=="AMOUNTTOPAY")value=m_order.amountToPayStr(av);else
+ if(vn=="AMOUNTTOREFUND")value=m_order.amountToRefundStr(av);else
+ if(vn=="TICKETS")value=QString::number(m_ticketmodel->rowCount()+av);
+ if(vn=="ADDRESSLINES")value=QString::number(m_order.customer().address().split("\n").size()+av);
}
void MOrderWindow::getLoopIterations(QString loopname,int&iterations)
{
if(loopname=="TICKETS")iterations=m_ticketmodel->rowCount();
+ if(loopname=="ADDRESSLINES")iterations=m_order.customer().address().split("\n").size();
}
-void MOrderWindow::getLoopVariable(QString loopname,int it,QString vn,QString&value)
+void MOrderWindow::getLoopVariable(QString loopname,int it,QString vn,int av,QString&value)
{
- if(loopname!="TICKETS")return;
- if(it<0 || it>=m_ticketmodel->rowCount())return;
-
- QList<MTicket>tickets=m_order.tickets();
-
- if(vn=="PRICE")value=tickets[it].priceString();else
- if(vn=="ID")value=tickets[it].ticketID();else
- if(vn=="TITLE")value=tickets[it].event().title();else
- if(vn=="ARTIST")value=tickets[it].event().artist();else
- if(vn=="DATE")value=tickets[it].event().startDateString();else
- if(vn=="STARTTIME")value=tickets[it].event().startTimeString();else
- if(vn=="ENDTIME")value=tickets[it].event().endTimeString();else
- if(vn=="ROOM")value=tickets[it].event().room();
+ if(loopname=="TICKETS"){
+ if(it<0 || it>=m_ticketmodel->rowCount())return;
+
+ QList<MTicket>tickets=m_order.tickets();
+
+ if(vn=="PRICE")value=tickets[it].priceString(av);else
+ if(vn=="ID")value=tickets[it].ticketID();else
+ if(vn=="TITLE")value=tickets[it].event().title();else
+ if(vn=="ARTIST")value=tickets[it].event().artist();else
+ if(vn=="DATE")value=tickets[it].event().startDateString();else
+ if(vn=="STARTTIME")value=tickets[it].event().startTimeString();else
+ if(vn=="ENDTIME")value=tickets[it].event().endTimeString();else
+ if(vn=="ROOM")value=tickets[it].event().room();
+ }else if(loopname=="ADDRESSLINES"){
+ QStringList lst=m_order.customer().address().split("\n");
+ if(it<0 || it>=lst.size())return;
+ value=lst[it];
+ }else
+ return /*empty handed*/;
}
void MOrderWindow::payment()
/**save the bill as file*/
void saveBill();
/**callback for bill generator: variables; see MOdtSignalRenderer for details*/
- void getVariable(QString varname,QString&value);
+ void getVariable(QString varname,int,QString&value);
/**callback for bill generator: loops; see MOdtSignalRenderer for details*/
void getLoopIterations(QString loopname,int&iterations);
/**callback for bill generator: loop variables; see MOdtSignalRenderer for details*/
- void getLoopVariable(QString loopname,int iteration,QString varname,QString&value);
+ void getLoopVariable(QString loopname,int iteration,QString varname,int,QString&value);
/**received payment*/
void payment();