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