Get customers number of orders - nopcommerce

How can I get customer number of orders on customer order page on public store. I have seen that already exist on admin page bu is there any setting that should be activated as this can be shown on public store.

Assuming the controller you are using has the _storeContext, _workContext and _orderService variables injected, this will do it:
var orderCount = _orderService.SearchOrders(
storeId: _storeContext.CurrentStore.Id,
customerId: _workContext.CurrentCustomer.Id)
.Count();
If any of those variables don't exist, manually add them to your controller. Toy need to add the private variables:
private readonly IStoreContext _storeContext;
private readonly IOrderService _orderService;
private readonly IWorkContext _workContext;
Extend the constructor of the controller and add in the code to save the injected values:
public YourController(/* other parameters */
IOrderService orderService,
IWorkContext workContext,
IStoreContext storeContext)
{
//snip
this._orderService = orderService;
this._shipmentService = shipmentService;
this._workContext = workContext;
this._storeContext = storeContext;
}

Related

Asp.net Identity DbContext / Repository Issue

I am using Asp.Net identity within my MVC app. I can see that this has it's own ApplicationDbContext - albeit it is connected to the same SQL db as my own DbContext I am using elsewhere.
So I am trying to access some of my own data via my own code within the AccountController - it does not seem to work I presume because of some confusion over which DBContext it thinks is active?
My Code :
public class AccountController : Controller
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
private PostageManager postmgr;
public AccountController()
{
}
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, PostageManager _postmgr)
{
UserManager = userManager;
SignInManager = signInManager;
postmgr = _postmgr;
}
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
// GET: /Account/Register
[AllowAnonymous]
public ActionResult Register()
{
//create select list items for countries drop down
List<SelectListItem> countries;
countries = postmgr.GetCountries().Select(item => new SelectListItem
{
Value = item.Country,
Text = item.Country
}).ToList();
countries.Insert(0, new SelectListItem { Value = string.Empty, Text = "Select delivery country or region...", Selected = true });
RegisterViewModel mode = new RegisterViewModel
{
Countries = countries
};
return View();
}
}
}
PostageManager is just a class that sits over my DAL to fetch some data (which uses repository pattern) - I'm using just a kind of pass through method to grab a list of countries, and using it in exactly the same way I have in other controllers which works fine. Underneath that class is my repository code that is linked to my default connection string (DBContext). It's balking at the following line with a null reference exception, I think postmgr is null :
countries = postmgr.GetCountries().Select(item => new SelectListItem
In reverse to get access to the identity data within my own controllers I have done the following :
public BasketController(BasketManager _mgr, PostageManager _postmgr, ProductManager _prodmgr)
{
mgr = _mgr;
postmgr = _postmgr;
prodmgr = _prodmgr;
shopper = Cart.GetShopperId();
this.applicationDbContext = new ApplicationDbContext();
this.userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(this.applicationDbContext));
}
protected ApplicationDbContext applicationDbContext { get; set; }
protected UserManager<ApplicationUser> userManager { get; set; }
Which as far as I understand it points the identity code to use the right DbContext - I looked at doing this in reverse in my AccountController but can't fathom it out.
I basically just want to be able to use my own code that grabs my own data from within the Identity controllers to help pass extra data etc through to the views.
I might be wrong but most probably postmgr field is not initialized from constructor and that is why you have this error.
Explanation:
By default Asp will try to create controller instance by constructor without parameters. If Asp can't find constructor without parameters it will try to call constructor with parameters, but to make it possible you have to configure IoC in your app. As your controler has constructor without parameters it will be selected by Asp. So all 3 fields are empty.
But in properties SignInManager and UserManager you try to take value from field or from OwinContext. As field is empty your code will take value from OwinContext. OwinContext is quite complex and smart tool that create its context automatically based on configuration provided in Startup.Auth.cs file or any other file under App_Start folder.
I think I have figured it out - added the following to my NinjectControllerFactory :
ninjectKernel.Bind<IAuthenticationManager>().ToMethod(c => HttpContext.Current.GetOwinContext().Authentication); //.InRequestScope();
ninjectKernel.Bind<IUserStore<ApplicationUser>>().To<UserStore<ApplicationUser>>();
ninjectKernel.Bind<UserManager<ApplicationUser>>().ToSelf();
ninjectKernel.Bind<IRoleStore<IdentityRole, string>>().To<RoleStore<IdentityRole, string, IdentityUserRole>>();
ninjectKernel.Bind<RoleManager<IdentityRole>>().ToSelf();
And changed my constructor to :
public AccountController(PostageManager _postmgr)
{
postmgr = _postmgr;
}

Spring Data REST Controllers vs Custom Controllers

I have a 2 domain classes one with reference to another like this:
#Document
public class Dummy {
#Id
private UUID id;
private String name;
#Reference
private DummyAttribute dummyAttribute;
// getters and setters omitted.
}
#Document
public class DummyAttribute {
#Id
private UUID id;
private String name;
// getters and setters omitted.
}
I also have 2 repositories corresponding to Dummy and DummyAttribute.
public interface DummyRepository extends CrudRepository<Dummy, UUID> {
}
public interface DummyAttributeRepository extends
CrudRepository<DummyAttribute, UUID> {
}
I want to create a Dummy with a DummyAttribute. So, I create a dummyAttribute by posting to /dummyattributes. I get the response body with a self link to dummyAttribute back. This self link that I get back is used during the creation of Dummy. My JSON payload to the /dummies looks like :
{
"name" : "dummy",
"dummyAttribute" : <self link of dummyAttribute generated during POST>
}
When I do a GET on the association URL generated after POST, I correctly get
the dummyAttribute that was used. So far works well in Spring Data REST.
I want to do the same using my custom controllers. So, I created controllers
for both Dummy and DummyAttribute.
#RestController
public class DummyController {
#Autowired
private DummyRepository dummyRepository;
#Autowired
private DummyResourceProcessor processor;
#RequestMapping(value = "/dummies", method = RequestMethod.POST)
public HttpEntity<Resource<Dummy>> createTenant(#RequestBody Dummy dummy)
{
Dummy save = dummyRepository.save(dummy);
Resource<Dummy> dummyr = new Resource<Dummy>(save);
return new ResponseEntity<Resource<Dummy>>(processor.process(dummyr),
HttpStatus.CREATED);
}
#RequestMapping(value = "/dummies/{id}", method = RequestMethod.GET)
public HttpEntity<Resource<Dummy>> getDummy(#PathVariable("id") Dummy
dummy) {
Resource<Dummy> dummyr = new Resource<Dummy>(dummy);
return new ResponseEntity<Resource<Dummy>>(processor.process(dummyr),
HttpStatus.OK);
}
#RestController
public class DummyAttributeController {
#Autowired
private DummyRepository dummyRepository;
#Autowired
private DummyAttributeRepository dummyAttributeRepository;
#Autowired
private DummyAttributeResourceProcessor processor;
#RequestMapping(value = "/dummyAttributes", method =
RequestMethod.POST)
public HttpEntity<Resource<DummyAttribute>> createDummyAttribute(
#RequestBody DummyAttribute dummyAttribute) {
DummyAttribute save = dummyAttributeRepository.save(dummyAttribute);
Resource<DummyAttribute> dummyr = new Resource<DummyAttribute>(save);
return new ResponseEntity<Resource<DummyAttribute>>
(processor.process(dummyr),createHeaders(request,save.getId()),
HttpStatus.CREATED);
}
#RequestMapping(value = "/dummyAttributes/{id}", method =
RequestMethod.GET)
public HttpEntity<Resource<DummyAttribute>> getDummyAttribute(
#PathVariable("id") DummyAttribute dummyAttribute) {
Resource<DummyAttribute> dummyr = new Resource<DummyAttribute>
(dummyAttribute);
return new ResponseEntity<Resource<DummyAttribute>>
(processor.process(dummyr), HttpStatus.OK);
}
I followed the same sequence of step as above. I did a POST todummyAttribute.
Using this self link , I tried to create a dummy.
This time things are not so smooth. I get this exception back.
Can not instantiate value of type [simple type,
class com.sudo.DummyAttribute] from String value
('http://localhost:8080/dummyAttributes/3fa67f88-f3f9-4efa-a502-
bbeffd3f6025'); no single-String constructor/factory method at
[Source: java.io.PushbackInputStream#224c018a; line: 2, column: 19]
(through reference chain: com.sudo.Dummy["dummyAttribute"])
When I create a constructor inside DummyAttribute, and I parse the id from the url and assign it to the id.
public DummyAttribute(String url) {
String attrId = // parse the URL to get the id;
this.id = attrId;
}
Now things are work as expected.The dummyAttribute is assigned to dummy.
What I would like to know is why are things different when I write my custom-controller ? What am I missing ? How is it that when I use Spring Data REST, the reference URL to the dummyAttribute was automatically resolved to the corresponding dummyAttribute object and in the custom controller, I had to parse it manually and assign the id value explicitly to domainAttribute id?
Also, in the constructor I believe, the dummyAttribute is not resolved by finding it from repository by doing a findOne but a new dummyAttribute is being created. Is this correct?
How do I make my POSTs to my custom controller work exactly like how it works in Spring Data REST ? Do I need a custom serializer/deserializer for this ? Do I need to register some components manually and invoked it ?
I found that when I have customer controllers and #EnableWebMvc is used, the associated resource does not get resolved. That results in the error above. If no #EnableWebMvc is present, then the associated resource gets resolved properly. Not sure how #EnableWebMvc gets in between....
The spring versions that I use are : spring-boot-starter-1.2.5, spring-boot-starter-data-rest-1.2.5, spring-data-commons-1.9.3. spring-hateoas-0.16.0, spring-data-rest-core-2.2.3, spring-data-rest-webmvc-2.2.3.

Advice on web api unity and lifetime of repositories

I'm just running some tests with web api and unity, I have created a simple product repository and registered it with unity
public class ProductRepository : IProductRepository
{
private List<Product> products = new List<Product>();
private int _nextId = 1;
public ProductRepository()
{
Add(new Product { Name = "Tomato soup", Category = "Groceries", Price = 1.39M });
Add(new Product { Name = "Yo-yo", Category = "Toys", Price = 3.75M });
Add(new Product { Name = "Hammer", Category = "Hardware", Price = 16.99M });
}
public IEnumerable<Product> GetAll()
{
return products;
}
... etc
container.RegisterType<IProductRepository, ProductRepository>((new HierarchicalLifetimeManager()));
when instantiated the product repository populates itself with 3 products so calls to products
api/Products returns all products.
The controller is initialised
private IProductRepository _repository;
public ProductsController(IProductRepository repository)
{
_repository = repository;
}
by using the HierarchicalLifetimeManager I was expecting that if I put to the controller and then subsequently get that the previously put item would exist, this is not the case and the repository is initialized with every call, I'm only prototyping at the moment so don't want a dbcontext but want the repositories state to persist with multiple calls sort of singleton I suppose. any pointers on how this works or what I should do?
Try using the ContainerControlledLifetimeManager instead. From http://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx#sec34.
The default lifetime manager for the RegisterType method is the TransientLifetimeManager and the default lifetime manager for the RegisterInstance method is the ContainerControlledLifetimeManager. If you want the container to create or return a singleton instance of a type when you call the Resolve method, you can use the ContainerControlledLifetimeManager type when you register your type or instance.

Moq and setting properties in a class

I have a class with properties in it that are populated via a loader class. Quick example:
class Employee : IEmployee
{
public string EmpFirstName {get; set}
public string EmpLastName {get; set}
}
public class EmpLoader(int employeeID)
{
public void Load(IEmployee emp)
{
emp.EmpFirstName = //lookup the employee using the EmployeeID
//...
}
}
I'm wondering how to go about arranging things so that a mocked EmpLoader's Load() method fills in particular values in the Employee. Something like:
Employee myEmp = new Employee();
_empLoader = new Mock<EmpLoader>();
_empLoader.Setup(empL => empL.Load(myEmp)).Sets_myEmp_Properties_Somehow();
I've used Moq's Setup() method before when deciding what sort of return values come back, but wasn't sure if I can use it or another method to set properties in one class via a third party class. Could be I'm way off here; I'm not an expert in Moq and am open to suggestions.
You can use the Callback() method on the Setup() to load the data:
Employee myEmp = new Employee();
Mock<EmpLoader> _empLoader = new Mock<EmpLoader>();
_empLoader.Setup(empL => empL.Load(myEmp)).Callback<IEmployee>((emp) => {
emp.EmpFirstName = "Steve";
// ... Load all properties
}

ASMX Web Service (ASP.net 2.0) - Serializable Dictionary not serialized

All,
I have an instance of ProjectBudget class returned from a web method.
Ex:
[WebMethod()]
public ProjectBudget LoadBudget(int id)
{
ProjectBudget budget = BudgetManager.LoadBudget(id);
return budget;
}
The ProjectBudget class contains the following defintion:
public class ProjectBudget
{
public int Id = -1;
public long VersionNumber = -1;
public string QuoteNumber = "";
public string CurrencyCode = "";
public ProjectInfo Project;
public ClientInfo Client;
public readonly List<InventoryItem> Inventory = new List<InventoryItem>();
public readonly List<Staff> Staff = new List<Staff>();
public readonly List<CodeType> Departments = new List<CodeType>();
public readonly SerializableDictionary<string, string> Tasks = new SerializableDictionary<string, string>();
public ProjectBudget()
{
}
}
All public fields you see are serialized just fine with the exception of Tasks field, which is completely ignored by XML serializer. Since we all know by now that Dictionaries cannot be handled by XML serializer, I use a serializable dictionary (which is just a dictionary that implements IXmlSerializable) here but XML serializer decides to ignore it completely, i.e. the XML output does not contain any tasks and the generated proxy class doesn't have this field.
I need to figure out how to tell the XML serializer not to omit this field.
Btw, what is interesting is that a web method that returns SerializableDictionary works fine!
A very similar question as yours appears to have been asked already: Link.
Use DataContractSerializer or try explicitly implementing your getter (and setter), as per this link.

Resources