narsil/Tanshu.Accounts.Print/Thermal.cs
unknown d8ecec8bb6 Added inverse Attribute to ProductGroup.
BillInventory Renamed.
Refactored Bill to be more usable.
Added Bill Detail Report.
Added Open Bill and Bill Details Roles.
Zero Rate Products have Yellow background Color.
Refactored UserBI, FoodTableBI, ModifierBI, PrintLocationBI, ProductBI, ProductGroupBI, TaxBI, UserBI,
Cached the Products List.
Product and Product Group Form Working.
2011-06-23 18:17:48 +05:30

476 lines
22 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Tanshu.Accounts.Contracts;
using Tanshu.Accounts.Entities;
using Tanshu.Accounts.Entities.Auth;
using Tanshu.Accounts.Repository;
using System.Diagnostics;
namespace Tanshu.Accounts.Print
{
internal enum Align
{
None = 0,
Left = 1,
Centre = 2,
Right = 4
}
public static class Thermal
{
private const string DrawLine = "\n\r------------------------------------------";
private const string DrawEqual = "\n\r==========================================";
private static string DesignKot(Voucher trans, string kotCode, IEnumerable<Inventory> billItems, int copyNumber)
{
var waiter = trans.Waiter;
var billText = "\n\r" + FormatText("KOT / BOT", 42, false, Align.Centre);
billText += "\n\r" + FormatText(string.Format("Copy No. {0}", copyNumber), 42, false, Align.Centre);
billText += DrawLine;
billText += string.Format("\n\rKOT ID : {0,-7}/{1,-7} {2:dd-MMM-yyyy HH:mm}", trans.KotID, kotCode,
trans.Date);
billText += string.Format("\n\rTable No.: {0} / {1}", trans.TableID, waiter.Name);
billText += DrawLine;
billText += "\n\r Qty. x Name ";
billText += DrawLine;
foreach (var item in billItems)
{
billText += string.Format("\n\r{0,6:#,##0.00} x {1,-33}", item.Quantity, Name(item.Product));
foreach (var mod in item.InventoryModifier)
billText += string.Format("\n\r --- {0,-32}", mod.Modifier.Name);
}
billText += DrawLine;
if (trans.Narration != "")
{
billText += "\n\r" + FormatText(trans.Narration, 42, false, Align.Centre);
billText += DrawLine;
}
return billText;
}
private static string DesignBill(Voucher trans)
{
var list = new Dictionary<int, Inventory>();
foreach (var kot in trans.Kots)
{
foreach (var item in kot.Inventories)
{
if (list.ContainsKey(item.Product.ProductID))
list[item.Product.ProductID].Quantity += item.Quantity;
else
list.Add(item.Product.ProductID, item);
}
}
var cashier = trans.User;
var waiter = trans.Waiter;
var customer = trans.Customer;
var billNo = trans.BillID.Substring(trans.BillID.IndexOf("-") + 1);
var billText = "";
billText = "\n\r" + FormatText("Hops n Grains", 42, false, Align.Centre);
billText += "\n\r" + FormatText("The Microbrewery", 42, false, Align.Centre);
billText += "\n\r" + FormatText("SCO 358, Sector 9, Panchkula", 42, false, Align.Centre);
billText += "\n\r" + FormatText("A Unit of Peitho Foods Pvt. Ltd.", 42, false, Align.Centre);
billText += "\n\r" + FormatText("TIN: 06592507323", 42, false, Align.Centre);
billText += "\n\r" + FormatText("Retail Invoice", 42, false, Align.Centre);
billText += "\n\r";
billText += "\n\r" + "Bill No: " + FormatText(billNo, 13, false, Align.Centre) +
string.Format("{0:dd-MMM-yyyy HH:mm:ss}", trans.Date);
billText += "\n\r" + "Table No.: " + trans.TableID;
billText += "\n\r" + "------------------------------------------";
billText += "\n\r" + "Qty. Particulars Price Amount";
billText += "\n\r" + "------------------------------------------";
foreach (var item in list.Values)
{
if (item.Quantity == 0)
continue;
if (Math.Round((item.Rate * (1 + item.Tax)), 0) == 1)
{
billText += "\n\r" + " ";
billText += FormatText(Name(item.Product), 22, false, Align.Left) + " ";
billText += " ";
billText += FormatBillNum(item.Rate * item.Quantity, 6);
}
else
{
billText += "\n\r" + FormatBillNum(item.Quantity, 5) + " ";
billText += FormatText(Name(item.Product), 22, false, Align.Left) + " ";
billText += FormatBillNum(item.Rate, 6) + " ";
billText += FormatBillNum(item.Rate * item.Quantity, 6);
}
}
billText += "\n\r" + "------------------------------------------";
decimal amount;
amount = Net(list.Values);
if (amount != 0)
billText += "\n\r" + FormatText("Net : ", 33, false, Align.Right) + FormatBillNum(amount, 9);
amount = Discount(list.Values);
if (amount != 0)
billText += "\n\r" + FormatText("Discount : ", 33, false, Align.Right) + FormatBillNum(amount, 9);
amount = ServiceCharge(list.Values);
if (amount != 0)
billText += "\n\r" + FormatText("Service Charge : ", 33, false, Align.Right) + FormatBillNum(amount, 9);
// Begin Service Tax and VAT Hack
decimal st = 0;
amount = list.Values.Where(x => x.Tax == 0.14741M).Sum(item => item.Quantity * item.Rate * (1 - item.Discount) * (1 + item.ServiceCharge) * item.Tax);
st = amount * 0.190564292M;
amount = amount * (1 - 0.190564292M);
if (amount != 0)
billText += "\n\r" + FormatText("VAT @ 12.5% + 5% Sur. : ", 33, false, Align.Right) +
FormatBillNum(amount, 9);
amount = list.Values.Where(x => x.Tax == 0.26673M).Sum(item => item.Quantity * item.Rate * (1 - item.Discount) * (1 + item.ServiceCharge) * item.Tax);
st += amount * 0.105316973M;
amount = amount * (1 - 0.105316973M);
if (amount != 0)
billText += "\n\r" + FormatText("VAT @ 25% + 5% Sur. : ", 33, false, Align.Right) +
FormatBillNum(amount, 9);
if (st != 0)
billText += "\n\r" + FormatText("Cental Govt. ST : ", 33, false, Align.Right) +
FormatBillNum(st, 9);
//// Original
//amount = Tax(list.Values);
//if (amount != 0)
// billText += "\n\r" + FormatText("VAT (incl. surcharge) : ", 33, false, Align.Right) +
// FormatBillNum(amount, 9);
// End Service Tax and VAT Hack
amount = Amount(list.Values);
if (amount != 0)
billText += string.Format("\n\r Final Amount : {0,9:#,##0.00;(#,##0.00);0}",
Math.Round(amount, 0));
billText += DrawLine;
if (trans.Narration != "")
{
billText += "\n\r" + FormatText(trans.Narration, 42, false, Align.Centre);
billText += DrawLine;
}
if (customer.CustomerID != 1)
{
billText += "\n\r" + customer.Name;
billText += string.Format("\n\r{0}\n\r{1}", customer.Phone, customer.Address);
billText += DrawLine;
}
billText += "\n\r" + "Cashier : " + cashier.Name + " / " + waiter.Name;
billText += "\n\r" + "Call: 0172-4026666, 8054923853, 8054923856";
return billText;
}
private static decimal Amount(IEnumerable<Inventory> list)
{
return list.Sum(item => item.Quantity * item.Rate * (1 - item.Discount) * (1 + item.ServiceCharge) * (1 + item.Tax));
}
private static decimal Tax(IEnumerable<Inventory> list)
{
return list.Sum(item => item.Quantity * item.Rate * (1 - item.Discount) * (1 + item.ServiceCharge) * item.Tax);
}
private static decimal ServiceCharge(IEnumerable<Inventory> list)
{
return list.Sum(item => item.Quantity * item.Rate * (1 - item.Discount) * item.ServiceCharge);
}
private static decimal Discount(IEnumerable<Inventory> list)
{
return list.Sum(item => item.Quantity * item.Rate * item.Discount);
}
private static decimal Net(IEnumerable<Inventory> list)
{
return list.Sum(item => item.Quantity * item.Rate);
}
private static string Name(Product product)
{
return string.IsNullOrEmpty(product.Units)
? product.Name
: string.Format("{0} ({1})", product.Name, product.Units);
}
private static string FormatText(string inputString, int width, Boolean multiline, Align alignment)
{
if ((multiline) && (inputString.Length > width))
{
var newString = "";
var lines = Convert.ToInt32(Math.Floor(Convert.ToDecimal(inputString.Length / width)));
for (var i = 0; i < lines; i++)
newString += inputString.Substring(i * width, width) + "\n\r";
newString += FormatText(inputString.Substring(lines * width), width, multiline, alignment);
return newString;
}
if (inputString.Length > width)
return inputString.Substring(0, width);
if (alignment == Align.None)
return inputString;
if (alignment == Align.Left)
return string.Format("{0,-" + width + "}", inputString);
if (alignment == Align.Centre)
{
int left;
left = Convert.ToInt32(Math.Ceiling(Convert.ToDouble((width - inputString.Length) / 2))) +
inputString.Length;
inputString = string.Format("{0,-" + left + "}", inputString);
return string.Format("{0," + width + "}", inputString);
}
if (alignment == Align.Right)
return string.Format("{0," + width + "}", inputString);
return inputString;
}
private static string FormatBillNum(decimal amount, int length)
{
var temp = String.Format("{0:#,##0.00;(#,##0.00);0}", amount);
return string.Format("{0," + length + "}", temp);
}
private static bool PrintRaw(PrintLocation printer, string text, string documentName)
{
#if (DEBUG)
MessageBox.Show(text);
return true;
#else
try
{
text += printer.CutCode;
if (!RawPrinterHelper.PrintString(printer.Printer, documentName, text, new[] { ';' }))
{
GC.Collect();
MessageBox.Show("Error in PrintRAW Function. Please Report immediately");
}
}
catch (Exception ex)
{
throw ex;
}
return true;
#endif
}
public static Boolean PrintAdvance(string user, string advance, string narration)
{
var billText = "\n\r" + FormatText("Hops n Grains", 42, false, Align.Centre);
billText += "\n\r" + FormatText("The Microbrewery", 42, false, Align.Centre);
billText += "\n\r" + FormatText("SCO 358, Sector 9, Panchkula", 42, false, Align.Centre);
billText += "\n\r" + FormatText("A Unit of Peitho Foods Pvt. Ltd.", 42, false, Align.Centre);
billText += DrawLine;
billText += "\n\r" +
FormatText(string.Format("{0:dd-MMM-yyyy HH:mm:ss}", DateTime.Now), 42, false, Align.Centre);
billText += "\n\r" + FormatText("Received Rs. " + advance + " as advance.", 42, false, Align.Centre);
billText += DrawLine;
if (narration != "") billText += "\n\r" + FormatText(narration, 42, false, Align.Centre);
billText += DrawLine;
billText += "\n\r" + FormatText("Thanking you " + user, 42, false, Align.Left);
billText += "\n\r";
billText += "\n\r";
billText += "\n\r";
billText += "\n\r";
billText += "\n\r";
billText += "Signed" + "\n\r";
billText += "\n\r";
PrintRaw(PrintLocationBI.BasePrinter, billText, "Advance for " + user);
return PrintRaw(PrintLocationBI.BasePrinter, billText, "Advance for " + user);
}
public static Boolean PrintClosing(CheckoutBI details)
{
try
{
var billText = FormatText(string.Format("{0} Checkout By {1}", details.Cashier.Name, details.Manager), 42,
false, Align.Centre);
billText += string.Format("\n\r{0:dd-MMM-yy} To {1:dd-MMM-yy} @ {2:dd-MMM-yyyy HH:mm}",
details.StartDate, details.FinishDate, DateTime.Now);
billText += DrawLine;
//BillText += string.Format("\n\rOpening : {0,26:#,##0.00}", details.Opening);
//BillText += string.Format("\n\rReceipts : {0,26:#,##0.00}", details.Receipts);
billText += string.Format("\n\rAdvance Rcv. : {0,26:#,##0.00}", details.AdvanceReceipts);
billText += string.Format("\n\rCC Receipts : {0,26:#,##0.00}", details.CcReceipts);
billText += string.Format("\n\rNC Amount : {0,26:#,##0.00}", details.NcReceipts);
billText += string.Format("\n\rBTC Amount : {0,26:#,##0.00}", details.BtcReceipts);
billText += string.Format("\n\rCash Amount : {0,26:#,##0.00}", details.CashReceipts);
billText += string.Format("\n\rAdvance Adj. : {0,26:#,##0.00}", details.AdvanceAdjusted);
//BillText += string.Format("\n\rPayments : {0,26:#,##0.00}", details.CashPayments);
//BillText += string.Format("\n\rAddl. Voids : {0,26:#,##0.00}", details.AdditionalVoids);
billText += string.Format("\n\rVoids in Sys. : {0,26:#,##0.00}", details.VoidsInSystem);
billText += string.Format("\n\rDiscounts : {0,26:#,##0.00}", details.Discount);
billText += string.Format("\n\rPending Bills : {0,26:#,##0.00}", details.PendingBills);
billText += string.Format("\n\rNet Sales : {0,26:#,##0.00}", details.CashReceipts);
billText += string.Format("\n\rClosing Bal. : {0,26:#,##0.00}", details.ClosingBalance);
billText += string.Format("\n\rCash Dep. : {0,26:#,##0.00}", details.CashDeposited);
billText += DrawLine;
billText += string.Format("\n\rOld Pending : {0,26:#,##0.00}", details.OldPending);
billText += string.Format("\n\rOld Receipts : {0,26:#,##0.00}", details.OldReceipts);
billText += string.Format("\n\rOld Voided : {0,26:#,##0.00}", details.OldVoided);
billText += DrawEqual;
billText += "\n\r" + FormatText(details.Status, 42, false, Align.Centre);
billText += DrawEqual;
billText += string.Format("\n\rActive Cashiers : {0}", details.Cashiers);
if (details.PendingString.Length > 0)
billText += details.PendingString;
if (details.CcString.Length > 0)
billText += details.CcString;
if (details.NcString.Length > 0)
billText += details.NcString;
if (details.BtcString.Length > 0)
billText += details.BtcString;
if (details.VoidsString.Length > 0)
billText += details.VoidsString;
if (details.PaymentString.Length > 0)
billText += details.PaymentString;
if (details.DiscountString.Length > 0)
billText += details.DiscountString;
return PrintRaw(PrintLocationBI.BasePrinter, billText, "Closing");
}
catch (Exception ex)
{
throw ex;
}
}
public static string FormatPrintNum(string inputString)
{
return inputString == "" ? "0.00" : FormatText(inputString, 24, false, Align.Right);
//return FormatText(FormatNumber(InputString.Trim, 2, TriState.UseDefault, TriState.True, TriState.True), 24, False, Align.Right);
}
public static void PrintBill(int voucherID)
{
var voucher = VoucherBI.Get(voucherID);
PrintRaw(PrintLocationBI.BasePrinter, DesignBill(voucher), "Bill");
}
public static void PrintKot(int voucherID, int kotID)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var voucher = VoucherBI.Get(voucherID);
var dict = new Dictionary<PrintLocation, List<Inventory>>();
foreach (var item in voucher.Kots.Where(x => x.KotID == kotID))
{
foreach (var inventory in item.Inventories)
{
var type = inventory.Product.ProductGroup.ProductGroupID;
var printer = PrintLocationBI.KotPrinter(type);
if (!dict.ContainsKey(printer))
{
dict.Add(printer, new List<Inventory>());
}
dict[printer].Add(inventory);
}
}
stopwatch.Stop();
Trace.TraceWarning("kot and printers built in {0} ms", stopwatch.ElapsedMilliseconds);
stopwatch.Reset();
foreach (var item in dict)
{
for (var i = 0; i < item.Key.Copies; i++)
{
stopwatch.Start();
PrintRaw(item.Key,
DesignKot(voucher, voucher.Kots.Where(x => x.KotID == kotID).Single().Code, item.Value, i),
"KOT");
stopwatch.Stop();
Trace.TraceWarning("kot designed and printed in {0} ms", stopwatch.ElapsedMilliseconds);
stopwatch.Reset();
}
}
}
#region Print Cash Total
public static Boolean PrintCash(Dictionary<int, int> amount, string user)
{
string printText;
int total = 0;
try
{
printText = FormatText(user, 42, false, Align.Centre);
printText += DrawLine;
printText += "\n\r" +
FormatText(string.Format("{0:dd-MMM-yyyy HH:mm:ss}", DateTime.Now), 42, false, Align.Centre);
foreach (int key in amount.Keys.OrderByDescending(k => k))
{
printText += CashLine(amount, key);
total += amount[key] * key;
}
printText += "\n\r" + DrawEqual;
printText += string.Format("\n\r Total = {0,10:#,##0}", total);
printText += DrawLine;
return PrintRaw(PrintLocationBI.BasePrinter, printText, "Closing/Opening for " + user);
}
catch (Exception ex)
{
throw ex;
}
}
public static Boolean PrintSale(string user, IList<SalesAnalysis> det, DateTime startDate, DateTime endDate)
{
string printText;
try
{
printText = FormatText(user, 42, false, Align.Centre);
printText += DrawLine;
printText += "\n\r" +
FormatText(string.Format("{0:dd-MMM-yyyy HH:mm:ss}", DateTime.Now), 42, false, Align.Centre);
printText += "\n\r" +
FormatText(string.Format("{0:dd-MMM-yyyy} to {1:dd-MMM-yyyy}", startDate, endDate), 42,
false, Align.Centre);
printText += DrawLine;
foreach (SalesAnalysis d in det)
{
printText += string.Format("\n\r {0,-22} {1,9:#,##0}", d.GroupType, d.Amount);
}
printText += DrawEqual;
return PrintRaw(PrintLocationBI.BasePrinter, printText, "Sale Detail " + user);
}
catch (Exception ex)
{
throw ex;
}
}
public static Boolean PrintSale(string user, IList<SalesAnalysisDetail> list, DateTime startDate,
DateTime endDate)
{
var printText = FormatText(user, 42, false, Align.Centre);
printText += DrawLine;
printText += "\n\r" +
FormatText(string.Format("{0:dd-MMM-yyyy HH:mm:ss}", DateTime.Now), 42, false, Align.Centre);
printText += "\n\r" +
FormatText(string.Format("{0:dd-MMM-yyyy} to {1:dd-MMM-yyyy}", startDate, endDate), 42,
false, Align.Centre);
printText += DrawLine;
foreach (var item in list)
{
printText += string.Format("\n\r{0,-22} {1,9:#,##0.00} {2,9:#,##0.00}", item.Product, item.Sale,
item.NC);
}
printText += DrawEqual;
return PrintRaw(PrintLocationBI.BasePrinter, printText, "Sale Detail " + user);
}
private static string CashLine(IDictionary<int, int> amount, int key)
{
return amount.ContainsKey(key) ? string.Format("\n\r{0,5:#,##0} x {1,10:#,##0} = {2,10:#,##0}", key, amount[key], key * amount[key]) : string.Empty;
}
#endregion
}
}