{
  "_class" : "hudson.model.FreeStyleBuild",
  "actions" : [
    {
      "_class" : "hudson.model.CauseAction",
      "causes" : [
        {
          "_class" : "hudson.triggers.TimerTrigger$TimerTriggerCause",
          "shortDescription" : "Started by timer"
        }
      ]
    },
    {
      
    },
    {
      "_class" : "hudson.plugins.git.util.BuildData",
      "buildsByBranchName" : {
        "refs/remotes/origin/dev" : {
          "_class" : "hudson.plugins.git.util.Build",
          "buildNumber" : 738,
          "buildResult" : null,
          "marked" : {
            "SHA1" : "c11453c0e75288e9d497bff9644e55c9541eafea",
            "branch" : [
              {
                "SHA1" : "c11453c0e75288e9d497bff9644e55c9541eafea",
                "name" : "refs/remotes/origin/dev"
              }
            ]
          },
          "revision" : {
            "SHA1" : "c11453c0e75288e9d497bff9644e55c9541eafea",
            "branch" : [
              {
                "SHA1" : "c11453c0e75288e9d497bff9644e55c9541eafea",
                "name" : "refs/remotes/origin/dev"
              }
            ]
          }
        }
      },
      "lastBuiltRevision" : {
        "SHA1" : "c11453c0e75288e9d497bff9644e55c9541eafea",
        "branch" : [
          {
            "SHA1" : "c11453c0e75288e9d497bff9644e55c9541eafea",
            "name" : "refs/remotes/origin/dev"
          }
        ]
      },
      "remoteUrls" : [
        "https://github.com/younex1/erp-nuxt-frontend.git"
      ],
      "scmName" : ""
    },
    {
      
    },
    {
      
    },
    {
      "_class" : "org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction"
    }
  ],
  "artifacts" : [
    
  ],
  "building" : false,
  "description" : null,
  "displayName" : "#738",
  "duration" : 68685,
  "estimatedDuration" : 71602,
  "executor" : null,
  "fullDisplayName" : "build-logship-frontend #738",
  "id" : "738",
  "inProgress" : false,
  "keepLog" : false,
  "number" : 738,
  "queueId" : 5705,
  "result" : "SUCCESS",
  "timestamp" : 1789516800273,
  "url" : "https://jenkins.younex.de/view/all/job/build-logship-frontend/738/",
  "builtOn" : "",
  "changeSet" : {
    "_class" : "hudson.plugins.git.GitChangeSetList",
    "items" : [
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "app/components/dashboard/RecentCallsCard.vue",
          "server/api/telephony/blacklist.post.ts",
          "server/utils/telephony/blacklist.ts",
          "app/assets/langs/shared.js"
        ],
        "commitId" : "31601308527d637a24ce1dbb928085488affb6c8",
        "timestamp" : 1789459780000,
        "author" : {
          "absoluteUrl" : "https://jenkins.younex.de/user/info",
          "fullName" : "info"
        },
        "authorEmail" : "info@younex.de",
        "comment" : "Dashboard: add call-blacklist button to Recent Calls card\u000a\u000aAdmin-only \"Sperren\" action per row, writes to FreePBX's astdb-based\u000aBlacklist via AMI DBPut (no MySQL table involved) so future calls from\u000athat number are rejected immediately.\u000a",
        "date" : "2026-09-15 10:09:40 +0200",
        "id" : "31601308527d637a24ce1dbb928085488affb6c8",
        "msg" : "Dashboard: add call-blacklist button to Recent Calls card",
        "paths" : [
          {
            "editType" : "add",
            "file" : "server/utils/telephony/blacklist.ts"
          },
          {
            "editType" : "edit",
            "file" : "app/assets/langs/shared.js"
          },
          {
            "editType" : "edit",
            "file" : "app/components/dashboard/RecentCallsCard.vue"
          },
          {
            "editType" : "add",
            "file" : "server/api/telephony/blacklist.post.ts"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "server/utils/telephony/cdr.ts",
          "app/components/dashboard/RecentCallsCard.vue",
          "app/assets/langs/shared.js"
        ],
        "commitId" : "d8620a46b42efac1131bfce361e06bb2beec307b",
        "timestamp" : 1789460110000,
        "author" : {
          "absoluteUrl" : "https://jenkins.younex.de/user/info",
          "fullName" : "info"
        },
        "authorEmail" : "info@younex.de",
        "comment" : "Dashboard: always show Queue-routed calls on Recent Calls card\u000a\u000aPreviously the card only showed missed inbound + answered outbound,\u000aso support-line calls that came in via the Queue and got answered\u000a(possibly after a missed ring on another agent) never appeared.\u000aQueue-routed inbound calls now always show regardless of outcome;\u000adirect-dial inbound calls keep the missed-only behavior.\u000a",
        "date" : "2026-09-15 10:15:10 +0200",
        "id" : "d8620a46b42efac1131bfce361e06bb2beec307b",
        "msg" : "Dashboard: always show Queue-routed calls on Recent Calls card",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "server/utils/telephony/cdr.ts"
          },
          {
            "editType" : "edit",
            "file" : "app/components/dashboard/RecentCallsCard.vue"
          },
          {
            "editType" : "edit",
            "file" : "app/assets/langs/shared.js"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "app/pages/sales/sis/index.vue",
          "server/api/sales/sis/listings.get.ts",
          "server/utils/amazonSpApi.ts",
          "server/utils/sisMatching.ts",
          "server/api/sales/sis/price-update.post.ts"
        ],
        "commitId" : "89a23e942f5ea0be7a9453c79ffef0b394b352f6",
        "timestamp" : 1789462887000,
        "author" : {
          "absoluteUrl" : "https://jenkins.younex.de/user/info",
          "fullName" : "info"
        },
        "authorEmail" : "info@younex.de",
        "comment" : "SIS: fix intermittent load hang, safen Amazon price pushes, in-flight glow\u000a\u000aAmazon-side errors (report timeout, 429, ...) were silently triggering a\u000afull refresh-and-retry of the whole route (report poll + matching, or a\u000afull price push run twice) because event.context.lastIdempiereError is\u000aonly ever set by iDempiere calls — tag Amazon-origin errors and skip the\u000aretry for them. Also: timeouts + retry-after-aware backoff on every raw\u000aSP-API/LWA call (none had any before), parallelize the previously serial\u000aSKU/ASIN/price chunk lookups in sisMatching.ts, a real loading\u000aspinner/elapsed-time + client-side fetch timeout instead of a static\u000a\"Loading listings...\" line, and a per-order-source push queue so rapid\u000aper-field price pushes never burst past Amazon's ~1 req/sec limit.\u000a\u000aAlso adds the requested \"knight rider\" glowing border animation on a\u000aprice field while its push is in flight, handing off to the existing\u000asuccess/error flash once it resolves.\u000a\u000aCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>\u000aClaude-Session: https://claude.ai/code/session_013G7aDXCyYUwGgTG81QTP8E\u000a",
        "date" : "2026-09-15 11:01:27 +0200",
        "id" : "89a23e942f5ea0be7a9453c79ffef0b394b352f6",
        "msg" : "SIS: fix intermittent load hang, safen Amazon price pushes, in-flight glow",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "server/api/sales/sis/listings.get.ts"
          },
          {
            "editType" : "edit",
            "file" : "server/utils/amazonSpApi.ts"
          },
          {
            "editType" : "edit",
            "file" : "app/pages/sales/sis/index.vue"
          },
          {
            "editType" : "edit",
            "file" : "server/api/sales/sis/price-update.post.ts"
          },
          {
            "editType" : "edit",
            "file" : "server/utils/sisMatching.ts"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "server/api/telephony/recordings/audio.get.ts",
          "server/utils/telephony/recordings.ts"
        ],
        "commitId" : "11e64f412c360e3e27d2d2f1e62aceee6f5f3e2f",
        "timestamp" : 1789462899000,
        "author" : {
          "absoluteUrl" : "https://jenkins.younex.de/user/info",
          "fullName" : "info"
        },
        "authorEmail" : "info@younex.de",
        "comment" : "Telephony: fix call recording playback for .gsm files\u000a\u000aRecordings served as .gsm played inconsistently in the dashboard phone\u000acard and the contact-page recordings modal (\"play does nothing\" for\u000amost, \"player shows up\" only for .wav/.mp3) — no browser ships a native\u000aGSM 06.10 decoder, so the <audio> element just sits at\u000areadyState=HAVE_NOTHING forever with no error event. ffmpeg (already\u000aused to decode these same .gsm files for whisper transcription)\u000atranscodes .gsm to mp3 server-side before streaming; .wav/.mp3 pass\u000athrough unchanged.\u000a\u000aCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>\u000aClaude-Session: https://claude.ai/code/session_013G7aDXCyYUwGgTG81QTP8E\u000a",
        "date" : "2026-09-15 11:01:39 +0200",
        "id" : "11e64f412c360e3e27d2d2f1e62aceee6f5f3e2f",
        "msg" : "Telephony: fix call recording playback for .gsm files",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "server/api/telephony/recordings/audio.get.ts"
          },
          {
            "editType" : "edit",
            "file" : "server/utils/telephony/recordings.ts"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "app/pages/sales/returns/index.vue"
        ],
        "commitId" : "e7e99c24f3437370b725c5cd1ff3b75eb198bf86",
        "timestamp" : 1789463284000,
        "author" : {
          "absoluteUrl" : "https://jenkins.younex.de/user/info",
          "fullName" : "info"
        },
        "authorEmail" : "info@younex.de",
        "comment" : "Returns: add searchable Products column (line items + qty)\u000a\u000a/sales/returns now fetches ?withLines=1 (the M_InOutLine + nested\u000aM_Product_ID expand already used by the dashboard \"Letzte Retouren\"\u000acard) and shows the returned products with their quantities inline in\u000aa new grid column, with its own text filter — no master-detail.\u000a\u000aCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>\u000aClaude-Session: https://claude.ai/code/session_013G7aDXCyYUwGgTG81QTP8E\u000a",
        "date" : "2026-09-15 11:08:04 +0200",
        "id" : "e7e99c24f3437370b725c5cd1ff3b75eb198bf86",
        "msg" : "Returns: add searchable Products column (line items + qty)",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "app/pages/sales/returns/index.vue"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "app/pages/integrations/inventory-desktop.vue"
        ],
        "commitId" : "376abf176801739a3c3d427a56263898d657861c",
        "timestamp" : 1789470038000,
        "author" : {
          "absoluteUrl" : "https://jenkins.younex.de/user/info",
          "fullName" : "info"
        },
        "authorEmail" : "info@younex.de",
        "comment" : "Inventory Desktop: BOM tags + exclude-BOM filter on article search\u000a\u000aPorts the same excludeBom checkbox + BOM/JTL-BOM tags mobile/inventory.vue\u000aalready has on its article text search (server already supports both via\u000a/api/materials/products/search?excludeBom=), but defaults the checkbox to\u000achecked here — a physical stock count is about individually-located\u000aarticles, not kit/BOM headers, unlike the mobile default (unchecked).\u000a\u000aCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>\u000aClaude-Session: https://claude.ai/code/session_013G7aDXCyYUwGgTG81QTP8E\u000a",
        "date" : "2026-09-15 13:00:38 +0200",
        "id" : "376abf176801739a3c3d427a56263898d657861c",
        "msg" : "Inventory Desktop: BOM tags + exclude-BOM filter on article search",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "app/pages/integrations/inventory-desktop.vue"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "server/api/print/return-label.post.ts"
        ],
        "commitId" : "006f06ebd1f54f49f2fef962ffa4a48861c1a862",
        "timestamp" : 1789482747000,
        "author" : {
          "absoluteUrl" : "https://jenkins.younex.de/user/info",
          "fullName" : "info"
        },
        "authorEmail" : "info@younex.de",
        "comment" : "Return label: enlarge header-band text for readability\u000a\u000aCompany name and date/time in the dark top band were too small against\u000athe fill, especially on the common 74x52/56x75/102x152 label sizes.\u000aBumps bar height and font sizes on both sides and raises the minimum\u000ashrink-to-fit floor for long company names.\u000a",
        "date" : "2026-09-15 16:32:27 +0200",
        "id" : "006f06ebd1f54f49f2fef962ffa4a48861c1a862",
        "msg" : "Return label: enlarge header-band text for readability",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "server/api/print/return-label.post.ts"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "app/composables/useReturnLabelPrinter.ts",
          "server/api/print/return-label.post.ts",
          "app/components/NavBar.vue",
          "app/composables/states.ts",
          "app/components/rmas/ReturnLabelPrinterPicker.vue",
          "app/pages/mobile/return.vue",
          "app/pages/integrations/returns-desktop.vue"
        ],
        "commitId" : "8e1a9966727348cffb3a45f49e81b2eebed592d5",
        "timestamp" : 1789482760000,
        "author" : {
          "absoluteUrl" : "https://jenkins.younex.de/user/info",
          "fullName" : "info"
        },
        "authorEmail" : "info@younex.de",
        "comment" : "Return-label printer: org default + per-session override\u000a\u000aReturn labels no longer print per-article, so the legacy per-product\u000aprinter field (m_product.labelprinter_rma) no longer fits how they're\u000aused. Replaces it with a printer picker in the top navbar (desktop) /\u000areturns page header (mobile), admin-only (IsClientAdministrator), that\u000astaff switch per working place — remembered per device via localStorage\u000aso it survives reloads. Falls back to the org's CUST_Printer marked\u000a\"Default printer (for its type)\" (printerType=lab), else the lab\u000aprinter with the smallest id.\u000a\u000aAlso fixes a bug in /api/print/return-label where an explicit body.queue\u000aoverride was never actually consulted (labelPrinterId always defaulted\u000ato a truthy 'b', winning the || before queue was checked), and\u000aconsolidates return-label printing to one request per return instead of\u000agrouping lines by printer — a return is one label listing every article,\u000aso the old per-product grouping could silently split one return across\u000amultiple partial-article labels.\u000a",
        "date" : "2026-09-15 16:32:40 +0200",
        "id" : "8e1a9966727348cffb3a45f49e81b2eebed592d5",
        "msg" : "Return-label printer: org default + per-session override",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "app/pages/integrations/returns-desktop.vue"
          },
          {
            "editType" : "add",
            "file" : "app/components/rmas/ReturnLabelPrinterPicker.vue"
          },
          {
            "editType" : "edit",
            "file" : "app/components/NavBar.vue"
          },
          {
            "editType" : "edit",
            "file" : "server/api/print/return-label.post.ts"
          },
          {
            "editType" : "edit",
            "file" : "app/composables/states.ts"
          },
          {
            "editType" : "add",
            "file" : "app/composables/useReturnLabelPrinter.ts"
          },
          {
            "editType" : "edit",
            "file" : "app/pages/mobile/return.vue"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "app/components/sales/OrderForm.vue"
        ],
        "commitId" : "70d978c5f75ce97343d7740bbd8478a2c3d7b01d",
        "timestamp" : 1789482764000,
        "author" : {
          "absoluteUrl" : "https://jenkins.younex.de/user/info",
          "fullName" : "info"
        },
        "authorEmail" : "info@younex.de",
        "comment" : "Sales order edit: emphasize ship-to name over partner\u000a\u000aOn the completed-order shipping summary, the partner name was bold and\u000athe actual ship-to location (Name/Name2) was plain text, making it easy\u000ato misread which one the order ships to. Indents the partner row and\u000adrops its bold, and bolds the Name/Name2 values instead.\u000a",
        "date" : "2026-09-15 16:32:44 +0200",
        "id" : "70d978c5f75ce97343d7740bbd8478a2c3d7b01d",
        "msg" : "Sales order edit: emphasize ship-to name over partner",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "app/components/sales/OrderForm.vue"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "app/components/requests/MyTicketDetail.vue"
        ],
        "commitId" : "c11453c0e75288e9d497bff9644e55c9541eafea",
        "timestamp" : 1789483734000,
        "author" : {
          "absoluteUrl" : "https://jenkins.younex.de/user/info",
          "fullName" : "info"
        },
        "authorEmail" : "info@younex.de",
        "comment" : "My-Tickets: fix staff replies stamped with wrong org, hiding them from limited-role customers\u000a\u000asendMessage() stamped new r_requestupdate rows with the replying staff\u000amember's currently active org (logship_organization_id cookie) instead\u000aof the ticket's own org. A limited-role customer's access is scoped to\u000aonly their own org (IsAccessAllOrgs=false), so any reply written while\u000astaff had a different org active became invisible to them via\u000aiDempiere's row-level security — even though the ticket itself and\u000atheir own messages stayed visible. Every other send path in this file\u000a(accounting-flag note, assign-to-merchant, status actions) already\u000apreferred the ticket's own org with this exact fallback; only the main\u000acomposer's sendMessage() was missing it.\u000a\u000aConfirmed against production data: customer \"stoyan\" (Wonderhome) was\u000amissing 4 of 9 staff replies on ticket 1000426, all sent while support\u000ahad a different org active.\u000a",
        "date" : "2026-09-15 16:48:54 +0200",
        "id" : "c11453c0e75288e9d497bff9644e55c9541eafea",
        "msg" : "My-Tickets: fix staff replies stamped with wrong org, hiding them from limited-role customers",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "app/components/requests/MyTicketDetail.vue"
          }
        ]
      }
    ],
    "kind" : "git"
  },
  "culprits" : [
    {
      "absoluteUrl" : "https://jenkins.younex.de/user/info",
      "fullName" : "info"
    }
  ]
}