Add project files.
This commit is contained in:
parent
42d80e3322
commit
ffa8f61b92
25
OdooTool.sln
Normal file
25
OdooTool.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.14.36623.8 d17.14
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OdooTool", "OdooTool\OdooTool.csproj", "{2548C905-823E-4986-B8AC-C0D2F42990FB}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{2548C905-823E-4986-B8AC-C0D2F42990FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2548C905-823E-4986-B8AC-C0D2F42990FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2548C905-823E-4986-B8AC-C0D2F42990FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2548C905-823E-4986-B8AC-C0D2F42990FB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {61AD41D9-DB20-4415-8F92-804E7A3A60C4}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
17
OdooTool/OdooTool.csproj
Normal file
17
OdooTool/OdooTool.csproj
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Kveer.XmlRPC" Version="1.3.1" />
|
||||||
|
<PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
339
OdooTool/Program.cs
Normal file
339
OdooTool/Program.cs
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static async Task Main()
|
||||||
|
{
|
||||||
|
string url = "https://testsync1.odoo.com/jsonrpc";
|
||||||
|
string db = "testsync1";
|
||||||
|
string username = "*";
|
||||||
|
string password = "*";
|
||||||
|
|
||||||
|
using var http = new HttpClient();
|
||||||
|
|
||||||
|
Console.WriteLine("Verbinden met Odoo...");
|
||||||
|
int uid = await LoginOdoo(http, url, db, username, password);
|
||||||
|
if (uid == -1) return;
|
||||||
|
|
||||||
|
Console.WriteLine("Producten ophalen uit Odoo...");
|
||||||
|
var odooProducts = await GetOdooProducts(http, url, db, uid, password);
|
||||||
|
Console.WriteLine($"{odooProducts.Count} Odoo producten gevonden");
|
||||||
|
|
||||||
|
using var dbContext = new ToolContext();
|
||||||
|
var dbArtikels = dbContext.Artikels.Include(a => a.LevArtikels).ToList();
|
||||||
|
Console.WriteLine($"{dbArtikels.Count} artikelen in DB");
|
||||||
|
|
||||||
|
int matchCount = 0;
|
||||||
|
int supplierCreateCount = 0;
|
||||||
|
int supplierUpdateCount = 0;
|
||||||
|
|
||||||
|
foreach (var odoo in odooProducts)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(odoo.Name) ||
|
||||||
|
string.IsNullOrWhiteSpace(odoo.DefaultCode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var matches = dbArtikels
|
||||||
|
.Where(a =>
|
||||||
|
a.ArtikelNaam != null &&
|
||||||
|
a.FactoryNR != null &&
|
||||||
|
a.ArtikelNaam.Trim().Equals(odoo.Name.Trim(), StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
a.FactoryNR.Trim().Equals(odoo.DefaultCode.Trim(), StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
(string.IsNullOrEmpty(a.EAN) ||
|
||||||
|
string.IsNullOrEmpty(odoo.Barcode) ||
|
||||||
|
a.EAN == odoo.Barcode)
|
||||||
|
)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var artikel in matches)
|
||||||
|
{
|
||||||
|
matchCount++;
|
||||||
|
|
||||||
|
if (artikel.InOdoo == 0)
|
||||||
|
artikel.InOdoo = 1;
|
||||||
|
|
||||||
|
foreach (var lev in artikel.LevArtikels)
|
||||||
|
{
|
||||||
|
int? partnerId = await GetOdooPartnerId(http, url, db, uid, password, lev.LevID);
|
||||||
|
if (partnerId == null)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Leverancier ID {lev.LevID} bestaat niet in Odoo");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int? supplierId = await GetOdooSupplierInfoId(
|
||||||
|
http, url, db, uid, password, odoo.Id, partnerId.Value);
|
||||||
|
|
||||||
|
if (supplierId.HasValue)
|
||||||
|
{
|
||||||
|
bool updated = await UpdateOdooSupplierInfo(
|
||||||
|
http, url, db, uid, password,
|
||||||
|
supplierId.Value,
|
||||||
|
lev.Inkoopprijs ?? 0,
|
||||||
|
lev.ArtikelNRLev ?? ""
|
||||||
|
);
|
||||||
|
if (updated) supplierUpdateCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool created = await CreateOdooSupplierInfo(
|
||||||
|
http, url, db, uid, password,
|
||||||
|
odoo.TemplateId, partnerId.Value,
|
||||||
|
lev.ArtikelNRLev ?? "", lev.Inkoopprijs ?? 0);
|
||||||
|
if (created) supplierCreateCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
|
||||||
|
Console.WriteLine("------------ RESULTAAT ------------");
|
||||||
|
Console.WriteLine($"Matches gevonden: {matchCount}");
|
||||||
|
Console.WriteLine($"SupplierInfo aangemaakt: {supplierCreateCount}");
|
||||||
|
Console.WriteLine($"SupplierInfo geüpdatet: {supplierUpdateCount}");
|
||||||
|
Console.WriteLine("----------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task<int> LoginOdoo(HttpClient http, string url, string db, string username, string password)
|
||||||
|
{
|
||||||
|
var payload = new
|
||||||
|
{
|
||||||
|
jsonrpc = "2.0",
|
||||||
|
method = "call",
|
||||||
|
@params = new
|
||||||
|
{
|
||||||
|
service = "common",
|
||||||
|
method = "authenticate",
|
||||||
|
args = new object[] { db, username, password, new { } }
|
||||||
|
},
|
||||||
|
id = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
var response = await http.PostAsync(
|
||||||
|
url,
|
||||||
|
new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"));
|
||||||
|
|
||||||
|
var text = await response.Content.ReadAsStringAsync();
|
||||||
|
using var doc = JsonDocument.Parse(text);
|
||||||
|
|
||||||
|
if (doc.RootElement.TryGetProperty("result", out var result) &&
|
||||||
|
result.ValueKind == JsonValueKind.Number)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Ingelogd (UID {result.GetInt32()})");
|
||||||
|
return result.GetInt32();
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Login mislukt");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
class OdooProduct
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public string? DefaultCode { get; set; }
|
||||||
|
public string? Barcode { get; set; }
|
||||||
|
public decimal ListPrice { get; set; }
|
||||||
|
public int TemplateId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task<List<OdooProduct>> GetOdooProducts(HttpClient http, string url, string db, int uid, string password)
|
||||||
|
{
|
||||||
|
var payload = new
|
||||||
|
{
|
||||||
|
jsonrpc = "2.0",
|
||||||
|
method = "call",
|
||||||
|
@params = new
|
||||||
|
{
|
||||||
|
service = "object",
|
||||||
|
method = "execute_kw",
|
||||||
|
args = new object[]
|
||||||
|
{
|
||||||
|
db, uid, password,
|
||||||
|
"product.product", "search_read",
|
||||||
|
new object[] { },
|
||||||
|
new { fields = new[] { "id", "name", "default_code", "barcode", "list_price", "product_tmpl_id" } }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
id = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
var response = await http.PostAsync(
|
||||||
|
url,
|
||||||
|
new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"));
|
||||||
|
|
||||||
|
var text = await response.Content.ReadAsStringAsync();
|
||||||
|
using var doc = JsonDocument.Parse(text);
|
||||||
|
|
||||||
|
if (!doc.RootElement.TryGetProperty("result", out var result) ||
|
||||||
|
result.ValueKind != JsonValueKind.Array)
|
||||||
|
return new List<OdooProduct>();
|
||||||
|
|
||||||
|
var list = new List<OdooProduct>();
|
||||||
|
|
||||||
|
foreach (var item in result.EnumerateArray())
|
||||||
|
{
|
||||||
|
if (!item.TryGetProperty("id", out var idElem) || idElem.ValueKind != JsonValueKind.Number)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int templateId = 0;
|
||||||
|
if (item.TryGetProperty("product_tmpl_id", out var tmpl))
|
||||||
|
{
|
||||||
|
var maybe = GetIntFromJsonElement(tmpl);
|
||||||
|
if (maybe.HasValue) templateId = maybe.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Add(new OdooProduct
|
||||||
|
{
|
||||||
|
Id = idElem.GetInt32(),
|
||||||
|
Name = item.TryGetProperty("name", out var n) && n.ValueKind == JsonValueKind.String ? n.GetString() : null,
|
||||||
|
DefaultCode = item.TryGetProperty("default_code", out var d) && d.ValueKind == JsonValueKind.String ? d.GetString() : null,
|
||||||
|
Barcode = item.TryGetProperty("barcode", out var b) && b.ValueKind == JsonValueKind.String ? b.GetString() : null,
|
||||||
|
ListPrice = item.TryGetProperty("list_price", out var p) && p.ValueKind == JsonValueKind.Number ? p.GetDecimal() : 0,
|
||||||
|
TemplateId = templateId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int? GetIntFromJsonElement(JsonElement e)
|
||||||
|
{
|
||||||
|
if (e.ValueKind == JsonValueKind.Number)
|
||||||
|
return e.GetInt32();
|
||||||
|
|
||||||
|
if (e.ValueKind == JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
var arr = e.EnumerateArray();
|
||||||
|
if (arr.MoveNext() && arr.Current.ValueKind == JsonValueKind.Number)
|
||||||
|
return arr.Current.GetInt32();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.ValueKind == JsonValueKind.Object &&
|
||||||
|
e.TryGetProperty("id", out var idProp) &&
|
||||||
|
idProp.ValueKind == JsonValueKind.Number)
|
||||||
|
return idProp.GetInt32();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task<int?> GetOdooPartnerId(HttpClient http, string url, string db, int uid, string password, int levId)
|
||||||
|
{
|
||||||
|
return levId;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task<int?> GetOdooSupplierInfoId(HttpClient http, string url, string db, int uid, string password, int productId, int partnerId)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task<bool> CreateOdooSupplierInfo(HttpClient http, string url, string db, int uid, string password,
|
||||||
|
int templateId, int partnerId, string productCode, decimal price)
|
||||||
|
{
|
||||||
|
var payload = new
|
||||||
|
{
|
||||||
|
jsonrpc = "2.0",
|
||||||
|
method = "call",
|
||||||
|
@params = new
|
||||||
|
{
|
||||||
|
service = "object",
|
||||||
|
method = "execute_kw",
|
||||||
|
args = new object[]
|
||||||
|
{
|
||||||
|
db, uid, password,
|
||||||
|
"product.supplierinfo", "create",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
product_tmpl_id = templateId,
|
||||||
|
name = partnerId,
|
||||||
|
product_code = productCode,
|
||||||
|
price = price,
|
||||||
|
delay = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
id = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
var response = await http.PostAsync(
|
||||||
|
url,
|
||||||
|
new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"));
|
||||||
|
|
||||||
|
return response.IsSuccessStatusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task<bool> UpdateOdooSupplierInfo(HttpClient http, string url, string db, int uid, string password,
|
||||||
|
int supplierId, decimal price, string productCode)
|
||||||
|
{
|
||||||
|
var payload = new
|
||||||
|
{
|
||||||
|
jsonrpc = "2.0",
|
||||||
|
method = "call",
|
||||||
|
@params = new
|
||||||
|
{
|
||||||
|
service = "object",
|
||||||
|
method = "execute_kw",
|
||||||
|
args = new object[]
|
||||||
|
{
|
||||||
|
db, uid, password,
|
||||||
|
"product.supplierinfo", "write",
|
||||||
|
new object[] { new int[] { supplierId }, new { price = price, product_code = productCode } }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
id = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
var response = await http.PostAsync(
|
||||||
|
url,
|
||||||
|
new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"));
|
||||||
|
|
||||||
|
return response.IsSuccessStatusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ToolContext : DbContext
|
||||||
|
{
|
||||||
|
public DbSet<Artikel> Artikels { get; set; } = null!;
|
||||||
|
public DbSet<LevArtikel> LevArtikels { get; set; } = null!;
|
||||||
|
public DbSet<Leverancier> Leveranciers { get; set; } = null!;
|
||||||
|
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder options)
|
||||||
|
=> options.UseSqlite("Data Source=Tool.db");
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Artikel
|
||||||
|
{
|
||||||
|
public int ID { get; set; }
|
||||||
|
public string? FactoryNR { get; set; }
|
||||||
|
public string? ArtikelNaam { get; set; }
|
||||||
|
public string? EAN { get; set; }
|
||||||
|
public int InOdoo { get; set; }
|
||||||
|
public List<LevArtikel> LevArtikels { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LevArtikel
|
||||||
|
{
|
||||||
|
public int ID { get; set; }
|
||||||
|
public int ArtikelID { get; set; }
|
||||||
|
public int LevID { get; set; }
|
||||||
|
public string? ArtikelNRLev { get; set; }
|
||||||
|
public decimal? Inkoopprijs { get; set; }
|
||||||
|
public decimal? Korting { get; set; }
|
||||||
|
public string? LeverTijd { get; set; }
|
||||||
|
public string? Omschrijving { get; set; }
|
||||||
|
public bool Leverbaar { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Leverancier
|
||||||
|
{
|
||||||
|
public int ID { get; set; }
|
||||||
|
public string? Naam { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user