Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating Sales Order and Sales Lines in Microsoft Dynamics #207

Closed
hsajib-jsf opened this issue Mar 2, 2022 · 3 comments
Closed

Creating Sales Order and Sales Lines in Microsoft Dynamics #207

hsajib-jsf opened this issue Mar 2, 2022 · 3 comments
Labels
question Further information is requested

Comments

@hsajib-jsf
Copy link

I am working on integrating Microsoft Dynamics NAV 2013 R2 with my Python application. My objectives for this integration are:

  1. Query all the Sales Orders
  2. Create a new Sales Order and related Sales Lines

On the Dynamics NAV side, I am using web services compatible with OData 1.0 - 3.0. I am exposing both Sales Order and Sales Line objects from the web service. I can access the web service through a browser.

On the Python side, I am using experimental_v3 branch of this library to communicate with Dynamics NAV.

My testing code looks like following:

import pyodata
import requests
from requests_ntlm import HttpNtlmAuth
import logging

# Logging to get more information
Log_Format = "%(levelname)s %(asctime)s - %(message)s"
logging.basicConfig(level=logging.DEBUG, filename="logfile.log", filemode="w", format=Log_Format)
SERVICE_URL = "http://localhost:7648/RRFITest4/OData/"

# Creating session and providing authentication credentials
session = requests.Session()
session.auth = HttpNtlmAuth('username', 'password')
client = pyodata.Client(SERVICE_URL, session)

# Get the entity specific to the company name
company_entity = client.entity_sets.Company.get_entity('Company Name')
sales_order = {
    'Sell_to_Customer_No': '30001',
    'Sales_OrderSalesLines': {
        'Document_Type': 'Order',
        'Document_No': 'SO-0147924',
        'Line_No': 10000,
        'Type': "Item",
        'Family_Code': 'B116A',
        'No': 'W211608',
        'Quantity_Container': 0,
    }
}
# Creating a navigation property of the company
create_request = company_entity.nav('Sales_Order').create_entity()
create_request.set(**sales_order)
new_sales_order = create_request.execute()
print(new_sales_order)

The problem I am facing is I can query all the sales orders just fine but when I am trying to create a sales order along with related sales lines, I am getting the following error:

Traceback (most recent call last):
  File "C:/Users/hsajib/Dev/nav-webservices-integration/odata-sample.py", line 37, in <module>
    new_sales_order = create_request.execute()
  File "C:\Users\UserName\AppData\Local\pypoetry\Cache\virtualenvs\nav-webservices-integration-iyrYYhSb-py3.8\lib\site-packages\pyodata\v2\service.py", line 305, in execute
    return self._handler(response)
  File "C:\Users\UserName\AppData\Local\pypoetry\Cache\virtualenvs\nav-webservices-integration-iyrYYhSb-py3.8\lib\site-packages\pyodata\v2\service.py", line 1135, in create_entity_handler
    raise HttpError('HTTP POST for Entity Set {0} failed with status code {1}'
pyodata.exceptions.HttpError: HTTP POST for Entity Set Sales_Order failed with status code 400

Process finished with exit code 1

Here are the detailed logs from running the code:

INFO 2022-03-02 10:08:12,279 - Fetching metadata
DEBUG 2022-03-02 10:08:12,281 - Starting new HTTP connection (1): localhost:7648
DEBUG 2022-03-02 10:08:12,347 - http://localhost:7648 "GET /RRFITest4/OData/$metadata HTTP/1.1" 401 0
DEBUG 2022-03-02 10:08:12,367 - http://localhost:7648 "GET /RRFITest4/OData/$metadata HTTP/1.1" 401 0
DEBUG 2022-03-02 10:08:13,540 - http://localhost:7648 "GET /RRFITest4/OData/$metadata HTTP/1.1" 200 42231
DEBUG 2022-03-02 10:08:13,541 - Retrieved the response:
H: Cache-Control: no-cache
H: Content-Length: 42231
H: Content-Type: application/xml;charset=utf-8
H: Server: Microsoft-HTTPAPI/2.0
H: X-Content-Type-Options: nosniff
H: DataServiceVersion: 1.0;
H: Date: Wed, 02 Mar 2022 15:08:12 GMT
INFO 2022-03-02 10:08:13,542 - Creating OData Schema (version: 2)
INFO 2022-03-02 10:08:13,563 - Creating OData Service (version: 2)
DEBUG 2022-03-02 10:08:13,563 - New entity set proxy instance for Customers
DEBUG 2022-03-02 10:08:13,563 - New entity set proxy instance for CustomersDoc_Distribution_Line
DEBUG 2022-03-02 10:08:13,564 - New entity set proxy instance for Items
DEBUG 2022-03-02 10:08:13,564 - New entity set proxy instance for Job_Ledger_Entries
DEBUG 2022-03-02 10:08:13,564 - New entity set proxy instance for Sales_Lines
DEBUG 2022-03-02 10:08:13,564 - New entity set proxy instance for Sales_Order
DEBUG 2022-03-02 10:08:13,564 - New entity set proxy instance for Sales_OrderSalesLines
DEBUG 2022-03-02 10:08:13,564 - New entity set proxy instance for Company
DEBUG 2022-03-02 10:08:13,564 - Detected single property key, adding pair Name->Company Name to keyproperties
INFO 2022-03-02 10:08:13,564 - Getting entity Company for key Company Name and args {}
DEBUG 2022-03-02 10:08:13,564 - New instance of EntityGetRequest for last segment: Company
DEBUG 2022-03-02 10:08:13,564 - New entity set proxy instance for Sales_Order
DEBUG 2022-03-02 10:08:13,564 - New instance of EntityCreateRequest for entity type: Sales_Order on path Company('Company Name')/Sales_Order
INFO 2022-03-02 10:08:13,564 - {'Sell_to_Customer_No': '30001'}
DEBUG 2022-03-02 10:08:13,564 - Send (execute) POST request to http://localhost:7648/RRFITest4/OData/Company('Company Name')/Sales_Order
DEBUG 2022-03-02 10:08:13,564 -   query params: {}
DEBUG 2022-03-02 10:08:13,564 -   headers: {'Accept': 'application/json', 'Content-Type': 'application/json', 'X-Requested-With': 'X'}
DEBUG 2022-03-02 10:08:13,564 -   body: {"Sell_to_Customer_No": "30001"}
DEBUG 2022-03-02 10:08:13,646 - http://localhost:7648 "POST /RRFITest4/OData/Company('Company%20Name')/Sales_Order HTTP/1.1" 401 0
DEBUG 2022-03-02 10:08:13,705 - http://localhost:7648 "POST /RRFITest4/OData/Company('Company%20Name')/Sales_Order HTTP/1.1" 401 0
DEBUG 2022-03-02 10:08:13,755 - http://localhost:7648 "POST /RRFITest4/OData/Company('Company%20Name')/Sales_Order HTTP/1.1" 400 187
DEBUG 2022-03-02 10:08:13,755 - Received response
DEBUG 2022-03-02 10:08:13,755 -   url: http://localhost:7648/RRFITest4/OData/Company('Company%20Name')/Sales_Order
DEBUG 2022-03-02 10:08:13,756 -   headers: {'Content-Length': '187', 'Content-Type': 'application/json;odata=minimalmetadata;streaming=true;charset=utf-8', 'Server': 'Microsoft-HTTPAPI/2.0', 'X-Content-Type-Options': 'nosniff', 'DataServiceVersion': '3.0;', 'Date': 'Wed, 02 Mar 2022 15:08:13 GMT'}
DEBUG 2022-03-02 10:08:13,756 -   status code: 400
DEBUG 2022-03-02 10:08:13,756 -   body: {"odata.error":{"code":"","message":{"lang":"en-US","value":"The length of the string is 31, but it must be less than or equal to 30 characters. Value: ='Company Name'"}}}

I have tried to debug this from the NAV side. For that I have used the Dynamics NAV debugger using the 'Debug Next' option. I have used this article as a guideline for debugging without any luck.

My question is how can I get around this error and create the sales lines for the sales order? Are there other things I can do to debug this on the NAV side?

@phanak-sap
Copy link
Contributor

Hi @hsajib-js.

First point:

Please try your case with the latest stable (currently 1.9.0) pyodata version. If your service is " compatible with OData 1.0 - 3.0", there is no reason to use experimental_v3 branch, which is clearly just a, well, experiment, without any changes for year. But in the log is response from server 'DataServiceVersion': '3.0;', so maybe you created Odata V3 service.

Second point:

The root cause seems to lie in the last line of the provided log file . Seems like an error on the server side to me at first glance. I would focus on debugging the "Microsoft Dynamics NAV 2013" service. I don't see what actually is 31 characters long, but definitely not the Value: ='Company Name' (and not even urlencoded Company%20Name). This does not look like some wrongly generated HTTP request by pyodata - if you will pinpoint to that, please provide some kind of reproducer script, that could be executed locally, for example like https://github.com/phanak-sap/pyodata-issue-files/tree/master/%23142. Feel free to add PR to that repository, with new folder "#207" so its easy to link with this particular issue - or attach it as zip/tar.gz/7zip directly to this issue record.

log line:
The length of the string is 31, but it must be less than or equal to 30 characters. Value: ='Company Name'"}

@phanak-sap phanak-sap added the question Further information is requested label Mar 3, 2022
@hsajib-jsf
Copy link
Author

Hello @phanak-sap ,

Thank you for responding!

For the first point, I actually started using the experimental branch because I was getting this error and this issue discussed about it and suggested to use the experimental branch.

For the second point, I will try to provide some script ASAP.

@phanak-sap
Copy link
Contributor

Hi @hsajib-jsf

no sample script was provided and I am not sure if this is even odata V2 or odata V3 problem. Re-open if the problem still persist with more info and the script reproducing the bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants