From db13b1ab1b81934a8e0dbf0fdc22d95e986799f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Zieli=C5=84ski?= Date: Mon, 19 Dec 2022 18:36:57 +0100 Subject: [PATCH] Login fix and rename columns in DB --- Frontend/src/app/auth/auth.service.ts | 12 +- .../login-page/login-page.component.html | 3 + .../login-page/login-page.component.ts | 59 ++++-- .../src/app/main-view/main-view.component.ts | 3 +- Frontend/src/app/models/dataRow.model copy.ts | 2 +- Frontend/src/app/models/dataSet.model.ts | 20 +- .../data-set-edit.component.html | 45 +++- .../data-set-edit.component.scss | 6 +- .../data-set-edit/data-set-edit.component.ts | 24 ++- WebAPI/Controllers/AuthController.cs | 2 +- WebAPI/Controllers/DataSetsController.cs | 9 + .../20221219163620_RenameFields.Designer.cs | 197 ++++++++++++++++++ .../Migrations/20221219163620_RenameFields.cs | 73 +++++++ .../Migrations/AppDbContextModelSnapshot.cs | 15 +- WebAPI/Models/DataRow.cs | 4 +- WebAPI/Models/DataSet.cs | 12 +- WebAPI/WebAPI.csproj | 1 + WebAPI/dataParsers/csv.parser.cs | 49 +++++ 18 files changed, 480 insertions(+), 56 deletions(-) create mode 100644 WebAPI/Migrations/20221219163620_RenameFields.Designer.cs create mode 100644 WebAPI/Migrations/20221219163620_RenameFields.cs create mode 100644 WebAPI/dataParsers/csv.parser.cs diff --git a/Frontend/src/app/auth/auth.service.ts b/Frontend/src/app/auth/auth.service.ts index 660b6e5..0ad558d 100644 --- a/Frontend/src/app/auth/auth.service.ts +++ b/Frontend/src/app/auth/auth.service.ts @@ -1,5 +1,6 @@ -import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { MatSnackBar } from '@angular/material/snack-bar'; import { environment } from 'src/environments/environment'; import { User } from '../models/user.model'; @@ -12,7 +13,7 @@ export class AuthService { user!: User; constructor( - private http$: HttpClient + private http$: HttpClient, ) { } ping() { @@ -33,20 +34,17 @@ export class AuthService { getAPIToken(credentials: string): Promise { return new Promise((resolve, reject) => { const header = new HttpHeaders().set('Content-type', 'application/json'); - this.http$.post(`${environment.api.url}/auth/apiToken`, JSON.stringify(credentials), { headers: header }).subscribe({ + this.http$.post(`${environment.api.url}/auth/apiToken`, JSON.stringify(credentials), { headers: header }).subscribe({ next: (data) => { this.user.id = data.id; this.apiToken = data.token; resolve(data); }, - error: (e) => { - console.error('apiToken error', e); + error: (e: HttpErrorResponse) => { reject(e); } } ); }); - //const header = new HttpHeaders().set('Content-type', 'application/json'); - //return this.httpClient.post(this.path + "LoginWithGoogle", JSON.stringify(credentials), { headers: header }); } } diff --git a/Frontend/src/app/components/login-page/login-page.component.html b/Frontend/src/app/components/login-page/login-page.component.html index 19bdcf4..e5243c7 100644 --- a/Frontend/src/app/components/login-page/login-page.component.html +++ b/Frontend/src/app/components/login-page/login-page.component.html @@ -1,3 +1,6 @@ +
+ +
diff --git a/Frontend/src/app/components/login-page/login-page.component.ts b/Frontend/src/app/components/login-page/login-page.component.ts index 1beebc8..ca00928 100644 --- a/Frontend/src/app/components/login-page/login-page.component.ts +++ b/Frontend/src/app/components/login-page/login-page.component.ts @@ -1,4 +1,6 @@ +import { HttpErrorResponse } from '@angular/common/http'; import { Component, NgZone, OnInit } from '@angular/core'; +import { MatSnackBar } from '@angular/material/snack-bar'; import { Router } from '@angular/router'; import jwt_decode from "jwt-decode"; import { AuthService } from 'src/app/auth/auth.service'; @@ -14,34 +16,37 @@ import { environment } from 'src/environments/environment'; export class LoginPageComponent implements OnInit { constructor( - private data$: DataService, private router$: Router, private auth$: AuthService, - private ngZone$: NgZone - ) {} + private ngZone$: NgZone, + private snackBar$: MatSnackBar + ) { } + + loading: boolean = false; ngOnInit(): void { + this.snackBar$.open("", "", { duration: 1 }); + // @ts-ignore + window.onGoogleLibraryLoad = () => { // @ts-ignore - window.onGoogleLibraryLoad = () => { - // @ts-ignore - google.accounts.id.initialize({ - client_id: environment.google.clientId, - callback: this.handleCredentialResponse.bind(this), - auto_select: true, - cancel_on_tap_outside: true - }); - // @ts-ignore - google.accounts.id.renderButton( + google.accounts.id.initialize({ + client_id: environment.google.clientId, + callback: this.handleCredentialResponse.bind(this), + auto_select: true, + cancel_on_tap_outside: true + }); + // @ts-ignore + google.accounts.id.renderButton( // @ts-ignore document.getElementById("google-button"), - { theme: "outline", size: "large", width: "100%" } - ); - // @ts-ignore - google.accounts.id.prompt((notification: PromptMomentNotification) => {}); - }; + { theme: "outline", size: "large", width: "100%" } + ); + // @ts-ignore + google.accounts.id.prompt((notification: PromptMomentNotification) => { }); + }; } - async handleCredentialResponse(response: any) { + async handleCredentialResponse(response: any) { try { const responsePayload: any = jwt_decode(response.credential); this.auth$.user = new User({ @@ -50,12 +55,20 @@ export class LoginPageComponent implements OnInit { email: responsePayload.email, avatar: responsePayload.picture }); - this.ngZone$.run(() => { + this.loading = true; + await this.auth$.getAPIToken(response.credential); + this.ngZone$.run(() => { this.router$.navigate(['/app']); }); - await this.auth$.getAPIToken(response.credential); - } catch (e) { - console.error('Get user error', e); + } catch (e: any) { + this.loading = false; + if (e.status === 401) { + this.snackBar$.open("Użytkownik nie istnieje w bazie danych aplikacji Diuna.", "", { duration: 3000 }); + } else { + this.snackBar$.open("Błąd połączenia z serwerem. Skontaktuj się z administratorem.", "", { duration: 3000 }); + } + } finally { + this.loading = false; } } } diff --git a/Frontend/src/app/main-view/main-view.component.ts b/Frontend/src/app/main-view/main-view.component.ts index fdcdffd..5206dd9 100644 --- a/Frontend/src/app/main-view/main-view.component.ts +++ b/Frontend/src/app/main-view/main-view.component.ts @@ -53,7 +53,6 @@ export class MainViewComponent { logout() { // @ts-ignore google.accounts.id.disableAutoSelect(); - this.router$.navigate(['']); - this.auth$.user = new User({}); + this.reloadApp(); } } diff --git a/Frontend/src/app/models/dataRow.model copy.ts b/Frontend/src/app/models/dataRow.model copy.ts index 8665d9c..4399f0d 100644 --- a/Frontend/src/app/models/dataRow.model copy.ts +++ b/Frontend/src/app/models/dataRow.model copy.ts @@ -6,7 +6,7 @@ import { DataService } from '../services/data.service'; import { map } from 'rxjs'; export class DataRow extends Base { - mpk?: string; + code?: string; value?: number; desc1?: string; desc2?: string; diff --git a/Frontend/src/app/models/dataSet.model.ts b/Frontend/src/app/models/dataSet.model.ts index 7874ce3..8b1cabb 100644 --- a/Frontend/src/app/models/dataSet.model.ts +++ b/Frontend/src/app/models/dataSet.model.ts @@ -2,12 +2,12 @@ import { Base } from './base.model'; import { UntypedFormBuilder, Validators, UntypedFormGroup } from '@angular/forms'; import { HttpClient } from '@angular/common/http'; import { environment } from 'src/environments/environment'; -import { DataService } from '../services/data.service'; import { map } from 'rxjs'; import { DataRow } from './dataRow.model copy'; export class DataSet extends Base { - number?: string; + number?: Number; + source?: string; name?: string; dataRows: DataRow[] = []; @@ -22,8 +22,8 @@ export class DataSet extends Base { static getForm(fb: UntypedFormBuilder) { return fb.group({ id: [null], - number: ['', Validators.required], name: ['', Validators.required], + source: ['', Validators.required], createdAt: '', modifiedAt: '', createdBy: '', @@ -84,6 +84,20 @@ export class DataSet extends Base { }) }); } + static parseFile(file: any, _http: HttpClient): Promise { + const formData = new FormData(); + formData.append(file.name, file); + return new Promise((resolve, reject) => { + _http.post(`${environment.api.url}/datasets/parseFile`, formData, + ).pipe(map(data => data.map(x => new DataRow().deserialize(x)))) + .subscribe({ + next: (data) => { + resolve(data); + }, + error: (e) => reject(e) + }) + }) + } /* static delete(id: string, _http: HttpClient): Promise { return new Promise((resolve, reject)=> { diff --git a/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.html b/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.html index fe7a0c4..ae77a1a 100644 --- a/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.html +++ b/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.html @@ -2,7 +2,7 @@
- Edycja zbioru danych + Edycja warstwy danych @@ -11,9 +11,9 @@ - Numer - - + Nazwa + + Pole obowiązkowe @@ -21,19 +21,48 @@ - - Import ręczny - Arkusz Google + + CSV + GoogleSheet SAP Symfonia - + Pole obowiązkowe + + + + + + + MPK + {{item.code}} + + + + Konto + {{item.desc1}} + + + + Wartość + {{item.value | number:'1.2-2'}} + + + + + + +
diff --git a/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.scss b/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.scss index b199958..38ef489 100644 --- a/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.scss +++ b/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.scss @@ -1 +1,5 @@ -@import "../../../main-view/main-view.component.scss"; \ No newline at end of file +@import "../../../main-view/main-view.component.scss"; + +.file-input { + display: none; +} \ No newline at end of file diff --git a/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.ts b/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.ts index 8d7e4a6..c078102 100644 --- a/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.ts +++ b/Frontend/src/app/modules/data-sets/data-set-edit/data-set-edit.component.ts @@ -1,10 +1,14 @@ import { HttpClient } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { MatTableDataSource } from '@angular/material/table'; import { Router, ActivatedRoute } from '@angular/router'; import moment from 'moment'; import { AuthService } from 'src/app/auth/auth.service'; +import { DataRow } from 'src/app/models/dataRow.model copy'; import { DataSet } from 'src/app/models/dataSet.model'; import { DataService } from 'src/app/services/data.service'; import { v4 as uuidv4 } from 'uuid'; @@ -19,6 +23,12 @@ export class DataSetEditComponent implements OnInit { public form!: UntypedFormGroup; private document!: DataSet; + displayedColumns = ['code', 'value', 'desc1']; + dataSource!: MatTableDataSource; + + @ViewChild(MatPaginator) paginator!: MatPaginator; + @ViewChild(MatSort) sort!: MatSort; + constructor( private fb$: UntypedFormBuilder, private router$: Router, @@ -62,7 +72,17 @@ export class DataSetEditComponent implements OnInit { } generateNumber() { this.form.patchValue({ - number: `${this.form.controls['name'].value}-${moment().format("YYYY")}-${moment().format("MM")}` + name: `${this.form.controls['source'].value}-${moment().format("YYYY")}${moment().format("MM")}${moment().format("DD")}${moment().format("HH")}${moment().format("mm")}` }) } + async onFileSelected(event : any) { + const file = event.target.files[0]; + this.document.dataRows = await DataSet.parseFile(file, this.http$); + this.dataSource = new MatTableDataSource(this.document.dataRows); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + trackByUid(index : number, item : DataRow) { + return item.id; + } } diff --git a/WebAPI/Controllers/AuthController.cs b/WebAPI/Controllers/AuthController.cs index 2b13d28..0e06fbd 100644 --- a/WebAPI/Controllers/AuthController.cs +++ b/WebAPI/Controllers/AuthController.cs @@ -40,7 +40,7 @@ namespace WebAPI.Controllers } else { - return BadRequest(); + return Unauthorized(); } } diff --git a/WebAPI/Controllers/DataSetsController.cs b/WebAPI/Controllers/DataSetsController.cs index 0c8eda7..100d029 100644 --- a/WebAPI/Controllers/DataSetsController.cs +++ b/WebAPI/Controllers/DataSetsController.cs @@ -9,6 +9,7 @@ using System.Configuration; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; +using WebAPI.dataParsers; using WebAPI.Models; namespace WebAPI.Controllers @@ -33,5 +34,13 @@ namespace WebAPI.Controllers return BadRequest(e.ToString()); } } + [HttpPost] + [DisableRequestSizeLimit] + [Route("parseFile")] + public IActionResult ParseFile() + { + var parser = new csvParser(); + return Ok(parser.parse(Request.Form.Files[0])); + } } } \ No newline at end of file diff --git a/WebAPI/Migrations/20221219163620_RenameFields.Designer.cs b/WebAPI/Migrations/20221219163620_RenameFields.Designer.cs new file mode 100644 index 0000000..ee6d2ce --- /dev/null +++ b/WebAPI/Migrations/20221219163620_RenameFields.Designer.cs @@ -0,0 +1,197 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using WebAPI; + +#nullable disable + +namespace WebAPI.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20221219163620_RenameFields")] + partial class RenameFields + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("WebAPI.Models.DataRow", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("DataSetId") + .HasColumnType("uniqueidentifier"); + + b.Property("Desc1") + .HasColumnType("nvarchar(max)"); + + b.Property("Desc2") + .HasColumnType("nvarchar(max)"); + + b.Property("Desc3") + .HasColumnType("nvarchar(max)"); + + b.Property("Desc4") + .HasColumnType("nvarchar(max)"); + + b.Property("Desc5") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModifiedAt") + .HasColumnType("datetime2"); + + b.Property("ModifiedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Value") + .HasColumnType("real"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DataSetId"); + + b.HasIndex("ModifiedById"); + + b.ToTable("DataRows"); + }); + + modelBuilder.Entity("WebAPI.Models.DataSet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModifiedAt") + .HasColumnType("datetime2"); + + b.Property("ModifiedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Number") + .IsRequired() + .HasColumnType("int"); + + b.Property("Source") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ModifiedById"); + + b.ToTable("DataSets"); + }); + + modelBuilder.Entity("WebAPI.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("UserName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("WebAPI.Models.DataRow", b => + { + b.HasOne("WebAPI.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WebAPI.Models.DataSet", null) + .WithMany("DataRows") + .HasForeignKey("DataSetId"); + + b.HasOne("WebAPI.Models.User", "ModifiedBy") + .WithMany() + .HasForeignKey("ModifiedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("ModifiedBy"); + }); + + modelBuilder.Entity("WebAPI.Models.DataSet", b => + { + b.HasOne("WebAPI.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WebAPI.Models.User", "ModifiedBy") + .WithMany() + .HasForeignKey("ModifiedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("ModifiedBy"); + }); + + modelBuilder.Entity("WebAPI.Models.DataSet", b => + { + b.Navigation("DataRows"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/WebAPI/Migrations/20221219163620_RenameFields.cs b/WebAPI/Migrations/20221219163620_RenameFields.cs new file mode 100644 index 0000000..03bcec5 --- /dev/null +++ b/WebAPI/Migrations/20221219163620_RenameFields.cs @@ -0,0 +1,73 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace WebAPI.Migrations +{ + /// + public partial class RenameFields : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "MPK", + table: "DataRows", + newName: "Code"); + + migrationBuilder.AlterColumn( + name: "Number", + table: "DataSets", + type: "int", + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(max)"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "DataSets", + type: "nvarchar(max)", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AddColumn( + name: "Source", + table: "DataSets", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Source", + table: "DataSets"); + + migrationBuilder.RenameColumn( + name: "Code", + table: "DataRows", + newName: "MPK"); + + migrationBuilder.AlterColumn( + name: "Number", + table: "DataSets", + type: "nvarchar(max)", + nullable: false, + oldClrType: typeof(int), + oldType: "int"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "DataSets", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)"); + } + } +} diff --git a/WebAPI/Migrations/AppDbContextModelSnapshot.cs b/WebAPI/Migrations/AppDbContextModelSnapshot.cs index 92ff024..43e1acb 100644 --- a/WebAPI/Migrations/AppDbContextModelSnapshot.cs +++ b/WebAPI/Migrations/AppDbContextModelSnapshot.cs @@ -28,6 +28,10 @@ namespace WebAPI.Migrations .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); + b.Property("Code") + .IsRequired() + .HasColumnType("nvarchar(max)"); + b.Property("CreatedAt") .HasColumnType("datetime2"); @@ -55,10 +59,6 @@ namespace WebAPI.Migrations b.Property("IsDeleted") .HasColumnType("bit"); - b.Property("MPK") - .IsRequired() - .HasColumnType("nvarchar(max)"); - b.Property("ModifiedAt") .HasColumnType("datetime2"); @@ -101,9 +101,14 @@ namespace WebAPI.Migrations .HasColumnType("uniqueidentifier"); b.Property("Name") + .IsRequired() .HasColumnType("nvarchar(max)"); - b.Property("Number") + b.Property("Number") + .IsRequired() + .HasColumnType("int"); + + b.Property("Source") .IsRequired() .HasColumnType("nvarchar(max)"); diff --git a/WebAPI/Models/DataRow.cs b/WebAPI/Models/DataRow.cs index 511d084..4578f93 100644 --- a/WebAPI/Models/DataRow.cs +++ b/WebAPI/Models/DataRow.cs @@ -8,7 +8,7 @@ namespace WebAPI.Models [Key] public Guid Id { get; set; } [Required] - public string? MPK { get; set; } + public string? Code { get; set; } [Required] public float Value { get; set; } //Description fields @@ -22,8 +22,10 @@ namespace WebAPI.Models public bool IsDeleted { get; set; } #endregion #region Relations + [Required] public Guid CreatedById { get; set; } public User? CreatedBy { get; set; } + [Required] public Guid ModifiedById { get; set; } public User? ModifiedBy { get; set; } #endregion diff --git a/WebAPI/Models/DataSet.cs b/WebAPI/Models/DataSet.cs index 9e0a0fc..30fd8e8 100644 --- a/WebAPI/Models/DataSet.cs +++ b/WebAPI/Models/DataSet.cs @@ -8,16 +8,24 @@ namespace WebAPI.Models [Key] public Guid Id { get; set; } [Required] - public string? Number { get; set; } + public int? Number { get; set; } + [Required] + public string? Source { get; set; } + [Required] public string? Name { get; set; } + [Required] public DateTime CreatedAt { get; set; } + [Required] public DateTime ModifiedAt { get; set; } + [Required] public bool IsDeleted { get; set; } #endregion #region Relations - public ICollection? DataRows { get; set; } + public ICollection? DataRows { get; set; } + [Required] public Guid CreatedById { get; set; } public User? CreatedBy { get; set; } + [Required] public Guid ModifiedById { get; set; } public User? ModifiedBy { get; set; } #endregion diff --git a/WebAPI/WebAPI.csproj b/WebAPI/WebAPI.csproj index f2a2ba6..dead182 100644 --- a/WebAPI/WebAPI.csproj +++ b/WebAPI/WebAPI.csproj @@ -7,6 +7,7 @@ + diff --git a/WebAPI/dataParsers/csv.parser.cs b/WebAPI/dataParsers/csv.parser.cs new file mode 100644 index 0000000..f9fe1f4 --- /dev/null +++ b/WebAPI/dataParsers/csv.parser.cs @@ -0,0 +1,49 @@ +using CsvHelper; +using CsvHelper.Configuration; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using System.Formats.Asn1; +using System.Globalization; +using System.Text; +using WebAPI.Models; + +namespace WebAPI.dataParsers +{ + public class csvParser + { + public List parse(IFormFile file) + { + List dataRows = new List(); + + var stream = new StreamReader(file.OpenReadStream()); + string content = stream.ReadToEnd(); + + List lines = content.Split("\n").ToList(); + List> data = new List>(); + foreach (string line in lines) + { + data.Add(line.Split(";").ToList()); + } + + for (int i = 1; i < data[0].Count; i++) + { + for (int j = 1; j < data.Count; j++) { + if (data[j][0].Length > 0) + { + float value = float.Parse(data[j][i]); + if (value > 0) + { + DataRow dataRow = new DataRow(); + dataRow.Id = Guid.NewGuid(); + dataRow.Code = data[0][i]; + dataRow.Desc1 = data[j][0]; + dataRow.Value = value; + dataRows.Add(dataRow); + } + } + }; + } + + return dataRows; + } + } +}