Accounting-Companion / TallyConnector

You can use Tally Connector to Connect your desktop/Mobile Applications with Tally seamlessly.
48 stars 29 forks source link

Add Bill table #35

Closed aquib-sh closed 9 months ago

aquib-sh commented 9 months ago

Adding bill table would be helpful, since opening, closing and final balance is shown in the bill table. It is almost identical to the Voucher table but has additional table.

I tried to add the bill table but got lost in complexity. If you could add bill table or provide some pointers to implement it would be great.

saivineeth100 commented 9 months ago

you mean Bill Allocations, Bill allocations are there in Voucher,

If you want them separately Refer how this method is implemented.

Create a class with required properties matching XML Element names with XML and send that in GetCustomCollectionAsync after setting appropriate request options.

Here is the sample

[XmlRoot(ElementName = "BILL")]
public class Bill : TallyBaseObject
{
    [XmlElement(ElementName = "BILLID")]
    public int BillId { get; set; }

    [XmlElement(ElementName = "OPENINGBALANCE")]
    public TallyAmount OpeningBal {  get; set; }

    [XmlElement(ElementName = "CLOSINGBALANCE")]
    public TallyAmount ClosingBal {  get; set; }
}
CollectionRequestOptions collectionOptions = new CollectionRequestOptions()
{
    CollectionType = "Bills",
    FetchList = ["BILLID,"]

};
collectionOptions.XMLAttributeOverrides ??= new();
XmlAttributes attrs = new();
attrs.XmlElements.Add(new("BILL"));
collectionOptions.XMLAttributeOverrides.Add(typeof(Colllection<Bill>), "Objects", attrs);
var billsData = await _tallyService.GetCustomCollectionAsync<Bill>(collectionOptions);
var bills = billsData.Data;
aquib-sh commented 3 months ago

Hello @saivineeth100

How do I get only the new or or altered bills based on alterId?

from GetLastAlterIds method we are getting master and voucher alter id, but when voucher alter id is used to get bills then there is nothing.

if I am not wrong then Bill table is also a part of Voucher (sales voucher) basically. so I must work on VoucherAlterId right?

So to sum up the issue, when a new sales voucher is added, I am able to see it using voucheralterid while getting voucher table and also when I get all the bill table entires at same time without alterid, but when I put the voucheralterid in alter id for bills it gives 0 bills.

I am using below code to get the bill data which then I am using further in other services.

        public void UploadBills(string endpoint = "bill", bool shouldAlter = false, int alterId = 0)
        {
            string url = host + $"{endpoint}/create?companyId={companyGUID}";

            CollectionRequestOptions options = new CollectionRequestOptions()
            {
                Company = company,
                CollectionType = "Bills",
                FetchList =
                [
                    "BILLID",
                    "*.*",
                    "masterid",
                    "BILLCREDITPERIOD",
                    "PARENT",
                    "PARENTGROUPNAME",
                    "LEDGER.ENTRIES"
                ],
            };

            options.XMLAttributeOverrides ??= new();
            XmlAttributes attrs = new();
            attrs.XmlElements.Add(new("BILL"));

            options.XMLAttributeOverrides.Add(typeof(Colllection<Bill>), "Objects", attrs);

            if (shouldAlter && alterId > 0)
            {
                options.Filters = new() { new("TDLALTERFILTER", $"$AlterId > {alterId}") };
            }

            postDispatchService.UploadBills(options, url, companyGUID);
        }

   public void UploadBills(CollectionRequestOptions options, string url, string companyId)
   {
       var finalTimer = new Stopwatch();

       finalTimer.Start();
       List<Bill> listOfBills = (tally.GetCustomCollectionAsync<Bill>(options)).Result!.Data ?? new List<Bill>();
       listOfBills = listOfBills.Distinct().ToList();

       Console.WriteLine($"Found {listOfBills.Count} Bills");

       // Split the bills in chunk of 500 to avoid JSON overload
       const int pageSize = 500;
       int totalPages = listOfBills.Count / pageSize;
       int pageIndex = 0;

       int uploaded = 0;

       while (pageIndex <= totalPages)
       {
           Console.WriteLine($"--------------- BILLS PAGE:{pageIndex} -----------");
           List<Bill> billsOnPage = listOfBills.Skip(pageIndex * pageSize).Take(pageSize).ToList();

           Upload<Bill>(url, billsOnPage);

           uploaded += listOfBills.Count;
           pageIndex++;    
       }

       finalTimer.Stop();

       Console.WriteLine($"Total {uploaded} record dispatched to Sync service in {finalTimer.Elapsed.TotalSeconds} seconds.");
       Console.WriteLine("--------------------------------------------\n");
   }
saivineeth100 commented 3 months ago

Bill is a separate table has no AlterId (Since this table is just a helper table to generate reports faster) If you want to filter bill based on voucherAlterId change filter to "$LEDGERENTRIES.AlterId > {alterId}"

In Bill Type we can access voucher information through LEDGERENTRIES so above filter works