Print Invoices in Code
Print Invoices in Code
Is it possible to print a range of Invoices in code?
I would supply the range of OrderID's (through my own SQL query)
and would want to print the Invoices in that range.
Can this be done?
I would supply the range of OrderID's (through my own SQL query)
and would want to print the Invoices in that range.
Can this be done?
Re: Print Invoices in Code
You can write your custom component that queries the database for range of order ids and then formats the data in desired printing format. AbleCommerce do support out of the box invoice printing for multiple orders. All you need is to select desired orders on order manager and then trigger print invoice command from bottom drop down.
Re: Print Invoices in Code
>> You can write your custom component that queries the database for range of order ids and then formats the data in desired printing format.
Do I need the source code to do this?
Do I need the source code to do this?
Re: Print Invoices in Code
No there is no need of source code. You can read about custom queries and data access layer from here
http://wiki.ablecommerce.com/index.php/ ... uilder_API
You can query database via some custom queries for those orders and then format the fetched data according to your needs.
http://wiki.ablecommerce.com/index.php/ ... uilder_API
You can query database via some custom queries for those orders and then format the fetched data according to your needs.
Re: Print Invoices in Code
thanks Mazhar, . . I'm really not sure on how to use the data access layer yet,
but is the idea along these lines:
CommerceBuilder.Data.Database database = Token.Instance.Database;
string sql = ("SELECT ..........");
............
Here is what I want to do:
I added a "dateOrd" field to the ac_Orders table.
I want to select all OrderID's for the current day:
SELECT OrderID
FROM ac_Orders
WHERE dateOrd = getdate()
Then I want to print those Invoices - directly to the printer,
and not to the "printable stylesheet" first.
but is the idea along these lines:
CommerceBuilder.Data.Database database = Token.Instance.Database;
string sql = ("SELECT ..........");
............
Here is what I want to do:
I added a "dateOrd" field to the ac_Orders table.
I want to select all OrderID's for the current day:
SELECT OrderID
FROM ac_Orders
WHERE dateOrd = getdate()
Then I want to print those Invoices - directly to the printer,
and not to the "printable stylesheet" first.
Re: Print Invoices in Code
You can try following code snippet to find all order falling in current dateI'm really not sure on how to use the data access layer yet,
but is the idea along these lines:
CommerceBuilder.Data.Database database = Token.Instance.Database;
string sql = ("SELECT ..........");
............
Here is what I want to do:
I added a "dateOrd" field to the ac_Orders table.
I want to select all OrderID's for the current day:
SELECT OrderID
FROM ac_Orders
WHERE dateOrd = getdate()
Code: Select all
DateTime now = LocaleHelper.LocalNow;
DateTime startDate = new DateTime(now.Year,now.Month,now.Day,0,0,0);
DateTime endDate = new DateTime(now.Year,now.Month,now.Day,23,59,59);
OrderCollection orders = OrderDataSource.LoadForCriteria(string.Format(" OrderDate >= '{0}' AND OrderDate <= '{1}' ",startDate,endDate));
//you custom processing here
Re: Print Invoices in Code
Not sure, but I think I could be looking at an easier way of doing this: Invoices.aspx page
When you select a number of Order#'s and then select "Print Invoice", Go,
it displays all the printable style sheets for those orders:
localhost/SuperVits/Admin/Orders/Print/Invoices.aspx?orders=32,31,30 << OrderID's
then you click "Print" and it prints them.
I could probably modify this code to use my range of OrderID's, but because
I might have over 100 orders to print, this might crash the brower.
If there was some way I could avoid displaying the orders and just send them to the printer.
The "Print" button uses "window.print()" to send them to the printer:
<asp:Button ID="Print" runat="server" Text="Print" OnClientClick="window.print();return false;" />
so I guess the Invoices need to be displayed in the window first.
If I could setup a Loop that:
Displays One Invoice, Prints it, removes/clears that Invoice from screen,
Displays Next Invoice, Prints it, removes/clears that Invoice from screen,
repeats .......
I have to begin experimenting. Any assistence apprecitated.
When you select a number of Order#'s and then select "Print Invoice", Go,
it displays all the printable style sheets for those orders:
localhost/SuperVits/Admin/Orders/Print/Invoices.aspx?orders=32,31,30 << OrderID's
then you click "Print" and it prints them.
I could probably modify this code to use my range of OrderID's, but because
I might have over 100 orders to print, this might crash the brower.
If there was some way I could avoid displaying the orders and just send them to the printer.
The "Print" button uses "window.print()" to send them to the printer:
<asp:Button ID="Print" runat="server" Text="Print" OnClientClick="window.print();return false;" />
so I guess the Invoices need to be displayed in the window first.
If I could setup a Loop that:
Displays One Invoice, Prints it, removes/clears that Invoice from screen,
Displays Next Invoice, Prints it, removes/clears that Invoice from screen,
repeats .......
I have to begin experimenting. Any assistence apprecitated.
Re: Print Invoices in Code
Don't know if this will eventually be possible, but I got another step further.
I was able to pass my OrderID's in and loop through the Invoices one by one:
protected void Page_Load(object sender, EventArgs e)
{
string query = "SELECT OrderID FROM ac_Orders WHERE ......";
Microsoft.Practices.EnterpriseLibrary.Data.Database database = Token.Instance.Database;
System.Data.Common.DbCommand selectCommand = database.GetSqlStringCommand(query);
System.Data.SqlClient.SqlDataReader dr = database.ExecuteReader(selectCommand);
while (dr.Read())
{
OrderRepeater.DataSource = GetOrders(Convert.ToInt32(dr["OrderID"]));
OrderRepeater.DataBind();
******** NEED SOME WAY TO PRINT EACH INVOICE HERE *************
}
dr.Close();
I commented out:
//private List<int> GetSelectedOrders()
//string orderIdList = Request.QueryString["orders"];
//private string GetOrderNumbers(List<int> orders)
I added at the bottom of the page:
........
<script language="javascript">
window.print();
</script>
</asp:Content>
But it will only print the last Invoice from the Loop that was displayed on the screen.
I know you can't call Client scripts (like window.print()) because of security reasons.
Is there a third party or ActiveX control that will let me print to the printer from code?
I was able to pass my OrderID's in and loop through the Invoices one by one:
protected void Page_Load(object sender, EventArgs e)
{
string query = "SELECT OrderID FROM ac_Orders WHERE ......";
Microsoft.Practices.EnterpriseLibrary.Data.Database database = Token.Instance.Database;
System.Data.Common.DbCommand selectCommand = database.GetSqlStringCommand(query);
System.Data.SqlClient.SqlDataReader dr = database.ExecuteReader(selectCommand);
while (dr.Read())
{
OrderRepeater.DataSource = GetOrders(Convert.ToInt32(dr["OrderID"]));
OrderRepeater.DataBind();
******** NEED SOME WAY TO PRINT EACH INVOICE HERE *************
}
dr.Close();
I commented out:
//private List<int> GetSelectedOrders()
//string orderIdList = Request.QueryString["orders"];
//private string GetOrderNumbers(List<int> orders)
I added at the bottom of the page:
........
<script language="javascript">
window.print();
</script>
</asp:Content>
But it will only print the last Invoice from the Loop that was displayed on the screen.
I know you can't call Client scripts (like window.print()) because of security reasons.
Is there a third party or ActiveX control that will let me print to the printer from code?
- Logan Rhodehamel
- Developer
- Posts: 4116
- Joined: Wed Dec 10, 2003 5:26 pm
Re: Print Invoices in Code
The order invoices are mostly text styled by css... not a lot of images or a fantastic amount of data. Have you tried seeing whether the default invoices page would load with 100 orders? You might be surprised. Also, if there are issues of timeout there are ways of adjusting this.
I am not aware of a way to send output directly to a printer. Another possibility might be to build a file suitable for printing. Prior to working with printable stylesheets, the original intent for the invoices page was to build a file using RTF format. RTF is text based, can have formatting codes, and can be opened with a wide variety of applications.
So you could do something like
open temporary rtf file
Load list of orders
for each order
write order invoice data to temp rtf file + page break
loop
close temporary rtf file
show link to download temp file
I am not aware of a way to send output directly to a printer. Another possibility might be to build a file suitable for printing. Prior to working with printable stylesheets, the original intent for the invoices page was to build a file using RTF format. RTF is text based, can have formatting codes, and can be opened with a wide variety of applications.
So you could do something like
open temporary rtf file
Load list of orders
for each order
write order invoice data to temp rtf file + page break
loop
close temporary rtf file
show link to download temp file
Cheers,
Logan
.com
If I do not respond to an unsolicited private message, it's not because I'm ignoring you. It's because the answer to your question is valuable to others. Try the new topic button.
Logan

If I do not respond to an unsolicited private message, it's not because I'm ignoring you. It's because the answer to your question is valuable to others. Try the new topic button.
Re: Print Invoices in Code
>> Have you tried seeing whether the default invoices page would load with 100 orders?
Yes, I did actually: The size of the file to print was 22.7 MB.
It took about 20 seconds to load them in the browser. I did not print them though.
But the ViewState was HUGE.
Question: Can I disable the ViewState in this Repeater: <asp:Repeater ID="OrderRepeater"> without causing the code not to function correctly?
What I decided to do was print the Invoices in batches of 70:
70 Invoices will be display in the browser, user clicks "Print",
user clicks another button to get next 70, . . . repeat until no more.
This is the code I came up with to do that:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Request.QueryString["orders"] == "Start")
{
pnlVendorList.Visible = true; // displays buttons to run the Invoice batches
return;
}
else
{
pnlVendorList.Visible = false;
List<int> selectedOrders2 = GetSelectedOrders();
DisplayInvoices(selectedOrders2);
}
}
private void DisplayInvoices(List<int> selectedOrders2)
{
List<int> selectedOrders = selectedOrders2;
if ((selectedOrders == null) || (selectedOrders.Count == 0)) Response.Redirect("~/Admin/Orders/Default.aspx");
OrderRepeater.DataSource = GetOrders(selectedOrders.ToArray());
OrderRepeater.DataBind();
OrderList.Text = GetOrderNumbers(selectedOrders);
}
// This is run first:
protected void VendorRun_Click(object sender, EventArgs e)
{
string query = "UPDATE ac_Orders Set ord = 1 WHERE . .";
int result = (int)database.ExecuteNonQuery(updateCommand);
List<int> selectedOrders2 = GetSelectedOrders();
DisplayInvoices(selectedOrders2);
btnVendorRun.Enabled = false;
if (moreInvoices)
{
btnNextBatch.Visible = true;
lblMsg.Text = "More Invoices after this . . . ";
}
else
{
lblMsg.Text = "Vendor Update Done - No more Invoices;
}
}
protected void NextBatch_Click(object sender, EventArgs e)
{
List<int> selectedOrders2 = GetSelectedOrders();
DisplayInvoices(selectedOrders2);
if (moreInvoices)
{
btnNextBatch.Visible = true;
lblMsg.Text = "More Invoices after this . . . ";
}
else
{
btnNextBatch.Visible = false;
lblMsg.Text = "Click Print now. This is your LAST BATCH.;
}
}
private List<int> GetSelectedOrders()
{
string orderIdList = string.Empty;
Int16 counter = 1;
//CHECK FOR QUERYSTRING PARAMETERS
List<int> selectedOrders = new List<int>();
if (Request.QueryString["orders"] == "Start")
{
System.Data.SqlClient.SqlDataReader dr = GetInvoices();
lastCountNum = (lastCountNum - 1);
if (moreInvoices)
{
while (dr.Read())
{
if ((counter == (lastCountNum)))
{
counter++;
break;
}
counter++;
}
lastCountNum = (lastCountNum + 70);
while (dr.Read())
{
if (counter > lastCountNum)
{
dr.Close();
lastCountNum = counter;
moreInvoices = true;
return selectedOrders;
}
selectedOrders.Add(Convert.ToInt32(dr["OrderID"]));
counter++;
}
moreInvoices = false;
dr.Close();
return selectedOrders;
}
while (dr.Read())
{
if (counter > 70)
{
lastCountNum = counter;
moreInvoices = true;
totalCount = counter;
while (dr.Read())
{
totalCount++;
}
dr.Close();
MP3.Text = "Total Count = " + totalCount; // total invoices from DataReader
return selectedOrders;
}
selectedOrders.Add(Convert.ToInt32(dr["OrderID"]));
counter++;
}
dr.Close();
return selectedOrders;
}
else
{
orderIdList = Request.QueryString["orders"];
}
if (!string.IsNullOrEmpty(orderIdList))
{
string[] numberTokens = orderIdList.Split(",".ToCharArray());
foreach (string numberToken in numberTokens)
{
int temp = AlwaysConvert.ToInt(numberToken);
if (temp > 0) selectedOrders.Add(temp);
}
}
return selectedOrders;
}
Do you think 70 is too many Invoices to be displayed and printed at once?
Yes, I did actually: The size of the file to print was 22.7 MB.
It took about 20 seconds to load them in the browser. I did not print them though.
But the ViewState was HUGE.
Question: Can I disable the ViewState in this Repeater: <asp:Repeater ID="OrderRepeater"> without causing the code not to function correctly?
What I decided to do was print the Invoices in batches of 70:
70 Invoices will be display in the browser, user clicks "Print",
user clicks another button to get next 70, . . . repeat until no more.
This is the code I came up with to do that:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Request.QueryString["orders"] == "Start")
{
pnlVendorList.Visible = true; // displays buttons to run the Invoice batches
return;
}
else
{
pnlVendorList.Visible = false;
List<int> selectedOrders2 = GetSelectedOrders();
DisplayInvoices(selectedOrders2);
}
}
private void DisplayInvoices(List<int> selectedOrders2)
{
List<int> selectedOrders = selectedOrders2;
if ((selectedOrders == null) || (selectedOrders.Count == 0)) Response.Redirect("~/Admin/Orders/Default.aspx");
OrderRepeater.DataSource = GetOrders(selectedOrders.ToArray());
OrderRepeater.DataBind();
OrderList.Text = GetOrderNumbers(selectedOrders);
}
// This is run first:
protected void VendorRun_Click(object sender, EventArgs e)
{
string query = "UPDATE ac_Orders Set ord = 1 WHERE . .";
int result = (int)database.ExecuteNonQuery(updateCommand);
List<int> selectedOrders2 = GetSelectedOrders();
DisplayInvoices(selectedOrders2);
btnVendorRun.Enabled = false;
if (moreInvoices)
{
btnNextBatch.Visible = true;
lblMsg.Text = "More Invoices after this . . . ";
}
else
{
lblMsg.Text = "Vendor Update Done - No more Invoices;
}
}
protected void NextBatch_Click(object sender, EventArgs e)
{
List<int> selectedOrders2 = GetSelectedOrders();
DisplayInvoices(selectedOrders2);
if (moreInvoices)
{
btnNextBatch.Visible = true;
lblMsg.Text = "More Invoices after this . . . ";
}
else
{
btnNextBatch.Visible = false;
lblMsg.Text = "Click Print now. This is your LAST BATCH.;
}
}
private List<int> GetSelectedOrders()
{
string orderIdList = string.Empty;
Int16 counter = 1;
//CHECK FOR QUERYSTRING PARAMETERS
List<int> selectedOrders = new List<int>();
if (Request.QueryString["orders"] == "Start")
{
System.Data.SqlClient.SqlDataReader dr = GetInvoices();
lastCountNum = (lastCountNum - 1);
if (moreInvoices)
{
while (dr.Read())
{
if ((counter == (lastCountNum)))
{
counter++;
break;
}
counter++;
}
lastCountNum = (lastCountNum + 70);
while (dr.Read())
{
if (counter > lastCountNum)
{
dr.Close();
lastCountNum = counter;
moreInvoices = true;
return selectedOrders;
}
selectedOrders.Add(Convert.ToInt32(dr["OrderID"]));
counter++;
}
moreInvoices = false;
dr.Close();
return selectedOrders;
}
while (dr.Read())
{
if (counter > 70)
{
lastCountNum = counter;
moreInvoices = true;
totalCount = counter;
while (dr.Read())
{
totalCount++;
}
dr.Close();
MP3.Text = "Total Count = " + totalCount; // total invoices from DataReader
return selectedOrders;
}
selectedOrders.Add(Convert.ToInt32(dr["OrderID"]));
counter++;
}
dr.Close();
return selectedOrders;
}
else
{
orderIdList = Request.QueryString["orders"];
}
if (!string.IsNullOrEmpty(orderIdList))
{
string[] numberTokens = orderIdList.Split(",".ToCharArray());
foreach (string numberToken in numberTokens)
{
int temp = AlwaysConvert.ToInt(numberToken);
if (temp > 0) selectedOrders.Add(temp);
}
}
return selectedOrders;
}
Do you think 70 is too many Invoices to be displayed and printed at once?