Yeni Müşteri ve Eski Müşteri Sipariş ayrımı
This commit is contained in:
parent
bab639ce63
commit
5c9c99206c
20 changed files with 1819 additions and 120 deletions
|
|
@ -9,6 +9,9 @@ public class CountryDto : AuditedEntityDto<string>
|
||||||
public string GroupName { get; set; }
|
public string GroupName { get; set; }
|
||||||
public string Currency { get; set; }
|
public string Currency { get; set; }
|
||||||
public int PhoneCode { get; set; }
|
public int PhoneCode { get; set; }
|
||||||
|
public int? PhoneNumberMinLength { get; set; }
|
||||||
|
public int? PhoneNumberMaxLength { get; set; }
|
||||||
|
public string? PhoneNumberFormat { get; set; }
|
||||||
public string TaxLabel { get; set; }
|
public string TaxLabel { get; set; }
|
||||||
public bool ZipRequired { get; set; }
|
public bool ZipRequired { get; set; }
|
||||||
public bool StateRequired { get; set; }
|
public bool StateRequired { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@ public class OrderDto : EntityDto<Guid>
|
||||||
|
|
||||||
public List<OrderItemDto> Items { get; set; }
|
public List<OrderItemDto> Items { get; set; }
|
||||||
|
|
||||||
|
public string BillingCycle { get; set; }
|
||||||
|
public int Period { get; set; }
|
||||||
|
public DateTime? LicenseStartTime { get; set; }
|
||||||
|
public DateTime? LicenseStopTime { get; set; }
|
||||||
|
|
||||||
public decimal Subtotal { get; set; }
|
public decimal Subtotal { get; set; }
|
||||||
public decimal Commission { get; set; }
|
public decimal Commission { get; set; }
|
||||||
public decimal Total { get; set; }
|
public decimal Total { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ public class CustomTenantDto
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool IsActive { get; set; }
|
public bool IsActive { get; set; }
|
||||||
|
public bool IsExisting { get; set; }
|
||||||
|
|
||||||
public Guid? Id { get; set; }
|
public Guid? Id { get; set; }
|
||||||
public string OrganizationName { get; set; }
|
public string OrganizationName { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,10 @@ public partial class CreateUpdateOrganizationUnitDtoToOrganizationUnitMapper : M
|
||||||
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
|
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
|
||||||
public partial class TenantToCustomTenantDtoMapper : MapperBase<Tenant, CustomTenantDto>
|
public partial class TenantToCustomTenantDtoMapper : MapperBase<Tenant, CustomTenantDto>
|
||||||
{
|
{
|
||||||
|
[MapperIgnoreTarget(nameof(CustomTenantDto.IsExisting))]
|
||||||
public override partial CustomTenantDto Map(Tenant source);
|
public override partial CustomTenantDto Map(Tenant source);
|
||||||
|
|
||||||
|
[MapperIgnoreTarget(nameof(CustomTenantDto.IsExisting))]
|
||||||
public override partial void Map(Tenant source, CustomTenantDto destination);
|
public override partial void Map(Tenant source, CustomTenantDto destination);
|
||||||
|
|
||||||
public override void BeforeMap(Tenant source)
|
public override void BeforeMap(Tenant source)
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ public class PublicAppService : PlatformAppService
|
||||||
private readonly IRepository<Home, Guid> _homeRepository;
|
private readonly IRepository<Home, Guid> _homeRepository;
|
||||||
private readonly IRepository<Contact, Guid> _contactRepository;
|
private readonly IRepository<Contact, Guid> _contactRepository;
|
||||||
private readonly IRepository<Country, string> _countryRepository;
|
private readonly IRepository<Country, string> _countryRepository;
|
||||||
|
private readonly IRepository<City, Guid> _cityRepository;
|
||||||
|
private readonly IRepository<District, Guid> _districtRepository;
|
||||||
private readonly IIdentityUserRepository _identityUserRepository;
|
private readonly IIdentityUserRepository _identityUserRepository;
|
||||||
private readonly IRepository<LanguageKey, Guid> _languageKeyRepository;
|
private readonly IRepository<LanguageKey, Guid> _languageKeyRepository;
|
||||||
private readonly IRepository<LanguageText, Guid> _languageTextRepository;
|
private readonly IRepository<LanguageText, Guid> _languageTextRepository;
|
||||||
|
|
@ -54,6 +56,8 @@ public class PublicAppService : PlatformAppService
|
||||||
IRepository<Home, Guid> homeRepository,
|
IRepository<Home, Guid> homeRepository,
|
||||||
IRepository<Contact, Guid> contactRepository,
|
IRepository<Contact, Guid> contactRepository,
|
||||||
IRepository<Country, string> countryRepository,
|
IRepository<Country, string> countryRepository,
|
||||||
|
IRepository<City, Guid> cityRepository,
|
||||||
|
IRepository<District, Guid> districtRepository,
|
||||||
IIdentityUserRepository identityUserRepository,
|
IIdentityUserRepository identityUserRepository,
|
||||||
IRepository<LanguageKey, Guid> languageKeyRepository,
|
IRepository<LanguageKey, Guid> languageKeyRepository,
|
||||||
IRepository<LanguageText, Guid> languageTextRepository,
|
IRepository<LanguageText, Guid> languageTextRepository,
|
||||||
|
|
@ -78,6 +82,8 @@ public class PublicAppService : PlatformAppService
|
||||||
_languageTextRepository = languageTextRepository;
|
_languageTextRepository = languageTextRepository;
|
||||||
_languageTextAppService = languageTextAppService;
|
_languageTextAppService = languageTextAppService;
|
||||||
_countryRepository = countryRepository;
|
_countryRepository = countryRepository;
|
||||||
|
_cityRepository = cityRepository;
|
||||||
|
_districtRepository = districtRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<ServiceDto>> GetServicesListAsync()
|
public async Task<List<ServiceDto>> GetServicesListAsync()
|
||||||
|
|
@ -457,10 +463,14 @@ public class PublicAppService : PlatformAppService
|
||||||
|
|
||||||
public async Task<OrderDto> CreateOrderAsync(OrderDto input)
|
public async Task<OrderDto> CreateOrderAsync(OrderDto input)
|
||||||
{
|
{
|
||||||
|
var billingCycle = input.BillingCycle.IsNullOrWhiteSpace() ? "yearly" : input.BillingCycle;
|
||||||
|
var period = input.Period > 0 ? input.Period : 1;
|
||||||
|
|
||||||
var entity = new Order()
|
var entity = new Order()
|
||||||
{
|
{
|
||||||
Name = input.Tenant.Name,
|
Name = input.Tenant.Name,
|
||||||
IsActive = input.Tenant.IsActive,
|
IsActive = input.Tenant.IsActive,
|
||||||
|
IsExisting = input.Tenant.IsExisting,
|
||||||
|
|
||||||
OrganizationName = input.Tenant.OrganizationName,
|
OrganizationName = input.Tenant.OrganizationName,
|
||||||
Founder = input.Tenant.Founder,
|
Founder = input.Tenant.Founder,
|
||||||
|
|
@ -479,6 +489,10 @@ public class PublicAppService : PlatformAppService
|
||||||
Website = input.Tenant.Website,
|
Website = input.Tenant.Website,
|
||||||
MenuGroup = input.Tenant.MenuGroup,
|
MenuGroup = input.Tenant.MenuGroup,
|
||||||
|
|
||||||
|
BillingCycle = billingCycle,
|
||||||
|
Period = period,
|
||||||
|
LicenseStartTime = input.LicenseStartTime,
|
||||||
|
LicenseStopTime = input.LicenseStopTime,
|
||||||
Subtotal = input.Subtotal,
|
Subtotal = input.Subtotal,
|
||||||
Commission = input.Commission,
|
Commission = input.Commission,
|
||||||
Total = input.Total,
|
Total = input.Total,
|
||||||
|
|
@ -526,9 +540,75 @@ public class PublicAppService : PlatformAppService
|
||||||
|
|
||||||
public async Task<List<CountryDto>> GetCountryAsync()
|
public async Task<List<CountryDto>> GetCountryAsync()
|
||||||
{
|
{
|
||||||
var entities = await _countryRepository.GetListAsync() ?? throw new EntityNotFoundException(typeof(Country));
|
var queryable = await _countryRepository.GetQueryableAsync();
|
||||||
|
|
||||||
return ObjectMapper.Map<List<Country>, List<CountryDto>>(entities);
|
return await AsyncExecuter.ToListAsync(
|
||||||
|
queryable
|
||||||
|
.OrderBy(country => country.Name)
|
||||||
|
.Select(country => new CountryDto
|
||||||
|
{
|
||||||
|
Id = country.Id,
|
||||||
|
Name = country.Name,
|
||||||
|
GroupName = country.GroupName,
|
||||||
|
Currency = country.Currency,
|
||||||
|
PhoneCode = country.PhoneCode,
|
||||||
|
PhoneNumberMinLength = country.PhoneNumberMinLength,
|
||||||
|
PhoneNumberMaxLength = country.PhoneNumberMaxLength,
|
||||||
|
PhoneNumberFormat = country.PhoneNumberFormat,
|
||||||
|
TaxLabel = country.TaxLabel,
|
||||||
|
ZipRequired = country.ZipRequired,
|
||||||
|
StateRequired = country.StateRequired,
|
||||||
|
Cities = new List<CityDto>()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<CityDto>> GetCityAsync(string country)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(country))
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var queryable = await _cityRepository.GetQueryableAsync();
|
||||||
|
|
||||||
|
return await AsyncExecuter.ToListAsync(
|
||||||
|
queryable
|
||||||
|
.Where(city => city.Country == country)
|
||||||
|
.OrderBy(city => city.Name)
|
||||||
|
.Select(city => new CityDto
|
||||||
|
{
|
||||||
|
Id = city.Id,
|
||||||
|
Country = city.Country,
|
||||||
|
Name = city.Name,
|
||||||
|
PlateCode = city.PlateCode
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<DistrictDto>> GetDistrictAsync(string country, string city)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(country) || string.IsNullOrWhiteSpace(city))
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var queryable = await _districtRepository.GetQueryableAsync();
|
||||||
|
var entities = await AsyncExecuter.ToListAsync(
|
||||||
|
queryable
|
||||||
|
.Where(district => district.Country == country && district.City == city)
|
||||||
|
.OrderBy(district => district.Name));
|
||||||
|
|
||||||
|
return entities
|
||||||
|
.GroupBy(district => district.Name, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.Select(group => group.First())
|
||||||
|
.Select(district => new DistrictDto
|
||||||
|
{
|
||||||
|
Id = district.Id,
|
||||||
|
Country = district.Country,
|
||||||
|
City = district.City,
|
||||||
|
Name = district.Name,
|
||||||
|
Township = district.Township
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SaveContactPageAsync(SaveContactPageInput input)
|
public async Task SaveContactPageAsync(SaveContactPageInput input)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -248,6 +248,9 @@ public class HostDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
groupName,
|
groupName,
|
||||||
item.Currency,
|
item.Currency,
|
||||||
item.PhoneCode,
|
item.PhoneCode,
|
||||||
|
item.PhoneNumberMinLength,
|
||||||
|
item.PhoneNumberMaxLength,
|
||||||
|
item.PhoneNumberFormat,
|
||||||
item.TaxLabel
|
item.TaxLabel
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13758,6 +13758,24 @@
|
||||||
"en": "Billing Cycle",
|
"en": "Billing Cycle",
|
||||||
"tr": "Fatura Döngüsü"
|
"tr": "Fatura Döngüsü"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.Period",
|
||||||
|
"en": "Period",
|
||||||
|
"tr": "Periyot"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.LicenseStartTime",
|
||||||
|
"en": "License Start Time",
|
||||||
|
"tr": "Lisans Başlangıç Tarihi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.LicenseStopTime",
|
||||||
|
"en": "License Stop Time",
|
||||||
|
"tr": "Lisans Bitiş Tarihi"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Listform.ListformField.Abbreviation",
|
"key": "App.Listform.ListformField.Abbreviation",
|
||||||
|
|
@ -16068,6 +16086,24 @@
|
||||||
"en": "Phone Code",
|
"en": "Phone Code",
|
||||||
"tr": "Telefon Kodu"
|
"tr": "Telefon Kodu"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.PhoneNumberMinLength",
|
||||||
|
"en": "Phone Number Min Length",
|
||||||
|
"tr": "Telefon Numarası Minimum Uzunluk"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.PhoneNumberMaxLength",
|
||||||
|
"en": "Phone Number Max Length",
|
||||||
|
"tr": "Telefon Numarası Maksimum Uzunluk"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.PhoneNumberFormat",
|
||||||
|
"en": "Phone Number Format",
|
||||||
|
"tr": "Telefon Numarası Formatı"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Listform.ListformField.Place",
|
"key": "App.Listform.ListformField.Place",
|
||||||
|
|
@ -16140,6 +16176,12 @@
|
||||||
"en": "Postal Code",
|
"en": "Postal Code",
|
||||||
"tr": "Posta Kodu"
|
"tr": "Posta Kodu"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.IsExisting",
|
||||||
|
"en": "Existing Customer",
|
||||||
|
"tr": "Mevcut Musteri"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Listform.ListformField.Priority",
|
"key": "App.Listform.ListformField.Priority",
|
||||||
|
|
|
||||||
|
|
@ -1766,9 +1766,12 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
new EditingFormItemDto { Order = 3, DataField = "GroupName", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
new EditingFormItemDto { Order = 3, DataField = "GroupName", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
||||||
new EditingFormItemDto { Order = 4, DataField = "Currency", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
new EditingFormItemDto { Order = 4, DataField = "Currency", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
||||||
new EditingFormItemDto { Order = 5, DataField = "PhoneCode", ColSpan = 1, EditorType2 = EditorTypes.dxNumberBox },
|
new EditingFormItemDto { Order = 5, DataField = "PhoneCode", ColSpan = 1, EditorType2 = EditorTypes.dxNumberBox },
|
||||||
new EditingFormItemDto { Order = 6, DataField = "TaxLabel", ColSpan = 1, EditorType2 = EditorTypes.dxTextBox },
|
new EditingFormItemDto { Order = 6, DataField = "PhoneNumberMinLength", ColSpan = 1, EditorType2 = EditorTypes.dxNumberBox },
|
||||||
new EditingFormItemDto { Order = 7, DataField = "ZipRequired", ColSpan = 1, EditorType2 = EditorTypes.dxCheckBox },
|
new EditingFormItemDto { Order = 7, DataField = "PhoneNumberMaxLength", ColSpan = 1, EditorType2 = EditorTypes.dxNumberBox },
|
||||||
new EditingFormItemDto { Order = 8, DataField = "StateRequired", ColSpan = 1, EditorType2 = EditorTypes.dxCheckBox }
|
new EditingFormItemDto { Order = 8, DataField = "PhoneNumberFormat", ColSpan = 1, EditorType2 = EditorTypes.dxTextBox },
|
||||||
|
new EditingFormItemDto { Order = 9, DataField = "TaxLabel", ColSpan = 1, EditorType2 = EditorTypes.dxTextBox },
|
||||||
|
new EditingFormItemDto { Order = 10, DataField = "ZipRequired", ColSpan = 1, EditorType2 = EditorTypes.dxCheckBox },
|
||||||
|
new EditingFormItemDto { Order = 11, DataField = "StateRequired", ColSpan = 1, EditorType2 = EditorTypes.dxCheckBox }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
@ -1866,6 +1869,57 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
},
|
},
|
||||||
new()
|
new()
|
||||||
|
{
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Int32,
|
||||||
|
FieldName = "PhoneNumberMinLength",
|
||||||
|
CaptionName = "App.Listform.ListformField.PhoneNumberMinLength",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 7,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = false,
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Int32,
|
||||||
|
FieldName = "PhoneNumberMaxLength",
|
||||||
|
CaptionName = "App.Listform.ListformField.PhoneNumberMaxLength",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 8,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = false,
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.String,
|
||||||
|
FieldName = "PhoneNumberFormat",
|
||||||
|
CaptionName = "App.Listform.ListformField.PhoneNumberFormat",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 9,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = false,
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
},
|
||||||
|
new()
|
||||||
{
|
{
|
||||||
ListFormCode = listForm.ListFormCode,
|
ListFormCode = listForm.ListFormCode,
|
||||||
CultureName = LanguageCodes.En,
|
CultureName = LanguageCodes.En,
|
||||||
|
|
@ -1873,7 +1927,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "TaxLabel",
|
FieldName = "TaxLabel",
|
||||||
CaptionName = "App.Listform.ListformField.TaxLabel",
|
CaptionName = "App.Listform.ListformField.TaxLabel",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 7,
|
ListOrderNo = 10,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -1889,7 +1943,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "ZipRequired",
|
FieldName = "ZipRequired",
|
||||||
CaptionName = "App.Listform.ListformField.ZipRequired",
|
CaptionName = "App.Listform.ListformField.ZipRequired",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 8,
|
ListOrderNo = 11,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -1904,7 +1958,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "StateRequired",
|
FieldName = "StateRequired",
|
||||||
CaptionName = "App.Listform.ListformField.StateRequired",
|
CaptionName = "App.Listform.ListformField.StateRequired",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 9,
|
ListOrderNo = 12,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -6931,13 +6985,21 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
new EditingFormItemDto { Order = 18, DataField = "Total", ColSpan = 1, EditorType2 = EditorTypes.dxNumberBox, EditorOptions=EditorOptionValues.NumberStandartFormat() },
|
new EditingFormItemDto { Order = 18, DataField = "Total", ColSpan = 1, EditorType2 = EditorTypes.dxNumberBox, EditorOptions=EditorOptionValues.NumberStandartFormat() },
|
||||||
new EditingFormItemDto { Order = 19, DataField = "PaymentMethodId", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
new EditingFormItemDto { Order = 19, DataField = "PaymentMethodId", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
||||||
new EditingFormItemDto { Order = 20, DataField = "Installment", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
new EditingFormItemDto { Order = 20, DataField = "Installment", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
||||||
new EditingFormItemDto { Order = 21, DataField = "IsActive", ColSpan = 1, EditorType2 = EditorTypes.dxCheckBox },
|
new EditingFormItemDto { Order = 21, DataField = "BillingCycle", ColSpan = 1, EditorType2 = EditorTypes.dxTextBox },
|
||||||
|
new EditingFormItemDto { Order = 22, DataField = "Period", ColSpan = 1, EditorType2 = EditorTypes.dxNumberBox },
|
||||||
|
new EditingFormItemDto { Order = 23, DataField = "LicenseStartTime", ColSpan = 1, EditorType2 = EditorTypes.dxDateBox },
|
||||||
|
new EditingFormItemDto { Order = 24, DataField = "LicenseStopTime", ColSpan = 1, EditorType2 = EditorTypes.dxDateBox },
|
||||||
|
new EditingFormItemDto { Order = 25, DataField = "IsExisting", ColSpan = 1, EditorType2 = EditorTypes.dxCheckBox },
|
||||||
|
new EditingFormItemDto { Order = 26, DataField = "IsActive", ColSpan = 1, EditorType2 = EditorTypes.dxCheckBox },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(),
|
InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(),
|
||||||
FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
|
FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
|
||||||
new() { FieldName = "Country", FieldDbType = DbType.String, Value = "Türkiye", CustomValueType = FieldCustomValueTypeEnum.Value },
|
new() { FieldName = "Country", FieldDbType = DbType.String, Value = "Türkiye", CustomValueType = FieldCustomValueTypeEnum.Value },
|
||||||
|
new() { FieldName = "BillingCycle", FieldDbType = DbType.String, Value = "yearly", CustomValueType = FieldCustomValueTypeEnum.Value },
|
||||||
|
new() { FieldName = "Period", FieldDbType = DbType.Int32, Value = "1", CustomValueType = FieldCustomValueTypeEnum.Value },
|
||||||
|
new() { FieldName = "IsExisting", FieldDbType = DbType.Boolean, Value = "false", CustomValueType = FieldCustomValueTypeEnum.Value },
|
||||||
new() { FieldName = "IsActive", FieldDbType = DbType.Boolean, Value = "true", CustomValueType = FieldCustomValueTypeEnum.Value },
|
new() { FieldName = "IsActive", FieldDbType = DbType.Boolean, Value = "true", CustomValueType = FieldCustomValueTypeEnum.Value },
|
||||||
new() { FieldName = "Commission", FieldDbType = DbType.Decimal, Value = "0", CustomValueType = FieldCustomValueTypeEnum.Value }
|
new() { FieldName = "Commission", FieldDbType = DbType.Decimal, Value = "0", CustomValueType = FieldCustomValueTypeEnum.Value }
|
||||||
}),
|
}),
|
||||||
|
|
@ -7013,6 +7075,91 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
PivotSettingsJson = DefaultPivotSettingsJson,
|
PivotSettingsJson = DefaultPivotSettingsJson,
|
||||||
},
|
},
|
||||||
new()
|
new()
|
||||||
|
{
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Boolean,
|
||||||
|
FieldName = "IsExisting",
|
||||||
|
CaptionName = "App.Listform.ListformField.IsExisting",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 4,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.String,
|
||||||
|
FieldName = "BillingCycle",
|
||||||
|
CaptionName = "App.Listform.ListformField.BillingCycle",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 5,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Int32,
|
||||||
|
FieldName = "Period",
|
||||||
|
CaptionName = "App.Listform.ListformField.Period",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 6,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.DateTime,
|
||||||
|
FieldName = "LicenseStartTime",
|
||||||
|
CaptionName = "App.Listform.ListformField.LicenseStartTime",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 7,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.DateTime,
|
||||||
|
FieldName = "LicenseStopTime",
|
||||||
|
CaptionName = "App.Listform.ListformField.LicenseStopTime",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 8,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson,
|
||||||
|
},
|
||||||
|
new()
|
||||||
{
|
{
|
||||||
ListFormCode = listForm.ListFormCode,
|
ListFormCode = listForm.ListFormCode,
|
||||||
CultureName = LanguageCodes.En,
|
CultureName = LanguageCodes.En,
|
||||||
|
|
@ -7020,7 +7167,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "VknTckn",
|
FieldName = "VknTckn",
|
||||||
CaptionName = "App.Listform.ListformField.VknTckn",
|
CaptionName = "App.Listform.ListformField.VknTckn",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 4,
|
ListOrderNo = 9,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7038,7 +7185,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "TaxOffice",
|
FieldName = "TaxOffice",
|
||||||
CaptionName = "App.Listform.ListformField.TaxOffice",
|
CaptionName = "App.Listform.ListformField.TaxOffice",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 5,
|
ListOrderNo = 10,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7056,7 +7203,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "Address1",
|
FieldName = "Address1",
|
||||||
CaptionName = "App.Listform.ListformField.Address1",
|
CaptionName = "App.Listform.ListformField.Address1",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 6,
|
ListOrderNo = 11,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7074,7 +7221,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "Address2",
|
FieldName = "Address2",
|
||||||
CaptionName = "App.Listform.ListformField.Address2",
|
CaptionName = "App.Listform.ListformField.Address2",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 7,
|
ListOrderNo = 12,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7091,7 +7238,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "Country",
|
FieldName = "Country",
|
||||||
CaptionName = "App.Listform.ListformField.Country",
|
CaptionName = "App.Listform.ListformField.Country",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 8,
|
ListOrderNo = 13,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7117,7 +7264,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "City",
|
FieldName = "City",
|
||||||
CaptionName = "App.Listform.ListformField.City",
|
CaptionName = "App.Listform.ListformField.City",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 9,
|
ListOrderNo = 14,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7146,7 +7293,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "District",
|
FieldName = "District",
|
||||||
CaptionName = "App.Listform.ListformField.District",
|
CaptionName = "App.Listform.ListformField.District",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 10,
|
ListOrderNo = 15,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7174,7 +7321,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "PhoneNumber",
|
FieldName = "PhoneNumber",
|
||||||
CaptionName = "Abp.Identity.User.UserInformation.PhoneNumber",
|
CaptionName = "Abp.Identity.User.UserInformation.PhoneNumber",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 11,
|
ListOrderNo = 16,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7193,7 +7340,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "MobileNumber",
|
FieldName = "MobileNumber",
|
||||||
CaptionName = "App.Listform.ListformField.MobileNumber",
|
CaptionName = "App.Listform.ListformField.MobileNumber",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 12,
|
ListOrderNo = 17,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7212,7 +7359,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "FaxNumber",
|
FieldName = "FaxNumber",
|
||||||
CaptionName = "App.Listform.ListformField.FaxNumber",
|
CaptionName = "App.Listform.ListformField.FaxNumber",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 13,
|
ListOrderNo = 18,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7230,7 +7377,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "Website",
|
FieldName = "Website",
|
||||||
CaptionName = "App.Listform.ListformField.Website",
|
CaptionName = "App.Listform.ListformField.Website",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 14,
|
ListOrderNo = 19,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7249,7 +7396,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
CaptionName = "App.Listform.ListformField.Subtotal",
|
CaptionName = "App.Listform.ListformField.Subtotal",
|
||||||
Alignment = "right",
|
Alignment = "right",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 15,
|
ListOrderNo = 20,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7269,7 +7416,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
CaptionName = "App.Listform.ListformField.Commission",
|
CaptionName = "App.Listform.ListformField.Commission",
|
||||||
Alignment = "right",
|
Alignment = "right",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 16,
|
ListOrderNo = 21,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7289,7 +7436,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
CaptionName = "App.Listform.ListformField.Total",
|
CaptionName = "App.Listform.ListformField.Total",
|
||||||
Alignment = "right",
|
Alignment = "right",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 17,
|
ListOrderNo = 22,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7308,7 +7455,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "PaymentMethodId",
|
FieldName = "PaymentMethodId",
|
||||||
CaptionName = "App.Listform.ListformField.PaymentMethodId",
|
CaptionName = "App.Listform.ListformField.PaymentMethodId",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 18,
|
ListOrderNo = 23,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7327,7 +7474,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "Installment",
|
FieldName = "Installment",
|
||||||
CaptionName = "App.Listform.ListformField.Installment",
|
CaptionName = "App.Listform.ListformField.Installment",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 19,
|
ListOrderNo = 24,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7346,7 +7493,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "IsActive",
|
FieldName = "IsActive",
|
||||||
CaptionName = "App.Listform.ListformField.IsActive",
|
CaptionName = "App.Listform.ListformField.IsActive",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 20,
|
ListOrderNo = 25,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7363,7 +7510,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "PostalCode",
|
FieldName = "PostalCode",
|
||||||
CaptionName = "App.Listform.ListformField.PostalCode",
|
CaptionName = "App.Listform.ListformField.PostalCode",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 21,
|
ListOrderNo = 26,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7381,7 +7528,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
FieldName = "Email",
|
FieldName = "Email",
|
||||||
CaptionName = "App.Listform.ListformField.Email",
|
CaptionName = "App.Listform.ListformField.Email",
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = 22,
|
ListOrderNo = 27,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
|
|
||||||
|
|
@ -7394,6 +7541,133 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
]);
|
]);
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var existingListForm = await _listFormRepository.FirstOrDefaultAsync(a => a.ListFormCode == listFormName);
|
||||||
|
|
||||||
|
if (existingListForm != null)
|
||||||
|
{
|
||||||
|
if (!await _listFormFieldRepository.AnyAsync(a =>
|
||||||
|
a.ListFormCode == listFormName &&
|
||||||
|
a.FieldName == "BillingCycle" &&
|
||||||
|
a.CultureName == LanguageCodes.En))
|
||||||
|
{
|
||||||
|
await _listFormFieldRepository.InsertAsync(new()
|
||||||
|
{
|
||||||
|
ListFormCode = existingListForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.String,
|
||||||
|
FieldName = "BillingCycle",
|
||||||
|
CaptionName = "App.Listform.ListformField.BillingCycle",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 20,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(existingListForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await _listFormFieldRepository.AnyAsync(a =>
|
||||||
|
a.ListFormCode == listFormName &&
|
||||||
|
a.FieldName == "Period" &&
|
||||||
|
a.CultureName == LanguageCodes.En))
|
||||||
|
{
|
||||||
|
await _listFormFieldRepository.InsertAsync(new()
|
||||||
|
{
|
||||||
|
ListFormCode = existingListForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Int32,
|
||||||
|
FieldName = "Period",
|
||||||
|
CaptionName = "App.Listform.ListformField.Period",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 21,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(existingListForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await _listFormFieldRepository.AnyAsync(a =>
|
||||||
|
a.ListFormCode == listFormName &&
|
||||||
|
a.FieldName == "LicenseStartTime" &&
|
||||||
|
a.CultureName == LanguageCodes.En))
|
||||||
|
{
|
||||||
|
await _listFormFieldRepository.InsertAsync(new()
|
||||||
|
{
|
||||||
|
ListFormCode = existingListForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.DateTime,
|
||||||
|
FieldName = "LicenseStartTime",
|
||||||
|
CaptionName = "App.Listform.ListformField.LicenseStartTime",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 22,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(existingListForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await _listFormFieldRepository.AnyAsync(a =>
|
||||||
|
a.ListFormCode == listFormName &&
|
||||||
|
a.FieldName == "LicenseStopTime" &&
|
||||||
|
a.CultureName == LanguageCodes.En))
|
||||||
|
{
|
||||||
|
await _listFormFieldRepository.InsertAsync(new()
|
||||||
|
{
|
||||||
|
ListFormCode = existingListForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.DateTime,
|
||||||
|
FieldName = "LicenseStopTime",
|
||||||
|
CaptionName = "App.Listform.ListformField.LicenseStopTime",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 23,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(existingListForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await _listFormFieldRepository.AnyAsync(a =>
|
||||||
|
a.ListFormCode == listFormName &&
|
||||||
|
a.FieldName == "IsExisting" &&
|
||||||
|
a.CultureName == LanguageCodes.En))
|
||||||
|
{
|
||||||
|
await _listFormFieldRepository.InsertAsync(new()
|
||||||
|
{
|
||||||
|
ListFormCode = existingListForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Boolean,
|
||||||
|
FieldName = "IsExisting",
|
||||||
|
CaptionName = "App.Listform.ListformField.IsExisting",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 24,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(existingListForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Sales Order Item
|
#region Sales Order Item
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ public class Country : FullAuditedEntity<string>
|
||||||
public string GroupName { get; set; }
|
public string GroupName { get; set; }
|
||||||
public string Currency { get; set; }
|
public string Currency { get; set; }
|
||||||
public int PhoneCode { get; set; }
|
public int PhoneCode { get; set; }
|
||||||
|
public int? PhoneNumberMinLength { get; set; }
|
||||||
|
public int? PhoneNumberMaxLength { get; set; }
|
||||||
|
public string? PhoneNumberFormat { get; set; }
|
||||||
public string TaxLabel { get; set; }
|
public string TaxLabel { get; set; }
|
||||||
public bool ZipRequired { get; set; }
|
public bool ZipRequired { get; set; }
|
||||||
public bool StateRequired { get; set; }
|
public bool StateRequired { get; set; }
|
||||||
|
|
@ -23,6 +26,9 @@ public class Country : FullAuditedEntity<string>
|
||||||
string groupName,
|
string groupName,
|
||||||
string currency,
|
string currency,
|
||||||
int phoneCode,
|
int phoneCode,
|
||||||
|
int? phoneNumberMinLength,
|
||||||
|
int? phoneNumberMaxLength,
|
||||||
|
string? phoneNumberFormat,
|
||||||
string taxLabel,
|
string taxLabel,
|
||||||
bool zipRequired = false,
|
bool zipRequired = false,
|
||||||
bool stateRequired = false)
|
bool stateRequired = false)
|
||||||
|
|
@ -32,6 +38,9 @@ public class Country : FullAuditedEntity<string>
|
||||||
GroupName = groupName;
|
GroupName = groupName;
|
||||||
Currency = currency;
|
Currency = currency;
|
||||||
PhoneCode = phoneCode;
|
PhoneCode = phoneCode;
|
||||||
|
PhoneNumberMinLength = phoneNumberMinLength;
|
||||||
|
PhoneNumberMaxLength = phoneNumberMaxLength;
|
||||||
|
PhoneNumberFormat = phoneNumberFormat;
|
||||||
TaxLabel = taxLabel;
|
TaxLabel = taxLabel;
|
||||||
ZipRequired = zipRequired;
|
ZipRequired = zipRequired;
|
||||||
StateRequired = stateRequired;
|
StateRequired = stateRequired;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ public class Order : FullAuditedEntity<Guid>
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool IsActive { get; set; }
|
public bool IsActive { get; set; }
|
||||||
|
public bool IsExisting { get; set; }
|
||||||
|
|
||||||
public string OrganizationName { get; set; }
|
public string OrganizationName { get; set; }
|
||||||
public string Founder { get; set; }
|
public string Founder { get; set; }
|
||||||
|
|
@ -26,6 +27,11 @@ public class Order : FullAuditedEntity<Guid>
|
||||||
public string Website { get; set; }
|
public string Website { get; set; }
|
||||||
public string MenuGroup { get; set; }
|
public string MenuGroup { get; set; }
|
||||||
|
|
||||||
|
public string BillingCycle { get; set; }
|
||||||
|
public int Period { get; set; }
|
||||||
|
public DateTime? LicenseStartTime { get; set; }
|
||||||
|
public DateTime? LicenseStopTime { get; set; }
|
||||||
|
|
||||||
public List<OrderItem> Items { get; set; } = new();
|
public List<OrderItem> Items { get; set; } = new();
|
||||||
public decimal Subtotal { get; set; }
|
public decimal Subtotal { get; set; }
|
||||||
public decimal Commission { get; set; }
|
public decimal Commission { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -747,6 +747,9 @@ public class PlatformDbContext :
|
||||||
b.Property(x => x.GroupName).HasMaxLength(128);
|
b.Property(x => x.GroupName).HasMaxLength(128);
|
||||||
b.Property(x => x.TaxLabel).HasMaxLength(64);
|
b.Property(x => x.TaxLabel).HasMaxLength(64);
|
||||||
b.Property(x => x.Currency).IsRequired().HasMaxLength(8);
|
b.Property(x => x.Currency).IsRequired().HasMaxLength(8);
|
||||||
|
b.Property(x => x.PhoneNumberMinLength).HasDefaultValue(0);
|
||||||
|
b.Property(x => x.PhoneNumberMaxLength).HasDefaultValue(0);
|
||||||
|
b.Property(x => x.PhoneNumberFormat).HasMaxLength(64);
|
||||||
|
|
||||||
b.HasIndex(x => new { x.Name }).IsUnique().HasFilter("[IsDeleted] = 0");
|
b.HasIndex(x => new { x.Name }).IsUnique().HasFilter("[IsDeleted] = 0");
|
||||||
|
|
||||||
|
|
@ -1011,6 +1014,7 @@ public class PlatformDbContext :
|
||||||
b.ConfigureByConvention();
|
b.ConfigureByConvention();
|
||||||
|
|
||||||
b.Property(o => o.Name).HasMaxLength(64);
|
b.Property(o => o.Name).HasMaxLength(64);
|
||||||
|
b.Property(o => o.IsExisting).IsRequired().HasDefaultValue(false);
|
||||||
b.Property(o => o.OrganizationName).HasMaxLength(128);
|
b.Property(o => o.OrganizationName).HasMaxLength(128);
|
||||||
b.Property(o => o.Founder).HasMaxLength(128);
|
b.Property(o => o.Founder).HasMaxLength(128);
|
||||||
b.Property(o => o.TaxOffice).HasMaxLength(128);
|
b.Property(o => o.TaxOffice).HasMaxLength(128);
|
||||||
|
|
@ -1026,6 +1030,8 @@ public class PlatformDbContext :
|
||||||
b.Property(o => o.Email).HasMaxLength(128);
|
b.Property(o => o.Email).HasMaxLength(128);
|
||||||
b.Property(o => o.Website).HasMaxLength(128);
|
b.Property(o => o.Website).HasMaxLength(128);
|
||||||
b.Property(o => o.MenuGroup).HasMaxLength(64);
|
b.Property(o => o.MenuGroup).HasMaxLength(64);
|
||||||
|
b.Property(o => o.BillingCycle).HasMaxLength(32);
|
||||||
|
b.Property(o => o.Period).IsRequired().HasDefaultValue(1);
|
||||||
|
|
||||||
b.Property(o => o.Subtotal).IsRequired().HasPrecision(18, 2);
|
b.Property(o => o.Subtotal).IsRequired().HasPrecision(18, 2);
|
||||||
b.Property(o => o.Commission).IsRequired().HasPrecision(18, 2);
|
b.Property(o => o.Commission).IsRequired().HasPrecision(18, 2);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
|
||||||
namespace Sozsoft.Platform.Migrations
|
namespace Sozsoft.Platform.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(PlatformDbContext))]
|
[DbContext(typeof(PlatformDbContext))]
|
||||||
[Migration("20260625183130_Initial")]
|
[Migration("20260706213526_Initial")]
|
||||||
partial class Initial
|
partial class Initial
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -1542,6 +1542,20 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.Property<int>("PhoneCode")
|
b.Property<int>("PhoneCode")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumberFormat")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("nvarchar(64)");
|
||||||
|
|
||||||
|
b.Property<int?>("PhoneNumberMaxLength")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasDefaultValue(0);
|
||||||
|
|
||||||
|
b.Property<int?>("PhoneNumberMinLength")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasDefaultValue(0);
|
||||||
|
|
||||||
b.Property<bool>("StateRequired")
|
b.Property<bool>("StateRequired")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
|
@ -4071,6 +4085,10 @@ namespace Sozsoft.Platform.Migrations
|
||||||
.HasMaxLength(512)
|
.HasMaxLength(512)
|
||||||
.HasColumnType("nvarchar(512)");
|
.HasColumnType("nvarchar(512)");
|
||||||
|
|
||||||
|
b.Property<string>("BillingCycle")
|
||||||
|
.HasMaxLength(32)
|
||||||
|
.HasColumnType("nvarchar(32)");
|
||||||
|
|
||||||
b.Property<string>("City")
|
b.Property<string>("City")
|
||||||
.HasMaxLength(128)
|
.HasMaxLength(128)
|
||||||
.HasColumnType("nvarchar(128)");
|
.HasColumnType("nvarchar(128)");
|
||||||
|
|
@ -4127,6 +4145,11 @@ namespace Sozsoft.Platform.Migrations
|
||||||
.HasDefaultValue(false)
|
.HasDefaultValue(false)
|
||||||
.HasColumnName("IsDeleted");
|
.HasColumnName("IsDeleted");
|
||||||
|
|
||||||
|
b.Property<bool>("IsExisting")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(false);
|
||||||
|
|
||||||
b.Property<DateTime?>("LastModificationTime")
|
b.Property<DateTime?>("LastModificationTime")
|
||||||
.HasColumnType("datetime2")
|
.HasColumnType("datetime2")
|
||||||
.HasColumnName("LastModificationTime");
|
.HasColumnName("LastModificationTime");
|
||||||
|
|
@ -4135,6 +4158,12 @@ namespace Sozsoft.Platform.Migrations
|
||||||
.HasColumnType("uniqueidentifier")
|
.HasColumnType("uniqueidentifier")
|
||||||
.HasColumnName("LastModifierId");
|
.HasColumnName("LastModifierId");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LicenseStartTime")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LicenseStopTime")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
b.Property<string>("MenuGroup")
|
b.Property<string>("MenuGroup")
|
||||||
.HasMaxLength(64)
|
.HasMaxLength(64)
|
||||||
.HasColumnType("nvarchar(64)");
|
.HasColumnType("nvarchar(64)");
|
||||||
|
|
@ -4158,6 +4187,11 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.Property<Guid>("PaymentMethodId")
|
b.Property<Guid>("PaymentMethodId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
|
b.Property<int>("Period")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasDefaultValue(1);
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
b.Property<string>("PhoneNumber")
|
||||||
.HasMaxLength(20)
|
.HasMaxLength(20)
|
||||||
.HasColumnType("nvarchar(20)");
|
.HasColumnType("nvarchar(20)");
|
||||||
|
|
@ -1573,6 +1573,7 @@ namespace Sozsoft.Platform.Migrations
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||||
Name = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
|
Name = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
|
||||||
IsActive = table.Column<bool>(type: "bit", nullable: false),
|
IsActive = table.Column<bool>(type: "bit", nullable: false),
|
||||||
|
IsExisting = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
|
||||||
OrganizationName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
OrganizationName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
||||||
Founder = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
Founder = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
||||||
VknTckn = table.Column<long>(type: "bigint", nullable: true),
|
VknTckn = table.Column<long>(type: "bigint", nullable: true),
|
||||||
|
|
@ -1589,6 +1590,10 @@ namespace Sozsoft.Platform.Migrations
|
||||||
Email = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
Email = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
||||||
Website = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
Website = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
||||||
MenuGroup = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
|
MenuGroup = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
|
||||||
|
BillingCycle = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: true),
|
||||||
|
Period = table.Column<int>(type: "int", nullable: false, defaultValue: 1),
|
||||||
|
LicenseStartTime = table.Column<DateTime>(type: "datetime2", nullable: true),
|
||||||
|
LicenseStopTime = table.Column<DateTime>(type: "datetime2", nullable: true),
|
||||||
Subtotal = table.Column<decimal>(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
|
Subtotal = table.Column<decimal>(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
|
||||||
Commission = table.Column<decimal>(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
|
Commission = table.Column<decimal>(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
|
||||||
Total = table.Column<decimal>(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
|
Total = table.Column<decimal>(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false),
|
||||||
|
|
@ -2683,6 +2688,9 @@ namespace Sozsoft.Platform.Migrations
|
||||||
GroupName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
GroupName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
||||||
Currency = table.Column<string>(type: "nvarchar(8)", maxLength: 8, nullable: false),
|
Currency = table.Column<string>(type: "nvarchar(8)", maxLength: 8, nullable: false),
|
||||||
PhoneCode = table.Column<int>(type: "int", nullable: false),
|
PhoneCode = table.Column<int>(type: "int", nullable: false),
|
||||||
|
PhoneNumberMinLength = table.Column<int>(type: "int", nullable: true, defaultValue: 0),
|
||||||
|
PhoneNumberMaxLength = table.Column<int>(type: "int", nullable: true, defaultValue: 0),
|
||||||
|
PhoneNumberFormat = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
|
||||||
TaxLabel = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
|
TaxLabel = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
|
||||||
ZipRequired = table.Column<bool>(type: "bit", nullable: false),
|
ZipRequired = table.Column<bool>(type: "bit", nullable: false),
|
||||||
StateRequired = table.Column<bool>(type: "bit", nullable: false),
|
StateRequired = table.Column<bool>(type: "bit", nullable: false),
|
||||||
|
|
@ -1539,6 +1539,20 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.Property<int>("PhoneCode")
|
b.Property<int>("PhoneCode")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumberFormat")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("nvarchar(64)");
|
||||||
|
|
||||||
|
b.Property<int?>("PhoneNumberMaxLength")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasDefaultValue(0);
|
||||||
|
|
||||||
|
b.Property<int?>("PhoneNumberMinLength")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasDefaultValue(0);
|
||||||
|
|
||||||
b.Property<bool>("StateRequired")
|
b.Property<bool>("StateRequired")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
|
@ -4068,6 +4082,10 @@ namespace Sozsoft.Platform.Migrations
|
||||||
.HasMaxLength(512)
|
.HasMaxLength(512)
|
||||||
.HasColumnType("nvarchar(512)");
|
.HasColumnType("nvarchar(512)");
|
||||||
|
|
||||||
|
b.Property<string>("BillingCycle")
|
||||||
|
.HasMaxLength(32)
|
||||||
|
.HasColumnType("nvarchar(32)");
|
||||||
|
|
||||||
b.Property<string>("City")
|
b.Property<string>("City")
|
||||||
.HasMaxLength(128)
|
.HasMaxLength(128)
|
||||||
.HasColumnType("nvarchar(128)");
|
.HasColumnType("nvarchar(128)");
|
||||||
|
|
@ -4124,6 +4142,11 @@ namespace Sozsoft.Platform.Migrations
|
||||||
.HasDefaultValue(false)
|
.HasDefaultValue(false)
|
||||||
.HasColumnName("IsDeleted");
|
.HasColumnName("IsDeleted");
|
||||||
|
|
||||||
|
b.Property<bool>("IsExisting")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(false);
|
||||||
|
|
||||||
b.Property<DateTime?>("LastModificationTime")
|
b.Property<DateTime?>("LastModificationTime")
|
||||||
.HasColumnType("datetime2")
|
.HasColumnType("datetime2")
|
||||||
.HasColumnName("LastModificationTime");
|
.HasColumnName("LastModificationTime");
|
||||||
|
|
@ -4132,6 +4155,12 @@ namespace Sozsoft.Platform.Migrations
|
||||||
.HasColumnType("uniqueidentifier")
|
.HasColumnType("uniqueidentifier")
|
||||||
.HasColumnName("LastModifierId");
|
.HasColumnName("LastModifierId");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LicenseStartTime")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LicenseStopTime")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
b.Property<string>("MenuGroup")
|
b.Property<string>("MenuGroup")
|
||||||
.HasMaxLength(64)
|
.HasMaxLength(64)
|
||||||
.HasColumnType("nvarchar(64)");
|
.HasColumnType("nvarchar(64)");
|
||||||
|
|
@ -4155,6 +4184,11 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.Property<Guid>("PaymentMethodId")
|
b.Property<Guid>("PaymentMethodId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
|
b.Property<int>("Period")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasDefaultValue(1);
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
b.Property<string>("PhoneNumber")
|
||||||
.HasMaxLength(20)
|
.HasMaxLength(20)
|
||||||
.HasColumnType("nvarchar(20)");
|
.HasColumnType("nvarchar(20)");
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,123 @@ import {
|
||||||
FaUser,
|
FaUser,
|
||||||
FaUserPlus,
|
FaUserPlus,
|
||||||
} from 'react-icons/fa'
|
} from 'react-icons/fa'
|
||||||
import React, { useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||||
import { Button } from '@/components/ui'
|
import { Button, Select } from '@/components/ui'
|
||||||
|
import {
|
||||||
|
CityDto,
|
||||||
|
CountryDto,
|
||||||
|
DistrictDto,
|
||||||
|
getCities,
|
||||||
|
getCountries,
|
||||||
|
getDistricts,
|
||||||
|
} from '@/services/location.service'
|
||||||
|
|
||||||
|
interface LocationOption<T> {
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
data: T
|
||||||
|
}
|
||||||
|
|
||||||
|
const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||||
|
const DEFAULT_PHONE_FORMAT = '000 000 000 000 000'
|
||||||
|
const TURKEY_PHONE_FORMAT = '(000) 000-0000'
|
||||||
|
const REQUIRED_NEW_CUSTOMER_FIELDS: Array<keyof CustomTenantDto> = [
|
||||||
|
'organizationName',
|
||||||
|
'founder',
|
||||||
|
'country',
|
||||||
|
'city',
|
||||||
|
'district',
|
||||||
|
'postalCode',
|
||||||
|
'address1',
|
||||||
|
'phoneNumber',
|
||||||
|
'email',
|
||||||
|
'taxOffice',
|
||||||
|
'vknTckn',
|
||||||
|
]
|
||||||
|
const REQUIRED_EXISTING_CUSTOMER_FIELDS: Array<keyof CustomTenantDto> = [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'organizationName',
|
||||||
|
'founder',
|
||||||
|
'country',
|
||||||
|
'city',
|
||||||
|
'district',
|
||||||
|
'address1',
|
||||||
|
'email',
|
||||||
|
]
|
||||||
|
|
||||||
|
const getPhoneFormat = (country?: CountryDto) =>
|
||||||
|
country?.phoneNumberFormat ||
|
||||||
|
(country?.phoneCode === 90 ? TURKEY_PHONE_FORMAT : DEFAULT_PHONE_FORMAT)
|
||||||
|
|
||||||
|
const getPhoneMaxLength = (country?: CountryDto) =>
|
||||||
|
country?.phoneNumberMaxLength ?? getPhoneFormat(country).replace(/[^0]/g, '').length
|
||||||
|
|
||||||
|
const getPhoneMinLength = (country?: CountryDto) =>
|
||||||
|
country?.phoneNumberMinLength ?? getPhoneMaxLength(country)
|
||||||
|
|
||||||
|
const getNationalPhoneDigits = (value: string, country?: CountryDto) => {
|
||||||
|
let digits = value.replace(/\D/g, '')
|
||||||
|
if (!country) return digits
|
||||||
|
|
||||||
|
const code = String(country.phoneCode)
|
||||||
|
if (value.trimStart().startsWith('+') && digits.startsWith(code)) {
|
||||||
|
digits = digits.slice(code.length)
|
||||||
|
}
|
||||||
|
return digits
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPhoneValidationError = (value: string, country?: CountryDto) => {
|
||||||
|
if (!country) return 'Lütfen önce ülke seçin.'
|
||||||
|
|
||||||
|
const length = getNationalPhoneDigits(value, country).length
|
||||||
|
const minLength = getPhoneMinLength(country)
|
||||||
|
const maxLength = getPhoneMaxLength(country)
|
||||||
|
if (length >= minLength && length <= maxLength) return ''
|
||||||
|
|
||||||
|
return minLength === maxLength
|
||||||
|
? `Telefon numarası ${minLength} haneli olmalıdır.`
|
||||||
|
: `Telefon numarası ${minLength}-${maxLength} hane arasında olmalıdır.`
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatPhoneNumber = (value: string, country?: CountryDto) => {
|
||||||
|
if (!country) return value.replace(/\D/g, '').slice(0, 15)
|
||||||
|
|
||||||
|
const maxLength = getPhoneMaxLength(country)
|
||||||
|
const digits = getNationalPhoneDigits(value, country).slice(0, maxLength)
|
||||||
|
const format = getPhoneFormat(country)
|
||||||
|
let digitIndex = 0
|
||||||
|
let nationalNumber = ''
|
||||||
|
|
||||||
|
for (const character of format) {
|
||||||
|
if (character === '0') {
|
||||||
|
if (digitIndex >= digits.length) break
|
||||||
|
nationalNumber += digits[digitIndex]
|
||||||
|
digitIndex += 1
|
||||||
|
} else if (digitIndex === 0) {
|
||||||
|
if (digits.length > 0) nationalNumber += character
|
||||||
|
} else if (digitIndex < digits.length || character === ')') {
|
||||||
|
nationalNumber += character
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `+${country.phoneCode}${nationalNumber ? ` ${nationalNumber}` : ''}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const isBlankValue = (value: unknown) =>
|
||||||
|
value === undefined || value === null || String(value).trim() === ''
|
||||||
|
|
||||||
|
const hasRequiredFields = (
|
||||||
|
tenant: Partial<CustomTenantDto>,
|
||||||
|
fields: Array<keyof CustomTenantDto>,
|
||||||
|
) => fields.every((field) => !isBlankValue(tenant[field]))
|
||||||
|
|
||||||
|
const normalizeCode = (value?: string) => value?.trim().toLowerCase() || ''
|
||||||
|
|
||||||
interface TenantFormProps {
|
interface TenantFormProps {
|
||||||
onSubmit: (tenant: CustomTenantDto) => void
|
onSubmit: (tenant: CustomTenantDto) => void
|
||||||
|
|
@ -29,22 +141,203 @@ interface TenantFormProps {
|
||||||
export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
const [isExisting, setIsExisting] = useState<boolean>(true)
|
const [isExisting, setIsExisting] = useState<boolean>(true)
|
||||||
const [formData, setFormData] = useState<Partial<CustomTenantDto>>({})
|
const [formData, setFormData] = useState<Partial<CustomTenantDto>>({})
|
||||||
|
const [countries, setCountries] = useState<CountryDto[]>([])
|
||||||
|
const [cities, setCities] = useState<CityDto[]>([])
|
||||||
|
const [districts, setDistricts] = useState<DistrictDto[]>([])
|
||||||
|
const [isLoadingCountries, setIsLoadingCountries] = useState(false)
|
||||||
|
const [isLoadingCities, setIsLoadingCities] = useState(false)
|
||||||
|
const [isLoadingDistricts, setIsLoadingDistricts] = useState(false)
|
||||||
|
const [isLoadingTenant, setIsLoadingTenant] = useState(false)
|
||||||
|
const [emailError, setEmailError] = useState('')
|
||||||
|
const [phoneError, setPhoneError] = useState('')
|
||||||
|
const [existingTenantError, setExistingTenantError] = useState('')
|
||||||
|
const [formError, setFormError] = useState('')
|
||||||
|
const [foundTenantName, setFoundTenantName] = useState('')
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadCountries = async () => {
|
||||||
|
setIsLoadingCountries(true)
|
||||||
|
try {
|
||||||
|
const response = await getCountries()
|
||||||
|
setCountries(response.data)
|
||||||
|
|
||||||
|
const defaultCountry = response.data.find((country) => country.name === 'Türkiye')
|
||||||
|
if (defaultCountry) {
|
||||||
|
setFormData((prev) =>
|
||||||
|
prev.country
|
||||||
|
? prev
|
||||||
|
: {
|
||||||
|
...prev,
|
||||||
|
country: defaultCountry.name,
|
||||||
|
city: '',
|
||||||
|
district: '',
|
||||||
|
phoneNumber: `+${defaultCountry.phoneCode}`,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
setIsLoadingCities(true)
|
||||||
|
try {
|
||||||
|
const cityResponse = await getCities(defaultCountry.name)
|
||||||
|
setCities(cityResponse.data)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Şehirler alınırken hata:', error)
|
||||||
|
} finally {
|
||||||
|
setIsLoadingCities(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Ülkeler alınırken hata:', error)
|
||||||
|
} finally {
|
||||||
|
setIsLoadingCountries(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadCountries()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const selectedCountry = countries.find((country) => country.name === formData.country)
|
||||||
|
const phoneMask = selectedCountry
|
||||||
|
? `+${selectedCountry.phoneCode} ${getPhoneFormat(selectedCountry)}`
|
||||||
|
: DEFAULT_PHONE_FORMAT
|
||||||
|
const canSubmitExistingTenant =
|
||||||
|
Boolean(
|
||||||
|
formData.id &&
|
||||||
|
formData.organizationName &&
|
||||||
|
normalizeCode(foundTenantName) === normalizeCode(formData.name),
|
||||||
|
) && !isLoadingTenant
|
||||||
|
|
||||||
const handleSubmit = (e: React.FormEvent) => {
|
const handleSubmit = (e: React.FormEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
onSubmit({ ...formData, isExisting: isExisting! } as CustomTenantDto)
|
let hasValidationError = false
|
||||||
|
setFormError('')
|
||||||
|
|
||||||
|
if (isExisting) {
|
||||||
|
if (!formData.name?.trim()) {
|
||||||
|
setExistingTenantError('Lütfen önce organization code girin.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!formData.id ||
|
||||||
|
normalizeCode(foundTenantName) !== normalizeCode(formData.name) ||
|
||||||
|
!formData.organizationName
|
||||||
|
) {
|
||||||
|
setExistingTenantError('Devam etmek için önce organization code ile kurum bilgisini bulun.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasRequiredFields(formData, REQUIRED_EXISTING_CUSTOMER_FIELDS)) {
|
||||||
|
setExistingTenantError('Kurum bilgileri eksik geldi. Lütfen kurum kodunu tekrar aratın.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit({ ...formData, isExisting: true } as CustomTenantDto)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasRequiredFields(formData, REQUIRED_NEW_CUSTOMER_FIELDS)) {
|
||||||
|
setFormError('Lütfen zorunlu alanları eksiksiz doldurun.')
|
||||||
|
hasValidationError = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextPhoneError = getPhoneValidationError(formData.phoneNumber || '', selectedCountry)
|
||||||
|
setPhoneError(nextPhoneError)
|
||||||
|
if (nextPhoneError) {
|
||||||
|
hasValidationError = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isExisting && !EMAIL_PATTERN.test(formData.email || '')) {
|
||||||
|
setEmailError('Lütfen geçerli bir e-posta adresi girin.')
|
||||||
|
hasValidationError = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasValidationError) return
|
||||||
|
onSubmit({ ...formData, isExisting: false } as CustomTenantDto)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleInputChange = (field: keyof CustomTenantDto, value: string) => {
|
const handleInputChange = (field: keyof CustomTenantDto, value: string) => {
|
||||||
setFormData((prev) => ({ ...prev, [field]: value }))
|
setFormData((prev) => ({ ...prev, [field]: value }))
|
||||||
}
|
}
|
||||||
|
|
||||||
const getTenantInfo = async () => {
|
const resetExistingTenantDetails = (name: string) => {
|
||||||
if (!formData.name) return
|
setFoundTenantName('')
|
||||||
|
setExistingTenantError('')
|
||||||
|
setFormError('')
|
||||||
|
setFormData({ name })
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCountryChange = async (option: LocationOption<CountryDto> | null) => {
|
||||||
|
const country = option?.data
|
||||||
|
setFormData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
country: country?.name || '',
|
||||||
|
city: '',
|
||||||
|
district: '',
|
||||||
|
phoneNumber: country ? `+${country.phoneCode}` : '',
|
||||||
|
}))
|
||||||
|
setCities([])
|
||||||
|
setDistricts([])
|
||||||
|
setPhoneError('')
|
||||||
|
|
||||||
|
if (!country) return
|
||||||
|
setIsLoadingCities(true)
|
||||||
try {
|
try {
|
||||||
const tenant = await getTenantByNameDetail(formData.name)
|
const response = await getCities(country.name)
|
||||||
|
setCities(response.data)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Şehirler alınırken hata:', error)
|
||||||
|
} finally {
|
||||||
|
setIsLoadingCities(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCityChange = async (option: LocationOption<CityDto> | null) => {
|
||||||
|
const city = option?.data
|
||||||
|
setFormData((prev) => ({ ...prev, city: city?.name || '', district: '' }))
|
||||||
|
setDistricts([])
|
||||||
|
|
||||||
|
if (!city || !formData.country) return
|
||||||
|
setIsLoadingDistricts(true)
|
||||||
|
try {
|
||||||
|
const response = await getDistricts(formData.country, city.name)
|
||||||
|
setDistricts(response.data)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('İlçeler alınırken hata:', error)
|
||||||
|
} finally {
|
||||||
|
setIsLoadingDistricts(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const countryOptions: LocationOption<CountryDto>[] = countries.map((country) => ({
|
||||||
|
label: country.name,
|
||||||
|
value: country.name,
|
||||||
|
data: country,
|
||||||
|
}))
|
||||||
|
const cityOptions: LocationOption<CityDto>[] = cities.map((city) => ({
|
||||||
|
label: city.name,
|
||||||
|
value: city.name,
|
||||||
|
data: city,
|
||||||
|
}))
|
||||||
|
const districtOptions: LocationOption<DistrictDto>[] = districts.map((district) => ({
|
||||||
|
label: district.name,
|
||||||
|
value: district.name,
|
||||||
|
data: district,
|
||||||
|
}))
|
||||||
|
|
||||||
|
const getTenantInfo = async () => {
|
||||||
|
const tenantName = formData.name?.trim()
|
||||||
|
if (!tenantName) {
|
||||||
|
setExistingTenantError('Lütfen önce organization code girin.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoadingTenant(true)
|
||||||
|
setExistingTenantError('')
|
||||||
|
setFormError('')
|
||||||
|
try {
|
||||||
|
const tenant = await getTenantByNameDetail(tenantName)
|
||||||
|
|
||||||
setFormData((prev) => ({
|
setFormData((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
|
|
@ -68,8 +361,13 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
website: tenant.data.website,
|
website: tenant.data.website,
|
||||||
menuGroup: tenant.data.menuGroup,
|
menuGroup: tenant.data.menuGroup,
|
||||||
}))
|
}))
|
||||||
|
setFoundTenantName(tenant.data.name)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
setFoundTenantName('')
|
||||||
|
setExistingTenantError('Kurum bulunamadı. Lütfen organization code bilgisini kontrol edin.')
|
||||||
console.error('Kurum bilgisi alınırken hata:', error)
|
console.error('Kurum bilgisi alınırken hata:', error)
|
||||||
|
} finally {
|
||||||
|
setIsLoadingTenant(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,7 +437,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
autoFocus
|
autoFocus
|
||||||
placeholder="Enter your organization code"
|
placeholder="Enter your organization code"
|
||||||
value={formData.name || ''}
|
value={formData.name || ''}
|
||||||
onChange={(e) => handleInputChange('name', e.target.value)}
|
onChange={(e) => resetExistingTenantDetails(e.target.value)}
|
||||||
onKeyDown={async (e) => {
|
onKeyDown={async (e) => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
@ -151,23 +449,36 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
disabled={isLoadingTenant || !formData.name?.trim()}
|
||||||
onClick={getTenantInfo}
|
onClick={getTenantInfo}
|
||||||
icon={<FaSearch className="w-4 h-4" />}
|
icon={<FaSearch className="w-4 h-4" />}
|
||||||
variant="solid"
|
variant="solid"
|
||||||
size="sm"
|
size="sm"
|
||||||
className="!h-[40px] min-w-[180px] sm:mr-2 sm:rounded-r-lg sm:rounded-l-none [&>span]:gap-2"
|
className="!h-[40px] min-w-[180px] sm:mr-2 sm:rounded-r-lg sm:rounded-l-none [&>span]:gap-2"
|
||||||
>
|
>
|
||||||
{translate('::Public.products.tenantForm.searchOrg')}
|
{isLoadingTenant
|
||||||
|
? 'Aranıyor...'
|
||||||
|
: translate('::Public.products.tenantForm.searchOrg')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{existingTenantError && (
|
||||||
|
<p className="mt-2 text-sm text-red-600">{existingTenantError}</p>
|
||||||
|
)}
|
||||||
|
{!existingTenantError &&
|
||||||
|
formData.name &&
|
||||||
|
!canSubmitExistingTenant &&
|
||||||
|
!isLoadingTenant && (
|
||||||
|
<p className="mt-2 text-sm text-amber-600">
|
||||||
|
Devam etmek için önce Find Organization ile kurum bilgilerini getirin.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
{formData.organizationName && (
|
{formData.organizationName && (
|
||||||
<div className="grid grid-cols-1 gap-y-3 text-sm text-gray-700 dark:text-gray-300 p-3">
|
<div className="grid grid-cols-1 gap-y-3 text-sm text-gray-700 dark:text-gray-300 p-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<FaUser className="w-4 h-4 text-gray-500" />
|
<FaUser className="w-4 h-4 text-gray-500" />
|
||||||
<span className="font-medium">
|
<span className="font-medium">{translate('::LoginPanel.Profil')}</span>
|
||||||
{translate('::LoginPanel.Profil')}
|
|
||||||
</span>
|
|
||||||
<span>{formData.founder}</span>
|
<span>{formData.founder}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -189,18 +500,14 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<FaPhone className="w-4 h-4 text-gray-500" />
|
<FaPhone className="w-4 h-4 text-gray-500" />
|
||||||
<span className="font-medium">
|
<span className="font-medium">{translate('::blog.categories.mobile')}:</span>
|
||||||
{translate('::blog.categories.mobile')}:
|
|
||||||
</span>
|
|
||||||
<span>{formData.mobileNumber}</span>
|
<span>{formData.mobileNumber}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-start gap-2">
|
<div className="flex items-start gap-2">
|
||||||
<FaMapPin className="w-4 h-4 text-gray-500 mt-0.5" />
|
<FaMapPin className="w-4 h-4 text-gray-500 mt-0.5" />
|
||||||
<div>
|
<div>
|
||||||
<span className="font-medium">
|
<span className="font-medium">{translate('::App.Address')}:</span>
|
||||||
{translate('::App.Address')}:
|
|
||||||
</span>
|
|
||||||
<div>{formData.address1}</div>
|
<div>{formData.address1}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -215,9 +522,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<FaGlobe className="w-4 h-4 text-gray-500" />
|
<FaGlobe className="w-4 h-4 text-gray-500" />
|
||||||
<span className="font-medium">
|
<span className="font-medium">{translate('::Public.common.city')}:</span>
|
||||||
{translate('::Public.common.city')}:
|
|
||||||
</span>
|
|
||||||
<span>{formData.city}</span>
|
<span>{formData.city}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -306,32 +611,76 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||||
{translate('::Abp.Identity.User.UserInformation.PhoneNumber')}
|
{translate('::Public.payment.customer.country')}
|
||||||
</label>
|
</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<FaPhone className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
<Select<LocationOption<CountryDto>>
|
||||||
<input
|
|
||||||
type="tel"
|
|
||||||
required
|
required
|
||||||
placeholder="+90 (___) ___-____"
|
isClearable
|
||||||
value={formData.phoneNumber || ''}
|
isLoading={isLoadingCountries}
|
||||||
onChange={(e) => handleInputChange('phoneNumber', e.target.value)}
|
options={countryOptions}
|
||||||
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
value={
|
||||||
|
countryOptions.find((option) => option.value === formData.country) || null
|
||||||
|
}
|
||||||
|
onChange={handleCountryChange}
|
||||||
|
placeholder="Ülke seçin"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||||
{translate('::Abp.Account.EmailAddress')}
|
{translate('::Public.common.city')}
|
||||||
</label>
|
</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<FaEnvelope className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
<Select<LocationOption<CityDto>>
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
required
|
required
|
||||||
placeholder="sample@email.com"
|
isClearable
|
||||||
value={formData.email || ''}
|
isDisabled={!formData.country}
|
||||||
onChange={(e) => handleInputChange('email', e.target.value)}
|
isLoading={isLoadingCities}
|
||||||
|
options={cityOptions}
|
||||||
|
value={cityOptions.find((option) => option.value === formData.city) || null}
|
||||||
|
onChange={handleCityChange}
|
||||||
|
placeholder={formData.country ? 'Şehir seçin' : 'Önce ülke seçin'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||||
|
{translate('::Public.payment.customer.district')}
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<Select<LocationOption<DistrictDto>>
|
||||||
|
required
|
||||||
|
isClearable
|
||||||
|
isDisabled={!formData.city}
|
||||||
|
isLoading={isLoadingDistricts}
|
||||||
|
options={districtOptions}
|
||||||
|
value={
|
||||||
|
districtOptions.find((option) => option.value === formData.district) ||
|
||||||
|
null
|
||||||
|
}
|
||||||
|
onChange={(option) =>
|
||||||
|
handleInputChange('district', option?.data.name || '')
|
||||||
|
}
|
||||||
|
placeholder={formData.city ? 'İlçe seçin' : 'Önce şehir seçin'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||||
|
{translate('::Public.payment.customer.postalCode')}
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<FaMapPin className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
placeholder="34782"
|
||||||
|
value={formData.postalCode || ''}
|
||||||
|
onChange={(e) => handleInputChange('postalCode', e.target.value)}
|
||||||
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -358,69 +707,87 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||||
{translate('::Public.payment.customer.country')}
|
{translate('::Abp.Identity.User.UserInformation.PhoneNumber')}
|
||||||
</label>
|
</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<FaGlobe className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
<FaPhone className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="tel"
|
||||||
placeholder="Türkiye"
|
required
|
||||||
value={formData.country || ''}
|
inputMode="numeric"
|
||||||
onChange={(e) => handleInputChange('country', e.target.value)}
|
placeholder={phoneMask.replace(/0/g, '_')}
|
||||||
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
aria-label={`Telefon numarası, format: ${phoneMask}`}
|
||||||
|
value={formData.phoneNumber || ''}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleInputChange(
|
||||||
|
'phoneNumber',
|
||||||
|
formatPhoneNumber(e.target.value, selectedCountry),
|
||||||
|
)
|
||||||
|
if (phoneError) setPhoneError('')
|
||||||
|
}}
|
||||||
|
onBlur={() =>
|
||||||
|
setPhoneError(
|
||||||
|
getPhoneValidationError(formData.phoneNumber || '', selectedCountry),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
aria-invalid={Boolean(phoneError)}
|
||||||
|
aria-describedby={phoneError ? 'tenant-phone-error' : undefined}
|
||||||
|
title={`Beklenen format: ${phoneMask}`}
|
||||||
|
className={`w-full pl-10 pr-4 py-2 border rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
||||||
|
phoneError
|
||||||
|
? 'border-red-500 dark:border-red-500'
|
||||||
|
: 'border-gray-300 dark:border-gray-700'
|
||||||
|
}`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{phoneError && (
|
||||||
|
<p id="tenant-phone-error" className="mt-1 text-sm text-red-600">
|
||||||
|
{phoneError}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||||
{translate('::Public.common.city')}
|
{translate('::Abp.Account.EmailAddress')}
|
||||||
</label>
|
</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<FaGlobe className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
<FaEnvelope className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="email"
|
||||||
required
|
required
|
||||||
placeholder="İstanbul"
|
placeholder="sample@email.com"
|
||||||
value={formData.city || ''}
|
value={formData.email || ''}
|
||||||
onChange={(e) => handleInputChange('city', e.target.value)}
|
onChange={(e) => {
|
||||||
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
handleInputChange('email', e.target.value)
|
||||||
/>
|
if (emailError) {
|
||||||
</div>
|
setEmailError(
|
||||||
</div>
|
EMAIL_PATTERN.test(e.target.value)
|
||||||
</div>
|
? ''
|
||||||
|
: 'Lütfen geçerli bir e-posta adresi girin.',
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
)
|
||||||
<div>
|
}
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
}}
|
||||||
{translate('::Public.payment.customer.district')}
|
onBlur={() =>
|
||||||
</label>
|
setEmailError(
|
||||||
<div className="relative">
|
EMAIL_PATTERN.test(formData.email || '')
|
||||||
<FaMapPin className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
? ''
|
||||||
<input
|
: 'Lütfen geçerli bir e-posta adresi girin.',
|
||||||
type="text"
|
)
|
||||||
required
|
}
|
||||||
placeholder="Çekmeköy"
|
aria-invalid={Boolean(emailError)}
|
||||||
value={formData.district || ''}
|
aria-describedby={emailError ? 'tenant-email-error' : undefined}
|
||||||
onChange={(e) => handleInputChange('district', e.target.value)}
|
className={`w-full pl-10 pr-4 py-2 border rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
||||||
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
emailError
|
||||||
/>
|
? 'border-red-500 dark:border-red-500'
|
||||||
</div>
|
: 'border-gray-300 dark:border-gray-700'
|
||||||
</div>
|
}`}
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
|
||||||
{translate('::Public.payment.customer.postalCode')}
|
|
||||||
</label>
|
|
||||||
<div className="relative">
|
|
||||||
<FaMapPin className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
required
|
|
||||||
placeholder="34782"
|
|
||||||
value={formData.postalCode || ''}
|
|
||||||
onChange={(e) => handleInputChange('postalCode', e.target.value)}
|
|
||||||
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{emailError && (
|
||||||
|
<p id="tenant-email-error" className="mt-1 text-sm text-red-600">
|
||||||
|
{emailError}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -477,6 +844,8 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{formError && <p className="mt-2 text-sm text-red-600">{formError}</p>}
|
||||||
|
|
||||||
<div className="flex justify-between items-center mt-6">
|
<div className="flex justify-between items-center mt-6">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
@ -489,6 +858,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
disabled={isExisting && !canSubmitExistingTenant}
|
||||||
icon={<FaArrowRight className="w-5 h-5" />}
|
icon={<FaArrowRight className="w-5 h-5" />}
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="green-600"
|
color="green-600"
|
||||||
|
|
@ -503,4 +873,3 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,10 @@ export interface InstallmentOptionDto {
|
||||||
export interface OrderDto {
|
export interface OrderDto {
|
||||||
tenant: CustomTenantDto
|
tenant: CustomTenantDto
|
||||||
items: BasketItem[]
|
items: BasketItem[]
|
||||||
|
billingCycle: BillingCycle
|
||||||
|
period: number
|
||||||
|
licenseStartTime?: string
|
||||||
|
licenseStopTime?: string
|
||||||
subtotal: number
|
subtotal: number
|
||||||
commission: number
|
commission: number
|
||||||
total: number
|
total: number
|
||||||
|
|
|
||||||
45
ui/src/services/location.service.ts
Normal file
45
ui/src/services/location.service.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
import apiService from './api.service'
|
||||||
|
|
||||||
|
export interface CountryDto {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
phoneCode: number
|
||||||
|
phoneNumberMinLength: number | null
|
||||||
|
phoneNumberMaxLength: number | null
|
||||||
|
phoneNumberFormat: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CityDto {
|
||||||
|
id: string
|
||||||
|
country: string
|
||||||
|
name: string
|
||||||
|
plateCode?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DistrictDto {
|
||||||
|
id: string
|
||||||
|
country: string
|
||||||
|
city: string
|
||||||
|
name: string
|
||||||
|
township?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getCountries = () =>
|
||||||
|
apiService.fetchData<CountryDto[]>({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/api/app/public/country',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getCities = (country: string) =>
|
||||||
|
apiService.fetchData<CityDto[]>({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/api/app/public/city',
|
||||||
|
params: { country },
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getDistricts = (country: string, city: string) =>
|
||||||
|
apiService.fetchData<DistrictDto[]>({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/api/app/public/district',
|
||||||
|
params: { country, city },
|
||||||
|
})
|
||||||
|
|
@ -44,6 +44,10 @@ export class OrderService {
|
||||||
data: {
|
data: {
|
||||||
tenant: orderData.tenant,
|
tenant: orderData.tenant,
|
||||||
items: orderData.items,
|
items: orderData.items,
|
||||||
|
billingCycle: orderData.billingCycle,
|
||||||
|
period: orderData.period,
|
||||||
|
licenseStartTime: orderData.licenseStartTime,
|
||||||
|
licenseStopTime: orderData.licenseStopTime,
|
||||||
subtotal: orderData.subtotal,
|
subtotal: orderData.subtotal,
|
||||||
commission: orderData.commission,
|
commission: orderData.commission,
|
||||||
total: orderData.total,
|
total: orderData.total,
|
||||||
|
|
|
||||||
|
|
@ -62,13 +62,34 @@ const Payment: React.FC = () => {
|
||||||
setCartState(clearCart())
|
setCartState(clearCart())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const calculateLicenseStopTime = (startTime: Date, billingCycle: string, period: number) => {
|
||||||
|
const stopTime = new Date(startTime)
|
||||||
|
|
||||||
|
if (billingCycle === 'monthly') {
|
||||||
|
stopTime.setMonth(stopTime.getMonth() + period)
|
||||||
|
} else {
|
||||||
|
stopTime.setFullYear(stopTime.getFullYear() + period)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stopTime
|
||||||
|
}
|
||||||
|
|
||||||
const handlePaymentComplete = async (paymentData: Record<string, unknown>) => {
|
const handlePaymentComplete = async (paymentData: Record<string, unknown>) => {
|
||||||
if (!tenant) return
|
if (!tenant) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const billingCycle = cartState.globalBillingCycle || 'yearly'
|
||||||
|
const period = cartState.globalPeriod > 0 ? cartState.globalPeriod : 1
|
||||||
|
const licenseStartTime = new Date()
|
||||||
|
const licenseStopTime = calculateLicenseStopTime(licenseStartTime, billingCycle, period)
|
||||||
|
|
||||||
const orderData = {
|
const orderData = {
|
||||||
tenant,
|
tenant,
|
||||||
items: cartState.items,
|
items: cartState.items,
|
||||||
|
billingCycle,
|
||||||
|
period,
|
||||||
|
licenseStartTime: licenseStartTime.toISOString(),
|
||||||
|
licenseStopTime: licenseStopTime.toISOString(),
|
||||||
subtotal: cartState.total,
|
subtotal: cartState.total,
|
||||||
commission: paymentData.commission,
|
commission: paymentData.commission,
|
||||||
total: paymentData.total,
|
total: paymentData.total,
|
||||||
|
|
@ -136,20 +157,20 @@ const Payment: React.FC = () => {
|
||||||
|
|
||||||
<div className="container mx-auto px-4 pt-4">
|
<div className="container mx-auto px-4 pt-4">
|
||||||
<PaymentForm
|
<PaymentForm
|
||||||
|
cartState={cartState}
|
||||||
tenant={tenant}
|
tenant={tenant}
|
||||||
onBack={handleBackToTenant}
|
onBack={handleBackToTenant}
|
||||||
onComplete={handlePaymentComplete}
|
onComplete={handlePaymentComplete}
|
||||||
cartState={cartState}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Cart
|
<Cart
|
||||||
|
cartState={cartState}
|
||||||
isOpen={isCartOpen}
|
isOpen={isCartOpen}
|
||||||
|
clearCart={handleClearCart}
|
||||||
|
removeItem={handleRemoveItem}
|
||||||
|
updateQuantity={handleUpdateQuantity}
|
||||||
onClose={() => setIsCartOpen(false)}
|
onClose={() => setIsCartOpen(false)}
|
||||||
onCheckout={handleCheckout}
|
onCheckout={handleCheckout}
|
||||||
cartState={cartState}
|
|
||||||
updateQuantity={handleUpdateQuantity}
|
|
||||||
removeItem={handleRemoveItem}
|
|
||||||
clearCart={handleClearCart}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue