implemented document creation
this required a major refactoring of the object model
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
description = "Umbrella : Documents"
|
||||
|
||||
dependencies{
|
||||
implementation(project(":company"))
|
||||
implementation(project(":core"))
|
||||
implementation("de.srsoftware:configuration.api:1.0.2")
|
||||
implementation("de.srsoftware:tools.jdbc:1.3.2")
|
||||
implementation("de.srsoftware:tools.mime:1.1.2")
|
||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||
implementation("de.srsoftware:tools.util:2.0.3")
|
||||
implementation("org.json:json:20240303")
|
||||
}
|
||||
@@ -14,26 +14,18 @@ public class Constants {
|
||||
public static final String CONFIG_DATABASE = "umbrella.modules.document.database";
|
||||
public static final String CONTACTS = "contacts";
|
||||
|
||||
public static final String CUSTOMER_NUMBER_PREFIX = "customer_number_prefix";
|
||||
public static final String DECIMAL_SEPARATOR = "decimal_separator";
|
||||
public static final String DECIMALS = "decimals";
|
||||
public static final String ERROR_ADDRESS_MISSING = "{0} address does not contain street address / post code / city";
|
||||
public static final String LAST_CUSTOMER_NUMBER = "last_customer_number";
|
||||
public static final String THOUSANDS_SEPARATOR = "thousands_separator";
|
||||
public static final String PROJECT_ID = "project_id";
|
||||
|
||||
|
||||
public static final String FIELD_AMOUNT = "amount";
|
||||
public static final String FIELD_BANK_ACCOUNT = "bank_account";
|
||||
public static final String FIELD_CODE = "code";
|
||||
public static final String FIELD_COMPANY = "company";
|
||||
public static final String FIELD_COMPANY_ID = "company_id";
|
||||
public static final String FIELD_COURT = "court";
|
||||
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_CURRENCY = "currency";
|
||||
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";
|
||||
@@ -53,7 +45,6 @@ public class Constants {
|
||||
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_PHONE = "phone";
|
||||
public static final String FIELD_POS = "pos";
|
||||
public static final String FIELD_POSITIONS = "positions";
|
||||
public static final String FIELD_PRICE = "single_price";
|
||||
@@ -61,7 +52,6 @@ public class Constants {
|
||||
public static final String FIELD_PROJECTS = "projects";
|
||||
public static final String FIELD_RECEIVER = "receiver";
|
||||
public static final String FIELD_START_TIME = "start_time";
|
||||
public static final String FIELD_TAX_NUMBER = "tax_number";
|
||||
public static final String FIELD_TEMPLATE_ID = "template_id";
|
||||
public static final String FIELD_TASKS = "tasks";
|
||||
public static final String FIELD_TAX = "tax";
|
||||
|
||||
@@ -3,25 +3,29 @@ package de.srsoftware.umbrella.documents;
|
||||
|
||||
import static de.srsoftware.tools.MimeType.MIME_FORM_URL;
|
||||
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
||||
import static de.srsoftware.umbrella.core.Constants.ERROR_MISSING_FIELD;
|
||||
import static de.srsoftware.umbrella.core.Constants.SENDER;
|
||||
import static de.srsoftware.umbrella.core.Paths.LIST;
|
||||
import static de.srsoftware.umbrella.core.Util.request;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.model.Document.State.NEW;
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
|
||||
import static java.net.HttpURLConnection.*;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.configuration.Configuration;
|
||||
import de.srsoftware.tools.Path;
|
||||
import de.srsoftware.tools.SessionToken;
|
||||
import de.srsoftware.umbrella.core.BaseHandler;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.api.CompanyService;
|
||||
import de.srsoftware.umbrella.core.api.UserService;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.Token;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
import de.srsoftware.umbrella.documents.model.Type;
|
||||
import de.srsoftware.umbrella.documents.model.*;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -31,15 +35,17 @@ import org.json.JSONObject;
|
||||
|
||||
public class DocumentApi extends BaseHandler {
|
||||
|
||||
private final UserService users;
|
||||
private final CompanyService companies;
|
||||
private final Configuration config;
|
||||
private final DocumentDb db;
|
||||
private final UserService users;
|
||||
|
||||
public DocumentApi(UserService userHelper, Configuration config) throws UmbrellaException {
|
||||
public DocumentApi(CompanyService companyService, Configuration config) throws UmbrellaException {
|
||||
this.config = config;
|
||||
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> new UmbrellaException(ERROR_MISSING_FIELD,CONFIG_DATABASE));
|
||||
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
|
||||
db = new SqliteDb(connect(dbFile));
|
||||
users = userHelper;
|
||||
companies = companyService;
|
||||
users = companyService.userService();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,7 +117,7 @@ public class DocumentApi extends BaseHandler {
|
||||
private boolean listDocuments(HttpExchange ex, UmbrellaUser user, Token token) throws UmbrellaException {
|
||||
try {
|
||||
var json = json(ex);
|
||||
if (!json.has(COMPANY)) throw new UmbrellaException(HTTP_BAD_REQUEST,ERROR_MISSING_FIELD, COMPANY);
|
||||
if (!json.has(COMPANY)) throw missingFieldException(COMPANY);
|
||||
long companyId = json.getLong(COMPANY);
|
||||
var companies = getLegacyCompanies(ex,user, token);
|
||||
var company = companies.get(companyId);
|
||||
@@ -126,17 +132,34 @@ public class DocumentApi extends BaseHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean postDocument(HttpExchange ex, UmbrellaUser umbrellaUser) throws IOException, UmbrellaException {
|
||||
private boolean postDocument(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException {
|
||||
var json = json(ex);
|
||||
if (!(json.has(COMPANY) && json.get(COMPANY) instanceof String cid) || cid.isBlank()) throw new UmbrellaException(HTTP_BAD_REQUEST,ERROR_MISSING_FIELD,COMPANY);
|
||||
long companyId;
|
||||
try {
|
||||
companyId = Long.parseLong(cid);
|
||||
} catch (NumberFormatException nfe){
|
||||
throw new UmbrellaException(HTTP_BAD_REQUEST,nfe.getMessage());
|
||||
}
|
||||
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);
|
||||
|
||||
var company = companies.get(companyId.longValue());
|
||||
var members = companies.getMembers(companyId.longValue());
|
||||
var match = false;
|
||||
for (var member : members) match |= user.equals(member);
|
||||
if (!match) return sendContent(ex,HTTP_FORBIDDEN,"You are mot a member of company "+companyId);
|
||||
|
||||
if (!json.has(FIELD_CUSTOMER) || !(json.get(FIELD_CUSTOMER) instanceof JSONObject customerData)) throw missingFieldException(FIELD_CUSTOMER);
|
||||
if (!json.has(FIELD_TYPE) || !(json.get(FIELD_TYPE) instanceof Number docTypeId)) throw missingFieldException(FIELD_TYPE);
|
||||
var type = db.getType(docTypeId.intValue());
|
||||
var customer = Customer.of(customerData);
|
||||
Template template = new Template(6,companyId.longValue(),"unknwon",null);
|
||||
String currency = company.currency();
|
||||
String sep = company.decimalSeparator();
|
||||
var settings = db.getCustomerSettings(companyId.longValue(),type,customer.id());
|
||||
var companySettings = db.getCompanySettings(companyId.longValue(),type);
|
||||
var nextNumber = companySettings.nextDocId();
|
||||
String lastHead = settings.header();
|
||||
String lastFooter = settings.footer();
|
||||
var sender = Sender.of(senderData);
|
||||
LOG.log(DEBUG,json.toString(2));
|
||||
return notImplemented(ex,"{0}.postDocument(…)",this);
|
||||
var doc = new Document(0,companyId.longValue(),nextNumber,type, LocalDate.now(), NEW,template,null,lastHead,lastFooter,currency,sep,sender,customer,new PositionList());
|
||||
var saved = db.save(doc);
|
||||
db.step(companySettings);
|
||||
return sendContent(ex,saved.toMap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package de.srsoftware.umbrella.documents;
|
||||
|
||||
import de.srsoftware.tools.Pair;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.documents.model.CompanySettings;
|
||||
import de.srsoftware.umbrella.documents.model.CustomerSettings;
|
||||
import de.srsoftware.umbrella.documents.model.Document;
|
||||
|
||||
@@ -6,6 +6,7 @@ import static de.srsoftware.tools.jdbc.Condition.equal;
|
||||
import static de.srsoftware.tools.jdbc.Condition.in;
|
||||
import static de.srsoftware.tools.jdbc.Query.*;
|
||||
import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL;
|
||||
import static de.srsoftware.umbrella.company.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.model.Document.DEFAULT_THOUSANDS_SEPARATOR;
|
||||
@@ -16,7 +17,7 @@ import static java.time.ZoneOffset.UTC;
|
||||
|
||||
import de.srsoftware.tools.Pair;
|
||||
import de.srsoftware.tools.jdbc.Query;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.documents.model.*;
|
||||
import de.srsoftware.umbrella.documents.model.Type;
|
||||
import java.sql.Connection;
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.documents.model;
|
||||
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public record Company(long id, String name, String address, String court, String taxId, String phone, String decimalSeparator, String thousandsSeparator, long lastCustomerNumber, int decimals, String customerNumberPrefix, String currency, String email, String bankAccount) {
|
||||
|
||||
public static Company of(JSONObject json) throws UmbrellaException {
|
||||
try {
|
||||
var id = json.getLong(ID);
|
||||
var name = json.getString(NAME);
|
||||
var address = json.getString(ADDRESS);
|
||||
var court = json.getString(FIELD_COURT);
|
||||
var taxId = json.getString(FIELD_TAX_NUMBER);
|
||||
var phone = json.getString(FIELD_PHONE);
|
||||
var decimalSep = json.getString(DECIMAL_SEPARATOR);
|
||||
var thousandsSep = json.getString(THOUSANDS_SEPARATOR);
|
||||
var lastCustomerNumber = json.getLong(LAST_CUSTOMER_NUMBER);
|
||||
var decimals = json.getInt(DECIMALS);
|
||||
var customerNumberPrefix = json.getString(CUSTOMER_NUMBER_PREFIX);
|
||||
var currency = json.getString(FIELD_CURRENCY);
|
||||
var email = json.getString(EMAIL);
|
||||
var bankAccount = json.getString(FIELD_BANK_ACCOUNT);
|
||||
return new Company(id,name,address,court,taxId,phone,decimalSep,thousandsSep,lastCustomerNumber,decimals,customerNumberPrefix,currency,email,bankAccount);
|
||||
} catch (JSONException e){
|
||||
throw new UmbrellaException(500,"Failed to convert JSON to Company!").causedBy(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,11 @@
|
||||
package de.srsoftware.umbrella.documents.model;
|
||||
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
import static de.srsoftware.umbrella.documents.Constants.FIELD_TAX_ID;
|
||||
|
||||
import de.srsoftware.tools.Mappable;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -63,10 +64,10 @@ public final class Customer implements Mappable {
|
||||
}
|
||||
|
||||
public static Customer of(JSONObject json) throws UmbrellaException {
|
||||
if (!json.has(ID) || !(json.get(ID) instanceof String id)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,ID);
|
||||
if (!json.has(NAME) || !(json.get(NAME) instanceof String name)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,NAME);
|
||||
if (!json.has(EMAIL) || !(json.get(EMAIL) instanceof String email)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,EMAIL);
|
||||
if (!json.has(FIELD_TAX_ID) || !(json.get(FIELD_TAX_ID) instanceof String taxId)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,FIELD_TAX_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(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);
|
||||
return new Customer(id,name,email,taxId);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
|
||||
import de.srsoftware.tools.Pair;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.documents.model;
|
||||
|
||||
import static de.srsoftware.umbrella.core.Constants.ERROR_MISSING_FIELD;
|
||||
import static de.srsoftware.umbrella.core.Constants.NAME;
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
|
||||
import de.srsoftware.tools.Mappable;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -65,10 +65,10 @@ public final class Sender implements Mappable {
|
||||
}
|
||||
|
||||
public static Sender of(JSONObject json) throws UmbrellaException {
|
||||
if (!json.has(NAME) || !(json.get(NAME) instanceof String name)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,NAME);
|
||||
if (!json.has(FIELD_BANK_ACCOUNT) || !(json.get(FIELD_BANK_ACCOUNT) instanceof String bankAccount)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,FIELD_BANK_ACCOUNT);
|
||||
if (!json.has(FIELD_TAX_ID) || !(json.get(FIELD_TAX_ID) instanceof String taxId)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,FIELD_TAX_ID);
|
||||
if (!json.has(FIELD_COURT) || !(json.get(FIELD_COURT) instanceof String court)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,FIELD_COURT);
|
||||
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(FIELD_TAX_ID) || !(json.get(FIELD_TAX_ID) instanceof String taxId)) throw missingFieldException(FIELD_TAX_ID);
|
||||
if (!json.has(FIELD_COURT) || !(json.get(FIELD_COURT) instanceof String court)) throw missingFieldException(FIELD_COURT);
|
||||
return new Sender(name,bankAccount,taxId,court);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user