** Se il vendorID è quello di Webmobili-dropship mostro il pulsante '''CLONA e ASSEGNA a RIVENDITORE'''.
** Se il vendorID è quello di Webmobili-dropship mostro il pulsante '''CLONA e ASSEGNA a RIVENDITORE'''. Attenzione il metodo è cambiato da code>prodService.GetProductById(item.ProductId).VendorId</code> a <code>GetProductByIdAsync</code>: <syntaxhighlight lang="c#">
Attenzione il metodo è cambiato da <code>prodService.GetProductById(item.ProductId).VendorId</code> a <code>GetProductByIdAsync</code>:
<syntaxhighlight lang="c#">
@{
@{
var productById = await prodService.GetProductByIdAsync(item.ProductId);
var productById = await prodService.GetProductByIdAsync(item.ProductId);
Riga 365:
Riga 363:
}
}
</syntaxhighlight>
</syntaxhighlight>
** Il pulsante '''CLONA e ASSEGNA a RIVENDITORE''' apre un modale in cui selezionare il rivenditore, innanzitutto dobbiamo creare la vista/componente del modale '''ProductToVendorModal'''.
** Il pulsante '''CLONA e ASSEGNA a RIVENDITORE''' apre un modale in cui selezionare il rivenditore, innanzitutto dobbiamo creare la vista/componente del modale ''ProductToVendorModal'''. <br/>Creiamo il componente in <code>Nop.Web\Areas\Admin\Components\ProductToVendorModal.cs</code> così: <syntaxhighlight lang="c#">
Creiamo il componente in <code>Nop.Web\Areas\Admin\Components\ProductToVendorModal.cs</code> così:
<syntaxhighlight lang="c#">
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc;
using System;
using System;
Riga 476:
Riga 472:
</syntaxhighlight>
</syntaxhighlight>
* '''ERORRI'''
* '''ERORI'''
<blockquote>
<blockquote>
Durante il test di acquisto di prodotto DesignbestShop, in fase di selezione della spedizione
Durante il test di acquisto di prodotto DesignbestShop, in fase di selezione della spedizione
non ci sono opzioni e rimane lì e non avanza, probabilmente per assenza plugin spedizione.
non ci sono opzioni e rimane lì e non avanza, probabilmente per assenza plugin spedizione.
In questa guida saranno evidenziati in rosso tutti i file del core di Nop che verranno toccati.
Operazioni sul DB
Creare un dump del database di produzione (Nop 4.3)
Ripristinarlo
Per ripristinare l'utente wmuser è necessario disassociarlo dal catalogo fulltext
Da SQL Management Aprire Storage -> Fulltext Catalogs -> nopCommerceFullTextCatalog, nella tab General impostare come Owner => dbo
Eliminare l'utente wmuser
Ri-mappare l'utente wmuser sul database nuovo
Aprire di nuovo Storage -> Fulltext Catalogs -> nopCommerceFullTextCatalog, nella tab General inserire come Owner => wmuser
Aprire di nuovo Storage -> Fulltext Catalogs -> nopCommerceFullTextCatalog, nella tab Tables/Views, pannello Eligible columns impostare italian per tutti i campi
Configurazione della Solution
Aggiornare i file Presentation\Nop.Web\App_Data\dataSettings.json e Presentation\Nop.Web\App_Data\appsettings.json
Copiare i plugin di terze parti nella cartella Plugins\Nop.Plugin.Compiled
Aggiungere il seguente codice nei build events => post build event progetto Nop.Web
Addare alla Solution (cartella Libraries) i progetti GenericUtilites, WM4Search, WM_Core e USO
Runnando la Solution dovrebbe partire con tutti i plugin disabilitati. Una volta entrati in admin è possibile vederli dall'elenco e installarli.
Non ci saranno tutti i plugin, in tal caso cliccare su ricaricare la lista di plugin, la soluzione si chiuderà da sola, ma al successivo login la lista dovrebbe essere aggiornata.
Aggiornare tutti i pacchetti nuGet della Solution che abbiano un update minor (dalla seconda cifra in poi)
Creazione di IWMCoreModelFactory per le chiamate alla WMCore.
INTERFACCIA: creare Presentation\Nop.Web\Factories\IWMCoreModelFactory.cs così
BINDING: comunicare la sua esistenza al framework modificando Presentation\Nop.Web\Startup.cs aggiungendo una riga a ConfigureServices() così
publicvoidConfigureServices(IServiceCollectionservices){// aggiunta di IWMCoreModelFactoryservices.AddSingleton<IWMCoreModelFactory,WMCoreModelFactory>();services.ConfigureApplicationServices(_configuration,_webHostEnvironment);}
Inserimento di UsoUtilitiesController uguale a quello precedente con la differenza che le chiamate a services sono diventate tutte ASYNC e perciò il trucco è aggiungere al fondo .Result per le variabili o .Wait() per i metodi come ad esempio
Cambiare le regole di rewrite, i prodotti sotto /catalogo-prodotti , le categorie sotto /catalogo e i cataloghi sotto /brand
Modificare in Nop.Web\Infrastructure\GenericUrlRouteProvider.cs
usingMicrosoft.AspNetCore.Builder;usingMicrosoft.AspNetCore.Routing;usingNop.Data;usingNop.Web.Framework.Mvc.Routing;namespaceNop.Web.Infrastructure{/// <summary>/// Represents provider that provided generic routes/// </summary>publicpartialclassGenericUrlRouteProvider:BaseRouteProvider,IRouteProvider{#region Methods/// <summary>/// Register routes/// </summary>/// <param name="endpointRouteBuilder">Route builder</param>publicvoidRegisterRoutes(IEndpointRouteBuilderendpointRouteBuilder){varlang=GetLanguageRoutePattern();#region WEBMOBILIstringconstProducts="catalogo-prodotti";stringconstCategories="catalogo";stringconstManufacturers="brand";#endregion//default routes//these routes are not generic, they are just default to map requests that don't match other patterns, //but we define them here since this route provider is with the lowest priority, to allow to add additional routes before themif(!string.IsNullOrEmpty(lang)){endpointRouteBuilder.MapControllerRoute(name:"DefaultWithLanguageCode",pattern:$"{lang}/{{controller=Home}}/{{action=Index}}/{{id?}}");}endpointRouteBuilder.MapControllerRoute(name:"Default",pattern:"{controller=Home}/{action=Index}/{id?}");if(!DataSettingsManager.IsDatabaseInstalled())return;//generic routesvargenericPattern=$"{lang}/{{SeName}}";#region WEBMOBILIendpointRouteBuilder.MapDynamicControllerRoute<SlugRouteTransformer>(constProducts+"/{SeName}");endpointRouteBuilder.MapDynamicControllerRoute<SlugRouteTransformer>(constCategories+"/{SeName}");endpointRouteBuilder.MapDynamicControllerRoute<SlugRouteTransformer>(constManufacturers+"/{SeName}");#endregionendpointRouteBuilder.MapDynamicControllerRoute<SlugRouteTransformer>(genericPattern);endpointRouteBuilder.MapControllerRoute(name:"GenericUrl",pattern:"{genericSeName}",defaults:new{controller="Common",action="GenericUrl"});endpointRouteBuilder.MapControllerRoute(name:"GenericUrlWithParameter",pattern:"{genericSeName}/{genericParameter}",defaults:new{controller="Common",action="GenericUrl"});endpointRouteBuilder.MapControllerRoute(name:"Product",pattern:$"{lang}/{constProducts}/{{SeName}}",defaults:new{controller="Product",action="ProductDetails"});endpointRouteBuilder.MapControllerRoute(name:"Category",pattern:$"{lang}/{constCategories}/{{SeName}}",defaults:new{controller="Catalog",action="Category"});endpointRouteBuilder.MapControllerRoute(name:"Manufacturer",pattern:$"{lang}/{constManufacturers}/{{SeName}}",defaults:new{controller="Catalog",action="Manufacturer"});endpointRouteBuilder.MapControllerRoute(name:"Vendor",pattern:genericPattern,defaults:new{controller="Catalog",action="Vendor"});endpointRouteBuilder.MapControllerRoute(name:"NewsItem",pattern:genericPattern,defaults:new{controller="News",action="NewsItem"});endpointRouteBuilder.MapControllerRoute(name:"BlogPost",pattern:genericPattern,defaults:new{controller="Blog",action="BlogPost"});endpointRouteBuilder.MapControllerRoute(name:"Topic",pattern:genericPattern,defaults:new{controller="Topic",action="TopicDetails"});endpointRouteBuilder.MapControllerRoute(name:"ProductsByTag",pattern:genericPattern,defaults:new{controller="Catalog",action="ProductsByTag"});}#endregion#region Properties/// <summary>/// Gets a priority of route provider/// </summary>/// <remarks>/// it should be the last route. we do not set it to -int.MaxValue so it could be overridden (if required)/// </remarks>publicintPriority=>-1000000;#endregion}}
Prodotto
Aggiunta metodi frmt() di utilità nelle viste per restituire decimali in Nop.Web\Extensions\HtmlExtensions.cs:
/// Restituisce (come stringa) il numero decimale specificato inserendo il punto/// ogni tre cifre. I numeri decimali sono limitati a 2/// </summary>/// <param name="val">Un decimal</param>/// <returns>Il numero nella forma mmm.kkk.uuu,dd</returns>publicstaticstringfrmt(thisdecimalval){varci=newCultureInfo("it-IT");ci.NumberFormat.NumberDecimalDigits=2;returnval.ToString("N",ci);}/// Restituisce (come stringa) il numero intero specificato inserendo il punto/// ogni tre cifre./// </summary>/// <param name="val">Un decimal</param>/// <returns>Il numero nella forma mmm.kkk.uuu,dd</returns>publicstaticstringfrmt(thisintval){varci=newCultureInfo("it-IT");ci.NumberFormat.NumberDecimalDigits=2;returnval.ToString("N",ci);}
Nel modello del prodotto in Nop.Web\Models\Catalog\ProductDetailsModel.cs aggiungere:
#region WEBMOBILI/// <summary>/// Nella nostra struttura c'è sempre un solo manufacturer per prodotto. Questa property lo restituisce./// In caso di manufacturer non settato (errore di dati) restituisce un manu vuoto per evitare una NullPointerException/// </summary>publicManufacturerBriefInfoModelManufacturer{get{if(ProductManufacturers.Count>0){returnProductManufacturers[0];}returnnewManufacturerBriefInfoModel{Name="",SeName="",IsActive=false};}}publicstringShopCity{get;set;}publicdecimalAdditionalShippingCharge{get;set;}#endregion
ProductController: al momento dichiarata l'istanza dell'interfaccia IWMCoreModelFactory, ma non utilizzata, i campi necessari sono stati aggiunti direttamente nel modello del prodotto, aggiungiamo quindi solo questa istruzione nel metodo ProductDetails(int productId, int updatecartitemid = 0):
#region WEBMOBILImodel.AdditionalShippingCharge=product.AdditionalShippingCharge;// spese di spedizione da stampare in frontend#endregion
Nella vista del prodotto, copiare la vista del tema base Nop.Web\Views\Product\_DeliveryInfo.cs in Nop.Web\Themes\Brooklyn\Views\Product\_DeliveryInfo.cs e modificarla così:
Per cambiare l'immagine in alto a sinistra bisogna sovrascriverla qui P:\DesignbestCommerce3\Presentation\Nop.Web\wwwroot\css\admin\images per 2 versioni del menu(compatto e non) logo.png 250x57 e logo-mini.png
Home - Vendor
Nascondere il pulsante Visualizza nei best seller(un Vendor non deve entrare nella pagina di modifica del prodotto lato NOP), bisogna commentare l'ultima ColumnProperty in queste 2 viste:
Nop.Web\Areas\Admin\Views\Home\_BestsellersBriefReportByAmount.cshtml e
Nop.Web\Areas\Admin\Views\Home\_BestsellersBriefReportByQuantity.cshtml
Vendite - Ordini del Cliente
Nascondere il filtro Magazzino (aggiungere la classe d-none), altrimenti un vendor potrebbe vedere le vendite degli altri vendor, vista da modificare Nop.Web\Areas\Admin\Views\Order\List.cshtml.
Nel box dove sono elencati i prodotti, il link del prodotti rimanderà alla scheda del prodotto nel frontend, mentre solo se siamo Admin entreremo nell'edit del prodotto di NOP modificare in Nop.Web\Areas\Admin\Views\Order\_OrderDetails.Products.cshtml
Dobbiamo recuperare il VendorID del dropship di Webmobili:
<em>@if(!Model.IsLoggedInAsVendor){<aasp-controller="Product"asp-action="Edit"asp-route-id="@item.ProductId">@item.ProductName</a>}else{<ahref="@Url.RouteUrl("Product", new { SeName = item.ProductSeoName })"target="_blank">@item.ProductName</a>}</em>
Se il vendorID è quello di Webmobili-dropship mostro il pulsante CLONA e ASSEGNA a RIVENDITORE. Attenzione il metodo è cambiato da code>prodService.GetProductById(item.ProductId).VendorId a GetProductByIdAsync:
Il pulsante CLONA e ASSEGNA a RIVENDITORE' apre un modale in cui selezionare il rivenditore, innanzitutto dobbiamo creare la vista/componente del modale ProductToVendorModal. Creiamo il componente in Nop.Web\Areas\Admin\Components\ProductToVendorModal.cs così:
Torniamo nella pagina contenitore di dettaglio dell'ordine in Nop.Web\Areas\Admin\Views\Order\Edit.cshtml e inseriamo al fondo la chiamata al nostro component modale appena creato con questa riga di codice:
Durante il test di acquisto di prodotto DesignbestShop, in fase di selezione della spedizione
non ci sono opzioni e rimane lì e non avanza, probabilmente per assenza plugin spedizione.