Definition der Anbindung SAP B1 an Shopware

Grundsätzliches zu sync4

sync4® verbindet die Warenwirtschaft SAP B1 mit Ihrem Shopware Shop. Produktinformationen lassen sich so komfortabel aufbereiten und mit der sync4 Schnittstelle an Ihren Shop übertragen. Bestellungen und Kundendaten werden GDPdU-konform synchronisiert. Als Middleware ist sync4® zwischen Ihrer Warenwirtschaft und Ihrem Onlineshop geschaltet, um Ihre Artikelinformationen aufzubereiten und mit dem Onlineshop zu synchronisieren.

Grundsätzliches zu Shopware

Shopware ist ein Shop System der Shopware AG. Die Shopware AG als Hersteller übernimmt für das Shopsystem die Gewährleistung.

Shopware Hosting

Als Hoster wird ein von Shopware zertifizierter Hoster wie z.B. Profihost (http://s.sync4.de/profihost) empfohlen. Nur mit einem solchem Hoster wird Shopware vollständigen Support übernehmen können. Andernfalls kann es sein, dass der Support von Shopware abgelehnt wird. Bei nicht zertifizierten Hostern sind die Systemvoraussetzungen ( https://community.shopware.com/Systemanforderungen_detail_1840.html )  zu prüfen. Der Hoster bzw. der Betreuer dessen muss die entsprechenden Anpassungen vornehmen. Dies kann hierbei zu einem erhöhtem Aufwand führen.

Shopware Plugins

Für Plugins von Drittanbieter sind die jeweiligen Hersteller verantwortlich. Die empfohlenen Plugins werden vorab nicht auf Funktion getestet. Plugins werden im Standard von sync4 nicht berücksichtigt.

sync4 Voraussetzung

Die Systemvoraussetzungen für die Installation und den Betrieb der sync4 Schnittstelle ist auf folgender Seite notiert: https://www.sync4.de/voraussetzungen/

Empfohlener Projekt Ablauf

Den aktuellen Projekt-Leitfaden zur Einführung von sync4 finden Sie bei uns auf der Homepage: https://www.sync4.de/leitfaden/

Felddefinitionen

SAP B1 an Shopware -> Artikel

Folgende Felder werden bei der Übernahme der Artikel aus SAP B1 übernommen.

 

SAP B1 sync4 Shopware Anmerkung
OITM.ItemCode products_model article.mainDetail Artikelnummer
OITM.ItemName products_name article.name Artikelname
OITM.OnHand products_quantity article.inStock Bestand
OITM.OnOrder products_ordered article.inStock – Auftragsbestand
OITM.IsCommited products_committed article.inStock + Bestellbestand
OITM.PictureName Medien Tabelle Medien Tabelle Artikelbild
OITM.SWeight1 products_weight article.weight Gewicht
OITM.VatGourpSA products_tax_class article.tax Steuersatz
OITM.CodeBars products_ean article.ean EAN Nummer
OITM.frozenfor products_status article.active Artikelstatus
OITM.UserText products_description article.descriptionLong Artikelbeschreibung
SalPackUn VPE article.purchaseUnit VPE
SalPackMsr products_vpe_unit article.unit VPE Wert
OITM.SuppCatNum Products_manufacures_number Article.mainDetail.supplierNumber

Weitere Felder wie z.B. UDF und UDTs können mit einer Sonderprogrammierung berücksichtigt werden. Dabei ist sehr genau zu definieren, welche Felder wie übertragen werden sollen.

Shopware an SAP B1 -> Adresse und Bestellung

Folgende Felder werden bei der Adresse Übergabe vom Shopware Shop zu SAP verwendet.

Shopware sync4 SAP B1 Anmerkung
order.number orders_id vOrder.NumAtCard Wenn Bankverbindung vorhanden auch vBP.BPBankAccounts.UserNo2
order.billing.number customers_id
billing.vatId customers_vat_id vBP.Addresses.FederalTaxID
order.customer.salutation customers_gender vBP.ContactEmployees.Gender Nur Frau oder Mann
order.billing.firstName + order.billing.lastName customers_name vBP.ContactPerson + vBP.CardName (Wenn keine Firma) + vBP.ContactEmployees.Name
order.billing.firstName customers_firstname vBP.ContactEmployees.FirstName
order.billing.lastName customers_lastname vBP.ContactEmployees.LastName
order.billing.company customers_company vBP.CardName
order.billing.street customers_street_address
order.billing.city customers_city
order.billing.zipCode customers_postcode
order.billing.country.isoName customers_country
order.billing.phone customers_telephone vBP.Phone1 + vBP.ContactEmployees.Phone1
order.customer.email customers_email_address vBP.EmailAddress + vBP.ContactEmployees.E_Mail
order.delivery.firstName + order.delivery.lastName delivery_name vBP.Addresses.AddressName + vBP.Addresses.AddressName2 + wenn Firma (vBP.Addresses.AddressName3)
order.delivery.firstName delivery _firstname
order.delivery.lastName delivery _lastname
order.delivery.company delivery_company vBP.Addresses.AddressName + vBP.Addresses.AddressName2
order.delivery.street delivery_street_address vBP.Addresses.Street
order.delivery.city delivery_city vBP.Addresses.City
order.delivery.zipCode delivery_postcode vBP.Addresses.ZipCode
order.delivery.country.isoName delivery_country
order.delivery.country.iso delivery_country_iso_code_2 vBP.Addresses.Country
order.delivery.phone delivery_telephone
order.customer.email delivery_email_address
order.billing.firstName + order. billing.lastName billing_name vBP.Addresses.AddressName + vBP.Addresses.AddressName2 + wenn Firma (vBP.Addresses.AddressName3)
order.billing.firstName billing_firstname
order.billing.lastName billing_lastname
order.billing.company billing_company vBP.Addresses.AddressName + vBP.Addresses.AddressName2
order.billing.street billing_street_address vBP.Addresses.Street
order.billing.city billing_city vBP.Addresses.City
order.billing.zipCode billing_postcode vBP.Addresses.ZipCode
order.billing.country.isoName billing_country
order.billing.country.iso billing_country_iso_code_2 vBP.Addresses.Country
order.billing.phone billing_telephone
order.billing.email billing_email_address
order.customerComment comments vOrder.Comments
order.orderTime date_purchased vOrder.DocDate + vBP.BPBankAccounts.SignatureDate
order.orderStatusId orders_status
order.currency currency
order.currencyFactor currency_value
order.customer.accountMode account_type
order.payment.name payment_class vOrder.PaymentGroupCode
order.payment.name payment_method
order.dispatch shipping_method
order.dispatch shipping_class vOrder.TransportationCode
order.paymentInstances[0].accountHolder banktransfer_owner vBP.BPBankAccounts.AccountName + vBP.BPBankAccounts.UserNo1
order.paymentInstances[0].accountNumber banktransfer_number vBP.BPBankAccounts.AccountNo + vBP.DefaultAccount
order.paymentInstances[0].bankName banktransfer_bankname
order.paymentInstances[0].bankCode banktransfer_blz vBP.BPBankAccounts.BankCode + vBP.DefaultBankCode
order.paymentInstances[0].iban IBAN vBP.BPBankAccounts.IBAN
order.paymentInstances[0].bic BIC vBP.BPBankAccounts.BICSwiftCode
vBP.BPBankAccounts.MandateID IBAN+“_“+vBP.CardCode
order.transactionId transaction_number
position.articleNumber products_model vOrder.Lines.ItemCode
position.articleName products_name
price products_price ?
final_price final_price
position.quantity products_quantity vOrder.Lines.Quantity
taxRate original_tax
price price_net vOrder.Lines.UnitPrice Wenn Bruttopreis != -1
price bzw. price_gross price_gross vOrder.Lines.PriceAfterVat Wenn Bruttopreise == -1
order.billing.countryId geo_zone_id
position.tax_shopID tax_rates_id
products_tax products_tax Wird verwendet für die Variable Bruttopreise
order.net und order.taxFree allow_tax Wird verwendet für die Variable Bruttopreise

 

Weitere Felder können mit einer Sonderprogrammierung berücksichtigt werden. Dabei ist sehr genau zu definieren, welche Felder wie übertragen werden sollen. Sprechen Sie dies auch mit Ihrem SAP B1 Betreuer ab, da die Felder in der weiteren Verarbeitung berücksichtigt werden müssen.

Preislisten zu Kundengruppen

Die Preislisten können zu den Shopware Kundengruppen zugewiesen werden. Dabei kann auch eine Preisliste aus SAP mehrfach verwendet werden. Mit folgendem SQL Befehl werden die Preise ausgelesene. Lassen Sie diesen von Ihrem SAP Betreuer prüfen.

SELECT b.ItemCode AS Artikelnummer, b.PriceList as Preisliste, ‚1‘ as Anzahl,
(
SELECT CASE
WHEN (ISNULL(IsGrossPrc, ‚N‘) = ‚Y‘)
THEN ISNULL(d.Price*(100-c.Discount)/100,ISNULL(c.Price,ISNULL(d.Price*(100-a.Discount)/100,ISNULL(a.Price,b.Price)))) / ((100.0 + (SELECT ISNULL(Rate,0) FROM OVTG WHERE Code = VatGourpSa)) / 100)
ELSE
ISNULL(d.Price*(100-c.Discount)/100,ISNULL(c.Price,ISNULL(d.Price*(100-a.Discount)/100,ISNULL(a.Price,b.Price))))
END
)
AS Preis,
“ as Rabatt

FROM ITM1 AS b
LEFT JOIN SPP1 AS a ON a.ItemCode = b.ItemCode and replace(a.CardCode,’*‘,“) = cast(b.PriceList as nvarchar) and a.FromDate <= GETDATE() and (a.ToDate+1 >= GETDATE() or a.ToDate IS NULL)
LEFT JOIN SPP2 AS c ON a.ItemCode = c.ItemCode and a.CardCode = c.CardCode and a.LINENUM = c.SPP1LNum and c.Amount = 1
LEFT JOIN ITM1 AS d ON a.ItemCode = d.ItemCode and a.ListNum = d.PriceList and ISNULL(d.Currency,“) != “ and ISNULL(d.Price,0) != 0
LEFT JOIN OPLN AS e ON b.PriceList = e.ListNum
LEFT JOIN OITM AS f ON b.ItemCode = f.ItemCode
WHERE b.ItemCode = ‚{0}‘ and (ISNULL(d.Price,0)!=0 or ISNULL(c.Price,0)!=0 or ISNULL(b.Price,0)!=0 or ISNULL(a.Price,0)!=0)
UNION

SELECT b.ItemCode AS Artikelnummer, b.PriceList as Preisliste, c.Amount as Anzahl,
(
SELECT CASE
WHEN (ISNULL(IsGrossPrc, ‚N‘) = ‚Y‘)
THEN ISNULL(d.Price*(100-c.Discount)/100,ISNULL(c.Price,0)) / ((100.0 + (SELECT ISNULL(Rate,0) FROM OVTG WHERE Code = VatGourpSa)) / 100)
ELSE
ISNULL(d.Price*(100-c.Discount)/100,ISNULL(c.Price,0))
END
)
AS Preis,
“ as Rabatt

FROM ITM1 AS b
LEFT JOIN SPP2 AS c ON c.ItemCode = b.ItemCode and replace(c.CardCode,’*‘,“) = cast(b.PriceList as nvarchar)
LEFT JOIN SPP1 AS a ON a.ItemCode = c.ItemCode and c.SPP1LNum = a.LINENUM and c.CardCode = a.CardCode
LEFT JOIN ITM1 AS d ON a.ItemCode = d.ItemCode and a.ListNum = d.PriceList and ISNULL(d.Currency,“) != “ and ISNULL(d.Price,0) != 0
LEFT JOIN OPLN AS e ON b.PriceList = e.ListNum
LEFT JOIN OITM AS f ON b.ItemCode = f.ItemCode
WHERE c.ItemCode = ‚{0}‘ and a.FromDate <= GETDATE() and (a.ToDate+1 >= GETDATE() or a.ToDate IS NULL) and (ISNULL(d.Price,0)!=0 or ISNULL(c.Price,0)!=0) and c.Amount > 1

Kundenspezifische Einzelpreise

Die Erweiterung kundenspezifische Einzelpreise ist eine kostenpflichtiges Modul für sync4. Für die Verwendung von kundenspezifischen Einzelpreisen wird ein Plugin im Shopware Shop benötigt (https://store.shopware.com/swaguserpricef/kundenspezifische-preise.html). Die Reihenfolge ist definiert anhand der aufgelisteten SQL Befehle.

getCustomerPrices

getCustomerPrices
SELECT ‚{customers_cid}‘ AS customers_cid, a.ItemCode AS products_model,
ISNULL(b.Discount,ISNULL(c.Discount,ISNULL(a.Discount,0))) AS rabatt,
(
SELECT CASE
WHEN (ISNULL(IsGrossPrc, ‚N‘) = ‚Y‘)
THEN ISNULL(e.Price*(100-b.Discount)/100,ISNULL(b.Price,ISNULL(e.Price*(100-c.Discount)/100,ISNULL(c.Price,ISNULL(d.Price*(100-a.Discount)/100,a.Price))))) / ((100.0 + (SELECT ISNULL(Rate,0) FROM OVTG WHERE Code IN (SELECT VatGourpSa FROM OITM WHERE ItemCode=a.ItemCode))) / 100)
ELSE
ISNULL(e.Price*(100-b.Discount)/100,ISNULL(b.Price,ISNULL(e.Price*(100-c.Discount)/100,ISNULL(c.Price,ISNULL(d.Price*(100-a.Discount)/100,a.Price)))))
END
)
AS products_price,

(
SELECT CASE
WHEN (ISNULL(IsGrossPrc, ‚N‘) = ‚Y‘)
THEN ISNULL(e.Price,ISNULL(b.Price/(100-b.Discount)*100,ISNULL(b.Price,ISNULL(c.Price/(100-c.Discount)*100,ISNULL(c.Price,ISNULL(d.Price,ISNULL(a.Price/(100-a.Discount)*100,a.Price))))))) / ((100.0 + (SELECT ISNULL(Rate,0) FROM OVTG WHERE Code IN (SELECT VatGourpSa FROM OITM WHERE ItemCode=a.ItemCode))) / 100)
ELSE
ISNULL(e.Price,ISNULL(b.Price/(100-b.Discount)*100,ISNULL(b.Price,ISNULL(c.Price/(100-c.Discount)*100,ISNULL(c.Price,ISNULL(d.Price,ISNULL(a.Price/(100-a.Discount)*100,a.Price)))))))
END
)
AS products_original_price,

‚1‘ as amount
FROM OSPP as a
LEFT JOIN ITM1 AS d ON a.ItemCode = d.ItemCode and a.ListNum = d.PriceList and ISNULL(d.Price,0) != 0 and ISNULL(d.Currency,“) != “
LEFT JOIN SPP1 AS c ON a.ItemCode = c.ItemCode and a.CardCode = c.CardCode and (c.FromDate <= GETDATE() or c.FromDate IS NULL) and (c.ToDate+1 >= GETDATE() or c.ToDate IS NULL)
LEFT JOIN SPP2 AS b ON a.ItemCode = b.ItemCode and a.CardCode = b.CardCode and b.SPP1LNum = c.LINENUM and b.Amount = 1
LEFT JOIN ITM1 AS e ON a.ItemCode = e.ItemCode and c.ListNum = e.PriceList and ISNULL(e.Price,0) != 0 and ISNULL(e.Currency,“) != “
LEFT JOIN OPLN AS f ON a.ListNum = f.ListNum
WHERE a.CardCode = ‚{customers_cid}‘
UNION
SELECT a.CardCode AS customer_cid, a.ItemCode AS products_model, b.Discount AS rabatt,
(
SELECT CASE
WHEN (ISNULL(IsGrossPrc, ‚N‘) = ‚Y‘)
THEN ISNULL(e.Price*(100-b.Discount)/100,b.Price) / ((100.0 + (SELECT ISNULL(Rate,0) FROM OVTG WHERE Code IN (SELECT VatGourpSa FROM OITM WHERE ItemCode=a.ItemCode))) / 100)
ELSE
ISNULL(e.Price*(100-b.Discount)/100,b.Price)
END
)
AS products_price,

(
SELECT CASE
WHEN (ISNULL(IsGrossPrc, ‚N‘) = ‚Y‘)
THEN ISNULL(e.Price,ISNULL(b.Price/(100-b.Discount)*100,b.Price)) / ((100.0 + (SELECT ISNULL(Rate,0) FROM OVTG WHERE Code IN (SELECT VatGourpSa FROM OITM WHERE ItemCode=a.ItemCode))) / 100)
ELSE
ISNULL(e.Price,ISNULL(b.Price/(100-b.Discount)*100,b.Price))
END
)
AS products_original_price,

b.Amount as amount
FROM OSPP as a
LEFT JOIN ITM1 AS d ON a.ItemCode = d.ItemCode and a.ListNum = d.PriceList and ISNULL(d.Price,0) != 0 and ISNULL(d.Currency,“) != “
LEFT JOIN SPP1 AS c ON a.ItemCode = c.ItemCode and a.CardCode = c.CardCode
LEFT JOIN SPP2 AS b ON a.ItemCode = b.ItemCode and a.CardCode = b.CardCode and b.SPP1LNum = c.LINENUM and b.Amount > 1
LEFT JOIN ITM1 AS e ON a.ItemCode = e.ItemCode and c.ListNum = e.PriceList and ISNULL(e.Price,0) != 0 and ISNULL(e.Currency,“) != “
LEFT JOIN OPLN AS f ON a.ListNum = f.ListNum
WHERE b.CardCode = ‚{customers_cid}‘ and (c.FromDate <= GETDATE() or c.FromDate IS NULL) and (c.ToDate+1 >= GETDATE() or c.ToDate IS NULL)

getCustomersProductsgroupDiscount

getCustomersProductsgroupDiscount
SELECT ‚{customer_cid}‘ AS customers_cid, c.ItemCode AS products_model, b.Discount AS rabatt,
(
SELECT CASE
WHEN (ISNULL(IsGrossPrc, ‚N‘) = ‚Y‘)
THEN ISNULL(e.Price,0) * (100-ISNULL(b.Discount,0)) / 100 / ((100.0 + (SELECT ISNULL(Rate,0) FROM OVTG WHERE Code = VatGourpSa )) / 100)
ELSE
ISNULL(e.Price,0) * (100-ISNULL(b.Discount,0)) / 100
END
)
AS products_price,

(
SELECT CASE
WHEN (ISNULL(IsGrossPrc, ‚N‘) = ‚Y‘)
THEN ISNULL(e.Price,0) / ((100.0 + (SELECT ISNULL(Rate,0) FROM OVTG WHERE Code = VatGourpSa)) / 100)
ELSE
ISNULL(e.Price,0)
END
)
AS products_original_price,

‚1‘ AS amount
FROM OEDG AS a
LEFT JOIN EDG1 AS b ON a.AbsEntry = b.AbsEntry
LEFT JOIN OITM AS c ON b.ObjKey = (CASE b.ObjType WHEN 4 THEN c.ItemCode WHEN 52 THEN CAST(c.ItmsGrpCod AS nvarchar) END)

— Wenn für ein Artikel beide Rabatt-Typen vorhanden sind, wird ObjType 4 (Artikelrabatt) gegenüber 52 (Artikelgruppenrabatt) priorisiert durch MIN(g.ObjType).
— Über das INNER JOIN wird dann der Rabatt vom Artikel nur über einen ObjType geholt.

INNER JOIN (
SELECT h.ItemCode, MIN(g.ObjType) AS ObjType FROM EDG1 AS g
LEFT JOIN OITM AS h ON g.ObjKey = (CASE g.ObjType WHEN 4 THEN h.ItemCode WHEN 52 THEN CAST(h.ItmsGrpCod AS nvarchar) END)
GROUP BY h.ItemCode
) AS i ON b.ObjType = i.ObjType AND c.ItemCode = i.ItemCode
LEFT JOIN OCRD AS d ON a.ObjCode = d.CardCode
LEFT JOIN ITM1 AS e ON c.ItemCode = e.ItemCode AND d.ListNum = e.PriceList
LEFT JOIN OPLN AS f ON d.ListNum = f.ListNum
WHERE a.ObjType = 2 AND a.ObjCode = ‚{customer_cid}‘ AND b.ObjType IN (4,52) AND a.ValidFor = ‚Y‘
AND (a.ValidForm <= GETDATE() OR a.ValidForm IS NULL) AND (a.ValidTo+1 >= GETDATE() OR a.ValidTo IS NULL)

getCustomersGroupDiscount
SELECT ‚{customer_cid}‘ AS customers_cid, c.ItemCode AS products_model, b.Discount AS rabatt,
(
SELECT CASE
WHEN (ISNULL(IsGrossPrc, ‚N‘) = ‚Y‘)
THEN ISNULL(e.Price,0) * (100-ISNULL(b.Discount,0)) / 100 / ((100.0 + (SELECT ISNULL(Rate,0) FROM OVTG WHERE Code = c.VatGourpSa)) / 100)
ELSE
ISNULL(e.Price,0) * (100-ISNULL(b.Discount,0)) / 100
END
)
AS products_price,
(
SELECT CASE
WHEN (ISNULL(IsGrossPrc, ‚N‘) = ‚Y‘)
THEN ISNULL(e.Price,0) / ((100.0 + (SELECT ISNULL(Rate,0) FROM OVTG WHERE Code = c.VatGourpSa)) / 100)
ELSE
ISNULL(e.Price,0)
END
)
AS products_original_price,

‚1‘ AS amount
FROM OCRD AS d
LEFT JOIN OEDG AS a ON d.GroupCode = a.ObjCode
LEFT JOIN EDG1 AS b ON a.AbsEntry = b.AbsEntry
LEFT JOIN OITM AS c ON b.ObjKey = (CASE b.ObjType WHEN 4 THEN c.ItemCode WHEN 52 THEN CAST(c.ItmsGrpCod AS nvarchar) END)

— Wenn für ein Artikel beide Rabatt-Typen vorhanden sind, wird ObjType 4 (Artikelrabatt) gegenüber 52 (Artikelgruppenrabatt) priorisiert durch MIN(g.ObjType).
— Über das INNER JOIN wird dann der Rabatt vom Artikel nur über einen ObjType geholt.

INNER JOIN (
SELECT h.ItemCode, MIN(g.ObjType) AS ObjType FROM EDG1 AS g
LEFT JOIN OITM AS h ON g.ObjKey = (CASE g.ObjType WHEN 4 THEN h.ItemCode WHEN 52 THEN CAST(h.ItmsGrpCod AS nvarchar) END)
GROUP BY h.ItemCode
) AS i ON b.ObjType = i.ObjType AND c.ItemCode = i.ItemCode
LEFT JOIN ITM1 AS e ON c.ItemCode = e.ItemCode AND d.ListNum = e.PriceList
LEFT JOIN OPLN AS f ON d.ListNum = f.Listnum
WHERE a.ObjType = 10 AND d.CardCode = ‚{customer_cid}‘ AND b.ObjType IN (4,52) AND a.ValidFor = ‚Y‘
AND (a.ValidForm <= GETDATE() OR a.ValidForm IS NULL) AND (a.ValidTo+1 >= GETDATE() OR a.ValidTo IS NULL)

Mit folgenden SQL Befehlen werden die kundenspezifischen Einzelpreise aus SAP ermittelt. Lassen Sie diese von Ihrem SAP Betreuer prüfen.

Besonderheiten

Artikelnummer Beschränkungen

Shopware beschränkt die Artikelnummer ein, welche verwendet werden können. Die Artikelnummer muss aus mindestens einer 4-stelligen Mischung aus Buchstaben und Zahlen angelegt werden, darf im System nur einmal verwendet werden und muss immer mit einem Buchstaben beginnen!

Erlaubt sind:

  • Die alphanumerischen Zeichen: 0-9 A-Z
  • folgende Sonderzeichen: . – _

Abweichende Sonderzeichen können nicht gespeichert werden, in diesem Fall wird eine Warnung angezeigt. Weitere Informationen dazu gibt es auch in der Dokumentation von Shopware: https://docs.shopware.com/de/shopware-5-de/produkte-und-kategorien/produkte-anlegen#aufbau-der-artikelnummern-in-shopware

Zeichensatz der sync4 Datenbank

Latin1_general_CI_AS (https://en.wikipedia.org/wiki/ISO/IEC_8859-1)

Entsprechende einschränken sind zu beachten.

Zusätzliche Anpassungen

Etwaig benötigte Anpassungen für sync4 und der Warenwirtschaft sind kostenpflichtige Dienstleistungen und  können in einem späteren Angebot definiert werden.