Genereret: 2026-09-15 16:01:02
| Beskrivelse |
|---|
| #1541 - 0-fakturaer danner nu Debitor-/Kreditorposter + div. småforbedringer (15-09-26 16:00) 0-fakturaer (bruttobeløb 0) blev hidtil undertrykt og dannede hverken debitor- eller kreditorpost. De danner nu poster som alle andre fakturaer. Derudover en række mindre forbedringer. 0-fakturaer danner nu Debitor-/Kreditorposter`FILE/SFaktura.PTD` (trigger `DSAMLEPOST`) og `FILE/IFaktura.PTD` (trigger `KSAMLEPOST`): `Brutto`-betingelsen er fjernet fra begge triggeres `CanExecute`. ```diff
``` `Brutto` er falsk ved beløb 0, så samleposten blev slet ikke dannet — fakturaen fandtes kun i fakturajournalen og var usynlig i reskontroen. Øvrige betingelser er uændrede. Dagssaldo i bankafstemning
Valuta ved manuel import af bankposter`TASK/Import_BankPost_Generisk.PTD`: `Valuta` blev ikke sat ved generisk import, hvilket gav poster uden valuta på valutabankkonti. Den hentes nu fra bankkontoens finanskonto via `lookup(Finans.Valuta;1;lookup(Bankkonti.Kontonr;1;#BankKonto))`. `if`-vagten sikrer, at feltet kun sættes når kontoen faktisk har en valuta — konti i systemvaluta røres ikke. BS — tilføj ekstra bilag
Sordrekort værksted`TASK/SORDREKORT_VÆRKS.PTD`:
Valgfrie tekster på arbejdskort`TASK/UARBEJDSKORT.PTD`:
Til reviewer: diff-støj i SFaktura.PTDFilen fremstår med ca. 4.500 ændrede linjer, fordi den er EOL-normaliseret CRLF → LF ved commit (`core.autocrlf`). Indholdet er uændret bortset fra `CanExecute`-linjen ovenfor og nogle kommentarer, hvor efterstillet whitespace er brudt om på ny linje. **Slå "ignorer whitespace" til** — så er ændringen 17 linjer. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
#1514 - WEB_API_TokenGrp: AuthMode EntraID Intern / Statisk + EntraID Intern, DefaultUser required for External modes (13-09-26 19:38)What`FILE/WEB_API_TokenGrp.PTD` only.
WhyThe server (Keybalance2018 branch `feature/apiv3-license-filter`) binds every Entra-authenticated APIv3 call to a real Bruger and enforces that user's standard access controls. External modes run as `DefaultUser`, so a group in one of those modes without it is skipped at config build. This PR makes the PTD enforce the same rule at save time and offers the two Internal modes. Notes
🤖 Generated with [Claude Code](https://claude.com/claude-code) |
| #1479 - Brug TSAkt i stedet for HRTimer (08-09-26 19:18) Brug TSAkt i stedet for HRTimer |
#1489 - Aktivitetsteksten blev hentet fra den forkerte fil og blankede feltet (08-09-26 11:23)ResuméI `OpdaterJobFørDag` slår opslaget aktivitetsteksten op i **`TSAktivitet`** i stedet for **`TSBCAktivitet`** — `TSBC` er faldet ud af en kopi af linjen. Nøgle 1 i `TSAktivitet` er `KEY Kørselnr`, hvis første segment er det ulong `Kørselnr`. Opslaget søger altså på et *kørselsnummer* med et *ydelsesnummer*. Resultatet er enten en tom tekst eller en vilkårlig fremmed aktivitets tekst — hver gang `Bemærk1` er tom. ```
``` Den korrekte form står i samme fil 141 linjer længere oppe, i søster-tasken `OpdaterJobFørSammeDag` (linje 172), og i forældre-tasken (linje 94). `TSBCAktivitet` nøgle 1 er `KEY I_ID` med ét segment, `Navn`, `BString(10)` — samme type og længde som `VNummer`. Fejlen har vist sig i Sentry som **Compare failed** med `TSAktivitet:Kørselnr` (B_ULONG) mod et streng-udtryk, bruger SUSANNE S, licens BTM. Overflødig tildeling fjernet`TSAktivitet2.Tekst = TSBCF.Bemærk1;` stod umiddelbart før `if TSBCF.Bemærk1 then TSAktivitet2.Tekst = TSBCF.Bemærk1`. Den er formentlig grunden til at fejlen har kunnet ligge upåagtet: teksten så rigtig ud så længe `Bemærk1` var udfyldt. Blokken er nu identisk med søster-taskens. Filer
Filen er samtidig konverteret fra **cp1252 til UTF-8**. Det er de øvrige 19 linjer i diffen — rene `æ ø å`, ingen indholdsændring. Linjeskift (CRLF) er uændrede. Test
🤖 Generated with [Claude Code](https://claude.com/claude-code) |
| #1424 - Forbedring af CRM kundeemne-kort i klient og app (08-09-26 09:58) Forbedring af kundeemne-kortet, så det både i klienten og i app'en (WE) fremstår som en færdig funktion frem for en demo. Klient — `TASK/CRM_Map.PTD`
"Viser alle oplysninger om kontoen".
App/WE — ny `TASK/CRM_Map_WE.ptd`
på at `AdrLat`/`AdrLng` er sat (`FromTo( [0,01..] )`).
Menu og handlingsliste
der pegede på `actTEST_DebitorMap2_WE`. Licens/modul — `MODULEMAIN/MODULES.PTD`
(som ikke understøtter kontrollen). Da ribbon-menuen i dag kun kører i den nye klient og hovedmenuen mest i den gamle, er den gating ikke relevant længere. Bemærkninger
referencer.
|
| #1437 - Div forbedringer: POSuid på debitor, mailvalg ved nyt password, BC-ID fallback (08-09-26 09:52) En blanding af mindre forbedringer og rettelser på tværs af debitorstamdata, FlexPos-integrationen, bankfileksport, brugeradministration og bilagsgodkendelse. --- Debitor — nyt felt POSuid`FILE/Debitor.PTD`
hvis flere debitorer skulle ende med samme POSuid. FlexPos — UID flyttet fra Bemærk3 til POSuid`TASK/FlexPosAPI_Customer.PTD` FlexPos-kundens UID blev hidtil gemt i `Debitor.Bemærk3` — et generelt notatfelt, der ligger frit redigerbart på debitorkortet sammen med Bemærk1 og Bemærk2. Et forkert tastetryk dér kunne afkoble debitoren fra sin FlexPos-kunde. UID'et genereres og gemmes nu i `Debitor.POSuid`, som både er dedikeret til formålet og har en nøgle. `Bemærk3` er dermed frigivet til sit egentlige brug. FlexPos — find debitor på POSuid`TASK/FlexPosApi_SalgBon.PTD` Kæden, der finder debitoren til en bon, har hidtil kun kunnet slå op i `FlexPos_Customer`. Rammer `Customer_UID` ikke en kunde dér, blev bonnen sendt videre til afdelingens standarddebitor, selvom kunden godt kunne findes i KeyBalance. Opslagsrækkefølgen er nu: 1. `FlexPos_Customer.ID1` på `Customer_UID` (uændret) 2. **`Debitor.POSuid` på `Customer_UID`** (ny) 3. `FlexPos_CUnit_ID` på ClientID + Unit_ID 4. `FlexPos_Setup.DKontonr` som sidste udvej Fil-varianten `FlexPos_SalgBon` er bevidst ikke rørt — FlexPos uden API er under udfasning, og ny funktionalitet lægges kun i API-varianten. Nyt password — vælg hvordan mailen sendes`TASK/Bruger_NytPassword.ptd`
Med Outlook-valget popper mailen op i et åbent Outlook-vindue i stedet for at blive sendt afsted med det samme. Dermed kan koden læses på skærmen og videregives ad anden vej — fx til den, der skal instruere brugeren — inden mailen eventuelt sendes. Tidligere kørte den eneste blok altid (`ShouldExecute( 1 )`). Bankfileksport — Id-tag faldt tilbage til tom værdi`TASK/EXPORT_BANK_ISO20022_Fil.PTD` `Id`-tagget under afsenderidentifikationen blev udfyldt ud fra bankcentralen (BANKDATA/SDC → `BC_Funktion`, BEC → `00` + SE-nr). Var det pågældende felt ikke udfyldt — eller var bankcentralen en anden — returnerede beregningen ingenting, og filen kom afsted med et tomt `Id`, som banken afviser. Betingelserne kræver nu, at værdien rent faktisk findes, og der er tilføjet en generel fallback til firmaets SE-nr, så tagget altid får indhold. Bilagsgodkendelse — versalufølsom sammenligning`TASK/BS_GodkendEgneUdv.PTD` `CanEnter` sammenlignede `BS_Bilag_Godkend.Godkender` direkte med `user()`. Er godkenderen registreret med anden bogstavskasse end brugerens login, kunne brugeren ikke åbne sine egne bilag. Sammenligningen er nu pakket i `toupper()` i begge sider. Bemærk: gruppeopslaget i samme udtryk (`lookup(Medarbejder.BS_GodkGrp;1;user()) == BS_Bilag_Godkend.Godkender`) er stadig versalfølsomt — det er bevidst ikke rørt her, da det sammenligner en godkendergruppe og ikke et brugernavn. --- Til gennemsyn — eksisterende dataFlytningen af FlexPos-UID fra `Bemærk3` til `POSuid` rammer kun nye debitorer af sig selv. Debitorer, der **allerede** er synkroniseret til FlexPos, har deres UID liggende i `Bemærk3` og har tom `POSuid`. Kører `FlexPosAPI_Customer` på dem, får de tildelt et nyt guid og oprettes som **nye** kunder i FlexPos ved siden af de eksisterende. Inden dette rulles ud på en installation med data i FlexPos, skal eksisterende værdier derfor kopieres fra `Bemærk3` til `POSuid`. |
#1454 - Outlook Plugin: skrivbare tasks til KundeEmne og KontaktPerson (01-09-26 20:16)FormålKB Outlook Plugin (Standard V1) kunne indtil nu kun læse stamdata på KundeEmne og KontaktPerson via `API_OP_S1_KE` og `API_OP_S1_KP`. Denne PR tilføjer to skrivbare søster-tasks, så stamdata kan rettes direkte fra Outlook uden at skifte over i klienten. TASK/API_OP_S1_KERW.ptd (ny)Skrivbar task på `KundeEmne` — `TaskMode = Update`. Kolonner: Kontonr, Navn, Adr1, PostNr, ByNavn, Land, Tlf, EmailDomæne. Modsat `API_OP_S1_KE` er der ingen subtasks (Debitorpost/SFaktura), da RW-tasken kun bruges til redigering af selve stamkortet. TASK/API_OP_S1_KPRW.ptd (ny)Skrivbar task på `KontaktPerson` — `TaskMode = Update`. Kolonner: Kontonr, Initial, Navn, Titel, Email, Tlf. `Initial` er med her, men ikke i læse-tasken `API_OP_S1_KP`. Feltet er andet nøglesegment i primærnøglen `Kunde` (Kontonr + Initial), jf. `FILE/KontaktPerson.PTD`, og skal derfor kunne sættes ved oprettelse. Bemærkninger
|
#1452 - Bankafstemning: gem original bankpost + korrekt valutaindlaesning fra MIB (01-09-26 19:21)Forbedring af bankafstemningOriginal bankpost gemmes ved indlæsning, og valutaoplysninger indlæses nu korrekt fra MIB. FILE/BankPostAfstem.PTD
når en afstemning ikke går op, uden at skulle hente posten igen. TASK/Bank_MIB_TransHent.ptd
De gamle navne matchede ikke MIB's faktiske JSON, så kursen blev aldrig fundet og org.valuta-felterne forblev tomme.
`currencyExchange.sourceCurrency` manglede indeks og kunne derfor ikke resolve.
TASK/Bank_Ng_TransHent.PTD
Bemærk til senere`Bank_Ng_TransHent` bruger fortsat de gamle camelCase-tagnavne og ganger ikke med 100 ved beregning af `BeløbOrgVal`. Det er ikke ændret her, da denne PR kun retter MIB-siden, men det bør efterprøves mod Nordeas faktiske svar. |
| #1451 - Udvidelse af promptexpr() hintexpr() taget fra Vitrex (01-09-26 18:20) |
| #1448 - Oversigt valuta sum / hvis ikke standard valuta eller "". (01-09-26 18:18) |
| #1379 - Peppol BIS 3: reelle EDI-ID'er og bankkonto pr. valuta, adresser på ISO20022 og Outlook API-backend (27-08-26 19:56) Fire områder i denne PR: Peppol-eksporten er lagt om til de reelle EDI-ID'er og bankkonto pr. valuta, Debitor leverer nu rigtige Peppol-scheme-koder, modtageradressen kommer med på alle ISO20022-betalingsformater, og første step af API-backenden til Outlook-pluginnet er på plads. PEPPOL BIS 3 (TASK/UDSKRIVFAKTURA_PEPPOL_BIS_3.ptd)
Filen er reformateret af editoren undervejs, så langt de fleste diff-linjer er whitespace og klammer omkring enkelt-statement `if`'er uden funktionel betydning. Debitor: Peppol-scheme-koder (FILE/Debitor.PTD)
Også her er resten af diffen reformatering; de reelle ændringer er de to `Init`-udtryk. ISO20022: modtageradresse på alle formater (TASK/EXPORT_BANK_ISO20022_Fil.PTD)Gade, postnummer og bynavn på modtageren blev kun udfyldt ved IBAN-betalinger — linjerne var udkommenteret i de øvrige grene. De er nu aktive for **FIK/Giro**, **Overførsel** og **SWIFT** også, så adressen følger med uanset betalingsform. Outlook-plugin: API-backend, første step (TASK/API_OutLook_KE.ptd, TASK/API_OutLook_KP.ptd)To nye tasks der eksponerer de data pluginnet skal vise:
Test`KBRebuild -IPTD` på alle fem ændrede filer kompilerer uden fejl (`done OK`). Peppol-outputtet er kontrolleret mod svensk validering. |
| #1334 - Tilføj Azure DevOps MCP-server til Claude Code (25-08-26 11:06) Giver Claude Code direkte adgang til PR'er, kommentartråde og build-logs, så fejlsøgning på en PR ikke kræver manuel kopiering fra webfladen. Baggrunden er arbejdet med PR 1332: hele undersøgelsen af hvorfor review-bottens JSON blev postet råt måtte foregå uden adgang til selve PR'en, fordi hverken `az devops` eller anonym REST kunne læse den. Hvad der tilføjes`.mcp.json` i repo-roden med den officielle server `@azure-devops/mcp` (v2.9.0) mod organisationen KeyBalance, samt en linje i `CLAUDE.md` der nævner serveren. Valg der er truffet**Kun tre domæner slået til:** `core`, `repositories` og `pipelines`. Serveren loader som standard alle domæner (også work-items, wiki, search, test-plans og advanced-security), og hvert værktøjs schema fylder i konteksten i hver eneste session. De tre giver de 18 værktøjer vi reelt bruger — herunder `repo_pull_request_thread` og `pipelines_build_log`. Listen kan udvides ved at rette `args`. **Interaktivt browser-login (serverens standard).** Ingen PAT gemmes i repoet, og hver udvikler logger ind som sig selv første gang serveren bruges. `-a azcli` blev fravalgt: token fra en almindelig `az login` afvises af organisationen med TF400813. **Ingen hemmeligheder i konfigurationen.** Eneste `env` er `ado_mcp_project`, som blot er projektnavnet, så værktøjerne ikke behøver spørge. For dem der henter ændringenServeren starter ikke af sig selv. Projekt-scopede `.mcp.json`-servere kræver eksplicit godkendelse ved opstart af Claude Code — det er den normale sikkerhedsspærre for MCP-konfiguration der kommer med et repo. Efter godkendelse åbner første værktøjskald et browser-login mod `dev.azure.com/KeyBalance`. Verifikation`initialize`-handshake mod serveren svarer (Azure DevOps MCP Server 2.9.0), og de tre domæner parses som forventet. Efterfølgende brugt i praksis til at læse review-trådene på PR 1332 og svare på dem. |
| #1408 - Navngivning FakturaTil (25-08-26 10:06) |
| #1384 - Div småting fra opgradering (21-08-26 15:11) Div småting fra opgradering |
| #1332 - Claude PR review: robust JSON-parsing i stedet for raa dump i PR'en (14-08-26 12:17) Claude PR review: robust JSON-parsing i stedet for raa dump i PR'en Nogle PR'er (fx 1313 og 1328) fik hele review-JSON'en postet raat ind i PR-kommentaren i stedet for den formaterede opsummering. Aarsagen var oprydningen foer ConvertFrom-Json: den strippede kun en markdown-fence der laa PRAECIS i start og slut af svaret. Skrev modellen en indledning ("Her er reviewet:") eller en afsluttende bemaerkning, slog parsingen fejl, og fallbacken postede $raw direkte. Samme udfald ved afkortede svar og ved trailing comma. Reproduceret under PowerShell 5.1. Vaerst af alt gjorde fallbacken "exit 0" med en lukket traad: ingen inline-fund, ingen impact-vurdering, og PR'en gled igennem porten uden at nogen havde set paa den. Aendringer:
en scanner der ignorerer klammer inde i strenge. Trailing comma ryddes kun op som sidste udvej, saa strenge ikke korrumperes.
samtidig subtype, is_error, stop_reason og afviste tool-kald.
raa svar vises afkortet i en kodeblok og ligger som artefakt.
Verificeret under Windows PowerShell 5.1: alle steps parser, 10 udtraeks-cases giver forventet resultat, og et rigtigt CLI-kald med prosa foer og efter fencen parses nu korrekt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
| #1328 - Små rettelser Indkøb / bilag (14-08-26 10:34) Kontroller flyttet til task, der kan udvides - på sigt evt. ændres til system opsætning. Kørt og testet hos Helsinge (m. Gitte). |
| #1322 - Div småting opsamlet ved opgradering (14-08-26 07:59) Div småting opsamlet ved opgradering |
#1313 - ISO20022 PAIN.001 export som manuel fil (uden BankConnect) + 2026 adresseformat (13-08-26 11:27)ISO20022 PAIN.001 export som manuel fil (uden BankConnect)Hovedformålet er at gøre det muligt at danne en ISO20022 PAIN.001-betalingsfil **manuelt** — dvs. filen gemmes lokalt på pc'en og indlæses selv i netbanken — i stedet for kun at kunne sendes via BankConnect. Samtidig er adresseblokkene bragt på det format bankerne kræver fra 2026 (struktureret adresse). EXPORT_BANK_ISO20022_Fil
**Adresser (2026-format):**
**Valuta:**
KBetForHistHeadDlg
EXPORT_TILBANK
EXPORT_BANK_ISO20022_Samlet
Øvrige rettelser i denne branch
|
| #1311 - Rettelser fra Lasses noter (13-08-26 10:01) |
| #1316 - Smårettelser, init på user() i userformular (13-08-26 09:56) Smårettelser, init på user() i userformular UDSKRIVFØLGESEDDEL_FAKTURA Helt tossede lookups på ordrelinje, ordre |
| #1305 - Mindre rettelse til Varebilag til ordre (12-08-26 10:49) |
| #1291 - Reguleringslog + små rettelser (fundet fra Helsinge) (10-08-26 12:48) |
#1287 - Registrér hvem der har bestilt en pakke-klipning (09-08-26 16:50)HvorforAlle konsulenter starter pipelinen med **samme PAT**, så Azure DevOps krediterer hver eneste kørsel til den der ejer tokenet. Oplysningen om hvem der faktisk trykkede på knappen fandtes kun i Keybalance — og gik tabt. HvadNy parameter **`RequestedBy`** ("Bestilt af"), som `KB_PkgKlip` udfylder med `user()`. Værdien lander tre steder: | Sted | Hvorfor | |---|---| | `CreatedBy` på den nye katalogrække | synligt i UI'et, feltet findes allerede | | `MANIFEST.json` | payloaden bærer selv sporet, uforanderligt | | Byggeloggen | ved fejlsøgning | Hvorfor `CreatedBy` og ikke et nyt feltFeltet er der allerede og vises på pakke-kortet. Dets `Init(user())` er bare ubrugelig her: oprettes rækken over api2, er `user()` api2-kontoen — altså den samme på hver eneste pakke der nogensinde klippes. Nu overskrives den med den rigtige. BemærkParameteren er valgfri (`default: ''`), så en kørsel startet direkte fra Azure DevOps-UI'et virker uændret — den får bare ingen attribution. Den tilhørende PTD-ændring (`KB_PkgCatalogOpret` udstiller `CreatedBy`, `KB_PkgKlip` sender `user()`) ligger i admin-PTD'en uden for git, jf. §4.0 i modellen. Test
|
#1282 - Send blob-SAS gennem miljøet i stedet for --sas-token (08-08-26 20:42)FejlenUploaden fejlede med `NoAuthenticationInformation`, efterfulgt af en stribe mærkelige linjer: ``` 'st' is not recognized as an internal or external command 'se' is not recognized as an internal or external command 'sig' is not recognized as an internal or external command ``` Det er **SAS-tokenets query-parametre der bliver eksekveret som kommandoer**. Årsagen`az` er `az.cmd` på Windows, så argumenterne genparses af `cmd.exe` — og dér er `&` en kommandoseparator. Tokenet blev derfor hugget over ved første `&`: ``` --sas-token "sp=racwl&st=...&sig=..." ^ cmd deler her ``` az fik ingen credential overhovedet, og resten (`st=...`, `se=...`, `sig=...`) blev forsøgt kørt som programmer. Det kan ikke løses med bedre citering i PowerShell — opdelingen sker *efter* PowerShell er færdig med linjen. Rettelsenaz læser `AZURE_STORAGE_ACCOUNT` og `AZURE_STORAGE_SAS_TOKEN` direkte fra miljøet, så værdien aldrig rører en kommandolinje: ```yaml env: AZURE_STORAGE_ACCOUNT: kbupdate AZURE_STORAGE_SAS_TOKEN: $(BlobWriteSas) ``` `--account-name` og `--sas-token` er dermed fjernet fra kaldet. Sidegevinst: hemmeligheden står ikke længere i procesargumenterne. Bedre fejlbeskedKatalogrækken oprettes før uploaden, så en fejlet upload efterlader en pakke uden payload. Beskeden nævner nu pakkenummeret der skal ryddes op, i stedet for kun at tale om blob-mappen. Status på kørslen der fejledeDen nåede at oprette **pakke 10 med 2 objektlinjer** før uploaden fejlede. Den pakke har ingen payload og bør slettes før næste kørsel. Test
|
#1281 - Vis api2's fejlbesked i stedet for kun statuskoden (08-08-26 20:06)ProblemetFørste rigtige kørsel (uden DryRun) fejlede med: ``` Invoke-RestMethod : The remote server returned an error: (406) Not Acceptable. ``` Og intet andet. api2 lægger forklaringen i svarets **body**, men `Invoke-RestMethod` kaster og smider den væk. Kørte man samme kald med curl, stod der: ``` Row not valid - Denne række findes allerede! (PackageId: KB_PkgCatalog:PackageId=6) ``` Altså årsagen sort på hvidt — nummerserien uddeler et id der allerede er taget — men intet af det nåede byggeloggen. RettelsenAlle seks api2-kald går nu gennem en lille wrapper der læser response-streamen og hænger serverens besked på fejlen: ```powershell catch { $resp = $_.Exception.Response if ($resp) { $detail = (New-Object System.IO.StreamReader($resp.GetResponseStream())).ReadToEnd() } $msg = "$What failed ($Method): $($_.Exception.Message)" if ($detail) { $msg += " -- server said: $detail" } throw $msg } ``` Hvert kald får en `-What`-tekst, så det fremgår hvilket skridt der fejlede ("Creating the package", "Copying TASK X onto package 57", …). **URL'en er bevidst udeladt** af fejlbeskeden — api2-tokenet står i dens sti. VerifikationKørt mod det endpoint der faktisk fejlede: ``` Creating the package failed (Post): (406) Ikke acceptabel. -- server said: Row not valid - Denne række findes allerede! (PackageId: KB_PkgCatalog:PackageId=6) ``` Det er beskeden der manglede. BemærkSelve 406-fejlen er ikke en fejl i pipelinen: nummerserien for `PackageId` er ude af trit med kataloget og skal sættes frem forbi den højeste eksisterende pakke. Denne PR sørger blot for at den slags siger sig selv næste gang. Test
|
#1279 - Fix: objektlisten blev ikke læst korrekt i PowerShell 5.1 (08-08-26 19:26)FejlenFørste kørsel af pakke-klipperen fejlede med: ``` ##[warning]FILE TASK Vare VAREKORT: not found at 20260804.2 - skipped None of the listed objects exist at 20260804.2 ``` Bemærk at **to objekters værdier står sammenkædet i én advarsel**. Løkken kørte altså kun én gang, med hele listen bundet til `$o`, så `$o.ObjType` returnerede `@("FILE","TASK")` — der interpoleres til `"FILE TASK"`. Årsagen`@(Get-Content ... | ConvertFrom-Json)` gør ikke det den ser ud til på agenten. Den kører **Windows PowerShell 5.1** (`WindowsPowerShell\v1.0\powershell.exe`), som sender hele det parsede array videre som ét pipeline-element. Array-subexpressionen pakker det derfor ind i et 1-element-array der indeholder arrayet. RettelsenTildel først, konvertér bagefter — det opfører sig ens i 5.1 og 7: ```powershell $parsed = Get-Content $f -Raw | ConvertFrom-Json $list = @($parsed) ``` Samme mønster tre steder: objektlisten i `Build payload`, i `Create package and copy the object list`, og payload-rækkerne i `Write manifest`. Dertil et formtjek efter indlæsning, så en fremtidig ændring i deserialiseringen fejler med en tydelig besked frem for stille at iterere over det forkerte: ```powershell if ($list.Count -gt 0 -and -not $list[0].PSObject.Properties['ObjType']) { throw ... } ``` VerifikationReproduceret mod Windows PowerShell 5.1 med samme data som i den fejlede kørsel: | Form | Resultat | |---|---| | `@(... \| ConvertFrom-Json)` | `Count = 1`, `ObjType = "FILE TASK"` | | `$parsed = ...; @($parsed)` | `Count = 2`, rækkerne intakte | Den øverste er nøjagtig den streng der stod i byggeloggen. Test
|
#1278 - Pipeline: klip PTD-pakke fra objektliste og to baseline-tags (08-08-26 10:40)FormålProducent-siden af pakke-distributionen. Indtil nu skulle hver payload samles i hånden i blob storage — det skalerer ikke, og en håndlavet mappe er ikke reproducerbar, hvilket ellers er hele grundlaget modellen hviler på. Pipelinen tager en **kildepakkes objektliste** plus **to baseline-tags** og udgiver de af listens objekter der er ændret imellem dem. `trigger: none` — filen starter ikke noget af sig selv. ArbejdsgangenDu angiver kun hvilken pakke du kopierer listen fra, et navn, og hvilket tag du udgiver til. `BaseTag` kommer af sig selv fra kildens `SourceTag`, så der er intet tag-bogholderi at holde styr på fra måned til måned. ``` læs kilde → validér tags → byg payload ↓ (første centrale skrivning først her) opret pakke → kopiér liste → manifest ↓ upload → stempl SourceTag ``` Fejler noget i de tre første trin, er der intet oprettet centralt. `SourceTag` stemples allersidst, fordi det er dét den næste klipning fortsætter fra — en pakke uden publiceret payload må ikke hævde at være nået dertil. Detaljer værd at kende
OpsætningTo secret-variabler på pipelinen: `PkgApiToken` (api2-token) og `BlobWriteSas` (write-SAS til `ptdreleases`). Test
|
#1277 - SFaktura: beskyt DB% med KOSTPRIS + indsnævr arkivoversigtens bilagstyper (07-08-26 15:46)FormålDe to ændringer der blev holdt ude af MCP-PR'en (#1276), fordi de ikke har med MCP at gøre. De er indbyrdes uafhængige og kan skilles, hvis I foretrækker det. 1. `FILE/SFaktura.PTD` — rettighedslæk på dækningsgrad`FILEFIELD DB1` (dækningsbidrag i kr.) er beskyttet af `RightsGroup = "KOSTPRIS"`. `DGrad` (DB %) var ikke — men beregnes som: ``` Init( SFaktura.DB1 * 100 / SFaktura.NettoDKR ) ``` Altså præcis samme oplysning udtrykt som procent. Brugere uden KOSTPRIS-rettighed kunne se dækningsgraden, selvom kronebeløbet var skjult. `DGrad` får nu samme `RightsGroup`. Mønsteret følger huset — `RightsGroup` på FILEFIELD-niveau bruges bl.a. i `FILE/BS_Bilag_VareLinjer.PTD` med samme indrykning. ```diff FILEFIELD DGrad { BaseType = BDouble TypeRef = Beløb + RightsGroup = "KOSTPRIS" Details { TYPEDETAIL { Prompt = "DB %" ``` Diffen er **én tilføjet linje, nul slettede**. Tidligere udgave af denne ændring optrådte som en omskrivning af alle 2252 linjer, fordi filens blandede linjeskift var blevet normaliseret. Filen har `CRLF` de fleste steder, men **bare `CR`** på en række `// AfterRecord` / `// DoTask`-kommentarlinjer. Den profil er bevaret uændret her, så kun den reelle ændring er i diffen. Normaliseringen bør tages for sig, hvis den ønskes. 2. `TASK/SFAKTURA_ALLE.PTD` — arkivoversigtens udvalg```diff SelectField = SalgKøbProd
``` Type **3–9 udgår** af "Salgsfaktura - Arkiv". ⚠️ **Bør bekræftes ved review:** der findes ingen `TYPE`/enum for `SalgKøbProd` i repoet — feltet er en rå `BUShort` med hinttekst "Er Ordren salg/Indkøb eller produktion". Værdirummet er kun dokumenteret implicit gennem andre tasks: `0` = salgsfaktura (`SFAKTURA`), `10` = abonnement (`SFAKTURA_ABONNEMENT`), `12` = maskine (`SFAKTURA_MASKIN`). Hvad 3–9 dækker, og om de bevidst skal ud af arkivoversigten, kan jeg ikke afgøre ud fra koden. Forhold til #1276Begge PR'er rører `TASK/SFAKTURA_ALLE.PTD` — #1276 tilføjer `Scope = UseMCP` (linje 5), denne ændrer `FromTo` (linje 7). Jeg har simuleret fletningen med `git merge-tree`: **ingen konflikt**, resultatet får korrekt begge ændringer. Rækkefølgen de merges i er uden betydning. Test
🤖 Generated with [Claude Code](https://claude.com/claude-code) |
#1276 - MCP: Scope = UseMCP på standard-tasks + MCP-pakke til tidlig udrulning (07-08-26 15:42)FormålÅbner 1034 TASK-definitioner for MCP-serveren, og lægger samtidig en kopi-pakke i `EXTRA_PTD`, så udvalgte kunder kan få funktionaliteten **før** næste standardopdatering. Standard — permanent
Pakke til tidlig udrulning — midlertidig20 tasks er kopieret til `EXTRA_PTD/TASK/MCP_<navn>.PTD`: `ALSTATISTIK`, `DEBITOR`, `DTRANSAKTIONER`, `DVSTATISTIK`, `FKONTOPLAN`, `FTRANSAKTIONER`, `IOLSTATISTIK`, `KREDITOR`, `KTRANSAKTIONER`, `LVSTATISTIK`, `MASKINE`, `MTRANSAKTIONER`, `OLSTATISTIK`, `SAG`, `SFAKTURA`, `SFAKTURA_ALLE`, `SOLSTATISTIK`, `STLSTATISTIK`, `VARER`, `VTRANSAKTIONER` I hver kopi er **kun to linjer** ændret: 1. `TASK <navn> {` → `TASK MCP_<navn> {` 2. Den selv-refererende `TaskRef = <navn>` → `TaskRef = MCP_<navn>` Bevidst urørt: fremmed-`TaskRef` (fx `DEBITORKORT`, `DPOST`, `SAGSKORT`) peger på tasks der ikke pakkes med; `FileId`/`FileRef`, `RightsGroup` og `Hint`/`Title`-tekster indeholder samme ord, men er ikke task-navne. Verificeret: hver kopi er præcis 8 bytes større end originalen (2 × `MCP_`), `diff` viser nøjagtigt 2 linjer, og original-encoding (ISO-8859-1 / UTF-8 pr. fil) samt CRLF er bevaret. ⚠️ `EXTRA_PTD/TASK` er uden for autobyg, så **kopierne oversættes ikke af pipelinen og fanges ikke af PR-validering**. De skal bygges manuelt hos kunden. Kopierne er et udrulningsvehikel, ikke en varig parallel-version — når standarden er ude, er de redundante og bør fjernes. Holdt bevidst udenfor
Derudover er `Scope = UseMCP` i `IOLSTATISTIK.PTD` rykket ind med 2 spaces som i alle øvrige filer (stod i kolonne 0). Test
🤖 Generated with [Claude Code](https://claude.com/claude-code) |
#1273 - Pakke-ledger: kundeside-filer til PTD-distribution (07-08-26 10:26)FormålFørste skridt mod at udsende PTD-funktionalitet til kunderne som nummererede, tildelte pakker i stedet for ét `PTDVersionNY`-nummer. Disse to FILEs er kundesiden af modellen. Design: `docs/ptd-distribution-model.md` i Keybalance2018 (separat PR). Filer**Beholdt — skal ud til kunderne**
**Slettet — kun til os selv**
De tre er centrale administrationstabeller. De er indlæst i vores egen centrale Keybalance og må aldrig havne hos en kunde — så slipper kundens ressourcesystem også for tabeller det ikke bruger. Ændringer i denne PR
Test
BemærkIngen kode bruger tabellerne endnu — de er tomme definitioner. Selve mekanikken ligger i Phase 0 af `KBAutoU` (skitseret, ikke bygget), så denne PR kan ikke ændre adfærd for nogen kunde. |
| #1253 - :102 udenfor string() (04-08-26 16:39) :102 udenfor string() |
| #1255 - Nulstilling af BSBilag ved kørsel på flere bankposter (04-08-26 16:38) Nulstiller $BSBilag i BeforeRecord i BankPost_Afstem_TilKladde, så en tidligere bankposts BS-nummer ikke bæres videre til næste post, når kun én af flere bankposter har angivet BS. |
| #1168 - Beregn rabat på oio fra AAB (bruttopris) (03-08-26 14:05) Beregn rabat på oio fra AAB (bruttopris) |
| #1249 - Kopiér salgsordre: åbn korrekt kort + fix af Fkey-tabel (03-08-26 13:46) Retter to fejl relateret til kopiering af salgsordre (SORDREKOPIER): |
| #924 - Salgsgebyrer grundlæggende forbedret. Nu burde alle beregnes og printes korrekt! (03-08-26 13:17) Louise: Tilføjelse af gebyr på udskrifter Lasse Nu er gebyrgrupper lagt om til virtuelle felter Der er opfundet samlet gebyr som er med på ordrekort og bruges i beregningerne. Så bør alt være VARE + SamletGebyrFørMoms + SamletGebyrEfterMoms + Fragt - Rabat Ved fakturering flyttes fra Auto felterne (de nye virtuelle) til at sammenlægges med de manuelle. Ordre, FakKladde og OrdreMulti er rettet til med gebyrer. Momsgrundlag bør have review. Jeg mener den er korrekt MEN check gerne. NettoDKK er ikke bare Netto*kurs - er det fordi at kursen ganges på helt nede på ordrelinjen eller hvordan? |
| #1188 - Små rettelse Chart (2nd level CarlJ) (03-08-26 11:03) |
#1247 - KeyBalanceWF2GitBuild.bat: hent compileren hvor den bliver bygget (03-08-26 08:53)BaggrundBatten hentede assemblies fra `..\..\KeybalanceWF`, det gamle WinForms-træ. De fire filer den skulle forny — `KRuntime.dll`, `KB.PTD.Parser.dll`, `KB.PTD.Grammar.dll` og `KBRebuild` — bliver ikke bygget der længere. De kommer fra Keybalance2018. Et tørløb (`xcopy /L`) viser hvad linjen faktisk gjorde: ``` gammel: EXTDLLS\FileHelpers.dll, EXTDLLS\SecuredClient.dll 2 filer ny: de seks filer fra KBRebuild\bin\Release 6 filer ``` Den har altså **aldrig** fornyet compileren. Det eneste den nåede var at overskrive to EXTDLLS-afhængigheder med kopier fra 2022, fordi `/S` rekurserer og `/U` rammer ethvert filnavn der tilfældigvis også findes i destinationen. Det skete i praksis i dag: en utilsigtet kørsel byttede `FileHelpers.dll` fra 146.944 til 208.896 bytes — væk fra den version værktøjskæden i PR 1243 er verificeret med. Uden varsel, og kun synligt fordi `git status` fangede den. Ændringen```diff xcopy /U /S ..\..\New\Def\* Def\ /Y -xcopy /U /S ..\..\KeybalanceWF\* KeybalanceWF\ /Y +xcopy /U ..\..\Keybalance2018\KBRebuild\bin\Release\net10.0-windows\* KeybalanceWF\ /Y ``` Kilden peger nu på det build der faktisk producerer filerne, og `/S` er væk fra den linje, så xcopy ikke kan grave i undermapper. `/U` bevares, så kun de seks filer der allerede ligger i mappen fornys, og `EXTDLLS` bliver ladt i fred — præcis det sæt der blev lagt op i hånden i PR 1243. Def-linjen er urørt. Kommentaren over linjerne forklarer hvorfor de fire assemblies skal komme fra ét og samme build: `KB.PTD.Parser` slår felter op med refleksion i KRuntimes structs, så parser og runtime kan ikke fornys hver for sig uden at modellen og tabellen driver fra hinanden. Det her er stadig en genvejDen rigtige løsning er at udgive værktøjskæden som pipeline-artefakt i stedet for indcheckede binære filer, så der slet ikke er kopier at holde ved lige. Mønstret findes allerede i PTD-pipelinen, som henter `programEmpty` som pipeline-ressource. Det står noteret sammen med embedding af `objects.tab` i KRuntime i Keybalance2018s `docs/REFACTORING-BACKLOG.md`. Test
🤖 Generated with [Claude Code](https://claude.com/claude-code) |
| #1248 - Barcode og vare forbedringer (03-08-26 08:23) Barcode og vare forbedringer |
#1243 - Delt udskrifts-skabelon: 16 udskrifter styres nu fra ét sted (BlockRef/ElementRef + PostLinje) (31-07-26 13:50)FormålElementer der er placeret på en formular kan nu rettes centralt via skabelonen `Faktura`, uden at rette i de enkelte PTD'er. 16 udskrifter er med. Runtime slår op på `(Template, BlockRef, ElementRef)` — ikke rapportnavn. Ét ref = én placering på alle udskrifter. Omfang**Salg (3):** UDSKRIVFAKTURA, UDSKRIVORDRE, UDSKRIVTILBUD **Indkøb + kladde (10):** IUDSKRIVFAKTURA, IUDSKRIVORDRE, IUDSKRIVFAKKLADDE, IUDSKRIVFORESP, IUDSKRIVFØLGESEDDEL, IUDSKRIVMODTAGSEDDEL, IUDSKRIVREKV, IUDSKRIVOrdreRykker, UDSKRIVFAKKLADDE, UDSKRIVTILBUDSPEC **Debitor (3):** DKONTOUDTOG, UDSKRIVAABNEKTOG, UDSKRIVRYKKER Lønudskrifterne er holdt udenfor, da de udgår. Navngivning
Ny arketype: PostLinjePosteringstabellen på debitorudskrifterne (bilag, datoer, beløb) er en anden tabel end fakturaens varelinje. At tvinge den ind i `VLinje` gav semantisk forkerte mapninger og op til 284 mm skred. `PostLinje` har 8 kolonne-slots. Kun par der aldrig optræder i samme dokument deler position: `Udlign`/`RykNr`, `Valuta`/`Aabent`, `Saldo`/`Rente`. Kolonneoverskrifterne (`Post*Txt` i `Hoved`) har samme Left/Width som deres kolonne, så overskrift og data ikke kan glide fra hinanden. Dokumenteret i `_TOOLS/Templates/POSTLINJE.md`. Bevidst uden ref: rykkerens totalblok (Forfalden saldo/Rente/Gebyr er ikke fakturaens Netto/Moms/Total), aldringstabellerne (kun båndet får `Total` for `BetID`) og carry-over-båndene, hvis højde og saldo-position ikke passer. Risiko: hvad sker der uden skabelonrækker?**15 af 16 udskrifter printer præcis som før.** Alle koordinat- og højdelinjer er sammenlignet før/efter (encoding neutraliseret): 13 filer har kun den slettede `FirmaHovedTom`-linje, som er højde-neutral. Eneste ægte undtagelse er UDSKRIVTILBUD, hvor `TekstLinje`-båndet er 1 mm lavere. Refs er inerte uden en skabelonrække — `FindTemplateInfo` returnerer false, og PTD'ens egne koordinater gælder. Risikoen ligger derfor i **importen**, ikke i PTD-ændringerne. Slettes rækkerne, falder alt tilbage til koordinaterne. Filer
Test
🤖 Generated with [Claude Code](https://claude.com/claude-code) |
| #1219 - L.Saldo + mps udskrift linjeskift (30-07-26 18:30) |
#1242 - Saldooversigter: totalerne summeres nu fra de linjer der faktisk printes (30-07-26 12:43)ResuméDe fire saldooversigter tog deres totaler fra kontofelterne `SaldoDKR` / `ForfaldentDkr`, mens de printede linjer var et filtreret udsnit — kun forfaldne poster, eller kun poster der var åbne pr. en given dato. Total og linjer kunne derfor ikke stemme. Nu summeres der undervejs: hver linje lægger sit eget åbne beløb til `$LinjerSaldo` (og til `$LinjerForfaldent` hvis den er forfalden), delsummen pr. konto printes fra de to variabler, og hovedtotalen bygges af delsummerne og nulstilles før næste konto. **Tre ting værd at fremhæve:** 1. **Akkumuleringen i `_DATO`-varianterne er pakket i samme betingelse som `REPORT PosterList`s `ShouldExecute`.** Uden den blev en linje der netter til nul i valuta talt med i DKK — og da DKK-beløbet er `ÅbentBeløbDkr + $TotalDKR` med to forskellige kurser, lagde en fuldt udlignet valutalinje sin kursdifference oveni totalen uden en synlig linje at forklare den med. Samtidig springes footer-snapshottet over for en linje der ikke printes, så delsum og hovedtotal kunne drive fra hinanden. 2. **Forfaldstesten er strammet fra `<=` til `<` pr.-datoen,** så den matcher definitionen af `ForfaldentDkr`, der opgør over `[..max(DatoAfgrænsning) - 1D]`. En post der forfalder præcis på pr.-datoen regnes altså ikke længere som forfalden. Rettet både i subtaskens `CanEnter` (hvad der printes) og i akkumuleringen (hvad der summeres) — og tilsvarende mod `$$BogføringsDato` i ikke-dato-varianterne, så hele familien har samme definition. 3. **I `KSALDOOVERSIGT.PTD` skifter forfaldent-totalen reelt grundlag:** den kom fra `Kreditor.ForfaldentDkr`, som opgør over `max(Kreditor.DatoAfgrænsning)` — men `DatoAfgrænsning` bliver aldrig sat i den task. Nu er det eksplicit "forfald før bogføringsdato" summeret over de linjer der faktisk printes. Placeringen af akkumuleringen inde i `AfterRecord` er uden betydning for delsummen: `KTask.OnLeave()` afvikler hele `AfterRecord`-listen, og først derefter kaldes `PrintFooters()`, som snapshotter footer-værdierne. Sidste linje kommer altid med. Filer| Fil | Ændring | |---|---| | `TASK/DSALDOOVERSIGT.PTD` | Linjesummer + `< $$BogføringsDato` i `CanEnter` og akkumulering | | `TASK/DSALDOOVERSIGT_DATO.PTD` | Linjesummer, guard mod `ShouldExecute`, `< #PrDato` begge steder | | `TASK/KSALDOOVERSIGT.PTD` | Samme port som debitor-varianten (ingen `KunForfaldne`, så kun akkumuleringen) | | `TASK/KSALDOOVERSIGT_DATO.PTD` | Fuld port af `_DATO`-mønsteret inkl. guard | `DSALDOOVERSIGT-STYLE2025.PTD` er urørt — den bruger `Options = [ Style2025 ]` med automatiske kolonnetotaler. Testplan
🤖 Generated with [Claude Code](https://claude.com/claude-code) |
| #1241 - Warnings - lookup - fejl (30-07-26 11:28) Enkelte fejl i Flexpos lookup, fejl i lookup |
| #1239 - RTEXT - CalText/TextLayer opryddet (30-07-26 11:09) RTEXT - CalText/TextLayer opryddet Der kan ikke være CalcText og TextLayer i samme RTEXT Vise CalcText med konstante strings er blevet til Text og TextLayer bevaret. |
| #1189 - Ret bemærkning på godkendte bilag (hvis de ligger og afventer noget) (22-07-26 12:02) |
#1186 - Running page-balance carry-over in tilbud/ordre/fakkladde printouts (10-07-26 06:38)SummaryPorts the "Overført fra/til side" running-balance mechanism from **UDSKRIVFAKTURA** to **UDSKRIVTILBUD**, **UDSKRIVORDRE** and **UDSKRIVFAKKLADDE**, so multi-page printouts carry the accumulated net amount across page breaks. In each report's `UDSKRIV` subtask:
Mirrors the existing, proven pattern in UDSKRIVFAKTURA exactly. Files
Test plan
|
| #1166 - CRM - kører nu på KundeEmne, knappen virker, interface er det samme (09-07-26 08:19) CRM - kører nu på KundeEmne, knappen virker, interface er det samme |
| #1178 - Trigger, ikke alias, men fil (09-07-26 07:30) Trigger, ikke alias, men fil I Select - FromTo |
#1169 - Claude PR review: inline kontekst og diff i prompten for hurtigere review (08-07-26 10:41)Baggrund |
| #1173 - Fejl i Vis Tilbud (08-07-26 10:03) Fejl i Vis Tilbud Ingen parametre overhovedet - kopieret fra SORDREKORT |
| #1171 - Feature bedre graf over omsætning resultat (08-07-26 10:02) Feature bedre graf over omsætning resultat |