Moin moin!
Bedauerlicherweise hat weder der Quellcode, noch die Doku noch das Forum eine richtig schöne Erklärung, wie man den Shop erweitert, ohne euren (im Übrigen leckeren) Source anzufassen und für etwaige Updates gut aufgestellt zu sein.
Also versuche ich jetzt in diesem Forum mein bisheriges Vorgehen zu erläutern und ihr könnt mir ja vielleicht verraten, wie es weitergehen könnte / sollte.
Anforderung:
In der Administration des Kunden (Admin/Customer/Edit/x) soll ein weiteres Textfeld zur Verfügung stehen, in welches ich die Kundennummer aus dem möglicherweise verwendeten ERP-System erfasst werden soll, nennen wir es: string ErpArticleNo
Aktuelle Umsetzung bis zum Punkt "Fragezeichen":
- Ich habe eine kleine View erstellt die über den WidgetController gerendert wird. In diesem Feld wird der Inhalt richtig angezeigt. Der HtmlHelper ist nur ein Wrapper für eure Helper, sodass mir sämtliche Label, Controls und Validation-Elemente, in einer Zeile generiert werden. Das klappt auch. Ich kann im Filter auch ohne weiteren "EventHandler" oder "ModelBinder" auf das Element zugreifen.
@model SmartStore.Admin.Models.Customers.CustomerModel <script> var erpCustomerNrHtmlControl = '@Html.OwnSmartStoreTextBox("CustomProperties[ErpCustomerNo]", Model.CustomProperties.Get("ErpCustomerNo"), new { }, labelText: "ErpCustomerNo")'; $('#Username').closest('.adminContent').append(erpCustomerNrHtmlControl); </script>
- Ich habe einen Action-Filter implementiert, der zwischen Aufrufen und Speichern der Edit-Maske unterscheidet. Je nachdem, was gerade Phase ist, wird entweder in das CustomerModel.CustomProperties["ErpArticleNo"] geschrieben oder gelesen. Und jetzt kommt es, was das eigentliche Problem ist: Wohin mit den Daten!? In einigen Beiträgen habe ich das "neue" - aber nirgends erklärte "Syncmapping" probiert. Quälcode:
public void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.ActionDescriptor.ActionName.Equals("Edit") && filterContext.HttpContext.Request.HttpMethod == "POST" && filterContext.Controller.ViewData.ModelState.IsValid) { var model = (CustomerModel)filterContext.ActionParameters["model"]; if (model != null && model.CustomProperties.Keys.Contains("ErpCustomerNo")) { var syncedMap = _syncMappingService.GetSyncMappingByEntity(_customerService.GetCustomerById(model.Id), PluginInfo.SystemName); if (syncedMap != null) { syncedMap.CustomString = model.CustomProperties["ErpCustomerNo"].ToString(); _syncMappingService.UpdateSyncMapping(syncedMap); } else { _syncMappingService.InsertSyncMapping(_customerService.GetCustomerByEmail(model.Email), PluginInfo.SystemName, "ErpCustomerNo"); } } } } public void OnActionExecuted(ActionExecutedContext filterContext) { // open customerInfo view (register widget with additional field) if (filterContext.ActionDescriptor.ActionName.Equals("Edit") && filterContext.HttpContext.Request.HttpMethod == "GET") { // get model? if (filterContext.Result is ViewResultBase result) { if (result.Model is CustomerModel model) { var syncedMap = _syncMappingService.GetSyncMappingByEntity(_customerService.GetCustomerById(model.Id), PluginInfo.SystemName); model.CustomProperties.Add("ErpCustomerNo", syncedMap == null ? "Baumwolle" : syncedMap.CustomString); _widgetProvider.Value.RegisterAction("admin_content_after", "ErpCustomerNoView", "Widget", new { area = "PluginXYZ", model }); } } } }
Ist die SyncMapping Idee überhaupt sinnvoll für den Anwendungsfall? Wenn nein - wie wäre die Empfehlung es stattdessen zu lösen? Wenn ja, dann wäre ich euch sehr dankbar, wenn ihr die konkrete Idee dahinter noch einmal erläutern würdet und vielleicht mit dem korrekten Aufruf des Services um es zu veranschaulichen. Ich glaube dieses Problem würde nicht nur mir helfen! Mir ist bewusst, dass der SyncService gerade falsch bestückt wird. (Es wird nichts gespeichert). Aber den Anwendungsfall den ihr mit den SyncMappingTests abdeckt habe ich ja auch nicht..
Viele Grüße,
Fro.