the absolute state of S T U F F

This commit is contained in:
femsci 2023-11-18 11:01:11 +01:00
parent 17ed4cdb6f
commit c22d5c6d82
Signed by: femsci
GPG key ID: 08F7911F0E650C67
28 changed files with 12110 additions and 95 deletions

2
.gitignore vendored
View file

@ -3,3 +3,5 @@
**/target/
/build
/umogenkey.secret
**.db
**.db-*

BIN
out.pdf Normal file

Binary file not shown.

View file

@ -1,11 +1,18 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Nyanlabs.Umogen.Core.Models;
public class LegalEntity(string Name, string? Nip = null, string? Headquarters = null, Person? Representative = null) : IEntity, INLSerializable
public class LegalEntity : IEntity, INLSerializable
{
public string Name { get; set; } = Name;
public string? Nip { get; set; } = Nip;
public string? Headquarters { get; set; } = Headquarters;
public Person? Representative { get; set; } = Representative;
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public long Id { get; set; }
public string Name { get; set; } = default!;
public string? Nip { get; set; } = default!;
public string? Headquarters { get; set; }
public Person? Representative { get; set; }
public long? PersonId { get; set; }
public string GetName()
{
@ -24,6 +31,6 @@ public class LegalEntity(string Name, string? Nip = null, string? Headquarters =
public string SerializeToDocument()
{
return $"{Name}, reprezentowaną przez {Representative.GetName()}";
return $"{Name}{(Representative != null ? $", reprezentowaną przez {Representative.GetName()}" : "")}";
}
}

View file

@ -1,13 +1,23 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
namespace Nyanlabs.Umogen.Core.Models;
public record Person(string Name, string Surname, string? Id = null, string? Pesel = null, DateTime? DoB = null) : IEntity, INLSerializable
public record Person(string Name, string Surname, string IdC, string Pesel, DateTime? DoB = null) : IEntity, INLSerializable
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public long Id { get; set; }
public string Name { get; set; } = Name;
public string Surname { get; set; } = Surname;
public string? IDCode { get; set; } = Id;
public string? Pesel { get; set; } = Pesel;
public string IDCode { get; set; } = IdC;
public string Pesel { get; set; } = Pesel;
public DateTime? DoB { get; set; } = DoB;
[JsonIgnore]
public virtual ICollection<LegalEntity> Companies { get; set; }
public string GetName()
{
return $"{Name} {Surname}";

View file

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace Nyanlabs.Umogen.Core.Models;

View file

@ -27,6 +27,6 @@ public readonly struct ValidTime : INLSerializable, IDocSerializable
public string SerializeToDocument()
{
return this.Start != DateTime.MaxValue ? $"na czas od {Start:dd MMM yyyy} do {End:dd MMM yyyy}" : "na czas nieokreślony";
return this.Start != DateTime.MaxValue ? $"na czas od {Start:dd.MM.yyyy} do {End:dd.MM.yyyy}" : "na czas nieokreślony";
}
}

View file

@ -27,6 +27,7 @@ public class SseConsumer<TEvent> : IDisposable, IAsyncDisposable
yield return JsonSerializer.Deserialize<TEvent>(line, Umogen.JSON_OPTS) ?? throw new DataException("Invalid data...");
}
reader.Close();
}
public void Dispose()

View file

@ -0,0 +1,21 @@
using Microsoft.EntityFrameworkCore;
using Nyanlabs.Umogen.Core.Models;
namespace Nyanlabs.Umogen.Server;
public class DataContext : DbContext
{
public DbSet<Person> Persons => Set<Person>();
public DbSet<LegalEntity> Companies => Set<LegalEntity>();
protected override void OnConfiguring(DbContextOptionsBuilder o)
{
o.UseSqlite("Data Source=data.db;");
}
protected override void OnModelCreating(ModelBuilder m)
{
m.Entity<LegalEntity>().HasOne(e => e.Representative).WithMany(e => e.Companies);
}
}

View file

@ -6,6 +6,8 @@
<ItemGroup>
<PackageReference Include="Femsci.AspapajNet" Version="1.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0" />
</ItemGroup>
<PropertyGroup>

View file

@ -2,19 +2,43 @@
@using Umogen.Core;
@using Umogen.Core.Models;
@inject IJSRuntime js
@inject DataContext db
@using Microsoft.EntityFrameworkCore;
<PageTitle>Umowy</PageTitle>
<h2 class="text-center">Umowy</h2>
<div class="form-control">
<input type="text" placeholder="Osoba" @bind-value="_person" />
</div>
<div class="form-control">
<input type="text" placeholder="Wynagrodzenie" @bind-value="_value" />
</div>
<div class="form-control">
<input type="text" placeholder="Wpisz dane" @bind-value="_prompt" />
<div class="container">
<form>
<div class="row justify-content-center align-items-center g-2">
<div class="col mb-3">
<label for="employer" class="form-label">Pracodawca (PESEL lub NIP)</label>
<input type="text" class="form-control" id="employer" @onchange="ChgEmployer" value="@_employerId">
<span class="validation-message">@(employer == null ? "" : $"{employer.GetName()}")</span>
</div>
<div class="col mb-3">
<label for="employee" class="form-label">Pracownik (PESEL)</label>
<input type="text" class="form-control" id="employee" @onchange="ChgEmployee" value="@_employeeId">
<span class="validation-message">@(employee == null ? "" : $"{employee.Name} {employee.Surname}")</span>
</div>
</div>
<div class="row justify-content-center align-items-center g-2">
<div class="col mb-3">
<label for="validity" class="form-label">Okres trwania [dni]</label>
<input type="text" class="form-control" id="validity" @onchange="ChgValidity" value="@_validityText">
</div>
<div class="col mb-3">
<label for="value" class="form-label">Wynagrodzenie [PLN]</label>
<input type="number" class="form-control" id="value" @bind-value="_payment">
</div>
</div>
<div class="col mb-3">
<label for="query" class="form-label">Dane (NLP)</label>
<input type="text" class="form-control" id="query" @bind-value="_query">
</div>
<button disabled="@disB" type="button" @onclick="Process" class="btn btn-primary">Generuj</button>
</form>
</div>
@ -22,19 +46,69 @@
<div class="text-center"><b>OUT:</b> @output</div>
</div>
<button class="btn btn-primary" @onclick="Process">Wyszukaj</button>
@code {
private string _prompt, _person, _value;
private string _employerId = "", _employeeId = "";
private Person? employee;
private IEntity? employer;
private string _query = "";
private ValidTime _validity;
private decimal _payment;
private string output = "";
private bool disB = false;
private async Task ChgEmployer(ChangeEventArgs e)
{
_employerId = (string)e.Value!;
employer = await db.Persons.AsNoTracking().SingleOrDefaultAsync(s => s.Pesel == _employerId) as IEntity ?? await
db.Companies.AsNoTracking().SingleOrDefaultAsync(s => s.Nip == _employerId);
}
private async Task ChgEmployee(ChangeEventArgs e)
{
_employeeId = (string)e.Value!;
employee = await db.Persons.AsNoTracking().SingleOrDefaultAsync(s => s.Pesel == _employeeId);
}
private string _validityText = "";
private async Task ChgValidity(ChangeEventArgs e)
{
string val = (string)e.Value!;
_validityText = val;
StateHasChanged();
var now = DateTime.Now;
if (!TimeSpan.TryParse(val, out TimeSpan span))
{
_validityText = "nieokreślony";
_validity = ValidTime.Invalid;
}
if (span.TotalDays < 1)
{
_validityText = "nieokreślony";
_validity = ValidTime.Invalid;
StateHasChanged();
return;
}
_validityText = $"{span.TotalDays} d";
_validity = new ValidTime(now, span);
}
private async Task Process()
{
disB = true;
this.StateHasChanged();
await Task.Yield();
output = string.Empty;
using UmoEngine eng = new("/home/nya/Dev/csharp/umogen/umogenkey.secret");
UmoProcess proc = new(eng);
Thread.Yield();
await foreach (var str in proc.Ask(_prompt))
await foreach (var str in proc.Ask(_query + $" wynagrodzenie {_payment} zł"))
{
output += str;
Console.Write(str);
@ -42,13 +116,14 @@
}
var anal = System.Text.Json.JsonSerializer.Deserialize<UmoAnalModel>(output, Umogen.JSON_OPTS);
UmoDocumentResult res = new(null, new Person("Kotek", "Miauczyński", "CBS4327563", "04281308999", new DateTime(2004, 08,
13)),
new Person("Kotek", "Miauczyński", "CBS4327563", "04281308999", new DateTime(2004, 08, 13)), ValidTime.Invalid, 2137,
UmoDocumentResult res = new(null, employee, employer, _validity, _payment,
anal);
var bytes = await res.ProcessPdf(Path.Combine("/home/nya/Dev/csharp/umogen/",
$"templates/{anal.Doctype.TemplateDoc()}"));
await js.InvokeVoidAsync("blobby", bytes);
disB = false;
this.StateHasChanged();
}
}

View file

@ -0,0 +1,97 @@
@page "/entities"
@inject DataContext db
@using Microsoft.EntityFrameworkCore
<PageTitle>Podmioty</PageTitle>
<h2 class="text-center">Podmioty</h2>
<div class="col-md-4">
<a href="/entities#" @onclick="ShowPersonDialog">Dodaj nową osobę</a>
</div>
@if (_mode == 1)
{
<div class="mt-4 mb-4">
<PersonAddForm OnSubmit="HideAll" />
</div>
}
<div class="table-responsive-xl">
<table class="table table-primary">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Imię</th>
<th scope="col">PESEL</th>
<th scope="col">Seria dowodu</th>
</tr>
</thead>
<tbody>
@foreach (var person in db.Persons.AsNoTracking().ToList())
{
<tr class="">
<td scope="row">@person.Id</td>
<td>@person.Name @person.Surname</td>
<td>@person.Pesel</td>
<td>@person.IdC</td>
</tr>
}
</tbody>
</table>
</div>
<div class="col-md-4">
<a href="/entities#" @onclick="ShowCompanyDialog">Dodaj nową firmę</a>
</div>
@if (_mode == 2)
{
<div class="mt-4 mb-4">
<CompanyAddForm OnSubmit="HideAll" />
</div>
}
<div class="table-responsive-xl">
<table class="table table-primary">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Nazwa</th>
<th scope="col">NIP</th>
<th scope="col">Siedziba</th>
<th scope="col">Reprezentant</th>
</tr>
</thead>
<tbody>
@foreach (var company in db.Companies.AsNoTracking().Include(c => c.Representative).ToList())
{
<tr class="">
<td scope="row">@company.Id</td>
<td>@company.Name</td>
<td>@company.Nip</td>
<td>@company.Headquarters</td>
<td>@(company.Representative!.Name) @(company.Representative.Surname) [ID @company.Representative.Id]
</td>
</tr>
}
</tbody>
</table>
</div>
@code {
int _mode = 0;
private void HideAll()
{
_mode = 0;
}
private void ShowCompanyDialog()
{
_mode = (_mode != 2 ? 2 : 0);
}
private void ShowPersonDialog()
{
_mode = (_mode != 1 ? 1 : 0);
}
}

View file

@ -2,4 +2,14 @@
<PageTitle>Index</PageTitle>
<h1>Hello, meowmeow~</h1>
<div class="container text-center">
<h1>umogen</h1>
<h3 class="mb-5">Silly Integrated Unified System for Accounting and Contract Handling</h3>
<p>umogen is an experiment that aims to leverage large language models in order to decrease the effort of
handwriting various Polish legal contracts. This iteration will focus on employment and service contracts,
namely: contract of employment
and civic-law contracts which are the primary contracts used to employ workers. Moreover, civic-law contracts
can be utilized to exchange services.</p>
<p>Check <a href="/entities">podmioty</a> for entity data manipulation and <a href="/contracts">umowy</a> to get
started with contract generation.</p>
</div>

View file

@ -1,20 +0,0 @@
@page "/people"
<PageTitle>Osoby</PageTitle>
<h2 class="text-center">Osoby</h2>
<button @onclick="Toggle">Dodaj nowe osoby</button>
@if (addVis)
{
<PersonAddForm OnSubmit="Toggle" />
}
@code {
private bool addVis = false;
private void Toggle()
{
addVis = !addVis;
}
}

View file

@ -10,8 +10,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="~/" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
<link href="css/bs.css" rel="stylesheet">
<link href="css/site.css" rel="stylesheet" />
<link href="Nyanlabs.Umogen.Server.styles.css" rel="stylesheet" />
<link rel="icon" href="favicon.ico" />

View file

@ -1,14 +1,24 @@
using Femsci.AspapajNet;
using Nyanlabs.Umogen.Server;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddPapiez();
builder.Services.AddDbContextFactory<DataContext>();
var app = builder.Build();
using (var db = new DataContext())
{
await db.Database.EnsureCreatedAsync();
}
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");

View file

@ -0,0 +1,56 @@
@inject DataContext db
<h2 class="text-center">Dodaj firmę</h2>
<div class="container">
<form>
<div class="mb-3">
<label for="repr" class="form-label">Id reprezentanta</label>
<input type="text" class="form-control" id="repr" @bind-value="_reprId">
</div>
<div class="row justify-content-center align-items-center g-2">
<div class="col mb-3">
<label for="name" class="form-label">Nazwa firmy</label>
<input type="text" class="form-control" id="name" @bind-value="_name">
</div>
<div class="col mb-3">
<label for="nip" class="form-label">NIP</label>
<input type="text" class="form-control" id="nip" @bind-value="_nip">
</div>
</div>
<div class="mb-3">
<label for="loc" class="form-label">Siedziba</label>
<input type="text" class="form-control" id="loc" @bind-value="_loc">
</div>
<button @onclick="Submit" class="btn btn-primary">Dodaj</button>
</form>
</div>
@code {
[Parameter]
public required Action OnSubmit { get; set; }
private long _reprId;
private string _name = string.Empty,
_loc = string.Empty,
_nip = string.Empty;
private async Task Submit()
{
Core.Models.LegalEntity p = new()
{
Name = _name,
Nip = _nip,
Headquarters = _loc,
PersonId = _reprId,
};
await db.AddAsync(p);
await db.SaveChangesAsync();
_name = string.Empty;
_loc = string.Empty;
_nip = string.Empty;
_reprId = 0;
OnSubmit.Invoke();
}
}

View file

@ -11,7 +11,7 @@
<a class="nav-link active" aria-current="page" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/people">Osoby</a>
<a class="nav-link" href="/entities">Osoby</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/contracts">Umowy</a>

View file

@ -1,21 +1,27 @@
@inject DataContext db
<h2 class="text-center">Dodaj osobę</h2>
<div class="container">
<div class="container align-items-center">
<form>
<div class="mb-3">
<label for="name" class="form-label">Imię</label>
<input type="text" class="form-control" id="name" @bind-value="_name">
<div class="row justify-content-center align-items-center g-2">
<div class="col mb-3">
<label for="name" class="form-label">Imię</label>
<input type="text" class="form-control" id="name" @bind-value="_name">
</div>
<div class="col mb-3">
<label for="surname" class="form-label">Nazwisko</label>
<input type="text" class="form-control" id="surname" @bind-value="_surname">
</div>
</div>
<div class="mb-3">
<label for="surname" class="form-label">Nazwisko</label>
<input type="text" class="form-control" id="surname" @bind-value="_surname">
</div>
<div class="mb-3">
<label for="pesel" class="form-label">PESEL</label>
<input type="text" class="form-control" id="pesel" @bind-value="_pesel">
</div>
<div class="mb-3">
<label for="cbs" class="form-label">Seria dowodu</label>
<input type="text" class="form-control" id="cbs" @bind-value="_id">
<div class="row justify-content-center align-items-center g-2">
<div class="col mb-3">
<label for="pesel" class="form-label">PESEL</label>
<input type="text" class="form-control" id="pesel" @bind-value="_pesel">
</div>
<div class="col mb-3">
<label for="cbs" class="form-label">Seria dowodu</label>
<input type="text" class="form-control" id="cbs" @bind-value="_id">
</div>
</div>
<button @onclick="Submit" class="btn btn-primary">Dodaj</button>
</form>
@ -30,9 +36,17 @@
_pesel = string.Empty,
_id = string.Empty;
private void Submit()
private async Task Submit()
{
Core.Models.Person p = new(_name, _surname, _id, _pesel);
await db.AddAsync(p);
await db.SaveChangesAsync();
_name = string.Empty;
_surname = string.Empty;
_pesel = string.Empty;
_id = string.Empty;
OnSubmit.Invoke();
}
}

File diff suppressed because it is too large Load diff

View file

@ -53,6 +53,10 @@ a,
outline: 1px solid #26b050;
}
.validation-message {
display: inline-flex;
}
.invalid {
outline: 1px solid red;
}

View file

@ -8,13 +8,9 @@ function blobby(arr) {
var downloadLink = document.createElement("a");
downloadLink.target = "_blank";
downloadLink.download = "umo.pdf";
// set object URL as the anchor's href
downloadLink.href = url;
// append the anchor to document body
document.body.append(downloadLink);
// fire a click event on the anchor
downloadLink.click();
}

View file

@ -47,25 +47,13 @@ public class NLSerializationTests
Assert.Equal("Kotek Miauczyński; PESEL 04281308999; ID series CBS4327563; born 13 Aug 2004", query);
}
[Fact]
public void PersonNLTestNoData()
private LegalEntity ModelCompany => new()
{
// Given
Person p = ModelEmployer with
{
IDCode = null,
Pesel = null,
DoB = null,
};
// When
var query = p.NLQuerySerialize();
// Then
Assert.Equal("Kotek Miauczyński; unknown PESEL; unknown ID series; unknown date of birth", query);
}
private LegalEntity ModelCompany => new("Nyanbyte P.S.A.", "1313131313", "Miaumiaśna 13, Miauczki", ModelEmployer);
Name = "Nyanbyte P.S.A.",
Nip = "1313131313",
Headquarters = "Miaumiaśna 13, Miauczki",
Representative = ModelEmployer
};
[Fact]
public void CompanySerializationTest()

View file

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Nyanlabs.Umogen.Core;
using Nyanlabs.Umogen.Core.Models;