Rechnungen werden in lexoffice nun erstellt

This commit is contained in:
2023-07-12 20:44:06 +02:00
parent 85c43cce77
commit 632f5ab236
7 changed files with 386 additions and 27 deletions

View File

@@ -0,0 +1,4 @@
namespace ConsoleApp3.DataContracts
{
public record Employee(string Name, int Number);
}

View File

@@ -0,0 +1,45 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3.DataContracts
{
internal class Invoice
{
[JsonProperty("id")] public string Id { get; set; }
//[JsonProperty("organizationId")] public string OrganizationId { get; set; }
[JsonProperty("createdDate")] public string CreatedDate { get; set; }
[JsonProperty("updatedDate")] public string UpdatedDate { get; set; }
[JsonProperty("version")] public decimal Version { get; set; }
[JsonProperty("language")] public string Language { get; set; }
[JsonProperty("archived")] public bool Archived { get; set; }
[JsonProperty("voucherStatus")] public string VoucherStatus { get; set; }
[JsonProperty("voucherNumber")] public string VoucherNumber { get; set; }
[JsonProperty("voucherDate")] public string VoucherDate { get; set; }
[JsonProperty("dueDate")] public string DueDate { get; set; }
[JsonProperty("address")] public InvoiceAddress Address { get; set; }
[JsonProperty("lineItems")] public List<InvoiceLineItem> LineItems { get; set; }
[JsonProperty("totalPrice")] public TotalPrice TotalPrice { get; set; }
[JsonProperty("taxConditions")] public TaxConditions TaxConditions { get; set; }
[JsonProperty("shippingConditions")] public ShippingConditions ShippingConditions { get; set; }
}
public class ShippingConditions
{
[JsonProperty("shippingDate")] public string shippingDate { get; set; } = "2023-04-22T00:00:00.000+02:00";
[JsonProperty("shippingType")] public string shippingType { get; set; } = "delivery";
}
public class TaxConditions
{
[JsonProperty("taxType")] public string TaxType { get; set; } = "net";
}
public class TotalPrice
{
[JsonProperty("currency")] public string Currency { get; set; } = "EUR";
}
}

View File

@@ -0,0 +1,26 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3.DataContracts
{
internal class InvoiceAddress
{
[JsonProperty("contactId")] public string ContactId { get; set; }
[JsonProperty("name")] public string Name { get; set; }
[JsonProperty("supplement")] public string Supplement { get; set; }
[JsonProperty("street")] public string Street { get; set; }
[JsonProperty("city")] public string City { get; set; }
[JsonProperty("zip")] public string Zip { get; set; }
[JsonProperty("countryCode")] public string CountryCode { get; set; }
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3.DataContracts
{
public record InvoiceItem
{
internal InvoiceItem(string invoiceId, string customer, DateTime date, Employee employee, int account,
string description, decimal amountHours, decimal price)
{
InvoiceId = invoiceId;
Customer = customer;
Date = date;
Employee = employee;
Account = account;
Description = description;
AmountHours = amountHours;
Price = price;
}
public string InvoiceId { get; }
public string Customer { get; }
public DateTime Date { get; }
public Employee Employee { get; }
public int Account { get; }
public string Description { get; }
public decimal AmountHours { get; }
public decimal Price { get; }
}
}

View File

@@ -0,0 +1,21 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3.DataContracts
{
internal class InvoiceLineItem
{
[JsonProperty("type")] public string Type { get; set; }
[JsonProperty("name")] public string Name { get; set; }
[JsonProperty("description")] public string Description { get; set; }
[JsonProperty("quantity")] public decimal Quantity { get; set; }
[JsonProperty("unitName")] public string UnitName { get; set; }
[JsonProperty("unitPrice")] public InvoiceLineUnitPrice UnitPrice { get; set; }
[JsonProperty("discountPercentage")] public decimal DiscountPercentage { get; set; }
[JsonProperty("lineItemAmount")] public decimal LineItemAmount { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using Newtonsoft.Json;
namespace ConsoleApp3.DataContracts
{
public class InvoiceLineUnitPrice
{
[JsonProperty("currency")] public string Currency { get; set; }
[JsonProperty("netAmount")] public decimal NetAmount { get; set; }
[JsonProperty("grossAmount")] public decimal GrossAmount { get; set; }
[JsonProperty("taxRatePercentage")] public decimal TaxRatePercentage { get; set; }
}
}

View File

@@ -6,6 +6,8 @@ using System.Diagnostics;
using System.Net;
using System.Text;
using static System.Collections.Specialized.BitVector32;
using ConsoleApp3.DataContracts;
using Newtonsoft.Json;
/*
*
@@ -13,15 +15,147 @@ using static System.Collections.Specialized.BitVector32;
username: Skywalkerex
userPassword: Magnatpower310!!
/de/OnePiece/PostGetAction/User_Login
curbpJUJmtup1t.Tq0awbHIhIRwhzMW7vrsWxLAJu.pI9X4r
*/
namespace CardmarketBot
{
static class LexofficeApiAddressesBuilder
{
private static string BaseAddress = @"https://api.lexoffice.io";
private static string Invoice = "v1/invoices";
public static string InvoiceUri(string id)
{
return $"{BaseAddress}/{Invoice}/{id}";
}
public static string CreateInvoice()
{
return $"{BaseAddress}/{Invoice}";
}
}
class InvoiceService
{
private readonly WebRequest request;
public InvoiceService()
{
request = WebRequest.Create("https://api.lexoffice.io/v1/invoices");
request.Method = "POST";
request.Headers.Add("Authorization", "Bearer curbpJUJmtup1t.Tq0awbHIhIRwhzMW7vrsWxLAJu.pI9X4r");
request.Headers.Add("Accept", "application/json");
}
public void InsertInvoice(Invoice invoice)
{
var json = JsonConvert.SerializeObject(invoice);
byte[] bytearray = Encoding.UTF8.GetBytes(json);
request.ContentType = "application/json";
using var reqStream = request.GetRequestStream();
reqStream.Write(bytearray, 0, bytearray.Length);
using var response = request.GetResponse();
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
reqStream.Close();
}
}
class LexofficeService
{
private readonly HttpClient _client;
private readonly Random _random = new();
public LexofficeService()
{
_client = new HttpClient
{
DefaultRequestHeaders =
{
{ "Authorization", "Bearer curbpJUJmtup1t.Tq0awbHIhIRwhzMW7vrsWxLAJu.pI9X4r" },
{ "Accept", "application/json" }
}
};
}
public void test()
{
var d = GetInvoiceAsync("d47936c1-71c6-4e22-b394-3630d7354ebf");
var m = d.Result;
Console.WriteLine(m);
}
public void m(Invoice invoice)
{
}
public async void WriteInvoice(Invoice invoice)
{
var jsonSerializerSettings = new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Ignore
};
var s = JsonConvert.SerializeObject(invoice, jsonSerializerSettings);
var content = new StringContent(invoice.ToString(), Encoding.UTF8, "application/json");
var uri = LexofficeApiAddressesBuilder.CreateInvoice();
var result = await _client.PostAsync(uri, content);
Console.WriteLine(result.Content);
}
private async Task<Invoice> GetInvoiceAsync(string id)
{
var uri = LexofficeApiAddressesBuilder.InvoiceUri(id);
var response = await _client.GetAsync(uri).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var contents = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var jsonSerializerSettings = new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Ignore
};
return JsonConvert.DeserializeObject<Invoice>(contents, jsonSerializerSettings);
}
}
internal class Programm
{
static string DateTimeConverter(string input)
{
//2023-06-20T11:30:00"
//2023-02-22T00:00:00.000+01:0
string datum = input.Substring(0, 10);
string uhrzeit = input.Substring(10, input.Length - 10);
input = string.Format("{0} {1}", datum, uhrzeit);
DateTime converted = Convert.ToDateTime(input);
var format = "yyyy-MM-ddTHH:mm:ssK";
string res = converted.ToString(format);
return string.Format("{0}.000+01:00", res);
}
static void Main(string[] args)
{
// Result 2023-02-22T00:00:00.000+01:00
/*string input = "20.06.202311:30";
var localTime = new DateTime(2022, 1, 13, 16, 25, 35, 125, DateTimeKind.Local);
Console.WriteLine(converted.ToString(format));
Debugger.Break();
return;
*/
Dictionary<string, Helper.Porto> portoberechnung = new Dictionary<string, Helper.Porto>()
{
@@ -32,6 +166,16 @@ namespace CardmarketBot
{"2,60 €", Helper.Porto.PRIO210 },
{"3,20 €", Helper.Porto.PRIO270 },
};
Dictionary<Helper.Porto, decimal> PortoPreis = new Dictionary<Helper.Porto, decimal>()
{
{Helper.Porto.BRIEF085, 1.15m },
{Helper.Porto.BRIEF100, 1.30m },
{Helper.Porto.BRIEF160, 2.10m },
{Helper.Porto.BRIEF275, 3.25m },
{Helper.Porto.PRIO210, 2.60m },
{Helper.Porto.PRIO270, 3.20m }
};
ChromeOptions options = new ChromeOptions();
options.AddArgument("start-maximized");
IWebDriver cd = new ChromeDriver(options);
@@ -63,25 +207,25 @@ namespace CardmarketBot
string content = element.Text;
string[] datas = content.Split("\r\n");
List<string> ids = new List<string>();
for(int i =0; i < datas.Length; i+= 7)
for (int i = 0; i < datas.Length; i += 7)
{
ids.Add(datas[i]);
}
//cd.Navigate().GoToUrl(@"https://www.cardmarket.com/de/OnePiece/Orders/1117521790");
Debugger.Break();
List<Kunde> kunden = new List<Kunde>();
int maxCounter = 4;
int maxCounter = 2;
int counter = 0;
foreach (string id in ids)
{
@@ -90,15 +234,19 @@ namespace CardmarketBot
Console.WriteLine(id);
cd.Navigate().GoToUrl(string.Format(@"https://www.cardmarket.com/de/OnePiece/Orders/{0}", id));
element = cd.FindElement(By.XPath("/html/body/main/section/div/div[1]/div/div[3]/div[2]/div[2]/div/div"));
Kunde kunde = Helper.ConvertToKunde(element.Text);
// Bezahldatum
element = cd.FindElement(By.XPath("/html/body/main/section/div/div[1]/div/div[2]/div/div[2]/div[2]"));
kunde.Bezahldatum = element.Text;
//Debugger.Break();
// Versandkosten
element = cd.FindElement(By.XPath("/html/body/main/section/div/div[1]/div/div[3]/div[1]/div[2]/div/div[3]/span[2]"));
kunde.Versandskosten = portoberechnung[element.Text];
kunde.BestellungID = id;
// Artikeln
@@ -109,16 +257,82 @@ namespace CardmarketBot
kunden.Add(kunde);
counter++;
}
List<Invoice> rechnungen = new List<Invoice>();
foreach(Kunde kunde in kunden)
{
Invoice invoice = new Invoice();
invoice.Language = "de";
invoice.VoucherDate = DateTimeConverter(kunde.Bezahldatum); // "2023-02-22T00:00:00.000+01:00"; //
invoice.Address = new InvoiceAddress()
{
Name = kunde.Name,
Street = kunde.Strasse + " " + kunde.Hausnummer,
City = kunde.Ort,
Zip = kunde.Plz,
CountryCode = "DE"
};
invoice.LineItems = new List<InvoiceLineItem>();
foreach(var artikel in kunde.Artikels)
{
invoice.LineItems.Add(new InvoiceLineItem()
{
Type = "custom",
Name = artikel.ENGName + "(" + artikel.Source + ")",
Quantity = artikel.Amount,
UnitName = "Stück",
UnitPrice = new InvoiceLineUnitPrice()
{
Currency = "EUR",
GrossAmount = Convert.ToDecimal(artikel.Preis),
TaxRatePercentage = 19
}
});
}
invoice.LineItems.Add(new InvoiceLineItem()
{
Type = "custom",
Name = "Versandkosten",
Quantity = 1,
UnitName = "Stück",
UnitPrice = new InvoiceLineUnitPrice()
{
Currency = "EUR",
GrossAmount = PortoPreis[kunde.Versandskosten],
TaxRatePercentage = 19
}
});
invoice.TotalPrice = new TotalPrice() { Currency = "EUR" };
invoice.TaxConditions = new TaxConditions() { TaxType = "gross" };
invoice.ShippingConditions = new ShippingConditions()
{
shippingDate = "2023-04-22T00:00:00.000+02:00",
shippingType = "delivery"
};
rechnungen.Add(invoice);
}
foreach(var item in rechnungen)
{
InvoiceService invoiceService = new InvoiceService();
invoiceService.InsertInvoice(item);
}
Debugger.Break();
// Post CSV Erstellen
IEnumerable<IGrouping<Helper.Porto, Kunde>> groupedPorto = kunden.GroupBy(x => x.Versandskosten).Distinct();
foreach(IGrouping<Helper.Porto, Kunde> gkunde in groupedPorto)
foreach (IGrouping<Helper.Porto, Kunde> gkunde in groupedPorto)
{
//FileStream stream = File.Create(string.Format("test_{0}.csv", gkunde.Key.ToString()));
Helper.Porto porto = gkunde.Key;
using (StreamWriter writer = new StreamWriter(string.Format("./test_{0}.csv", gkunde.Key.ToString()),false,Encoding.Latin1))
using (StreamWriter writer = new StreamWriter(string.Format("./test_{0}.csv", gkunde.Key.ToString()), false, Encoding.Latin1))
{
string header = "NAME;ZUSATZ;STRASSE;NUMMER;PLZ;STADT;LAND;ADRESS_TYP;REFERENZ";
@@ -164,7 +378,7 @@ static class Helper
}
internal static Kunde ConvertToKunde(string text)
{
string[] datas = text.Split("\r\n");
string name = datas[0];
string adresseUNDHausnummer = datas[1];
@@ -177,14 +391,14 @@ static class Helper
datas = adresseUNDHausnummer.Split(" ");
string strasse = "";
for(int i = 0; i < datas.Length - 1; i++)
for (int i = 0; i < datas.Length - 1; i++)
{
strasse += datas[i] + " ";
}
strasse = strasse.Trim();
string hausnummer = datas[datas.Length -1];
string hausnummer = datas[datas.Length - 1];
return new Kunde(name,strasse,hausnummer, plz, ort,land);
return new Kunde(name, strasse, hausnummer, plz, ort, land);
}
@@ -193,21 +407,21 @@ static class Helper
List<Artikel> result = new List<Artikel>();
string[] datas = text.Split("\r\n");
int anzahl = datas.Length / 6;
for(int i = 0; i < datas.Length; i+=6)
for (int i = 0; i < datas.Length; i += 6)
{
Artikel temp = new Artikel();
var xFound = datas[i].IndexOf("x");
var am = datas[i].Substring(0, xFound);
temp.Amount = Convert.ToInt32(am);
temp.GERName = datas[i].Substring(xFound+1);
temp.ENGName = datas[i+1];
temp.CardNumber = datas[i+2];
temp.Source = datas[i+3];
temp.Raritaet = datas[i+4];
temp.Preis = datas[i+5];
temp.GERName = datas[i].Substring(xFound + 1);
temp.ENGName = datas[i + 1];
temp.CardNumber = datas[i + 2];
temp.Source = datas[i + 3];
temp.Raritaet = datas[i + 4];
temp.Preis = datas[i + 5].Split(' ')[0];
result.Add(temp);
}
return result;
@@ -236,6 +450,7 @@ class Kunde
string ort;
string land;
List<Artikel> artikels = new List<Artikel>();
public string Bezahldatum { get; set; } = "";
public string Name { get => name; set => name = value; }
public string Strasse { get => strasse; set => strasse = value; }
@@ -247,7 +462,7 @@ class Kunde
public string Hausnummer { get => hausnummer; set => hausnummer = value; }
internal List<Artikel> Artikels { get => artikels; set => artikels = value; }
public Kunde(string Name, string Strasse,string Hausnummer, string PLZ, string Ort, string Land)
public Kunde(string Name, string Strasse, string Hausnummer, string PLZ, string Ort, string Land)
{
name = Name;
hausnummer = Hausnummer;