Geschrieben von

Rolf

am

14.1.2020

Remote Working bei VIU

Ich habe das Herbstsemester 2019 meines Wirtschaftsinformatik Studiums in einem Auslandaufenthalt verbracht. Während dieser Zeit habe ich gleichzeitig für VIU gearbeitet.

Ein bisschen Hintergrund

Meine Schule, die ZHAW School of Management and Law, bietet ihren Studenten an, ein Semester an einer ihrer internationalen Partnerhochschulen zu verbringen. Ich habe dieses Angebot in Anspruch genommen und mich an der Schule “Tecnologico de Monterrey” in Mexiko beworben. Die VIU hat mich dabei unterstützt, indem ich während des Semesters weiterhin arbeiten konnte. Meine Beweggründe für das Auslandsemester waren sehr persönlich: Meine Frau stammt aus Mexiko. Ich wollte das Land und seine Kultur besser kennenlernen und mein Spanisch verbessern.

Blick auf die Stadt Monterrey vom Gipfel des Hausbergs Cerro de la Silla.
Remote Working

Die vier Monate in Mexiko habe ich mir finanziert, indem ich darauf gespart habe und ein Stipendium von der Schule erhalten habe. Zu einem grossen Teil aber auch, indem ich von Mexiko aus weiter für VIU arbeiten konnte. Neben der Einkunft hat es mir auch die Möglichkeit gegeben, den Kontakt zur Firma und zum Team zu halten. Da ich auch in Mexiko nur teilzeit Schule hatte, konnte ich gut zwei Tage pro Woche arbeiten.

Da es aufgrund der geographischen Distanz schwierig war, für neue Kundenprojekte zu arbeiten (schwierigere Interaktion mit Kunden), habe ich mich hauptsächlich um bestehende Projekte gekümmert. Ich habe vor allem Wartungsarbeiten ausgeführt und ein paar neue Funktionen entwickelt.

Sieben Stunden in der Vergangenheit

Wegen der Zeitverschiebung war das mit der Kommunikation nicht ganz so einfach. Mein einziges “Fenster” war am Morgen bis etwa 10 Uhr, da der Unterschied zur Schweiz +7 Stunden beträgt. Das bedeutete, dass ich alle Telefonate und sonstige synchrone Kommunikation in den zwei bis drei Stunden am Morgen erledigen musste. Falls es später am Tag mal ein Problem gab, bzw. während ich am Schlafen war, musste die Angelegenheit jeweils warten bis zum nächsten Fenster.

Ein Denkmal für alle Gaststudenten. Ich war der einzige Schweizer.
Connecting...

Eine weitere Herausforderung war das Internet. Einerseits gab es hie und da Strom- bzw. Netzausfälle, das war aber nicht weiter schlimm. Schwieriger war die Latenz, die es aufgrund der Distanz gab. Gerade bei Arbeiten über Remote Desktop hatte ich stets Latenzen im Bereich von einer halben bis einer Sekunde. Arbeiten ist so nicht unmöglich, aber unglaublich mühsam.

Coworking Spaces

Die Uni hat auf ihrem Campus spezielle Räumlichkeiten, die reserviert sind für Freelancer und ich habe mit Hilfe von ein Bisschen Vitamin B einen Platz dort bekommen, um zu arbeiten. Das war im Vergleich zur Bibliothek, wo ich die ersten zwei Wochen gearbeitet habe, sehr angenehm, da es wenig Leute hatte und sehr ruhig war. Ausserdem war das Internet da schneller 😉.

Eine Schwarzrote Vogelspinne in freier Wildbahn auf der Yucatán Halbinsel.
Danke

Alles in Allem hat es aus meiner Sicht sehr gut funktioniert. Und weil es nicht selbstverständlich ist, dass man die Arbeit so mit dem Reisen kombinieren kann, möchte ich VIU für diese Möglichkeit nochmals Danke sagen.

No items found.

Lass uns darüber sprechen.

Dirk Fliescher

Head of Sales und Marketing

Jetzt kontaktieren

6 Mins Read

30.1.2020

Extend the Admin Interface in NopCommerce 4.2

Mehr lesen

What if you wanted to create a plugin that extends, for example, the product entity? This tutorial shows an alternative way to the classical approach of adding a configuration site.

Basically, you could create a basic configuration page that offers standard CRUD operations, as described in the nopCommerce docs. This approach might be adequate for a plugin that adds new functionality to the system, but I find it cumbersome in the case of an extension. Instead, I prefer to extend the existing editing page of an entity. For this example, I am going to add a tab to add or edit related blog posts - similar to the concept of related products. I am going to skip the data layer part to keep this post as short as possible (see https://docs.nopcommerce.com/­developer/­plugins/­plugin-with-data-access.html for information on how to extend the data layer).

I wrote this tutorial for NopCommerce 4.2, but its concepts also apply for older as well as new versions. The most noticeable difference between the current and older versions is the approach on how to extend an existing admin page. While older versions required implementation of an event consumer and adding the HTML within that code, the most recent release of nopCommerce offers a much more beautiful way by using a widget zone.

Create a new plugin that implements IWidgetPlugin and configure the widget zone to use (How to create a new plugin in NopCommerce: https://docs.nopcommerce.com/­developer/­plugins/­index.html).

using ...

namespace VIU.Plugin.Extensions.Product.Admin {
  public class ProductAdminPlugin : BasePlugin, IWidgetPlugin {
    public bool HideInWidgetList => false;

    public IList<string> GetWidgetZones() {
      return new List<string> {
        AdminWidgetZones.ProductDetailsBlock
      };
    }

    public string GetWidgetViewComponentName(string widgetZone) {
      if (widgetZone.Equals(AdminWidgetZones.ProductDetailsBlock))
        return "RelatedBlogPosts";
      return string.Empty;
    }
  }
}

NopCommerce requires you to create a bunch of models for this to work. The first three models back the newly added section on the editing page and its contained list of existing related blogs. To keep things tidy, I decided to pack those models into one file:

using ...

namespace VIU.Plugin.Extensions.Product.Admin.Model.RelatedBlogPost {
  public class RelatedBlogPostModel : BaseNopEntityModel {
    public int RelatedBlogPostId { get; set; }
    public string Title { get; set; }
    public string LanguageName { get; set; }
    public int DisplayOrder { get; set; }
  }

  public class RelatedBlogPostSearchModel : BaseSearchModel {
    public int ProductId { get; set; }
  }

  public class RelatedBlogPostListModel : BasePagedListModel<RelatedBlogPostModel> { }
}

The class RelatedBlogPostModel defines the list data, the system uses RelatedBlogPostSearchModel to load the list data, and RelatedBlogPostListModel holds the list data.

The three following models do the same as the latter but for the popup to add a new entry. They look pretty similar except for the search model since we want to have a search interface in the popup.

using ...

namespace VIU.Plugin.Extensions.Product.Admin.Model.RelatedBlogPost {
  public class AddRelatedBlogPostModel : BaseNopModel {
    public AddRelatedBlogPostModel() {
      SelectedBlogPostIds = new List<int>();
    }

    public int ProductId { get; set; }

    public IList<int> SelectedBlogPostIds { get; set; }
  }

  public class AddRelatedBlogPostSearchModel : BaseSearchModel {
    public AddRelatedBlogPostSearchModel() {
      AvailableStores = new List<SelectListItem>();
    }

    [NopResourceDisplayName("Plugins.VIU.Extensions.Product.RelatedBlogPosts.SearchBlogTitle")]
    public string SearchBlogTitle { get; set; }

    [NopResourceDisplayName("Admin.Catalog.Products.List.SearchStore")]
    public int SearchStoreId { get; set; }

    public IList<SelectListItem> AvailableStores { get; set; }
  }

  public class AddRelatedBlogPostListModel : BasePagedListModel<BlogPostModel> { }
}

Lastly, we extend the product model with an instance of RelatedBlogPostSearchModel (I don't extend the product model in a programmatic sense as it would add overhead).

using ...

namespace VIU.Plugin.Extensions.Product.Admin.Model {
  public class ExtendedProductModel {
    public ExtendedProductModel() {
      RelatedBlogPostSearchModel = new RelatedBlogPostSearchModel();
    }

    public int ProductId { get; set; }

    public RelatedBlogPostSearchModel RelatedBlogPostSearchModel { get; set; }
  }
}

In the next step, we implement the necessary views. The first one is the components default view (we define the component later), so we call it Default.cshtml. It contains quite a bit of code but basically what it does is it defines the data grid and fills it with data fetched from the controller via RelatedBlogPostList (We implement this method in the next step). The rest should be self-explanatory.

aasd