Skip to content

Implement queryTaxPayer & registerCreditEntry function#85

Open
passatgt wants to merge 9 commits intoewngs:masterfrom
passatgt:master
Open

Implement queryTaxPayer & registerCreditEntry function#85
passatgt wants to merge 9 commits intoewngs:masterfrom
passatgt:master

Conversation

@passatgt
Copy link
Copy Markdown

@passatgt passatgt commented Jan 21, 2025

This pull request introduces the queryTaxPayer function, which queries taxpayer details from the Számlázz.hu API(which mirrors the NAV API). The implementation ensures proper XML handling, response parsing. The response contains the validity of the tax payer id and if its valid, it will return the address and name in the following format:

{
  taxpayerValidity: true,
  taxpayerId: '12345678',
  vatCode: '2',
  countyCode: '41',
  taxpayerName: 'taxpayerName KERESKEDELMI ÉS SZOLGÁLTATÓ KORLÁTOLT FELELŐSSÉGŰ TÁRSASÁG',
  taxpayerShortName: 'taxpayerName KFT.',
  address: {
    countryCode: 'HU',
    postalCode: '1000',
    city: 'BUDAPEST',
    streetName: 'TESZT',
    publicPlaceCategory: 'UTCA',
    number: '1.'
  }
}

Also adds the registerCreditEntry function, which you can use to mark an invoice as paid by registering a credit entry.

@passatgt passatgt changed the title Implement queryTaxPayer function Implement queryTaxPayer & registerCreditEntry function Jan 21, 2025
Copy link
Copy Markdown
Collaborator

@ert78gb ert78gb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for the PR. I have some modification request please review them.
I would like to ask you next time please open individual pull request for every feature or bug fix.

@@ -0,0 +1,45 @@
import assert from 'assert'
import merge from 'merge'
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please delete the unused import

import {wrapWithElement} from './XMLUtils.js'
import {PaymentMethod, PaymentMethods} from './Constants.js'

const defaultOptions = {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed the defaultOptions just overcomplicate the code. You could simply set the default values in the line 11 and 12

lib/Client.js Outdated
}

async queryTaxPayer (taxPayerId) {
assert(typeof taxPayerId === 'number' && /^[0-9]{8}$/.test(taxPayerId.toString()), 'taxPayerId must be an 8-digit number');
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You expect the taxPayerId should be a number but after you convert it to string to validate with regexp.
taxPayerId is string in the xsd documentation. In the response we also return as string so I think better not expect a number type.
We have 2 options expect a string type or don't expect any type because the regexp do string coercion.

I would like if we expect string type. Don't forget to update the readme.md too

return data
}

async queryTaxPayer (taxPayerId) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a jsdoc especially of the input and returns type.


const response = await this._sendRequest('action-szamla_agent_taxpayer', xml)
const parsedBody = await parseString(response.data)
const cleanParsedBody = removeNamespaces(parsedBody);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the removeNamespaces utility function is not necessary it is just an overhead. We could read the properties of the object with namespace.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if the namespace changes? happened before... :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have never used the Nav API. I found the https://github.com/nav-gov-hu/Online-Invoice, looks like it is up to date.
Based in it the address DetailedAddressType in the base namespace.
All of the xml example response contain descriptive namespace prefixes. I don't know why the szamlazz.hu returns with nsX. Anyway the response contains the namespace definition xmlns:nsX="http://schemas.nav.gov.hu/OSA/3.0/base". Based on that we could properly find the proper namespace prefix of the schema.

If you think it is overcomplicated and Nav never will use the same element name from more namespace we could strip the prefixes but in this case please use the built in feature of the xml parser lib.

Just for a note. I called 4 times the queryTaxPayer method and once I got NAV API is not available response. Looks like it not HA.

*/
export function createCreditEntry(CreditEntry) {
return new CreditEntry({
paymentMethod: PaymentMethod.BankTransfer,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PaymentMethod does not have the BankTransfer property. I am fixing other invalid setup in the file after the CR


return wrapWithElement('tetel', [
[ 'megnevezes', this._options.label ],
[ 'azonosito', this._options.id ],
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please extend the readme.md with this optional property

'</xmlszamlakifiz>'

const httpResponse = await this._sendRequest('action-szamla_agent_kifiz', xml)
const data = {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please implement error branch too

};
}

async registerCreditEntry (options, creditEntries) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To follow the lib pattern please create a new complex type that contains the options and creditEntries.
Move the assert from this method to the new type.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure about this one? I don't see this being used by other already implemented functions in the Client class.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the public interfaces of the Client accept only 1 input argument. The options and creditEntries can be easily merge into 1 object like

const creditEntry = new CreditEntry({
  invoiceId: 'something',
  taxNumber: '',
  additive: true,
  entries: [
    new CreditItem({
      date: new Date(),
      paymentMethod: PaymentMethods.BankTransfer,
      amount: 0
    })
  ]
})

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW just now recognised in the szamlazz.hu documentation it allows maximum 5 kifizetes type

beforeEach(() => {
nock('https://www.szamlazz.hu')
.post('/szamla/')
.replyWithFile(200, RESPONSE_FILE_PATHS.SUCCESS_WITHOUT_PDF, {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the success response of the request is xmlagentresponse=DONE text. If I read well the documentation.

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please keep the namespace and other meta data elements like header, funcCode, software, etc

'beallitasok', [
...this._getAuthFields(),
['szamlaszam', options.invoiceId],
['adoszam', options.taxNumber || ''],
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is an optional filed. please don't set a default value . We save some bandwidth with it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants