# Shopify

Alle Schlüssel dieser Seite stehen in der `config.json` im Abschnitt `shopify`. Was der
Artikel- und Bestellabgleich im Regelfall tut, steht im
[Handbuch für Shopify](https://wiki.dako-it.com/books/finnghost-fur-shopify).

## Artikel und Preise

| Schlüssel | Typ | Wirkung |
| ------------------------------ | -------- | ------------------------------------------- |
| `continueSelling` | Feldname | Artikelfeld; liefert es einen Wert, bleibt der Artikel bei Bestand 0 **weiter bestellbar**. |
| `forceTax` | Schalter | überträgt jeden Artikel als **steuerpflichtig**, auch wenn in der SelectLine kein gültiger Steuersatz gefunden wird. |
| `reducedTax` | Wert | Steuercode der SelectLine, der als **ermäßigt** gilt. Vorgabe `2`. Artikel mit diesem Code kommen in die Artikelgruppe für ermäßigte Steuer. |
| `costPricePG` | Wert | Preisgruppe, aus der die **Kosten** je Artikel übertragen werden. Ohne die Angabe gilt der letzte Einkaufspreis aus der Kalkulation. |
| `firstImgToEnd` | Schalter | verschiebt das **erste Bild an das Ende** der Bilderreihe. |
| `disableSafeguardPriceField` | Feldname | Artikelfeld; ist es `True`, wird ein Artikel **ohne Preis** mit Preis 0 übertragen statt übersprungen. |
| `extrafeldMapping` | Liste | benennt Zusatzfelder beim Übertragen um, wie bei Shopware 6. Das Ursprungsfeld wird dabei immer entfernt. |

<p class="callout warning">Ohne <code>disableSafeguardPriceField</code> wird ein Artikel ohne gültigen Preis in Shopify <strong>archiviert</strong> und eine Meldung ins Protokoll geschrieben. Das ist Absicht — ein Artikel mit Preis 0 im Shop ist teurer als ein fehlender.</p>

<p class="callout info"><code>firstImgToEnd</code> wirkt nur bei Artikeln mit mehr als einem Bild. Der Hintergrund: Shopify zeigt das erste Bild als Vorschaubild, die SelectLine sortiert Bilder nach der Ordnung — passt beides nicht zusammen, ist das die schnellste Abhilfe.</p>

<p class="callout warning">Bei <code>continueSelling</code> wird — anders als bei den übrigen Feldern dieses Kapitels — <strong>nicht</strong> auf den Wert <code>True</code> geprüft. Ausgewertet wird nur, ob das Feld überhaupt einen Wert liefert. Ein Ja/Nein-Extrafeld ist hier deshalb die falsche Wahl: Es enthält auch bei <em>Nein</em> einen Wert. Passend ist ein Feld, das für die betroffenen Artikel gefüllt und für alle anderen leer ist.</p>

<p class="callout danger"><code>reducedTax</code> vergleicht den <em>Steuercode</em> des Artikels, nicht den Steuersatz. Bei abweichender Nummerierung der Steuercodes im Mandanten muss der Wert angepasst werden — sonst landen entweder alle oder keine Artikel in der Gruppe für ermäßigte Steuer.</p>

## Artikelgruppen und Aufräumen

| Schlüssel | Typ | Wirkung |
| ------------------------------ | -------- | ------------------------------------------- |
| `shopaktivArtikelGruppenFeld` | Feldname | Feld an der Artikelgruppe; nur Gruppen mit `True` werden übertragen. |
| `deleteUnknownProducts` | Schalter | **archiviert** Produkte im Shop, die in der SelectLine nicht existieren oder nicht mehr shopaktiv sind. |

<p class="callout danger"><code>deleteUnknownProducts</code> greift auf den ganzen Shop zu. Produkte, die im Shop von Hand angelegt wurden und in der SelectLine nicht existieren, werden dabei ebenfalls archiviert. Vor dem Einschalten gehört geprüft, ob es solche Produkte gibt.</p>

## Bestände

Bestand und Bestandsführung stehen auf einer eigenen Seite, weil dort mehrere
Einstellungen zusammenwirken: [Bestand und Bestellmenge](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/bestand-und-bestellmenge).

## Belege

| Schlüssel | Typ | Wirkung |
| ---------------------------------------- | -------- | --------------------------------- |
| `idField` | Feldname | Belegfeld, in dem die **Shopify-Bestellkennung** abgelegt wird. Vorgabe `IhrAuftrag`. |
| `orderTag` | Wert | Kürzel, mit dem die Kennung beginnt. Vorgabe `sfy_`. |
| `mailField` | Feldname | Belegfeld für die **E-Mail-Adresse** des Bestellers. |
| `phoneField` | Feldname | Belegfeld für die **Telefonnummer**. |
| `noteToFooter` | Schalter | schreibt die Kundenanmerkung in den **Schlusstext** statt in den Kopftext. |
| `useSfyPostext` | Schalter | übernimmt den **Positionstext aus Shopify** statt der Artikelbezeichnung aus der SelectLine. Auf 80 Zeichen gekürzt. |
| `documentImportCheckField` | Feldname | Belegfeld, das nach erfolgreichem Import auf `True` gesetzt wird. |
| `tooLongAdrField` | Feldname | Belegfeld, in dem Adressbestandteile über 80 Zeichen vermerkt werden. |
| `simplePrintStatus` | Schalter | erkennt den Versand daran, dass der Lieferschein als **gedruckt** markiert und der Beleg seit dem letzten Lauf bearbeitet wurde — statt am protokollierten Druckvorgang. |
| `mapMarketOrderIdField` | Feldname | Belegfeld für die **Amazon-Bestellnummer** aus den Bestellattributen. Vorgabe `_SFYMARKETORDERID`. |
| `businessPartnerContractDateWithTime` | Schalter | schreibt in das Vertragsdatum zusätzlich die **Uhrzeit**. |
| `noPosCheck` | Schalter | schaltet die Kontrolle ab, ob alle Positionen im Beleg angekommen sind. |
| `useCurrentQuantity` | Schalter | übernimmt die in Shopify **verbleibende Menge** statt der ursprünglich bestellten. In Shopify entfernte Positionen landen dadurch nicht im Beleg. |

<p class="callout danger"><code>idField</code> und <code>orderTag</code> sind die Wiedererkennung einer Bestellung. Werden sie im laufenden Betrieb geändert, findet FINN.ghost die bereits importierten Bestellungen nicht mehr und importiert sie erneut. Beides gehört vor der Inbetriebnahme festgelegt und danach nicht mehr angefasst.</p>

<p class="callout warning"><code>noPosCheck</code> schaltet eine Sicherung ab: Normalerweise vergleicht FINN.ghost nach dem Anlegen die Anzahl der Positionen und bricht mit einem Fehler ab, wenn die SelectLine Positionen verworfen hat. Ohne diese Prüfung entstehen unvollständige Belege, ohne dass es auffällt.</p>

<p class="callout success"><code>useCurrentQuantity</code> ist die Antwort auf entfernte Positionen: Wird eine Bestellung in Shopify nach dem Eingang bearbeitet — eine Position entfernt oder die Menge verringert — bleibt die ursprüngliche Menge (<code>quantity</code>) an der Position stehen, die verbleibende steht in <code>current_quantity</code>. Ohne den Schalter übernimmt FINN.ghost die ursprüngliche Menge und legt entfernte Positionen mit an. Mit dem Schalter zählt die verbleibende Menge; Positionen mit Menge 0 werden übersprungen und ein anteiliger Rabatt wird mitgekürzt. Greift nur bei Bestellungen, die zum Zeitpunkt des Imports bereits bearbeitet waren — ein bestehender Beleg wird nicht nachträglich angepasst.</p>

<p class="callout warning"><code>useCurrentQuantity</code> und die Gutschriftenprüfung (<code>disableRefundCheck</code> auf <code>false</code>) schließen sich aus. Die Gutschriftenprüfung braucht die volle Menge im Auftrag, um daraus die Gutschrift zu bilden — sind die Positionen bereits gekürzt, findet sie die Position nicht mehr und der Import läuft auf einen Fehler.</p>

<p class="callout info"><code>tooLongAdrField</code> ist für Shops mit langen Firmenbezeichnungen gedacht. Die SelectLine nimmt nur 80 Zeichen je Adressfeld — was abgeschnitten wird, ist dann wenigstens am Beleg vermerkt.</p>

<p class="callout success"><code>simplePrintStatus</code> ist die Abhilfe, wenn Versandmeldungen ausbleiben, obwohl Lieferscheine gedruckt werden. Normalerweise liest FINN.ghost den Druckvorgang aus der Belegausgabe — wird in der SelectLine nicht über den regulären Druck ausgegeben, entsteht dort kein Eintrag. Der Schalter wertet dann stattdessen das Kennzeichen <em>Gedruckt</em> am Beleg aus.</p>

### Gutschriften

| Schlüssel | Typ | Wirkung |
| --------------------------------- | ---- | ------------------------------------------------ |
| `belegtyp_gutschrift` | Wert | Belegtyp für Gutschriften. Vorgabe `G`. |
| `belegtyp_gutschriftNoRestock` | Wert | abweichender Belegtyp für Gutschriften **ohne Rücknahme in den Bestand**. |
| `disableRefundCheck` | Schalter | Vorgabe `true`. Mit `false` prüft FINN.ghost auch bei einem Komplettstorno auf Gutschriften. |

<p class="callout success"><code>belegtyp_gutschriftNoRestock</code> ist die Antwort auf eine häufige Anforderung: Wird eine Rücksendung in Shopify ohne Wiedereinlagerung erstattet, soll in der SelectLine ein Belegtyp entstehen, der den Bestand nicht erhöht.</p>

### Zuordnung über Tags und Metafelder

| Schlüssel | Typ | Wirkung |
| ------------------------ | ----- | ------------------------------------------------------ |
| `shopkundeTagMapping` | Liste | ordnet einem **Bestell-Tag** einen anderen Shopkunden zu. |
| `mapMetafields` | Liste | überträgt **Metafelder** der Bestellung in Belegfelder. |
| `presentment_currencies` | Liste | Währungen, in denen Bestellungen zusätzlich importiert werden. |

```json
{
  "shopify": {
    "shopkundeTagMapping": { "b2b": "10001", "haendler": "10002" },
    "mapMetafields": { "custom": { "wunschtermin": "FreiesDatum1" } }
  }
}
```

<p class="callout info">Bei <code>mapMetafields</code> ist die Struktur zweistufig: erst der Namensraum des Metafelds, darin der Schlüssel, dahinter das Ziel-Belegfeld.</p>

## Kunden

| Schlüssel | Typ | Wirkung |
| ------------------------------------ | -------- | --------------------------------------- |
| `kdfeld1` bis `kdfeld9` | Feldname | **weitere** Kundenfelder, in denen bei der Suche nach einem vorhandenen Kunden ebenfalls nach der Shopify-Kundennummer gesucht wird. |
| `customerNumberRange` | Wert | Nummernkreis für neu angelegte Kunden. Die neue Nummer ist die höchste vorhandene Nummer mit diesem Beginn, um eins erhöht. |
| `updateCustomer` | Schalter | aktualisiert vorhandene Kunden beim Bestellimport, auch wenn das Aktualisieren sonst abgeschaltet ist. |
| `sendEmailInviteToNewCustomers` | Schalter | lässt Shopify neu angelegten Kunden eine **Einladung** senden. |

<p class="callout warning">Die Felder <code>kdfeld1</code> bis <code>kdfeld9</code> ergänzen das in der Oberfläche eingestellte Kundenfeld, sie ersetzen es nicht. Ist <code>kdfeld1</code> gesetzt, schreibt FINN.ghost die Kundennummer bei neuen Kunden allerdings <strong>nicht</strong> mehr selbst in das Standardfeld — dann sind diese Felder die einzige Zuordnung und müssen gepflegt sein.</p>

<p class="callout danger">Vor <code>sendEmailInviteToNewCustomers</code> ist zu bedenken, dass Shopify die Mail an jeden neu übertragenen Kunden schickt. Beim ersten Vollabgleich der Kunden aus der SelectLine sind das unter Umständen sehr viele Mails auf einmal.</p>

## B2B mit Shopify Plus

| Schlüssel | Typ | Wirkung |
| --------------------------------- | -------- | ---------------------------------------- |
| `plus.status` | Schalter | schaltet den B2B-Betrieb ein: Kunden werden als **Firmen** übertragen statt als Privatkunden. |
| `plus.checkoutToDraft` | Schalter | Bestellungen der Firma werden als **Entwurf** angelegt und müssen freigegeben werden. |
| `plus.editableShippingAddress` | Schalter | die Lieferadresse darf im Shop geändert werden. |
| `plus.paymentTermsTemplateId` | Wert | Kennung der Zahlungsbedingung, die den Firmen zugewiesen wird. |

<p class="callout danger"><code>plus.status</code> setzt Shopify Plus voraus und ändert die Übertragung grundlegend. Zusätzlich entfällt damit die Prüfung, ob eine Bestellung bezahlt ist — im B2B ist der Rechnungskauf der Regelfall, unbezahlte Bestellungen werden also importiert.</p>

<p class="callout info">Die Kennung für <code>plus.paymentTermsTemplateId</code> ist die reine Nummer der Vorlage aus Shopify; die vollständige Kennung setzt FINN.ghost selbst zusammen.</p>

## Nächster Schritt

[Weitere Module](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/weitere-module)