*-- sync-comenzi-web.prg - Orchestrator pentru sincronizarea comenzilor web cu Oracle ROA *-- Autor: Claude AI *-- Data: 10 septembrie 2025 *-- Dependency: gomag-vending.prg trebuie rulat mai intai pentru generarea JSON-urilor Set Safety Off Set Century On Set Date Dmy Set Exact On Set Ansi On Set Deleted On *-- Variabile globale Private gcAppPath, gcLogFile, gnStartTime, gnOrdersProcessed, gnOrdersSuccess, gnOrdersErrors Private goConnectie, goSettings, goAppSetup Local lcJsonPattern, laJsonFiles[1], lnJsonFiles, lnIndex, lcJsonFile Local loJsonData, lcJsonContent, lnOrderCount, lnOrderIndex Local loOrder, lcResult, llProcessSuccess, lcPath goConnectie = Null *-- Initializare gcAppPath = Addbs(Justpath(Sys(16,0))) Set Default To (m.gcAppPath) lcPath = gcAppPath + 'nfjson;' Set Path To &lcPath Additive Set Procedure To utils.prg Additive Set Procedure To ApplicationSetup.prg Additive Set Procedure To nfjsonread.prg Additive Set Procedure To nfjsoncreate.prg Additive Set Procedure To regex.prg Additive *-- Statistici gnStartTime = Seconds() gnOrdersProcessed = 0 gnOrdersSuccess = 0 gnOrdersErrors = 0 *-- Initializare logging gcLogFile = InitLog("sync_comenzi") LogMessage("=== SYNC COMENZI WEB > ORACLE ROA ===", "INFO", gcLogFile) *-- Creare si initializare clasa setup aplicatie goAppSetup = Createobject("ApplicationSetup", gcAppPath) *-- Setup complet cu validare si afisare configuratie If !goAppSetup.Initialize() LogMessage("EROARE: Setup-ul aplicatiei a esuat sau necesita configurare!", "ERROR", gcLogFile) Return .F. Endif *-- Obtinere setari din clasa goSettings = goAppSetup.GetSettings() *-- Verificare directoare necesare If !Directory(gcAppPath + "output") LogMessage("EROARE: Directorul output/ nu exista! Ruleaza mai intai adapter-ul web", "ERROR", gcLogFile) Return .F. Endif *-- Rulare automata adapter pentru obtinere comenzi (daca este configurat) If goSettings.AutoRunAdapter LogMessage("Rulez adapter pentru obtinere comenzi: " + goSettings.AdapterProgram, "INFO", gcLogFile) If !ExecuteAdapter() LogMessage("EROARE la rularea adapter-ului, continuez cu fisierele JSON existente", "WARN", gcLogFile) Endif Else LogMessage("AutoRunAdapter este dezactivat, folosesc doar fisierele JSON existente", "INFO", gcLogFile) Endif *-- Gasire fisiere JSON comenzi din pattern configurat lcJsonPattern = gcAppPath + "output\" + goSettings.JsonFilePattern lnJsonFiles = Adir(laJsonFiles, lcJsonPattern) If lnJsonFiles = 0 LogMessage("AVERTISMENT: Nu au fost gasite fisiere JSON cu comenzi web", "WARN", gcLogFile) LogMessage("Ruleaza mai intai adapter-ul web cu GetOrders=1 in settings.ini", "INFO", gcLogFile) Return .T. Endif LogMessage("Gasite " + Transform(lnJsonFiles) + " fisiere JSON cu comenzi web", "INFO", gcLogFile) *-- Incercare conectare Oracle (folosind conexiunea existenta din sistem) If !ConnectToOracle() LogMessage("EROARE: Nu s-a putut conecta la Oracle ROA", "ERROR", gcLogFile) Return .F. Endif SET STEP ON *-- Procesare fiecare fisier JSON gasit For lnIndex = 1 To lnJsonFiles lcJsonFile = gcAppPath + "output\" + laJsonFiles[lnIndex, 1] LogMessage("Procesez fisierul: " + laJsonFiles[lnIndex, 1], "INFO", gcLogFile) *-- Citire si parsare JSON Try lcJsonContent = Filetostr(lcJsonFile) If Empty(lcJsonContent) LogMessage("AVERTISMENT: Fisier JSON gol - " + laJsonFiles[lnIndex, 1], "WARN", gcLogFile) Loop Endif *-- Parsare JSON array cu comenzi loJsonData = nfjsonread(lcJsonContent) If Isnull(loJsonData) LogMessage("EROARE: Nu s-a putut parsa JSON-ul din " + laJsonFiles[lnIndex, 1], "ERROR", gcLogFile) Loop Endif *-- Verificare daca este obiect JSON valid If Type('loJsonData') != 'O' LogMessage("EROARE: JSON-ul nu este un obiect valid - " + laJsonFiles[lnIndex, 1], "ERROR", gcLogFile) Loop Endif *-- Verificare structura GoMag (cu proprietatea "orders") If Type('loJsonData.orders') != 'O' LogMessage("EROARE: JSON-ul nu contine proprietatea 'orders' - " + laJsonFiles[lnIndex, 1], "ERROR", gcLogFile) Loop Endif *-- Obtinere numar comenzi din obiectul orders Local Array laOrderProps[1] lnOrderCount = Amembers(laOrderProps, loJsonData.orders, 0) LogMessage("Gasite " + Transform(lnOrderCount) + " comenzi in " + laJsonFiles[lnIndex, 1], "INFO", gcLogFile) *-- Log informatii pagina daca sunt disponibile If Type('loJsonData.page') = 'C' Or Type('loJsonData.page') = 'N' LogMessage("Pagina: " + Transform(loJsonData.Page) + " din " + Transform(loJsonData.Pages), "DEBUG", gcLogFile) Endif *-- Procesare fiecare comanda din obiectul orders For lnOrderIndex = 1 To lnOrderCount Local lcOrderId, loOrder lcOrderId = laOrderProps[lnOrderIndex] loOrder = Evaluate('loJsonData.orders.' + lcOrderId) If Type('loOrder') = 'O' gnOrdersProcessed = gnOrdersProcessed + 1 LogMessage("Procesez comanda ID: " + lcOrderId + " (Nr: " + Iif(Type('loOrder.number') = 'C', loOrder.Number, "NECUNOSCUT") + ")", "DEBUG", gcLogFile) llProcessSuccess = ProcessWebOrder(loOrder) If llProcessSuccess gnOrdersSuccess = gnOrdersSuccess + 1 Else gnOrdersErrors = gnOrdersErrors + 1 Endif Else LogMessage("AVERTISMENT: Comanda cu ID " + lcOrderId + " nu este un obiect valid", "WARN", gcLogFile) Endif * Daca sunt peste 10 erori, ies din import fara sa mai import alte comenzi * Probabil ca sunt erori in cod / baza de date If m.gnOrdersErrors > 10 Exit Endif Endfor Catch To loError LogMessage("EROARE la procesarea fisierului " + laJsonFiles[lnIndex, 1] + ": " + loError.Message, "ERROR", gcLogFile) gnOrdersErrors = gnOrdersErrors + 1 Endtry * Daca sunt peste 10 erori, ies din import fara sa mai import alte comenzi * Probabil ca sunt erori in cod / baza de date If m.gnOrdersErrors > 10 LogMessage("Peste 10 comenzi au dat eroare la import. Nu se mai importa restul de comenzi.", "ERROR", gcLogFile) Exit Endif Endfor *-- Inchidere conexiune Oracle DisconnectFromOracle() *-- Logging final cu statistici LogMessage("=== PROCESARE COMPLETA ===", "INFO", gcLogFile) LogMessage("Total comenzi procesate: " + Transform(gnOrdersProcessed), "INFO", gcLogFile) LogMessage("Comenzi importate cu succes: " + Transform(gnOrdersSuccess), "INFO", gcLogFile) LogMessage("Comenzi cu erori: " + Transform(gnOrdersErrors), "INFO", gcLogFile) CloseLog(gnStartTime, 0, gnOrdersProcessed, gcLogFile) Return .T. *-- =================================================================== *-- HELPER FUNCTIONS *-- =================================================================== *-- Functie pentru conectarea la Oracle folosind setarile din settings.ini Function ConnectToOracle Local llSuccess, lcConnectionString, lnHandle llSuccess = .F. Try *-- Conectare Oracle folosind datele din settings.ini lnHandle = SQLConnect(goSettings.OracleDSN, goSettings.OracleUser, goSettings.OraclePassword) If lnHandle > 0 goConnectie = lnHandle llSuccess = .T. LogMessage("Conectare Oracle reusita - Handle: " + Transform(lnHandle), "INFO", gcLogFile) LogMessage("DSN: " + goSettings.OracleDSN + " | User: " + goSettings.OracleUser, "DEBUG", gcLogFile) Else LogMessage("EROARE: Conectare Oracle esuata - Handle: " + Transform(lnHandle), "ERROR", gcLogFile) LogMessage("DSN: " + goSettings.OracleDSN + " | User: " + goSettings.OracleUser, "ERROR", gcLogFile) Endif Catch To loError LogMessage("EROARE la conectarea Oracle: " + loError.Message, "ERROR", gcLogFile) Endtry Return llSuccess Endfunc *-- Functie pentru deconectarea de la Oracle Function DisconnectFromOracle If Type('goConnectie') = 'N' And goConnectie > 0 SQLDisconnect(goConnectie) LogMessage("Deconectare Oracle reusita", "INFO", gcLogFile) Endif Return .T. Endfunc *-- Functie principala de procesare comanda web Function ProcessWebOrder Parameters loOrder Local llSuccess, lcOrderNumber, lcOrderDate, lnPartnerID, lcArticlesJSON Local lcObservatii, lcSQL, lnResult, lcErrorDetails, lnIdComanda, llSucces Local ldOrderDate, loError Local lnIdAdresaFacturare, lnIdAdresaLivrare, lcErrorMessage lnIdAdresaLivrare = NULL lnIdAdresaFacturare = NULL lnIdComanda = 0 llSucces = .T. Try *-- Validare comanda If !ValidateWebOrder(loOrder) LogMessage("EROARE: Comanda web invalida - lipsesc date obligatorii", "ERROR", gcLogFile) llSucces = .F. Endif *-- Extragere date comanda If m.llSucces lcOrderNumber = CleanWebText(Transform(loOrder.Number)) lcOrderDate = ConvertWebDate(loOrder.Date) && yyyymmdd ldOrderDate = String2Date(m.lcOrderDate, 'yyyymmdd') LogMessage("Procesez comanda: " + lcOrderNumber + " din " + lcOrderDate, "INFO", gcLogFile) *-- Procesare partener (billing address) lnPartnerID = ProcessPartner(loOrder.billing) If lnPartnerID <= 0 LogMessage("EROARE: Nu s-a putut procesa partenerul pentru comanda " + lcOrderNumber, "ERROR", gcLogFile) llSucces = .F. Else LogMessage("Partener identificat/creat: ID=" + Transform(lnPartnerID), "INFO", gcLogFile) *-- Adresa facturare lnIdAdresaFacturare = ProcessAddress(m.lnPartnerID, loOrder.billing) IF TYPE('loOrder.shipping') = 'O' *-- Adresa livrares lnIdAdresaLivrare = ProcessAddress(m.lnPartnerID, loOrder.shipping) ENDIF Endif Endif *-- Construire JSON articole If m.llSucces lcArticlesJSON = BuildArticlesJSON(loOrder.items) If Empty(m.lcArticlesJSON) LogMessage("EROARE: Nu s-au gasit articole valide in comanda " + lcOrderNumber, "ERROR", gcLogFile) llSucces = .F. Endif Endif *-- Construire observatii cu detalii suplimentare *!* lcObservatii = BuildOrderObservations(loOrder) *-- Apel package Oracle pentru import comanda If m.llSucces lcSQL = "BEGIN PACK_IMPORT_COMENZI.importa_comanda(?lcOrderNumber, ?ldOrderDate, ?lnPartnerID, ?lcArticlesJSON, ?lnIdAdresaLivrare, ?lnIdAdresaFacturare, ?goSettings.IdPol, ?goSettings.IdSectie, ?@lnIdComanda); END;" lnResult = SQLExec(goConnectie, lcSQL) If lnResult > 0 And Nvl(m.lnIdComanda,0) > 0 LogMessage("SUCCES: Comanda importata - ID Oracle: " + Transform(m.lnIdComanda), "INFO", gcLogFile) llSuccess = .T. Else llSuccess = .F. *-- Obtinere detalii eroare Oracle lcErrorDetails = GetOracleErrorDetails(m.lcSQL) LogMessage("EROARE: Import comanda esuat pentru " + lcOrderNumber + CHR(10) + lcErrorDetails, "ERROR", gcLogFile) Endif Endif Catch To loError llSucces = .F. LogMessage("EXCEPTIE la procesarea comenzii " + lcOrderNumber + ": " + loError.Message, "ERROR", gcLogFile) Endtry Return llSuccess Endfunc *-- Functie pentru validarea comenzii web Function ValidateWebOrder Parameters loOrder Local llValid llValid = .T. *-- Verificari obligatorii If Type('loOrder.number') != 'C' Or Empty(loOrder.Number) llValid = .F. Endif If Type('loOrder.date') != 'C' Or Empty(loOrder.Date) llValid = .F. Endif If Type('loOrder.billing') != 'O' llValid = .F. Endif If Type('loOrder.items') != 'O' llValid = .F. Endif Return llValid Endfunc *-- Functie pentru procesarea partenerului din billing.company GoMag Function ProcessPartner Lparameters toBilling Local lcDenumire, lcCodFiscal, lcRegistru, lcAdresa, lcTelefon, lcEmail, lcRegistru Local lcSQL, lnResult Local lnIdPart, lnIdAdresa, lnIsPersoanaJuridica lnIdPart = 0 lnIdAdresa = 0 lcDenumire = '' lcCodFiscal = '' lcRegistru = '' lnIsPersoanaJuridica = 0 lcCodFiscal = Null && Persoanele fizice nu au CUI in platformele web If .F. TEXT TO lcExampleJsonAdresa NOSHOW "billing": { "address": "STR. CAMPUL LINISTII, NR. 1", "city": "Arad", "company": { "bank": "", "code": "RO30071208", "iban": "", "name": "BASSANO BUILDINGS SRL", "registrationNo": "" }, "country": "Romania", "customerId": "13422", "email": "office@bassano.ro", "firstname": "Ionela", "lastname": "Letcan", "phone": "0728141899", "region": "Arad" }, ENDTEXT ENDIF Try *-- Extragere date partener din datele billing If Type('toBilling.company') = 'O' And !Empty(toBilling.company.Name) loCompany = toBilling.company *-- Companie - persoana juridica lcDenumire = CleanWebText(loCompany.Name) lcCodFiscal = Iif(Type('loCompany.code') = 'C', loCompany.Code, Null) lcCodFiscal = CleanWebText(m.lcCodFiscal) lcRegistru = Iif(Type('loCompany.registrationNo') = 'C', loCompany.registrationNo, Null) lcRegistru = CleanWebText(m.lcRegistru) lnIsPersoanaJuridica = 1 && Persoana juridica Else *-- Persoana fizica IF TYPE('toBilling.firstname') = 'C' lcDenumire = CleanWebText(Alltrim(toBilling.firstname) + " " + Alltrim(toBilling.lastname)) lnIsPersoanaJuridica = 0 && Persoana fizica ENDIF Endif LogMessage("Partener: " + lcDenumire + " | CUI: " + Iif(Isnull(lcCodFiscal), "NULL", lcCodFiscal) + " | Tip: " + Iif(lnIsPersoanaJuridica = 1, "JURIDICA", "FIZICA"), "DEBUG", gcLogFile) * Cautare/creare client lcSQL = "BEGIN PACK_IMPORT_PARTENERI.cauta_sau_creeaza_partener(?lcCodFiscal, ?lcDenumire, ?lcRegistru, ?lnIsPersoanaJuridica, ?@lnIdPart); END;" lnResult = SQLExec(goConnectie, lcSQL) If lnResult > 0 LogMessage("Partener procesat cu succes: ID=" + Transform(m.lnIdPart), "DEBUG", gcLogFile) Else *-- Obtinere detalii eroare Oracle lcErrorDetails = GetOracleErrorDetails(m.lcSQL) LogMessage("EROARE la apelul procedurii PACK_IMPORT_PARTENERI.cauta_sau_creeaza_partener pentru: " + lcDenumire + CHR(10) + lcErrorDetails, "ERROR", gcLogFile) Endif Catch To loError LogMessage("EXCEPTIE la procesarea partenerului: " + loError.Message, "ERROR", gcLogFile) Endtry Return m.lnIdPart ENDFUNC && ProcessPartner *-- Functie pentru procesarea adresei din billing/shipping Function ProcessAddress Lparameters tnIdPart, toAdresa Local lcAdresa, lcTelefon, lcEmail, lcSQL, lnResult, lnIdAdresa lnIdAdresa = 0 If .F. TEXT TO lcExampleJsonAdresa NOSHOW "billing": { "address": "STR. CAMPUL LINISTII, NR. 1", "city": "Arad", "company": { "bank": "", "code": "RO30071208", "iban": "", "name": "BASSANO BUILDINGS SRL", "registrationNo": "" }, "country": "Romania", "customerId": "13422", "email": "office@bassano.ro", "firstname": "Ionela", "lastname": "Letcan", "phone": "0728141899", "region": "Arad" }, "shipping": { "address": "Strada Molnar Janos nr 23 bloc 37 sc B etj e ap. 16", "city": "Bra?ov", "company": "", "country": "Romania", "email": "ancamirela74@gmail.com", "firstname": "Anca", "lastname": "Stanciu", "phone": "0758261492", "region": "Brasov", "zipcode": "" } ENDTEXT Endif Try * Cautare/creare adresa If !Empty(Nvl(m.tnIdPart,0)) *-- Formatare adresa pentru Oracle (format semicolon cu prefix JUD:) lcAdresa = FormatAddressForOracle(toAdresa) *-- Date contact lcTelefon = Iif(Type('toAdresa.phone') = 'C', toAdresa.phone, "") lcEmail = Iif(Type('toAdresa.email') = 'C', toAdresa.email, "") lcSQL = "BEGIN PACK_IMPORT_PARTENERI.cauta_sau_creeaza_adresa(?tnIdPart, ?lcAdresa, ?lcTelefon, ?lcEmail, ?@lnIdAdresa); END;" lnResult = SQLExec(goConnectie, lcSQL) If lnResult > 0 LogMessage("Adresa procesata cu succes: ID=" + Transform(m.lnIdAdresa), "DEBUG", gcLogFile) Else *-- Obtinere detalii eroare Oracle lcErrorDetails = GetOracleErrorDetails(m.lcSQL) LogMessage("EROARE la apelul procedurii PACK_IMPORT_PARTENERI.cauta_sau_creeaza_adresa pentru PartnerId: " + ALLTRIM(TRANSFORM(m.tnIdPart)) + CHR(10) + lcErrorDetails, "ERROR", gcLogFile) Endif Endif Catch To loError LogMessage("EXCEPTIE la procesarea adresei: " + loError.Message, "ERROR", gcLogFile) Endtry Return m.lnIdAdresa Endfunc && ProcessAddress *-- Functie pentru construirea JSON-ului cu articole conform package Oracle Function BuildArticlesJSON Lparameters loItems Local lcJSON, loError lcJSON = "" Try lcJSON = nfjsoncreate(loItems) Catch To loError LogMessage("EROARE la construirea JSON articole: " + loError.Message, "ERROR", gcLogFile) lcJSON = "" Endtry Return lcJSON Endfunc *-- Functie pentru curatarea textului web (HTML entities → ASCII simplu) Function CleanWebText Parameters tcText Local lcResult If Empty(tcText) Or Type('tcText') != 'C' Return "" Endif lcResult = tcText *-- Conversie HTML entities in caractere simple (fara diacritice) lcResult = Strtran(lcResult, 'ă', 'a') && ă → a lcResult = Strtran(lcResult, 'ș', 's') && ș → s lcResult = Strtran(lcResult, 'ț', 't') && ț → t lcResult = Strtran(lcResult, 'î', 'i') && î → i lcResult = Strtran(lcResult, 'â', 'a') && â → a lcResult = Strtran(lcResult, '&', '&') lcResult = Strtran(lcResult, '<', '<') lcResult = Strtran(lcResult, '>', '>') lcResult = Strtran(lcResult, '"', '"') *-- Eliminare tag-uri HTML simple lcResult = Strtran(lcResult, '
', ' ') lcResult = Strtran(lcResult, '
', ' ') lcResult = Strtran(lcResult, '
', ' ') *-- Eliminare Esc character lcResult = Strtran(lcResult, '\/', '/') Return Alltrim(lcResult) Endfunc *-- Functie pentru conversia datei web in format Oracle Function ConvertWebDate Parameters tcWebDate Local lcResult If Empty(tcWebDate) Or Type('tcWebDate') != 'C' Return Dtos(Date()) && yyyymmdd Endif *-- Web date format: "2025-08-27 16:32:43" → "20250827" lcResult = Strtran(Left(tcWebDate, 10), "-", "",1,10,1) *-- Validare format YYYYMMDD If Len(lcResult) = 8 Return lcResult Else Return Dtos(Date()) Endif Endfunc *-- Functie pentru conversia datei string in Date * ldData = String2Date('20250912', ['yyyymmdd']) Function String2Date Lparameters tcDate, tcFormat * tcDate: 20250911 * tcFormat: yyyymmdd (default) Local lcAn, lcDate, lcFormat, lcLuna, lcZi, ldData, lnAn, lnLuna, lnZi, loEx ldData = {} lcDate = m.tcDate lcFormat = Iif(!Empty(m.tcFormat), Alltrim(Lower(m.tcFormat)), 'yyyymmdd') lcDate = Chrtran(m.lcDate, '-/\','...') && inlocuiesc .-/\ cu . ca sa am doar variante yyyy.mm.dd, dd.mm.yyyy lcDate = Strtran(m.lcDate, '.', '', 1, 2, 1) lcFormat = Chrtran(m.lcFormat, '.-/\','...') lcFormat = Strtran(m.lcFormat, '.', '', 1, 2, 1) Do Case Case m.lcFormat = 'ddmmyyyy' lcAn = Substr(m.tcDate, 5, 4) lcLuna = Substr(m.tcDate, 3, 2) lcZi = Substr(m.tcDate, 1, 2) Otherwise * yyyymmdd lcAn = Substr(m.tcDate, 1, 4) lcLuna = Substr(m.tcDate, 5, 2) lcZi = Substr(m.tcDate, 7, 2) Endcase lnAn = Int(Val(m.lcAn)) lnLuna = Int(Val(m.lcLuna)) lnZi = Int(Val(m.lcZi)) Try ldData = Date(m.lnAn, m.lnLuna, m.lnZi) Catch To loEx ldData = {} Endtry Return m.ldData Endfunc *-- Functie pentru formatarea adresei in format semicolon pentru Oracle Function FormatAddressForOracle Parameters loBilling Local lcAdresa, lcJudet, lcOras, lcStrada *-- Extragere componente adresa lcJudet = Iif(Type('loBilling.region') = 'C', CleanWebText(loBilling.Region), "") lcOras = Iif(Type('loBilling.city') = 'C', CleanWebText(loBilling.city), "") lcStrada = Iif(Type('loBilling.address') = 'C', CleanWebText(loBilling.address), "") *-- Format semicolon cu prefix JUD: conform specificatiilor Oracle lcAdresa = "JUD:" + lcJudet + ";" + lcOras + ";" + lcStrada Return lcAdresa Endfunc *-- Functie pentru construirea observatiilor comenzii Function BuildOrderObservations Parameters loOrder Local lcObservatii lcObservatii = "" *-- Informatii plata si livrare If Type('loOrder.payment') = 'O' And Type('loOrder.payment.name') = 'C' lcObservatii = lcObservatii + "Payment: " + CleanWebText(loOrder.Payment.Name) + "; " Endif If Type('loOrder.delivery') = 'O' And Type('loOrder.delivery.name') = 'C' lcObservatii = lcObservatii + "Delivery: " + CleanWebText(loOrder.delivery.Name) + "; " Endif *-- Status si sursa If Type('loOrder.status') = 'C' lcObservatii = lcObservatii + "Status: " + CleanWebText(loOrder.Status) + "; " Endif If Type('loOrder.source') = 'C' lcObservatii = lcObservatii + "Source: " + CleanWebText(loOrder.Source) If Type('loOrder.sales_channel') = 'C' lcObservatii = lcObservatii + " " + CleanWebText(loOrder.sales_channel) Endif lcObservatii = lcObservatii + "; " Endif *-- Verificare adrese diferite shipping vs billing If Type('loOrder.shipping') = 'O' And Type('loOrder.billing') = 'O' If Type('loOrder.shipping.address') = 'C' And Type('loOrder.billing.address') = 'C' If !Alltrim(loOrder.shipping.address) == Alltrim(loOrder.billing.address) lcObservatii = lcObservatii + "Shipping: " + CleanWebText(loOrder.shipping.address) If Type('loOrder.shipping.city') = 'C' lcObservatii = lcObservatii + ", " + CleanWebText(loOrder.shipping.city) Endif lcObservatii = lcObservatii + "; " Endif Endif Endif *-- Limitare lungime observatii pentru Oracle If Len(lcObservatii) > 500 lcObservatii = Left(lcObservatii, 497) + "..." Endif Return lcObservatii Endfunc *-- Functie pentru obtinerea detaliilor erorii Oracle Function GetOracleErrorDetails Lparameters tcSql * tcSql (optional) : SQL executat Local lcError, laError[1], lnErrorLines, lnIndex lcError = "" *-- Obtinere eroare Oracle lnErrorLines = Aerror(laError) If lnErrorLines > 0 For lnIndex = 1 To lnErrorLines If lnIndex > 1 lcError = lcError + " | " Endif lcError = lcError + Alltrim(Str(laError[lnIndex, 1])) + ": " + laError[lnIndex, 2] Endfor Endif If Empty(lcError) lcError = "Eroare Oracle nedefinita" Endif lcError = Iif(Pcount() = 1 And !Empty(m.tcSql) And Type('tcSql') = 'C', m.tcSql + Chr(13) + Chr(10), '') + m.lcError Return lcError Endfunc *-- Functie pentru executia adapter-ului configurat Function ExecuteAdapter Local llSuccess, lcAdapterPath llSuccess = .F. Try lcAdapterPath = gcAppPath + goSettings.AdapterProgram If File(lcAdapterPath) LogMessage("Executie adapter: " + lcAdapterPath, "INFO", gcLogFile) Do (lcAdapterPath) llSuccess = .T. LogMessage("Adapter executat cu succes", "INFO", gcLogFile) Else LogMessage("EROARE: Adapter-ul nu a fost gasit la: " + lcAdapterPath, "ERROR", gcLogFile) Endif Catch To loError LogMessage("EXCEPTIE la executia adapter-ului " + goSettings.AdapterProgram + ": " + loError.Message, "ERROR", gcLogFile) Endtry Return llSuccess Endfunc *-- Orchestrator complet pentru sincronizarea comenzilor web cu Oracle ROA *-- Caracteristici: *-- - Citeste JSON-urile generate de gomag-vending.prg *-- - Proceseaza comenzile cu toate helper functions necesare *-- - Integreaza cu package-urile Oracle validate in Phase 1 *-- - Logging complet cu statistici de procesare *-- - Error handling pentru toate situatiile *-- - Support pentru toate formatele GoMag (billing/shipping, companii/persoane fizice)