preparing to render document

This commit is contained in:
2025-07-16 08:55:08 +02:00
parent b372ae45b3
commit 07ef168226
4 changed files with 83 additions and 17 deletions

View File

@@ -3,5 +3,11 @@ description = "Umbrella : Documents"
dependencies{
implementation(project(":company"))
implementation(project(":core"))
implementation("de.srsoftware:document.api:1.0.1")
implementation("de.srsoftware:document.file:1.0.0")
implementation("de.srsoftware:document.processor:1.0.2")
implementation("de.srsoftware:document.zugferd:1.0.3")
implementation("de.srsoftware:tools.mime:1.1.2")
}

View File

@@ -19,10 +19,12 @@ import static java.util.stream.Collectors.toMap;
import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.configuration.Configuration;
import de.srsoftware.document.api.DocumentRegistry;
import de.srsoftware.tools.Pair;
import de.srsoftware.tools.Path;
import de.srsoftware.tools.SessionToken;
import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.Tuple;
import de.srsoftware.umbrella.core.api.CompanyService;
import de.srsoftware.umbrella.core.api.UserService;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
@@ -35,12 +37,14 @@ import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.json.JSONArray;
import org.json.JSONObject;
public class DocumentApi extends BaseHandler {
private static final Predicate<de.srsoftware.document.api.Document> ZUGFERD_FILTER = document -> document.id().equals("Zugferd");
private final DocumentRegistry registry = new DocumentRegistry();
private final CompanyService companies;
private final Configuration config;
@@ -110,18 +114,25 @@ public class DocumentApi extends BaseHandler {
case STATES -> getDocStates(ex);
case null -> super.doGet(path,ex);
default -> {
try {
var docId = Long.parseLong(head);
yield getDocument(ex,docId,user.get());
} catch (NumberFormatException ignored) {}
yield super.doGet(path,ex);
var docId = Long.parseLong(head);
head = path.pop();
yield switch (head){
case null -> getDocument(ex,docId,user.get());
case PATH_PDF -> getRenderedDocument(ex,docId,user.get());
default -> super.doGet(path,ex);
};
}
};
} catch (NumberFormatException ignored) {
return super.doGet(path,ex);
} catch (UmbrellaException e) {
return send(ex,e);
}
}
@Override
public boolean doOptions(Path path, HttpExchange ex) throws IOException {
return sendEmptyResponse(HTTP_OK,addCors(ex));
@@ -197,18 +208,46 @@ public class DocumentApi extends BaseHandler {
return sendContent(ex,map);
}
private boolean getDocument(HttpExchange ex, long docId, UmbrellaUser user) throws IOException, UmbrellaException {
private Tuple<Document,Company> getDocument(long docId, UmbrellaUser user) throws UmbrellaException {
var doc = db.loadDoc(docId);
var companyId = doc.companyId();
var company = companies.get(companyId);
if (!companies.membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
return Tuple.of(doc,company);
}
private Document getDocumentWithCompanyData(long docId, UmbrellaUser user) throws UmbrellaException {
var tuple = getDocument(docId,user);
var company = tuple.b;
var sep = company.decimalSeparator();
var doc = tuple.a;
if (sep != null) doc.setDecimalSeparator(sep);
doc.setCompanyName(company.name());
return doc;
}
private boolean getDocument(HttpExchange ex, long docId, UmbrellaUser user) throws IOException, UmbrellaException {
var doc = getDocumentWithCompanyData(docId,user);
return sendContent(ex,doc.renderToMap());
}
private boolean getRenderedDocument(HttpExchange ex, long docId, UmbrellaUser user) throws IOException, UmbrellaException {
var document = getDocumentWithCompanyData(docId,user);
var template = document.template().name();
var templateName = template+".html.pdf";
var type = document.type().name();
var zugferd = "invoice".equals(type);
Predicate<de.srsoftware.document.api.Document> filter = zugferd ? ZUGFERD_FILTER : doc -> doc.name().equals(templateName);
var optDoc = registry.documents()
.filter(filter)
.findAny();
if (optDoc.isEmpty()) throw new UmbrellaException(404,"Cannot render {0} {1}: Missing template \"{2}\"",type,document.number(),template);
return sendContent(ex,document.renderToMap());
}
private JSONArray getLegacyContacts(HttpExchange ex, UmbrellaUser umbrellaUser, Token token) throws IOException, UmbrellaException {
var location = config.get("umbrella.modules.contact.baseUrl").map(s -> s+"/json").orElseThrow(() -> new UmbrellaException(500,"umbrella.modules.contact.baseUrl not configured!"));
var resp = request(location, token.asMap(),MIME_FORM_URL,null);
@@ -234,9 +273,7 @@ public class DocumentApi extends BaseHandler {
}
private boolean patchDocument(long docId, UmbrellaUser user, HttpExchange ex) throws UmbrellaException, IOException {
var doc = db.loadDoc(docId);
var companyId = doc.companyId();
if (!companies.membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",doc.companyId());
var doc = getDocument(docId,user).a;
doc.patch(json(ex));
db.save(doc);
return ok(ex);
@@ -247,9 +284,7 @@ public class DocumentApi extends BaseHandler {
}
private boolean patchDocumentPosition(long docId, UmbrellaUser user, HttpExchange ex) throws UmbrellaException, IOException {
var doc = db.loadDoc(docId);
var companyId = doc.companyId();
if (!companies.membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",doc.companyId());
var doc = getDocument(docId,user).a;
if (doc.state() != NEW) throw forbidden("Document has already been send and is write-protected!");
var json = json(ex);
var step = json.has(MOVE) && json.get(MOVE) instanceof Number num ? num.intValue() : 0;
@@ -295,10 +330,7 @@ public class DocumentApi extends BaseHandler {
}
private boolean postDocumentPosition(long docId, HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException {
var doc = db.loadDoc(docId);
var companyId = doc.companyId();
var company = companies.get(companyId);
if (!companies.membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
var doc = getDocument(docId,user).a;
var json = json(ex);
if (!(json.has(FIELD_AMOUNT) && json.get(FIELD_AMOUNT) instanceof Number amount)) throw missingFieldException(FIELD_AMOUNT);