Enhance logging system with detailed product tracking and console cleanup
- Added comprehensive product logging to match order detail level - Moved all debug console messages to proper log files - Added JSON structure analysis logging for both products and orders - Enhanced per-page progress tracking with counts and warnings - Unified logging format with [PRODUCTS] and [ORDERS] prefixes - Removed SET STEP ON debug statement - All debug information now properly logged instead of console output 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
602
gomag-vending.prg
Normal file
602
gomag-vending.prg
Normal file
@@ -0,0 +1,602 @@
|
||||
*-- Script Visual FoxPro 9 pentru accesul la GoMag API cu paginare completa
|
||||
*-- Autor: Claude AI
|
||||
*-- Data: 26.08.2025
|
||||
|
||||
SET SAFETY OFF
|
||||
SET CENTURY ON
|
||||
SET DATE DMY
|
||||
SET EXACT ON
|
||||
SET ANSI ON
|
||||
SET DELETED ON
|
||||
|
||||
*-- Setari principale
|
||||
LOCAL lcApiBaseUrl, lcApiUrl, lcApiKey, lcUserAgent, lcContentType
|
||||
LOCAL loHttp, lcResponse, lcJsonResponse
|
||||
LOCAL laHeaders[10], lnHeaderCount
|
||||
Local lcApiShop, lcCsvFileName, lcErrorResponse, lcFileName, lcLogContent, lcLogFileName, lcPath
|
||||
Local lcStatusText, lnStatusCode, loError
|
||||
Local lnLimit, lnCurrentPage, llHasMorePages, loAllJsonData, lnTotalPages, lnTotalProducts
|
||||
Local lcOrderApiUrl, loAllOrderData, lcOrderCsvFileName, lcOrderJsonFileName
|
||||
Local ldStartDate, lcStartDateStr
|
||||
Local lcIniFile, loSettings
|
||||
LOCAL llGetProducts, llGetOrders
|
||||
PRIVATE gcAppPath, loJsonData, gcLogFile, gnStartTime, gnProductsProcessed, gnOrdersProcessed
|
||||
|
||||
|
||||
|
||||
gcAppPath = ADDBS(JUSTPATH(SYS(16,0)))
|
||||
SET DEFAULT TO (m.gcAppPath)
|
||||
lcPath = gcAppPath + 'nfjson;'
|
||||
SET PATH TO (m.lcPath) ADDITIVE
|
||||
|
||||
SET PROCEDURE TO utils.prg ADDITIVE
|
||||
SET PROCEDURE TO nfjsonread.prg ADDITIVE
|
||||
SET PROCEDURE TO nfjsoncreate.prg ADDITIVE
|
||||
|
||||
*-- Initializare logging si statistici
|
||||
gnStartTime = SECONDS()
|
||||
gnProductsProcessed = 0
|
||||
gnOrdersProcessed = 0
|
||||
gcLogFile = InitLog("gomag_sync")
|
||||
|
||||
*-- Cream directorul output daca nu existe
|
||||
LOCAL lcOutputDir
|
||||
lcOutputDir = gcAppPath + "output"
|
||||
IF !DIRECTORY(lcOutputDir)
|
||||
MKDIR (lcOutputDir)
|
||||
ENDIF
|
||||
|
||||
*-- Incarcarea setarilor din fisierul INI
|
||||
lcIniFile = gcAppPath + "settings.ini"
|
||||
|
||||
*-- Verificare existenta fisier INI
|
||||
IF !CheckIniFile(lcIniFile)
|
||||
LogMessage("ATENTIE: Fisierul settings.ini nu a fost gasit!", "WARN", gcLogFile)
|
||||
LogMessage("Cream un fisier settings.ini implicit...", "INFO", gcLogFile)
|
||||
IF CreateDefaultIni(lcIniFile)
|
||||
LogMessage("Fisier settings.ini creat cu succes.", "INFO", gcLogFile)
|
||||
LogMessage("IMPORTANT: Modifica setarile din settings.ini (ApiKey, ApiShop) inainte de a rula scriptul din nou!", "INFO", gcLogFile)
|
||||
RETURN .F.
|
||||
ELSE
|
||||
LogMessage("EROARE: Nu s-a putut crea fisierul settings.ini!", "ERROR", gcLogFile)
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
*-- Incarcarea setarilor
|
||||
loSettings = LoadSettings(lcIniFile)
|
||||
|
||||
*-- Verificare setari obligatorii
|
||||
IF EMPTY(loSettings.ApiKey) OR loSettings.ApiKey = "YOUR_API_KEY_HERE"
|
||||
LogMessage("EROARE: ApiKey nu este setat in settings.ini!", "ERROR", gcLogFile)
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
IF EMPTY(loSettings.ApiShop) OR "yourstore.gomag.ro" $ loSettings.ApiShop
|
||||
LogMessage("EROARE: ApiShop nu este setat corect in settings.ini!", "ERROR", gcLogFile)
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
*-- Configurare API din settings.ini
|
||||
lcApiBaseUrl = loSettings.ApiBaseUrl
|
||||
lcOrderApiUrl = loSettings.OrderApiUrl
|
||||
lcApiKey = loSettings.ApiKey
|
||||
lcApiShop = loSettings.ApiShop
|
||||
lcUserAgent = loSettings.UserAgent
|
||||
lcContentType = loSettings.ContentType
|
||||
lnLimit = loSettings.Limit
|
||||
llGetProducts = loSettings.GetProducts
|
||||
llGetOrders = loSettings.GetOrders
|
||||
lnCurrentPage = 1 && Pagina de start
|
||||
llHasMorePages = .T. && Flag pentru paginare
|
||||
loAllJsonData = NULL && Obiect pentru toate datele
|
||||
|
||||
*-- Calculare data pentru ultimele X zile (din settings.ini)
|
||||
ldStartDate = DATE() - loSettings.OrderDaysBack
|
||||
lcStartDateStr = TRANSFORM(YEAR(ldStartDate)) + "-" + ;
|
||||
RIGHT("0" + TRANSFORM(MONTH(ldStartDate)), 2) + "-" + ;
|
||||
RIGHT("0" + TRANSFORM(DAY(ldStartDate)), 2)
|
||||
|
||||
*-- Verificare daca avem WinHttp disponibil
|
||||
TRY
|
||||
loHttp = CREATEOBJECT("WinHttp.WinHttpRequest.5.1")
|
||||
CATCH TO loError
|
||||
LogMessage("Eroare la crearea obiectului WinHttp: " + loError.Message, "ERROR", gcLogFile)
|
||||
RETURN .F.
|
||||
ENDTRY
|
||||
*-- SECTIUNEA PRODUSE - se executa doar daca llGetProducts = .T.
|
||||
IF llGetProducts
|
||||
LogMessage("[PRODUCTS] Starting product retrieval", "INFO", gcLogFile)
|
||||
|
||||
*-- Bucla pentru preluarea tuturor produselor (paginare)
|
||||
loAllJsonData = CREATEOBJECT("Empty")
|
||||
ADDPROPERTY(loAllJsonData, "products", CREATEOBJECT("Empty"))
|
||||
ADDPROPERTY(loAllJsonData, "total", 0)
|
||||
ADDPROPERTY(loAllJsonData, "pages", 0)
|
||||
lnTotalProducts = 0
|
||||
|
||||
DO WHILE llHasMorePages
|
||||
*-- Construire URL cu paginare
|
||||
lcApiUrl = lcApiBaseUrl + "&page=" + TRANSFORM(lnCurrentPage) + "&limit=" + TRANSFORM(lnLimit)
|
||||
|
||||
LogMessage("[PRODUCTS] Page " + TRANSFORM(lnCurrentPage) + " fetching...", "INFO", gcLogFile)
|
||||
|
||||
*-- Configurare request
|
||||
TRY
|
||||
*-- Initializare request GET
|
||||
loHttp.Open("GET", lcApiUrl, .F.)
|
||||
|
||||
*-- Setare headers conform documentatiei GoMag
|
||||
loHttp.SetRequestHeader("User-Agent", lcUserAgent)
|
||||
loHttp.SetRequestHeader("Content-Type", lcContentType)
|
||||
loHttp.SetRequestHeader("Accept", "application/json")
|
||||
loHttp.SetRequestHeader("Apikey", lcApiKey) && Header pentru API Key
|
||||
loHttp.SetRequestHeader("ApiShop", lcApiShop) && Header pentru shop URL
|
||||
|
||||
*-- Setari timeout
|
||||
loHttp.SetTimeouts(30000, 30000, 30000, 30000) && 30 secunde pentru fiecare
|
||||
|
||||
*-- Trimitere request
|
||||
loHttp.Send()
|
||||
|
||||
*-- Verificare status code
|
||||
lnStatusCode = loHttp.Status
|
||||
lcStatusText = loHttp.StatusText
|
||||
|
||||
IF lnStatusCode = 200
|
||||
*-- Success - preluare raspuns
|
||||
lcResponse = loHttp.ResponseText
|
||||
|
||||
*-- Parsare JSON cu nfjson
|
||||
SET PATH TO nfjson ADDITIVE
|
||||
loJsonData = nfJsonRead(lcResponse)
|
||||
|
||||
IF !ISNULL(loJsonData)
|
||||
*-- Prima pagina - setam informatiile generale
|
||||
IF lnCurrentPage = 1
|
||||
LogMessage("[PRODUCTS] Analyzing JSON structure...", "INFO", gcLogFile)
|
||||
LOCAL ARRAY laJsonProps[1]
|
||||
lnPropCount = AMEMBERS(laJsonProps, loJsonData, 0)
|
||||
FOR lnDebugIndex = 1 TO MIN(lnPropCount, 10) && Primele 10 proprietati
|
||||
lcPropName = laJsonProps(lnDebugIndex)
|
||||
lcPropType = TYPE('loJsonData.' + lcPropName)
|
||||
LogMessage("[PRODUCTS] Property: " + lcPropName + " (Type: " + lcPropType + ")", "DEBUG", gcLogFile)
|
||||
ENDFOR
|
||||
|
||||
IF TYPE('loJsonData.total') = 'C' OR TYPE('loJsonData.total') = 'N'
|
||||
loAllJsonData.total = VAL(TRANSFORM(loJsonData.total))
|
||||
ENDIF
|
||||
IF TYPE('loJsonData.pages') = 'C' OR TYPE('loJsonData.pages') = 'N'
|
||||
loAllJsonData.pages = VAL(TRANSFORM(loJsonData.pages))
|
||||
ENDIF
|
||||
LogMessage("[PRODUCTS] Total items: " + TRANSFORM(loAllJsonData.total) + " | Pages: " + TRANSFORM(loAllJsonData.pages), "INFO", gcLogFile)
|
||||
ENDIF
|
||||
|
||||
*-- Adaugare produse din pagina curenta
|
||||
LOCAL llHasProducts, lnProductsFound
|
||||
llHasProducts = .F.
|
||||
lnProductsFound = 0
|
||||
|
||||
IF TYPE('loJsonData.products') = 'O'
|
||||
*-- Numaram produsele din obiectul products
|
||||
lnProductsFound = AMEMBERS(laProductsPage, loJsonData.products, 0)
|
||||
IF lnProductsFound > 0
|
||||
DO MergeProducts WITH loAllJsonData, loJsonData
|
||||
llHasProducts = .T.
|
||||
LogMessage("[PRODUCTS] Found: " + TRANSFORM(lnProductsFound) + " products in page " + TRANSFORM(lnCurrentPage), "INFO", gcLogFile)
|
||||
gnProductsProcessed = gnProductsProcessed + lnProductsFound
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
IF !llHasProducts
|
||||
LogMessage("[PRODUCTS] WARNING: No products found in JSON response for page " + TRANSFORM(lnCurrentPage), "WARN", gcLogFile)
|
||||
ENDIF
|
||||
|
||||
*-- Verificare daca mai sunt pagini
|
||||
IF TYPE('loJsonData.pages') = 'C' OR TYPE('loJsonData.pages') = 'N'
|
||||
lnTotalPages = VAL(TRANSFORM(loJsonData.pages))
|
||||
IF lnCurrentPage >= lnTotalPages
|
||||
llHasMorePages = .F.
|
||||
ENDIF
|
||||
ELSE
|
||||
*-- Daca nu avem info despre pagini, verificam daca sunt produse
|
||||
IF TYPE('loJsonData.products') != 'O'
|
||||
llHasMorePages = .F.
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
lnCurrentPage = lnCurrentPage + 1
|
||||
|
||||
ELSE
|
||||
*-- Salvare raspuns JSON raw in caz de eroare de parsare
|
||||
lcFileName = "gomag_error_page" + TRANSFORM(lnCurrentPage) + "_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".json"
|
||||
STRTOFILE(lcResponse, lcFileName)
|
||||
llHasMorePages = .F.
|
||||
ENDIF
|
||||
|
||||
ELSE
|
||||
*-- Eroare HTTP - salvare in fisier de log
|
||||
lcLogFileName = "gomag_error_page" + TRANSFORM(lnCurrentPage) + "_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".log"
|
||||
lcLogContent = "HTTP Error " + TRANSFORM(lnStatusCode) + ": " + lcStatusText + CHR(13) + CHR(10)
|
||||
|
||||
*-- Incearca sa citesti raspunsul pentru detalii despre eroare
|
||||
TRY
|
||||
lcErrorResponse = loHttp.ResponseText
|
||||
IF !EMPTY(lcErrorResponse)
|
||||
lcLogContent = lcLogContent + "Error Details:" + CHR(13) + CHR(10) + lcErrorResponse
|
||||
ENDIF
|
||||
CATCH
|
||||
lcLogContent = lcLogContent + "Could not read error details"
|
||||
ENDTRY
|
||||
|
||||
STRTOFILE(lcLogContent, lcLogFileName)
|
||||
llHasMorePages = .F.
|
||||
ENDIF
|
||||
|
||||
CATCH TO loError
|
||||
*-- Salvare erori in fisier de log pentru pagina curenta
|
||||
lcLogFileName = "gomag_error_page" + TRANSFORM(lnCurrentPage) + "_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".log"
|
||||
lcLogContent = "Script Error on page " + TRANSFORM(lnCurrentPage) + ":" + CHR(13) + CHR(10) +;
|
||||
"Error Number: " + TRANSFORM(loError.ErrorNo) + CHR(13) + CHR(10) +;
|
||||
"Error Message: " + loError.Message + CHR(13) + CHR(10) +;
|
||||
"Error Line: " + TRANSFORM(loError.LineNo)
|
||||
STRTOFILE(lcLogContent, lcLogFileName)
|
||||
llHasMorePages = .F.
|
||||
ENDTRY
|
||||
|
||||
*-- Pauza scurta intre cereri pentru a evita rate limiting
|
||||
IF llHasMorePages
|
||||
INKEY(1) && Pauza de 1 secunda
|
||||
ENDIF
|
||||
|
||||
ENDDO
|
||||
|
||||
*-- Salvare array JSON cu toate produsele
|
||||
IF !ISNULL(loAllJsonData) AND TYPE('loAllJsonData.products') = 'O'
|
||||
lcJsonFileName = lcOutputDir + "\gomag_all_products_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".json"
|
||||
DO SaveProductsArray WITH loAllJsonData, lcJsonFileName
|
||||
LogMessage("[PRODUCTS] JSON saved: " + lcJsonFileName, "INFO", gcLogFile)
|
||||
*-- Calculam numarul de produse procesate
|
||||
IF TYPE('loAllJsonData.products') = 'O'
|
||||
LOCAL ARRAY laProducts[1]
|
||||
lnPropCount = AMEMBERS(laProducts, loAllJsonData.products, 0)
|
||||
gnProductsProcessed = lnPropCount
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
ELSE
|
||||
LogMessage("[PRODUCTS] Skipped product retrieval (llGetProducts = .F.)", "INFO", gcLogFile)
|
||||
ENDIF
|
||||
|
||||
*-- SECTIUNEA COMENZI - se executa doar daca llGetOrders = .T.
|
||||
IF llGetOrders
|
||||
LogMessage("[ORDERS] =======================================", "INFO", gcLogFile)
|
||||
LogMessage("[ORDERS] RETRIEVING ORDERS FROM LAST " + TRANSFORM(loSettings.OrderDaysBack) + " DAYS", "INFO", gcLogFile)
|
||||
LogMessage("[ORDERS] Start date: " + lcStartDateStr, "INFO", gcLogFile)
|
||||
LogMessage("[ORDERS] =======================================", "INFO", gcLogFile)
|
||||
|
||||
*-- Reinitializare pentru comenzi
|
||||
lnCurrentPage = 1
|
||||
llHasMorePages = .T.
|
||||
loAllOrderData = CREATEOBJECT("Empty")
|
||||
ADDPROPERTY(loAllOrderData, "orders", CREATEOBJECT("Empty"))
|
||||
ADDPROPERTY(loAllOrderData, "total", 0)
|
||||
ADDPROPERTY(loAllOrderData, "pages", 0)
|
||||
|
||||
*-- Bucla pentru preluarea comenzilor
|
||||
DO WHILE llHasMorePages
|
||||
*-- Construire URL cu paginare si filtrare pe data (folosind startDate conform documentatiei GoMag)
|
||||
lcApiUrl = lcOrderApiUrl + "?startDate=" + lcStartDateStr + "&page=" + TRANSFORM(lnCurrentPage) + "&limit=" + TRANSFORM(lnLimit)
|
||||
|
||||
LogMessage("[ORDERS] Page " + TRANSFORM(lnCurrentPage) + " fetching...", "INFO", gcLogFile)
|
||||
|
||||
*-- Configurare request
|
||||
TRY
|
||||
*-- Initializare request GET
|
||||
loHttp.Open("GET", lcApiUrl, .F.)
|
||||
|
||||
*-- Setare headers conform documentatiei GoMag
|
||||
loHttp.SetRequestHeader("User-Agent", lcUserAgent)
|
||||
loHttp.SetRequestHeader("Content-Type", lcContentType)
|
||||
loHttp.SetRequestHeader("Accept", "application/json")
|
||||
loHttp.SetRequestHeader("Apikey", lcApiKey) && Header pentru API Key
|
||||
loHttp.SetRequestHeader("ApiShop", lcApiShop) && Header pentru shop URL
|
||||
|
||||
*-- Setari timeout
|
||||
loHttp.SetTimeouts(30000, 30000, 30000, 30000) && 30 secunde pentru fiecare
|
||||
|
||||
*-- Trimitere request
|
||||
loHttp.Send()
|
||||
|
||||
*-- Verificare status code
|
||||
lnStatusCode = loHttp.Status
|
||||
lcStatusText = loHttp.StatusText
|
||||
|
||||
IF lnStatusCode = 200
|
||||
*-- Success - preluare raspuns
|
||||
lcResponse = loHttp.ResponseText
|
||||
|
||||
*-- Parsare JSON cu nfjson
|
||||
SET PATH TO nfjson ADDITIVE
|
||||
loJsonData = nfJsonRead(lcResponse)
|
||||
|
||||
IF !ISNULL(loJsonData)
|
||||
*-- Debug: Afisam structura JSON pentru prima pagina
|
||||
IF lnCurrentPage = 1
|
||||
LogMessage("[ORDERS] Analyzing JSON structure...", "INFO", gcLogFile)
|
||||
LOCAL ARRAY laJsonProps[1]
|
||||
lnPropCount = AMEMBERS(laJsonProps, loJsonData, 0)
|
||||
FOR lnDebugIndex = 1 TO MIN(lnPropCount, 10) && Primele 10 proprietati
|
||||
lcPropName = laJsonProps(lnDebugIndex)
|
||||
lcPropType = TYPE('loJsonData.' + lcPropName)
|
||||
LogMessage("[ORDERS] Property: " + lcPropName + " (Type: " + lcPropType + ")", "DEBUG", gcLogFile)
|
||||
ENDFOR
|
||||
ENDIF
|
||||
|
||||
*-- Prima pagina - setam informatiile generale din metadata
|
||||
IF lnCurrentPage = 1
|
||||
IF TYPE('loJsonData.total') = 'C' OR TYPE('loJsonData.total') = 'N'
|
||||
loAllOrderData.total = VAL(TRANSFORM(loJsonData.total))
|
||||
ENDIF
|
||||
IF TYPE('loJsonData.pages') = 'C' OR TYPE('loJsonData.pages') = 'N'
|
||||
loAllOrderData.pages = VAL(TRANSFORM(loJsonData.pages))
|
||||
ENDIF
|
||||
LogMessage("[ORDERS] Total orders: " + TRANSFORM(loAllOrderData.total), "INFO", gcLogFile)
|
||||
LogMessage("[ORDERS] Total pages: " + TRANSFORM(loAllOrderData.pages), "INFO", gcLogFile)
|
||||
ENDIF
|
||||
|
||||
*-- Adaugare comenzi din pagina curenta
|
||||
*-- API-ul GoMag returneaza obiect cu metadata si orders
|
||||
LOCAL llHasOrders, lnOrdersFound
|
||||
llHasOrders = .F.
|
||||
lnOrdersFound = 0
|
||||
|
||||
*-- Verificam daca avem obiectul orders
|
||||
IF TYPE('loJsonData.orders') = 'O'
|
||||
*-- Numaram comenzile din obiectul orders
|
||||
lnOrdersFound = AMEMBERS(laOrdersPage, loJsonData.orders, 0)
|
||||
IF lnOrdersFound > 0
|
||||
*-- Mergem comenzile din pagina curenta
|
||||
DO MergeOrdersArray WITH loAllOrderData, loJsonData
|
||||
llHasOrders = .T.
|
||||
LogMessage("[ORDERS] Found: " + TRANSFORM(lnOrdersFound) + " orders in page " + TRANSFORM(lnCurrentPage), "INFO", gcLogFile)
|
||||
gnOrdersProcessed = gnOrdersProcessed + lnOrdersFound
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
IF !llHasOrders
|
||||
LogMessage("[ORDERS] WARNING: No orders found in JSON response for page " + TRANSFORM(lnCurrentPage), "WARN", gcLogFile)
|
||||
ENDIF
|
||||
|
||||
*-- Verificare daca mai sunt pagini folosind metadata
|
||||
IF TYPE('loJsonData.pages') = 'C' OR TYPE('loJsonData.pages') = 'N'
|
||||
lnTotalPages = VAL(TRANSFORM(loJsonData.pages))
|
||||
IF lnCurrentPage >= lnTotalPages
|
||||
llHasMorePages = .F.
|
||||
ENDIF
|
||||
ELSE
|
||||
*-- Fallback: verifica daca am primit mai putin decat limita
|
||||
IF !llHasOrders OR lnOrdersFound < lnLimit
|
||||
llHasMorePages = .F.
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
lnCurrentPage = lnCurrentPage + 1
|
||||
|
||||
ELSE
|
||||
*-- Salvare raspuns JSON raw in caz de eroare de parsare
|
||||
lcFileName = "gomag_order_error_page" + TRANSFORM(lnCurrentPage) + "_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".json"
|
||||
STRTOFILE(lcResponse, lcFileName)
|
||||
llHasMorePages = .F.
|
||||
ENDIF
|
||||
|
||||
ELSE
|
||||
*-- Eroare HTTP - salvare in fisier de log
|
||||
lcLogFileName = "gomag_order_error_page" + TRANSFORM(lnCurrentPage) + "_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".log"
|
||||
lcLogContent = "HTTP Error " + TRANSFORM(lnStatusCode) + ": " + lcStatusText + CHR(13) + CHR(10)
|
||||
|
||||
*-- Incearca sa citesti raspunsul pentru detalii despre eroare
|
||||
TRY
|
||||
lcErrorResponse = loHttp.ResponseText
|
||||
IF !EMPTY(lcErrorResponse)
|
||||
lcLogContent = lcLogContent + "Error Details:" + CHR(13) + CHR(10) + lcErrorResponse
|
||||
ENDIF
|
||||
CATCH
|
||||
lcLogContent = lcLogContent + "Could not read error details"
|
||||
ENDTRY
|
||||
|
||||
STRTOFILE(lcLogContent, lcLogFileName)
|
||||
llHasMorePages = .F.
|
||||
ENDIF
|
||||
|
||||
CATCH TO loError
|
||||
*-- Salvare erori in fisier de log pentru pagina curenta
|
||||
lcLogFileName = "gomag_order_error_page" + TRANSFORM(lnCurrentPage) + "_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".log"
|
||||
lcLogContent = "Script Error on page " + TRANSFORM(lnCurrentPage) + ":" + CHR(13) + CHR(10) +;
|
||||
"Error Number: " + TRANSFORM(loError.ErrorNo) + CHR(13) + CHR(10) +;
|
||||
"Error Message: " + loError.Message + CHR(13) + CHR(10) +;
|
||||
"Error Line: " + TRANSFORM(loError.LineNo)
|
||||
STRTOFILE(lcLogContent, lcLogFileName)
|
||||
llHasMorePages = .F.
|
||||
ENDTRY
|
||||
|
||||
*-- Pauza scurta intre cereri pentru a evita rate limiting
|
||||
IF llHasMorePages
|
||||
INKEY(1) && Pauza de 1 secunda
|
||||
ENDIF
|
||||
|
||||
ENDDO
|
||||
|
||||
*-- Salvare array JSON cu toate comenzile
|
||||
IF !ISNULL(loAllOrderData) AND TYPE('loAllOrderData.orders') = 'O'
|
||||
lcOrderJsonFileName = lcOutputDir + "\gomag_orders_last7days_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".json"
|
||||
DO SaveOrdersArray WITH loAllOrderData, lcOrderJsonFileName
|
||||
LogMessage("[ORDERS] JSON file created: " + lcOrderJsonFileName, "INFO", gcLogFile)
|
||||
ENDIF
|
||||
|
||||
ELSE
|
||||
LogMessage("[ORDERS] Skipped order retrieval (llGetOrders = .F.)", "INFO", gcLogFile)
|
||||
ENDIF
|
||||
|
||||
*-- Curatare
|
||||
loHttp = NULL
|
||||
|
||||
*-- Inchidere logging cu statistici finale
|
||||
CloseLog(gnStartTime, gnProductsProcessed, gnOrdersProcessed, gcLogFile)
|
||||
|
||||
|
||||
*-- Functie pentru salvarea array-ului de produse in format JSON
|
||||
PROCEDURE SaveProductsArray
|
||||
PARAMETERS tloAllData, tcFileName
|
||||
|
||||
LOCAL lcJsonContent, lnPropCount, lnIndex, lcPropName, loProduct
|
||||
|
||||
*-- Incepe array-ul JSON
|
||||
lcJsonContent = "[" + CHR(13) + CHR(10)
|
||||
|
||||
*-- Verifica daca avem produse
|
||||
IF TYPE('tloAllData.products') = 'O'
|
||||
lnPropCount = AMEMBERS(laProducts, tloAllData.products, 0)
|
||||
|
||||
FOR lnIndex = 1 TO lnPropCount
|
||||
lcPropName = laProducts(lnIndex)
|
||||
loProduct = EVALUATE('tloAllData.products.' + lcPropName)
|
||||
|
||||
IF TYPE('loProduct') = 'O'
|
||||
*-- Adauga virgula pentru elementele anterioare
|
||||
IF lnIndex > 1
|
||||
lcJsonContent = lcJsonContent + "," + CHR(13) + CHR(10)
|
||||
ENDIF
|
||||
|
||||
*-- Serializeaza produsul cu nfjsoncreate
|
||||
lcProductJson = nfJsonCreate(loProduct, .F.)
|
||||
lcJsonContent = lcJsonContent + " " + lcProductJson
|
||||
ENDIF
|
||||
ENDFOR
|
||||
ENDIF
|
||||
|
||||
*-- Inchide array-ul JSON
|
||||
lcJsonContent = lcJsonContent + CHR(13) + CHR(10) + "]"
|
||||
|
||||
*-- Salveaza fisierul
|
||||
STRTOFILE(lcJsonContent, tcFileName)
|
||||
|
||||
ENDPROC
|
||||
|
||||
*-- Functie pentru salvarea array-ului de comenzi in format JSON
|
||||
PROCEDURE SaveOrdersArray
|
||||
PARAMETERS tloAllData, tcFileName
|
||||
|
||||
LOCAL lcJsonContent, lnPropCount, lnIndex, lcPropName, loOrder
|
||||
|
||||
*-- Incepe array-ul JSON
|
||||
lcJsonContent = "[" + CHR(13) + CHR(10)
|
||||
|
||||
*-- Verifica daca avem comenzi
|
||||
IF TYPE('tloAllData.orders') = 'O'
|
||||
lnPropCount = AMEMBERS(laOrders, tloAllData.orders, 0)
|
||||
|
||||
FOR lnIndex = 1 TO lnPropCount
|
||||
lcPropName = laOrders(lnIndex)
|
||||
loOrder = EVALUATE('tloAllData.orders.' + lcPropName)
|
||||
|
||||
IF TYPE('loOrder') = 'O'
|
||||
*-- Adauga virgula pentru elementele anterioare
|
||||
IF lnIndex > 1
|
||||
lcJsonContent = lcJsonContent + "," + CHR(13) + CHR(10)
|
||||
ENDIF
|
||||
|
||||
*-- Serializeaza comanda cu nfjsoncreate
|
||||
lcOrderJson = nfJsonCreate(loOrder, .F.)
|
||||
lcJsonContent = lcJsonContent + " " + lcOrderJson
|
||||
ENDIF
|
||||
ENDFOR
|
||||
ENDIF
|
||||
|
||||
*-- Inchide array-ul JSON
|
||||
lcJsonContent = lcJsonContent + CHR(13) + CHR(10) + "]"
|
||||
|
||||
*-- Salveaza fisierul
|
||||
STRTOFILE(lcJsonContent, tcFileName)
|
||||
|
||||
ENDPROC
|
||||
|
||||
*-- Functie pentru unirea produselor din toate paginile (versiune simpla)
|
||||
PROCEDURE MergeProducts
|
||||
PARAMETERS tloAllData, tloPageData
|
||||
|
||||
LOCAL lnPropCount, lnIndex, lcPropName, loProduct
|
||||
|
||||
*-- Verifica daca avem produse in pagina curenta
|
||||
IF TYPE('tloPageData.products') = 'O'
|
||||
*-- Itereaza prin toate produsele din pagina
|
||||
lnPropCount = AMEMBERS(laPageProducts, tloPageData.products, 0)
|
||||
|
||||
FOR lnIndex = 1 TO lnPropCount
|
||||
lcPropName = laPageProducts(lnIndex)
|
||||
loProduct = EVALUATE('tloPageData.products.' + lcPropName)
|
||||
|
||||
IF TYPE('loProduct') = 'O'
|
||||
*-- Adauga produsul la colectia principala
|
||||
ADDPROPERTY(tloAllData.products, lcPropName, loProduct)
|
||||
ENDIF
|
||||
ENDFOR
|
||||
ENDIF
|
||||
|
||||
ENDPROC
|
||||
|
||||
*-- Functie pentru unirea comenzilor din array direct (structura GoMag)
|
||||
PROCEDURE MergeOrdersArray
|
||||
PARAMETERS tloAllData, tloPageData
|
||||
|
||||
LOCAL lnPropCount, lnIndex, lcPropName, loOrder
|
||||
|
||||
*-- Verifica daca avem comenzi in pagina curenta
|
||||
IF TYPE('tloPageData.orders') = 'O'
|
||||
*-- Itereaza prin toate comenzile din pagina (array direct)
|
||||
lnPropCount = AMEMBERS(laPageOrders, tloPageData.orders, 0)
|
||||
|
||||
FOR lnIndex = 1 TO lnPropCount
|
||||
lcPropName = laPageOrders(lnIndex)
|
||||
loOrder = EVALUATE('tloPageData.orders.' + lcPropName)
|
||||
|
||||
IF TYPE('loOrder') = 'O'
|
||||
*-- Folosim ID-ul comenzii ca nume proprietate, sau un index secvential
|
||||
LOCAL lcOrderId
|
||||
lcOrderId = ""
|
||||
IF TYPE('loOrder.id') = 'C'
|
||||
lcOrderId = "order_" + loOrder.id
|
||||
ELSE
|
||||
lcOrderId = "order_" + TRANSFORM(lnIndex)
|
||||
ENDIF
|
||||
|
||||
*-- Adauga comanda la colectia principala
|
||||
ADDPROPERTY(tloAllData.orders, lcOrderId, loOrder)
|
||||
ENDIF
|
||||
ENDFOR
|
||||
ENDIF
|
||||
|
||||
ENDPROC
|
||||
|
||||
*-- Functiile utilitare au fost mutate in utils.prg
|
||||
|
||||
*-- Scriptul cu paginare completa pentru preluarea tuturor produselor si comenzilor
|
||||
*-- Caracteristici principale:
|
||||
*-- - Paginare automata pentru toate produsele si comenzile
|
||||
*-- - Pauze intre cereri pentru respectarea rate limiting
|
||||
*-- - Salvare JSON array-uri pure (fara metadata de paginare)
|
||||
*-- - Utilizare nfjsoncreate pentru generare JSON corecta
|
||||
*-- - Logging separat pentru fiecare pagina in caz de eroare
|
||||
*-- - Afisare progres in timpul executiei
|
||||
|
||||
*-- INSTRUCTIUNI DE UTILIZARE:
|
||||
*-- 1. Modifica settings.ini cu setarile tale:
|
||||
*-- - ApiKey: cheia ta API de la GoMag
|
||||
*-- - ApiShop: URL-ul magazinului tau
|
||||
*-- - GetProducts: 1 pentru a prelua produse, 0 pentru a sari peste
|
||||
*-- - GetOrders: 1 pentru a prelua comenzi, 0 pentru a sari peste
|
||||
*-- - OrderDaysBack: numarul de zile pentru preluarea comenzilor
|
||||
*-- 2. Ruleaza scriptul - va prelua doar ce ai selectat
|
||||
*-- 3. Verifica fisierele JSON generate cu array-uri pure
|
||||
|
||||
*-- Script optimizat cu salvare JSON array-uri - verificati fisierele generate
|
||||
Reference in New Issue
Block a user