caf9b3106c
Feature: Settings database table added to store string based settings. It is right now used to store bill header and footer. Hard Coded header/footer removed from file. Feature: Tax Analysis form created to easily show the tax calculation. Feature: Management form uses background workers. Dont' know if it is functional though. Chore: Reorder Table form moved to masters from sales folder. Refactor: ManagementBI and SalesAnalysisBI
549 lines
21 KiB
C#
549 lines
21 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Web.Script.Serialization;
|
|
using System.Windows.Forms;
|
|
using Tanshu.Accounts.Repository;
|
|
using System.ComponentModel;
|
|
|
|
namespace Tanshu.Accounts.Management
|
|
{
|
|
public partial class ManagementForm : Form
|
|
{
|
|
Stopwatch _stopwatch;
|
|
Stopwatch _totalStopwatch;
|
|
private BackgroundWorker bwGo = new BackgroundWorker();
|
|
private BackgroundWorker bwExcel = new BackgroundWorker();
|
|
public ManagementForm()
|
|
{
|
|
InitializeComponent();
|
|
|
|
bwGo.WorkerReportsProgress = true;
|
|
bwGo.WorkerSupportsCancellation = true;
|
|
bwGo.DoWork += new DoWorkEventHandler(DoGo);
|
|
bwGo.ProgressChanged += new ProgressChangedEventHandler(bwGo_ProgressChanged);
|
|
bwGo.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwGo_RunWorkerCompleted);
|
|
|
|
bwExcel.WorkerReportsProgress = true;
|
|
bwExcel.WorkerSupportsCancellation = true;
|
|
bwExcel.DoWork += new DoWorkEventHandler(DoExcel);
|
|
bwExcel.ProgressChanged += new ProgressChangedEventHandler(bwGo_ProgressChanged);
|
|
bwExcel.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwExcel_RunWorkerCompleted);
|
|
}
|
|
|
|
private void Sale_Analysis_Form_Load(object sender, EventArgs e)
|
|
{
|
|
dtpStart.Value = DateTime.Today;
|
|
dtpFinish.Value = DateTime.Today;
|
|
}
|
|
|
|
#region Go
|
|
private void btnGo_Click(object sender, EventArgs e)
|
|
{
|
|
if (btnGo.Text == "Go")
|
|
{
|
|
txtStatus.Text = "";
|
|
btnGo.Text = "Cancel";
|
|
_stopwatch = Stopwatch.StartNew();
|
|
_totalStopwatch = Stopwatch.StartNew();
|
|
bwGo.RunWorkerAsync();
|
|
}
|
|
else
|
|
bwGo.CancelAsync();
|
|
}
|
|
private void btnExcel_Click(object sender, EventArgs e)
|
|
{
|
|
if (btnExcel.Text == "Excel")
|
|
{
|
|
txtStatus.Text = "";
|
|
btnExcel.Text = "Cancel";
|
|
_stopwatch = Stopwatch.StartNew();
|
|
_totalStopwatch = Stopwatch.StartNew();
|
|
bwExcel.RunWorkerAsync();
|
|
}
|
|
else
|
|
bwExcel.CancelAsync();
|
|
}
|
|
|
|
private void DoGo(object sender, DoWorkEventArgs e)
|
|
{
|
|
var beer = GetBeer();
|
|
var sale = GetSale();
|
|
var credit = GetCredit();
|
|
|
|
var info = string.Empty;
|
|
foreach (var item in sale)
|
|
{
|
|
var startDate = item.StartDate;
|
|
var finishDate = item.FinishDate;
|
|
var sDate = startDate.AddHours(7);
|
|
var fDate = finishDate.AddDays(1).AddHours(7);
|
|
int count = 0;
|
|
bwGo.ReportProgress(++count, "Starting on " + startDate.ToShortDateString() + " to " + finishDate.ToShortDateString());
|
|
using (var bi = new ManagementBI())
|
|
{
|
|
bi.DeleteVoid(sDate, fDate);
|
|
bwGo.ReportProgress(++count, "Voids Deleted");
|
|
if (bwGo.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
bi.MoveStaffToNc(sDate, fDate);
|
|
bwGo.ReportProgress(++count, "Staff Moved");
|
|
if (bwGo.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
bi.ClearModifiers(sDate, fDate);
|
|
bwGo.ReportProgress(++count, "Modifiers Cleared");
|
|
if (bwGo.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
bi.CombineKots(sDate, fDate);
|
|
bwGo.ReportProgress(++count, "Kots Combined");
|
|
if (bwGo.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
bi.RemoveBlankKots(sDate, fDate);
|
|
bwGo.ReportProgress(++count, "Blank Kots Removed");
|
|
if (bwGo.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
bwGo.ReportProgress(++count, "Starting beer");
|
|
foreach (var beerDate in beer)
|
|
{
|
|
if (beerDate.Date < startDate || beerDate.Date > finishDate)
|
|
continue;
|
|
bi.SetBeer(beerDate.Date.AddHours(7), beerDate.Date.AddDays(1).AddHours(7), beerDate.Quantity);
|
|
bwGo.ReportProgress(++count, "Beer set for " + beerDate.Date.ToShortDateString());
|
|
if (bwGo.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
}
|
|
bi.RemoveBlankKots(sDate, fDate);
|
|
bwGo.ReportProgress(++count, "Blank Kots Removed");
|
|
if (bwGo.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
bi.MoveToNc(sDate, fDate, item.Sale.Where(x => x.IsLiq).Sum(x => x.Amount) / .75M); // Do not put all in NC this will allow for about 25% discount on the rest of non nc liqour
|
|
bwGo.ReportProgress(++count, "Moved to Nc");
|
|
if (bwGo.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
IList<CreditJson> creditJ = credit.Where(x => x.Date >= startDate && x.Date <= finishDate).ToList();
|
|
bi.SetQuantityAndDiscount(item.Sale, creditJ, startDate, finishDate);
|
|
bwGo.ReportProgress(++count, "Sale Done");
|
|
if (bwGo.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
bi.RemoveBlankKots(sDate, fDate);
|
|
bwGo.ReportProgress(++count, "Blank Kots Removed");
|
|
if (bwGo.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
bi.SaveChanges();
|
|
}
|
|
bwGo.ReportProgress(++count, "Cleanup done");
|
|
}
|
|
}
|
|
private void DoExcel(object sender, DoWorkEventArgs e)
|
|
{
|
|
var startDate = dtpStart.Value.Date;
|
|
var finishDate = dtpFinish.Value.Date;
|
|
string sheet;
|
|
int count = 0;
|
|
var info = new List<ExcelInfo>();
|
|
var rates = new List<decimal>();
|
|
using (var bi = new ManagementBI())
|
|
{
|
|
for (var date = startDate; date <= finishDate; date = date.AddDays(1))
|
|
{
|
|
if (bwExcel.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
bwExcel.ReportProgress(++count, "Getting data for " + date.ToShortDateString());
|
|
var currentStart = date.AddHours(7);
|
|
var currentFinish = date.AddDays(1).AddHours(7);
|
|
var bills = bi.GetMinMaxBills(currentStart, currentFinish);
|
|
if (bills == null)
|
|
continue;
|
|
|
|
var saleList = bi.GetSaleAndVat(currentStart, currentFinish);
|
|
var serviceTax = bi.GetServiceTax(currentStart, currentFinish);
|
|
|
|
var ei = new ExcelInfo()
|
|
{
|
|
Date = date,
|
|
StartBill = bi.FullBillID(bills.StartBill, Tanshu.Accounts.Entities.VoucherType.Regular),
|
|
FinishBill = bi.FullBillID(bills.FinishBill, Tanshu.Accounts.Entities.VoucherType.Regular),
|
|
SaleAndVat = new Dictionary<decimal, SaleInfo>(),
|
|
ServiceTax = serviceTax
|
|
};
|
|
foreach (var item in saleList)
|
|
{
|
|
if (!rates.Contains(item.Rate))
|
|
rates.Add(item.Rate);
|
|
ei.SaleAndVat.Add(item.Rate, item);
|
|
}
|
|
info.Add(ei);
|
|
}
|
|
|
|
rates.Sort();
|
|
|
|
sheet = "Date\tBill Start\tBill Final\t";
|
|
|
|
foreach (var item in rates)
|
|
{
|
|
sheet += string.Format("Sale {0:#0.00}%\tVat {0:#0.00}%\t", item * 100);
|
|
}
|
|
sheet += "Service Tax\n";
|
|
|
|
foreach (var item in info)
|
|
{
|
|
if (bwExcel.CancellationPending == true)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
bwExcel.ReportProgress(++count, "Compiling data for " + item.Date.ToShortDateString());
|
|
sheet += string.Format("{0:dd-MMM-yyyy}\t'{1}\t'{2}\t", item.Date, item.StartBill, item.FinishBill);
|
|
foreach (var rate in rates)
|
|
{
|
|
if (item.SaleAndVat.ContainsKey(rate))
|
|
sheet += string.Format("{0:#0}\t{1:#0}\t", Math.Round(item.SaleAndVat[rate].Net), Math.Round(item.SaleAndVat[rate].Vat));
|
|
else
|
|
sheet += "0\t0\t";
|
|
}
|
|
sheet += string.Format("{0:#0}\n", Math.Round(item.ServiceTax));
|
|
|
|
}
|
|
}
|
|
e.Result = sheet;
|
|
}
|
|
|
|
private void bwGo_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
|
|
{
|
|
var time = (_stopwatch.ElapsedMilliseconds / 1000).ToString() + "s / " + (_totalStopwatch.ElapsedMilliseconds / 1000).ToString() + "s";
|
|
_stopwatch.Reset();
|
|
_stopwatch.Start();
|
|
txtStatus.Text = (string)e.UserState + " " + time + " \r\n" + txtStatus.Text;
|
|
}
|
|
private void bwGo_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
|
|
{
|
|
_stopwatch.Stop();
|
|
_totalStopwatch.Stop();
|
|
|
|
btnGo.Text = "Go";
|
|
if (!e.Cancelled)
|
|
txtStatus.Text = "Done !!!\r\n" + txtStatus.Text;
|
|
else
|
|
txtStatus.Text = "Cancelled :(\r\n" + txtStatus.Text;
|
|
}
|
|
private void bwExcel_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
|
|
{
|
|
_stopwatch.Stop();
|
|
_totalStopwatch.Stop();
|
|
|
|
btnExcel.Text = "Excel";
|
|
if (!e.Cancelled)
|
|
{
|
|
txtStatus.Text = "Done !!!\r\n" + txtStatus.Text;
|
|
var sheet = (string)e.Result;
|
|
Clipboard.SetText(sheet, TextDataFormat.Text);
|
|
}
|
|
else
|
|
{
|
|
txtStatus.Text = "Cancelled :(\r\n" + txtStatus.Text;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
#region Get Data
|
|
private IList<SaleJson> GetSale()
|
|
{
|
|
var currentDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
|
var sale = Path.Combine(currentDirectory, "sale.json");
|
|
if (!File.Exists(sale))
|
|
throw new ArgumentException("Sale not found!");
|
|
var startDate = dtpStart.Value.Date;
|
|
var finishDate = dtpFinish.Value.Date;
|
|
var fileContents = new StreamReader(File.OpenRead(sale)).ReadToEnd();
|
|
JavaScriptSerializer jss = new JavaScriptSerializer();
|
|
var data = jss.Deserialize<IList<SaleJson>>(fileContents);
|
|
IList<SaleJson> list = new List<SaleJson>();
|
|
foreach (var item in data)
|
|
{
|
|
if (item.FinishDate.Date < startDate.Date || item.StartDate.Date > finishDate.Date)
|
|
continue;
|
|
list.Add(item);
|
|
}
|
|
return list;
|
|
}
|
|
private IList<CreditJson> GetCredit()
|
|
{
|
|
var currentDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
|
var credit = Path.Combine(currentDirectory, "credit.json");
|
|
if (!File.Exists(credit))
|
|
throw new ArgumentException("Credit not found!");
|
|
var startDate = dtpStart.Value.Date;
|
|
var finishDate = dtpFinish.Value.Date;
|
|
var fileContents = new StreamReader(File.OpenRead(credit)).ReadToEnd();
|
|
JavaScriptSerializer jss = new JavaScriptSerializer();
|
|
var data = jss.Deserialize<IList<CreditJson>>(fileContents);
|
|
IList<CreditJson> list = new List<CreditJson>();
|
|
foreach (var item in data)
|
|
{
|
|
if (item.Date.Date < startDate.Date || item.Date.Date > finishDate.Date)
|
|
continue;
|
|
list.Add(item);
|
|
}
|
|
var am = list.GroupBy(x => x.Date).Where(x => x.Count() > 1).Select(x => x.Key);
|
|
if (am.Count() > 0)
|
|
throw new ArgumentException("Duplicate dates in credit: " + am.Select(x => x.ToString("dd-MMM-yyyy")).Aggregate((c, n) => c + ", " + n));
|
|
return list;
|
|
}
|
|
private IList<BeerJson> GetBeer()
|
|
{
|
|
var currentDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
|
var beer = Path.Combine(currentDirectory, "beer.json");
|
|
if (!File.Exists(beer))
|
|
throw new ArgumentException("Beer not found!");
|
|
var startDate = dtpStart.Value.Date;
|
|
var finishDate = dtpFinish.Value.Date;
|
|
var fileContents = new StreamReader(File.OpenRead(beer)).ReadToEnd();
|
|
JavaScriptSerializer jss = new JavaScriptSerializer();
|
|
var data = jss.Deserialize<IList<BeerJson>>(fileContents);
|
|
IList<BeerJson> list = new List<BeerJson>();
|
|
foreach (var item in data)
|
|
{
|
|
if (item.Date.Date < startDate.Date || item.Date.Date > finishDate.Date)
|
|
continue;
|
|
list.Add(item);
|
|
}
|
|
return list;
|
|
}
|
|
private static decimal TryConvert(string amount)
|
|
{
|
|
decimal result = 0;
|
|
decimal.TryParse(amount, out result);
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
#region Tally
|
|
private void btnTally_Click(object sender, EventArgs e)
|
|
{
|
|
var startDate = dtpStart.Value.Date;
|
|
var finishDate = dtpFinish.Value.Date;
|
|
var daybook = @"
|
|
<ENVELOPE>
|
|
<HEADER>
|
|
<TALLYREQUEST>Import Data</TALLYREQUEST>
|
|
</HEADER>
|
|
<BODY>
|
|
<IMPORTDATA>
|
|
<REQUESTDESC>
|
|
<REPORTNAME>All Masters</REPORTNAME>
|
|
<STATICVARIABLES>
|
|
<SVCURRENTCOMPANY>Peitho Foods Pvt. Ltd.(2012-13)</SVCURRENTCOMPANY>
|
|
</STATICVARIABLES>
|
|
</REQUESTDESC>
|
|
<REQUESTDATA>
|
|
<TALLYMESSAGE xmlns:UDF=""TallyUDF"">
|
|
";
|
|
|
|
for (var date = startDate; date <= finishDate; date = date.AddDays(1))
|
|
{
|
|
daybook += GetVoucher(date);
|
|
}
|
|
daybook += @"
|
|
</TALLYMESSAGE>
|
|
</REQUESTDATA>
|
|
</IMPORTDATA>
|
|
</BODY>
|
|
</ENVELOPE>
|
|
";
|
|
Clipboard.SetText(daybook, TextDataFormat.Text);
|
|
}
|
|
private static string GetVoucher(DateTime date)
|
|
{
|
|
var currentStart = date.AddHours(7);
|
|
var currentFinish = date.AddDays(1).AddHours(7);
|
|
var voucher = string.Empty;
|
|
var cash = 0M;
|
|
using (var bi = new ManagementBI())
|
|
{
|
|
var saleAndVat = bi.GetSaleAndVat(currentStart, currentFinish);
|
|
foreach (var item in saleAndVat)
|
|
{
|
|
if (item.Net == 0)
|
|
throw new ArgumentException();
|
|
cash += Math.Round(item.Net);
|
|
var rate = item.Rate * 100 / 1.05M;
|
|
voucher += GetLedger(string.Format("Sale @ {0:#} %", rate), item.Net.ToString("#0.00"));
|
|
var vat = Math.Round(item.Vat);
|
|
if (vat != 0)
|
|
{
|
|
cash += vat;
|
|
voucher += GetLedger(string.Format("Output Vat @ {0:#}%", rate), vat.ToString("#0.00"));
|
|
}
|
|
}
|
|
|
|
var st = Math.Round(bi.GetServiceTax(currentStart, currentFinish));
|
|
if (st != 0)
|
|
{
|
|
cash += st;
|
|
voucher += GetLedger("Central Service Tax", st.ToString("#0.00"));
|
|
}
|
|
|
|
if (cash != 0)
|
|
{
|
|
voucher = GetLedger("Cash", cash.ToString("#0.00")) + voucher;
|
|
}
|
|
}
|
|
return voucher != "" ? GetVoucher(date.ToString("yyyyMMdd"), voucher) : "";
|
|
}
|
|
private static string GetVoucher(string date, string ledgers)
|
|
{
|
|
#region Voucher Template
|
|
var template = @"
|
|
<VOUCHER REMOTEID=""{0}"" VCHTYPE=""Journal"" ACTION=""Create"">
|
|
<DATE>{1}</DATE>
|
|
<GUID>{0}</GUID>
|
|
<VOUCHERTYPENAME>Journal</VOUCHERTYPENAME>
|
|
<VOUCHERNUMBER>349</VOUCHERNUMBER>
|
|
<PARTYLEDGERNAME>Cash</PARTYLEDGERNAME>
|
|
<CSTFORMISSUETYPE/>
|
|
<CSTFORMRECVTYPE/>
|
|
<FBTPAYMENTTYPE>Default</FBTPAYMENTTYPE>
|
|
<VCHGSTCLASS/>
|
|
<ENTEREDBY>Admin</ENTEREDBY>
|
|
<DIFFACTUALQTY>No</DIFFACTUALQTY>
|
|
<AUDITED>No</AUDITED>
|
|
<FORJOBCOSTING>No</FORJOBCOSTING>
|
|
<ISOPTIONAL>No</ISOPTIONAL>
|
|
<EFFECTIVEDATE>{1}</EFFECTIVEDATE>
|
|
<USEFORINTEREST>No</USEFORINTEREST>
|
|
<USEFORGAINLOSS>No</USEFORGAINLOSS>
|
|
<USEFORGODOWNTRANSFER>No</USEFORGODOWNTRANSFER>
|
|
<USEFORCOMPOUND>No</USEFORCOMPOUND>
|
|
<ALTERID> 3525</ALTERID>
|
|
<EXCISEOPENING>No</EXCISEOPENING>
|
|
<ISCANCELLED>No</ISCANCELLED>
|
|
<HASCASHFLOW>Yes</HASCASHFLOW>
|
|
<ISPOSTDATED>No</ISPOSTDATED>
|
|
<USETRACKINGNUMBER>No</USETRACKINGNUMBER>
|
|
<ISINVOICE>No</ISINVOICE>
|
|
<MFGJOURNAL>No</MFGJOURNAL>
|
|
<HASDISCOUNTS>No</HASDISCOUNTS>
|
|
<ASPAYSLIP>No</ASPAYSLIP>
|
|
<ISDELETED>No</ISDELETED>
|
|
<ASORIGINAL>No</ASORIGINAL>
|
|
{2}
|
|
</VOUCHER>
|
|
";
|
|
var servicetaxtemplate = @"";
|
|
#endregion
|
|
return string.Format(template, Guid.NewGuid(), date, ledgers);
|
|
}
|
|
private static string GetLedger(string ledgername, string amount)
|
|
{
|
|
var isDeemedPositive = string.Empty;
|
|
var isPartyLedger = string.Empty;
|
|
switch (ledgername)
|
|
{
|
|
case "Cash":
|
|
isDeemedPositive = "Yes";
|
|
isPartyLedger = "Yes";
|
|
amount = "-" + amount;
|
|
break;
|
|
case "Sale 12.5%":
|
|
isDeemedPositive = "No";
|
|
isPartyLedger = "No";
|
|
break;
|
|
case "Sale @ 15%":
|
|
isDeemedPositive = "No";
|
|
isPartyLedger = "No";
|
|
break;
|
|
case "Sale @ 25 %":
|
|
isDeemedPositive = "No";
|
|
isPartyLedger = "No";
|
|
break;
|
|
case "Sale Tax Free":
|
|
isDeemedPositive = "No";
|
|
isPartyLedger = "No";
|
|
break;
|
|
case "Output Vat 12.5%":
|
|
isDeemedPositive = "No";
|
|
isPartyLedger = "No";
|
|
break;
|
|
case "Output Vat @ 15%":
|
|
isDeemedPositive = "No";
|
|
isPartyLedger = "No";
|
|
break;
|
|
case "Output Vat @ 25%":
|
|
isDeemedPositive = "No";
|
|
isPartyLedger = "No";
|
|
break;
|
|
case "Central Service Tax@3.708%":
|
|
isDeemedPositive = "No";
|
|
isPartyLedger = "No";
|
|
break;
|
|
|
|
|
|
}
|
|
#region Voucher Template
|
|
const string template = @"
|
|
<ALLLEDGERENTRIES.LIST>
|
|
<LEDGERNAME>{0}</LEDGERNAME>
|
|
<GSTCLASS/>
|
|
<ISDEEMEDPOSITIVE>{1}</ISDEEMEDPOSITIVE>
|
|
<LEDGERFROMITEM>No</LEDGERFROMITEM>
|
|
<REMOVEZEROENTRIES>No</REMOVEZEROENTRIES>
|
|
<ISPARTYLEDGER>{2}</ISPARTYLEDGER>
|
|
<AMOUNT>{3}</AMOUNT>
|
|
</ALLLEDGERENTRIES.LIST>
|
|
";
|
|
var servicetaxtemplate = @"";
|
|
#endregion
|
|
return string.Format(template, ledgername, isDeemedPositive, isPartyLedger, amount);
|
|
}
|
|
#endregion
|
|
|
|
private void btnFinalSanction_Click(object sender, EventArgs e)
|
|
{
|
|
var startDate = dtpStart.Value.Date.AddHours(7);
|
|
var finishDate = dtpFinish.Value.Date.AddDays(1).AddHours(7);
|
|
using (var bi = new ManagementBI())
|
|
{
|
|
bi.SetPayments(startDate, finishDate);
|
|
bi.UpdateBillID(startDate, finishDate);
|
|
bi.SaveChanges();
|
|
}
|
|
}
|
|
}
|
|
}
|