Zoho CRM Systemdokumentation
Komplet teknisk dokumentation af Forbrugsforeningens Zoho CRM-opsætning, automatiseringer og integrationer.
Systemoversigt
Forbrugsforeningens Zoho CRM-system er opbygget omkring følgende kernemoduler:
| Modul | Type | Formål |
|---|---|---|
| Partnere | Custom | Samarbejdsaftaler med butikker/virksomheder |
| Kæder | Custom | Grupper af butikker med fælles ejerskab |
| Organisationer | Standard | Fagforeninger, butikker, foreninger m.m. |
| Kontakter | Standard | Kontaktpersoner til organisationer og partnere |
| Ejerskaber | Custom | Ejerskabsforhold |
| Valggrupper | Custom | Simpelt grupperingsmodul |
Nøgleintegrationer
CVR Integration
cvrintegration.dkAutomatisk opslag af danske CVR-data og EU VIES-validering ved oprettelse/redigering af records.
Loyalty Solutions
fbf-loyaltfacts-api.loyaltfacts.comSynkronisering af partnere og kæder til Loyalty Solutions-platformen (opret, opdater, bonussats, vederlag).
Business Central
smartapiservice.azurewebsites.netSynkronisering af kundeposter (Customer) til Microsoft Dynamics 365 Business Central via SMART API.
OpenAI GPT
api.openai.comGenererer brugervenlige fejlbeskeder når LS-overførsler fejler. Bruges i "Fejl i Overførelse"-workflowet.
Modulrelationer
Oversigt over lookup-felter og relationer mellem moduler.
| Fra modul | Felt | Til modul | Felttype | Beskrivelse |
|---|---|---|---|---|
| Partnere | Kæde | Kæder | Lookup | Hvilken kæde partneren tilhører |
| Partnere | Primær Kontaktperson | Kontakter | Lookup | Primær kontaktperson for partneren |
| Partnere | FBF Ansvarlig | Users | Bruger | Intern ansvarlig medarbejder |
| Partnere | Tilsluttet til | Multi-modul | Multi-lookup | Multimodul-opslag |
| Kæder | FBF Ansvarlig | Users | Bruger | Intern ansvarlig medarbejder |
| Kæder | Kæde Ejer | Organisationer | Lookup | Kædens overordnede ejerorganisation |
| Kæder | Tilsluttet til | Multi-modul | Multi-lookup | Multimodul-opslag |
| Kontakter | Organisations Navn | Organisationer | Lookup | Tilknyttet organisation |
| Kontakter | Partner Navn | Partnere | Lookup | Tilknyttet partner |
| Kontakter | Kæde | Kæder | Lookup | Tilknyttet kæde |
| Kontakter | Ejerskab | Ejerskaber | Lookup | Tilknyttet ejerskab |
| Organisationer | Fædre Organisation | Organisationer | Self-lookup | Overordnet organisation |
| Organisationer | Fusioneres Sammen Med | Organisationer | Self-lookup | Organisation der fusioneres med |
| Organisationer | Tilsluttet til | Multi-modul | Multi-lookup | Multimodul-opslag |
| Ejerskaber | Primær Kontaktperson | Kontakter | Lookup | Primær kontaktperson |
| Ejerskaber | FBF Ansvarlig | Users | Bruger | Intern ansvarlig medarbejder |
| Ejerskaber | Tilsluttet til | Multi-modul | Multi-lookup | Multimodul-opslag |
| Valggrupper | Tilsluttet til | Multi-modul | Multi-lookup | Multimodul-opslag |
Integrationer i detaljer
1. CVR Integration (cvrintegration.dk)
Bruges både som client script (frontend) og Deluge workflow (backend) til automatisk opslag af virksomhedsdata.
Funktionalitet
- Dansk CVR-opslag: Indtastes et 8-cifret CVR-nummer eller "DK"+nummer, slås stamdata op (navn, adresse, branche, finansdata, bestyrelsesmedlemmer, direktører).
- EU VIES-validering: Indtastes et udenlandsk VAT-nummer (f.eks. SE+nummer), valideres det via VIES og basisdata hentes.
- Automatisk kontaktoprettelse: Ved oprettelse af Partner via workflow oprettes kontakter for direktører og bestyrelsesmedlemmer automatisk.
Anvendes i moduler
| Modul | Client Script (frontend) | Workflow (backend) |
|---|---|---|
| Partnere | Opret, Rediger (OnChange), Klon | Oprettelse Regel-1, Redigering Regel-1 |
| Organisationer | Opret, Rediger, Klon | CVR-workflows (identisk logik) |
| Ejerskaber | Opret, Rediger (OnChange), Klon | Oprettelse + Redigering (identisk logik) |
| Kontakter | - | Oprettelse + Redigering (CVR-integration for kontakter) |
Dataflow
2. Loyalty Solutions (LS)
Hovedintegration til partnerhåndtering. Synkroniserer partnere (merchants) og kæder (chains) til LS-platformen.
API Endpoints
| Handling | Metode | Endpoint |
|---|---|---|
| Opret partner | POST | /merchants |
| Opdater partner | PATCH | /merchants/{internalMerchantId} |
| Opret kæde | POST | /chains |
| Opdater kæde | PATCH | /chains/{internalChainId} |
Synkroniseringslogik
- Ved oprettelse sendes alle felter. LS returnerer et internt ID som gemmes på CRM-recorden (Internal Merchant ID / Internal Chain ID).
- Ved opdatering sammenlignes gammel data med aktuelle data. Kun ændrede felter sendes via PATCH.
- Ved fejl gemmes fejlbesked i feltet Loyalty Solutions Fejlbesked og status sættes til "Afvist af LS".
- Bonussats og vederlagssats kan planlægges til fremtidig dato via Skift Bonussats Dato / Skift Vederlagssats Dato.
Connection
Alle LS-kald benytter Zoho-forbindelsen loyalty solutions.
3. Business Central (BC)
Opretter og synkroniserer kundedata (Customer) til Microsoft Dynamics 365 Business Central via SMART API.
API Endpoints
| Handling | Metode | URL-mønster |
|---|---|---|
| Opret kunde | POST | smartapiservice.azurewebsites.net/SMARTapi/post/.../Customer |
| Hent kunde | GET | smartapiservice.azurewebsites.net/SMARTapi/get/...?filter=(No.={debitor}) |
| Opdater kunde | PUT | smartapiservice.azurewebsites.net/SMARTapi/put/...?filter=(No.={debitor}) |
Felter ved oprettelse af debitor (POST)
Når en partner eller kæde oprettes i CRM og ikke har et Debitor Nummer, genereres et nyt nummer automatisk og en BC-kunde oprettes via POST. Følgende felter sendes:
| BC-felt | CRM-felt (Partnere) | CRM-felt (Kæder) |
|---|---|---|
| No. | Auto-genereret debitornummer | |
| Name | Partnernavn | Kæde Navn |
| Address | Adresse 3 - Gade -> Adresse 2 - Gade -> Gade | Gade |
| City | Adresse 3 - By -> Adresse 2 - By -> By | By |
| Post Code | Adresse 3 - Postnummer -> Adresse 2 - Postnummer -> Postnummer | Postnummer |
| Country/Region Code | Adresse 3 - Land -> Adresse 2 - Land -> Land | Land |
| Phone No. | Telefon | Telefon |
| VAT Registration No. | CVR/VAT Nr. | CVR Nr. |
| Payment Terms Code | "KONTANT" (fast værdi) | |
| Customer Posting Group | "DEB" (fast værdi) | |
| Gen. Bus. Posting Group | "DANMARK" (fast værdi) | |
| VAT Bus. Posting Group | "DANMARK" (fast værdi) | |
Bemærk: Efter oprettelse bekræftes kunden via GET, og tomme CRM-felter beriges med data fra BC (adresse, telefon, email, navn m.fl.).
Felter ved løbende synkronisering (PUT)
Når en partner eller kæde redigeres og Debitor Nummer er udfyldt, synkroniseres ændrede felter til BC via PUT. Kun felter der er ændret siden sidste sync sendes (change detection via BC Record Data).
| BC-felt | CRM-felt (Partnere) | CRM-felt (Kæder) |
|---|---|---|
| Name | Partnernavn | Kæde Navn |
| Address | Adresse 3 - Gade -> Adresse 2 - Gade -> Gade | Gade |
| City | Adresse 3 - By -> Adresse 2 - By -> By | By |
| Post Code | Adresse 3 - Postnummer -> Adresse 2 - Postnummer -> Postnummer | Postnummer |
| Country/Region Code | Adresse 3 - Land -> Adresse 2 - Land -> Land | Land |
| Phone No. | Telefon | Telefon |
| VAT Registration No. | CVR/VAT Nr. | CVR Nr. |
4. OpenAI GPT (Fejlhåndtering)
Bruges i workflowet "Fejl i Overførelse af Partner" til at oversætte tekniske LS-fejlbeskeder til brugervenligt dansk.
- Model: GPT-5
- Trigger: Når feltet Loyalty Solutions Fejlbesked ændres til ikke-tom værdi
- Output: Brugervenlig besked gemmes i Chat Message (maks 255 tegn)
- Visning: Client scriptet "Vis Fejlbesked" viser beskeden som en fejl-popup på detaljesiden
Modul: Partnere
Partnere repræsenterer samarbejdsaftaler og overordnede relationer med butikker og virksomheder. Modulet adskiller sig fra Kontakter ved at fokusere på forretningsrelationen, ikke den specifikke person.
Partner Oplysninger
| Felt | Type | Beskrivelse |
|---|---|---|
| Partner Navn | Enkelt linje | Partnernavn / virksomhedsnavn |
| FBF Ansvarlig | Bruger | Intern ansvarlig for denne partner |
| CVR/VAT Nr. | Enkelt linje | CVR-nummer (DK) eller VAT-nummer (EU). Låses efter oprettelse. |
| Primær Kontaktperson | Lookup (Kontakter) | Primær kontaktperson |
| Kæde | Lookup (Kæder) | Tilknyttet kæde |
| Partner Status | Plukliste | Aktiv, Lukket, Afvist af LS m.fl. |
| Telefon | Telefon | Virksomhedens telefonnummer |
| Hjemmeside | URL | Virksomhedens hjemmeside |
| Partnernummer | Nummer | Unikt partnernummer (sættes automatisk til record-ID) |
| Kontakt-email | ||
| Tilsluttet til | Multimodul-opslag | Multimodul-reference |
CVR Data
| Felt | Type | Kilde |
|---|---|---|
| Selskabstype | Enkelt linje | CVR API |
| P-nummer | Enkelt linje | CVR API |
| Branchekode | Enkelt linje | CVR API |
| Branchetekst | Enkelt linje | CVR API |
| Virksomheds Status | Enkelt linje | CVR API |
| Medarbejdere | Nummer | CVR API |
Finansielle data
| Felt | Type | Kilde |
|---|---|---|
| Regnskabsdata fra år | Nummer | CVR API |
| Bruttofortjeneste | Nummer | CVR API |
| Årets resultat | Nummer | CVR API |
| Egenkapital | Nummer | CVR API |
| Statusbalance | Nummer | CVR API |
| Seneste Regnskab | URL | CVR API (link til PDF) |
| Bonussats | Procent | Manuelt / fra Kæde |
| Vederlagssats | Procent | Manuelt / fra Kæde |
Adresser
Partnere har op til 3 adresser:
- Adresse 1 (CVR-registreret): Gade, Postnummer, By, Land
- Adresse 2 (Butiks-adresse): Gade, Postnummer, By, Land
- Adresse 3 (Faktura-adresse): Gade, Postnummer, By, Land
Systemfelter (LS-synkronisering)
| Felt | Beskrivelse |
|---|---|
| Internal Merchant ID | ID fra Loyalty Solutions efter oprettelse |
| External Chain ID | Eksternt kæde-ID i LS |
| Old Record Data | Snapshot af seneste synkroniserede data (til change detection) |
| LS Record Data | Seneste opdaterede felter sendt til LS |
| LS Error Data | Fejlrespons fra LS |
| Loyalty Solutions Fejlbesked | Rå fejlbesked fra LS |
| Chat Message | Brugervenlig fejlbesked genereret af GPT |
| Faktureres gennem | "Kæde" eller "Selvstændigt" |
| Ny Bonussats | Planlagt ny bonussats |
| Skift Bonussats Dato | Dato for planlagt bonussats-skift |
| Ny Vederlagssats | Planlagt ny vederlagssats |
| Skift Vederlagssats Dato | Dato for planlagt vederlagssats-skift |
| BC Record Data | Snapshot af seneste BC-synkronisering |
| Debitor Nummer | BC debitornummer (krav for BC-sync) |
Økonomi / Faktura
| Felt | Beskrivelse |
|---|---|
| Visa CAID | Visa Card Acceptor ID |
| Visa Acquirer BIN | Visa Acquirer Bank ID Number |
| MC MID | Mastercard Merchant ID |
Bemærk: Visa CAID og Visa Acquirer BIN skal altid udfyldes sammen (valideret via client script). Hvis en af de tre kort-felter ændres, sendes alle tre til LS.
Modul: Kæder
Kæder består af en række butikker (partnere), som typisk har et overordnet ejerskab. En kæde kan styre bonussats og vederlagssats for alle tilknyttede partnere.
Kæde Oplysninger
| Felt | Type | Beskrivelse |
|---|---|---|
| Kæde Navn | Enkelt linje | Kædens navn |
| FBF Ansvarlig | Bruger | Intern ansvarlig |
| Opkrævningsgruppe | Enkelt linje | Opkrævningsgruppe |
| Produkt Gruppe | Enkelt linje | Produktgruppe |
| Type / Status | Plukliste | Aktiv, Lukket, Afvist af LS |
| Is Closed | Checkbox | Sættes automatisk til True når Type = Lukket |
| Kategori | Plukliste | LS-kategori |
| Benyt Kæde Bonus | Plukliste | "Ja"/"Nej" - om kædens satser overskriver partnernes |
| Bonussats | Procent | Kædens bonussats |
| Vederlagssats | Procent | Kædens vederlagssats |
| Land | Enkelt linje | Land (Danmark/Sverige) |
| Tilsluttet til | Multimodul-opslag | Multimodul-reference |
Kontakt & Faktura
| Felt | Beskrivelse |
|---|---|
| CVR Nr. | Kædens CVR-nummer |
| Kædens kontakt-email | |
| Telefon | Kædens telefon |
| Faktureringstype | "Leverandørservice" eller anden type |
| Faktura E-mail | Separat e-mail til LS-fakturering |
| Reg Nr. | Bankregistreringsnr (ved Leverandørservice) |
| Bankkonto Nr. | Bankkontonr (ved Leverandørservice) |
| Debitor Nummer | BC-debitornummer |
| Kæde Ejer | Overordnet ejerorganisation (lookup) |
Systemfelter (LS-synkronisering)
| Felt | Beskrivelse |
|---|---|
| Internal Chain ID | ID fra LS efter oprettelse |
| Old Record Data | Snapshot til change detection |
| Loyalty Solutions Fejlbesked | Fejlrespons fra LS |
| Ny Bonussats | Planlagt ny bonussats |
| Ny Vederlagssats | Planlagt ny vederlagssats |
| BC Record Data | Snapshot af seneste BC-synkronisering |
Modul: Organisationer
Organisationer anvendes til at registrere oplysninger om fagforeninger, butikker, foreninger m.m.
Organisation Oplysninger
| Felt | Type | Beskrivelse |
|---|---|---|
| FBF Ansvarlig | Bruger | Ansvarlig medarbejder |
| CVR/VAT Nr. | Enkelt linje | CVR-nummer |
| Organisationens Navn | Enkelt linje | Officielt navn |
| Telefon | Telefon | Primært telefonnr |
| Status | Tag | Aktiv/inaktiv/forældet |
| Branche | Plukliste | Virksomhedstype |
| Overordnet Organisation | Lookup (self) | Overordnet moderorganisation |
| Fusioneres sammen med | Lookup (self) | Målorganisation for fusionering |
| Tilsluttet til | Multimodul-opslag | Multimodul-reference |
CVR Stamdata
| Felt | Beskrivelse |
|---|---|
| Selskabstype | Juridisk form (ApS, A/S osv.) |
| P-nummer | 10-cifret produktionsenhedsnummer |
| Branchekode | 6-cifret international branchekode |
| Branchetekst | Beskrivelse af branche |
| Virksomhedsstatus | Aktiv, opløst, konkurs |
| Organisationstype | Forening, virksomhed, myndighed |
| Medarbejdere | Antal ansatte |
CVR Finansdata
| Felt | Beskrivelse |
|---|---|
| Regnskabsdata fra år | Det år regnskabstallene stammer fra |
| Bruttofortjeneste | Indtægter før fradrag |
| Årets resultat | Resultat efter skat |
| Statusbalance | Aktiver og passiver |
| Egenkapital | Ejernes andel af finansieringen |
| Seneste regnskab | Link til seneste årsrapport |
Adresseinformation
| Felt | Beskrivelse |
|---|---|
| Gade | Gadenavn og nummer |
| Postnummer | Postnummer |
| By | Bynavn |
| Stat | Region / stat |
| Land | Landekode |
Modul: Kontakter
Kontakter anvendes som kontaktpersoner til både organisationer og partnere.
Kontakt Oplysninger
| Felt | Type | Beskrivelse |
|---|---|---|
| FBF Ansvarlig | Bruger | Ansvarlig medarbejder |
| Fornavn | Enkelt linje | Kontaktpersonens fornavn |
| Efternavn | Enkelt linje | Kontaktpersonens efternavn |
| E-mail adresse | ||
| Kontakt Rolle | Tag | "Partner", "Bestyrelsesmedlem" m.fl. |
| Titel | Enkelt linje | Personens titel/rolle |
| Telefon | Telefon | Telefonnummer |
| Mobil | Telefon | Mobilnummer |
| Kundeemne Kilde | Plukliste | Hvor kontakten stammer fra |
| FBF Number | Enkelt linje | FBF-nummer |
| Tags | Tags | Klassificering |
Virksomheds Oplysninger
| Felt | Type | Beskrivelse |
|---|---|---|
| Organisations Navn | Lookup (Organisationer) | Tilknyttet organisation |
| Partner Navn | Lookup (Partnere) | Tilknyttet partner |
| Kæde | Lookup (Kæder) | Tilknyttet kæde |
| CVR/VAT Nr. | Enkelt linje | Auto-udfyldt fra organisation/partner |
| Ejerskab | Lookup (Ejerskaber) | Tilknyttet ejerskab |
| Websted | URL | Auto-udfyldt fra organisation/partner |
Synkroniseringsfelter (system)
| Felt | Beskrivelse |
|---|---|
| Show Fields | Boolean - styrer om CVR-felter vises |
| Show Website | Boolean - styrer om website vises |
| Show Ownership | Boolean - styrer om ejerskab vises |
| Unique | MD5-hash til deduplikering af auto-oprettede kontakter |
Modul: Ejerskaber
Ejerskab Oplysninger
| Felt | Type | Beskrivelse |
|---|---|---|
| Ejerskabs Navn | Enkelt linje | Ejerskabets navn |
| FBF Ansvarlig | Bruger | Ansvarlig medarbejder |
| Primær Kontaktperson | Lookup (Kontakter) | Primær kontaktperson |
| CVR Nr. | Enkelt linje (unik) | CVR-nummer - låses efter oprettelse |
| Hjemmeside | URL | Hjemmeside |
| Telefon | Telefon | Telefonnummer |
| Tilsluttet til | Multimodul-opslag | Multimodul-reference |
CVR Stamdata & Adresser
Identisk struktur som Partnere/Organisationer: Selskabstype, Medarbejdere, P-nummer, Branchekode, Branchetekst, Virksomheds Status, samt to adressesektioner (Adresse 1 og Adresse 2).
Modul: Valggrupper
Simpelt grupperingsmodul.
| Felt | Type | Beskrivelse |
|---|---|---|
| Valggruppe Navn | Enkelt linje | Gruppens navn |
| Valggruppe Ejer | Bruger | Ansvarlig bruger |
| Kontakt-email | ||
| Ændret af | Enkelt linje | Sidst ændret af |
| Oprettet af | Enkelt linje | Oprettet af |
| Tilsluttet til | Multimodul-opslag | Multimodul-reference |
Modul: Opgaver
Opgaver er typisk et stykke arbejde som er bundet af tid og kan bruges som en to-do liste.
| Felt | Beskrivelse |
|---|---|
| FBF Ansvarlig | Ansvarlig medarbejder |
| Emne | Emnet for opgaven |
| Forfaldsdato | Seneste løsningsdato |
| Kontakt | Tilknyttet kontaktperson |
| Partner | Tilknyttet partner |
| Status | Ikke startet, Udskudt, I gang, Udført, Venter på input |
| Prioritet | Høj, Højeste, Lav, Laveste, Normal |
| Gentag | Dagligt, ugentligt eller månedligt |
| Påmindelse | Email, pop-up eller begge |
| Beskrivelse | Opgavebeskrivelse |
Modul: Møder
Møder er en aktivitet som sker på et givent sted og tid.
| Felt | Beskrivelse |
|---|---|
| Titel | Mødets titel |
| Sted | Lokation for mødet |
| Hele Dagen | Om mødet er hele dagen |
| Fra / Til | Start- og sluttidspunkt |
| Vært | Ansvarlig for mødet |
| Relateret til | Mødets relation |
| Deltagere | Deltagere med mulighed for email-invitationer |
| Gentag | Dagligt, ugentligt, månedligt, årligt |
| Påmindelse | Systemspåmindelser |
| Beskrivelse | Mødebeskrivelse |
Modul: Opkald
Opkalds-modulet bruges til at registrere eller planlægge opkald.
| Felt | Beskrivelse |
|---|---|
| FBF Ansvarlig | Ansvarlig medarbejder |
| Opkald til | Dropdown over kontakter |
| Relateret til | Tilknyttet organisation |
| Status for udgående opkald | Udført eller Planlagt |
| Opkalds starttid | Dato og tid |
| Opkaldsvarighed | Længde |
| Emne | Opkaldsemne |
| Opkaldsformål | Formålet |
| Opkaldsresultat | Interesseret, ikke interesseret m.m. |
| Beskrivelse | Beskrivelse af opkaldet |
Client Scripts: Partnere
Frontend-scripts der kører i browseren når brugere interagerer med Partner-records.
CVR Integration Opret / Rediger (OnChange) / Klon
Trigger: Når feltet CVR/VAT Nr. ændres.
Formål: Slår virksomhedsdata op via CVR API og udfylder felter automatisk i realtid.
Logik
- Hvis værdien er 8 cifre eller starter med "DK": Dansk CVR-opslag med fuld data (stamdata, finans, adresse)
- Hvis værdien starter med 2 bogstaver (ikke DK): EU VIES-opslag med basisdata (navn, adresse)
- Ellers: Vis fejlbesked til brugeren
Felter der udfyldes (dansk CVR)
Telefon, Hjemmeside, Selskabstype, Branchekode, Branchetekst, Medarbejdere, P-nummer, Virksomheds Status, Gade, Postnummer, By, Land, Regnskabsdata fra år, Bruttofortjeneste, Årets resultat, Egenkapital, Statusbalance, Seneste Regnskab
// Eksempel: CVR-opslag og feltmapping
var cvr = ZDK.Apps.CRM.Connections.invoke(
"cvrintegration",
"http://api.cvrintegration.dk/fetchdata?query=" + value,
"GET", 1, {}, {}
);
// Udfyld felter
phone_field.setValue(phone);
website_field.setValue(website);
company_type_field.setValue(company_type);
// ... osv.
Lås CVR Felt Rediger (OnLoad)
Trigger: Når redigeringssiden indlæses.
Formål: Gør CVR-feltet skrivebeskyttet hvis det allerede har en værdi, så det ikke kan ændres.
var cvr_field = ZDK.Page.getField("CVR_VAT_Nr");
var cvr_field_value = cvr_field.getValue();
if (cvr_field_value != null) {
cvr_field.setReadOnly(true);
}
Lås Bonussats og Vederlagssats Rediger (OnLoad + OnChange Kæde)
Trigger: Når redigeringssiden indlæses ELLER når Kæde-feltet ændres.
Formål: Hvis den tilknyttede kæde har Benyt Kæde Bonus = "Ja", låses Bonussats og Vederlagssats så de ikke kan redigeres manuelt.
var chain_field = ZDK.Page.getField("K_de");
if (chain_field && chain_field.getValue()) {
var lookupId = chain_field.getValue().id;
if (lookupId) {
var chain_record = ZDK.Apps.CRM.Chains.fetchById(lookupId);
if (chain_record.Benyt_K_de_Bonus == "Ja") {
ZDK.Page.getField("Bonussats").setReadOnly(true);
ZDK.Page.getField("Vederlagssats").setReadOnly(true);
}
}
}
Validerings-scripts Detalje-side
validation_invoice_address.js / _city.js / _zipcode.js
Formål: Validerer at faktura-adressefelter (Adresse 3) enten er helt tomme eller helt udfyldte. Advarer brugeren hvis kun dele er udfyldt.
const street = ZDK.Page.getField("Adresse_3_Gade").getValue();
const zip = ZDK.Page.getField("Adresse_3_Postnummer").getValue();
const city = ZDK.Page.getField("Adresse_3_By").getValue();
const filled = [street, zip, city].filter(v => v && v.trim() !== '').length;
if (filled > 0 && filled < 3) {
ZDK.Client.showMessage(
'Hvis du angiver en særskilt fakturaadresse, skal gade, postnummer og by udfyldes sammen.',
{ type: 'warning' }
);
}
validation_visa_caid.js
Formål: Validerer at Visa CAID og Visa Acquirer BIN altid udfyldes sammen.
const visaCaid = ZDK.Page.getField("Visa_CAID").getValue();
const visaBin = ZDK.Page.getField("Visa_Acquirer_BIN").getValue();
if (Boolean(visaCaid) !== Boolean(visaBin)) {
ZDK.Client.showMessage(
'Begge felter: "Visa CAID" og "Visa Acquirer BIN" skal udfyldes sammen.',
{ type: 'warning' }
);
}
Vis Fejlbesked
Formål: Viser en fejl-popup hvis feltet Chat Message indeholder en værdi (genereret af GPT efter LS-fejl).
var message = ZDK.Page.getField("Chat_Message");
if (message != null) {
ZDK.Client.showMessage('This is an *important* warning.', {
type: 'error'
});
}
Client Scripts: Kæder
Deaktiverings Pop-up Detalje + Rediger
Trigger: Når bruger åbner detalje- eller redigeringssiden for en kæde med status "Lukket".
Formål: Viser en advarselsdialog om at alle partnere i kæden vil blive deaktiveret.
var chain_status_field = ZDK.Page.getField("Type");
var chain_status_value = chain_status_field ? chain_status_field.getValue() : null;
if (chain_status_value === "Lukket") {
ZDK.Client.showConfirmation(
"Vær opmærksom: Dette vil deaktivere alle partnere i denne kæde. " +
"Fjern først de partnere, som ikke skal deaktiveres.",
"Forstået", "Fortryd",
function(confirmed) { /* ... */ }
);
}
Pop-up Vindue (Is Closed variant) Detalje
Formål: Alternativ variant der tjekker Is Closed (boolean) i stedet for Type-feltet.
var chain_status_field = ZDK.Page.getField("Is_Closed");
if (chain_status_value === true) {
ZDK.Client.showConfirmation(
"Vær opmærksom: Dette vil deaktivere alle partnere...",
"Forstået", "Fortryd", function(confirmed) { /* ... */ }
);
}
Deaktiver Klon-knap + Forhindre Kloning Detalje + Klon
Formål: Forhindrer kloning af kæder. Klon-knappen deaktiveres på detaljesiden, og på klon-siden deaktiveres både Gem og Gem-og-ny knapperne.
// Detalje-side: Deaktiver klon-knap
var save_btn = ZDK.Page.getButton('clone');
save_btn.disable();
// Klon-side: Deaktiver gem-knapper
var save_btn = ZDK.Page.getButton('record_save');
var other_save_btn = ZDK.Page.getButton('record_save_and_new');
other_save_btn.disable();
save_btn.disable();
Client Scripts: Ejerskaber
Identisk mønster som Partnere:
| Script | Sider | Formål |
|---|---|---|
| CVR Integration | Opret, Klon, Rediger (OnChange) | CVR/VIES-opslag. Identisk logik som Partnere, men mapper til Ejerskaber-felter (Navn, Gade, By osv.) |
| Lås CVR | Detalje, Rediger (OnLoad) | Gør CVR-feltet skrivebeskyttet så det ikke kan ændres |
Client Scripts: Organisationer
Identisk mønster som Partnere/Ejerskaber:
| Script | Sider | Formål |
|---|---|---|
| CVR Integration | Opret, Klon, Rediger | CVR/VIES-opslag. Mapper til Organisationers felter (Organisationens Navn, Gade, Postnummer osv.). Inkluderer også finansdata. |
| Lås CVR | Rediger | Gør CVR-feltet skrivebeskyttet |
Forskel fra Partnere: Organisationer bruger Zohos standard adressefelter (Gade, Postnummer, By) i stedet for custom adressefelter.
Workflows: Partnere
Partnere har det mest omfattende workflow-setup med 16 regler fordelt på oprettelse, redigering og oprettelse/redigering.
Ved Oprettelse (4 regler)
Oprettelse - Regel 1: CVRintegration.dk
Betingelse: CVR/VAT Nr. er IKKE TOM.
Handling: Custom Function
Funktionalitet: Serverside CVR-opslag. Henter stamdata, finansdata og opretter automatisk Kontakter for direktører og bestyrelsesmedlemmer.
void automation.CVRintegration_dk1(Int accid) {
fetch_contacts = true;
account = zoho.crm.getRecordById("Partnere", accid);
cvr = account.get("CVR_VAT_Nr");
// Dansk CVR: Hent fuld data + opret kontakter
cvrdata = invokeurl[url: "http://api.cvrintegration.dk/fetchdata?query=" + cvr
type: GET connection: "cvrintegration"];
// Opdater partner med stamdata, finansdata, adresse
mp.put("Phone", ifnull(account.get("Phone"), phone));
mp.put("Selskabstype", ifnull(company_type, account.get("Selskabstype")));
// ... flere felter ...
// Opret kontakter for direktører
for each direktoer in cvrdata.get("direktoer") {
dmp.put("Kontakt_Rolle", "Partner");
dmp.put("Partner_Navn", accid);
zoho.crm.createRecord("Contacts", dmp);
}
// Opret kontakter for bestyrelsesmedlemmer
for each bestyrelsesmedlem in cvrdata.get("bestyrelsesmedlemmer") {
bmp.put("Kontakt_Rolle", "Bestyrelsesmedlem");
zoho.crm.createRecord("Contacts", bmp);
}
}
Oprettelse - Regel 2: Vælg kædefakturering
Betingelse: Kæde er IKKE TOM.
Handling: Custom Function - sætter Faktureres gennem til "Kæde".
void automation.changeInvoiceMethod(Int partner_id) {
mp = Map();
mp.put("Faktureres_gennem", "Kæde");
zoho.crm.updateRecord("Partnere", partner_id, mp);
}
Oprettelse - Regel 3: Opret Partner i LS
Betingelse: Status ≠ "Aktiv", Internal Merchant ID er TOM, Kommunenummer ≠ 1 (tag).
Handlinger: Opret partner i LS + Opret kunde i BC + Sæt partnernummer (2 min. forsinkelse)
Funktionalitet: Opretter partneren i Loyalty Solutions og opretter en kunde i Business Central (POST). Ved succes gemmes Internal Merchant ID og der oprettes en påmindelsesopgave. Ved fejl gemmes fejlbesked og status sættes til "Afvist af LS".
Oprettelse - Regel 4: Vælg selvstændig fakturering
Betingelse: Kæde er TOM.
Handling: Custom Function - sætter Faktureres gennem til "Selvstændigt".
Ved Redigering (11 regler)
Redigering - Regel 1: CVRintegration.dk
Betingelse: CVR/VAT Nr. ændret til ikke-tom værdi.
Handling: Custom Function - identisk logik som ved oprettelse.
Redigering - Regel 2: Opdater Kontakt Felter
Betingelse: Harmoninr, CVR/VAT Nr., Kort Nummer eller Cpr ændres.
Handling: Custom Function
Funktionalitet: Synkroniserer CVR, Website og Ownership fra partneren til alle tilknyttede kontakter. Sætter synkroniseringsfelterne på kontakterne.
void automation.updatePartnerContactFields(Int partner_id) {
account = zoho.crm.getRecordById("Partnere", partner_id);
cvr = account.get("CVR_VAT_Nr");
website = account.get("Website");
if (website == null) { website = account.get("Kerne_Website"); }
mp = Map();
if (cvr != null) { mp.put("CVR_VAT_Nr", cvr); mp.put("Show_Fields", true); }
if (website != null) { mp.put("Websted_1", website); mp.put("Show_Website", true); }
related_contact_list = zoho.crm.getRelatedRecords("Contacts2", "Partnere", partner_id);
for each contact in related_contact_list {
zoho.crm.updateRecord("Contacts", contact.get("id"), mp);
}
}
Redigering - Regel 3: Opret Partner i LS
Betingelse: Status ændret til "Aktiv", Internal Merchant ID er TOM.
Handlinger:
- Custom Function: Opret partner i LS
- Custom Function: Opret kunde i Business Central (POST)
- Planlagt handling: Sæt Partnernummer (2 min. efter, sætter Partnernummer = record ID)
Redigering - Regel 4: Opdater Partner i LS
Betingelse: Status = "Aktiv", Internal Merchant ID er IKKE TOM, Kommunenummer ≠ 1 (tag).
Handling: Custom Function (Opdater Partner i LS)
Funktionalitet (change detection):
- Hent Old Record Data (snapshot fra sidste sync)
- Hent aktuelle data fra CRM-recorden
- Sammenlign felt for felt - kun ændrede felter sendes
- Særregel: Hvis Visa CAID, Visa BIN eller MC MID ændres, sendes alle tre
- PATCH til LS med kun ændrede felter
- Ved succes: Opdater Old Record Data med nye værdier
- Ved fejl: Gem fejlrespons i LS Error Data
Redigering - Regel 5: Fejl i Overførelse af Partner
Betingelse: Loyalty Solutions Fejlbesked ændret til ikke-tom.
Handling: Custom Function
Funktionalitet: Sender fejlbeskeden til OpenAI GPT-5 med en dansk prompt der beder om en brugervenlig oversættelse (maks 255 tegn). Resultatet gemmes i Chat Message.
Redigering - Regel 6 & 7: Faktureringsmetode
Regel 6: Kæde ændret til ikke-tom -> Faktureres gennem sættes til "Kæde"
Regel 7: Kæde ændret til tom -> Faktureres gennem sættes til "Selvstændigt"
Redigering - Regel 8: Sæt Partner til inaktiv i LS
Betingelse: Status ændret til "Lukket", Ophør(Afviklet/Opsagt) = "Opsagt".
Handling: Opretter en Opgave:
| Felt | Værdi |
|---|---|
| Emne | "Sæt Partner til inaktiv i LS" |
| Forfaldsdato | Udløsningsdato + 2 dage |
| Status | Ikke startet |
| Prioritet | Højeste |
| FBF Ansvarlig | Forbrugsforeningen Salg |
Redigering - Regel 9: Opdater BC Kunde
Betingelse: Debitor Nummer er IKKE TOM.
Handling: Custom Function (Synkroniser til BC)
Funktionalitet: Synkroniserer partnerdata til Business Central via SMART API. Mapper CRM-felter til BC Customer-felter og sender PUT-request. Adresserne hentes i prioriteret rækkefølge: Adresse 3 -> Adresse 2 -> Adresse 1.
Redigering - Regel 10: Skift Bonussats
Betingelse: Skift Bonussats Dato er IKKE NULL, Tidspunkt: på dato.
Handling: Custom Function
Funktionalitet: Henter Ny Bonussats, sender PATCH til LS med den nye sats, og rydder planlægningsfelterne.
void automation.skiftBonussats(Int partner_id) {
partner_response = zoho.crm.getRecordById("Partnere", partner_id);
crm_new_bonus = partner_response.get("Ny_Bonussats");
new_bonus = crm_new_bonus.remove("%").replaceAll(",", ".");
mp = Map();
mp.put("rewardRate", new_bonus);
internal_merchant_id = partner_response.get("internal_Merchant_ID");
ls_response = invokeurl
[
url: "https://fbf-loyaltfacts-api.loyaltfacts.com/merchants/" + internal_merchant_id
type: PATCH
parameters: mp
connection: "loyalty solutions"
];
// Ryd planlægningsfelter og opdater aktuel sats:
quick_mp = Map();
quick_mp.put("Ny_Bonussats", null);
quick_mp.put("Bonussats", crm_new_bonus);
quick_mp.put("Skift_Bonussats_Dato", null);
zoho.crm.updateRecord("Partnere", partner_id, quick_mp);
}
Redigering - Regel 11: Skift Vederlagssats
Betingelse: Skift Vederlagssats Dato er IKKE NULL, Tidspunkt: på dato.
Handling: Custom Function - identisk logik som bonussats, men med vederlagssatsen.
Ved Oprettelse ELLER Redigering (1 regel)
Opret/Rediger - Regel 1: Kopier Data fra Kæde
Betingelse: Kæde er IKKE TOM.
Handling: Custom Function (Kopier Kæde Data)
Funktionalitet: Kopierer data fra den tilknyttede kæde til partneren, men kun for felter der er tomme på partneren. Overskriver aldrig eksisterende data. Feltet Ophørelsesårsag springes altid over.
void automation.copyChainData(Int partner_id) {
partner_response = zoho.crm.getRecordById("Partnere", partner_id);
// Find alle tomme felter på partner
for each key in partner_response.keys() {
if (value == null || value == "") { partner_map.put(key, null); }
}
// Hent kæde-data
chain_response = zoho.crm.getRecordById("Chains", partner_response.get("K_de").get("id"));
// Kopier kun felter der er tomme på partner men har værdi på kæde
for each partner_key in partner_map.keys() {
if (chain_map.containsKey(partner_key) && partner_key != "Oph_relse_rsag") {
update_map.put(partner_key, chain_map.get(partner_key));
}
}
zoho.crm.updateRecord("Partnere", partner_id, update_map);
}
Workflows: Kæder
Kæder har 9 workflow-regler der styrer synkronisering til LS, kaskadeopdatering af partnere og BC-integration.
Ved Oprettelse (1 regel)
Oprettelse - Regel 1: Opret Kæde i LS
Betingelse: Internal Chain ID er TOM, Status ≠ "Aktiv", Kommunenummer ≠ 1 (tag).
Handlinger: Opret kæde i LS + Opret kunde i Business Central (POST)
Funktionalitet:
- Opretter kæden i LS med navn, kategori, land, bonussats/vederlagssats, fakturadata
- Gemmer Internal Chain ID fra LS-respons
- Opretter en kunde i Business Central via POST
- Markerer alle tilknyttede partnere så de opdateres mod LS
- Ved fejl: Sætter Type til "Afvist af LS"
Ved Redigering (8 regler)
Redigering - Regel 1: Opdater Partnere (kaskade)
Betingelse: Status ændres.
Handling: Custom Function (Opdater Partnere)
Funktionalitet: Når en kædes status ændres, kaskaderes statusændringen til alle tilknyttede partnere.
void automation.opdaterPartnere(Int chain_id) {
chain_response = zoho.crm.getRecordById("Chains", chain_id);
chain_status = chain_response.get("Type");
partner_list = zoho.crm.getRelatedRecords("Partnere", "Chains", chain_id);
mp = Map();
mp.put("Partner_Status", chain_status);
for each partner in partner_list {
zoho.crm.updateRecord("Partnere", partner.get("id"), mp);
}
}
Redigering - Regel 2: Opret Kæde i LS
Betingelse: Status ændret, Internal Chain ID er TOM, status ≠ "Lukket".
Handlinger: Identisk med oprettelses-reglen (inkl. BC POST).
Redigering - Regel 3: Opdater Kæde i LS
Betingelse: Status = "Aktiv", felter ændret.
Handling: Custom Function (Opdater Kæde i LS)
Funktionalitet: Identisk change-detection logik som partnere. Sammenligner Old Record Data med aktuelle værdier og sender kun ændringer via PATCH.
Redigering - Regel 4: Automatisk udfyld Is Closed
Betingelse: Type ændret til "Lukket".
Handling: Feltopdatering - sætter Is Closed til True
Redigering - Regel 5: Inaktive Kæde (opgave)
Betingelse: Status ændret til "Lukket", Ophør(Afviklet/Opsagt) = "Opsagt".
Handling: Opretter Opgave: "Sæt kæde til inaktiv i LS" med forfald = Udløsningsdato + 3 dage, prioritet Højeste.
Redigering - Regel 6: Opdater BC Kunde
Betingelse: Debitor Nummer er IKKE TOM.
Handling: Custom Function (Synkroniser Kæde til BC)
Identisk logik som Partner BC-sync, men mapper fra Kæde-felter.
Redigering - Regel 7: Skift Bonussats
Betingelse: Skift Bonussats Dato er IKKE NULL, Tidspunkt: på dato.
Handling: Custom Function - sender PATCH med ny bonussats til LS for kæden.
Redigering - Regel 8: Skift Vederlagssats
Betingelse: Skift Vederlagssats Dato er IKKE NULL, Tidspunkt: på dato.
Handling: Custom Function - sender PATCH med ny vederlagssats til LS for kæden.
Workflows: Kontakter
Kontakter har 3 workflow-regler.
Oprettelse - Regel 1: CVRintegration.dk
Betingelse: CVR/VAT Nr. er IKKE TOM.
Handling: Custom Function
Funktionalitet:
- Søger efter eksisterende Organisation med samme CVR
- Hvis fundet: Tilknytter kontakten til organisationen og kopierer adresse
- Hvis ikke fundet: Opretter ny Organisation via CVR-data og tilknytter kontakten
- Opretter også kontakter for direktører og bestyrelsesmedlemmer (ligesom Partnere)
Redigering - Regel 1: CVRintegration.dk
Betingelse: CVR/VAT Nr. ændret til ikke-tom værdi.
Handling: Identisk logik som ved oprettelse.
Opret/Rediger - Vis/Skjul Felter
Betingelse: Record oprettet eller redigeret.
Handling: Custom Function (Vis/Skjul Felter)
Funktionalitet: Henter CVR, Website og Ownership fra den tilknyttede Organisation og/eller Partner. Sætter visibility-flags (Show Fields, Show Website, Show Ownership) så relevante felter vises/skjules på kontakten.
Prioritet: Organisationsdata foretrækkes. Partnerdata bruges kun som fallback for felter der ikke findes på organisationen.
Workflows: Organisationer
Organisationer har 5 workflow-regler: 2 CVR-integrationer (identisk med Partnere) og 3 custom-regler.
CVRintegration.dk (Oprettelse + Redigering): Identisk logik som Partnere-modulets CVR-workflows. Se Workflows: Partnere.
Redigering - Aktiver Partner
Betingelse: Organisations Status ændret til "Godkendt Partner".
Handling: Custom Function (Aktiver Partner)
void automation.aktiverPartner(Int account_id) {
account_response = zoho.crm.getRecordById("Accounts", account_id);
partner_number = account_response.get("Partner_nummer");
mp = Map();
mp.put("businessId", partner_number);
}
Redigering - Opdater Kontakt Felter
Betingelse: CVR/VAT Nr. eller Harmoninr ændres.
Handling: Custom Function (Opdater Kontakt Felter)
Funktionalitet: Synkroniserer CVR og Website fra organisationen til alle tilknyttede kontakter. Sætter visibility-flags.
void automation.updateContactFields(String account_id) {
account = zoho.crm.getRecordById("Accounts", account_id);
cvr = account.get("CVR_VAT_Nr");
website = account.get("Website");
mp = Map();
if (cvr != null) { mp.put("CVR_VAT_Nr", cvr); mp.put("Show_Fields", true); }
if (website != null) { mp.put("Websted_1", website); mp.put("Show_Website", true); }
contacts = zoho.crm.searchRecords("Contacts",
"(Account_Name:equals:" + account.get("Account_Name") + ")");
for each contact in contacts {
zoho.crm.updateRecord("Contacts", contact.get("id"), mp);
}
}
Redigering - Fusionering
Betingelse: Fusioneres sammen med ændret til ikke-tom værdi.
Handling: Custom Function (Organisations Fusionering)
Funktionalitet: Overfører alle kontakter fra den aktuelle organisation til målorganisationen.
void automation.organisationsFusionering(Int org_id) {
org_response = zoho.crm.getRecordById("Accounts", org_id);
new_org_id = org_response.get("Fusioneres_sammen_med").get("id");
// Transfer contacts
contact_list = zoho.crm.getRelatedRecords("Contacts", "Accounts", org_id);
for each contact in contact_list {
zoho.crm.updateRecord("Contacts", contact.get("id"),
{"Account_Name": new_org_id});
}
}
Workflows: Ejerskaber
Ejerskaber har 2 workflow-regler - begge er CVR-integration.