questo è il codice intero in AL che devi tradurlo in python. // MODE:   I    insert      U update        D delete
    procedure SendTimeSheet(ResNo: Code[20]; PostingDate: Date; Mode: Text; SapNo: Code[20]) // Numero risorsa, data di registrazione, modalità, numero SAP
    var
        Req: Text;  
        TSE: Record "HOR Resource Time Sheet Entry"; // record è una riga di una tabella
        ResTime: Record "HOR Resource Time Sheet";
        Pos: Code[10];
        Res: Record Resource;
        XmlRes: Text;
        XmlDoc: XmlDocument;
        XmlNod: XmlNode;
        XmlNod2: XmlNode;
        XmlLst: XmlNodeList;
        Env: Integer;
        Str: Text;
        Int: Integer;
        SendOne: Boolean;
        Job: Record job;
    begin
        Req := '<soapenv:Envelope xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/ xmlns:urn="urn:sap-com:document:sap:rfc:functions">';
        Req += '<soapenv:Header/>';
        Req += '<soapenv:Body>';
        Req += '<urn:ZHW_TIMESHEET_CREATE>';

        CurrEDIProfile.TestField("HOR SAP Company");
        CurrEDIProfile.TestField("HOR SAP Time Sheet Integration");
        Env := CurrEDIProfile."HOR SAP Time Sheet Integration";

        SendOne := false;

        TSE.Reset();
        TSE.SetRange("Resource No.", ResNo);
        TSE.SetRange("Posting Date", PostingDate);
        TSE.SetFilter("Expense Amount", '>0');
        if SapNo > '' then
            tse.SetRange("SAP Entry No.", SapNo)
        else
            TSE.SetRange(Sent, false);
        if TSE.FindSet() then begin
            Pos := '01';
            SendOne := true;

            Req += '<T_KOMV>';
            repeat
                TSE.TestField("Entry ID");
                TSE.TestField("SAP Expense Code");
                TSE.TestField("SAP Expense Level");

                Req += '<item>';
                Req += '<EXTERNAL_ID>' + CurrEDIProfile."HOR SAP Company" + '_' + Format(TSE."Entry ID", 0, 9) + '</EXTERNAL_ID>';
                Req += '<KSCHL>' + TSE."SAP Expense Code" + '</KSCHL>';
                Req += '<STUNR>' + TSE."SAP Expense Level" + '</STUNR>';
                Req += '<ZAEHK>' + Pos + '</ZAEHK>';
                Req += '<KWERT>' + Format(TSE."Expense Amount", 0, 9) + '</KWERT>';
                Req += '<WAERS>EUR</WAERS>';
                Req += '<KAEND_WRT>X</KAEND_WRT>';
                Req += '</item>';

                Pos := IncStr(Pos);
            until TSE.Next() = 0;
            Req += '</T_KOMV>';
        end;

        TSE.Reset();
        TSE.SetRange("Resource No.", ResNo);
        TSE.SetRange("Posting Date", PostingDate);
        TSE.SetFilter(Hours, '>0');
        if SapNo > '' then
            tse.SetRange("SAP Entry No.", SapNo)
        else
            TSE.SetRange(Sent, false);
        if TSE.FindSet() then begin
            SendOne := true;

            Req += '<T_LOG>';
            repeat
                TSE.TestField("SAP CID Code");
                tse.TestField("SAP Notify");
                TSE.TestField("SAP Task Number");
                tse.TestField("Job Task No.");

                Req += '<item>';
                Req += '<EXTERNAL_ID>' + CurrEDIProfile."HOR SAP Company" + '_' + Format(TSE."Entry ID", 0, 9) + '</EXTERNAL_ID>';

                if Mode IN ['U', 'D'] then begin
                    tse.TestField("SAP Entry No.");
                    Req += '<ZCODLOG>' + TSE."SAP Entry No." + '</ZCODLOG>';
                    Req += '<UPDKZ>' + Mode + '</UPDKZ>';
                end else
                    Req += '<UPDKZ>I</UPDKZ>';

                Req += '<PERNR>' + TSE."SAP CID Code" + '</PERNR>';
                Req += '<DATE_FROM>' + FormatDate(TSE."Posting Date") + '</DATE_FROM>';
                Req += '<TIME_FROM>' + FormatTime(TSE."Starting Time") + '</TIME_FROM>';
                Req += '<TIME_TO>' + FormatTime(TSE."Ending Time") + '</TIME_TO>';

                if TSE."Travel (km)" > 0 then begin
                    tse.TestField("SAP Route Code");
                    Req += '<ROUTE>' + TSE."SAP Route Code" + '</ROUTE>';
                    Req += '<ZTWKMPER>' + Format(TSE."Travel (km)", 0, 9) + '</ZTWKMPER>';
                    Req += '<ZTWKMMAN>' + Format(TSE."Travel (km)", 0, 9) + '</ZTWKMMAN>';
                    Req += '<ZTWKMEFF>X</ZTWKMEFF>';
                end;

                case tse."Valuation Type" of
                    tse."Valuation Type"::Overtime:
                        Req += '<ZTWTPLOG>1</ZTWTPLOG>';
                    tse."Valuation Type"::"Nonworking Overtime":
                        Req += '<ZTWTPLOG>2</ZTWTPLOG>';
                    tse."Valuation Type"::Recovery:
                        Req += '<ZTWTPLOG>4</ZTWTPLOG>';
                    tse."Valuation Type"::Travel:
                        Req += '<ZTWTPLOG>5</ZTWTPLOG>';
                end;

                Req += '<QMNUM>' + tse."SAP Notify" + '</QMNUM>';
                Req += '<MANUM>' + Format(TSE."SAP Task Number", 0, 9) + '</MANUM>';
                Req += '<KWMENG>' + Format(tse.Hours, 0, 9) + '</KWMENG>';
                Req += '<KWMENGF>' + Format(tse.Hours, 0, 9) + '</KWMENGF>';    // hours to be invoiced
                Req += '<VRKME>HO</VRKME>';
                Req += '<WAERS>EUR</WAERS>';

                if TSE.Travel <> TSE.Travel::" " then begin
                    case TSE.Travel of
                        TSE.Travel::Gone:
                            Req += '<ZTWTPMOV>A</ZTWTPMOV>';
                        TSE.Travel::Return:
                            Req += '<ZTWTPMOV>R</ZTWTPMOV>';
                        TSE.Travel::"Round Trip":
                            Req += '<ZTWTPMOV>T</ZTWTPMOV>';
                    end;
                end;

                if TSE.Site <> TSE.Site::" " then
                    case TSE.Site of
                        TSE.Site::Office:
                            Req += '<ZTW_LSVO>S</ZTW_LSVO>';
                        TSE.Site::"On-Site":
                            begin
                                Req += '<ZTW_LSVO>F</ZTW_LSVO>';
                                Req += '<ZTW_PSVO>I</ZTW_PSVO>';    // Italy
                            end;
                        TSE.Site::Other:
                            Req += '<ZTW_LSVO>C</ZTW_LSVO>';
                    end;

                Req += '<TIME_FROMP>' + FormatTime(130000T) + '</TIME_FROMP>';
                Req += '<TIME_TOP>' + FormatTime(140000T) + '</TIME_TOP>';
                Req += '<ZNOTE>.</ZNOTE>';

                IF tse.Overnight then begin
                    // Req += '<ZTWTPMOV>P</ZTWTPMOV>';
                    Req += '<RAD_PERNO_NO></RAD_PERNO_NO>';
                    Req += '<RAD_PERNO_IT>X</RAD_PERNO_IT>';
                    Req += '<RAD_PERNO_OUT></RAD_PERNO_OUT>';
                end else begin
                    Req += '<RAD_PERNO_NO>X</RAD_PERNO_NO>';
                    Req += '<RAD_PERNO_IT></RAD_PERNO_IT>';
                    Req += '<RAD_PERNO_OUT></RAD_PERNO_OUT>';
                end;

                case TSE.Distance of
                    tse.Distance::"50-99":
                        begin
                            Req += '<ZRAD_INDEN_19_0></ZRAD_INDEN_19_0>';
                            Req += '<ZRAD_INDEN_19_1>X</ZRAD_INDEN_19_1>';
                            Req += '<ZRAD_INDEN_19_2></ZRAD_INDEN_19_2>';
                            Req += '<ZRAD_INDEN_19_3></ZRAD_INDEN_19_3>';
                            Req += '<ZRAD_INDEN_19_4></ZRAD_INDEN_19_4>';
                        end;
                    tse.Distance::"100-199":
                        begin
                            Req += '<ZRAD_INDEN_19_0></ZRAD_INDEN_19_0>';
                            Req += '<ZRAD_INDEN_19_1></ZRAD_INDEN_19_1>';
                            Req += '<ZRAD_INDEN_19_2>X</ZRAD_INDEN_19_2>';
                            Req += '<ZRAD_INDEN_19_3></ZRAD_INDEN_19_3>';
                            Req += '<ZRAD_INDEN_19_4></ZRAD_INDEN_19_4>';
                        end;
                    tse.Distance::"200-299":
                        begin
                            Req += '<ZRAD_INDEN_19_0></ZRAD_INDEN_19_0>';
                            Req += '<ZRAD_INDEN_19_1></ZRAD_INDEN_19_1>';
                            Req += '<ZRAD_INDEN_19_2></ZRAD_INDEN_19_2>';
                            Req += '<ZRAD_INDEN_19_3>X</ZRAD_INDEN_19_3>';
                            Req += '<ZRAD_INDEN_19_4></ZRAD_INDEN_19_4>';
                        end;
                    tse.Distance::">300":
                        begin
                            Req += '<ZRAD_INDEN_19_0></ZRAD_INDEN_19_0>';
                            Req += '<ZRAD_INDEN_19_1></ZRAD_INDEN_19_1>';
                            Req += '<ZRAD_INDEN_19_2></ZRAD_INDEN_19_2>';
                            Req += '<ZRAD_INDEN_19_3></ZRAD_INDEN_19_3>';
                            Req += '<ZRAD_INDEN_19_4>X</ZRAD_INDEN_19_4>';
                        end;
                    else begin
                            Req += '<ZRAD_INDEN_19_0>X</ZRAD_INDEN_19_0>';
                            Req += '<ZRAD_INDEN_19_1></ZRAD_INDEN_19_1>';
                            Req += '<ZRAD_INDEN_19_2></ZRAD_INDEN_19_2>';
                            Req += '<ZRAD_INDEN_19_3></ZRAD_INDEN_19_3>';
                            Req += '<ZRAD_INDEN_19_4></ZRAD_INDEN_19_4>';
                        end;
                end;

                Req += '</item>';
            until TSE.Next() = 0;
            Req += '</T_LOG>';
        end;

        Req += '</urn:ZHW_TIMESHEET_CREATE>';
        Req += '</soapenv:Body>';
        Req += '</soapenv:Envelope>';

        if SendOne then begin
            XmlRes := Post(Env, 'ZHW_TIMESHEET_CREATERequest', Req);
            XmlDocument.ReadFrom(XmlRes, XmlDoc);

            XmlDoc.SelectNodes('//T_LOG/item', XmlLst);
            foreach XmlNod in XmlLst do begin
                XmlNod.SelectSingleNode('EXTERNAL_ID', XmlNod2);
                Evaluate(Int, XmlNod2.AsXmlElement().InnerText.Substring(StrLen(CurrEDIProfile."HOR SAP Company") + 2));

                XmlNod.SelectSingleNode('TYPE', XmlNod2);
                if XmlNod2.AsXmlElement().InnerText = 'S' then begin
                    if Mode <> 'D' then
                        XmlNod.SelectSingleNode('ZCODLOG', XmlNod2);

                    TSE.Reset();
                    TSE.SetRange("Entry ID", Int);
                    if TSE.FindSet() then
                        repeat
                            if Mode = 'D' then begin
                                tse.Sent := false;
                                tse."SAP Entry No." := '';
                                tse.Modify();
                            end else begin
                                tse.Sent := true;
                                tse."SAP Entry No." := XmlNod2.AsXmlElement().InnerText;
                                tse.Modify();
                            end;
                        until TSE.Next() = 0;
                end;
            end;
        end;

        ResTime.Reset();
        ResTime.SetRange("Posting Date", PostingDate);
        ResTime.SetRange("Resource No.", ResNo);

        TSE.Reset();
        TSE.SetRange("Posting Date", PostingDate);
        TSE.SetRange("Resource No.", ResNo);
        TSE.SetRange(Sent, true);
        if not TSE.IsEmpty then
            ResTime.ModifyAll(Sent, true);

        if SendOne then begin
            Commit();
            RaiseApplicationError(XmlDoc, '//T_LOG/item');
        end;
    end;

// 1 production 2 development
    procedure Post(Environment: Integer; SoapAction: Text; Request: Text) Response: Text
    var
        EnvError: Label 'Invalid environment';
        DryError: Label 'Dry mode';
        URL: Text;
        WebClient: HttpClient;
        Content: HttpContent;
        WebResponse: HttpResponseMessage;
        Headers: HttpHeaders;
        TypeHelper: Codeunit "Type Helper";
        EDILogin: Record "AHD EDI Login";
        AuthString: Text;
        XmlDoc: XmlDocument;
        XmlNod: XmlNode;
        GenericError: Label 'Generic SAP error';
        UID: Text;
        GID: Guid;
        LFN: Text;
    begin
        if not (Environment in [1, 2]) then
            Error(EnvError);

        if Environment = 1 then begin
            CurrEDIProfile.TestField("HOR SAP Prod. Endpoint");
            URL := CurrEDIProfile."HOR SAP Prod. Endpoint";
        end else begin
            CurrEDIProfile.TestField("HOR SAP devel. Endpoint");
            URL := CurrEDIProfile."HOR SAP devel. Endpoint";
        end;

        EDILogin.Reset();
        EDILogin.SetRange("Profile Code", CurrEDIProfile.Code);
        EDILogin.SetRange("HOR SAP Integration", Environment);
        EDILogin.SetRange(Enabled, true);
        EDILogin.FindFirst();
        EDILogin.TestField(Login);
        EDILogin.TestField(Password);

        GID := CreateGuid();
        UID := Format(GID).Replace('{', '').Replace('}', '');
        LFN := SoapAction + '_' +
               Format(CurrentDateTime, 0, '<Year4><Month,2><Day,2><Hours24,2><Filler Character,0><Minutes,2><Seconds,2>') +
               '_' + CopyStr(UID, 1, 8) + '.xml';

        if CurrEDIProfile."HWY Log SAP Interface" then
            NetLeg.SetFileTextContent('c:\\temp\\Req_' + LFN, Request);

        CurrEDIProfile.TestField("HWY SAP Dry Run", false);
        if DryMode then
            Error(DryError);

        AuthString := STRSUBSTNO('%1:%2', EDILogin.Login, EDILogin.Password);
        AuthString := TypeHelper.ConvertValueToBase64(AuthString);
        AuthString := STRSUBSTNO('Basic %1', AuthString);
        WebClient.DefaultRequestHeaders().Add('Authorization', AuthString);
        WebClient.DefaultRequestHeaders.Add('SOAPAction', '"urn:sap-com:document:sap:rfc:functions:ZHW_INTF:' + SoapAction + '"');

        Content.WriteFrom(Request);

        Content.GetHeaders(Headers);
        Headers.Remove('Content-Type');
        Headers.Add('Content-Type', 'text/xml; charset=utf-8');

        WebClient.Post(URL, Content, WebResponse);

        WebResponse.Content().ReadAs(Response);

        if CurrEDIProfile."HWY Log SAP Interface" then
            NetLeg.SetFileTextContent('c:\\temp\\Res_' + LFN, Response);

        if not WebResponse.IsSuccessStatusCode() then begin
            XmlDocument.ReadFrom(Response, XmlDoc);
            if XmlDoc.SelectSingleNode('.//Text', XmlNod) then
                Error(XmlNod.AsXmlElement().InnerText);
            if XmlDoc.SelectSingleNode('.//ERRORCODE', XmlNod) then
                Error(XmlNod.AsXmlElement().InnerText);
            Error(GenericError);
        end;
    end;

    local procedure RaiseApplicationError(var XmlDoc: XmlDocument; XPath: Text)
    var
        XmlLst: XmlNodeList;
        XmlNod: XmlNode;
        XmlNod2: XmlNode;
    begin
        XmlDoc.SelectNodes(XPath, XmlLst);
        foreach XmlNod in XmlLst do
            if XmlNod.SelectSingleNode('TYPE', XmlNod2) then
                if XmlNod2.AsXmlElement().InnerText = 'E' then
                    if XmlNod.SelectSingleNode('MESSAGE', XmlNod2) then
                        Error(XmlNod2.AsXmlElement().InnerText);
    end;