Accounting-Companion / TallyConnector

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

Altering the voucher without passing date #5

Closed saivineeth100 closed 3 years ago

saivineeth100 commented 3 years ago

more over, with method in current project, if we want to alter the voucher then we also have to pass the Voucher date.

Now let's imagine that we sent voucher XML from our source (excel or database) having Voucher Date = "2021-04-01" and Voucher Number="Test123". Tally will successfully create a new Voucher.

But now if someone changes the voucher date in Source (excel or database) then how it will alter the voucher in Tally, because we do not know old date now,

So with this scenario, I believe passing Voucher Number into RemoteID would be more beneficial. Correct me if I am wrong with this suggestion.

Thanks

Originally posted by @sanketgroup in https://github.com/Accounting-Companion/TallyConnector/issues/4#issuecomment-868398978

saivineeth100 commented 3 years ago

I think it is better to first retrieve voucher based on master ID and alter the voucher

Coming to remote ID - I didn't find any info about that field except in one stack thread so I didn't want to touch that field as it is generated by tally

Even this Documentation by tally suggests sending voucher number with date to alter voucher

sanketgroup commented 3 years ago

problem is what if date is changed in source database, we would not be able to find voucher with new date in Tally.

saivineeth100 commented 3 years ago

@sanketgroup As I earlier said we can retrieve voucher from tally using Master ID and then alter If you are saving voucher in db you will eventually save master ID

sanketgroup commented 3 years ago

MasterID: I do see one issue with bulk uploading. Tally article says: " For a Single-User Environment, the above solution holds good, but in case of Multi-User Environment where multiple users are entering data simultaneously, it is hard to determine the Master ID of the current voucher since the MasterID from the Company Object will be assigned to the first person saving the voucher. "

For e.g. Following code is two voucher creation in one request, it will return only one MasterID.

<?xml version="1.0" encoding="UTF-8"?>
<ENVELOPE>
   <HEADER>
      <VERSION>1</VERSION>
      <TALLYREQUEST>Import</TALLYREQUEST>
      <TYPE>Data</TYPE>
      <ID>Vouchers</ID>
   </HEADER>
   <BODY>
      <DESC />
      <DATA>
         <TALLYMESSAGE>
            <VOUCHER>
               <DATE>20080402</DATE>
               <NARRATION>Ch. No. Tested</NARRATION>
               <VOUCHERTYPENAME>Payment</VOUCHERTYPENAME>
               <VOUCHERNUMBER>1</VOUCHERNUMBER>
               <ALLLEDGERENTRIES.LIST>
                  <LEDGERNAME>Conveyance</LEDGERNAME>
                  <ISDEEMEDPOSITIVE>Yes</ISDEEMEDPOSITIVE>
                  <AMOUNT>-12000.00</AMOUNT>
               </ALLLEDGERENTRIES.LIST>
               <ALLLEDGERENTRIES.LIST>
                  <LEDGERNAME>Bank of India</LEDGERNAME>
                  <ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
                  <AMOUNT>12000.00</AMOUNT>
               </ALLLEDGERENTRIES.LIST>
            </VOUCHER>
            <VOUCHER>
               <DATE>20080402</DATE>
               <NARRATION>Ch. No. : Tested</NARRATION>
               <VOUCHERTYPENAME>Payment</VOUCHERTYPENAME>
               <VOUCHERNUMBER>2</VOUCHERNUMBER>
               <ALLLEDGERENTRIES.LIST>
                  <LEDGERNAME>Conveyance</LEDGERNAME>
                  <ISDEEMEDPOSITIVE>Yes</ISDEEMEDPOSITIVE>
                  <AMOUNT>-5000.00</AMOUNT>
               </ALLLEDGERENTRIES.LIST>
               <ALLLEDGERENTRIES.LIST>
                  <LEDGERNAME>Bank of India</LEDGERNAME>
                  <ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
                  <AMOUNT>5000.00</AMOUNT>
               </ALLLEDGERENTRIES.LIST>
            </VOUCHER>
         </TALLYMESSAGE>
      </DATA>
   </BODY>
</ENVELOPE>

It will return only one MasterID as shown below.


<?xml version="1.0" encoding="UTF-8"?>
<ENVELOPE>
   <HEADER>
      <VERSION>1</VERSION>
      <STATUS>1</STATUS>
   </HEADER>
   <BODY>
      <DATA>
         <IMPORTRESULT>
            **<CREATED>2</CREATED>**
            <ALTERED>0</ALTERED>
            <LASTVCHID>119</LASTVCHID>
            <LASTMID>0</LASTMID>
            <COMBINED>0</COMBINED>
            <IGNORED>0</IGNORED>
            <ERRORS>0</ERRORS>
         </IMPORTRESULT>
      </DATA>
   </BODY>
</ENVELOPE>
saivineeth100 commented 3 years ago

What you said is correct If we send multiple vouchers in one request but this library doesn't give option to send multiple vouchers at once you can only send one voucher/object per request and receive masterid in response

I restricted so because If we send multiple items in one request its difficult to know where error occurred like Totals mismatch /Ledger Doesn't exist

sanketgroup commented 3 years ago

yes, that is correct too.

drparasmehta commented 1 year ago

As per your suggestion, I am retrieving voucher first. And then immediately posting same voucher without any modification, via PostVoucherAsync() method. Still Tally is creating new voucher, insteading of updating existing one.


voucher = await tally.GetVoucherAsync<TCM.Voucher>(_invoice.Tally_MasterId.ToString(), new TCM.VoucherRequestOptions()
                {
                    LookupField = TCM.VoucherLookupField.MasterId,
                    FetchList = TCM.Constants.Voucher.InvoiceViewFetchList.All
                });

                if (voucher != null)
                {
                    var resultVT = await tally.PostVoucherAsync<TCM.Voucher>(voucher);

                    if (resultVT.Status == TCM.RespStatus.Sucess)
                    {
                        var y = System.Text.RegularExpressions.Regex.Matches(resultVT.Response!, @"[0-9.]+")[0].Value;
                        _invoice.Tally_MasterId = int.Parse(y ?? "0");
                        _context.Invoices.Update(_invoice);
                        await _context.SaveChangesAsync();
                    }

                }
saivineeth100 commented 1 year ago

As per your suggestion, I am retrieving voucher first. And then immediately posting same voucher without any modification, via PostVoucherAsync() method. Still Tally is creating new voucher, insteading of updating existing one.


voucher = await tally.GetVoucherAsync<TCM.Voucher>(_invoice.Tally_MasterId.ToString(), new TCM.VoucherRequestOptions()
                {
                    LookupField = TCM.VoucherLookupField.MasterId,
                    FetchList = TCM.Constants.Voucher.InvoiceViewFetchList.All
                });

                if (voucher != null)
                {
                    var resultVT = await tally.PostVoucherAsync<TCM.Voucher>(voucher);

                    if (resultVT.Status == TCM.RespStatus.Sucess)
                    {
                        var y = System.Text.RegularExpressions.Regex.Matches(resultVT.Response!, @"[0-9.]+")[0].Value;
                        _invoice.Tally_MasterId = int.Parse(y ?? "0");
                        _context.Invoices.Update(_invoice);
                        await _context.SaveChangesAsync();
                    }

                }

will check and update

drparasmehta commented 1 year ago

As per your suggestion, I am retrieving voucher first. And then immediately posting same voucher without any modification, via PostVoucherAsync() method. Still Tally is creating new voucher, insteading of updating existing one.


voucher = await tally.GetVoucherAsync<TCM.Voucher>(_invoice.Tally_MasterId.ToString(), new TCM.VoucherRequestOptions()
                {
                    LookupField = TCM.VoucherLookupField.MasterId,
                    FetchList = TCM.Constants.Voucher.InvoiceViewFetchList.All
                });

                if (voucher != null)
                {
                    var resultVT = await tally.PostVoucherAsync<TCM.Voucher>(voucher);

                    if (resultVT.Status == TCM.RespStatus.Sucess)
                    {
                        var y = System.Text.RegularExpressions.Regex.Matches(resultVT.Response!, @"[0-9.]+")[0].Value;
                        _invoice.Tally_MasterId = int.Parse(y ?? "0");
                        _context.Invoices.Update(_invoice);
                        await _context.SaveChangesAsync();
                    }

                }

will check and update

Some clues, if they can help....

1) Generated XML from voucher.GetXML(); contains <REMOTEGUID /> tag. While testing in POSTMAN, voucher gets updated correctly if we remove this tag.

2) Generated XML from voucher.GetXML(); contains ``

\r\n -1 \r\n `` We need to remove this new line character ('\r\n') then only POSTMAN is able to validate the XML.
saivineeth100 commented 1 year ago

I tried based on your suggestions. REMOTEGUID is only causing issues but removing it not fully solving the problem. its working in a case where voucher is created through xml. I am trying to resolve it fully by using xml mentioned here

drparasmehta commented 1 year ago

Thanks a lot for your prompt responses.While you find out the concrete solution, Can you suggest some workaround for the time being to solve the issue? My project is stuck for this single issue.On 29-Jan-2023 12:32 pm, Sai Vineeth @.***> wrote: I tried based on your suggestions. REMOTEGUID is only causing issues but removing it not fully solving the problem. its working in a case where voucher is created through xml. I am trying to resolve it fully by using xml mentioned here

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: @.***>

saivineeth100 commented 1 year ago

Add below code before PostVoucherAsync You can find example here VoucherAlterTest

        XmlDocument doc = new XmlDocument();
        XmlAttribute TagNameAttribute = doc.CreateAttribute("TAGNAME");
        TagNameAttribute.Value = "MasterId";
        XmlAttribute TagValueAttribute = doc.CreateAttribute("TAGVALUE");
        TagValueAttribute.Value = voucher.MasterId.ToString();
        voucher.OtherAttributes = new XmlAttribute[] { TagNameAttribute, TagValueAttribute };
drparasmehta commented 1 year ago

Wonderful. Your suggestion has worked perfectly.

However, I am facing another problem now.

My API is working perfectly on my Development PC (Windows 11, VS Code). However, if I deploy it to Ubuntu - .Net Core, I am getting following error in tally.imp file and voucher is not imported.


Importing Data through SOAP Request on 29-Jan-2023 at 19:21:09

Importing Data to company: 'Test Company'

ERROR: Voucher: ID:<>, Voucher Type: Purchase, Source Voucher Number: , Voucher Number: , Date: 

Import Summary Created : 0 Altered : 0 Deleted : 0 Combined: 0 Ignored : 0 Errors  : 1

I am banging my head against the wall. I am sure it might be some silly mistake/missing file. I have ensured TallyConnector.dll and TallyConnector.Core.dll files available in deployed folder. Can you please be a savior once again?

My full-hearted thanks to you in advance.

From: Sai Vineeth @.> Sent: Sun, 29 Jan 2023 14:05:20 To: Accounting-Companion/TallyConnector @.> Cc: Paras Mehta @.>, Comment @.> Subject: Re: [Accounting-Companion/TallyConnector] Altering the voucher without passing date (#5)    Add below code before PostVoucherAsync You can find example here VoucherAlterTest XmlDocument doc = new XmlDocument(); XmlAttribute TagNameAttribute = doc.CreateAttribute("TAGNAME"); TagNameAttribute.Value = "MasterId"; XmlAttribute TagValueAttribute = doc.CreateAttribute("TAGVALUE"); TagValueAttribute.Value = voucher.MasterId.ToString(); voucher.OtherAttributes = new XmlAttribute[] { TagNameAttribute, TagValueAttribute }; — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

saivineeth100 commented 1 year ago

I haven't tested with tally running in Linux as Tally officially supports running in windows only. You can use this library to generate xml in Linux, but I cannot support for tally running in unsupported main OS, as error may not relate to this library but OS specific.

Debug Steps: You can try sending xml through postman to tally running in Linux check error is from library or other.

Regarding Reference You no need to reference dll files manually as Tally connector is available in nugget also. Regarding Issues Also, try to comment on related issue or create new issue