Browse Source

separating fields from other constants

module/document
Stephan Richter 1 week ago
parent
commit
25f41cf66b
  1. 8
      company/src/main/java/de/srsoftware/umbrella/company/SqliteDb.java
  2. 51
      core/src/main/java/de/srsoftware/umbrella/core/Constants.java
  3. 33
      core/src/main/java/de/srsoftware/umbrella/core/model/Company.java
  4. 5
      core/src/main/java/de/srsoftware/umbrella/core/model/Customer.java
  5. 61
      core/src/main/java/de/srsoftware/umbrella/core/model/Document.java
  6. 55
      core/src/main/java/de/srsoftware/umbrella/core/model/Position.java
  7. 17
      core/src/main/java/de/srsoftware/umbrella/core/model/PositionList.java
  8. 19
      core/src/main/java/de/srsoftware/umbrella/core/model/Sender.java
  9. 4
      core/src/main/java/de/srsoftware/umbrella/core/model/Template.java
  10. 40
      documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java
  11. 149
      documents/src/main/java/de/srsoftware/umbrella/documents/SqliteDb.java
  12. 4
      documents/src/main/java/de/srsoftware/umbrella/documents/TemplateDoc.java
  13. 12
      documents/src/main/java/de/srsoftware/umbrella/documents/model/CompanySettings.java
  14. 13
      documents/src/main/java/de/srsoftware/umbrella/documents/model/CustomerSettings.java
  15. 3
      stock/src/main/java/de/srsoftware/umbrella/stock/StockModule.java

8
company/src/main/java/de/srsoftware/umbrella/company/SqliteDb.java

@ -8,6 +8,8 @@ import static de.srsoftware.tools.jdbc.Query.Dialect.SQLITE;
import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL; import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL;
import static de.srsoftware.umbrella.company.Constants.*; import static de.srsoftware.umbrella.company.Constants.*;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Field.*;
import static de.srsoftware.umbrella.core.Field.COMPANY_ID;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException;
import static java.lang.System.Logger.Level.ERROR; import static java.lang.System.Logger.Level.ERROR;
import static java.text.MessageFormat.format; import static java.text.MessageFormat.format;
@ -130,7 +132,7 @@ CREATE TABLE IF NOT EXISTS "companies" (
var query = select(DISTINCT).from(TABLE_COMPANIES).leftJoin(ID,TABLE_COMPANIES_USERS,COMPANY_ID) var query = select(DISTINCT).from(TABLE_COMPANIES).leftJoin(ID,TABLE_COMPANIES_USERS,COMPANY_ID)
.where(USER_ID,equal(userId)); .where(USER_ID,equal(userId));
for (var key : keys){ for (var key : keys){
query.where(format("CONCAT({0},\" \",{1},\" \",{2},\" \",{3},\" \",{4})",NAME,ADDRESS,EMAIL,FIELD_PHONE,FIELD_BANK_ACCOUNT),like("%"+key+"%")); query.where(format("CONCAT({0},\" \",{1},\" \",{2},\" \",{3},\" \",{4})",NAME,ADDRESS,EMAIL,PHONE,BANK_ACCOUNT),like("%"+key+"%"));
} }
var rs = query.exec(db); var rs = query.exec(db);
var companies = new HashMap<Long,Company>(); var companies = new HashMap<Long,Company>();
@ -180,7 +182,7 @@ CREATE TABLE IF NOT EXISTS "companies" (
try { try {
if (company.id() == 0){ // new if (company.id() == 0){ // new
long id = 0; long id = 0;
var rs = insertInto(TABLE_COMPANIES,NAME, ADDRESS, EMAIL, FIELD_PHONE, FIELD_BANK_ACCOUNT, FIELD_COURT, FIELD_CURRENCY, FIELD_TAX_NUMBER, DECIMALS, DECIMAL_SEPARATOR, THOUSANDS_SEPARATOR, LAST_CUSTOMER_NUMBER, CUSTOMER_NUMBER_PREFIX) var rs = insertInto(TABLE_COMPANIES,NAME, ADDRESS, EMAIL, PHONE, BANK_ACCOUNT, COURT, CURRENCY, TAX_NUMBER, DECIMALS, DECIMAL_SEPARATOR, THOUSANDS_SEPARATOR, LAST_CUSTOMER_NUMBER, CUSTOMER_NUMBER_PREFIX)
.values(company.name(),company.address(),company.email(),company.phone(),company.bankAccount(),company.court(),company.currency(),company.taxId(),company.decimals(),company.decimalSeparator(),company.thousandsSeparator(),0,company.customerNumberPrefix()) .values(company.name(),company.address(),company.email(),company.phone(),company.bankAccount(),company.court(),company.currency(),company.taxId(),company.decimals(),company.decimalSeparator(),company.thousandsSeparator(),0,company.customerNumberPrefix())
.execute(db) .execute(db)
.getGeneratedKeys(); .getGeneratedKeys();
@ -195,7 +197,7 @@ CREATE TABLE IF NOT EXISTS "companies" (
} else { // update } else { // update
if (company.isDirty()) { if (company.isDirty()) {
update(TABLE_COMPANIES) update(TABLE_COMPANIES)
.set(NAME, ADDRESS, EMAIL, FIELD_PHONE, FIELD_BANK_ACCOUNT, FIELD_COURT, FIELD_CURRENCY, FIELD_TAX_NUMBER, DECIMALS, DECIMAL_SEPARATOR, THOUSANDS_SEPARATOR, LAST_CUSTOMER_NUMBER, CUSTOMER_NUMBER_PREFIX) .set(NAME, ADDRESS, EMAIL, PHONE, BANK_ACCOUNT, COURT, CURRENCY, TAX_NUMBER, DECIMALS, DECIMAL_SEPARATOR, THOUSANDS_SEPARATOR, LAST_CUSTOMER_NUMBER, CUSTOMER_NUMBER_PREFIX)
.where(ID,equal(company.id())).prepare(db) .where(ID,equal(company.id())).prepare(db)
.apply(company.name(), company.address(), company.email(), company.phone(), company.bankAccount(), company.court(), company.currency(), company.taxId(), company.decimals(), company.decimalSeparator(), company.thousandsSeparator(), company.lastCustomerNumber(), company.customerNumberPrefix()) .apply(company.name(), company.address(), company.email(), company.phone(), company.bankAccount(), company.court(), company.currency(), company.taxId(), company.decimals(), company.decimalSeparator(), company.thousandsSeparator(), company.lastCustomerNumber(), company.customerNumberPrefix())
.close(); .close();

51
core/src/main/java/de/srsoftware/umbrella/core/Constants.java

@ -34,8 +34,6 @@ public class Constants {
public static final String DATE = "date"; public static final String DATE = "date";
public static final String DECIMALS = "decimals"; public static final String DECIMALS = "decimals";
public static final String DECIMAL_SEPARATOR = "decimal_separator"; public static final String DECIMAL_SEPARATOR = "decimal_separator";
public static final String DEFAULT_LANGUAGE = "en";
public static final String DEFAULT_THEME = "winter";
public static final String DELETED = "deleted"; public static final String DELETED = "deleted";
public static final String DESCRIPTION = "description"; public static final String DESCRIPTION = "description";
public static final String DOMAIN = "domain"; public static final String DOMAIN = "domain";
@ -56,53 +54,7 @@ public class Constants {
public static final String EXPIRATION = "expiration"; public static final String EXPIRATION = "expiration";
public static final String FALLBACK_LANG = "de"; public static final String FALLBACK_LANG = "de";
public static final String FIELD_BANK_ACCOUNT = "bank_account";
public static final String FIELD_COURT = "court";
public static final String FIELD_CURRENCY = "currency";
public static final String FIELD_END_TIME = "end_time";
public static final String FIELD_PHONE = "phone";
public static final String FIELD_START_TIME = "start_time";
public static final String FIELD_TASKS = "tasks";
public static final String FIELD_TAX_NUMBER = "tax_number";
public static final String FIELD_TAX = "tax";
public static final String FIELD_UNIT_PRICE = "unit_price";
public static final String FIELD_AMOUNT = "amount";
public static final String FIELD_COMPANY = "company";
public static final String FIELD_COMPANY_ID = "company_id";
public static final String FIELD_CUSTOMER = "customer";
public static final String FIELD_CUSTOMER_EMAIL = "customer_email";
public static final String FIELD_CUSTOMER_NUMBER = "customer_number";
public static final String FIELD_CUSTOMER_TAX_NUMBER = "customer_tax_number";
public static final String FIELD_DEFAULT_HEADER = "default_header";
public static final String FIELD_DEFAULT_FOOTER = "default_footer";
public static final String FIELD_DEFAULT_MAIL = "type_mail_text";
public static final String FIELD_DELIVERY = "delivery";
public static final String FIELD_DELIVERY_DATE = "delivery_date";
public static final String FIELD_DOCUMENT = "document";
public static final String FIELD_DOCUMENT_ID = "document_id";
public static final String FIELD_DOC_TYPE_ID = "document_type_id";
public static final String FIELD_FOOTER = "footer";
public static final String FIELD_GROSS_SUM = "gross_sum";
public static final String FIELD_HEAD = "head";
public static final String FIELD_ITEM = "item";
public static final String FIELD_ITEM_CODE = "item_code";
public static final String FIELD_NET_PRICE = "net_price";
public static final String FIELD_NET_SUM = "net_sum";
public static final String FIELD_NEXT_TYPE = "next_type_id";
public static final String FIELD_POS = "pos";
public static final String FIELD_POSITIONS = "positions";
public static final String FIELD_PRICE = "single_price";
public static final String FIELD_PRICE_FORMAT = "price_format";
public static final String FIELD_TEMPLATE_ID = "template_id";
public static final String FIELD_TAX_ID = "tax_id";
public static final String FIELD_TIME_ID = "time_id";
public static final String FIELD_TYPE = "type";
public static final String FIELD_TYPE_ID = "type_id";
public static final String FIELD_TYPE_NUMBER = "type_number";
public static final String FIELD_TYPE_PREFIX = "type_prefix";
public static final String FIELD_TYPE_SUFFIX = "type_suffix";
public static final String FIELD_UNIT = "unit";
public static final String FROM = "from"; public static final String FROM = "from";
public static final String FULLTEXT = "fulltext"; public static final String FULLTEXT = "fulltext";
@ -187,7 +139,6 @@ public class Constants {
public static final String UMBRELLA = "Umbrella"; public static final String UMBRELLA = "Umbrella";
public static final String UNIT = "unit"; public static final String UNIT = "unit";
public static final String UNIT_PRICE = "unit_price";
public static final String URI = "uri"; public static final String URI = "uri";
public static final String URL = "url"; public static final String URL = "url";
public static final String USER = "user"; public static final String USER = "user";

33
core/src/main/java/de/srsoftware/umbrella/core/model/Company.java

@ -3,6 +3,9 @@ package de.srsoftware.umbrella.core.model;
import static de.srsoftware.tools.Optionals.emptyIfNull; import static de.srsoftware.tools.Optionals.emptyIfNull;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Constants.COMPANY;
import static de.srsoftware.umbrella.core.Field.*;
import static de.srsoftware.umbrella.core.Field.TYPE;
import static java.util.Map.entry; import static java.util.Map.entry;
import de.srsoftware.tools.Mappable; import de.srsoftware.tools.Mappable;
@ -125,11 +128,11 @@ public class Company implements Mappable, Owner {
var name = json.getString(NAME); var name = json.getString(NAME);
var address = json.getString(ADDRESS); var address = json.getString(ADDRESS);
var email = json.getString(EMAIL); var email = json.getString(EMAIL);
var phone = json.getString(FIELD_PHONE); var phone = json.getString(PHONE);
var bankAccount = json.getString(FIELD_BANK_ACCOUNT); var bankAccount = json.getString(BANK_ACCOUNT);
var court = json.getString(FIELD_COURT); var court = json.getString(COURT);
var currency = json.getString(FIELD_CURRENCY); var currency = json.getString(CURRENCY);
var taxId = json.getString(FIELD_TAX_NUMBER); var taxId = json.getString(TAX_NUMBER);
var decimals = json.getInt(DECIMALS); var decimals = json.getInt(DECIMALS);
var decimalSep = json.getString(DECIMAL_SEPARATOR); var decimalSep = json.getString(DECIMAL_SEPARATOR);
var thousandsSep = json.getString(THOUSANDS_SEPARATOR); var thousandsSep = json.getString(THOUSANDS_SEPARATOR);
@ -146,17 +149,17 @@ public class Company implements Mappable, Owner {
switch (key){ switch (key){
case NAME: name = json.getString(NAME); break; case NAME: name = json.getString(NAME); break;
case ADDRESS: address = json.getString(ADDRESS); break; case ADDRESS: address = json.getString(ADDRESS); break;
case FIELD_COURT: court = json.getString(FIELD_COURT); break; case COURT: court = json.getString(COURT); break;
case FIELD_TAX_NUMBER: taxId = json.getString(FIELD_TAX_NUMBER); break; case TAX_NUMBER: taxId = json.getString(TAX_NUMBER); break;
case FIELD_PHONE: phone = json.getString(FIELD_PHONE); break; case PHONE: phone = json.getString(PHONE); break;
case DECIMAL_SEPARATOR: decimalSeparator = json.getString(DECIMAL_SEPARATOR); break; case DECIMAL_SEPARATOR: decimalSeparator = json.getString(DECIMAL_SEPARATOR); break;
case THOUSANDS_SEPARATOR: thousandsSeparator = json.getString(THOUSANDS_SEPARATOR); break; case THOUSANDS_SEPARATOR: thousandsSeparator = json.getString(THOUSANDS_SEPARATOR); break;
case LAST_CUSTOMER_NUMBER: lastCustomerNumber = json.getLong(LAST_CUSTOMER_NUMBER); break; case LAST_CUSTOMER_NUMBER: lastCustomerNumber = json.getLong(LAST_CUSTOMER_NUMBER); break;
case DECIMALS: decimals = json.getInt(DECIMALS); break; case DECIMALS: decimals = json.getInt(DECIMALS); break;
case CUSTOMER_NUMBER_PREFIX: customerNumberPrefix = json.getString(CUSTOMER_NUMBER_PREFIX); break; case CUSTOMER_NUMBER_PREFIX: customerNumberPrefix = json.getString(CUSTOMER_NUMBER_PREFIX); break;
case FIELD_CURRENCY: currency = json.getString(FIELD_CURRENCY); break; case CURRENCY: currency = json.getString(CURRENCY); break;
case EMAIL: email = json.getString(EMAIL); break; case EMAIL: email = json.getString(EMAIL); break;
case FIELD_BANK_ACCOUNT: bankAccount = json.getString(FIELD_BANK_ACCOUNT); break; case BANK_ACCOUNT: bankAccount = json.getString(BANK_ACCOUNT); break;
default: key = null; default: key = null;
} }
if (key != null) dirtyFields.add(key); if (key != null) dirtyFields.add(key);
@ -196,17 +199,17 @@ public class Company implements Mappable, Owner {
return Map.ofEntries( return Map.ofEntries(
entry(NAME,name), entry(NAME,name),
entry(ADDRESS,emptyIfNull(address)), entry(ADDRESS,emptyIfNull(address)),
entry(FIELD_COURT,emptyIfNull(court)), entry(COURT,emptyIfNull(court)),
entry(FIELD_TAX_NUMBER,emptyIfNull(taxId)), entry(TAX_NUMBER,emptyIfNull(taxId)),
entry(FIELD_PHONE,emptyIfNull(phone)), entry(PHONE,emptyIfNull(phone)),
entry(DECIMAL_SEPARATOR,emptyIfNull(decimalSeparator)), entry(DECIMAL_SEPARATOR,emptyIfNull(decimalSeparator)),
entry(THOUSANDS_SEPARATOR,emptyIfNull(thousandsSeparator)), entry(THOUSANDS_SEPARATOR,emptyIfNull(thousandsSeparator)),
entry(LAST_CUSTOMER_NUMBER,lastCustomerNumber), entry(LAST_CUSTOMER_NUMBER,lastCustomerNumber),
entry(DECIMALS,decimals), entry(DECIMALS,decimals),
entry(CUSTOMER_NUMBER_PREFIX,emptyIfNull(customerNumberPrefix)), entry(CUSTOMER_NUMBER_PREFIX,emptyIfNull(customerNumberPrefix)),
entry(FIELD_CURRENCY,emptyIfNull(currency)), entry(CURRENCY,emptyIfNull(currency)),
entry(EMAIL,emptyIfNull(email)), entry(EMAIL,emptyIfNull(email)),
entry(FIELD_BANK_ACCOUNT,emptyIfNull(bankAccount)), entry(BANK_ACCOUNT,emptyIfNull(bankAccount)),
entry(MEMBERS,memberMap), entry(MEMBERS,memberMap),
entry(TYPE,type()), entry(TYPE,type()),
entry(ID,id) entry(ID,id)

5
core/src/main/java/de/srsoftware/umbrella/core/model/Customer.java

@ -2,6 +2,7 @@
package de.srsoftware.umbrella.core.model; package de.srsoftware.umbrella.core.model;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Field.*;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
import de.srsoftware.tools.Mappable; import de.srsoftware.tools.Mappable;
@ -72,7 +73,7 @@ public final class Customer implements Mappable {
if (!json.has(ID) || !(json.get(ID) instanceof String id)) throw missingFieldException(ID); if (!json.has(ID) || !(json.get(ID) instanceof String id)) throw missingFieldException(ID);
if (!json.has(NAME) || !(json.get(NAME) instanceof String name)) throw missingFieldException(NAME); if (!json.has(NAME) || !(json.get(NAME) instanceof String name)) throw missingFieldException(NAME);
if (!json.has(EMAIL) || !(json.get(EMAIL) instanceof String email)) throw missingFieldException(EMAIL); if (!json.has(EMAIL) || !(json.get(EMAIL) instanceof String email)) throw missingFieldException(EMAIL);
if (!json.has(FIELD_TAX_ID) || !(json.get(FIELD_TAX_ID) instanceof String taxId)) throw missingFieldException(FIELD_TAX_ID); if (!json.has(TAX_ID) || !(json.get(TAX_ID) instanceof String taxId)) throw missingFieldException(TAX_ID);
var lang = json.has(LANGUAGE) && json.get(LANGUAGE) instanceof String l ? l : FALLBACK_LANG; var lang = json.has(LANGUAGE) && json.get(LANGUAGE) instanceof String l ? l : FALLBACK_LANG;
return new Customer(id,name,email,taxId,lang); return new Customer(id,name,email,taxId,lang);
} }
@ -83,7 +84,7 @@ public final class Customer implements Mappable {
case ID: id = json.getString(key); break; case ID: id = json.getString(key); break;
case NAME: name = json.getString(key); break; case NAME: name = json.getString(key); break;
case EMAIL: email = json.getString(key); break; case EMAIL: email = json.getString(key); break;
case FIELD_TAX_ID: taxNumber = json.getString(key); break; case TAX_ID: taxNumber = json.getString(key); break;
default: key = null; default: key = null;
} }
if (key != null) dirtyFields.add(key); if (key != null) dirtyFields.add(key);

61
core/src/main/java/de/srsoftware/umbrella/core/model/Document.java

@ -2,6 +2,9 @@
package de.srsoftware.umbrella.core.model; package de.srsoftware.umbrella.core.model;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Field.*;
import static de.srsoftware.umbrella.core.Field.COMPANY;
import static de.srsoftware.umbrella.core.Field.TYPE;
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_UNPROCESSABLE; import static de.srsoftware.umbrella.core.ResponseCode.HTTP_UNPROCESSABLE;
import static de.srsoftware.umbrella.core.Util.mapMarkdown; import static de.srsoftware.umbrella.core.Util.mapMarkdown;
import static java.util.Optional.empty; import static java.util.Optional.empty;
@ -193,17 +196,17 @@ public final class Document implements Mappable {
public void patch(JSONObject json) throws UmbrellaException { public void patch(JSONObject json) throws UmbrellaException {
for (var key : json.keySet()){ for (var key : json.keySet()){
switch (key){ switch (key){
case FIELD_CUSTOMER: if (json.get(key) instanceof JSONObject nested) customer.patch(nested); break; case CUSTOMER: if (json.get(key) instanceof JSONObject nested) customer.patch(nested); break;
case FIELD_CURRENCY: currency = json.getString(key); break; case CURRENCY: currency = json.getString(key); break;
case DATE: date = LocalDate.parse(json.getString(key)); break; case DATE: date = LocalDate.parse(json.getString(key)); break;
case FIELD_DELIVERY: delivery = json.getString(key); break; case DELIVERY: delivery = json.getString(key); break;
case FIELD_FOOTER: footer = json.getString(key); break; case FOOTER: footer = json.getString(key); break;
case FIELD_HEAD: head = json.getString(key); break; case HEAD: head = json.getString(key); break;
case NUMBER: number = json.getString(key); break; case NUMBER: number = json.getString(key); break;
case SENDER: if (json.get(key) instanceof JSONObject nested) sender.patch(nested); break; case SENDER: if (json.get(key) instanceof JSONObject nested) sender.patch(nested); break;
case STATE: state = State.of(json.getInt(key)).orElseThrow(() -> new UmbrellaException(HTTP_UNPROCESSABLE,"Invalid state")); break; case STATE: state = State.of(json.getInt(key)).orElseThrow(() -> new UmbrellaException(HTTP_UNPROCESSABLE,"Invalid state")); break;
case FIELD_POS: if (json.get(key) instanceof JSONObject nested) positions.patch(nested); break; case POS: if (json.get(key) instanceof JSONObject nested) positions.patch(nested); break;
case FIELD_TEMPLATE_ID: if (json.get(key) instanceof Number num) template = new Template(num.longValue(),companyId,null,null); break; case TEMPLATE_ID: if (json.get(key) instanceof Number num) template = new Template(num.longValue(),companyId,null,null); break;
default: key = null; default: key = null;
} }
if (key != null) dirtyFields.add(key); if (key != null) dirtyFields.add(key);
@ -217,21 +220,21 @@ public final class Document implements Mappable {
public Map<String, Object> renderToMap() { public Map<String, Object> renderToMap() {
var map = new HashMap<String, Object>(); var map = new HashMap<String, Object>();
map.put(ID, id); map.put(ID, id);
map.put(FIELD_COMPANY, Map.of(ID,companyId, NAME,companyName)); map.put(COMPANY, Map.of(ID,companyId, NAME,companyName));
map.put(NUMBER, number); map.put(NUMBER, number);
map.put(FIELD_TYPE, type.name()); map.put(TYPE, type.name());
map.put(DATE, date); map.put(DATE, date);
map.put(STATE, state.code); map.put(STATE, state.code);
map.put(FIELD_DELIVERY, delivery == null ? "" : delivery); map.put(DELIVERY, delivery == null ? "" : delivery);
map.put(FIELD_HEAD, mapMarkdown(head)); map.put(HEAD, mapMarkdown(head));
map.put(FIELD_FOOTER, mapMarkdown(footer)); map.put(FOOTER, mapMarkdown(footer));
map.put(FIELD_CURRENCY, currency); map.put(CURRENCY, currency);
map.put(SENDER, sender.toMap()); map.put(SENDER, sender.toMap());
map.put(FIELD_CUSTOMER, customer.toMap()); map.put(CUSTOMER, customer.toMap());
map.put(FIELD_POSITIONS, positions.asMap(true)); map.put(POSITIONS, positions.asMap(true));
map.put("taxes",positions.taxNetSums(true)); map.put("taxes",positions.taxNetSums(true));
map.put(FIELD_NET_SUM, netSum()); map.put(NET_SUM, netSum());
map.put(FIELD_GROSS_SUM, grossSum()); map.put(GROSS_SUM, grossSum());
if (template != null) map.put("template", template.toMap()); if (template != null) map.put("template", template.toMap());
return map; return map;
} }
@ -277,8 +280,8 @@ public final class Document implements Mappable {
"type", type.name(), "type", type.name(),
STATE, Map.of(NAME,state.toString(),ID,state.code), STATE, Map.of(NAME,state.toString(),ID,state.code),
DATE, date, DATE, date,
FIELD_CURRENCY, currency, CURRENCY, currency,
FIELD_CUSTOMER, customer.toMap(), CUSTOMER, customer.toMap(),
"sum", positions.grossSum(true) "sum", positions.grossSum(true)
); );
} }
@ -291,21 +294,21 @@ public final class Document implements Mappable {
public Map<String, Object> toMap() { public Map<String, Object> toMap() {
var map = new HashMap<String, Object>(); var map = new HashMap<String, Object>();
map.put(ID, id); map.put(ID, id);
map.put(FIELD_COMPANY, companyId); map.put(COMPANY, companyId);
map.put(NUMBER, number); map.put(NUMBER, number);
map.put(FIELD_TYPE, type); map.put(TYPE, type);
map.put(DATE, date); map.put(DATE, date);
map.put(STATE, state.code); map.put(STATE, state.code);
map.put(FIELD_DELIVERY, delivery); map.put(DELIVERY, delivery);
map.put(FIELD_HEAD, head); map.put(HEAD, head);
map.put(FIELD_FOOTER, footer); map.put(FOOTER, footer);
map.put(FIELD_CURRENCY, currency); map.put(CURRENCY, currency);
map.put(SENDER, sender.toMap()); map.put(SENDER, sender.toMap());
map.put(FIELD_CUSTOMER, customer.toMap()); map.put(CUSTOMER, customer.toMap());
map.put(FIELD_POSITIONS, positions.asMap(false)); map.put(POSITIONS, positions.asMap(false));
map.put("taxes",positions.taxNetSums(true)); map.put("taxes",positions.taxNetSums(true));
map.put(FIELD_NET_SUM, netSum()); map.put(NET_SUM, netSum());
map.put(FIELD_GROSS_SUM, grossSum()); map.put(GROSS_SUM, grossSum());
if (template != null) map.put("template", template.toMap()); if (template != null) map.put("template", template.toMap());
return map; return map;
} }

55
core/src/main/java/de/srsoftware/umbrella/core/model/Position.java

@ -3,6 +3,9 @@ package de.srsoftware.umbrella.core.model;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Field.*;
import static de.srsoftware.umbrella.core.Field.TAX;
import static de.srsoftware.umbrella.core.Field.UNIT;
import static de.srsoftware.umbrella.core.Util.mapMarkdown; import static de.srsoftware.umbrella.core.Util.mapMarkdown;
import de.srsoftware.tools.Mappable; import de.srsoftware.tools.Mappable;
@ -91,7 +94,7 @@ public final class Position implements Mappable {
} }
public boolean isNew(){ public boolean isNew(){
return dirtyFields.contains(FIELD_DOCUMENT_ID); return dirtyFields.contains(DOCUMENT_ID);
} }
public String itemCode() { public String itemCode() {
@ -113,14 +116,14 @@ public final class Position implements Mappable {
public void patch(JSONObject json) { public void patch(JSONObject json) {
for (var key : json.keySet()) { for (var key : json.keySet()) {
switch (key) { switch (key) {
case FIELD_AMOUNT: amount = json.getDouble(key); break; case AMOUNT: amount = json.getDouble(key); break;
case DESCRIPTION: description = json.getString(key); break; case DESCRIPTION: description = json.getString(key); break;
case FIELD_ITEM: itemCode = json.getString(key); break; case ITEM: itemCode = json.getString(key); break;
case OPTIONAL: optional = json.getBoolean(key); break; case OPTIONAL: optional = json.getBoolean(key); break;
case FIELD_TAX: tax = json.getInt(key); break; case TAX: tax = json.getInt(key); break;
case TITLE: title = json.getString(key); break; case TITLE: title = json.getString(key); break;
case FIELD_UNIT: unit = json.getString(key); break; case UNIT: unit = json.getString(key); break;
case FIELD_UNIT_PRICE: unitPrice = json.getLong(key); break; case UNIT_PRICE: unitPrice = json.getLong(key); break;
default: key = null; default: key = null;
} }
if (key != null) dirtyFields.add(key); if (key != null) dirtyFields.add(key);
@ -129,25 +132,25 @@ public final class Position implements Mappable {
public Position setDocId(long docId) { public Position setDocId(long docId) {
this.docId = docId; this.docId = docId;
dirtyFields.add(FIELD_DOCUMENT_ID); dirtyFields.add(DOCUMENT_ID);
return this; return this;
} }
public Position setItemCode(String newValue) { public Position setItemCode(String newValue) {
this.itemCode = newValue; this.itemCode = newValue;
dirtyFields.add(FIELD_ITEM); dirtyFields.add(ITEM);
return this; return this;
} }
public Position setUnit(String newValue) { public Position setUnit(String newValue) {
unit = newValue; unit = newValue;
dirtyFields.add(FIELD_UNIT); dirtyFields.add(UNIT);
return this; return this;
} }
public void setUnitPrice(long price) { public void setUnitPrice(long price) {
unitPrice = price; unitPrice = price;
dirtyFields.add(FIELD_UNIT_PRICE); dirtyFields.add(UNIT_PRICE);
} }
public int tax() { public int tax() {
@ -171,35 +174,35 @@ public final class Position implements Mappable {
@Override @Override
public Map<String, Object> toMap() { public Map<String, Object> toMap() {
var map = new HashMap<String, Object>(); var map = new HashMap<String, Object>();
map.put(FIELD_DOCUMENT_ID, docId); map.put(DOCUMENT_ID, docId);
map.put(NUMBER, num); map.put(NUMBER, num);
map.put(FIELD_ITEM, itemCode); map.put(ITEM, itemCode);
map.put(FIELD_AMOUNT, amount); map.put(AMOUNT, amount);
map.put(FIELD_UNIT, unit); map.put(UNIT, unit);
map.put(TITLE, title); map.put(TITLE, title);
map.put(DESCRIPTION, description); map.put(DESCRIPTION, description);
map.put(FIELD_UNIT_PRICE, unitPrice); map.put(UNIT_PRICE, unitPrice);
map.put(FIELD_TAX, tax); map.put(TAX, tax);
map.put(FIELD_TIME_ID, timeId); map.put(TIME_ID, timeId);
map.put(OPTIONAL, optional); map.put(OPTIONAL, optional);
map.put(FIELD_NET_PRICE, netPrice()); map.put(NET_PRICE, netPrice());
return map; return map;
} }
public Map<String, Object> renderToMap() { public Map<String, Object> renderToMap() {
var map = new HashMap<String, Object>(); var map = new HashMap<String, Object>();
map.put(FIELD_DOCUMENT_ID, docId); map.put(DOCUMENT_ID, docId);
map.put(NUMBER, num); map.put(NUMBER, num);
map.put(FIELD_ITEM, itemCode); map.put(ITEM, itemCode);
map.put(FIELD_AMOUNT, amount); map.put(AMOUNT, amount);
map.put(FIELD_UNIT, unit); map.put(UNIT, unit);
map.put(TITLE, title); map.put(TITLE, title);
map.put(DESCRIPTION, mapMarkdown(description)); map.put(DESCRIPTION, mapMarkdown(description));
map.put(FIELD_UNIT_PRICE, unitPrice); map.put(UNIT_PRICE, unitPrice);
map.put(FIELD_TAX, tax); map.put(TAX, tax);
map.put(FIELD_TIME_ID, timeId); map.put(TIME_ID, timeId);
map.put(OPTIONAL, optional); map.put(OPTIONAL, optional);
map.put(FIELD_NET_PRICE, netPrice()); map.put(NET_PRICE, netPrice());
return map; return map;
} }

17
core/src/main/java/de/srsoftware/umbrella/core/model/PositionList.java

@ -2,6 +2,11 @@
package de.srsoftware.umbrella.core.model; package de.srsoftware.umbrella.core.model;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Field.*;
import static de.srsoftware.umbrella.core.Field.END_TIME;
import static de.srsoftware.umbrella.core.Field.START_TIME;
import static de.srsoftware.umbrella.core.Field.TAX;
import static de.srsoftware.umbrella.core.Field.UNIT;
import de.srsoftware.tools.Pair; import de.srsoftware.tools.Pair;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
@ -23,8 +28,8 @@ public class PositionList extends HashMap<Integer,Position> {
var unit = item.getString(UNIT); var unit = item.getString(UNIT);
var name = item.getString(NAME); var name = item.getString(NAME);
var description = item.getString(DESCRIPTION); var description = item.getString(DESCRIPTION);
var unitPrice = item.getLong(FIELD_UNIT_PRICE); var unitPrice = item.getLong(UNIT_PRICE);
var tax = item.getInt(FIELD_TAX); var tax = item.getInt(TAX);
var position = new Position(size()+1,itemCode,1.0,unit,name,description,unitPrice,tax,null,false); var position = new Position(size()+1,itemCode,1.0,unit,name,description,unitPrice,tax,null,false);
add(position); add(position);
return position; return position;
@ -44,15 +49,15 @@ public class PositionList extends HashMap<Integer,Position> {
public Position addTime(JSONObject time) { public Position addTime(JSONObject time) {
var id = time.getLong(ID); var id = time.getLong(ID);
var start = time.getLong(FIELD_START_TIME); var start = time.getLong(START_TIME);
var end = time.getLong(FIELD_END_TIME); var end = time.getLong(END_TIME);
var amount = (end - start)/3600d; var amount = (end - start)/3600d;
var name = time.getString(SUBJECT); var name = time.getString(SUBJECT);
var desc = time.getString(DESCRIPTION).trim(); var desc = time.getString(DESCRIPTION).trim();
var description = new StringBuilder(); var description = new StringBuilder();
if (!desc.isEmpty()) description.append(desc); if (!desc.isEmpty()) description.append(desc);
if (time.has(FIELD_TASKS)){ if (time.has(TASKS)){
var tasks = time.getJSONObject(FIELD_TASKS); var tasks = time.getJSONObject(TASKS);
var taskKeys = tasks.keySet(); var taskKeys = tasks.keySet();
if (taskKeys.size()>1) { // description normally came from first task if (taskKeys.size()>1) { // description normally came from first task
if (!desc.isEmpty()) description.append("\n\n"); if (!desc.isEmpty()) description.append("\n\n");

19
core/src/main/java/de/srsoftware/umbrella/core/model/Sender.java

@ -2,6 +2,7 @@
package de.srsoftware.umbrella.core.model; package de.srsoftware.umbrella.core.model;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Field.*;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
import de.srsoftware.tools.Mappable; import de.srsoftware.tools.Mappable;
@ -65,19 +66,19 @@ public final class Sender implements Mappable {
public static Sender of(JSONObject json) throws UmbrellaException { public static Sender of(JSONObject json) throws UmbrellaException {
if (!json.has(NAME) || !(json.get(NAME) instanceof String name)) throw missingFieldException(NAME); if (!json.has(NAME) || !(json.get(NAME) instanceof String name)) throw missingFieldException(NAME);
if (!json.has(FIELD_BANK_ACCOUNT) || !(json.get(FIELD_BANK_ACCOUNT) instanceof String bankAccount)) throw missingFieldException(FIELD_BANK_ACCOUNT); if (!json.has(BANK_ACCOUNT) || !(json.get(BANK_ACCOUNT) instanceof String bankAccount)) throw missingFieldException(BANK_ACCOUNT);
if (!json.has(FIELD_TAX_ID) || !(json.get(FIELD_TAX_ID) instanceof String taxId)) throw missingFieldException(FIELD_TAX_ID); if (!json.has(TAX_ID) || !(json.get(TAX_ID) instanceof String taxId)) throw missingFieldException(TAX_ID);
if (!json.has(FIELD_COURT) || !(json.get(FIELD_COURT) instanceof String court)) throw missingFieldException(FIELD_COURT); if (!json.has(COURT) || !(json.get(COURT) instanceof String court)) throw missingFieldException(COURT);
return new Sender(name,bankAccount,taxId,court); return new Sender(name,bankAccount,taxId,court);
} }
public void patch(JSONObject json) { public void patch(JSONObject json) {
for (var key : json.keySet()){ for (var key : json.keySet()){
switch (key){ switch (key){
case FIELD_BANK_ACCOUNT: bankAccount = json.getString(key); break; case BANK_ACCOUNT: bankAccount = json.getString(key); break;
case NAME: name = json.getString(key); break; case NAME: name = json.getString(key); break;
case FIELD_COURT: court = json.getString(key); break; case COURT: court = json.getString(key); break;
case FIELD_TAX_ID: taxNumber = json.getString(key); break; case TAX_ID: taxNumber = json.getString(key); break;
default: key = null; default: key = null;
} }
if (key != null) dirtyFields.add(key); if (key != null) dirtyFields.add(key);
@ -91,10 +92,10 @@ public final class Sender implements Mappable {
@Override @Override
public Map<String, Object> toMap() { public Map<String, Object> toMap() {
return Map.of( return Map.of(
FIELD_BANK_ACCOUNT, bankAccount, BANK_ACCOUNT, bankAccount,
FIELD_COURT, court, COURT, court,
NAME, name, NAME, name,
FIELD_TAX_ID, taxNumber TAX_ID, taxNumber
); );
} }

4
core/src/main/java/de/srsoftware/umbrella/core/model/Template.java

@ -2,6 +2,8 @@
package de.srsoftware.umbrella.core.model; package de.srsoftware.umbrella.core.model;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Field.COMPANY;
import static de.srsoftware.umbrella.core.Field.COMPANY_ID;
import de.srsoftware.tools.Mappable; import de.srsoftware.tools.Mappable;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -16,6 +18,6 @@ public record Template(long id, long company, String name, byte[] data) implemen
@Override @Override
public Map<String, Object> toMap() { public Map<String, Object> toMap() {
return Map.of(ID,id, FIELD_COMPANY,company, NAME,name); return Map.of(ID,id, COMPANY,company, NAME,name);
} }
} }

40
documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java

@ -12,15 +12,11 @@ import static de.srsoftware.tools.Optionals.isSet;
import static de.srsoftware.tools.Strings.escapeHtmlEntities; import static de.srsoftware.tools.Strings.escapeHtmlEntities;
import static de.srsoftware.umbrella.core.ConnectionProvider.connect; import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Constants.FIELD_AMOUNT; import static de.srsoftware.umbrella.core.Field.*;
import static de.srsoftware.umbrella.core.Constants.FIELD_COMPANY; import static de.srsoftware.umbrella.core.Field.COMPANY;
import static de.srsoftware.umbrella.core.Constants.FIELD_CUSTOMER; import static de.srsoftware.umbrella.core.Field.TAX;
import static de.srsoftware.umbrella.core.Constants.FIELD_DOCUMENT; import static de.srsoftware.umbrella.core.Field.TYPE;
import static de.srsoftware.umbrella.core.Constants.FIELD_ITEM_CODE; import static de.srsoftware.umbrella.core.Field.UNIT;
import static de.srsoftware.umbrella.core.Constants.FIELD_PRICE_FORMAT;
import static de.srsoftware.umbrella.core.Constants.FIELD_TIME_ID;
import static de.srsoftware.umbrella.core.Constants.FIELD_TYPE;
import static de.srsoftware.umbrella.core.Constants.FIELD_UNIT;
import static de.srsoftware.umbrella.core.ModuleRegistry.*; import static de.srsoftware.umbrella.core.ModuleRegistry.*;
import static de.srsoftware.umbrella.core.Paths.*; import static de.srsoftware.umbrella.core.Paths.*;
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_UNPROCESSABLE; import static de.srsoftware.umbrella.core.ResponseCode.HTTP_UNPROCESSABLE;
@ -274,7 +270,7 @@ public class DocumentApi extends BaseHandler implements DocumentService {
var author = new Author(name,countryID,postCode,city,streetAddress,taxNumber); var author = new Author(name,countryID,postCode,city,streetAddress,taxNumber);
match = POST_CODE.matcher(document.customer().name()); match = POST_CODE.matcher(document.customer().name());
if (!match.find()) throw unprocessable(ERROR_ADDRESS_MISSING,FIELD_CUSTOMER); if (!match.find()) throw unprocessable(ERROR_ADDRESS_MISSING,CUSTOMER);
name = escapeHtmlEntities(match.group(1).trim()); name = escapeHtmlEntities(match.group(1).trim());
streetAddress = escapeHtmlEntities(match.group(2).trim()); streetAddress = escapeHtmlEntities(match.group(2).trim());
postCode = match.group(3); postCode = match.group(3);
@ -332,10 +328,10 @@ public class DocumentApi extends BaseHandler implements DocumentService {
if (optDoc.isEmpty()) throw UmbrellaException.notFound("Cannot render {0} {1}: Missing template \"{2}\"",type,document.number(),template); if (optDoc.isEmpty()) throw UmbrellaException.notFound("Cannot render {0} {1}: Missing template \"{2}\"",type,document.number(),template);
Function<String,String> translate = text -> translator().translate(user.language(),text); Function<String,String> translate = text -> translator().translate(user.language(),text);
var pdfData = new HashMap<String,Object>(); var pdfData = new HashMap<String,Object>();
pdfData.put(FIELD_DOCUMENT,document.renderToMap()); pdfData.put(DOCUMENT,document.renderToMap());
pdfData.put("translate",translate); pdfData.put("translate",translate);
pdfData.put(USER,user); pdfData.put(USER,user);
pdfData.put(FIELD_PRICE_FORMAT, priceFormat(document.currency(),user.language())); pdfData.put(PRICE_FORMAT, priceFormat(document.currency(),user.language()));
Map<String,Object> data = pdfData; Map<String,Object> data = pdfData;
if (zugferd) {// create additional data if (zugferd) {// create additional data
data = Map.of( data = Map.of(
@ -398,7 +394,7 @@ public class DocumentApi extends BaseHandler implements DocumentService {
var doc = getDocument(docId,user).a; var doc = getDocument(docId,user).a;
var data = json(ex); var data = json(ex);
doc.patch(data); doc.patch(data);
if (doc.isDirty(FIELD_FOOTER,FIELD_HEAD)) { if (doc.isDirty(FOOTER,HEAD)) {
var settings = db.getCustomerSettings(doc.companyId(),doc.type(),doc.customer().id()); var settings = db.getCustomerSettings(doc.companyId(),doc.type(),doc.customer().id());
if (settings == null) settings = CustomerSettings.empty(); if (settings == null) settings = CustomerSettings.empty();
db.save(doc.companyId(),doc.type(),doc.customer().id(), settings.patch(data)); db.save(doc.companyId(),doc.type(),doc.customer().id(), settings.patch(data));
@ -466,13 +462,13 @@ public class DocumentApi extends BaseHandler implements DocumentService {
private boolean postDocument(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException { private boolean postDocument(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException {
var json = json(ex); var json = json(ex);
if (!(json.has(SENDER) && json.get(SENDER) instanceof JSONObject senderData)) throw missingFieldException(SENDER); if (!(json.has(SENDER) && json.get(SENDER) instanceof JSONObject senderData)) throw missingFieldException(SENDER);
if (!senderData.has(FIELD_COMPANY) || !(senderData.get(FIELD_COMPANY) instanceof Number companyId)) throw missingFieldException(FIELD_COMPANY); if (!senderData.has(COMPANY) || !(senderData.get(COMPANY) instanceof Number companyId)) throw missingFieldException(COMPANY);
var company = companyService().get(companyId.longValue()); var company = companyService().get(companyId.longValue());
if (!companyService().membership(companyId.longValue(),user.id())) throw forbidden("You are mot a member of company {0}",company); if (!companyService().membership(companyId.longValue(),user.id())) throw forbidden("You are mot a member of company {0}",company);
if (!json.has(FIELD_CUSTOMER) || !(json.get(FIELD_CUSTOMER) instanceof JSONObject customerData)) throw missingFieldException(FIELD_CUSTOMER); if (!json.has(CUSTOMER) || !(json.get(CUSTOMER) instanceof JSONObject customerData)) throw missingFieldException(CUSTOMER);
if (!json.has(FIELD_TYPE) || !(json.get(FIELD_TYPE) instanceof Number docTypeId)) throw missingFieldException(FIELD_TYPE); if (!json.has(TYPE) || !(json.get(TYPE) instanceof Number docTypeId)) throw missingFieldException(TYPE);
var type = db.getType(docTypeId.intValue()); var type = db.getType(docTypeId.intValue());
var customer = Customer.of(customerData); var customer = Customer.of(customerData);
Template template = new Template(6,companyId.longValue(),"unknwon",null); Template template = new Template(6,companyId.longValue(),"unknwon",null);
@ -496,17 +492,17 @@ public class DocumentApi extends BaseHandler implements DocumentService {
var doc = getDocument(docId,user).a; var doc = getDocument(docId,user).a;
var json = json(ex); var json = json(ex);
if (!(json.has(FIELD_AMOUNT) && json.get(FIELD_AMOUNT) instanceof Number amount)) throw missingFieldException(FIELD_AMOUNT); if (!(json.has(AMOUNT) && json.get(AMOUNT) instanceof Number amount)) throw missingFieldException(AMOUNT);
if (!(json.has(DESCRIPTION) && json.get(DESCRIPTION) instanceof String description)) throw missingFieldException(DESCRIPTION); if (!(json.has(DESCRIPTION) && json.get(DESCRIPTION) instanceof String description)) throw missingFieldException(DESCRIPTION);
if (!(json.has(FIELD_ITEM_CODE) && json.get(FIELD_ITEM_CODE) instanceof String itemCode)) throw missingFieldException(FIELD_ITEM_CODE); if (!(json.has(ITEM_CODE) && json.get(ITEM_CODE) instanceof String itemCode)) throw missingFieldException(ITEM_CODE);
if (!(json.has(TITLE) && json.get(TITLE) instanceof String title)) throw missingFieldException(TITLE); if (!(json.has(TITLE) && json.get(TITLE) instanceof String title)) throw missingFieldException(TITLE);
if (!(json.has(FIELD_UNIT) && json.get(FIELD_UNIT) instanceof String unit)) throw missingFieldException(FIELD_UNIT); if (!(json.has(UNIT) && json.get(UNIT) instanceof String unit)) throw missingFieldException(UNIT);
var unitPrice = json.has(FIELD_UNIT_PRICE) && json.get(FIELD_UNIT_PRICE) instanceof Number num ? num : 0L; var unitPrice = json.has(UNIT_PRICE) && json.get(UNIT_PRICE) instanceof Number num ? num : 0L;
try { try {
unitPrice = db.getCustomerPrice(doc.companyId(),doc.customer().id(),itemCode); unitPrice = db.getCustomerPrice(doc.companyId(),doc.customer().id(),itemCode);
} catch (UmbrellaException ignored) {} } catch (UmbrellaException ignored) {}
int tax = json.has(FIELD_TAX) && json.get(FIELD_TAX) instanceof Number t ? t.intValue() : 19; // TODO should not be hard-coded int tax = json.has(TAX) && json.get(TAX) instanceof Number t ? t.intValue() : 19; // TODO should not be hard-coded
Long timeId = json.has(FIELD_TIME_ID) && json.get(FIELD_TIME_ID) instanceof Number t ? t.longValue() : null; Long timeId = json.has(TIME_ID) && json.get(TIME_ID) instanceof Number t ? t.longValue() : null;
var pos = new Position(doc.positions().size()+1,itemCode,amount.doubleValue(),unit,title,description,unitPrice.longValue(),tax,timeId,false); var pos = new Position(doc.positions().size()+1,itemCode,amount.doubleValue(),unit,title,description,unitPrice.longValue(),tax,timeId,false);
doc.positions().add(pos); doc.positions().add(pos);

149
documents/src/main/java/de/srsoftware/umbrella/documents/SqliteDb.java

@ -6,7 +6,10 @@ import static de.srsoftware.tools.jdbc.Condition.*;
import static de.srsoftware.tools.jdbc.Query.*; import static de.srsoftware.tools.jdbc.Query.*;
import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL; import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Constants.FIELD_COMPANY_ID; import static de.srsoftware.umbrella.core.Field.*;
import static de.srsoftware.umbrella.core.Field.COMPANY_ID;
import static de.srsoftware.umbrella.core.Field.TAX;
import static de.srsoftware.umbrella.core.Field.UNIT;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException;
import static de.srsoftware.umbrella.core.model.Document.DEFAULT_THOUSANDS_SEPARATOR; import static de.srsoftware.umbrella.core.model.Document.DEFAULT_THOUSANDS_SEPARATOR;
import static de.srsoftware.umbrella.core.model.Document.State; import static de.srsoftware.umbrella.core.model.Document.State;
@ -51,7 +54,7 @@ public class SqliteDb implements DocumentDb{
private void createTableCompanySettings() { private void createTableCompanySettings() {
var sql = "CREATE TABLE IF NOT EXISTS {0} ({1} INT NOT NULL, {2} INT NOT NULL, {3} TEXT DEFAULT \"A\", {4} TEXT DEFAULT NULL, {5} INT NOT NULL DEFAULT 1, PRIMARY KEY ({1}, {2}))"; var sql = "CREATE TABLE IF NOT EXISTS {0} ({1} INT NOT NULL, {2} INT NOT NULL, {3} TEXT DEFAULT \"A\", {4} TEXT DEFAULT NULL, {5} INT NOT NULL DEFAULT 1, PRIMARY KEY ({1}, {2}))";
try { try {
var stmt = db.prepareStatement(format(sql,TABLE_COMPANY_SETTINGS, FIELD_COMPANY_ID,FIELD_DOC_TYPE_ID,FIELD_TYPE_PREFIX,FIELD_TYPE_SUFFIX,FIELD_TYPE_NUMBER)); var stmt = db.prepareStatement(format(sql,TABLE_COMPANY_SETTINGS, COMPANY_ID,DOC_TYPE_ID,TYPE_PREFIX,TYPE_SUFFIX,TYPE_NUMBER));
stmt.execute(); stmt.execute();
stmt.close(); stmt.close();
} catch (SQLException e) { } catch (SQLException e) {
@ -63,7 +66,7 @@ public class SqliteDb implements DocumentDb{
private void createTableCustomerPrices() { private void createTableCustomerPrices() {
var sql = "CREATE TABLE IF NOT EXISTS {0} ({1} INT NOT NULL, {2} VARCHAR(255), {3} VARCHAR(50), {4} INTEGER)"; var sql = "CREATE TABLE IF NOT EXISTS {0} ({1} INT NOT NULL, {2} VARCHAR(255), {3} VARCHAR(50), {4} INTEGER)";
try { try {
var stmt = db.prepareStatement(format(sql,TABLE_PRICES, FIELD_COMPANY_ID,FIELD_CUSTOMER_NUMBER, FIELD_ITEM_CODE,FIELD_PRICE)); var stmt = db.prepareStatement(format(sql,TABLE_PRICES, COMPANY_ID,CUSTOMER_NUMBER, ITEM_CODE,PRICE));
stmt.execute(); stmt.execute();
stmt.close(); stmt.close();
} catch (SQLException e) { } catch (SQLException e) {
@ -75,7 +78,7 @@ public class SqliteDb implements DocumentDb{
private void createTableCustomerSettings() { private void createTableCustomerSettings() {
var sql = "CREATE TABLE IF NOT EXISTS {0} ({1} INT NOT NULL, {2} INT NOT NULL, {3} VARCHAR(255), {4} TEXT, {5} TEXT, {6} TEXT, PRIMARY KEY ({1}, {2}, {3}))"; var sql = "CREATE TABLE IF NOT EXISTS {0} ({1} INT NOT NULL, {2} INT NOT NULL, {3} VARCHAR(255), {4} TEXT, {5} TEXT, {6} TEXT, PRIMARY KEY ({1}, {2}, {3}))";
try { try {
var stmt = db.prepareStatement(format(sql,TABLE_CUSTOMER_SETTINGS, FIELD_COMPANY_ID,FIELD_DOC_TYPE_ID,FIELD_CUSTOMER_NUMBER,FIELD_DEFAULT_HEADER,FIELD_DEFAULT_FOOTER,FIELD_DEFAULT_MAIL)); var stmt = db.prepareStatement(format(sql,TABLE_CUSTOMER_SETTINGS, COMPANY_ID,DOC_TYPE_ID,CUSTOMER_NUMBER,DEFAULT_HEADER,DEFAULT_FOOTER,DEFAULT_MAIL));
stmt.execute(); stmt.execute();
stmt.close(); stmt.close();
} catch (SQLException e) { } catch (SQLException e) {
@ -108,7 +111,7 @@ CREATE TABLE IF NOT EXISTS {0} (
{18} VARCHAR(255), {18} VARCHAR(255),
{19} VARCHAR(255) {19} VARCHAR(255)
)"""; )""";
createTable = format(createTable,TABLE_DOCUMENTS, ID, FIELD_TYPE_ID, FIELD_COMPANY_ID, NUMBER, DATE, STATE, FIELD_TEMPLATE_ID, FIELD_DELIVERY_DATE,FIELD_HEAD,FIELD_FOOTER,FIELD_CURRENCY, SENDER,FIELD_TAX_NUMBER,FIELD_BANK_ACCOUNT,FIELD_COURT,FIELD_CUSTOMER,FIELD_CUSTOMER_NUMBER,FIELD_CUSTOMER_TAX_NUMBER,FIELD_CUSTOMER_EMAIL); createTable = format(createTable,TABLE_DOCUMENTS, ID, TYPE_ID, COMPANY_ID, NUMBER, DATE, STATE, TEMPLATE_ID, DELIVERY_DATE,HEAD,FOOTER,CURRENCY, SENDER,TAX_NUMBER,BANK_ACCOUNT,COURT,CUSTOMER,CUSTOMER_NUMBER,CUSTOMER_TAX_NUMBER,CUSTOMER_EMAIL);
try { try {
var stmt = db.prepareStatement(createTable); var stmt = db.prepareStatement(createTable);
stmt.execute(); stmt.execute();
@ -122,7 +125,7 @@ CREATE TABLE IF NOT EXISTS {0} (
private void createTableDocumentTypes() { private void createTableDocumentTypes() {
var createTable = "CREATE TABLE IF NOT EXISTS {0} ({1} INTEGER PRIMARY KEY, {2} INT, {3} VARCHAR(255) NOT NULL)"; var createTable = "CREATE TABLE IF NOT EXISTS {0} ({1} INTEGER PRIMARY KEY, {2} INT, {3} VARCHAR(255) NOT NULL)";
try { try {
var stmt = db.prepareStatement(format(createTable,TABLE_DOCUMENT_TYPES, ID,FIELD_NEXT_TYPE, NAME)); var stmt = db.prepareStatement(format(createTable,TABLE_DOCUMENT_TYPES, ID,NEXT_TYPE, NAME));
stmt.execute(); stmt.execute();
stmt.close(); stmt.close();
} catch (SQLException e) { } catch (SQLException e) {
@ -147,7 +150,7 @@ CREATE TABLE IF NOT EXISTS {0} (
{11} BOOLEAN DEFAULT 0 {11} BOOLEAN DEFAULT 0
) )
"""; """;
sql = format(sql,TABLE_POSITIONS,FIELD_DOCUMENT_ID,FIELD_POS, FIELD_ITEM_CODE,FIELD_AMOUNT,FIELD_UNIT, TITLE, DESCRIPTION,FIELD_PRICE,FIELD_TAX,FIELD_TIME_ID, OPTIONAL); sql = format(sql,TABLE_POSITIONS,DOCUMENT_ID,POS, ITEM_CODE,AMOUNT,UNIT, TITLE, DESCRIPTION,PRICE,TAX,TIME_ID, OPTIONAL);
try { try {
var stmt = db.prepareStatement(sql); var stmt = db.prepareStatement(sql);
stmt.execute(); stmt.execute();
@ -191,7 +194,7 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
private void createTableTemplates() { private void createTableTemplates() {
var createTable = "CREATE TABLE IF NOT EXISTS {0} ({1} INTEGER PRIMARY KEY, {2} INT NOT NULL, {3} VARCHAR(255) NOT NULL, {4} BLOB)"; var createTable = "CREATE TABLE IF NOT EXISTS {0} ({1} INTEGER PRIMARY KEY, {2} INT NOT NULL, {3} VARCHAR(255) NOT NULL, {4} BLOB)";
try { try {
var stmt = db.prepareStatement(format(createTable,TABLE_TEMPLATES, ID, FIELD_COMPANY_ID, NAME, TEMPLATE)); var stmt = db.prepareStatement(format(createTable,TABLE_TEMPLATES, ID, COMPANY_ID, NAME, TEMPLATE));
stmt.execute(); stmt.execute();
stmt.close(); stmt.close();
} catch (SQLException e) { } catch (SQLException e) {
@ -208,7 +211,7 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
String number = null; String number = null;
if (rs.next()) number = rs.getString(NUMBER); if (rs.next()) number = rs.getString(NUMBER);
rs.close(); rs.close();
delete().from(TABLE_POSITIONS).where(FIELD_DOCUMENT_ID,equal(docId)).execute(db); delete().from(TABLE_POSITIONS).where(DOCUMENT_ID,equal(docId)).execute(db);
delete().from(TABLE_DOCUMENTS).where(ID,equal(docId)).execute(db); delete().from(TABLE_DOCUMENTS).where(ID,equal(docId)).execute(db);
db.setAutoCommit(true); db.setAutoCommit(true);
if (number != null) return number; if (number != null) return number;
@ -222,8 +225,8 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
public Long dropPosition(long docId, long pos) throws UmbrellaException { public Long dropPosition(long docId, long pos) throws UmbrellaException {
try { try {
db.setAutoCommit(false); db.setAutoCommit(false);
delete().from(TABLE_POSITIONS).where(FIELD_DOCUMENT_ID,equal(docId)).where(FIELD_POS,equal(pos)).execute(db); delete().from(TABLE_POSITIONS).where(DOCUMENT_ID,equal(docId)).where(POS,equal(pos)).execute(db);
var sql = format("UPDATE {0} SET {1} = {1}-1 WHERE {2} = ? AND {1} > ?",TABLE_POSITIONS,FIELD_POS,FIELD_DOCUMENT_ID); var sql = format("UPDATE {0} SET {1} = {1}-1 WHERE {2} = ? AND {1} > ?",TABLE_POSITIONS,POS,DOCUMENT_ID);
LOG.log(DEBUG,sql.replaceFirst("\\?",docId+"").replace("?",pos+"")); LOG.log(DEBUG,sql.replaceFirst("\\?",docId+"").replace("?",pos+""));
var stmt = db.prepareStatement(sql); var stmt = db.prepareStatement(sql);
stmt.setLong(1,docId); stmt.setLong(1,docId);
@ -241,7 +244,7 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
@Override @Override
public CompanySettings getCompanySettings(long companyId, Type docType) throws UmbrellaException { public CompanySettings getCompanySettings(long companyId, Type docType) throws UmbrellaException {
try { try {
var rs = select(ALL).from(TABLE_COMPANY_SETTINGS).where(FIELD_COMPANY_ID,equal(companyId)).where(FIELD_DOC_TYPE_ID,equal(docType.id())).exec(db); var rs = select(ALL).from(TABLE_COMPANY_SETTINGS).where(COMPANY_ID,equal(companyId)).where(DOC_TYPE_ID,equal(docType.id())).exec(db);
CompanySettings settings = null; CompanySettings settings = null;
if (rs.next()) settings = CompanySettings.of(rs); if (rs.next()) settings = CompanySettings.of(rs);
rs.close(); rs.close();
@ -267,9 +270,9 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
@Override @Override
public Long getCustomerPrice(long company, String customer, String itemCode) throws UmbrellaException { public Long getCustomerPrice(long company, String customer, String itemCode) throws UmbrellaException {
try { try {
var rs = select(FIELD_PRICE).from(TABLE_PRICES).where(FIELD_COMPANY_ID,equal(company)).where(FIELD_CUSTOMER_NUMBER,equal(customer)).where(FIELD_ITEM_CODE,equal(itemCode)).exec(db); var rs = select(PRICE).from(TABLE_PRICES).where(COMPANY_ID,equal(company)).where(CUSTOMER_NUMBER,equal(customer)).where(ITEM_CODE,equal(itemCode)).exec(db);
Long price = null; Long price = null;
if (rs.next()) price = rs.getLong(FIELD_PRICE); if (rs.next()) price = rs.getLong(PRICE);
rs.close(); rs.close();
if (price != null) return price; if (price != null) return price;
} catch (SQLException e) { } catch (SQLException e) {
@ -281,7 +284,7 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
@Override @Override
public CustomerSettings getCustomerSettings(long companyId, Type docType, String customerId) throws UmbrellaException { public CustomerSettings getCustomerSettings(long companyId, Type docType, String customerId) throws UmbrellaException {
try { try {
var rs = select(ALL).from(TABLE_CUSTOMER_SETTINGS).where(FIELD_COMPANY_ID,equal(companyId)).where(FIELD_DOC_TYPE_ID,equal(docType.id())).where(FIELD_CUSTOMER_NUMBER,equal(customerId)).exec(db); var rs = select(ALL).from(TABLE_CUSTOMER_SETTINGS).where(COMPANY_ID,equal(companyId)).where(DOC_TYPE_ID,equal(docType.id())).where(CUSTOMER_NUMBER,equal(customerId)).exec(db);
CustomerSettings settings = null; CustomerSettings settings = null;
if (rs.next()) settings = CustomerSettings.of(rs); if (rs.next()) settings = CustomerSettings.of(rs);
rs.close(); rs.close();
@ -314,10 +317,10 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
public Map<Long, Map<Long, String>> docReferencedByTimes(Set<Long> timeIds) throws UmbrellaException { public Map<Long, Map<Long, String>> docReferencedByTimes(Set<Long> timeIds) throws UmbrellaException {
try { try {
var map = new HashMap<Long, Map<Long, String>>(); // Map ( timeId → Map ( docId → name )) var map = new HashMap<Long, Map<Long, String>>(); // Map ( timeId → Map ( docId → name ))
var rs = select(FIELD_TIME_ID,FIELD_DOCUMENT_ID,NUMBER).from(TABLE_POSITIONS).leftJoin(FIELD_DOCUMENT_ID,TABLE_DOCUMENTS,ID).where(FIELD_TIME_ID,in(timeIds.toArray())).exec(db); var rs = select(TIME_ID,DOCUMENT_ID,NUMBER).from(TABLE_POSITIONS).leftJoin(DOCUMENT_ID,TABLE_DOCUMENTS,ID).where(TIME_ID,in(timeIds.toArray())).exec(db);
while (rs.next()) { while (rs.next()) {
var timeId = rs.getLong(FIELD_TIME_ID); var timeId = rs.getLong(TIME_ID);
var docId = rs.getLong(FIELD_DOCUMENT_ID); var docId = rs.getLong(DOCUMENT_ID);
var number = rs.getString(NUMBER); var number = rs.getString(NUMBER);
map.computeIfAbsent(timeId,k -> new HashMap<>()).put(docId,number); map.computeIfAbsent(timeId,k -> new HashMap<>()).put(docId,number);
} }
@ -338,9 +341,9 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
var query = Query.select(ALL).from(TABLE_DOCUMENTS).where(COMPANY_ID,in(companyIds.toArray())); var query = Query.select(ALL).from(TABLE_DOCUMENTS).where(COMPANY_ID,in(companyIds.toArray()));
if (fulltext) { if (fulltext) {
for (var key : keys) query.where(format("CONCAT({0},\" \",{1},\" \",{2},\" \",{3},\" \",{4},\" \",{5},\" \",{6},\" \",{7},\" \",{8},\" \",{9})",NUMBER,FIELD_HEAD,FIELD_FOOTER,SENDER,FIELD_TAX_NUMBER,FIELD_BANK_ACCOUNT,FIELD_CUSTOMER,FIELD_CUSTOMER_NUMBER,FIELD_CUSTOMER_TAX_NUMBER,FIELD_CUSTOMER_EMAIL),like("%"+key+"%")); for (var key : keys) query.where(format("CONCAT({0},\" \",{1},\" \",{2},\" \",{3},\" \",{4},\" \",{5},\" \",{6},\" \",{7},\" \",{8},\" \",{9})",NUMBER,HEAD,FOOTER,SENDER,TAX_NUMBER,BANK_ACCOUNT,CUSTOMER,CUSTOMER_NUMBER,CUSTOMER_TAX_NUMBER,CUSTOMER_EMAIL),like("%"+key+"%"));
} else { } else {
for (var key : keys) query.where(format("CONCAT({0},\" \",{1},\" \",{2},\" \",{3},\" \",{4})",NUMBER,FIELD_HEAD,FIELD_FOOTER,SENDER,FIELD_CUSTOMER),like("%"+key+"%")); for (var key : keys) query.where(format("CONCAT({0},\" \",{1},\" \",{2},\" \",{3},\" \",{4})",NUMBER,HEAD,FOOTER,SENDER,CUSTOMER),like("%"+key+"%"));
} }
rs = query.exec(db); rs = query.exec(db);
var map = new HashMap<Long,Document>(); var map = new HashMap<Long,Document>();
@ -349,10 +352,10 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
if (fulltext){ if (fulltext){
var additionalDocIds = new HashSet<Long>(); var additionalDocIds = new HashSet<Long>();
query = select(FIELD_DOCUMENT_ID).from(TABLE_POSITIONS).leftJoin(FIELD_DOCUMENT_ID,TABLE_DOCUMENTS,ID).where(COMPANY_ID,in(companyIds.toArray())); query = select(DOCUMENT_ID).from(TABLE_POSITIONS).leftJoin(DOCUMENT_ID,TABLE_DOCUMENTS,ID).where(COMPANY_ID,in(companyIds.toArray()));
for (var key : keys) query.where(format("CONCAT({0},\" \",{1},\" \",{2},\" \",{3})",FIELD_ITEM_CODE,UNIT,TITLE,DESCRIPTION),like("%"+key+"%")); for (var key : keys) query.where(format("CONCAT({0},\" \",{1},\" \",{2},\" \",{3})",ITEM_CODE,UNIT,TITLE,DESCRIPTION),like("%"+key+"%"));
rs = query.exec(db); rs = query.exec(db);
while (rs.next()) additionalDocIds.add(rs.getLong(FIELD_DOCUMENT_ID)); while (rs.next()) additionalDocIds.add(rs.getLong(DOCUMENT_ID));
rs.close(); rs.close();
additionalDocIds.removeAll(map.keySet()); additionalDocIds.removeAll(map.keySet());
@ -363,9 +366,9 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
rs.close(); rs.close();
} }
rs = Query.select(ALL).from(TABLE_POSITIONS).where(FIELD_DOCUMENT_ID,in(map.keySet().toArray())).exec(db); rs = Query.select(ALL).from(TABLE_POSITIONS).where(DOCUMENT_ID,in(map.keySet().toArray())).exec(db);
while (rs.next()){ while (rs.next()){
var docId = rs.getLong(FIELD_DOCUMENT_ID); var docId = rs.getLong(DOCUMENT_ID);
var position = toPosition(rs); var position = toPosition(rs);
map.get(docId).positions().add(position); map.get(docId).positions().add(position);
position.clean(); position.clean();
@ -386,14 +389,14 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
while (rs.next()) types.put(rs.getInt(ID),toType(rs)); while (rs.next()) types.put(rs.getInt(ID),toType(rs));
rs.close(); rs.close();
rs = Query.select(ALL).from(TABLE_DOCUMENTS).where(FIELD_COMPANY_ID,equal(companyId)).exec(db); rs = Query.select(ALL).from(TABLE_DOCUMENTS).where(COMPANY_ID,equal(companyId)).exec(db);
var map = new HashMap<Long,Document>(); var map = new HashMap<Long,Document>();
while (rs.next()) map.put(rs.getLong(ID),toDoc(rs,types)); while (rs.next()) map.put(rs.getLong(ID),toDoc(rs,types));
rs.close(); rs.close();
rs = Query.select(ALL).from(TABLE_POSITIONS).where(FIELD_DOCUMENT_ID,in(map.keySet().toArray())).exec(db); rs = Query.select(ALL).from(TABLE_POSITIONS).where(DOCUMENT_ID,in(map.keySet().toArray())).exec(db);
while (rs.next()){ while (rs.next()){
var docId = rs.getLong(FIELD_DOCUMENT_ID); var docId = rs.getLong(DOCUMENT_ID);
var position = toPosition(rs); var position = toPosition(rs);
map.get(docId).positions().add(position); map.get(docId).positions().add(position);
position.clean(); position.clean();
@ -428,14 +431,14 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
while (rs.next()) types.put(rs.getInt(ID),toType(rs)); while (rs.next()) types.put(rs.getInt(ID),toType(rs));
rs.close(); rs.close();
rs = Query.select(ALL).from(TABLE_DOCUMENTS).leftJoin(FIELD_TEMPLATE_ID,TABLE_TEMPLATES, ID).where(TABLE_DOCUMENTS+"."+ ID,equal(docId)).exec(db); rs = Query.select(ALL).from(TABLE_DOCUMENTS).leftJoin(TEMPLATE_ID,TABLE_TEMPLATES, ID).where(TABLE_DOCUMENTS+"."+ ID,equal(docId)).exec(db);
Document doc = null; Document doc = null;
while (rs.next()) doc = toDoc(rs,types); while (rs.next()) doc = toDoc(rs,types);
rs.close(); rs.close();
if (doc != null) { if (doc != null) {
var positions = doc.positions(); var positions = doc.positions();
rs = Query.select(ALL).from(TABLE_POSITIONS).where(FIELD_DOCUMENT_ID, equal(docId)).exec(db); rs = Query.select(ALL).from(TABLE_POSITIONS).where(DOCUMENT_ID, equal(docId)).exec(db);
while (rs.next()) { while (rs.next()) {
var position = toPosition(rs); var position = toPosition(rs);
positions.add(position); positions.add(position);
@ -456,7 +459,7 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
var settings = getCompanySettings(companyId,type); var settings = getCompanySettings(companyId,type);
var numbers = new HashSet<String>(); var numbers = new HashSet<String>();
var rs = select(NUMBER).from(TABLE_DOCUMENTS).where(FIELD_COMPANY_ID,equal(companyId)).exec(db); var rs = select(NUMBER).from(TABLE_DOCUMENTS).where(COMPANY_ID,equal(companyId)).exec(db);
while (rs.next()) numbers.add(rs.getString(NUMBER)); while (rs.next()) numbers.add(rs.getString(NUMBER));
rs.close(); rs.close();
@ -475,7 +478,7 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
var typeId = doc.type().id(); var typeId = doc.type().id();
var customerId = doc.customer().id(); var customerId = doc.customer().id();
try{ try{
replaceInto(TABLE_CUSTOMER_SETTINGS, FIELD_COMPANY_ID, FIELD_DOC_TYPE_ID, FIELD_CUSTOMER_NUMBER, FIELD_DEFAULT_HEADER, FIELD_DEFAULT_FOOTER, FIELD_DEFAULT_MAIL) replaceInto(TABLE_CUSTOMER_SETTINGS, COMPANY_ID, DOC_TYPE_ID, CUSTOMER_NUMBER, DEFAULT_HEADER, DEFAULT_FOOTER, DEFAULT_MAIL)
.values(companyId, typeId, customerId, settings.header(), settings.footer(), settings.mailText()) .values(companyId, typeId, customerId, settings.header(), settings.footer(), settings.mailText())
.execute(db); .execute(db);
return settings; return settings;
@ -490,7 +493,7 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
var timestamp = doc.date().atStartOfDay(UTC).toInstant().getEpochSecond(); var timestamp = doc.date().atStartOfDay(UTC).toInstant().getEpochSecond();
var sender = doc.sender(); var sender = doc.sender();
var custom = doc.customer(); var custom = doc.customer();
var stmt = insertInto(TABLE_DOCUMENTS,FIELD_TYPE_ID,FIELD_COMPANY_ID, DATE, FIELD_DELIVERY_DATE,FIELD_FOOTER,FIELD_HEAD, NUMBER, STATE, SENDER,FIELD_TAX_NUMBER,FIELD_BANK_ACCOUNT,FIELD_COURT,FIELD_CUSTOMER,FIELD_CUSTOMER_EMAIL,FIELD_CUSTOMER_NUMBER,FIELD_CUSTOMER_TAX_NUMBER,FIELD_TEMPLATE_ID,FIELD_CURRENCY) var stmt = insertInto(TABLE_DOCUMENTS,TYPE_ID,COMPANY_ID, DATE, DELIVERY_DATE,FOOTER,HEAD, NUMBER, STATE, SENDER,TAX_NUMBER,BANK_ACCOUNT,COURT,CUSTOMER,CUSTOMER_EMAIL,CUSTOMER_NUMBER,CUSTOMER_TAX_NUMBER,TEMPLATE_ID,CURRENCY)
.values(doc.type().id(),doc.companyId(),timestamp,doc.delivery(),doc.footer(),doc.head(),doc.number(),doc.state().code(),sender.name(),sender.taxNumber(),sender.bankAccount(),sender.court(),custom.name(),custom.email(),custom.id(),custom.taxNumber(),doc.template().id(),doc.currency()) .values(doc.type().id(),doc.companyId(),timestamp,doc.delivery(),doc.footer(),doc.head(),doc.number(),doc.state().code(),sender.name(),sender.taxNumber(),sender.bankAccount(),sender.court(),custom.name(),custom.email(),custom.id(),custom.taxNumber(),doc.template().id(),doc.currency())
.execute(db); .execute(db);
var rs = stmt.getGeneratedKeys(); var rs = stmt.getGeneratedKeys();
@ -513,7 +516,7 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
var sender = doc.sender(); var sender = doc.sender();
var custom = doc.customer(); var custom = doc.customer();
update(TABLE_DOCUMENTS) update(TABLE_DOCUMENTS)
.set(DATE, FIELD_DELIVERY_DATE,FIELD_FOOTER,FIELD_HEAD, NUMBER, STATE, SENDER,FIELD_TAX_NUMBER,FIELD_BANK_ACCOUNT,FIELD_COURT,FIELD_CUSTOMER,FIELD_CUSTOMER_EMAIL,FIELD_CUSTOMER_NUMBER,FIELD_CUSTOMER_TAX_NUMBER,FIELD_TEMPLATE_ID) .set(DATE, DELIVERY_DATE,FOOTER,HEAD, NUMBER, STATE, SENDER,TAX_NUMBER,BANK_ACCOUNT,COURT,CUSTOMER,CUSTOMER_EMAIL,CUSTOMER_NUMBER,CUSTOMER_TAX_NUMBER,TEMPLATE_ID)
.where(ID,equal(doc.id())) .where(ID,equal(doc.id()))
.prepare(db) .prepare(db)
.apply(timestamp,doc.delivery(),doc.footer(),doc.head(),doc.number(),doc.state().code(),sender.name(),sender.taxNumber(),sender.bankAccount(),sender.court(),custom.name(),custom.email(),custom.id(),custom.taxNumber(),doc.template().id()) .apply(timestamp,doc.delivery(),doc.footer(),doc.head(),doc.number(),doc.state().code(),sender.name(),sender.taxNumber(),sender.bankAccount(),sender.court(),custom.name(),custom.email(),custom.id(),custom.taxNumber(),doc.template().id())
@ -530,7 +533,7 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
var pos = entry.getValue(); var pos = entry.getValue();
if (pos.docId() != doc.id()) pos.setDocId(doc.id()); if (pos.docId() != doc.id()) pos.setDocId(doc.id());
if (pos.isNew()){ if (pos.isNew()){
insertInto(TABLE_POSITIONS,FIELD_DOCUMENT_ID,FIELD_POS, FIELD_ITEM_CODE,FIELD_AMOUNT, DESCRIPTION, TITLE,FIELD_UNIT,FIELD_PRICE,FIELD_TAX,FIELD_TIME_ID, OPTIONAL) insertInto(TABLE_POSITIONS,DOCUMENT_ID,POS, ITEM_CODE,AMOUNT, DESCRIPTION, TITLE,UNIT,PRICE,TAX,TIME_ID, OPTIONAL)
.values(pos.docId(),pos.num(),pos.itemCode(),pos.amount(),pos.description(),pos.title(),pos.unit(),pos.unitPrice(),pos.tax(),pos.timeId(),pos.optional()) .values(pos.docId(),pos.num(),pos.itemCode(),pos.amount(),pos.description(),pos.title(),pos.unit(),pos.unitPrice(),pos.tax(),pos.timeId(),pos.optional())
.execute(db) .execute(db)
.close(); .close();
@ -538,12 +541,12 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
} }
if (pos.isDirty()){ if (pos.isDirty()){
update(TABLE_POSITIONS) update(TABLE_POSITIONS)
.set(FIELD_ITEM_CODE,FIELD_AMOUNT, DESCRIPTION, TITLE,FIELD_UNIT,FIELD_PRICE,FIELD_TAX,FIELD_TIME_ID, OPTIONAL) .set(ITEM_CODE,AMOUNT, DESCRIPTION, TITLE,UNIT,PRICE,TAX,TIME_ID, OPTIONAL)
.where(FIELD_DOCUMENT_ID,equal(doc.id())) .where(DOCUMENT_ID,equal(doc.id()))
.where(FIELD_POS,equal(pos.num())).prepare(db) .where(POS,equal(pos.num())).prepare(db)
.apply(pos.itemCode(),pos.amount(),pos.description(),pos.title(),pos.unit(),pos.unitPrice(),pos.tax(),pos.timeId(),pos.optional()) .apply(pos.itemCode(),pos.amount(),pos.description(),pos.title(),pos.unit(),pos.unitPrice(),pos.tax(),pos.timeId(),pos.optional())
.close(); .close();
if (pos.isDirty(FIELD_UNIT_PRICE)) saveCustomerPrice(doc.companyId(),doc.customer().id(),pos.itemCode(),pos.unitPrice()); if (pos.isDirty(UNIT_PRICE)) saveCustomerPrice(doc.companyId(),doc.customer().id(),pos.itemCode(),pos.unitPrice());
pos.clean(); pos.clean();
} }
@ -558,7 +561,7 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
public CustomerSettings save(long companyId, Type docType, String customerId, CustomerSettings settings) throws UmbrellaException { public CustomerSettings save(long companyId, Type docType, String customerId, CustomerSettings settings) throws UmbrellaException {
if (!settings.isDirty()) return settings; if (!settings.isDirty()) return settings;
try { try {
replaceInto(TABLE_CUSTOMER_SETTINGS,FIELD_COMPANY_ID,FIELD_DOC_TYPE_ID,FIELD_CUSTOMER_NUMBER,FIELD_DEFAULT_HEADER,FIELD_DEFAULT_FOOTER,FIELD_DEFAULT_MAIL) replaceInto(TABLE_CUSTOMER_SETTINGS,COMPANY_ID,DOC_TYPE_ID,CUSTOMER_NUMBER,DEFAULT_HEADER,DEFAULT_FOOTER,DEFAULT_MAIL)
.values(companyId,docType.id(),customerId,settings.header(),settings.footer(),settings.mailText()) .values(companyId,docType.id(),customerId,settings.header(),settings.footer(),settings.mailText())
.execute(db) .execute(db)
.close(); .close();
@ -570,16 +573,16 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
private void saveCustomerPrice(long company, String customer, String item, long price) { private void saveCustomerPrice(long company, String customer, String item, long price) {
try { try {
var rs = select(FIELD_PRICE).from(TABLE_PRICES).where(FIELD_COMPANY_ID,equal(company)).where(FIELD_CUSTOMER_NUMBER,equal(customer)).where(FIELD_ITEM_CODE,equal(item)).exec(db); var rs = select(PRICE).from(TABLE_PRICES).where(COMPANY_ID,equal(company)).where(CUSTOMER_NUMBER,equal(customer)).where(ITEM_CODE,equal(item)).exec(db);
Long oldPrice = null; Long oldPrice = null;
if (rs.next()) oldPrice = rs.getLong(FIELD_PRICE); if (rs.next()) oldPrice = rs.getLong(PRICE);
rs.close(); rs.close();
if (oldPrice == null) { if (oldPrice == null) {
insertInto(TABLE_PRICES, FIELD_COMPANY_ID, FIELD_CUSTOMER_NUMBER, FIELD_ITEM_CODE, FIELD_PRICE).values(company, customer, item, price).execute(db).close(); insertInto(TABLE_PRICES, COMPANY_ID, CUSTOMER_NUMBER, ITEM_CODE, PRICE).values(company, customer, item, price).execute(db).close();
} else { } else {
update(TABLE_PRICES).where(FIELD_COMPANY_ID,equal(company)).where(FIELD_CUSTOMER_NUMBER,equal(customer)).where(FIELD_ITEM_CODE,equal(item)) update(TABLE_PRICES).where(COMPANY_ID,equal(company)).where(CUSTOMER_NUMBER,equal(customer)).where(ITEM_CODE,equal(item))
.set(FIELD_PRICE).prepare(db).apply(price).close(); .set(PRICE).prepare(db).apply(price).close();
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -590,8 +593,8 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
public void step(CompanySettings settings) { public void step(CompanySettings settings) {
try { try {
update(TABLE_COMPANY_SETTINGS) update(TABLE_COMPANY_SETTINGS)
.set(FIELD_TYPE_NUMBER) .set(TYPE_NUMBER)
.where(FIELD_COMPANY_ID,equal(settings.companyId())).where(FIELD_DOC_TYPE_ID,equal(settings.typeId())) .where(COMPANY_ID,equal(settings.companyId())).where(DOC_TYPE_ID,equal(settings.typeId()))
.prepare(db) .prepare(db)
.apply(settings.typeNumber()+1) .apply(settings.typeNumber()+1)
.close(); .close();
@ -604,9 +607,9 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
public Pair<Integer> switchPositions(long docId, Pair<Integer> pair) throws UmbrellaException { public Pair<Integer> switchPositions(long docId, Pair<Integer> pair) throws UmbrellaException {
try { try {
db.setAutoCommit(false); db.setAutoCommit(false);
update(TABLE_POSITIONS).set(FIELD_POS).where(FIELD_DOCUMENT_ID,equal(docId)).where(FIELD_POS,equal(pair.left())).prepare(db).apply(-pair.right()).close(); update(TABLE_POSITIONS).set(POS).where(DOCUMENT_ID,equal(docId)).where(POS,equal(pair.left())).prepare(db).apply(-pair.right()).close();
update(TABLE_POSITIONS).set(FIELD_POS).where(FIELD_DOCUMENT_ID,equal(docId)).where(FIELD_POS,equal(pair.right())).prepare(db).apply(pair.left()).close(); update(TABLE_POSITIONS).set(POS).where(DOCUMENT_ID,equal(docId)).where(POS,equal(pair.right())).prepare(db).apply(pair.left()).close();
update(TABLE_POSITIONS).set(FIELD_POS).where(FIELD_DOCUMENT_ID,equal(docId)).where(FIELD_POS,equal(-pair.right())).prepare(db).apply(pair.right()).close(); update(TABLE_POSITIONS).set(POS).where(DOCUMENT_ID,equal(docId)).where(POS,equal(-pair.right())).prepare(db).apply(pair.right()).close();
db.setAutoCommit(true); db.setAutoCommit(true);
} catch (SQLException e) { } catch (SQLException e) {
LOG.log(ERROR,"Failed to switch positions {0} and {1} of document {2}",pair.left(),pair.right(),docId); LOG.log(ERROR,"Failed to switch positions {0} and {1} of document {2}",pair.left(),pair.right(),docId);
@ -617,26 +620,26 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
private Document toDoc(ResultSet rs, HashMap<Integer, Type> types) throws SQLException { private Document toDoc(ResultSet rs, HashMap<Integer, Type> types) throws SQLException {
var id = rs.getLong(ID); var id = rs.getLong(ID);
var typeId = rs.getInt(FIELD_TYPE_ID); var typeId = rs.getInt(TYPE_ID);
var type = types.get(typeId); var type = types.get(typeId);
var company = rs.getLong(FIELD_COMPANY_ID); var company = rs.getLong(COMPANY_ID);
var number = rs.getString(NUMBER); var number = rs.getString(NUMBER);
var timestamp = rs.getLong(DATE); var timestamp = rs.getLong(DATE);
var date = timestamp > 0 ? Instant.ofEpochSecond(timestamp).atOffset(UTC).toLocalDate() : null; var date = timestamp > 0 ? Instant.ofEpochSecond(timestamp).atOffset(UTC).toLocalDate() : null;
var state = rs.getInt(STATE); var state = rs.getInt(STATE);
var delivery = rs.getString(FIELD_DELIVERY_DATE); var delivery = rs.getString(DELIVERY_DATE);
var head = rs.getString(FIELD_HEAD); var head = rs.getString(HEAD);
var footer = rs.getString(FIELD_FOOTER); var footer = rs.getString(FOOTER);
var currency = rs.getString(FIELD_CURRENCY); var currency = rs.getString(CURRENCY);
var senderName = rs.getString(SENDER); var senderName = rs.getString(SENDER);
var taxNumber = rs.getString(FIELD_TAX_NUMBER); var taxNumber = rs.getString(TAX_NUMBER);
var bankAccount = rs.getString(FIELD_BANK_ACCOUNT); var bankAccount = rs.getString(BANK_ACCOUNT);
var court = rs.getString(FIELD_COURT); var court = rs.getString(COURT);
var customerName = rs.getString(FIELD_CUSTOMER); var customerName = rs.getString(CUSTOMER);
var customerId = rs.getString(FIELD_CUSTOMER_NUMBER); var customerId = rs.getString(CUSTOMER_NUMBER);
var customerTaxNumber = rs.getString(FIELD_CUSTOMER_TAX_NUMBER); var customerTaxNumber = rs.getString(CUSTOMER_TAX_NUMBER);
var customerEmail = rs.getString(FIELD_CUSTOMER_EMAIL); var customerEmail = rs.getString(CUSTOMER_EMAIL);
var customer = new Customer(customerId, customerName, customerEmail, customerTaxNumber,FALLBACK_LANG); var customer = new Customer(customerId, customerName, customerEmail, customerTaxNumber,FALLBACK_LANG);
var sender = new Sender(senderName,bankAccount,taxNumber,court); var sender = new Sender(senderName,bankAccount,taxNumber,court);
var template = toTemplate(rs); var template = toTemplate(rs);
@ -645,8 +648,8 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
private Template toTemplate(ResultSet rs) throws SQLException { private Template toTemplate(ResultSet rs) throws SQLException {
try { try {
var id = rs.getLong(FIELD_TEMPLATE_ID); var id = rs.getLong(TEMPLATE_ID);
var company = rs.getLong(FIELD_COMPANY_ID); var company = rs.getLong(COMPANY_ID);
var name = rs.getString(NAME); var name = rs.getString(NAME);
var data = rs.getBytes(TEMPLATE); var data = rs.getBytes(TEMPLATE);
return new Template(id,company,name,data); return new Template(id,company,name,data);
@ -656,20 +659,20 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
} }
private Position toPosition(ResultSet rs) throws SQLException { private Position toPosition(ResultSet rs) throws SQLException {
var num = rs.getInt(FIELD_POS); var num = rs.getInt(POS);
var itemCode = rs.getString(FIELD_ITEM_CODE); var itemCode = rs.getString(ITEM_CODE);
var amount = rs.getDouble(FIELD_AMOUNT); var amount = rs.getDouble(AMOUNT);
var unit = rs.getString(FIELD_UNIT); var unit = rs.getString(UNIT);
var title = rs.getString(TITLE); var title = rs.getString(TITLE);
var description = rs.getString(DESCRIPTION); var description = rs.getString(DESCRIPTION);
var unitPrice = rs.getLong(FIELD_PRICE); var unitPrice = rs.getLong(PRICE);
var tax = rs.getInt(FIELD_TAX); var tax = rs.getInt(TAX);
var timeId = rs.getLong(FIELD_TIME_ID); var timeId = rs.getLong(TIME_ID);
var optional = rs.getBoolean(OPTIONAL); var optional = rs.getBoolean(OPTIONAL);
return new Position(num,itemCode,amount,unit,title,description,unitPrice,tax,timeId,optional); return new Position(num,itemCode,amount,unit,title,description,unitPrice,tax,timeId,optional);
} }
private Type toType(ResultSet rs) throws SQLException { private Type toType(ResultSet rs) throws SQLException {
return new Type(rs.getInt(ID),rs.getInt(FIELD_NEXT_TYPE),rs.getString(NAME)); return new Type(rs.getInt(ID),rs.getInt(NEXT_TYPE),rs.getString(NAME));
} }
} }

4
documents/src/main/java/de/srsoftware/umbrella/documents/TemplateDoc.java

@ -3,8 +3,8 @@ package de.srsoftware.umbrella.documents;
import static de.srsoftware.tools.MimeType.*; import static de.srsoftware.tools.MimeType.*;
import static de.srsoftware.umbrella.core.Constants.ERROR_MISSING_FIELD; import static de.srsoftware.umbrella.core.Constants.ERROR_MISSING_FIELD;
import static de.srsoftware.umbrella.core.Constants.FIELD_PRICE_FORMAT;
import static de.srsoftware.umbrella.core.Constants.USER; import static de.srsoftware.umbrella.core.Constants.USER;
import static de.srsoftware.umbrella.core.Field.PRICE_FORMAT;
import static java.lang.System.Logger.Level.TRACE; import static java.lang.System.Logger.Level.TRACE;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static java.text.MessageFormat.format; import static java.text.MessageFormat.format;
@ -55,7 +55,7 @@ public abstract class TemplateDoc implements Document {
@Override @Override
public RenderResult render(Map<String, Object> data) { public RenderResult render(Map<String, Object> data) {
data = new HashMap<>(data); data = new HashMap<>(data);
if (!(data.get(FIELD_PRICE_FORMAT) instanceof PriceFormat price)) return RenderError.of(ERROR_MISSING_FIELD,FIELD_PRICE_FORMAT); if (!(data.get(PRICE_FORMAT) instanceof PriceFormat price)) return RenderError.of(ERROR_MISSING_FIELD,PRICE_FORMAT);
if (data.get(USER) instanceof UmbrellaUser user) data.put(USER,user.toMap()); if (data.get(USER) instanceof UmbrellaUser user) data.put(USER,user.toMap());
var precursor = source().render(data); var precursor = source().render(data);
if (precursor instanceof Content content){ if (precursor instanceof Content content){

12
documents/src/main/java/de/srsoftware/umbrella/documents/model/CompanySettings.java

@ -3,6 +3,8 @@ package de.srsoftware.umbrella.documents.model;
import static de.srsoftware.tools.Optionals.emptyIfNull; import static de.srsoftware.tools.Optionals.emptyIfNull;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Field.*;
import static de.srsoftware.umbrella.core.Field.COMPANY_ID;
import static de.srsoftware.umbrella.documents.Constants.*; import static de.srsoftware.umbrella.documents.Constants.*;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -16,11 +18,11 @@ public record CompanySettings(long companyId, long typeId, String typePrefix, St
} }
public static CompanySettings of(ResultSet rs) throws SQLException { public static CompanySettings of(ResultSet rs) throws SQLException {
var companyId = rs.getLong(FIELD_COMPANY_ID); var companyId = rs.getLong(COMPANY_ID);
var typeId = rs.getLong(FIELD_DOC_TYPE_ID); var typeId = rs.getLong(DOC_TYPE_ID);
var typePrefix = emptyIfNull(rs.getString(FIELD_TYPE_PREFIX)); var typePrefix = emptyIfNull(rs.getString(TYPE_PREFIX));
var typeSuffix = emptyIfNull(rs.getString(FIELD_TYPE_SUFFIX)); var typeSuffix = emptyIfNull(rs.getString(TYPE_SUFFIX));
var typeNumber = rs.getLong(FIELD_TYPE_NUMBER); var typeNumber = rs.getLong(TYPE_NUMBER);
return new CompanySettings(companyId,typeId,typePrefix,typeSuffix,typeNumber); return new CompanySettings(companyId,typeId,typePrefix,typeSuffix,typeNumber);
} }

13
documents/src/main/java/de/srsoftware/umbrella/documents/model/CustomerSettings.java

@ -3,6 +3,7 @@ package de.srsoftware.umbrella.documents.model;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Field.*;
import de.srsoftware.tools.Mappable; import de.srsoftware.tools.Mappable;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -47,24 +48,24 @@ public class CustomerSettings implements Mappable {
} }
public static CustomerSettings of(ResultSet rs) throws SQLException { public static CustomerSettings of(ResultSet rs) throws SQLException {
var header = rs.getString(FIELD_DEFAULT_HEADER); var header = rs.getString(DEFAULT_HEADER);
var footer = rs.getString(FIELD_DEFAULT_FOOTER); var footer = rs.getString(DEFAULT_FOOTER);
var mailText = rs.getString(FIELD_DEFAULT_MAIL); var mailText = rs.getString(DEFAULT_MAIL);
return new CustomerSettings(header,footer,mailText); return new CustomerSettings(header,footer,mailText);
} }
@Override @Override
public Map<String, Object> toMap() { public Map<String, Object> toMap() {
return Map.of(FIELD_FOOTER,footer,FIELD_HEAD,header,CONTENT,mailText); return Map.of(FOOTER,footer,HEAD,header,CONTENT,mailText);
} }
public CustomerSettings patch(JSONObject json) { public CustomerSettings patch(JSONObject json) {
for (var key : json.keySet()){ for (var key : json.keySet()){
var valid = true; var valid = true;
switch (key){ switch (key){
case FIELD_FOOTER: case FOOTER:
footer = json.getString(key); break; footer = json.getString(key); break;
case FIELD_HEAD: case HEAD:
header = json.getString(key); break; header = json.getString(key); break;
default: default:
valid = false; valid = false;

3
stock/src/main/java/de/srsoftware/umbrella/stock/StockModule.java

@ -5,6 +5,7 @@ import static de.srsoftware.tools.Optionals.is0;
import static de.srsoftware.tools.Optionals.nullIfEmpty; import static de.srsoftware.tools.Optionals.nullIfEmpty;
import static de.srsoftware.umbrella.core.ConnectionProvider.connect; import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Field.ITEM;
import static de.srsoftware.umbrella.core.ModuleRegistry.companyService; import static de.srsoftware.umbrella.core.ModuleRegistry.companyService;
import static de.srsoftware.umbrella.core.ModuleRegistry.userService; import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
@ -311,7 +312,7 @@ public class StockModule extends BaseHandler implements StockService {
private boolean postProperty(UmbrellaUser user, HttpExchange ex) throws IOException { private boolean postProperty(UmbrellaUser user, HttpExchange ex) throws IOException {
var json = json(ex); var json = json(ex);
if (!(json.get(FIELD_ITEM) instanceof JSONObject itemData)) throw missingFieldException(FIELD_ITEM); if (!(json.get(ITEM) instanceof JSONObject itemData)) throw missingFieldException(ITEM);
if (!(itemData.get(ID) instanceof Number itemId)) throw missingFieldException(ID); if (!(itemData.get(ID) instanceof Number itemId)) throw missingFieldException(ID);
if (!(json.get("add_prop") instanceof JSONObject propData)) throw missingFieldException("add_prop"); if (!(json.get("add_prop") instanceof JSONObject propData)) throw missingFieldException("add_prop");
if (!propData.has(VALUE)) throw missingFieldException(VALUE); if (!propData.has(VALUE)) throw missingFieldException(VALUE);

Loading…
Cancel
Save