u
This commit is contained in:
@@ -35,6 +35,11 @@ struct Config {
|
||||
int customerNumberSequence = 6;
|
||||
};
|
||||
|
||||
constexpr int VERSANDPOSITION_TYPE = 2;
|
||||
constexpr int ZAHLUNG_TYPE_ZAHLUNG = 10;
|
||||
constexpr int NIST_READONLY_NICHT_AENDERBAR = 2;
|
||||
constexpr int NIST_EXTERNE_RECHNUNG_KEINE = 2;
|
||||
|
||||
Config g_config;
|
||||
std::unique_ptr<Defaults> g_resolved_defaults;
|
||||
std::map<std::string, nlohmann::json> g_zahlungsart_cache;
|
||||
@@ -128,6 +133,12 @@ inline int json_int(const nlohmann::json& obj, const char* key, int fallback = 0
|
||||
return to_int(*it, fallback);
|
||||
}
|
||||
|
||||
inline double json_double(const nlohmann::json& obj, const char* key, double fallback = 0) {
|
||||
auto it = obj.find(key);
|
||||
if (it == obj.end()) return fallback;
|
||||
return to_number(*it, fallback);
|
||||
}
|
||||
|
||||
inline int steuerklasse_for_vat(double vat) {
|
||||
if (vat >= 15) return 1;
|
||||
if (vat > 0) return 2;
|
||||
@@ -232,38 +243,158 @@ inline int allocate_pk(OdbcPool::Connection* c, const std::string& tableName) {
|
||||
return std::stoi(rs[0][0].str);
|
||||
}
|
||||
|
||||
inline int parse_import_setting(const nlohmann::json& order) {
|
||||
if (!order.contains("settings") || order["settings"].is_null()) return 0;
|
||||
return json_int(order["settings"], "importSetting", 0);
|
||||
}
|
||||
|
||||
inline int parse_invoice_setting(const nlohmann::json& order) {
|
||||
if (!order.contains("settings") || order["settings"].is_null()) return 0;
|
||||
return json_int(order["settings"], "invoiceSetting", 0);
|
||||
}
|
||||
|
||||
inline int resolve_n_ist_readonly(const nlohmann::json& order) {
|
||||
return parse_import_setting(order) == 0 ? NIST_READONLY_NICHT_AENDERBAR : 0;
|
||||
}
|
||||
|
||||
inline int resolve_n_ist_externe_rechnung(const nlohmann::json& order) {
|
||||
const int import_setting = parse_import_setting(order);
|
||||
const int invoice_setting = parse_invoice_setting(order);
|
||||
if (import_setting >= 2 && import_setting <= 5) return 0;
|
||||
if (invoice_setting & 1) return 0;
|
||||
if (import_setting == 0) return NIST_EXTERNE_RECHNUNG_KEINE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct VersandArtRow {
|
||||
int kVersandArt = 0;
|
||||
std::string cName;
|
||||
double fPrice = 0;
|
||||
double fMwSt = 19;
|
||||
};
|
||||
|
||||
inline bool is_versandposition(const nlohmann::json& item) {
|
||||
return json_int(item, "type", 0) == VERSANDPOSITION_TYPE;
|
||||
}
|
||||
|
||||
inline bool has_versandposition(const nlohmann::json& items) {
|
||||
if (!items.is_array()) return false;
|
||||
for (const auto& item : items) {
|
||||
if (is_versandposition(item)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool has_non_return_sale_items(const nlohmann::json& items) {
|
||||
if (!items.is_array()) return false;
|
||||
for (const auto& item : items) {
|
||||
if (json_double(item, "isReturn", 0) == 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool should_inject_selbstabholer_shipping(const nlohmann::json& items) {
|
||||
if (has_versandposition(items)) return false;
|
||||
return has_non_return_sale_items(items);
|
||||
}
|
||||
|
||||
inline std::optional<VersandArtRow> lookup_versand_art(OdbcPool::Connection* c,
|
||||
const std::string& shipping_name) {
|
||||
auto try_lookup = [&](const std::string& cName) -> std::optional<VersandArtRow> {
|
||||
std::vector<Param> ps = {{ParamType::NVarChar, cName, 0}};
|
||||
ResultSet rs;
|
||||
if (!get_pool().execute(c,
|
||||
"SELECT TOP 1 kVersandArt, cName, fPrice, fMwSt "
|
||||
"FROM dbo.tVersandArt WHERE cName = ?", ps, rs)
|
||||
|| rs.empty() || rs[0].empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
VersandArtRow row;
|
||||
row.kVersandArt = std::stoi(rs[0][0].str);
|
||||
row.cName = rs[0][1].str;
|
||||
row.fPrice = rs[0].size() > 2 ? to_number(nlohmann::json(rs[0][2].str), 0) : 0;
|
||||
row.fMwSt = rs[0].size() > 3 ? to_number(nlohmann::json(rs[0][3].str), 19) : 19;
|
||||
return row;
|
||||
};
|
||||
|
||||
std::string name = shipping_name;
|
||||
if (name.empty()) name = "Selbstabholer";
|
||||
if (auto row = try_lookup(name)) return row;
|
||||
if (name != "Selbstabholer") return try_lookup("Selbstabholer");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
inline nlohmann::json synthetic_shipping_item(const VersandArtRow& versand_art) {
|
||||
const double vat = versand_art.fMwSt;
|
||||
const double gross = versand_art.fPrice;
|
||||
const double net = gross / (1 + vat / 100);
|
||||
return {
|
||||
{"type", std::to_string(VERSANDPOSITION_TYPE)},
|
||||
{"quantity", "1"},
|
||||
{"name", versand_art.cName},
|
||||
{"priceGross", std::to_string(gross)},
|
||||
{"priceNet", std::to_string(net)},
|
||||
{"vat", std::to_string(vat)},
|
||||
{"isReturn", "0"}
|
||||
};
|
||||
}
|
||||
|
||||
inline nlohmann::json resolve_zahlungsart(OdbcPool::Connection* c, const std::string& name) {
|
||||
std::string key = name.empty() ? "bar" : name;
|
||||
std::transform(key.begin(), key.end(), key.begin(), [](unsigned char ch) { return std::tolower(ch); });
|
||||
auto it = g_zahlungsart_cache.find(key);
|
||||
const std::string lookup_name = name.empty() ? "Bar" : name;
|
||||
const std::string cache_key = [&]() {
|
||||
std::string key = lookup_name;
|
||||
std::transform(key.begin(), key.end(), key.begin(),
|
||||
[](unsigned char ch) { return static_cast<char>(std::tolower(ch)); });
|
||||
return key;
|
||||
}();
|
||||
auto it = g_zahlungsart_cache.find(cache_key);
|
||||
if (it != g_zahlungsart_cache.end()) return it->second;
|
||||
|
||||
std::vector<Param> ps = {{ParamType::NVarChar, key, 0}};
|
||||
ResultSet rs;
|
||||
get_pool().execute(c, "SELECT TOP 1 kZahlungsart, cName FROM dbo.tZahlungsart WHERE cName = ?", ps, rs);
|
||||
auto fetch_row = [&](const char* sql) -> std::optional<std::pair<int, std::string>> {
|
||||
std::vector<Param> ps = {{ParamType::NVarChar, lookup_name, 0}};
|
||||
ResultSet rs;
|
||||
if (!get_pool().execute(c, sql, ps, rs) || rs.empty() || rs[0].empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return std::make_pair(std::stoi(rs[0][0].str), rs[0][1].str);
|
||||
};
|
||||
|
||||
if (!rs.empty() && !rs[0].empty()) {
|
||||
nlohmann::json z = {{"kZahlungsart", std::stoi(rs[0][0].str)}, {"cName", rs[0][1].str}};
|
||||
g_zahlungsart_cache[key] = z;
|
||||
return z;
|
||||
std::optional<std::pair<int, std::string>> row =
|
||||
fetch_row("SELECT TOP 1 kZahlungsart, cName FROM dbo.tZahlungsart WHERE cName = ?");
|
||||
if (!row) {
|
||||
row = fetch_row(
|
||||
"SELECT TOP 1 z.kZahlungsart, z.cName "
|
||||
"FROM dbo.tZahlungsArtSprache zs "
|
||||
"INNER JOIN dbo.tZahlungsart z ON z.kZahlungsart = zs.kZahlungsart "
|
||||
"WHERE zs.cName = ?");
|
||||
}
|
||||
if (!row) {
|
||||
row = fetch_row(
|
||||
"SELECT TOP 1 kZahlungsart, cName FROM dbo.tZahlungsart WHERE UPPER(cName) = UPPER(?)");
|
||||
}
|
||||
|
||||
int kZahlungsart = allocate_pk(c, "tZahlungsart");
|
||||
const char* insert =
|
||||
"INSERT INTO dbo.tZahlungsart"
|
||||
" (kZahlungsart, cName, cPrtString, nLastschrift, cPrtStringVor, cPaymentOption, cKonto,"
|
||||
" nAusliefernVorZahlung, nPrioritaet, nMahnwesenAktiv, fSkontoWert, nSkontoZeitraum,"
|
||||
" nMatchingOptionen, nIstStandard, nAktiv)"
|
||||
" VALUES (?, ?, '', 0, '', '', '', 0, 0, 0, 0, 0, 0, 0, 1)";
|
||||
std::vector<Param> ps2 = {
|
||||
{ParamType::Int, "", kZahlungsart},
|
||||
{ParamType::NVarChar, key, 0}
|
||||
};
|
||||
get_pool().execute(c, insert, ps2, rs);
|
||||
nlohmann::json zahlungsart;
|
||||
if (row) {
|
||||
zahlungsart = {{"kZahlungsart", row->first}, {"cName", row->second}};
|
||||
} else {
|
||||
int kZahlungsart = allocate_pk(c, "tZahlungsart");
|
||||
const char* insert =
|
||||
"INSERT INTO dbo.tZahlungsart"
|
||||
" (kZahlungsart, cName, cPrtString, nLastschrift, cPrtStringVor, cPaymentOption, cKonto,"
|
||||
" nAusliefernVorZahlung, nPrioritaet, nMahnwesenAktiv, fSkontoWert, nSkontoZeitraum,"
|
||||
" nMatchingOptionen, nIstStandard, nAktiv)"
|
||||
" VALUES (?, ?, '', 0, '', '', '', 0, 0, 0, 0, 0, 0, 0, 1)";
|
||||
std::vector<Param> ps2 = {
|
||||
{ParamType::Int, "", kZahlungsart},
|
||||
{ParamType::NVarChar, lookup_name, 0}
|
||||
};
|
||||
ResultSet rs;
|
||||
get_pool().execute(c, insert, ps2, rs);
|
||||
zahlungsart = {{"kZahlungsart", kZahlungsart}, {"cName", lookup_name}};
|
||||
}
|
||||
|
||||
nlohmann::json z = {{"kZahlungsart", kZahlungsart}, {"cName", key}};
|
||||
g_zahlungsart_cache[key] = z;
|
||||
return z;
|
||||
g_zahlungsart_cache[cache_key] = zahlungsart;
|
||||
return zahlungsart;
|
||||
}
|
||||
|
||||
inline std::string next_customer_number(OdbcPool::Connection* c) {
|
||||
@@ -303,21 +434,6 @@ inline std::string resolve_auftrag_c_kunden_nr(const nlohmann::json& order) {
|
||||
return order.value("customerNumber", "");
|
||||
}
|
||||
|
||||
// POS settings.invoiceSetting: 0 = external/POS invoice (nIstExterneRechnung=1).
|
||||
inline int resolve_n_ist_externe_rechnung(const nlohmann::json& order) {
|
||||
if (!order.contains("settings") || order["settings"].is_null()) return 1;
|
||||
const auto& settings = order["settings"];
|
||||
if (!settings.contains("invoiceSetting")) return 1;
|
||||
const auto& inv = settings["invoiceSetting"];
|
||||
if (inv.is_boolean()) return inv.get<bool>() ? 0 : 1;
|
||||
if (inv.is_number_integer()) return inv.get<int>() == 1 ? 0 : 1;
|
||||
if (inv.is_string()) {
|
||||
std::string s = inv.get<std::string>();
|
||||
return (s == "1" || s == "true") ? 0 : 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline std::pair<int,int> create_customer(OdbcPool::Connection* c, const std::string& customer_number,
|
||||
const nlohmann::json& address, const Defaults& defaults) {
|
||||
const nlohmann::json a = address.is_null() ? nlohmann::json::object() : address;
|
||||
@@ -328,8 +444,8 @@ inline std::pair<int,int> create_customer(OdbcPool::Connection* c, const std::st
|
||||
|
||||
const char* sql =
|
||||
"DECLARE @returnValue INT;"
|
||||
"DECLARE @p1 dbo.TYPE_spkundeInsert;"
|
||||
"INSERT INTO @p1"
|
||||
"DECLARE @kunde_daten dbo.TYPE_spkundeInsert;"
|
||||
"INSERT INTO @kunde_daten"
|
||||
" (kInetKunde, kKundenKategorie, cKundenNr, cFirma, cAnrede, cTitel, cVorname, cName,"
|
||||
" cStrasse, cPLZ, cOrt, cLand, cTel, cFax, cEMail, dErstellt, cMobil, fRabatt, cUSTID, cNewsletter,"
|
||||
" cZusatz, cEbayName, kBuyer, cAdressZusatz, cGeburtstag, cWWW, cSperre, cPostID, kKundenGruppe,"
|
||||
@@ -342,7 +458,7 @@ inline std::pair<int,int> create_customer(OdbcPool::Connection* c, const std::st
|
||||
" 0, ?, ?, ?, ?, ?, N'', 0,"
|
||||
" ?, N'', 0, 0, 0, 0, 0,"
|
||||
" NULL, 0, 0, 0);"
|
||||
"EXEC @returnValue = Kunde.spKundeInsert @daten = @p1;"
|
||||
"EXEC @returnValue = Kunde.spKundeInsert @daten = @kunde_daten;"
|
||||
"SELECT @returnValue AS kKunde";
|
||||
|
||||
std::vector<Param> ps = {
|
||||
@@ -360,7 +476,7 @@ inline std::pair<int,int> create_customer(OdbcPool::Connection* c, const std::st
|
||||
{ParamType::NVarChar, a.value("fax", ""), 0},
|
||||
{ParamType::NVarChar, a.value("email", ""), 0},
|
||||
{ParamType::NVarChar, a.value("mobile", ""), 0},
|
||||
{ParamType::Double, "", 0, to_number(a["discount"], 0)},
|
||||
{ParamType::Double, "", 0, json_double(a, "discount", 0)},
|
||||
{ParamType::NVarChar, a.value("addressAddition", ""), 0},
|
||||
{ParamType::NVarChar, a.value("birthday", ""), 0},
|
||||
{ParamType::Int, "", kKundengruppe},
|
||||
@@ -445,17 +561,18 @@ inline void insert_order_address(OdbcPool::Connection* c, int kAuftrag, int kKun
|
||||
}
|
||||
|
||||
inline int insert_order_item(OdbcPool::Connection* c, int kAuftrag, const nlohmann::json& item) {
|
||||
double vat = to_number(item["vat"], 19);
|
||||
double quantity = to_number(item["quantity"], 1);
|
||||
double price_gross = to_number(item["priceGross"], 0);
|
||||
double price_net = to_number(item["priceNet"], price_gross / (1 + vat / 100));
|
||||
double discount = to_number(item["discountPercent"], 0);
|
||||
double vat = json_double(item, "vat", 19);
|
||||
double quantity = json_double(item, "quantity", 1);
|
||||
double price_gross = json_double(item, "priceGross", 0);
|
||||
double price_net = json_double(item, "priceNet", price_gross / (1 + vat / 100));
|
||||
double discount = json_double(item, "discountPercent", 0);
|
||||
int kSteuerklasse = steuerklasse_for_vat(vat);
|
||||
std::string sku = item.value("sku", "");
|
||||
const int position_type = is_versandposition(item) ? VERSANDPOSITION_TYPE : json_int(item, "type", 0);
|
||||
|
||||
int kArtikel = 0;
|
||||
bool has_artikel = false;
|
||||
if (!sku.empty()) {
|
||||
if (!sku.empty() && position_type != VERSANDPOSITION_TYPE) {
|
||||
std::vector<Param> ps = {{ParamType::NVarChar, sku, 0}};
|
||||
ResultSet rs;
|
||||
get_pool().execute(c, "SELECT TOP 1 kArtikel FROM dbo.tArtikel WHERE cArtNr = ?", ps, rs);
|
||||
@@ -465,18 +582,20 @@ inline int insert_order_item(OdbcPool::Connection* c, int kAuftrag, const nlohma
|
||||
}
|
||||
}
|
||||
|
||||
const int nType = position_type == VERSANDPOSITION_TYPE ? VERSANDPOSITION_TYPE : (has_artikel ? 1 : 0);
|
||||
const int nReserviert = nType == VERSANDPOSITION_TYPE ? 0 : 1;
|
||||
|
||||
const char* sql =
|
||||
"DECLARE @t TABLE ([kAuftragPosition] INT);"
|
||||
"INSERT INTO Verkauf.tAuftragPosition"
|
||||
" (kArtikel, kAuftrag, cArtNr, nReserviert, cName, cHinweis, fAnzahl, fVkNetto, fMwSt,"
|
||||
" cNameStandard, kSteuerklasse, nType, cEinheit, fFaktor, kSteuerschluessel, fRabatt)"
|
||||
" OUTPUT inserted.kAuftragPosition INTO @t"
|
||||
" VALUES (?, ?, ?, 1, ?, ?, ?, ?, ?,"
|
||||
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,"
|
||||
" ?, ?, ?, ?, 1.0, 3, ?);"
|
||||
"SELECT kAuftragPosition FROM @t";
|
||||
|
||||
Param cartnr{ParamType::NVarChar, has_artikel ? sku : std::string(), 0, 0.0, !has_artikel};
|
||||
|
||||
Param pk_art{ParamType::Int, "", kArtikel, 0.0, !has_artikel};
|
||||
|
||||
std::string name = item.value("name", sku.empty() ? std::string("Position") : sku);
|
||||
@@ -484,6 +603,7 @@ inline int insert_order_item(OdbcPool::Connection* c, int kAuftrag, const nlohma
|
||||
pk_art,
|
||||
{ParamType::Int, "", kAuftrag},
|
||||
cartnr,
|
||||
{ParamType::Int, "", nReserviert},
|
||||
{ParamType::NVarChar, name, 0},
|
||||
{ParamType::NVarChar, item.value("note", ""), 0},
|
||||
{ParamType::Double, "", 0, quantity},
|
||||
@@ -491,7 +611,7 @@ inline int insert_order_item(OdbcPool::Connection* c, int kAuftrag, const nlohma
|
||||
{ParamType::Double, "", 0, vat},
|
||||
{ParamType::NVarChar, name, 0},
|
||||
{ParamType::Int, "", kSteuerklasse},
|
||||
{ParamType::Int, "", has_artikel ? 1 : 0},
|
||||
{ParamType::Int, "", nType},
|
||||
{ParamType::NVarChar, item.value("unit", ""), 0},
|
||||
{ParamType::Double, "", 0, discount}
|
||||
};
|
||||
@@ -608,6 +728,39 @@ inline bool is_order_delivered(const nlohmann::json& order) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ODBC maps ? placeholders to @p1, @p2, … — never DECLARE @p1 in the same batch.
|
||||
inline void recalculate_auftrag_eckdaten(OdbcPool::Connection* c, int kAuftrag) {
|
||||
const char* sql =
|
||||
"DECLARE @eckdaten_calc Verkauf.TYPE_spAuftragEckdatenBerechnen;"
|
||||
"INSERT INTO @eckdaten_calc VALUES (?);"
|
||||
"EXEC Verkauf.spAuftragEckdatenBerechnen @auftrag = @eckdaten_calc";
|
||||
std::vector<Param> ps = {{ParamType::Int, "", kAuftrag}};
|
||||
ResultSet rs;
|
||||
if (!get_pool().execute(c, sql, ps, rs)) {
|
||||
throw std::runtime_error("spAuftragEckdatenBerechnen failed for kAuftrag="
|
||||
+ std::to_string(kAuftrag));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::optional<double> get_offener_auftragswert(OdbcPool::Connection* c, int kAuftrag) {
|
||||
const char* sql =
|
||||
"SELECT ROUND(tAuftragEckdaten.fOffenerWertOhneStorno, 2) AS fOffenerAuftragswert "
|
||||
"FROM Verkauf.tAuftrag "
|
||||
"LEFT JOIN Verkauf.tAuftragEckdaten ON tAuftragEckdaten.kAuftrag = tAuftrag.kAuftrag "
|
||||
"WHERE tAuftrag.kAuftrag = ?";
|
||||
std::vector<Param> ps = {{ParamType::Int, "", kAuftrag}};
|
||||
ResultSet rs;
|
||||
if (!get_pool().execute(c, sql, ps, rs) || rs.empty() || rs[0].empty()
|
||||
|| rs[0][0].type == CellType::Null) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return to_number(nlohmann::json(rs[0][0].str), 0);
|
||||
}
|
||||
|
||||
inline bool is_new_payment(const nlohmann::json& payment) {
|
||||
return json_int(payment, "paymentId", 0) <= 0;
|
||||
}
|
||||
|
||||
inline void insert_payment(OdbcPool::Connection* c, int kAuftrag, const nlohmann::json& payment,
|
||||
const nlohmann::json& order, const std::tm& order_date_tm) {
|
||||
std::string payment_name = payment.value("paymentMethodName", "");
|
||||
@@ -615,25 +768,46 @@ inline void insert_payment(OdbcPool::Connection* c, int kAuftrag, const nlohmann
|
||||
nlohmann::json zahlungsart = resolve_zahlungsart(c, payment_name);
|
||||
int kZahlung = allocate_pk(c, "tZahlung");
|
||||
|
||||
recalculate_auftrag_eckdaten(c, kAuftrag);
|
||||
auto fOffenerWert = get_offener_auftragswert(c, kAuftrag);
|
||||
if (!fOffenerWert) {
|
||||
throw std::runtime_error("no open order amount for kAuftrag=" + std::to_string(kAuftrag));
|
||||
}
|
||||
|
||||
const char* sql =
|
||||
"INSERT INTO dbo.tZahlung"
|
||||
" (kZahlung, cName, dDatum, fBetrag, kBestellung, kBenutzer, nAnzahlung, cHinweis, kZahlungsart,"
|
||||
" nKeinExport, cExternalTransactionId, nZuweisungstyp, nZahlungstyp, cZuweisungsinfo, nZuweisungswertung)"
|
||||
" VALUES (?, ?, ?, ?, ?, ?, 0, '', ?,"
|
||||
" 0, ?, 0, 0, '', 0)";
|
||||
"IF EXISTS ("
|
||||
" SELECT 1 FROM Verkauf.tAuftragEckdaten"
|
||||
" WHERE kAuftrag = ?"
|
||||
" AND ROUND(fOffenerWertOhneStorno, 2) = ROUND(?, 2)"
|
||||
")"
|
||||
"BEGIN"
|
||||
" INSERT INTO dbo.tZahlung"
|
||||
" (kZahlung, cName, dDatum, fBetrag, kBestellung, kBenutzer, nAnzahlung, cHinweis, kZahlungsart,"
|
||||
" nKeinExport, cExternalTransactionId, nZuweisungstyp, nZahlungstyp, cZuweisungsinfo, nZuweisungswertung)"
|
||||
" VALUES (?, ?, ?, ?, ?, ?, 0, '', ?,"
|
||||
" 0, ?, 0, ?, '', 0);"
|
||||
"END;"
|
||||
"SELECT @@ROWCOUNT AS inserted";
|
||||
|
||||
std::vector<Param> ps = {
|
||||
{ParamType::Int, "", kAuftrag},
|
||||
{ParamType::Double, "", 0, *fOffenerWert},
|
||||
{ParamType::Int, "", kZahlung},
|
||||
{ParamType::NVarChar, zahlungsart.value("cName", ""), 0},
|
||||
{ParamType::NVarChar, order_date_sql(order_date_tm), 0},
|
||||
{ParamType::Double, "", 0, to_number(payment["amount"], 0)},
|
||||
{ParamType::Double, "", 0, json_double(payment, "amount", 0)},
|
||||
{ParamType::Int, "", kAuftrag},
|
||||
{ParamType::Int, "", g_config.kBenutzer},
|
||||
{ParamType::Int, "", json_int(zahlungsart, "kZahlungsart", 0)},
|
||||
{ParamType::NVarChar, order.value("externalOrderNumber", ""), 0}
|
||||
{ParamType::NVarChar, order.value("externalOrderNumber", ""), 0},
|
||||
{ParamType::Int, "", ZAHLUNG_TYPE_ZAHLUNG},
|
||||
};
|
||||
ResultSet rs;
|
||||
get_pool().execute(c, sql, ps, rs);
|
||||
if (!get_pool().execute(c, sql, ps, rs) || rs.empty() || rs[0].empty()
|
||||
|| std::stoi(rs[0][0].str) == 0) {
|
||||
throw std::runtime_error("payment insert skipped: open amount changed for kAuftrag="
|
||||
+ std::to_string(kAuftrag));
|
||||
}
|
||||
}
|
||||
|
||||
inline nlohmann::json create_order(const nlohmann::json& order) {
|
||||
@@ -678,7 +852,18 @@ inline nlohmann::json create_order(const nlohmann::json& order) {
|
||||
nlohmann::json zahlungsart = resolve_zahlungsart(c, order.value("paymentMethodName", "Bar"));
|
||||
std::string cAuftragsNr = next_order_number(c, order_date_tm);
|
||||
|
||||
nlohmann::json order_items = order.contains("orderItems") ? order["orderItems"] : nlohmann::json::array();
|
||||
if (!order_items.is_array()) order_items = nlohmann::json::array();
|
||||
|
||||
auto versand_art = lookup_versand_art(c, order.value("shippingName", ""));
|
||||
int kVersandArt = versand_art ? versand_art->kVersandArt : defaults.kVersandArt;
|
||||
if (should_inject_selbstabholer_shipping(order_items) && versand_art) {
|
||||
order_items.push_back(synthetic_shipping_item(*versand_art));
|
||||
}
|
||||
|
||||
int active_shop = get_active_shop_id();
|
||||
const int nIstReadOnly = resolve_n_ist_readonly(order);
|
||||
const int nIstExterneRechnung = resolve_n_ist_externe_rechnung(order);
|
||||
|
||||
const char* insert_auftrag =
|
||||
"DECLARE @t TABLE ([kAuftrag] INT);"
|
||||
@@ -700,7 +885,6 @@ inline nlohmann::json create_order(const nlohmann::json& order) {
|
||||
|
||||
std::string currency_iso = order.value("currencyIso", "EUR");
|
||||
std::string cKundenNr = resolve_auftrag_c_kunden_nr(order);
|
||||
int nIstExterneRechnung = resolve_n_ist_externe_rechnung(order);
|
||||
std::vector<Param> ps = {
|
||||
{ParamType::NVarChar, cAuftragsNr, 0},
|
||||
{ParamType::NVarChar, order_date_sql(order_date_tm), 0},
|
||||
@@ -715,13 +899,13 @@ inline nlohmann::json create_order(const nlohmann::json& order) {
|
||||
{ParamType::Int, "", active_shop == 0 ? -1 : active_shop},
|
||||
{ParamType::NVarChar, cKundenNr, 0},
|
||||
{ParamType::NVarChar, shipping_iso, 0},
|
||||
{ParamType::Int, "", defaults.kVersandArt},
|
||||
{ParamType::Int, "", kVersandArt},
|
||||
{ParamType::Int, "", json_int(zahlungsart, "kZahlungsart", 0)},
|
||||
{ParamType::Int, "", kKundengruppe},
|
||||
{ParamType::NVarChar, order.value("externalOrderNumber", ""), 0},
|
||||
{ParamType::Int, "", nIstExterneRechnung},
|
||||
{ParamType::NVarChar, "Y", 0},
|
||||
{ParamType::Int, "", 2},
|
||||
{ParamType::Int, "", nIstReadOnly},
|
||||
};
|
||||
if (active_shop == 0) {
|
||||
ps[11] = Param::null_int();
|
||||
@@ -738,22 +922,25 @@ inline nlohmann::json create_order(const nlohmann::json& order) {
|
||||
insert_order_address(c, kAuftrag, kKunde, order.value("billingAddress", nlohmann::json::object()), 1);
|
||||
|
||||
std::vector<delivery::DeliveredItem> delivered_items;
|
||||
const nlohmann::json& items = order.contains("orderItems") ? order["orderItems"] : nlohmann::json::array();
|
||||
for (const auto& item : items) {
|
||||
for (const auto& item : order_items) {
|
||||
int kAuftragPosition = insert_order_item(c, kAuftrag, item);
|
||||
insert_pos_order_position_mapping(c, kAuftragPosition, item.value("externalId", ""));
|
||||
if (kAuftragPosition > 0) {
|
||||
delivered_items.push_back({kAuftragPosition, to_number(item["quantity"], 1)});
|
||||
const std::string external_id = item.value("externalId", "");
|
||||
if (!external_id.empty()) {
|
||||
insert_pos_order_position_mapping(c, kAuftragPosition, external_id);
|
||||
}
|
||||
if (kAuftragPosition > 0 && !is_versandposition(item)) {
|
||||
delivered_items.push_back({kAuftragPosition, json_double(item, "quantity", 1)});
|
||||
}
|
||||
}
|
||||
|
||||
const nlohmann::json& payments = order.contains("payments") ? order["payments"] : nlohmann::json::array();
|
||||
for (const auto& payment : payments) {
|
||||
if (!is_new_payment(payment)) continue;
|
||||
insert_payment(c, kAuftrag, payment, order, order_date_tm);
|
||||
}
|
||||
|
||||
if (is_order_delivered(order)) {
|
||||
delivery::deliver_order(c, g_config.kBenutzer, kAuftrag, defaults.kVersandArt, delivered_items);
|
||||
delivery::deliver_order(c, g_config.kBenutzer, kAuftrag, kVersandArt, delivered_items);
|
||||
}
|
||||
|
||||
const char* calc =
|
||||
|
||||
Reference in New Issue
Block a user