diff --git a/SystemKonkursow/4.2.1/angular/src/app/competition-detail/competition-detail.component.ts b/SystemKonkursow/4.2.1/angular/src/app/competition-detail/competition-detail.component.ts index 9303aa6..6bb0100 100644 --- a/SystemKonkursow/4.2.1/angular/src/app/competition-detail/competition-detail.component.ts +++ b/SystemKonkursow/4.2.1/angular/src/app/competition-detail/competition-detail.component.ts @@ -3,12 +3,14 @@ import { appModuleAnimation } from '@shared/animations/routerTransition'; import { AppComponentBase } from '@shared/app-component-base'; import { Subscription } from 'rxjs/Rx'; import { ActivatedRoute } from '@angular/router'; +import { mergeMap } from 'rxjs/operators'; import { finalize } from 'rxjs/operators'; import { forkJoin } from 'rxjs'; import { CompetitionServiceProxy, CompetitionDto, QuestionDto, - QuestionOptionDto } from '@shared/service-proxies/service-proxies'; + QuestionOptionDto, + CreateRankingPositionDto } from '@shared/service-proxies/service-proxies'; @Component({ templateUrl: './competition-detail.component.html', @@ -19,6 +21,7 @@ export class CompetitionDetailComponent extends AppComponentBase implements OnIn private paramSubscription: Subscription; private routeSubscription: Subscription; + private solveSubscription: Subscription; public competitionId: number; public competition: CompetitionDto = null; @@ -121,7 +124,23 @@ export class CompetitionDetailComponent extends AppComponentBase implements OnIn ) points += 1; }); - console.log('Punkty: ' + points); + console.log('Points: ' + points); + let rankingPosition = new CreateRankingPositionDto(); + + rankingPosition.competitionId = this.competitionId; + rankingPosition.points = points; + + this.setBusy(this.competitionDetailAreaId); + + this.solveSubscription = this._competitionService.solveCompetition(rankingPosition) + .pipe(mergeMap((result: number) => { + const solveCompetitionStream = this._competitionService.canSolveCompetition(this.competitionId); + return solveCompetitionStream.pipe(finalize(() => { this.clearBusy(this.competitionDetailAreaId); })); + })) + .subscribe((data: boolean) => { + this.canSolveCompetition = data; + }); + this.mode = 'result'; } @@ -133,6 +152,10 @@ export class CompetitionDetailComponent extends AppComponentBase implements OnIn if (this.routeSubscription) { this.routeSubscription.unsubscribe(); } + + if (this.solveSubscription) { + this.solveSubscription.unsubscribe(); + } } } \ No newline at end of file diff --git a/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxies.ts b/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxies.ts index 37bebd7..2b5d962 100644 --- a/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxies.ts +++ b/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxies.ts @@ -329,6 +329,62 @@ export class CompetitionServiceProxy { return _observableOf(null); } + /** + * @input (optional) + * @return Success + */ + solveCompetition(input: CreateRankingPositionDto | null | undefined): Observable { + let url_ = this.baseUrl + "/api/services/app/Competition/SolveCompetition"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(input); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processSolveCompetition(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processSolveCompetition(response_); + } catch (e) { + return >_observableThrow(e); + } + } else + return >_observableThrow(response_); + })); + } + + protected processSolveCompetition(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response).error instanceof Blob ? (response).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }}; + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => { + let result200: any = null; + let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result200 = resultData200 !== undefined ? resultData200 : null; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null); + } + /** * @competitionId (optional) * @return Success @@ -2508,6 +2564,53 @@ export interface IQuestionOptionDto { id: number | undefined; } +export class CreateRankingPositionDto implements ICreateRankingPositionDto { + competitionId: number | undefined; + points: number | undefined; + + constructor(data?: ICreateRankingPositionDto) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) + (this)[property] = (data)[property]; + } + } + } + + init(data?: any) { + if (data) { + this.competitionId = data["competitionId"]; + this.points = data["points"]; + } + } + + static fromJS(data: any): CreateRankingPositionDto { + data = typeof data === 'object' ? data : {}; + let result = new CreateRankingPositionDto(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data["competitionId"] = this.competitionId; + data["points"] = this.points; + return data; + } + + clone(): CreateRankingPositionDto { + const json = this.toJSON(); + let result = new CreateRankingPositionDto(); + result.init(json); + return result; + } +} + +export interface ICreateRankingPositionDto { + competitionId: number | undefined; + points: number | undefined; +} + export class ChangeUiThemeInput implements IChangeUiThemeInput { theme: string; diff --git a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/Competition/CompetitionCategory/CompetitionAppService.cs b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/Competition/CompetitionCategory/CompetitionAppService.cs index 9c9e6a2..7c85371 100644 --- a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/Competition/CompetitionCategory/CompetitionAppService.cs +++ b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/Competition/CompetitionCategory/CompetitionAppService.cs @@ -18,13 +18,15 @@ namespace SystemKonkursow.Competition.CompetitionCategory private readonly IRepository _questionOptionRepository; private readonly UserManager _userManager; private readonly IRepository _participantRepository; + private readonly IRepository _rankingPositionRepository; public CompetitionAppService(IRepository competitionCategoryRepository, IRepository competitionRepository, IRepository questionRepository, IRepository questionOptionRepository, UserManager userManager, - IRepository participantRepository) + IRepository participantRepository, + IRepository rankingPositionRepository) { _competitionCategoryRepository = competitionCategoryRepository; _competitionRepository = competitionRepository; @@ -32,6 +34,7 @@ namespace SystemKonkursow.Competition.CompetitionCategory _questionOptionRepository = questionOptionRepository; _userManager = userManager; _participantRepository = participantRepository; + _rankingPositionRepository = rankingPositionRepository; } [AbpAuthorize] @@ -123,6 +126,20 @@ namespace SystemKonkursow.Competition.CompetitionCategory return mappedObject; } + [AbpAuthorize] + public async Task SolveCompetition(CreateRankingPositionDto input) + { + var user = await GetCurrentUserAsync(); + + var mappedRankingPosition = ObjectMapper.Map(input); + + mappedRankingPosition.UserId = user.Id; + + var newRankingPositionId = await _rankingPositionRepository.InsertAndGetIdAsync(mappedRankingPosition); + + return newRankingPositionId; + } + [AbpAuthorize] public async Task CanSolveCompetition(int competitionId) { @@ -143,6 +160,13 @@ namespace SystemKonkursow.Competition.CompetitionCategory return false; } + var rankingPosition = await _rankingPositionRepository.GetAll().Where(t => t.UserId == user.Id).FirstOrDefaultAsync(); + + if (null != rankingPosition) + { + return false; + } + return true; } diff --git a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/Competition/CompetitionCategory/Dto/CompetitionCategoryMapProfile.cs b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/Competition/CompetitionCategory/Dto/CompetitionCategoryMapProfile.cs index 566a0d8..bc7b293 100644 --- a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/Competition/CompetitionCategory/Dto/CompetitionCategoryMapProfile.cs +++ b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/Competition/CompetitionCategory/Dto/CompetitionCategoryMapProfile.cs @@ -22,6 +22,8 @@ namespace SystemKonkursow.Competition.CompetitionCategory.Dto CreateMap() .ForMember(dest => dest.CreatorName, opt => opt.MapFrom(src => src.Creator.UserName)); + + CreateMap(); } } } diff --git a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/Competition/CompetitionCategory/Dto/CreateRankingPositionDto.cs b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/Competition/CompetitionCategory/Dto/CreateRankingPositionDto.cs new file mode 100644 index 0000000..560e2e4 --- /dev/null +++ b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/Competition/CompetitionCategory/Dto/CreateRankingPositionDto.cs @@ -0,0 +1,9 @@ +namespace SystemKonkursow.Competition.CompetitionCategory.Dto +{ + public class CreateRankingPositionDto + { + public long CompetitionId { get; set; } + + public int Points { get; set; } + } +} diff --git a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Core/Domain/RankingPosition.cs b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Core/Domain/RankingPosition.cs new file mode 100644 index 0000000..bc4c3da --- /dev/null +++ b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Core/Domain/RankingPosition.cs @@ -0,0 +1,22 @@ +using Abp.Domain.Entities; +using System.ComponentModel.DataAnnotations.Schema; +using SystemKonkursow.Authorization.Users; + +namespace SystemKonkursow.Domain +{ + [Table("RankingPositions")] + public class RankingPosition : Entity + { + public long UserId { get; set; } + + public long CompetitionId { get; set; } + + public int Points { get; set; } + + [ForeignKey(nameof(UserId))] + public virtual User User { get; set; } + + [ForeignKey(nameof(CompetitionId))] + public virtual Competition Competition { get; set; } + } +} diff --git a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/EntityFrameworkCore/SystemKonkursowDbContext.cs b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/EntityFrameworkCore/SystemKonkursowDbContext.cs index 94b77b1..3cee3ff 100644 --- a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/EntityFrameworkCore/SystemKonkursowDbContext.cs +++ b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/EntityFrameworkCore/SystemKonkursowDbContext.cs @@ -28,5 +28,7 @@ namespace SystemKonkursow.EntityFrameworkCore public DbSet QuestionOptions { get; set; } + public DbSet RankingPositions { get; set; } + } } diff --git a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/Migrations/SystemKonkursowDbContextModelSnapshot.cs b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/Migrations/SystemKonkursowDbContextModelSnapshot.cs index 38a3d2c..7daaed2 100644 --- a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/Migrations/SystemKonkursowDbContextModelSnapshot.cs +++ b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/Migrations/SystemKonkursowDbContextModelSnapshot.cs @@ -1134,6 +1134,27 @@ namespace SystemKonkursow.Migrations b.ToTable("QuestionOptions"); }); + modelBuilder.Entity("SystemKonkursow.Domain.RankingPosition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CompetitionId"); + + b.Property("Points"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("CompetitionId"); + + b.HasIndex("UserId"); + + b.ToTable("RankingPositions"); + }); + modelBuilder.Entity("SystemKonkursow.MultiTenancy.Tenant", b => { b.Property("Id") @@ -1379,6 +1400,19 @@ namespace SystemKonkursow.Migrations .OnDelete(DeleteBehavior.Cascade); }); + modelBuilder.Entity("SystemKonkursow.Domain.RankingPosition", b => + { + b.HasOne("SystemKonkursow.Domain.Competition", "Competition") + .WithMany() + .HasForeignKey("CompetitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("SystemKonkursow.Authorization.Users.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + modelBuilder.Entity("SystemKonkursow.MultiTenancy.Tenant", b => { b.HasOne("SystemKonkursow.Authorization.Users.User", "CreatorUser") diff --git a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/SystemKonkursow.EntityFrameworkCore.csproj b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/SystemKonkursow.EntityFrameworkCore.csproj index 68c6fa9..dcbd57e 100644 --- a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/SystemKonkursow.EntityFrameworkCore.csproj +++ b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.EntityFrameworkCore/SystemKonkursow.EntityFrameworkCore.csproj @@ -25,7 +25,4 @@ - - - \ No newline at end of file