Конфликт пространства имен Netsuite (core_2017_2.platform vs accounting_2017_2.lists) - PullRequest
0 голосов
/ 22 мая 2018

Я хочу опубликовать запись журнала в Netsuite из моего скрипта Python.Я использую Zeep для общения с SuiteTalk.

Я новичок в Netsuite и новичок в SOAP.Следуя примерам в Интернете, мне удалось добавить тестового клиента с помощью скрипта Python, используя следующий код:

def make_app_info(client):
    AppInfo = client.get_type('ns4:ApplicationInfo')
    app_info = AppInfo(applicationId=NS_APPID)
    return app_info


def make_passport(client):
    RecordRef = client.get_type('ns0:RecordRef')
    Passport = client.get_type('ns0:Passport')
    role = RecordRef(internalId=NS_ROLE)

    return Passport(email=NS_EMAIL,
                    password=NS_PASSWORD,
                    account=NS_ACCOUNT,
                    role=role)


def login_client():
    client = Client(WSDL_URL)
    login = client.service.login(passport=make_passport(client), _soapheaders={'applicationInfo': make_app_info(client)})
    return client

WSDL_URL Я использую https://webservices.netsuite.com/wsdl/v2017_2_0/netsuite.wsdl

Использование вышеуказанного клиентаприведенный ниже код добавляет клиента:

def add_customer():
    client = login_client()

    Customer = client.get_type('ns13:Customer')
    customer = Customer(
        lastName='Prasad',
        firstName='Vikas',
        email='vikasprasad@example.com',
        companyName='Test Company'
    )

    client.service.add(customer)

add_customer()

Приведенный выше код успешно добавляет Customer к учетной записи Netsuite, и я вижу его в списке в веб-приложении.Продолжая приведенный выше пример, я написал этот код для добавления JournalEntry:

def get_record_by_type(client, type, internal_id):
    RecordRef = client.get_type('ns0:RecordRef')

    record = RecordRef(internalId=internal_id, type=type)
    response = client.service.get(record,
        _soapheaders={
            'applicationInfo': make_app_info(client),
            'passport': make_passport(client),
        }
    )
    r = response.body.readResponse
    if r.status.isSuccess:
        return r.record

def add_journal_entry():
    client = login_client()

    # get subsidiary by internal id
    subsidiary = get_record_by_type(client, 'subsidiary', '1')
    print(subsidiary)    # This prints a valid subsidiary having internal id 1

    # create two journal entry lines
    JournalEntryLine = client.get_type('ns31:JournalEntryLine')
    credit_line = JournalEntryLine(account=get_record_by_type(client, 'account', '1'), credit=100)
    debit_line = JournalEntryLine(account=get_record_by_type(client, 'account', '2'), debit=100)
    print(credit_line)    # This prints credit_line with a valid account having internal id 1
    print(debit_line)    # This prints debit_line with a valid account having internal id 2

    JournalEntryLineList = client.get_type('ns31:JournalEntryLineList')
    journal_entry_line_list = JournalEntryLineList(line=[credit_line, debit_line])

    JournalEntry = client.get_type('ns31:JournalEntry')
    journal_entry = JournalEntry(subsidiary=subsidiary, lineList=journal_entry_line_list)

    client.service.add(journal_entry, _soapheaders={'passport': make_passport(client),
                   'applicationInfo': make_app_info(client)})  # Fails on this line.

add_journal_entry()

. Это не удается при вызове client.service.add(...) с ошибкой:

zeep.exceptions.Ошибка: org.xml.sax.SAXException: Ожидаемое имя {urn: core_2017_2.platform.webservices.netsuite.com}, найдено {urn: accounting_2017_2.lists.webservices.netsuite.com} имя

Я уверен, что это что-то глупое в мире SOAP, но я не уверен, в каком направлении отлаживать.Почему существует разница между ожидаемым и найденным?Я нигде не упомянул какие-либо конкретные пространства имен.Это просто WSDL v2017_2_0, и все вызовы client.get_type() сделаны поверх этого.Откуда эта ошибка?

Задал тот же вопрос в группе пользователей Netsuite: https://usergroup.netsuite.com/users/forum/platform-areas/web-services-suitetalk/434717-netsuite-namespace-conflict#post434717

ОБНОВЛЕНИЕ: На основании ответа @Justin W выясняется,что вместо извлечения subsidiary и account s по internalId из Suitetalk и последующего добавления их в запрос я могу напрямую указать Suitetalk type и internalId, используя RecordRef, и Suitetalk будетпонять, какие subsidiary и account s использовать.

т.е. subsidiary = get_record_by_type(client, 'subsidiary', '1') можно изменить на subsidiary = RecordRef(internalId='1', type='subsidiary')

Аналогично

credit_line = JournalEntryLine(account=get_record_by_type(client, 'account', '1'), credit=100)
debit_line = JournalEntryLine(account=get_record_by_type(client, 'account', '2'), debit=100)

можно изменить на

credit_line = JournalEntryLine(account=RecordRef(internalId='1', type='account'), credit=100)
debit_line = JournalEntryLine(account=RecordRef(internalId='2', type='account'), debit=100)

1 Ответ

0 голосов
/ 25 мая 2018

Я думаю, что, вероятно, ваш get_account() возвращает Account, но JournalEntryLine.account должен быть RecordRef (фактически, такая же проблема и для get_subsidiary())

...