Compare commits
5 Commits
ecb43012ac
...
fafbc55732
| Author | SHA1 | Date | |
|---|---|---|---|
| fafbc55732 | |||
| 555273aed1 | |||
| b481a3999a | |||
| 38142f2435 | |||
| ada8b7a200 |
@ -3933,4 +3933,13 @@
|
|||||||
<data name="Subscription_MaxRegisteredDate" xml:space="preserve">
|
<data name="Subscription_MaxRegisteredDate" xml:space="preserve">
|
||||||
<value>Max. Registrierungsdatum</value>
|
<value>Max. Registrierungsdatum</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="WalkPaymentType_MangoPay" xml:space="preserve">
|
||||||
|
<value>Mangopay</value>
|
||||||
|
</data>
|
||||||
|
<data name="WalkPaymentType_Cash" xml:space="preserve">
|
||||||
|
<value>Barzahlung</value>
|
||||||
|
</data>
|
||||||
|
<data name="Walk_PaymentType" xml:space="preserve">
|
||||||
|
<value>Zahlungsart</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@ -3935,4 +3935,13 @@
|
|||||||
<data name="Subscription_MaxRegisteredDate" xml:space="preserve">
|
<data name="Subscription_MaxRegisteredDate" xml:space="preserve">
|
||||||
<value>Max. registered date</value>
|
<value>Max. registered date</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="WalkPaymentType_MangoPay" xml:space="preserve">
|
||||||
|
<value>Mangopay</value>
|
||||||
|
</data>
|
||||||
|
<data name="WalkPaymentType_Cash" xml:space="preserve">
|
||||||
|
<value>Cash</value>
|
||||||
|
</data>
|
||||||
|
<data name="Walk_PaymentType" xml:space="preserve">
|
||||||
|
<value>Payment tye</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@ -3934,4 +3934,13 @@
|
|||||||
<data name="Subscription_MaxRegisteredDate" xml:space="preserve">
|
<data name="Subscription_MaxRegisteredDate" xml:space="preserve">
|
||||||
<value />
|
<value />
|
||||||
</data>
|
</data>
|
||||||
|
<data name="WalkPaymentType_MangoPay" xml:space="preserve">
|
||||||
|
<value />
|
||||||
|
</data>
|
||||||
|
<data name="WalkPaymentType_Cash" xml:space="preserve">
|
||||||
|
<value />
|
||||||
|
</data>
|
||||||
|
<data name="Walk_PaymentType" xml:space="preserve">
|
||||||
|
<value />
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@ -50,6 +50,7 @@ namespace gehGassi.Core.Services
|
|||||||
var walk = new Walk()
|
var walk = new Walk()
|
||||||
{
|
{
|
||||||
Id = Guid.NewGuid().ToString("N"),
|
Id = Guid.NewGuid().ToString("N"),
|
||||||
|
PaymentType = WalkPaymentType.MangoPay,
|
||||||
Created = DateTimeOffset.UtcNow
|
Created = DateTimeOffset.UtcNow
|
||||||
};
|
};
|
||||||
return walk;
|
return walk;
|
||||||
@ -591,81 +592,84 @@ namespace gehGassi.Core.Services
|
|||||||
walk.PaymentStatus = PaymentStatus.Paid;
|
walk.PaymentStatus = PaymentStatus.Paid;
|
||||||
await CommitAsync("System");
|
await CommitAsync("System");
|
||||||
|
|
||||||
decimal feeDecimal = 0;
|
if (walk.PaymentType == WalkPaymentType.MangoPay)
|
||||||
long feeFromUser = 0;
|
|
||||||
long feeFromVoucher = 0;
|
|
||||||
var gehGassiFee = await gehGassiTransactionService.GetMinGehGassiFeeAsync(walk.Price);
|
|
||||||
if (gehGassiFee != null)
|
|
||||||
{
|
{
|
||||||
if (gehGassiFee.Percent > 0)
|
decimal feeDecimal = 0;
|
||||||
|
long feeFromUser = 0;
|
||||||
|
long feeFromVoucher = 0;
|
||||||
|
var gehGassiFee = await gehGassiTransactionService.GetMinGehGassiFeeAsync(walk.Price);
|
||||||
|
if (gehGassiFee != null)
|
||||||
{
|
{
|
||||||
var percent = walk.Price * gehGassiFee.Percent / 100;
|
if (gehGassiFee.Percent > 0)
|
||||||
feeDecimal = percent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gehGassiFee.Fixed > 0)
|
|
||||||
{
|
|
||||||
feeDecimal += gehGassiFee.Fixed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (feeDecimal > 0)
|
|
||||||
{
|
|
||||||
feeFromUser = (long)(feeDecimal * 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Wenn es einen gutschein gibt, dann Geld vom Transferkontos des Gutscheins auf das transferkonto des Hundebesitzers überweisen
|
|
||||||
if (!string.IsNullOrWhiteSpace(walk.VoucherId) && walk.VoucherAmmount > 0)
|
|
||||||
{
|
|
||||||
var voucherUsed = await voucherCampaignService.GetUsageAsync(walk.VoucherId, walk.DogOwnerId, walk.Id);
|
|
||||||
if (voucherUsed != null)
|
|
||||||
{
|
|
||||||
var ammountFromVoucher = (long)(voucherUsed.VoucherAmmountUsed * 100);
|
|
||||||
voucherUsed.UsageStatus = VoucherUsageStatus.Used;
|
|
||||||
await CommitAsync("System");
|
|
||||||
|
|
||||||
var voucher = await voucherCampaignService.GetVoucherAsync(voucherUsed.VoucherId);
|
|
||||||
if (voucher != null)
|
|
||||||
{
|
{
|
||||||
var campaign = await voucherCampaignService.GetAsync(voucher.VoucherCampaignId);
|
var percent = walk.Price * gehGassiFee.Percent / 100;
|
||||||
if (campaign != null)
|
feeDecimal = percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gehGassiFee.Fixed > 0)
|
||||||
|
{
|
||||||
|
feeDecimal += gehGassiFee.Fixed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (feeDecimal > 0)
|
||||||
|
{
|
||||||
|
feeFromUser = (long)(feeDecimal * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Wenn es einen gutschein gibt, dann Geld vom Transferkontos des Gutscheins auf das transferkonto des Hundebesitzers überweisen
|
||||||
|
if (!string.IsNullOrWhiteSpace(walk.VoucherId) && walk.VoucherAmmount > 0)
|
||||||
|
{
|
||||||
|
var voucherUsed = await voucherCampaignService.GetUsageAsync(walk.VoucherId, walk.DogOwnerId, walk.Id);
|
||||||
|
if (voucherUsed != null)
|
||||||
|
{
|
||||||
|
var ammountFromVoucher = (long)(voucherUsed.VoucherAmmountUsed * 100);
|
||||||
|
voucherUsed.UsageStatus = VoucherUsageStatus.Used;
|
||||||
|
await CommitAsync("System");
|
||||||
|
|
||||||
|
var voucher = await voucherCampaignService.GetVoucherAsync(voucherUsed.VoucherId);
|
||||||
|
if (voucher != null)
|
||||||
{
|
{
|
||||||
var customer = await customerService.GetAsync(campaign.CustomerId);
|
var campaign = await voucherCampaignService.GetAsync(voucher.VoucherCampaignId);
|
||||||
if (customer != null)
|
if (campaign != null)
|
||||||
{
|
{
|
||||||
var dogOwner = await appUserService.GetAsync(walk.DogOwnerId);
|
var customer = await customerService.GetAsync(campaign.CustomerId);
|
||||||
if (dogOwner != null)
|
if (customer != null)
|
||||||
{
|
{
|
||||||
var wallet = await walletService.GetAsync(walk.DogOwnerId, WalletType.Fees);
|
var dogOwner = await appUserService.GetAsync(walk.DogOwnerId);
|
||||||
if (wallet != null)
|
if (dogOwner != null)
|
||||||
{
|
{
|
||||||
var transferResult = await mangoPayService.TransferMoneyAsync(customer.MangopayPaymentId, campaign.WalletFeeId, dogOwner.PaymentId, wallet.Id, walk.Id, ammountFromVoucher, 0, $"VoucherId_{voucher.Id}_WalkId_{walk.Id}", targetAppUserId: dogOwner.Id);
|
var wallet = await walletService.GetAsync(walk.DogOwnerId, WalletType.Fees);
|
||||||
|
if (wallet != null)
|
||||||
|
{
|
||||||
|
var transferResult = await mangoPayService.TransferMoneyAsync(customer.MangopayPaymentId, campaign.WalletFeeId, dogOwner.PaymentId, wallet.Id, walk.Id, ammountFromVoucher, 0, $"VoucherId_{voucher.Id}_WalkId_{walk.Id}", targetAppUserId: dogOwner.Id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var sourceWallet = await walletService.GetAsync(walk.DogOwnerId, WalletType.Fees);
|
var sourceWallet = await walletService.GetAsync(walk.DogOwnerId, WalletType.Fees);
|
||||||
var targetWallet = await walletService.GetAsync(walk.DogWalkerId, WalletType.Credits);
|
var targetWallet = await walletService.GetAsync(walk.DogWalkerId, WalletType.Credits);
|
||||||
if (sourceWallet != null && targetWallet != null)
|
if (sourceWallet != null && targetWallet != null)
|
||||||
{
|
|
||||||
var sourceUser = await appUserService.GetAsync(walk.DogOwnerId);
|
|
||||||
var targetUser = await appUserService.GetAsync(walk.DogWalkerId);
|
|
||||||
|
|
||||||
if (sourceUser != null && targetUser != null)
|
|
||||||
{
|
{
|
||||||
var ammount = (long)(walk.Price * 100);
|
var sourceUser = await appUserService.GetAsync(walk.DogOwnerId);
|
||||||
var transcationSuccess = await mangoPayService.TransferMoneyAsync(walk.DogOwnerId, walk.DogWalkerId, walk.Id, ammount, feeFromUser, $"WalkId_Payment_{walk.Id}");
|
var targetUser = await appUserService.GetAsync(walk.DogWalkerId);
|
||||||
|
|
||||||
//Wallets aktualisieren
|
if (sourceUser != null && targetUser != null)
|
||||||
await mangoPayService.GetWalletBalanceAsync(sourceUser.Id, WalletType.Credits);
|
{
|
||||||
await mangoPayService.GetWalletBalanceAsync(sourceUser.Id, WalletType.Fees);
|
var ammount = (long)(walk.Price * 100);
|
||||||
|
var transcationSuccess = await mangoPayService.TransferMoneyAsync(walk.DogOwnerId, walk.DogWalkerId, walk.Id, ammount, feeFromUser, $"WalkId_Payment_{walk.Id}");
|
||||||
|
|
||||||
await mangoPayService.GetWalletBalanceAsync(targetUser.Id, WalletType.Credits);
|
//Wallets aktualisieren
|
||||||
await mangoPayService.GetWalletBalanceAsync(targetUser.Id, WalletType.Fees);
|
await mangoPayService.GetWalletBalanceAsync(sourceUser.Id, WalletType.Credits);
|
||||||
|
await mangoPayService.GetWalletBalanceAsync(sourceUser.Id, WalletType.Fees);
|
||||||
|
|
||||||
|
await mangoPayService.GetWalletBalanceAsync(targetUser.Id, WalletType.Credits);
|
||||||
|
await mangoPayService.GetWalletBalanceAsync(targetUser.Id, WalletType.Fees);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -303,6 +303,21 @@ namespace gehGassi.Domain.Common
|
|||||||
PayPal = 30
|
PayPal = 30
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zahlungsart für einen Walk
|
||||||
|
/// </summary>
|
||||||
|
public enum WalkPaymentType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Mit MangoPay bezahlen (z.B. Kreditkarte)
|
||||||
|
/// </summary>
|
||||||
|
MangoPay = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// Barzahlung
|
||||||
|
/// </summary>
|
||||||
|
Cash = 10
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Zahlungsstatus
|
/// Zahlungsstatus
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -178,6 +178,12 @@ namespace gehGassi.Domain.Walks
|
|||||||
[Required]
|
[Required]
|
||||||
public PaymentStatus PaymentStatus { get; set; }
|
public PaymentStatus PaymentStatus { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Welche Art von Bezahlung wurde verwendet
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public WalkPaymentType PaymentType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id des Gutscheins der verwendet wurde, wenn einer verwendet wurde
|
/// Id des Gutscheins der verwendet wurde, wenn einer verwendet wurde
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -473,6 +479,11 @@ namespace gehGassi.Domain.Walks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public PaymentStatus PaymentStatus { get; set; }
|
public PaymentStatus PaymentStatus { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Welche Art von Bezahlung wurde verwendet
|
||||||
|
/// </summary>
|
||||||
|
public WalkPaymentType PaymentType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id des Gutscheins der verwendet wurde, wenn einer verwendet wurde
|
/// Id des Gutscheins der verwendet wurde, wenn einer verwendet wurde
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -584,6 +584,21 @@ namespace gehGassi.Dto.Common
|
|||||||
RefundendAndPayed = 60
|
RefundendAndPayed = 60
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zahlungsart für einen Walk
|
||||||
|
/// </summary>
|
||||||
|
public enum WalkPaymentTypeDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Mit MangoPay bezahlen (z.B. Kreditkarte)
|
||||||
|
/// </summary>
|
||||||
|
MangoPay = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// Barzahlung
|
||||||
|
/// </summary>
|
||||||
|
Cash = 10
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sortierreihenfolge
|
/// Sortierreihenfolge
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using gehGassi.Dto.Common;
|
||||||
|
|
||||||
namespace gehGassi.Dto.Walks
|
namespace gehGassi.Dto.Walks
|
||||||
{
|
{
|
||||||
@ -36,5 +37,9 @@ namespace gehGassi.Dto.Walks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset UpdatedAt { get; set; }
|
public DateTimeOffset UpdatedAt { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zahlungsart für den Walk
|
||||||
|
/// </summary>
|
||||||
|
public WalkPaymentTypeDto? PaymentType { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,5 +101,10 @@ namespace gehGassi.Dto.Walks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(500)]
|
[MaxLength(500)]
|
||||||
public string Info { get; set; }
|
public string Info { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zahlungsart für den Walk
|
||||||
|
/// </summary>
|
||||||
|
public WalkPaymentTypeDto? PaymentType { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -179,6 +179,11 @@ namespace gehGassi.Dto.Walks
|
|||||||
[Required]
|
[Required]
|
||||||
public PaymentStatusDto PaymentStatus { get; set; }
|
public PaymentStatusDto PaymentStatus { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zahlungsart für den Walk
|
||||||
|
/// </summary>
|
||||||
|
public WalkPaymentTypeDto PaymentType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Datum der Erstellung des Walks
|
/// Datum der Erstellung des Walks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -204,6 +204,11 @@ namespace gehGassi.Dto.Walks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public PaymentStatusDto PaymentStatus { get; set; }
|
public PaymentStatusDto PaymentStatus { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zahlungsart für den Walk
|
||||||
|
/// </summary>
|
||||||
|
public WalkPaymentTypeDto PaymentType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id des Gutscheins der verwendet wurde, wenn einer verwendet wurde
|
/// Id des Gutscheins der verwendet wurde, wenn einer verwendet wurde
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
9478
gehGassi.Persistence/Migrations/20250630082853_Walk_PaymentType_Added.Designer.cs
generated
Normal file
9478
gehGassi.Persistence/Migrations/20250630082853_Walk_PaymentType_Added.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,65 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace gehGassi.Persistence.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Walk_PaymentType_Added : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "PaymentType",
|
||||||
|
table: "Walks",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.Sql("Update Walks SET PaymentType = 1");
|
||||||
|
|
||||||
|
|
||||||
|
var viewName = "tv_WalksWithNames";
|
||||||
|
var sql = @"CREATE FUNCTION tv_WalksWithNames() RETURNS TABLE AS RETURN
|
||||||
|
SELECT W.*,
|
||||||
|
CONCAT(DW.FirstName, ' ' , DW.LastName) AS DogWalkerName, DW.Photo AS DogWalkerPhoto,
|
||||||
|
IsNull(DW.Locked,0) AS DogWalkerLocked, CAST((SELECT CASE WHEN AUBDW.Id IS NOT NULL THEN 1 ELSE 0 END) AS BIT) AS DogWalkerBlocked,
|
||||||
|
CONCAT(DO.FirstName, ' ' , DO.LastName) AS DogOwnerName, DO.Photo AS DogOwnerPhoto,
|
||||||
|
IsNull(DO.Locked,0) AS DogOwnerLocked, CAST((SELECT CASE WHEN AUBDO.Id IS NOT NULL THEN 1 ELSE 0 END) AS BIT) AS DogOwnerBlocked
|
||||||
|
FROM Walks W
|
||||||
|
LEFT JOIN AppUsers DW ON W.DogWalkerId = DW.Id
|
||||||
|
LEFT JOIN AppUsers DO ON W.DogOwnerId = DO.Id
|
||||||
|
LEFT OUTER JOIN AppUserBlocks AUBDW ON AUBDW.BlockedAppUserId = DW.Id AND AUBDW.BlockingAppUserId = DO.Id
|
||||||
|
LEFT OUTER JOIN AppUserBlocks AUBDO ON AUBDO.BlockedAppUserId = DO.Id AND AUBDO.BlockingAppUserId = DW.Id";
|
||||||
|
|
||||||
|
migrationBuilder.Sql($"IF(exists (SELECT 1 FROM sys.objects WHERE Name = '{viewName}')) BEGIN DROP FUNCTION [dbo].[{viewName}] END {Environment.NewLine} GO");
|
||||||
|
migrationBuilder.Sql($"{sql} {Environment.NewLine} GO");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "PaymentType",
|
||||||
|
table: "Walks");
|
||||||
|
|
||||||
|
var viewName = "tv_WalksWithNames";
|
||||||
|
var sql = @"CREATE FUNCTION tv_WalksWithNames() RETURNS TABLE AS RETURN
|
||||||
|
SELECT W.*,
|
||||||
|
CONCAT(DW.FirstName, ' ' , DW.LastName) AS DogWalkerName, DW.Photo AS DogWalkerPhoto,
|
||||||
|
IsNull(DW.Locked,0) AS DogWalkerLocked, CAST((SELECT CASE WHEN AUBDW.Id IS NOT NULL THEN 1 ELSE 0 END) AS BIT) AS DogWalkerBlocked,
|
||||||
|
CONCAT(DO.FirstName, ' ' , DO.LastName) AS DogOwnerName, DO.Photo AS DogOwnerPhoto,
|
||||||
|
IsNull(DO.Locked,0) AS DogOwnerLocked, CAST((SELECT CASE WHEN AUBDO.Id IS NOT NULL THEN 1 ELSE 0 END) AS BIT) AS DogOwnerBlocked
|
||||||
|
FROM Walks W
|
||||||
|
LEFT JOIN AppUsers DW ON W.DogWalkerId = DW.Id
|
||||||
|
LEFT JOIN AppUsers DO ON W.DogOwnerId = DO.Id
|
||||||
|
LEFT OUTER JOIN AppUserBlocks AUBDW ON AUBDW.BlockedAppUserId = DW.Id AND AUBDW.BlockingAppUserId = DO.Id
|
||||||
|
LEFT OUTER JOIN AppUserBlocks AUBDO ON AUBDO.BlockedAppUserId = DO.Id AND AUBDO.BlockingAppUserId = DW.Id";
|
||||||
|
|
||||||
|
migrationBuilder.Sql($"IF(exists (SELECT 1 FROM sys.objects WHERE Name = '{viewName}')) BEGIN DROP FUNCTION [dbo].[{viewName}] END {Environment.NewLine} GO");
|
||||||
|
migrationBuilder.Sql($"{sql} {Environment.NewLine} GO");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7818,6 +7818,9 @@ namespace gehGassi.Persistence.Migrations
|
|||||||
b.Property<int>("PaymentStatus")
|
b.Property<int>("PaymentStatus")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("PaymentType")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<Point>("PickupLocation")
|
b.Property<Point>("PickupLocation")
|
||||||
.HasColumnType("geography");
|
.HasColumnType("geography");
|
||||||
|
|
||||||
@ -8091,6 +8094,9 @@ namespace gehGassi.Persistence.Migrations
|
|||||||
b.Property<int>("PaymentStatus")
|
b.Property<int>("PaymentStatus")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("PaymentType")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("PickupAddress_AddressLine1")
|
b.Property<string>("PickupAddress_AddressLine1")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
|||||||
@ -776,7 +776,7 @@ namespace gehGassi.Web.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="model">Model</param>
|
/// <param name="model">Model</param>
|
||||||
/// <returns>Json</returns>
|
/// <returns>Json</returns>
|
||||||
[Authorize(Policy = Policies.PowerUserOnly)]
|
[Authorize(Policy = Policies.CustomerOnly)]
|
||||||
[HasPermission(Permission.AdvertisementsManage, Permission.AdvertisementsEdit)]
|
[HasPermission(Permission.AdvertisementsManage, Permission.AdvertisementsEdit)]
|
||||||
[CustomerAuthorize("CustomerId")]
|
[CustomerAuthorize("CustomerId")]
|
||||||
[ValidateAntiForgeryToken]
|
[ValidateAntiForgeryToken]
|
||||||
|
|||||||
@ -56,6 +56,7 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
[ApiController]
|
[ApiController]
|
||||||
[ApiVersion(1)]
|
[ApiVersion(1)]
|
||||||
[ApiVersion(2)]
|
[ApiVersion(2)]
|
||||||
|
[ApiVersion(3)]
|
||||||
[Route("api/account")]
|
[Route("api/account")]
|
||||||
[Route("api/v{v:apiVersion}/account")]
|
[Route("api/v{v:apiVersion}/account")]
|
||||||
public class ApiAccountController : ApiBaseController
|
public class ApiAccountController : ApiBaseController
|
||||||
@ -465,6 +466,131 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registrieren eines App-Users
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">Model</param>
|
||||||
|
/// <returns>HTTP 200 OK wenn erfolgreich</returns>
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost]
|
||||||
|
[MapToApiVersion(3)]
|
||||||
|
[Route("Register")]
|
||||||
|
public async Task<IActionResult> RegisterV3(RegisterV2Dto model)
|
||||||
|
{
|
||||||
|
var clientOffset = GetClientDateOffset();
|
||||||
|
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var user = await _userService.GetByUsernameAsync(model.UserName);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
user = _userService.Create();
|
||||||
|
user.Id = Guid.NewGuid().ToString();
|
||||||
|
user.UserName = model.UserName;
|
||||||
|
user.FirstName = model.FirstName;
|
||||||
|
user.LastName = model.LastName;
|
||||||
|
user.FullName = $"{model.FirstName} {model.LastName}";
|
||||||
|
user.RegistrationDate = DateTimeOffset.UtcNow;
|
||||||
|
user.Photo = string.Empty;
|
||||||
|
user.Email = model.UserName;
|
||||||
|
user.EmailConfirmed = !_authOptions.Value.MustConfirmEmail;
|
||||||
|
user.Permissions = PermissionHelper.GetForRole("AppUser").PackPermissionsIntoString();
|
||||||
|
|
||||||
|
var createResult = await _userManager.CreateAsync(user, model.Password);
|
||||||
|
if (createResult.Succeeded)
|
||||||
|
{
|
||||||
|
await _userManager.AddToRoleAsync(user, "AppUser");
|
||||||
|
user = await _userService.GetAsync(user.Id);
|
||||||
|
|
||||||
|
//Nun den AppUser anlegen und dann mit dem Benutzer verknüpfen
|
||||||
|
var appUser = AppUserService.Create();
|
||||||
|
appUser.Type = (AppUserType)model.AppUserType;
|
||||||
|
appUser.Number = AppUserService.GetNextNumber();
|
||||||
|
appUser.FirstName = model.FirstName;
|
||||||
|
appUser.LastName = model.LastName;
|
||||||
|
appUser.Sex = Sex.Undefined;
|
||||||
|
appUser.BirthDate = model.BirthDate;
|
||||||
|
appUser.Photo = string.Empty;
|
||||||
|
appUser.Contact.Email = model.UserName;
|
||||||
|
appUser.Address.City = model.City;
|
||||||
|
appUser.Address.Zip = model.Zip;
|
||||||
|
appUser.Address.CountryCode = model.CountryCode;
|
||||||
|
appUser.Address.State = model.State;
|
||||||
|
appUser.TermsAccepted = true;
|
||||||
|
appUser.TermsAcceptedDate = DateTimeOffset.UtcNow;
|
||||||
|
appUser.PrivacyAccepted = true;
|
||||||
|
appUser.PrivacyAcceptedDate = DateTimeOffset.UtcNow;
|
||||||
|
appUser.Verified = false;
|
||||||
|
appUser.VerifiedDate = null;
|
||||||
|
appUser.PaymentTermsAccepted = false;
|
||||||
|
appUser.PaymentTermsAcceptedDate = null;
|
||||||
|
appUser.NationalityCode = string.Empty;
|
||||||
|
appUser.MainResidenceCode = string.Empty;
|
||||||
|
|
||||||
|
if (appUser.Type == AppUserType.DogWalker)
|
||||||
|
{
|
||||||
|
appUser.PaymentTermsAccepted = false;
|
||||||
|
appUser.PaymentTermsAcceptedDate = null;
|
||||||
|
appUser.NationalityCode = model.NationalityCode;
|
||||||
|
appUser.MainResidenceCode = model.MainResidenceCountryCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
var location = await _geoLocationService.GetLocationAsync($"{model.Zip},{model.City},{model.CountryCode},{model.State}", CultureInfo.CurrentCulture.TwoLetterISOLanguageName);
|
||||||
|
if (location.Success)
|
||||||
|
{
|
||||||
|
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
|
||||||
|
var geoLocation = geometryFactory.CreatePoint(new Coordinate(location.Longitude, location.Latitude));
|
||||||
|
appUser.Location = geoLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppUserService.Add(appUser);
|
||||||
|
await AppUserService.CommitAsync("System");
|
||||||
|
|
||||||
|
user.AppUserId = appUser.Id;
|
||||||
|
await _userService.CommitAsync("System");
|
||||||
|
|
||||||
|
if (appUser.Type != AppUserType.DogOwner)
|
||||||
|
{
|
||||||
|
await AppUserService.CreateWalkerProfileIfNotExistsAsync(appUser.Id);
|
||||||
|
await AppUserService.CommitAsync("System");
|
||||||
|
|
||||||
|
//Nun für den Walker Mangopay User anlegen
|
||||||
|
//var mangoPayResult = await _mangoPayService.CreateOwnerAsync(appUser.Id, false);
|
||||||
|
//if (mangoPayResult.Success)
|
||||||
|
//{
|
||||||
|
// //Wallets anlegen
|
||||||
|
// var walletCreditsResult = await _mangoPayService.CreateWalletAsync(appUser.Id, WalletType.Credits);
|
||||||
|
// var walletFeesResult = await _mangoPayService.CreateWalletAsync(appUser.Id, WalletType.Fees);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_authOptions.Value.MustConfirmEmail)
|
||||||
|
{
|
||||||
|
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||||
|
var callbackUrl = Url.Action("ConfirmEmailApp", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
|
||||||
|
await _emailSender.SendEmailConfirmationAsync(user.UserName, callbackUrl, _localizer, _licenseOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (createResult.Errors.FirstOrDefault(c => c.Code == "PwnedPassword") != null)
|
||||||
|
{
|
||||||
|
return BadRequest(CommunicationErrors.Register_Password_Pwned);
|
||||||
|
}
|
||||||
|
if (createResult.Errors.FirstOrDefault(c => c.Code.StartsWith("IdentityError_Password")) != null)
|
||||||
|
{
|
||||||
|
return BadRequest(CommunicationErrors.Register_Password_Rules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Register_Failed);
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Register_Email_Exists);
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registrieren eines App-Users mittels external Provider
|
/// Registrieren eines App-Users mittels external Provider
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -958,6 +1084,254 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registrieren eines App-Users mittels external Provider
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">Model</param>
|
||||||
|
/// <returns>HTTP 200 OK wenn erfolgreich</returns>
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost]
|
||||||
|
[MapToApiVersion(3)]
|
||||||
|
[Route("RegisterExternal")]
|
||||||
|
public async Task<IActionResult> RegisterExternalV3(RegisterExternalV2Dto model)
|
||||||
|
{
|
||||||
|
var clientOffset = GetClientDateOffset();
|
||||||
|
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
//Zuerst holen wir nochmal die Infos für den User. Token prüfen... //TODO: Je nach Provider vorgehen. Derzeit nur google. Apple einführen...
|
||||||
|
var tokenValid = false;
|
||||||
|
ExternalLoginGoogleResponse userInfo = null;
|
||||||
|
AppleResponseDto appleResponse = null;
|
||||||
|
|
||||||
|
if (model.LoginProvider == "Google")
|
||||||
|
{
|
||||||
|
HttpStatusCode tokenResponseCode = HttpStatusCode.OK;
|
||||||
|
var httpClient = new HttpClient();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", model.AccessToken);
|
||||||
|
var tokenResult = await httpClient.GetAsync($"https://www.googleapis.com/oauth2/v3/userinfo");
|
||||||
|
if (tokenResult.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
string jsonString = tokenResult.Content.ReadAsStringAsync().Result;
|
||||||
|
userInfo = JsonSerializer.Deserialize<ExternalLoginGoogleResponse>(jsonString);
|
||||||
|
tokenValid = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tokenResponseCode = tokenResult.StatusCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
tokenValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (model.LoginProvider == "Apple")
|
||||||
|
{
|
||||||
|
var clientSecret = await GenerateAppleClientSecretAsync();
|
||||||
|
var parameters = new List<KeyValuePair<string, string>>
|
||||||
|
{
|
||||||
|
new KeyValuePair<string, string>("client_id", _appleOptions.Value.ClientId),
|
||||||
|
new KeyValuePair<string, string>("client_secret", clientSecret),
|
||||||
|
new KeyValuePair<string, string>("refresh_token", model.AccessToken),
|
||||||
|
new KeyValuePair<string, string>("grant_type", "refresh_token")
|
||||||
|
};
|
||||||
|
|
||||||
|
var httpClient = new HttpClient();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var tokenResult = await httpClient.PostAsync($"https://appleid.apple.com/auth/token", new FormUrlEncodedContent(parameters));
|
||||||
|
if (tokenResult.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
var successResponse = await tokenResult.Content.ReadAsStringAsync();
|
||||||
|
appleResponse = JsonSerializer.Deserialize<AppleResponseDto>(successResponse);
|
||||||
|
tokenValid = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var errorResponse = await tokenResult.Content.ReadAsStringAsync();
|
||||||
|
_logger.LogError(errorResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
tokenValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenValid)
|
||||||
|
{
|
||||||
|
var user = await _userService.GetByUsernameAsync(model.UserName);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
user = _userService.Create();
|
||||||
|
user.Id = Guid.NewGuid().ToString();
|
||||||
|
user.UserName = model.UserName;
|
||||||
|
user.FirstName = model.FirstName;
|
||||||
|
user.LastName = model.LastName;
|
||||||
|
user.FullName = $"{model.FirstName} {model.LastName}";
|
||||||
|
user.RegistrationDate = DateTimeOffset.UtcNow;
|
||||||
|
user.Photo = string.Empty;
|
||||||
|
user.Email = model.UserName;
|
||||||
|
user.EmailConfirmed = true; //Weil über externen Provider
|
||||||
|
user.Permissions = PermissionHelper.GetForRole("AppUser").PackPermissionsIntoString();
|
||||||
|
|
||||||
|
IdentityResult createResult;
|
||||||
|
if (!string.IsNullOrEmpty(model.Password))
|
||||||
|
createResult = await _userManager.CreateAsync(user, model.Password);
|
||||||
|
else
|
||||||
|
createResult = await _userManager.CreateAsync(user);
|
||||||
|
|
||||||
|
if (createResult.Succeeded)
|
||||||
|
{
|
||||||
|
await _userManager.AddToRoleAsync(user, "AppUser");
|
||||||
|
user = await _userManager.FindByEmailAsync(user.UserName);
|
||||||
|
|
||||||
|
//Nun den AppUser anlegen und dann mit dem Benutzer verknüpfen
|
||||||
|
var appUser = AppUserService.Create();
|
||||||
|
appUser.Type = (AppUserType)model.AppUserType;
|
||||||
|
appUser.Number = AppUserService.GetNextNumber();
|
||||||
|
appUser.FirstName = model.FirstName;
|
||||||
|
appUser.LastName = model.LastName;
|
||||||
|
appUser.Sex = Sex.Undefined;
|
||||||
|
appUser.BirthDate = model.BirthDate;
|
||||||
|
appUser.Photo = string.Empty;
|
||||||
|
appUser.Contact.Email = model.UserName;
|
||||||
|
appUser.Address.City = model.City;
|
||||||
|
appUser.Address.Zip = model.Zip;
|
||||||
|
appUser.Address.CountryCode = model.CountryCode;
|
||||||
|
appUser.Address.State = model.State;
|
||||||
|
appUser.TermsAccepted = true;
|
||||||
|
appUser.TermsAcceptedDate = DateTimeOffset.UtcNow;
|
||||||
|
appUser.PrivacyAccepted = true;
|
||||||
|
appUser.PrivacyAcceptedDate = DateTimeOffset.UtcNow;
|
||||||
|
appUser.Verified = false;
|
||||||
|
appUser.VerifiedDate = null;
|
||||||
|
appUser.PaymentTermsAccepted = false;
|
||||||
|
appUser.PaymentTermsAcceptedDate = null;
|
||||||
|
appUser.NationalityCode = string.Empty;
|
||||||
|
appUser.MainResidenceCode = string.Empty;
|
||||||
|
|
||||||
|
if (appUser.Type == AppUserType.DogWalker)
|
||||||
|
{
|
||||||
|
appUser.PaymentTermsAccepted = false;
|
||||||
|
appUser.PaymentTermsAcceptedDate = null;
|
||||||
|
appUser.NationalityCode = model.NationalityCode;
|
||||||
|
appUser.MainResidenceCode = model.MainResidenceCountryCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
var location = await _geoLocationService.GetLocationAsync($"{model.Zip},{model.City},{model.CountryCode},{model.State}", CultureInfo.CurrentCulture.TwoLetterISOLanguageName);
|
||||||
|
if (location.Success)
|
||||||
|
{
|
||||||
|
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
|
||||||
|
var geoLocation = geometryFactory.CreatePoint(new Coordinate(location.Longitude, location.Latitude));
|
||||||
|
appUser.Location = geoLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppUserService.Add(appUser);
|
||||||
|
await AppUserService.CommitAsync("System");
|
||||||
|
|
||||||
|
user.AppUserId = appUser.Id;
|
||||||
|
await _userManager.UpdateAsync(user);
|
||||||
|
|
||||||
|
if (appUser.Type != AppUserType.DogOwner)
|
||||||
|
{
|
||||||
|
await AppUserService.CreateWalkerProfileIfNotExistsAsync(appUser.Id);
|
||||||
|
await AppUserService.CommitAsync("System");
|
||||||
|
|
||||||
|
//Nun für den Walker Mangopay User anlegen
|
||||||
|
//var mangoPayResult = await _mangoPayService.CreateOwnerAsync(appUser.Id, false);
|
||||||
|
//if (mangoPayResult.Success)
|
||||||
|
//{
|
||||||
|
// //Wallets anlegen
|
||||||
|
// var walletCreditsResult = await _mangoPayService.CreateWalletAsync(appUser.Id, WalletType.Credits);
|
||||||
|
// var walletFeesResult = await _mangoPayService.CreateWalletAsync(appUser.Id, WalletType.Fees);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Da wir den User gleich einloggen möchten, geben wir alles nötige zurück
|
||||||
|
var usersClaims = new List<Claim>()
|
||||||
|
{
|
||||||
|
new Claim(ClaimTypes.Name, user.UserName),
|
||||||
|
new Claim(ClaimTypes.GivenName, user.FirstName),
|
||||||
|
new Claim(ClaimTypes.Surname, user.LastName),
|
||||||
|
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
||||||
|
new Claim(ClaimTypes.UserData, user.Photo ?? ""),
|
||||||
|
new Claim(ClaimConstants.AppUserIdClaimType, user.AppUserId ?? ""),
|
||||||
|
};
|
||||||
|
|
||||||
|
var roles = await _userManager.GetRolesAsync(user);
|
||||||
|
foreach (var role in roles)
|
||||||
|
{
|
||||||
|
usersClaims.Add(new Claim(ClaimTypes.Role, role));
|
||||||
|
}
|
||||||
|
|
||||||
|
var token = _tokenService.GenerateAccessToken(usersClaims);
|
||||||
|
await _refreshTokenService.RemoveExpiredAsync(user.Id, user.UserName);
|
||||||
|
var refreshToken = _refreshTokenService.Create();
|
||||||
|
refreshToken.UserId = user.Id;
|
||||||
|
_refreshTokenService.Add(refreshToken);
|
||||||
|
await _refreshTokenService.CommitAsync(user.UserName);
|
||||||
|
|
||||||
|
var userDto = Mapper.Map<UserDto>(user);
|
||||||
|
userDto.AccessToken = token;
|
||||||
|
userDto.AccessTokenExpires = DateTimeOffset.UtcNow.AddMinutes(_jwtTokenOptions.Value.TokenMinutes);
|
||||||
|
userDto.RefreshToken = refreshToken.Token;
|
||||||
|
userDto.RefreshTokenExpires = refreshToken.Expires;
|
||||||
|
userDto.AppUserType = (AppUserTypeDto)appUser.Type;
|
||||||
|
|
||||||
|
var roleList = roles.ToList();
|
||||||
|
userDto.Roles = string.Join(";", roleList);
|
||||||
|
|
||||||
|
user.LastLoginDate = DateTimeOffset.UtcNow;
|
||||||
|
await _userManager.UpdateAsync(user);
|
||||||
|
|
||||||
|
if (model.LoginProvider == "Google" && userInfo != null)
|
||||||
|
{
|
||||||
|
var createdUser = await _userManager.FindByEmailAsync(user.UserName);
|
||||||
|
if (createdUser != null)
|
||||||
|
{
|
||||||
|
await _userManager.AddLoginAsync(createdUser, new UserLoginInfo("Google", userInfo.Sub, user.FullName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (model.LoginProvider == "Apple" && appleResponse != null)
|
||||||
|
{
|
||||||
|
var createdUser = await _userManager.FindByEmailAsync(user.UserName);
|
||||||
|
if (createdUser != null)
|
||||||
|
{
|
||||||
|
var appleToken = new JwtSecurityToken(appleResponse.IdToken);
|
||||||
|
if (appleToken != null)
|
||||||
|
{
|
||||||
|
var appleUserId = appleToken.Claims.First(c => c.Type == "sub").Value;
|
||||||
|
await _userManager.AddLoginAsync(createdUser, new UserLoginInfo("Apple", appleUserId, user.FullName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(userDto);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (createResult.Errors.FirstOrDefault(c => c.Code == "PwnedPassword") != null)
|
||||||
|
{
|
||||||
|
return BadRequest(CommunicationErrors.Register_Password_Pwned);
|
||||||
|
}
|
||||||
|
if (createResult.Errors.FirstOrDefault(c => c.Code.StartsWith("Password")) != null)
|
||||||
|
{
|
||||||
|
return BadRequest(CommunicationErrors.Register_Password_Rules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Register_Failed);
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Register_Email_Exists);
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Register_TokenInvalid);
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Anmelden via API. Erstellt ein Access-Token und ein Refresh-Token wenn erfolgreich
|
/// Anmelden via API. Erstellt ein Access-Token und ein Refresh-Token wenn erfolgreich
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -2041,6 +2415,62 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
return NotFound(CommunicationErrors.Common_NotFound);
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setzt den Modus eines App-Users auf "Beides" - von Owner aufgerufen.
|
||||||
|
/// Erstellt keinen MangoPay User und legt keine Wallets an
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>200 OK</returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Route("SetAppUserTypeNoMango")]
|
||||||
|
public async Task<IActionResult> SetAppUserTypeNoMango(SetAppUserTypeExDto model)
|
||||||
|
{
|
||||||
|
var clientOffset = GetClientDateOffset();
|
||||||
|
|
||||||
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
var user = await _userService.GetByUsernameAsync(User.Identity.Name);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var appUser = await AppUserService.GetAsync(model.Id);
|
||||||
|
if (appUser != null)
|
||||||
|
{
|
||||||
|
if (model.UpdatedAt > appUser.UpdatedAt)
|
||||||
|
{
|
||||||
|
appUser.Type = (AppUserType)model.Type;
|
||||||
|
appUser.NationalityCode = model.NationalityCode;
|
||||||
|
appUser.MainResidenceCode = model.MainResidenceCode;
|
||||||
|
appUser.PaymentTermsAccepted = model.PaymentTermsAccepted;
|
||||||
|
appUser.PaymentTermsAcceptedDate = model.PaymentTermsAcceptedDate;
|
||||||
|
|
||||||
|
appUser.UpdatedAt = model.UpdatedAt;
|
||||||
|
|
||||||
|
await AppUserService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
if (appUser.Type != AppUserType.DogOwner)
|
||||||
|
{
|
||||||
|
await AppUserService.CreateWalkerProfileIfNotExistsAsync(appUser.Id);
|
||||||
|
await AppUserService.CommitAsync(User.Identity.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
var appUserDto = Mapper.Map<AppUserDto>(appUser);
|
||||||
|
var baseAddress = GetBaseAddress();
|
||||||
|
if (!string.IsNullOrWhiteSpace(appUserDto.Photo))
|
||||||
|
{
|
||||||
|
appUserDto.Photo = $"{baseAddress}/file/documents/thumbnails/{200}/{appUserDto.Photo}";
|
||||||
|
}
|
||||||
|
return Ok(appUserDto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hinzufügen eines PaymentUsers zu einem AppUser
|
/// Hinzufügen eines PaymentUsers zu einem AppUser
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -43,6 +43,7 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[ApiVersion(1)]
|
[ApiVersion(1)]
|
||||||
|
[ApiVersion(2)]
|
||||||
[Route("api/walks")]
|
[Route("api/walks")]
|
||||||
[Route("api/v{v:apiVersion}/walks")]
|
[Route("api/v{v:apiVersion}/walks")]
|
||||||
public class ApiWalksController : ApiBaseController
|
public class ApiWalksController : ApiBaseController
|
||||||
@ -954,6 +955,120 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
return NotFound(CommunicationErrors.Common_NotFound);
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Akzeptieren einer Antwort zu einer öffentlichen Anfrage
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">PublicWalkRequestDto</param>
|
||||||
|
/// <returns>HTTP 200 OK, Felher sonst</returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Route("AcceptPublicWalkRequest")]
|
||||||
|
[MapToApiVersion(2)]
|
||||||
|
public async Task<IActionResult> AcceptPublicWalkRequestV2(PublicWalkRequestAcceptDto model)
|
||||||
|
{
|
||||||
|
var clientOffset = GetClientDateOffset();
|
||||||
|
|
||||||
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var request = await _publicWalkRequestService.GetAsync(model.PublicWalkRequestId);
|
||||||
|
if (request != null && request.DogOwnerId == model.DogOwnerId)
|
||||||
|
{
|
||||||
|
var response = await _publicWalkResponseService.GetAsync(model.PublicWalkResponseId);
|
||||||
|
if (response != null && response.PublicWalkRequestId == request.Id)
|
||||||
|
{
|
||||||
|
response.Status = PublicWalkResponseStatus.Accepted;
|
||||||
|
response.UpdatedAt = model.UpdatedAt;
|
||||||
|
|
||||||
|
await _publicWalkResponseService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
//Nun Completed setzen für alle anderen die Warten...
|
||||||
|
await _publicWalkResponseService.SetCompletedForWaitingAsync(request.Id);
|
||||||
|
await _publicWalkResponseService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
request.Status = PublicWalkRequestStatus.Placed;
|
||||||
|
request.PlacedDate = model.UpdatedAt;
|
||||||
|
request.PublicWalkResponseId = response.Id;
|
||||||
|
request.DogWalkerId = response.DogWalkerId;
|
||||||
|
request.UpdatedAt = model.UpdatedAt;
|
||||||
|
|
||||||
|
await _publicWalkResponseService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
//Nachricht an alle Angebote senden...
|
||||||
|
var responses = await _publicWalkResponseService.FindAsync(c => c.PublicWalkRequestId == request.Id);
|
||||||
|
foreach (var publicWalkResponse in responses.Where(c => c.DogWalkerId != request.DogWalkerId))
|
||||||
|
{
|
||||||
|
_systemMessageService.Add(publicWalkResponse.DogWalkerId, AppUserType.DogWalker, request.Id, SystemMessageTables.PublicWalkRequest, SystemMessageType.PublicWalkRequestChanged, DateTimeOffset.UtcNow.AddDays(14));
|
||||||
|
await _pushNotificationService.SendPublicWalkRequestChangedAsync(publicWalkResponse.DogWalkerId, request.Id);
|
||||||
|
}
|
||||||
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
||||||
|
foreach (var publicWalkResponse in responses.Where(c => c.DogWalkerId != request.DogWalkerId))
|
||||||
|
{
|
||||||
|
await _appHubSender.SystemMessageAddedAsync(publicWalkResponse.DogWalkerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Nun einen Walk anlgegen!
|
||||||
|
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
|
||||||
|
var geoLocation = geometryFactory.CreatePoint(new Coordinate(request.Location.X, request.Location.Y));
|
||||||
|
|
||||||
|
var walk = _walkService.Create();
|
||||||
|
walk.Type = WalkType.OpenRequest;
|
||||||
|
walk.ServiceType = request.RequestType == PublicWalkRequestType.Sitting ? WalkServiceType.Sitting : WalkServiceType.Walking;
|
||||||
|
walk.DogWalkerId = request.DogWalkerId;
|
||||||
|
walk.DogOwnerId = request.DogOwnerId;
|
||||||
|
walk.PublicWalkRequestId = request.Id;
|
||||||
|
walk.DogsJson = request.DogsJson;
|
||||||
|
walk.DogCount = request.DogCount;
|
||||||
|
walk.Start = request.StartDate;
|
||||||
|
walk.End = request.EndDate;
|
||||||
|
walk.PickupAddress = request.PickupAddress.Clone();
|
||||||
|
walk.PickupLocation = geoLocation;
|
||||||
|
walk.ReturnAddress = request.PickupAddress.Clone();
|
||||||
|
walk.ReturnLocation = geoLocation;
|
||||||
|
walk.Price = response.Price;
|
||||||
|
walk.Info = request.Info;
|
||||||
|
walk.Status = WalkStatus.Accepted;
|
||||||
|
walk.Started = null;
|
||||||
|
walk.Completed = null;
|
||||||
|
walk.Confirmed = null;
|
||||||
|
walk.Complained = null;
|
||||||
|
walk.ComplainReason = string.Empty;
|
||||||
|
walk.DeclinedReason = string.Empty;
|
||||||
|
walk.CancelledReason = string.Empty;
|
||||||
|
walk.CancelledBy = CancellationSource.None;
|
||||||
|
walk.CompletedInfo = string.Empty;
|
||||||
|
walk.Defactation = false;
|
||||||
|
walk.PaymentStatus = PaymentStatus.Pending;
|
||||||
|
walk.PaymentType = model.PaymentType != null ? (WalkPaymentType)model.PaymentType : WalkPaymentType.MangoPay;
|
||||||
|
walk.UpdatedAt = DateTimeOffset.UtcNow;
|
||||||
|
walk.Created = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
if (walk.Price == 0 || walk.PaymentType == WalkPaymentType.Cash)
|
||||||
|
walk.PaymentStatus = PaymentStatus.Authorized;
|
||||||
|
|
||||||
|
_walkService.Add(walk);
|
||||||
|
await _walkService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
if (walk.PaymentStatus is PaymentStatus.Authorized or PaymentStatus.Paid)
|
||||||
|
{
|
||||||
|
//Nachricht an den dogWalker senden
|
||||||
|
_systemMessageService.Add(walk.DogWalkerId, AppUserType.DogWalker, walk.Id, SystemMessageTables.Walk, SystemMessageType.WalkAdded, DateTimeOffset.UtcNow.AddDays(14));
|
||||||
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
||||||
|
await _appHubSender.SystemMessageAddedAsync(walk.DogWalkerId);
|
||||||
|
await _pushNotificationService.SendNewWalkAsync(walk.DogWalkerId, walk.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
var walkDto = Mapper.Map<WalkDto>(walk);
|
||||||
|
return Ok(walkDto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
|
}
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stornieren einer öffentlichen Anfrage
|
/// Stornieren einer öffentlichen Anfrage
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -2224,6 +2339,128 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
return NotFound(CommunicationErrors.Common_NotFound);
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stornieren eines Walks
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">PublicWalkRequestCancelDto</param>
|
||||||
|
/// <returns>HTTP 200 OK, Fehler sonst</returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Route("CancelWalk")]
|
||||||
|
[MapToApiVersion(2)]
|
||||||
|
public async Task<IActionResult> CancelWalkV2(WalkCancelDto model)
|
||||||
|
{
|
||||||
|
var clientOffset = GetClientDateOffset();
|
||||||
|
|
||||||
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var walk = await _walkService.GetAsync(model.WalkId);
|
||||||
|
if (walk != null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(walk.VoucherId) && walk.VoucherAmmount > 0 && walk.PaymentType == WalkPaymentType.MangoPay)
|
||||||
|
{
|
||||||
|
var usage = await _voucherCampaignService.GetUsageAsync(walk.VoucherId, walk.DogOwnerId, walk.Id);
|
||||||
|
if (usage != null)
|
||||||
|
{
|
||||||
|
var voucher = await _voucherCampaignService.GetVoucherAsync(usage.VoucherId);
|
||||||
|
if (voucher != null && voucher.Id == usage.VoucherId)
|
||||||
|
{
|
||||||
|
var campaign = await _voucherCampaignService.GetAsync(voucher.VoucherCampaignId);
|
||||||
|
if (campaign != null)
|
||||||
|
{
|
||||||
|
var customer = await _customerService.GetAsync(campaign.CustomerId);
|
||||||
|
if (customer != null)
|
||||||
|
{
|
||||||
|
//Geld vom Transferkonto der Kamapgne auf das Guthabenkonto überweisen mit Verweis auf den Walk und Transaktion erfassen
|
||||||
|
var ammount = (int)(usage.VoucherAmmountUsed * 100);
|
||||||
|
var transferResult = await _mangoPayService.TransferMoneyAsync(customer.MangopayPaymentId, campaign.WalletFeeId,
|
||||||
|
customer.MangopayPaymentId, campaign.WalletCreditId, walk.Id, ammount, 0, $"VoucherId_{voucher.Id}_WalkId_{walk.Id}", "", "");
|
||||||
|
|
||||||
|
if (transferResult.Success)
|
||||||
|
{
|
||||||
|
//Usage beim voucher zurücksetzen (UsedCount, IsValid wenn Einzelgutschein)
|
||||||
|
voucher.UsedCount -= 1;
|
||||||
|
if (voucher.UsedCount < 0)
|
||||||
|
voucher.UsedCount = 0;
|
||||||
|
voucher.IsValid = true;
|
||||||
|
|
||||||
|
//Usage in der Kampagne zurücksetzen (VouchersUsed, BudgetUsed)
|
||||||
|
campaign.VouchersUsed -= 1;
|
||||||
|
if (campaign.VouchersUsed < 0)
|
||||||
|
campaign.VouchersUsed = 0;
|
||||||
|
campaign.BudgetUsed -= usage.VoucherAmmountUsed;
|
||||||
|
if (campaign.BudgetUsed < 0)
|
||||||
|
campaign.BudgetUsed = 0;
|
||||||
|
|
||||||
|
walk.VoucherId = null;
|
||||||
|
walk.VoucherAmmount = 0;
|
||||||
|
|
||||||
|
//Reservieren durch die Anlage einer VoucherUsage
|
||||||
|
_voucherCampaignService.RemoveUsage(usage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walk.Status = WalkStatus.Cancelled;
|
||||||
|
walk.UpdatedAt = model.UpdatedAt;
|
||||||
|
walk.CancelledBy = (CancellationSource)model.CancellationSource;
|
||||||
|
walk.CancelledReason = model.CancelledReason;
|
||||||
|
|
||||||
|
//Jetzt noch wegen Zahlungsstatus prüfen
|
||||||
|
if (walk.PaymentStatus == PaymentStatus.Paid || walk.PaymentStatus == PaymentStatus.Authorized)
|
||||||
|
{
|
||||||
|
//Zurücküberweisen der Summe vom Transaktionskonto auf das Guthabenkonto
|
||||||
|
if (walk.Price > 0 && walk.PaymentType == WalkPaymentType.MangoPay)
|
||||||
|
{
|
||||||
|
var ammount = (long)(walk.Price * 100);
|
||||||
|
var tag = $"Walk_Cancel_{walk.Id}";
|
||||||
|
var refundResult = await _mangoPayService.TransferMoneyFromFeeToCreditAccountAsync(walk.DogOwnerId, ammount, tag);
|
||||||
|
if (refundResult.Success)
|
||||||
|
walk.PaymentStatus = PaymentStatus.Refunded;
|
||||||
|
else
|
||||||
|
walk.PaymentStatus = PaymentStatus.Voided;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
walk.PaymentStatus = PaymentStatus.Voided;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _walkService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
//Wallets aktualisieren
|
||||||
|
if (walk.PaymentType == WalkPaymentType.MangoPay)
|
||||||
|
{
|
||||||
|
await _mangoPayService.GetWalletBalanceAsync(walk.DogOwnerId, WalletType.Credits);
|
||||||
|
await _mangoPayService.GetWalletBalanceAsync(walk.DogOwnerId, WalletType.Fees);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walk.CancelledBy == CancellationSource.DogWalker)
|
||||||
|
{
|
||||||
|
_systemMessageService.Add(walk.DogOwnerId, AppUserType.DogOwner, walk.Id, SystemMessageTables.Walk, SystemMessageType.WalkCancelled, DateTimeOffset.UtcNow.AddDays(14));
|
||||||
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
||||||
|
await _appHubSender.SystemMessageAddedAsync(walk.DogOwnerId);
|
||||||
|
await _pushNotificationService.SendWalkCancelledAsync(walk.DogOwnerId, walk.Id, AppMode.DogOwner);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_systemMessageService.Add(walk.DogWalkerId, AppUserType.DogWalker, walk.Id, SystemMessageTables.Walk, SystemMessageType.WalkCancelled, DateTimeOffset.UtcNow.AddDays(14));
|
||||||
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
||||||
|
await _appHubSender.SystemMessageAddedAsync(walk.DogWalkerId);
|
||||||
|
await _pushNotificationService.SendWalkCancelledAsync(walk.DogWalkerId, walk.Id, AppMode.DogWalker);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
|
}
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starten eines Walks
|
/// Starten eines Walks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -2604,6 +2841,190 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
return NotFound(CommunicationErrors.Common_NotFound);
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bestätigen eines Walks
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">WalkConfirmDto</param>
|
||||||
|
/// <returns>HTTP 200 OK, Felher sonst</returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Route("ConfirmWalk")]
|
||||||
|
[MapToApiVersion(2)]
|
||||||
|
public async Task<IActionResult> ConfirmWalkV2(WalkConfirmDto model)
|
||||||
|
{
|
||||||
|
var clientOffset = GetClientDateOffset();
|
||||||
|
|
||||||
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var walk = await _walkService.GetAsync(model.WalkId);
|
||||||
|
if (walk != null && walk.DogOwnerId == model.AppUserId)
|
||||||
|
{
|
||||||
|
var appUser = await AppUserService.GetAsync(walk.DogOwnerId);
|
||||||
|
if (appUser is { Locked: true })
|
||||||
|
{
|
||||||
|
return BadRequest(CommunicationErrors.Login_LockedOut);
|
||||||
|
}
|
||||||
|
var dogWalker = await AppUserService.GetAsync(walk.DogWalkerId);
|
||||||
|
if (dogWalker is { Locked: true })
|
||||||
|
{
|
||||||
|
return BadRequest(CommunicationErrors.Login_LockedOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walk.Status == WalkStatus.Completed && walk.Deleted == false)
|
||||||
|
{
|
||||||
|
walk.Status = WalkStatus.Confirmed;
|
||||||
|
walk.Confirmed = DateTimeOffset.UtcNow;
|
||||||
|
walk.UpdatedAt = DateTimeOffset.UtcNow;
|
||||||
|
walk.PaymentStatus = PaymentStatus.Paid;
|
||||||
|
await _walkService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
//Wenn der Dogwalker in 30 Minuten mehr als 4 Walks bestätigt bekommt, dann Sperren wegen Betrugsverdacht
|
||||||
|
var numberOfConfirmedWalksTwentyMinutes = await _walkService.CountConfirmedByTimeRangeAsync(walk.DogWalkerId, DateTimeOffset.UtcNow.AddMinutes(-30), DateTimeOffset.UtcNow);
|
||||||
|
if (numberOfConfirmedWalksTwentyMinutes >= 4)
|
||||||
|
{
|
||||||
|
if (dogWalker != null)
|
||||||
|
{
|
||||||
|
dogWalker.Locked = true;
|
||||||
|
dogWalker.LockedReason = "Suspicious behavior - verächtiges Verhalten";
|
||||||
|
dogWalker.LockedUntil = DateTimeOffset.UtcNow.AddYears(5);
|
||||||
|
await AppUserService.CommitAsync("System");
|
||||||
|
|
||||||
|
//Echten Benutzer sperren
|
||||||
|
var user = await _userService.GetByAppUserAsync(dogWalker.Id);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
user.LockoutEnd = DateTimeOffset.UtcNow.AddYears(5);
|
||||||
|
await _userService.CommitAsync("System");
|
||||||
|
await _ticketStore.RemoveAsync(user.UserName);
|
||||||
|
await _refreshTokenService.RemoveAllAsync(user.Id, User.Identity.Name);
|
||||||
|
await _refreshTokenService.CommitAsync("System");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walk.PaymentType == WalkPaymentType.MangoPay)
|
||||||
|
{
|
||||||
|
//Zahlung veranlassen....
|
||||||
|
if (walk.Price > 0)
|
||||||
|
{
|
||||||
|
decimal feeDecimal = 0;
|
||||||
|
long fee = 0;
|
||||||
|
var gehGassiFee = await _transactionFeeService.GetMinGehGassiFeeAsync(walk.Price);
|
||||||
|
if (gehGassiFee != null)
|
||||||
|
{
|
||||||
|
if (gehGassiFee.Percent > 0)
|
||||||
|
{
|
||||||
|
var percent = walk.Price * gehGassiFee.Percent / 100;
|
||||||
|
feeDecimal = percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gehGassiFee.Fixed > 0)
|
||||||
|
{
|
||||||
|
feeDecimal += gehGassiFee.Fixed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (feeDecimal > 0)
|
||||||
|
{
|
||||||
|
fee = (long)(feeDecimal * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Wenn es einen gutschein gibt, dann Geld vom Transferkontos des Gutscheins auf das transferkonto des Hundebesitzers überweisen
|
||||||
|
if (!string.IsNullOrWhiteSpace(walk.VoucherId) && walk.VoucherAmmount > 0)
|
||||||
|
{
|
||||||
|
var voucherUsed = await _voucherCampaignService.GetUsageAsync(walk.VoucherId, walk.DogOwnerId, walk.Id);
|
||||||
|
if (voucherUsed != null)
|
||||||
|
{
|
||||||
|
var ammountFromVoucher = (long)(voucherUsed.VoucherAmmountUsed * 100);
|
||||||
|
voucherUsed.UsageStatus = VoucherUsageStatus.Used;
|
||||||
|
await _voucherCampaignService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
var voucher = await _voucherCampaignService.GetVoucherAsync(voucherUsed.VoucherId);
|
||||||
|
if (voucher != null)
|
||||||
|
{
|
||||||
|
var campaign = await _voucherCampaignService.GetAsync(voucher.VoucherCampaignId);
|
||||||
|
if (campaign != null)
|
||||||
|
{
|
||||||
|
var customer = await _customerService.GetAsync(campaign.CustomerId);
|
||||||
|
if (customer != null)
|
||||||
|
{
|
||||||
|
var dogOwner = await AppUserService.GetAsync(walk.DogOwnerId);
|
||||||
|
if (dogOwner != null)
|
||||||
|
{
|
||||||
|
var wallet = await _walletService.GetAsync(walk.DogOwnerId, WalletType.Fees);
|
||||||
|
if (wallet != null)
|
||||||
|
{
|
||||||
|
var transferResult = await _mangoPayService.TransferMoneyAsync(customer.MangopayPaymentId, campaign.WalletFeeId, dogOwner.PaymentId, wallet.Id, walk.Id, ammountFromVoucher, 0, $"VoucherId_{voucher.Id}_WalkId_{walk.Id}", targetAppUserId: dogOwner.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceWallet = await _walletService.GetAsync(walk.DogOwnerId, WalletType.Fees);
|
||||||
|
var targetWallet = await _walletService.GetAsync(walk.DogWalkerId, WalletType.Credits);
|
||||||
|
if (sourceWallet != null && targetWallet != null)
|
||||||
|
{
|
||||||
|
var sourceUser = await AppUserService.GetAsync(walk.DogOwnerId);
|
||||||
|
var targetUser = await AppUserService.GetAsync(walk.DogWalkerId);
|
||||||
|
|
||||||
|
if (sourceUser != null && targetUser != null)
|
||||||
|
{
|
||||||
|
var ammount = (long)(walk.Price * 100);
|
||||||
|
var transcationSuccess = await _mangoPayService.TransferMoneyAsync(walk.DogOwnerId, walk.DogWalkerId, walk.Id, ammount, fee, $"WalkId_Payment_{walk.Id}");
|
||||||
|
|
||||||
|
//Wallets aktualisieren
|
||||||
|
await _mangoPayService.GetWalletBalanceAsync(sourceUser.Id, WalletType.Credits);
|
||||||
|
await _mangoPayService.GetWalletBalanceAsync(sourceUser.Id, WalletType.Fees);
|
||||||
|
|
||||||
|
await _mangoPayService.GetWalletBalanceAsync(targetUser.Id, WalletType.Credits);
|
||||||
|
await _mangoPayService.GetWalletBalanceAsync(targetUser.Id, WalletType.Fees);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Coins für den Walker gutschreiben
|
||||||
|
var coins = walk.ServiceType switch
|
||||||
|
{
|
||||||
|
WalkServiceType.Walking => _coinsOptions.Value.WalkForDogwalker,
|
||||||
|
WalkServiceType.Sitting => _coinsOptions.Value.SittingForDowgWalker,
|
||||||
|
WalkServiceType.DayCare => _coinsOptions.Value.DayCareForDowgWalker,
|
||||||
|
_ => 0m
|
||||||
|
};
|
||||||
|
await _coinsService.DepositAsync(walk.DogWalkerId, AppUserType.DogWalker, coins, walk.Id);
|
||||||
|
|
||||||
|
//Coins für den Besitzer gutschreiben
|
||||||
|
var coinsOwner = walk.ServiceType switch
|
||||||
|
{
|
||||||
|
WalkServiceType.Walking => _coinsOptions.Value.WalkForOwner,
|
||||||
|
WalkServiceType.Sitting => _coinsOptions.Value.SittingForOwner,
|
||||||
|
WalkServiceType.DayCare => _coinsOptions.Value.DayCareForOwner,
|
||||||
|
_ => 0m
|
||||||
|
};
|
||||||
|
await _coinsService.DepositAsync(walk.DogOwnerId, AppUserType.DogOwner, coinsOwner, walk.Id);
|
||||||
|
|
||||||
|
_systemMessageService.Add(walk.DogWalkerId, AppUserType.DogWalker, walk.Id, SystemMessageTables.Walk, SystemMessageType.WalkConfirmed, DateTimeOffset.UtcNow.AddDays(14));
|
||||||
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
||||||
|
await _appHubSender.SystemMessageAddedAsync(walk.DogWalkerId);
|
||||||
|
await _pushNotificationService.SendWalkConfirmedAsync(walk.DogWalkerId, walk.Id);
|
||||||
|
|
||||||
|
var walkDto = Mapper.Map<WalkDto>(walk);
|
||||||
|
return Ok(walkDto);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Bestätigen eines Walks mit Rating
|
/// Bestätigen eines Walks mit Rating
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -2798,6 +3219,205 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
return NotFound(CommunicationErrors.Common_NotFound);
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bestätigen eines Walks mit Rating
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">WalkConfirmDto</param>
|
||||||
|
/// <returns>HTTP 200 OK, Felher sonst</returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Route("ConfirmWalkWithRating")]
|
||||||
|
[MapToApiVersion(2)]
|
||||||
|
public async Task<IActionResult> ConfirmWalkWithRatingV2(WalkConfirmWithRatingDto model)
|
||||||
|
{
|
||||||
|
var clientOffset = GetClientDateOffset();
|
||||||
|
|
||||||
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var walk = await _walkService.GetAsync(model.WalkId);
|
||||||
|
if (walk != null && walk.DogOwnerId == model.AppUserId)
|
||||||
|
{
|
||||||
|
var appUser = await AppUserService.GetAsync(walk.DogOwnerId);
|
||||||
|
if (appUser is { Locked: true })
|
||||||
|
{
|
||||||
|
return BadRequest(CommunicationErrors.Login_LockedOut);
|
||||||
|
}
|
||||||
|
var dogWalker = await AppUserService.GetAsync(walk.DogWalkerId);
|
||||||
|
if (dogWalker is { Locked: true })
|
||||||
|
{
|
||||||
|
return BadRequest(CommunicationErrors.Login_LockedOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walk.Status == WalkStatus.Completed && walk.Deleted == false)
|
||||||
|
{
|
||||||
|
walk.Status = WalkStatus.Confirmed;
|
||||||
|
walk.Confirmed = DateTimeOffset.UtcNow;
|
||||||
|
walk.UpdatedAt = DateTimeOffset.UtcNow;
|
||||||
|
walk.PaymentStatus = PaymentStatus.Paid;
|
||||||
|
await _walkService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
//Wenn der Dogwalker in 30 Minuten mehr als 4 Walks bestätigt bekommt, dann Sperren wegen Betrugsverdacht
|
||||||
|
var numberOfConfirmedWalksTwentyMinutes = await _walkService.CountConfirmedByTimeRangeAsync(walk.DogWalkerId, DateTimeOffset.UtcNow.AddMinutes(-30), DateTimeOffset.UtcNow);
|
||||||
|
if (numberOfConfirmedWalksTwentyMinutes >= 4)
|
||||||
|
{
|
||||||
|
if (dogWalker != null)
|
||||||
|
{
|
||||||
|
dogWalker.Locked = true;
|
||||||
|
dogWalker.LockedReason = "Suspicious behavior - verächtiges Verhalten";
|
||||||
|
dogWalker.LockedUntil = DateTimeOffset.UtcNow.AddYears(5);
|
||||||
|
await AppUserService.CommitAsync("System");
|
||||||
|
|
||||||
|
//Echten Benutzer sperren
|
||||||
|
var user = await _userService.GetByAppUserAsync(dogWalker.Id);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
user.LockoutEnd = DateTimeOffset.UtcNow.AddYears(5);
|
||||||
|
await _userService.CommitAsync("System");
|
||||||
|
await _ticketStore.RemoveAsync(user.UserName);
|
||||||
|
await _refreshTokenService.RemoveAllAsync(user.Id, User.Identity.Name);
|
||||||
|
await _refreshTokenService.CommitAsync("System");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walk.PaymentType == WalkPaymentType.MangoPay)
|
||||||
|
{
|
||||||
|
//Zahlung veranlassen....
|
||||||
|
if (walk.Price > 0)
|
||||||
|
{
|
||||||
|
decimal feeDecimal = 0;
|
||||||
|
long fee = 0;
|
||||||
|
var gehGassiFee = await _transactionFeeService.GetMinGehGassiFeeAsync(walk.Price);
|
||||||
|
if (gehGassiFee != null)
|
||||||
|
{
|
||||||
|
if (gehGassiFee.Percent > 0)
|
||||||
|
{
|
||||||
|
var percent = walk.Price * gehGassiFee.Percent / 100;
|
||||||
|
feeDecimal = percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gehGassiFee.Fixed > 0)
|
||||||
|
{
|
||||||
|
feeDecimal += gehGassiFee.Fixed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (feeDecimal > 0)
|
||||||
|
{
|
||||||
|
fee = (long)(feeDecimal * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Wenn es einen gutschein gibt, dann Geld vom Transferkontos des Gutscheins auf das transferkonto des Hundebesitzers überweisen
|
||||||
|
if (!string.IsNullOrWhiteSpace(walk.VoucherId) && walk.VoucherAmmount > 0)
|
||||||
|
{
|
||||||
|
var voucherUsed = await _voucherCampaignService.GetUsageAsync(walk.VoucherId, walk.DogOwnerId, walk.Id);
|
||||||
|
if (voucherUsed != null)
|
||||||
|
{
|
||||||
|
var ammountFromVoucher = (long)(voucherUsed.VoucherAmmountUsed * 100);
|
||||||
|
voucherUsed.UsageStatus = VoucherUsageStatus.Used;
|
||||||
|
await _voucherCampaignService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
var voucher = await _voucherCampaignService.GetVoucherAsync(voucherUsed.VoucherId);
|
||||||
|
if (voucher != null)
|
||||||
|
{
|
||||||
|
var campaign = await _voucherCampaignService.GetAsync(voucher.VoucherCampaignId);
|
||||||
|
if (campaign != null)
|
||||||
|
{
|
||||||
|
var customer = await _customerService.GetAsync(campaign.CustomerId);
|
||||||
|
if (customer != null)
|
||||||
|
{
|
||||||
|
var dogOwner = await AppUserService.GetAsync(walk.DogOwnerId);
|
||||||
|
if (dogOwner != null)
|
||||||
|
{
|
||||||
|
var wallet = await _walletService.GetAsync(walk.DogOwnerId, WalletType.Fees);
|
||||||
|
if (wallet != null)
|
||||||
|
{
|
||||||
|
var transferResult = await _mangoPayService.TransferMoneyAsync(customer.MangopayPaymentId, campaign.WalletFeeId, dogOwner.PaymentId, wallet.Id, walk.Id, ammountFromVoucher, 0, $"VoucherId_{voucher.Id}_WalkId_{walk.Id}", targetAppUserId: dogOwner.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceWallet = await _walletService.GetAsync(walk.DogOwnerId, WalletType.Fees);
|
||||||
|
var targetWallet = await _walletService.GetAsync(walk.DogWalkerId, WalletType.Credits);
|
||||||
|
if (sourceWallet != null && targetWallet != null)
|
||||||
|
{
|
||||||
|
var sourceUser = await AppUserService.GetAsync(walk.DogOwnerId);
|
||||||
|
var targetUser = await AppUserService.GetAsync(walk.DogWalkerId);
|
||||||
|
|
||||||
|
if (sourceUser != null && targetUser != null)
|
||||||
|
{
|
||||||
|
var ammount = (long)(walk.Price * 100);
|
||||||
|
var transcationSuccess = await _mangoPayService.TransferMoneyAsync(walk.DogOwnerId, walk.DogWalkerId, walk.Id, ammount, fee, $"WalkId_Payment_{walk.Id}");
|
||||||
|
|
||||||
|
//Wallets aktualisieren
|
||||||
|
await _mangoPayService.GetWalletBalanceAsync(sourceUser.Id, WalletType.Credits);
|
||||||
|
await _mangoPayService.GetWalletBalanceAsync(sourceUser.Id, WalletType.Fees);
|
||||||
|
|
||||||
|
await _mangoPayService.GetWalletBalanceAsync(targetUser.Id, WalletType.Credits);
|
||||||
|
await _mangoPayService.GetWalletBalanceAsync(targetUser.Id, WalletType.Fees);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Coins für den Walker gutschreiben
|
||||||
|
var coins = walk.ServiceType switch
|
||||||
|
{
|
||||||
|
WalkServiceType.Walking => _coinsOptions.Value.WalkForDogwalker,
|
||||||
|
WalkServiceType.Sitting => _coinsOptions.Value.SittingForDowgWalker,
|
||||||
|
WalkServiceType.DayCare => _coinsOptions.Value.DayCareForDowgWalker,
|
||||||
|
_ => 0m
|
||||||
|
};
|
||||||
|
await _coinsService.DepositAsync(walk.DogWalkerId, AppUserType.DogWalker, coins, walk.Id);
|
||||||
|
|
||||||
|
//Coins für den Besitzer gutschreiben
|
||||||
|
var coinsOwner = walk.ServiceType switch
|
||||||
|
{
|
||||||
|
WalkServiceType.Walking => _coinsOptions.Value.WalkForOwner,
|
||||||
|
WalkServiceType.Sitting => _coinsOptions.Value.SittingForOwner,
|
||||||
|
WalkServiceType.DayCare => _coinsOptions.Value.DayCareForOwner,
|
||||||
|
_ => 0m
|
||||||
|
};
|
||||||
|
await _coinsService.DepositAsync(walk.DogOwnerId, AppUserType.DogOwner, coinsOwner, walk.Id);
|
||||||
|
|
||||||
|
//Rating erstellen
|
||||||
|
//var appUser = await AppUserService.GetAsync(walk.DogOwnerId);
|
||||||
|
if (appUser != null)
|
||||||
|
{
|
||||||
|
var rating = _ratingService.Create(walk.DogOwnerId, appUser.Type, walk.DogWalkerId, RatingTarget.Walker, model.RatingPoints, model.RatingInfo);
|
||||||
|
_ratingService.Add(rating);
|
||||||
|
|
||||||
|
await _ratingService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
//Statistik Hundebesitzer aktualisieren
|
||||||
|
await _ratingService.UpdateRatingStatisticsAsync(walk.DogWalkerId, RatingTarget.Walker);
|
||||||
|
await _ratingService.CommitAsync(User.Identity.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
_systemMessageService.Add(walk.DogWalkerId, AppUserType.DogWalker, walk.Id, SystemMessageTables.Walk, SystemMessageType.WalkConfirmed, DateTimeOffset.UtcNow.AddDays(14));
|
||||||
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
||||||
|
await _appHubSender.SystemMessageAddedAsync(walk.DogWalkerId);
|
||||||
|
await _pushNotificationService.SendWalkConfirmedAsync(walk.DogWalkerId, walk.Id);
|
||||||
|
|
||||||
|
var walkDto = Mapper.Map<WalkDto>(walk);
|
||||||
|
return Ok(walkDto);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Zahlungsstatus eines Walks setzen
|
/// Zahlungsstatus eines Walks setzen
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -2947,6 +3567,102 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Anlegen eines Walks wenn DIREKT! buchen möglich ist
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">WalkCreateDto</param>
|
||||||
|
/// <returns>HTTP 200 OK, Felher sonst</returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Route("CreateWalkDirect")]
|
||||||
|
[MapToApiVersion(2)]
|
||||||
|
public async Task<IActionResult> CreateWalkDirectV2(WalkCreateDto model)
|
||||||
|
{
|
||||||
|
var clientOffset = GetClientDateOffset();
|
||||||
|
|
||||||
|
var result = new CreateResponseDto<WalkDto>
|
||||||
|
{
|
||||||
|
Status = CreateStatusDto.Error,
|
||||||
|
Value = null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var appUserId = User.AppUserId();
|
||||||
|
var isLocked = await AppUserService.IsLockedAsync(appUserId);
|
||||||
|
var isBlocked = await AppUserService.IsBlockedAsync(model.DogWalkerId, appUserId);
|
||||||
|
|
||||||
|
var walkPossible = await _walkService.IsWalkPossibleAsync(model.DogWalkerId, model.Start, model.End);
|
||||||
|
if (walkPossible && !isLocked && !isBlocked)
|
||||||
|
{
|
||||||
|
//Nun einen Walk anlgegen!
|
||||||
|
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
|
||||||
|
var geoLocationPickup = geometryFactory.CreatePoint(new Coordinate(model.PickupAddressLng, model.PickupAddressLat));
|
||||||
|
var geoLocationReturn = geometryFactory.CreatePoint(new Coordinate(model.ReturnAddressLng, model.ReturnAddressLat));
|
||||||
|
|
||||||
|
|
||||||
|
var walk = _walkService.Create();
|
||||||
|
walk.Type = (WalkType)model.Type;
|
||||||
|
walk.ServiceType = (WalkServiceType)model.ServiceType;
|
||||||
|
walk.DogWalkerId = model.DogWalkerId;
|
||||||
|
walk.DogOwnerId = model.DogOwnerId;
|
||||||
|
walk.PublicWalkRequestId = string.Empty;
|
||||||
|
walk.DogsJson = model.DogsJson;
|
||||||
|
walk.DogCount = model.DogCount;
|
||||||
|
walk.Start = model.Start;
|
||||||
|
walk.End = model.End;
|
||||||
|
walk.PickupAddress = Mapper.Map<Address>(model.PickupAddress);
|
||||||
|
walk.PickupLocation = geoLocationPickup;
|
||||||
|
walk.ReturnAddress = Mapper.Map<Address>(model.ReturnAddress);
|
||||||
|
walk.ReturnLocation = geoLocationReturn;
|
||||||
|
walk.Price = model.Price;
|
||||||
|
walk.Info = model.Info;
|
||||||
|
walk.Status = WalkStatus.Accepted;
|
||||||
|
walk.Started = null;
|
||||||
|
walk.Completed = null;
|
||||||
|
walk.Confirmed = null;
|
||||||
|
walk.Complained = null;
|
||||||
|
walk.ComplainReason = string.Empty;
|
||||||
|
walk.DeclinedReason = string.Empty;
|
||||||
|
walk.CancelledReason = string.Empty;
|
||||||
|
walk.CancelledBy = CancellationSource.None;
|
||||||
|
walk.CompletedInfo = string.Empty;
|
||||||
|
walk.Defactation = false;
|
||||||
|
walk.PaymentStatus = PaymentStatus.Pending;
|
||||||
|
walk.PaymentType = model.PaymentType != null ? (WalkPaymentType)model.PaymentType : WalkPaymentType.MangoPay;
|
||||||
|
walk.UpdatedAt = DateTimeOffset.UtcNow;
|
||||||
|
walk.Created = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
if (walk.Price == 0 || walk.PaymentType == WalkPaymentType.Cash)
|
||||||
|
walk.PaymentStatus = PaymentStatus.Authorized;
|
||||||
|
|
||||||
|
_walkService.Add(walk);
|
||||||
|
await _walkService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
//Überlappende Walks die im Status "Request" sind, stornieren
|
||||||
|
if (walk.PaymentStatus is PaymentStatus.Authorized or PaymentStatus.Paid)
|
||||||
|
{
|
||||||
|
//Wenn der Preis eines Walks 0 ist, dann wird dieser direkt angelegt und gilt.
|
||||||
|
await _walkService.CancelWalkRequestsAsync(walk.DogWalkerId, walk.Start, walk.End);
|
||||||
|
await _walkService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
_systemMessageService.Add(walk.DogWalkerId, AppUserType.DogWalker, walk.Id, SystemMessageTables.Walk, SystemMessageType.WalkAdded, DateTimeOffset.UtcNow.AddDays(14));
|
||||||
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
||||||
|
await _appHubSender.SystemMessageAddedAsync(walk.DogWalkerId);
|
||||||
|
await _pushNotificationService.SendNewWalkAsync(walk.DogWalkerId, walk.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Status = CreateStatusDto.Success;
|
||||||
|
result.Value = Mapper.Map<WalkDto>(walk);
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
return NotFound(CommunicationErrors.Walk_NotPossible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Anlegen eines Walks als Anfrage
|
/// Anlegen eines Walks als Anfrage
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -3031,6 +3747,92 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Anlegen eines Walks als Anfrage
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">WalkCreateDto</param>
|
||||||
|
/// <returns>HTTP 200 OK, Felher sonst</returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Route("CreateWalkRequest")]
|
||||||
|
[MapToApiVersion(2)]
|
||||||
|
public async Task<IActionResult> CreateWalkRequestV2(WalkCreateDto model)
|
||||||
|
{
|
||||||
|
var clientOffset = GetClientDateOffset();
|
||||||
|
|
||||||
|
var result = new CreateResponseDto<WalkDto>
|
||||||
|
{
|
||||||
|
Status = CreateStatusDto.Error,
|
||||||
|
Value = null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var appUserId = User.AppUserId();
|
||||||
|
var isLocked = await AppUserService.IsLockedAsync(appUserId);
|
||||||
|
var isBlocked = await AppUserService.IsBlockedAsync(model.DogWalkerId, appUserId);
|
||||||
|
|
||||||
|
var walkPossible = await _walkService.IsWalkPossibleAsync(model.DogWalkerId, model.Start, model.End);
|
||||||
|
if (walkPossible && !isLocked && !isBlocked)
|
||||||
|
{
|
||||||
|
//Nun einen Walk anlgegen!
|
||||||
|
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
|
||||||
|
var geoLocationPickup = geometryFactory.CreatePoint(new Coordinate(model.PickupAddressLng, model.PickupAddressLat));
|
||||||
|
var geoLocationReturn = geometryFactory.CreatePoint(new Coordinate(model.ReturnAddressLng, model.ReturnAddressLat));
|
||||||
|
|
||||||
|
|
||||||
|
var walk = _walkService.Create();
|
||||||
|
walk.Type = (WalkType)model.Type;
|
||||||
|
walk.ServiceType = (WalkServiceType)model.ServiceType;
|
||||||
|
walk.DogWalkerId = model.DogWalkerId;
|
||||||
|
walk.DogOwnerId = model.DogOwnerId;
|
||||||
|
walk.PublicWalkRequestId = string.Empty;
|
||||||
|
walk.DogsJson = model.DogsJson;
|
||||||
|
walk.DogCount = model.DogCount;
|
||||||
|
walk.Start = model.Start;
|
||||||
|
walk.End = model.End;
|
||||||
|
walk.PickupAddress = Mapper.Map<Address>(model.PickupAddress);
|
||||||
|
walk.PickupLocation = geoLocationPickup;
|
||||||
|
walk.ReturnAddress = Mapper.Map<Address>(model.ReturnAddress);
|
||||||
|
walk.ReturnLocation = geoLocationReturn;
|
||||||
|
walk.Price = model.Price;
|
||||||
|
walk.Info = model.Info;
|
||||||
|
walk.Status = WalkStatus.Requested;
|
||||||
|
walk.Started = null;
|
||||||
|
walk.Completed = null;
|
||||||
|
walk.Confirmed = null;
|
||||||
|
walk.Complained = null;
|
||||||
|
walk.ComplainReason = string.Empty;
|
||||||
|
walk.DeclinedReason = string.Empty;
|
||||||
|
walk.CancelledReason = string.Empty;
|
||||||
|
walk.CancelledBy = CancellationSource.None;
|
||||||
|
walk.CompletedInfo = string.Empty;
|
||||||
|
walk.Defactation = false;
|
||||||
|
walk.PaymentStatus = PaymentStatus.None;
|
||||||
|
walk.PaymentType = model.PaymentType != null ? (WalkPaymentType)model.PaymentType : WalkPaymentType.MangoPay;
|
||||||
|
walk.UpdatedAt = DateTimeOffset.UtcNow;
|
||||||
|
walk.Created = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
_walkService.Add(walk);
|
||||||
|
await _walkService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
_systemMessageService.Add(walk.DogWalkerId, AppUserType.DogWalker, walk.Id, SystemMessageTables.Walk, SystemMessageType.WalkRequested, DateTimeOffset.UtcNow.AddDays(14));
|
||||||
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
||||||
|
await _appHubSender.SystemMessageAddedAsync(walk.DogWalkerId);
|
||||||
|
await _pushNotificationService.SendWalkRequestedAsync(walk.DogWalkerId, walk.Id);
|
||||||
|
|
||||||
|
result.Status = CreateStatusDto.Success;
|
||||||
|
result.Value = Mapper.Map<WalkDto>(walk);
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NotFound(CommunicationErrors.Walk_NotPossible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Akzeptieren eines Walks
|
/// Akzeptieren eines Walks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -3071,6 +3873,47 @@ namespace gehGassi.Web.Controllers.Api
|
|||||||
return NotFound(CommunicationErrors.Common_NotFound);
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Akzeptieren eines Walks
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">WalkAcceptDto</param>
|
||||||
|
/// <returns>HTTP 200 OK, Felher sonst</returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Route("AcceptWalk")]
|
||||||
|
[MapToApiVersion(2)]
|
||||||
|
public async Task<IActionResult> AcceptWalkV2(WalkAcceptDto model)
|
||||||
|
{
|
||||||
|
var clientOffset = GetClientDateOffset();
|
||||||
|
|
||||||
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var walk = await _walkService.GetAsync(model.WalkId);
|
||||||
|
if (walk != null)
|
||||||
|
{
|
||||||
|
walk.Status = WalkStatus.Accepted;
|
||||||
|
walk.PaymentStatus = PaymentStatus.Pending;
|
||||||
|
walk.UpdatedAt = model.UpdatedAt;
|
||||||
|
if (walk.Price == 0 || walk.PaymentType == WalkPaymentType.Cash)
|
||||||
|
walk.PaymentStatus = PaymentStatus.Authorized;
|
||||||
|
|
||||||
|
await _walkService.CommitAsync(User.Identity.Name);
|
||||||
|
|
||||||
|
_systemMessageService.Add(walk.DogOwnerId, AppUserType.DogOwner, walk.Id, SystemMessageTables.Walk, SystemMessageType.WalkAccepted, DateTimeOffset.UtcNow.AddDays(14));
|
||||||
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
||||||
|
await _appHubSender.SystemMessageAddedAsync(walk.DogOwnerId);
|
||||||
|
await _pushNotificationService.SendWalkAcceptedAsync(walk.DogOwnerId, walk.Id);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
||||||
|
}
|
||||||
|
return NotFound(CommunicationErrors.Common_NotFound);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ablehnen eines Walks
|
/// Ablehnen eines Walks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -98,6 +98,8 @@ namespace gehGassi.Web.Controllers
|
|||||||
whereFilterPredicate.value = (WalkStatus)((int)((long)whereFilterPredicate.value));
|
whereFilterPredicate.value = (WalkStatus)((int)((long)whereFilterPredicate.value));
|
||||||
if (whereFilterPredicate.Field == "paymentStatus")
|
if (whereFilterPredicate.Field == "paymentStatus")
|
||||||
whereFilterPredicate.value = (PaymentStatus)((int)((long)whereFilterPredicate.value));
|
whereFilterPredicate.value = (PaymentStatus)((int)((long)whereFilterPredicate.value));
|
||||||
|
if (whereFilterPredicate.Field == "paymentType")
|
||||||
|
whereFilterPredicate.value = (WalkPaymentType)((int)((long)whereFilterPredicate.value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,6 +122,7 @@ namespace gehGassi.Web.Controllers
|
|||||||
itemVm.ServiceTypeText = itemVm.ServiceType.GetDisplayName(AnnotationsLocalizer);
|
itemVm.ServiceTypeText = itemVm.ServiceType.GetDisplayName(AnnotationsLocalizer);
|
||||||
itemVm.StatusText = itemVm.Status.GetDisplayName(AnnotationsLocalizer);
|
itemVm.StatusText = itemVm.Status.GetDisplayName(AnnotationsLocalizer);
|
||||||
itemVm.PaymentStatusText = itemVm.PaymentStatus.GetDisplayName(AnnotationsLocalizer);
|
itemVm.PaymentStatusText = itemVm.PaymentStatus.GetDisplayName(AnnotationsLocalizer);
|
||||||
|
itemVm.PaymentTypeText = itemVm.PaymentType.GetDisplayName(AnnotationsLocalizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
//FilterPreview?
|
//FilterPreview?
|
||||||
|
|||||||
@ -135,6 +135,9 @@ namespace gehGassi.Web.Mapper
|
|||||||
CreateMap<PaymentStatus, PaymentStatusVm>();
|
CreateMap<PaymentStatus, PaymentStatusVm>();
|
||||||
CreateMap<PaymentStatusVm, PaymentStatus>();
|
CreateMap<PaymentStatusVm, PaymentStatus>();
|
||||||
|
|
||||||
|
CreateMap<WalkPaymentType, WalkPaymentTypeVm>();
|
||||||
|
CreateMap<WalkPaymentTypeVm, WalkPaymentType>();
|
||||||
|
|
||||||
CreateMap<OrderStatus, OrderStatusVm>();
|
CreateMap<OrderStatus, OrderStatusVm>();
|
||||||
CreateMap<OrderStatusVm, OrderStatus>();
|
CreateMap<OrderStatusVm, OrderStatus>();
|
||||||
|
|
||||||
@ -638,6 +641,9 @@ namespace gehGassi.Web.Mapper
|
|||||||
CreateMap<PaymentStatus, PaymentStatusDto>();
|
CreateMap<PaymentStatus, PaymentStatusDto>();
|
||||||
CreateMap<PaymentStatusDto, PaymentStatus>();
|
CreateMap<PaymentStatusDto, PaymentStatus>();
|
||||||
|
|
||||||
|
CreateMap<WalkPaymentType, WalkPaymentTypeDto>();
|
||||||
|
CreateMap<WalkPaymentTypeDto, WalkPaymentType>();
|
||||||
|
|
||||||
CreateMap<RatingTarget, RatingTargetDto>();
|
CreateMap<RatingTarget, RatingTargetDto>();
|
||||||
CreateMap<RatingTargetDto, RatingTarget>();
|
CreateMap<RatingTargetDto, RatingTarget>();
|
||||||
|
|
||||||
|
|||||||
@ -378,6 +378,23 @@ namespace gehGassi.Web.Models
|
|||||||
RefundendAndPayed = 60
|
RefundendAndPayed = 60
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zahlungsart für einen Walk
|
||||||
|
/// </summary>
|
||||||
|
public enum WalkPaymentTypeVm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Mit MangoPay bezahlen (z.B. Kreditkarte)
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "WalkPaymentType_MangoPay")]
|
||||||
|
MangoPay = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// Barzahlung
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "WalkPaymentType_Cash")]
|
||||||
|
Cash = 10
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Status einer Bestellung
|
/// Status einer Bestellung
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -220,6 +220,11 @@ namespace gehGassi.Web.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public PaymentStatusVm PaymentStatus { get; set; }
|
public PaymentStatusVm PaymentStatus { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zahlungsart des Walks
|
||||||
|
/// </summary>
|
||||||
|
public WalkPaymentTypeVm PaymentType { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -380,6 +385,16 @@ namespace gehGassi.Web.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string PaymentStatusText { get; set; }
|
public string PaymentStatusText { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Welche Art von Bezahlung wurde verwendet
|
||||||
|
/// </summary>
|
||||||
|
public WalkPaymentTypeVm PaymentType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Welche Art von Bezahlung wurde verwendet
|
||||||
|
/// </summary>
|
||||||
|
public string PaymentTypeText { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -229,7 +229,15 @@ export enum PaymentStatus {
|
|||||||
/**Entwertet */
|
/**Entwertet */
|
||||||
Voided = 50,
|
Voided = 50,
|
||||||
/**Rückerstattet gehgassi */
|
/**Rückerstattet gehgassi */
|
||||||
RefundendAndPayed = 60,
|
RefundendAndPayed = 60
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Zahlungsarten Walk */
|
||||||
|
export enum WalkPaymentType {
|
||||||
|
/**MangoPay */
|
||||||
|
MangoPay = 1,
|
||||||
|
/**Cash */
|
||||||
|
Cash = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Geoeinschränkungen für Listungen und Werbungen */
|
/**Geoeinschränkungen für Listungen und Werbungen */
|
||||||
@ -2473,6 +2481,9 @@ export class WalkWithNamesListItem extends SyncEntity {
|
|||||||
/**Zahlungsstatus des Walks */
|
/**Zahlungsstatus des Walks */
|
||||||
paymentStatus: PaymentStatus;
|
paymentStatus: PaymentStatus;
|
||||||
|
|
||||||
|
/**Zahlungsart des Walks */
|
||||||
|
paymentType: WalkPaymentType;
|
||||||
|
|
||||||
/**Datum der Erstellung des Walks */
|
/**Datum der Erstellung des Walks */
|
||||||
created: Date | string;
|
created: Date | string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import WalkType = Models.WalkType;
|
|||||||
import WalkStatus = Models.WalkStatus;
|
import WalkStatus = Models.WalkStatus;
|
||||||
import WalkServiceType = Models.WalkServiceType;
|
import WalkServiceType = Models.WalkServiceType;
|
||||||
import PaymentStatus = Models.PaymentStatus;
|
import PaymentStatus = Models.PaymentStatus;
|
||||||
|
import WalkPaymentType = Models.WalkPaymentType;
|
||||||
|
|
||||||
|
|
||||||
class WalksModule {
|
class WalksModule {
|
||||||
@ -40,6 +41,9 @@ class WalksModule {
|
|||||||
private _paymentStatusList;
|
private _paymentStatusList;
|
||||||
private _filterPaymentStatus: DropDownList;
|
private _filterPaymentStatus: DropDownList;
|
||||||
|
|
||||||
|
private _paymentTypeList;
|
||||||
|
private _filterPaymentType: DropDownList;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._global = Global.getInstance();
|
this._global = Global.getInstance();
|
||||||
this._eventManager = EventManager.getInstance();
|
this._eventManager = EventManager.getInstance();
|
||||||
@ -95,6 +99,10 @@ class WalksModule {
|
|||||||
{ value: PaymentStatus.Voided, text: self._localizationMananger.get("PaymentStatus_Voided") },
|
{ value: PaymentStatus.Voided, text: self._localizationMananger.get("PaymentStatus_Voided") },
|
||||||
{ value: PaymentStatus.RefundendAndPayed, text: self._localizationMananger.get("PaymentStatus_RefundendAndPayed") }];
|
{ value: PaymentStatus.RefundendAndPayed, text: self._localizationMananger.get("PaymentStatus_RefundendAndPayed") }];
|
||||||
|
|
||||||
|
self._paymentTypeList = [
|
||||||
|
{ value: WalkPaymentType.MangoPay, text: self._localizationMananger.get("WalkPaymentType_MangoPay")},
|
||||||
|
{ value: WalkPaymentType.Cash, text: self._localizationMananger.get("WalkPaymentType_Cash") }];
|
||||||
|
|
||||||
self._dataManager = new DataManager({
|
self._dataManager = new DataManager({
|
||||||
url: <string>$(self.prefix("#jsGetUrl")).val(),
|
url: <string>$(self.prefix("#jsGetUrl")).val(),
|
||||||
adaptor: new UrlAdaptor(),
|
adaptor: new UrlAdaptor(),
|
||||||
@ -201,6 +209,32 @@ class WalksModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: "paymentType", headerText: self._localizationMananger.get("Walk_PaymentType"), type: "number", template: "${paymentTypeText}",
|
||||||
|
filter: {
|
||||||
|
ui: {
|
||||||
|
create: (args: { target: Element, column: Object }) => {
|
||||||
|
let flValInput: HTMLElement = createElement("input", { className: "flm-input" });
|
||||||
|
args.target.appendChild(flValInput);
|
||||||
|
self._filterPaymentType = new DropDownList({
|
||||||
|
dataSource: new DataManager(self._paymentTypeList),
|
||||||
|
fields: { text: "text", value: "value" },
|
||||||
|
placeholder: self._localizationMananger.get("Common_Select"),
|
||||||
|
popupHeight: "200px"
|
||||||
|
});
|
||||||
|
self._filterPaymentType.appendTo(flValInput);
|
||||||
|
},
|
||||||
|
write: (args: {
|
||||||
|
column: Object, target: Element, parent: any, filteredValue: number | string
|
||||||
|
}) => {
|
||||||
|
self._filterPaymentType.value = args.filteredValue;
|
||||||
|
},
|
||||||
|
read: (args: { target: Element, column: any, operator: string, fltrObj: Filter }) => {
|
||||||
|
args.fltrObj.filterByColumn(args.column.field, args.operator, self._filterPaymentType.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: "paymentStatus", headerText: self._localizationMananger.get("Walk_PaymentStatus"), type: "number", template: "${paymentStatusText}",
|
field: "paymentStatus", headerText: self._localizationMananger.get("Walk_PaymentStatus"), type: "number", template: "${paymentStatusText}",
|
||||||
filter: {
|
filter: {
|
||||||
|
|||||||
@ -65,6 +65,13 @@
|
|||||||
<div class="h5 mb-1">@annotationsLocalizer["Walk_Status"]</div>
|
<div class="h5 mb-1">@annotationsLocalizer["Walk_Status"]</div>
|
||||||
@Model.Status.GetDisplayName(annotationsLocalizer)
|
@Model.Status.GetDisplayName(annotationsLocalizer)
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<div class="h5 mb-1">@annotationsLocalizer["Walk_PaymentType"]</div>
|
||||||
|
@Model.PaymentType.GetDisplayName(annotationsLocalizer)
|
||||||
|
</div>
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<div class="h5 mb-1">@annotationsLocalizer["Walk_PaymentStatus"]</div>
|
<div class="h5 mb-1">@annotationsLocalizer["Walk_PaymentStatus"]</div>
|
||||||
@Model.PaymentStatus.GetDisplayName(annotationsLocalizer)
|
@Model.PaymentStatus.GetDisplayName(annotationsLocalizer)
|
||||||
|
|||||||
@ -22,10 +22,10 @@
|
|||||||
"LicenseOptions": {
|
"LicenseOptions": {
|
||||||
"Address": "https://gehgassi.com",
|
"Address": "https://gehgassi.com",
|
||||||
"Software": "gehgassi",
|
"Software": "gehgassi",
|
||||||
"Version": "1.0.99"
|
"Version": "1.0.100"
|
||||||
},
|
},
|
||||||
"SystemJsOptions": {
|
"SystemJsOptions": {
|
||||||
"FileVersion": "1.0.99"
|
"FileVersion": "1.0.100"
|
||||||
},
|
},
|
||||||
"SessionSettings": {
|
"SessionSettings": {
|
||||||
"TimeOut": "60",
|
"TimeOut": "60",
|
||||||
|
|||||||
@ -23,10 +23,10 @@
|
|||||||
"LicenseOptions": {
|
"LicenseOptions": {
|
||||||
"Address": "https://creativeBITS.com",
|
"Address": "https://creativeBITS.com",
|
||||||
"Software": "gehgassi",
|
"Software": "gehgassi",
|
||||||
"Version": "1.0.99"
|
"Version": "1.0.100"
|
||||||
},
|
},
|
||||||
"SystemJsOptions": {
|
"SystemJsOptions": {
|
||||||
"FileVersion": "1.0.99"
|
"FileVersion": "1.0.100"
|
||||||
},
|
},
|
||||||
"SessionSettings": {
|
"SessionSettings": {
|
||||||
"TimeOut": "60",
|
"TimeOut": "60",
|
||||||
|
|||||||
@ -22,10 +22,10 @@
|
|||||||
"LicenseOptions": {
|
"LicenseOptions": {
|
||||||
"Address": "https://gehGassi.creativeBITS.eu",
|
"Address": "https://gehGassi.creativeBITS.eu",
|
||||||
"Software": "gehgassi",
|
"Software": "gehgassi",
|
||||||
"Version": "1.0.99"
|
"Version": "1.0.100"
|
||||||
},
|
},
|
||||||
"SystemJsOptions": {
|
"SystemJsOptions": {
|
||||||
"FileVersion": "1.0.99"
|
"FileVersion": "1.0.100"
|
||||||
},
|
},
|
||||||
"SessionSettings": {
|
"SessionSettings": {
|
||||||
"TimeOut": "60",
|
"TimeOut": "60",
|
||||||
|
|||||||
@ -23,10 +23,10 @@
|
|||||||
"LicenseOptions": {
|
"LicenseOptions": {
|
||||||
"Address": "https://creativeBITS.com",
|
"Address": "https://creativeBITS.com",
|
||||||
"Software": "gehgassi",
|
"Software": "gehgassi",
|
||||||
"Version": "1.0.99"
|
"Version": "1.0.100"
|
||||||
},
|
},
|
||||||
"SystemJsOptions": {
|
"SystemJsOptions": {
|
||||||
"FileVersion": "1.0.99"
|
"FileVersion": "1.0.100"
|
||||||
},
|
},
|
||||||
"SessionSettings": {
|
"SessionSettings": {
|
||||||
"TimeOut": "60",
|
"TimeOut": "60",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user