Nopcommerce unable to find my Payment Method plugin's component - c#

I am developing a customized Payment Method plugin for my client. I am a beginner in Nopcommerce plugin development and here's my plugin directory structure:
Code
Here's my CODBookingPaymentProcessor.cs
public class CODBookingPaymentProcessor : BasePlugin, IPaymentMethod
{
#region Ctor
public CODBookingPaymentProcessor()
{
}
#endregion
#region Methods
public bool SupportCapture => false;
public bool SupportPartiallyRefund => false;
public bool SupportRefund => false;
public bool SupportVoid => false;
public RecurringPaymentType RecurringPaymentType => RecurringPaymentType.NotSupported;
public PaymentMethodType PaymentMethodType => PaymentMethodType.Standard;
public bool SkipPaymentInfo => false;
public string PaymentMethodDescription => "Pay booking and extras before order placing.";
public CancelRecurringPaymentResult CancelRecurringPayment(CancelRecurringPaymentRequest cancelPaymentRequest)
{
return new CancelRecurringPaymentResult();
}
public bool CanRePostProcessPayment(Order order)
{
if (order == null)
throw new ArgumentNullException(nameof(order));
//it's not a redirection payment method. So we always return false
return false;
}
public CapturePaymentResult Capture(CapturePaymentRequest capturePaymentRequest)
{
return new CapturePaymentResult { Errors = new[] { "Capture method not supported" } };
}
public decimal GetAdditionalHandlingFee(IList<ShoppingCartItem> cart)
{
return 0;
}
public ProcessPaymentRequest GetPaymentInfo(IFormCollection form)
{
return new ProcessPaymentRequest();
}
public string GetPublicViewComponentName()
{
return "CODBooking";
}
public bool HidePaymentMethod(IList<ShoppingCartItem> cart)
{
return false;
}
public void PostProcessPayment(PostProcessPaymentRequest postProcessPaymentRequest)
{
}
public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest)
{
return new ProcessPaymentResult();
}
public ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest)
{
return new ProcessPaymentResult();
}
public RefundPaymentResult Refund(RefundPaymentRequest refundPaymentRequest)
{
return new RefundPaymentResult();
}
public IList<string> ValidatePaymentForm(IFormCollection form)
{
return null;
}
public VoidPaymentResult Void(VoidPaymentRequest voidPaymentRequest)
{
return new VoidPaymentResult();
}
#endregion
}
PaymentCODBookingController.cs code:
[AuthorizeAdmin]
[Area(AreaNames.Admin)]
public class PaymentCODBookingController : BasePaymentController
{
private readonly IPermissionService _permissionService;
public PaymentCODBookingController(IPermissionService permissionService)
{
_permissionService = permissionService;
}
}
CODBookingViewComponent.cs code:
[ViewComponent(Name = "CODBooking")]
public class CODBookingViewComponent : NopViewComponent
{
public IViewComponentResult Invoke()
{
return View("~/Plugins/Payments.CODBookingPaymentProcessor/Views/CODBooking.cshtml");
}
}
CODBooking.cshtml code:
#{
Layout = "";
}
<p>TESTING...</p>
Issue
The problem is that system is unable to find CODBooking.cshtml view. I tried every possible path format but none worked.
I checked other plugins and they are also defining the component path just like mine.

There is a typo in the .cshtml filename "Boooking.cshtml" :) Look closely.

Related

How to infer the Generics type in C#?

I have a class that I use every time I need to return something in my APIs.
public class OperResult<T>
{
public bool Ok { get; private set; }
public T Data { get; private set; }
// Failed result (Ok: false)
public string ErrorCode { get; private set; }
public string ErrorMessage { get; private set; }
public static OperResult<T> Success(T data)
{
return new OperResult<T>(data);
}
public static OperResult<T> Error(string message, string code = null)
{
return new OperResult<T>(message, code);
}
private OperResult(T data = default(T))
{
Data = data;
Ok = true;
}
private OperResult(string message, string code = null)
{
ErrorCode = code;
ErrorMessage = message;
Ok = false;
}
}
And one that doesn't have generics
public class OperResult
{
public string ErrorCode { get; private set; }
public string ErrorMessage { get; private set; }
public object Data { get; private set; }
public bool Ok { get; private set; }
public static OperResult Success(object data = null)
{
return new OperResult(data);
}
public static OperResult Error(string message, string code = null)
{
return new OperResult(message, code);
}
private OperResult(object data)
{
Data = data;
Ok = true;
}
private OperResult(string message, string code = null)
{
ErrorCode = code;
ErrorMessage = message;
Ok = false;
}
}
In every API response, I return these objects so I know the data and the status of the operation.
public async Task<OperResult<IEnumerable<string>>> GetLocationNames()
{
var locations = await locationService.GetAll(AuthState);
if (location != null)
return OperResult<IEnumerable<string>>.Success(locations.Select(u => u.name));
else
return OperResult<IEnumerable<string>>.Error("No location data found");
}
I would like to be able not to write the Generics part every time I use it.
Maybe something like:
public async Task<OperResult<IEnumerable<string>>> GetLocationNames()
{
var locations = await locationService.GetAll(AuthState);
if (location != null)
return OperResult.Success(locations.Select(u => u.name)); // infer <IEnumerable<string>>
else
return OperResult.Error("No location data found"); // here too
}
Is this possible?
First, I noticed that the non-generic OperResult can inherit from OperResult<object>. I recommend doing that to avoid code duplication.
The below is inspired by Simulating Return Type Inference in C#.
Create a DelayedResult<T> as a wrapper for some value. This will be useful later on:
public readonly struct DelayedResult<T>
{
public T Value { get; }
public DelayedResult(T value)
{
Value = value;
}
}
In the non-generic OperResult, create an Error and a generic Success method. These are what clients will use to create OperResult<T> and OperResults. Note that these will return the DelayedResult declared earlier:
public static DelayedResult<T> Success<T>(T ok) =>
new DelayedResult<T>(ok);
public static DelayedResult<Error> Error(string error, string code = null) =>
new DelayedResult<Error>(new Error(error, code));
where Error is just a simple type containing the error and code. It could be as simple as a record:
record Error(string Message, string Code);
In OperResult<T>, create implicit conversion operators that converts from DelayedResult to actual OperResult<T>s:
public static implicit operator OperResult<T>(DelayedResult<T> ok) =>
new OperResult<T>(ok.Value);
public static implicit operator OperResult<T>(DelayedResult<Error> error) =>
new OperResult<T>(error.Value.Message, error.Value.Code);
Note that you should never have OperResult<Error> (doesn’t make sense anyway), otherwise the above two overloads will be ambiguous.
In the non-generic OperResult, you can also have:
public static implicit operator OperResult(DelayedResult<object> ok) =>
new OperResult(ok.Value);
public static implicit operator OperResult(DelayedResult<Error> error) =>
new OperResult(error.Value.Msg, error.Value.Code);
Now you can do
public async Task<OperResult<IEnumerable<string>>> GetLocationNames()
{
var locations = await locationService.GetAll(AuthState);
if (location != null)
return OperResult.Success(locations.Select(u => u.name));
else
return OperResult.Error("No location data found");
}
Full code:
public record Error(string Message, string Code);
public readonly struct DelayedResult<T>
{
public T Value { get; }
public DelayedResult(T value)
{
Value = value;
}
}
public class OperResult: OperResult<object>
{
private OperResult(object data) : base(data) {}
private OperResult(string message, string code = null): base(message, code) {}
public static implicit operator OperResult(DelayedResult<object> ok) =>
new OperResult(ok.Value);
public static implicit operator OperResult(DelayedResult<Error> error) =>
new OperResult(error.Value.Message, error.Value.Code);
public static DelayedResult<T> Success<T>(T ok) =>
new DelayedResult<T>(ok);
public static DelayedResult<Error> Error(string message, string code = null) =>
new DelayedResult<Error>(new Error(message, code));
}
public class OperResult<T>
{
public bool Ok { get; private set; }
public T Data { get; private set; }
public string ErrorCode { get; private set; }
public string ErrorMessage { get; private set; }
public static implicit operator OperResult<T>(DelayedResult<T> ok) =>
new OperResult<T>(ok.Value);
public static implicit operator OperResult<T>(DelayedResult<Error> error) =>
new OperResult<T>(error.Value.Message, error.Value.Code);
protected OperResult(T data = default(T))
{
Data = data;
Ok = true;
}
protected OperResult(string message, string code = null)
{
ErrorCode = code;
ErrorMessage = message;
Ok = false;
}
}
Calling static from OperResult<T> will always require you to specify the generic part. However, if its a method that returns OperResult<T> from different class, it may infer the generic via method parameters (assuming OperResult<T> constructor is public):
public static class OperHelper
{
public static OperResult<T> Success<T>(T data)
{
return new OperResult<T>(data);
}
}
The method above can be called by OperHelper.Create(myPayload). However, it relies on the fact that myPayload can be used to infer what type is T. This will allow you to handle the "success" part of the OperResult.
The proposed solution below involves breaking down the OperResult<T> into several class. It assumes the following:
"Error" always have the bool Ok property as false and vice versa
"Error" doesnt need to bring payload/data
First, you have class OperResult, it only holds the contract for bool Ok:
public abstract class OperResult
{
public abstract bool Ok { get; }
}
Then, we extend the OperResult into two - OperSuccess and OperError:
public class OperSuccess<T> : OperResult
{
public override bool Ok { get { return true;} }
public T Data { get; private set; }
public OperSuccess(T data)
{
this.Data = data;
}
}
public class OperError : OperResult
{
public override bool Ok { get { return false;} }
public string ErrorCode { get; private set; }
public string ErrorMessage { get; private set; }
public OperError(string message, string code = null)
{
this.ErrorCode = code;
this.ErrorMessage = message;
}
}
This way, we can expand our OperHelper into accomodating the "error" part.
public static class OperHelper
{
public static OperSuccess<T> Success<T>(T data)
{
return new OperSuccess<T>(data);
}
public static OperError Error(string message, string code = null)
{
return new OperError(message, code);
}
}
This way, it allow us to call either OperHelper.Success(myObject) or OperHelper.Error("my error message").
Note:
Yes, none stops you from creating either OperSuccess and OperError manually
Yes, it works on .Net 4.7

How to disable button when the login is false using MVVM,WPF in C#

I am studying the mvvm pattern and ran into a problem, I need to make sure that the button is inactive when the user entered his data incorrectly
I have dialog window (loginPage) where i vote Login and Password
public class LoginViewModel : ViewModel
{
ApplicationDbContext db;
IEnumerable<User> users;
IAuthorizationService _authorizationService;
IHashingManager _hashingManager;
private bool? _closeWindow;
private RelayCommand _loginUser;
private RelayCommand _cancelCommand;
public bool EnableClose { get; set; }
public LoginViewModel(IViewFactory viewFactory, ICore core) : base(viewFactory)
{
_authorizationService = core.AuthorizationService;
_hashingManager = core.HashingManager;
db = new ApplicationDbContext();
}
public ICommand Command { get; set; }
private string login;
public string Login
{
get => login;
set
{
login = value;
RaisePropertyChanged(nameof(Login));
}
}
private string password;
public string Password
{
get => password;
set
{
password = value;
RaisePropertyChanged(nameof(Password));
}
}
public RelayCommand CancelCommand
{
get
{
return _cancelCommand ??
(_cancelCommand = new RelayCommand(() =>
{
var result = _authorizationService.Login(Login, _hashingManager.Encrypt(Password));
CloseWindow = true;
}));
}
}
public bool? CloseWindow
{
get { return _closeWindow; }
set
{
_closeWindow = value;
RaisePropertyChanged(nameof(CloseWindow));
}
}
public RelayCommand LoginUser
{
get
{
return _loginUser ??
(_loginUser = new RelayCommand(() =>
{
var result = _authorizationService.Login(Login, _hashingManager.Encrypt(Password));
CloseWindow = true;
}));
}
}
public IEnumerable<User> Users
{
get { return users; }
set
{
users = value;
RaisePropertyChanged("Users");
}
}
}
My MainWindow VM
public class MainViewModel : ViewModel
{
private readonly ICore _core;
public ICommand LoginCommand { get; }
public ObservableCollection<ILayoutElementViewModel> Documents { get; private set; }
public MainViewModel(IViewFactory viewFactory, ICore core) : base(viewFactory)
{
_core = core;
this.Documents = new ObservableCollection<ILayoutElementViewModel>();
}
ServiceResult _serviceResult = new ServiceResult();
private RelayCommand openChartView;
public RelayCommand OpenChartView
{
get
{
return openChartView ??
(openChartView = new RelayCommand(()=>
{
if (_serviceResult.IsSucceed)
{
var chartView = new ChartSelectionViewModel(_viewFactory);
_viewFactory.ShowDialogView(chartView);
}
}));
}
}
private string _myProperty;
public string MyProperty
{
get => _myProperty;
set
{
_myProperty = value;
RaisePropertyChanged(() => MyProperty);
}
}
protected override void LoadedExecute()
{
base.LoadedExecute();
_viewFactory.ShowDialogView(new LoginViewModel(_viewFactory, _core));
}
}
When i wrote corectly or not, my dialog window close and main window becomes active.
There is a button , and i want disable this button when the login and password was incorrect.
I think i must use my ServiceResult in MW
public class ServiceResult
{
public bool IsSucceed { get; set; }
public string Error { get; set; }
public ServiceResult()
{
IsSucceed = true;
}
public ServiceResult(string error)
{
IsSucceed = false;
Error = error;
}
}
or
AuthorizationService
public class AuthorizationService : IAuthorizationService
{
public ServiceResult Login(string login,string password)
{
ApplicationDbContext db = new ApplicationDbContext();
var listUsers = db.Users.ToList();
foreach (var item in listUsers)
{
if (item.Login == login && item.Password == password)
{
return new ServiceResult();
}
}
return new ServiceResult("Wrong Login or Password!");
}
}
How can i do that? Thx u.
I done, it was so easy
protected override void LoadedExecute()
{
base.LoadedExecute();
var vm = new LoginViewModel(_viewFactory, _core);
_viewFactory.ShowDialogView(vm);
IsAuth = vm.AuthorizationResult;
}
private RelayCommand openChartView;
public RelayCommand OpenChartView
{
get
{
return openChartView ??
(openChartView = new RelayCommand(()=>
{
if (IsAuth)
{
var chartView = new ChartSelectionViewModel(_viewFactory);
_viewFactory.ShowDialogView(chartView);
}
}));
}
}
You can do a bool binding to the IsEnable property of the button.
code:
public bool Enabled
{
get => _enabled; set
{
_enabled = value;
NotifypropertyChanged("Enabled");
}
}
xaml:
<Button IsEnabled="{Binding Enabled}"></Button>

How to add help for an dynamic parameter?

So, I've created a cmdlet with a dynamic parameter:
public class MyCmdLet : IDynamicParameters
{
public string StandbyFilePath => _standbyFilePathDynamicParameter.StandbyFilePath;
private StandbyFilePathDynamicParameter _standbyFilePathDynamicParameter;
public object GetDynamicParameters()
{
if (RecoveryState == RestoreMode.StandBy)
{
return _standbyFilePathDynamicParameter = new StandbyFilePathDynamicParameter();
}
return null;
}
}
public class StandbyFilePathDynamicParameter
{
[Parameter(Mandatory = true)]
public string StandbyFilePath
{
get { return _standbyFilePath; }
set { _standbyFilePath = value; }
}
private string _standbyFilePath;
}
So everything is great except, this parameter is not shown in cmdlet help. Is there anyway how to add help ?

How to get entity by specific field (not primary key)?

I have done get data by Id (primary key) with success. But if I call Get by another field, why is it always Id that is used?
Here is my code:
ITempatAppService.cs
public interface ITempatAppService:IApplicationService
{
GetTempatOutput GetTempatById(GetTempatInput input);
GetTempatOutput GetTempatByIdKategori(GetTempatKategori input);
}
GetTempatInput.cs
public class GetTempatInput
{
public int Id { get; set; }
}
GetTempatOutput.cs
public class GetTempatKategori
{
public int IdKategori { get; set; }
}
TempatAppService.cs
public class TempatAppService:ApplicationService,ITempatAppService
{
private readonly ITempatManager _tempatManager;
public TempatAppService(ITempatManager tempatManager)
{
_tempatManager = tempatManager;
}
public GetTempatOutput GetTempatById(GetTempatInput input)
{
var getTempat = _tempatManager.GetTempatById(input.Id);
GetTempatOutput output = Mapper.Map<MasterTempat, GetTempatOutput>(getTempat);
return output;
}
public GetTempatOutput GetTempatByIdKategori(GetTempatKategori input)
{
var getTempat = _tempatManager.GetTempatByIdKategori(input.IdKategori);
GetTempatOutput output = Mapper.Map<MasterTempat, GetTempatOutput>(getTempat);
return output;
}
}
Here is my TempatManager.cs:
public class TempatManager : DomainService, ITempatManager
{
private readonly IRepository<MasterTempat> _repositoryTempat;
public TempatManager(IRepository<MasterTempat> repositoryTempat)
{
_repositoryTempat = repositoryTempat;
}
public MasterTempat GetTempatById(int Id)
{
return _repositoryTempat.Get(Id);
}
public MasterTempat GetTempatByIdKategori(int IdKategori)
{
return _repositoryTempat.Get(IdKategori);
}
}
Naming the parameter IdKategori doesn't make it search by that column. Do this:
public MasterTempat GetTempatByIdKategori(int IdKategori)
{
return _repositoryTempat.GetAll().First(t => t.IdKategori == IdKategori);
}
To take the list of the selected kategori.
public List<MasterTempat> GetTempatByIdKategori(int IdKategori)
{
return _repositoryTempat.GetAll().Where(t => t.IdKategori == IdKategori).ToList();
}

Writing my first DSL in C# and getting hung up on func<T> & Action

I'm taking a crack at writing my first DSL for a simple tool at work. I'm using the builder pattern to setup the complex parent object but am running into brick walls for building out the child collections of the parent object. Here's a sample:
Use:
var myMorningCoffee = Coffee.Make.WithCream().WithOuncesToServe(16);
Sample with closure (I think that's what they're called):
var myMorningCoffee = Coffee.Make.WithCream().PourIn(
x => {
x.ShotOfExpresso.AtTemperature(100);
x.ShotOfExpresso.AtTemperature(100).OfPremiumType();
}
).WithOuncesToServe(16);
Sample class (without the child PourIn() method as this is what I'm trying to figure out.)
public class Coffee
{
private bool _cream;
public Coffee Make { get new Coffee(); }
public Coffee WithCream()
{
_cream = true;
return this;
}
public Coffee WithOuncesToServe(int ounces)
{
_ounces = ounces;
return this;
}
}
So in my app for work I have the complex object building just fine, but I can't for the life of me figure out how to get the lambda coded for the sub collection on the parent object. (in this example it's the shots (child collection) of expresso).
Perhaps I'm confusing concepts here and I don't mind being set straight; however, I really like how this reads and would like to figure out how to get this working.
Thanks,
Sam
Ok, so I figured out how to write my DSL using an additional expression builder. This is how I wanted my DSL to read:
var myPreferredCoffeeFromStarbucks =
Coffee.Make.WithCream().PourIn(
x =>
{
x.ShotOfExpresso().AtTemperature(100);
x.ShotOfExpresso().AtTemperature(100).OfPremiumType();
}
).ACupSizeInOunces(16);
Here's my passing test:
[TestFixture]
public class CoffeeTests
{
[Test]
public void Can_Create_A_Caramel_Macchiato()
{
var myPreferredCoffeeFromStarbucks =
Coffee.Make.WithCream().PourIn(
x =>
{
x.ShotOfExpresso().AtTemperature(100);
x.ShotOfExpresso().AtTemperature(100).OfPremiumType();
}
).ACupSizeInOunces(16);
Assert.IsTrue(myPreferredCoffeeFromStarbucks.expressoExpressions[0].ExpressoShots.Count == 2);
Assert.IsTrue(myPreferredCoffeeFromStarbucks.expressoExpressions[0].ExpressoShots.Dequeue().IsOfPremiumType == true);
Assert.IsTrue(myPreferredCoffeeFromStarbucks.expressoExpressions[0].ExpressoShots.Dequeue().IsOfPremiumType == false);
Assert.IsTrue(myPreferredCoffeeFromStarbucks.CupSizeInOunces.Equals(16));
}
}
And here's my CoffeeExpressionBuilder DSL class(s):
public class Coffee
{
public List<ExpressoExpressionBuilder> expressoExpressions { get; private set; }
public bool HasCream { get; private set; }
public int CupSizeInOunces { get; private set; }
public static Coffee Make
{
get
{
var coffee = new Coffee
{
expressoExpressions = new List<ExpressoExpressionBuilder>()
};
return coffee;
}
}
public Coffee WithCream()
{
HasCream = true;
return this;
}
public Coffee ACupSizeInOunces(int ounces)
{
CupSizeInOunces = ounces;
return this;
}
public Coffee PourIn(Action<ExpressoExpressionBuilder> action)
{
var expression = new ExpressoExpressionBuilder();
action.Invoke(expression);
expressoExpressions.Add(expression);
return this;
}
}
public class ExpressoExpressionBuilder
{
public readonly Queue<ExpressoExpression> ExpressoShots =
new Queue<ExpressoExpression>();
public ExpressoExpressionBuilder ShotOfExpresso()
{
var shot = new ExpressoExpression();
ExpressoShots.Enqueue(shot);
return this;
}
public ExpressoExpressionBuilder AtTemperature(int temp)
{
var recentlyAddedShot = ExpressoShots.Peek();
recentlyAddedShot.Temperature = temp;
return this;
}
public ExpressoExpressionBuilder OfPremiumType()
{
var recentlyAddedShot = ExpressoShots.Peek();
recentlyAddedShot.IsOfPremiumType = true;
return this;
}
}
public class ExpressoExpression
{
public int Temperature { get; set; }
public bool IsOfPremiumType { get; set; }
public ExpressoExpression()
{
Temperature = 0;
IsOfPremiumType = false;
}
}
Any and all suggestions are welcome.
What if .IncludeApps accepted an array of AppRegistrations
IncludeApps(params IAppRegistration[] apps)
then
public static class App
{
public static IAppRegistration IncludeAppFor(AppType type)
{
return new AppRegistration(type);
}
}
public class AppRegistration
{
private AppType _type;
private bool _cost;
public AppRegistration(AppType type)
{
_type = type;
}
public AppRegistration AtNoCost()
{
_cost = 0;
return this;
}
}
so eventually it would look like this...
.IncludeApps
(
App.IncludeAppFor(AppType.Any),
App.IncludeAppFor(AppType.Any).AtNoCost()
)
Inside your IncludeApps method you would inspect the registrations and create the objects as required.
To go the delegate route maybe something like this would work?
var aPhone = MyPhone.Create;
MyPhone.Create.IncludeApps
(
x =>
{
x.IncludeAppFor(new object());
}
);
class MyPhone
{
public MyPhone IncludeApps(Action<MyPhone> includeCommand)
{
includeCommand.Invoke(this);
return this;
}
}
If you aren't set on the delegate route maybe params would work?
var anotherPhone = MyPhone.Create.IncludeApps(
new IncludeAppClass(AppType.Math),
new IncludeAppClass(AppType.Entertainment).AtNoCost());
class MyPhone
{
internal MyPhone IncludeApps(params IncludeAppClass[] includeThese)
{
if (includeThese == null)
{
return this;
}
foreach (var item in includeThese)
{
this.Apps.Add(Item);
}
return this;
}
}

Categories