Initial commit

Initial commit til Git.
V2 er deployed
This commit is contained in:
2026-06-13 17:31:50 +02:00
parent 9fcd2b145e
commit 41e23b6184
375 changed files with 15956 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
using Microsoft.Extensions.Configuration;
namespace Pos.Dispatcher.Database
{
public class LoadConfig
{
private string dir;
public LoadConfig()
{
dir = AppDomain.CurrentDomain.BaseDirectory;
}
public IConfiguration ByEnvironment()
{
//Console.Out.WriteLine($"Json path: {dir}");
#if DEBUG
var config = new ConfigurationBuilder()
.SetBasePath(dir)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true)
.Build();
return config;
#else
var config = new ConfigurationBuilder()
.SetBasePath(dir)
.AddJsonFile("appsettings.Production.json", optional: true, reloadOnChange: true)
.Build();
return config;
#endif
//Running in a environment that not is supported in this setup
throw new Exception("HostingEnvironment is not supported! This config setup only supports Development or Production");
}
public IConfiguration DebugConfiguration()
{
var config = new ConfigurationBuilder()
.SetBasePath(dir)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true)
.Build();
return config;
}
public IConfiguration ReleaseConfiguration()
{
var config = new ConfigurationBuilder()
.SetBasePath(dir)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile("appsettings.Production.json", optional: true, reloadOnChange: true)
.Build();
return config;
}
}
}

View File

@@ -0,0 +1,75 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Pos.Dispatcher.Database.Models;
namespace Pos.Dispatcher.Database.Model;
public partial class PosDispatcherContext : DbContext
{
public PosDispatcherContext(DbContextOptions<PosDispatcherContext> options)
: base(options)
{
}
public virtual DbSet<Employee> Employees { get; set; }
public virtual DbSet<Payment> Payments { get; set; }
public virtual DbSet<Product> Products { get; set; }
public virtual DbSet<Productgroup> Productgroups { get; set; }
public virtual DbSet<Sale> Sales { get; set; }
public virtual DbSet<SaleLine> SaleLines { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.UseCollation("armscii8_bin")
.HasCharSet("armscii8");
modelBuilder.Entity<Employee>(entity =>
{
entity.HasKey(e => e.Id).HasName("PRIMARY");
});
modelBuilder.Entity<Payment>(entity =>
{
entity.HasKey(e => e.Id).HasName("PRIMARY");
});
modelBuilder.Entity<Product>(entity =>
{
entity.HasKey(e => e.Id).HasName("PRIMARY");
entity.Property(e => e.Id).ValueGeneratedOnAdd();
entity.HasOne(d => d.IdNavigation).WithOne(p => p.Product)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Product_ProductGroup");
});
modelBuilder.Entity<Productgroup>(entity =>
{
entity.HasKey(e => e.Id).HasName("PRIMARY");
});
modelBuilder.Entity<Sale>(entity =>
{
entity.HasKey(e => e.Id).HasName("PRIMARY");
});
modelBuilder.Entity<SaleLine>(entity =>
{
entity.HasKey(e => e.Id).HasName("PRIMARY");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Pos.Dispatcher.Database.Model
{
public partial class PosDispatcherContext
{
protected override void OnConfiguring(
DbContextOptionsBuilder optionsBuilder)
{
LoadConfig l = new LoadConfig();
IConfiguration config = l.ByEnvironment();
string connectionString = config["MariaSqlServer"].ToString();
optionsBuilder
.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString))
.UseLoggerFactory(LoggerFactory.Create(b => b
.AddFilter(level => level >= LogLevel.Information)))
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
base.OnConfiguring(optionsBuilder);
}
}
}

View File

@@ -0,0 +1,29 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace Pos.Dispatcher.Database.Models;
[Table("employee")]
[MySqlCharSet("utf8mb4")]
[MySqlCollation("utf8mb4_general_ci")]
public partial class Employee
{
[Key]
[Column(TypeName = "int(11)")]
public int Id { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Column(TypeName = "tinyint(4)")]
public sbyte IsArchived { get; set; }
[Column(TypeName = "tinyint(4)")]
public sbyte? IsModified { get; set; }
}

View File

@@ -0,0 +1,27 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace Pos.Dispatcher.Database.Models;
[Table("payment")]
public partial class Payment
{
[Key]
[Column(TypeName = "int(11)")]
public int Id { get; set; }
[Column(TypeName = "int(11)")]
public int SaleId { get; set; }
[Precision(20, 6)]
public decimal Amount { get; set; }
[Required]
[Column(TypeName = "tinytext")]
public string Type { get; set; }
}

View File

@@ -0,0 +1,46 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace Pos.Dispatcher.Database.Models;
[Table("product")]
[Index("ProductGroupId", Name = "FK_Product_Categories")]
[MySqlCharSet("utf8mb4")]
[MySqlCollation("utf8mb4_general_ci")]
public partial class Product
{
[Key]
[Column(TypeName = "int(11)")]
public int Id { get; set; }
[Required]
[Column(TypeName = "tinytext")]
public string Name { get; set; }
[Precision(10, 2)]
public decimal Price { get; set; }
[Column(TypeName = "mediumtext")]
public string Description { get; set; }
[Column(TypeName = "int(11)")]
public int ProductGroupId { get; set; }
[Column(TypeName = "tinyint(4)")]
public sbyte IsArchived { get; set; }
[Column(TypeName = "int(11)")]
public int Index { get; set; }
[Column(TypeName = "tinyint(4)")]
public sbyte? IsModified { get; set; }
[ForeignKey("Id")]
[InverseProperty("Product")]
public virtual Productgroup IdNavigation { get; set; }
}

View File

@@ -0,0 +1,35 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace Pos.Dispatcher.Database.Models;
[Table("productgroup")]
[MySqlCharSet("utf8mb4")]
[MySqlCollation("utf8mb4_general_ci")]
public partial class Productgroup
{
[Key]
[Column(TypeName = "int(11)")]
public int Id { get; set; }
[Required]
[Column(TypeName = "tinytext")]
public string Name { get; set; }
[Column(TypeName = "tinyint(4)")]
public sbyte IsArchived { get; set; }
[Column(TypeName = "int(11)")]
public int Index { get; set; }
[Column(TypeName = "tinyint(4)")]
public sbyte? IsModified { get; set; }
[InverseProperty("IdNavigation")]
public virtual Product Product { get; set; }
}

View File

@@ -0,0 +1,26 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace Pos.Dispatcher.Database.Models;
[Table("sale")]
public partial class Sale
{
[Key]
[Column(TypeName = "int(11)")]
public int Id { get; set; }
[Column(TypeName = "datetime")]
public DateTime Time { get; set; }
[Column(TypeName = "int(11)")]
public int EmployeeId { get; set; }
[Column(TypeName = "tinyint(4)")]
public sbyte? IsModified { get; set; }
}

View File

@@ -0,0 +1,33 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace Pos.Dispatcher.Database.Models;
[Table("sale_line")]
public partial class SaleLine
{
[Key]
[Column(TypeName = "int(11)")]
public int Id { get; set; }
[Column(TypeName = "int(11)")]
public int SaleId { get; set; }
[Required]
[Column(TypeName = "tinytext")]
public string Product { get; set; }
[Column(TypeName = "smallint(6)")]
public short Pieces { get; set; }
[Precision(20, 6)]
public decimal Price { get; set; }
[Precision(20, 6)]
public decimal Total { get; set; }
}

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,62 @@
{
"CodeGenerationMode": 3,
"ContextClassName": "PosDispatcherContext",
"ContextNamespace": null,
"DefaultDacpacSchema": null,
"FilterSchemas": false,
"IncludeConnectionString": false,
"ModelNamespace": null,
"OutputContextPath": "Model",
"OutputPath": "Models",
"PreserveCasingWithRegex": true,
"ProjectRootNamespace": "Pos.Dispatcher.Database",
"Schemas": null,
"SelectedHandlebarsLanguage": 0,
"SelectedToBeGenerated": 0,
"Tables": [
{
"Name": "employee",
"ObjectType": 0
},
{
"Name": "payment",
"ObjectType": 0
},
{
"Name": "product",
"ObjectType": 0
},
{
"Name": "productgroup",
"ObjectType": 0
},
{
"Name": "sale",
"ObjectType": 0
},
{
"Name": "sale_line",
"ObjectType": 0
}
],
"UiHint": "localhost",
"UncountableWords": null,
"UseBoolPropertiesWithoutDefaultSql": false,
"UseDatabaseNames": false,
"UseDateOnlyTimeOnly": false,
"UseDbContextSplitting": false,
"UseFluentApiOnly": false,
"UseHandleBars": false,
"UseHierarchyId": false,
"UseInflector": true,
"UseLegacyPluralizer": false,
"UseManyToManyEntity": false,
"UseNoDefaultConstructor": false,
"UseNoObjectFilter": false,
"UseNodaTime": false,
"UseNullableReferences": false,
"UseSchemaFolders": false,
"UseSchemaNamespaces": false,
"UseSpatial": false,
"UseT4": false
}

View File

@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Remove="appsettings.json" />
</ItemGroup>
<ItemGroup>
<Content Include="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="RestSharp" Version="110.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Pos.Dispatcher.Database\Pos.Dispatcher.Database.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,21 @@
// See https://aka.ms/new-console-template for more information
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Pomelo.EntityFrameworkCore;
using Pos.Dispatcher;
using Pos.Dispatcher.Database;
using Pos.Dispatcher.Database.Model;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
LoadConfig loadConfig = new LoadConfig();
IConfiguration config = loadConfig.ByEnvironment();
builder.Services.AddSingleton(config);
builder.Services.AddDbContext<PosDispatcherContext>();
builder.Services.AddScoped<Synchronize>();
using IHost host = builder.Build();
Synchronize synchronize = host.Services.GetRequiredService<Synchronize>();
synchronize.Go();

View File

@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Pos.Dispatcher.Database.Model;
using Pos.Dispatcher.Database.Models;
using RestSharp;
namespace Pos.Dispatcher
{
public class Synchronize
{
private readonly PosDispatcherContext _context;
private readonly IConfiguration _config;
private string _apiUrl;
private string _apiKey;
public Synchronize(PosDispatcherContext context, IConfiguration config)
{
_context = context;
_config = config;
_apiUrl = _config["PosApi"];
_apiKey = _config["ApiKey"];
}
public void Go()
{
Employee();
ProductGroup();
Sale();
}
private void Employee()
{
List<Employee> employees = _context.Employees.Where(c => c.IsModified == 1).ToList();
foreach (Employee employee in employees)
{
RestClient client = new RestClient(_apiUrl);
client.AddDefaultHeader("ApiKey", _apiKey);
var request = new RestRequest("/employee", Method.Post);
request.AddJsonBody(employee);
RestResponse restResponse = client.Post(request);
employee.IsModified = 0;
}
_context.SaveChanges();
}
private void ProductGroup()
{
List<Productgroup> productgroups = _context.Productgroups.Where(c => c.IsModified == 1).ToList();
foreach (Productgroup product in productgroups)
{
RestClient client = new RestClient(_apiUrl);
client.AddDefaultHeader("ApiKey", _apiKey);
var request = new RestRequest("/productgroup", Method.Post);
request.AddJsonBody(product);
RestResponse response = client.Post(request);
product.IsModified = 0;
}
_context.SaveChanges();
}
public void Sale()
{
List<Sale> sales = _context.Sales.Where(c => c.IsModified == 1).ToList();
foreach (Sale sale in sales)
{
RestClient client = new RestClient(_apiUrl);
client.AddDefaultHeader("ApiKey", _apiKey);
var request = new RestRequest("/sale", Method.Post);
request.AddJsonBody(sale);
RestResponse response = client.Post(request);
sale.IsModified = 0;
List<SaleLine> saleLines = _context.SaleLines.Where(c => c.SaleId == sale.Id).ToList();
foreach (SaleLine saleLine in saleLines)
{
client = new RestClient(_apiUrl);
client.AddDefaultHeader("ApiKey", _apiKey);
request = new RestRequest("/saleline", Method.Post);
request.AddJsonBody(saleLine);
response = client.Post(request);
}
List<Payment> payments = _context.Payments.Where(c => c.SaleId == sale.Id).ToList();
foreach (Payment payment in payments)
{
client = new RestClient(_apiUrl);
client.AddDefaultHeader("ApiKey", _apiKey);
request = new RestRequest("/payment", Method.Post);
request.AddJsonBody(payment);
response = client.Post(request);
}
sale.IsModified = 0;
}
_context.SaveChanges();
}
}
}

View File

@@ -0,0 +1,12 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"MariaSqlServer": "Data Source=localhost;Initial Catalog=PointOfSale;Persist Security Info=False;User ID=root",
"ApiKey": "ad0YfMYm5bdVGjmXkJBOdNggQaWtkB9nzyQv68GAcB7mpf9onGBP9j3DJ46S7go30NwaQgoZBNS7hZDOM79KTyU3K2ysMW2x4mWGHOkETJmWadaMXBTGpoWn0ef9KiUN",
"PosApi": "http://localhost:53151"
}