implemented storing of customer settings when sending document
This commit is contained in:
@@ -6,6 +6,7 @@ import static de.srsoftware.document.mustang.Constants.KEY_DATA;
|
||||
import static de.srsoftware.document.mustang.Constants.KEY_PDF;
|
||||
import static de.srsoftware.document.mustang.Constants.KEY_PRODUCER;
|
||||
import static de.srsoftware.document.mustang.Constants.KEY_TEMPLATE;
|
||||
import static de.srsoftware.document.zugferd.data.UnitCode.*;
|
||||
import static de.srsoftware.tools.MimeType.MIME_FORM_URL;
|
||||
import static de.srsoftware.tools.MimeType.MIME_PDF;
|
||||
import static de.srsoftware.tools.Optionals.isSet;
|
||||
@@ -15,8 +16,7 @@ import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.Paths.LIST;
|
||||
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_UNPROCESSABLE;
|
||||
import static de.srsoftware.umbrella.core.Util.request;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.forbidden;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.model.Document.State.NEW;
|
||||
import static de.srsoftware.umbrella.documents.model.Document.State.SENT;
|
||||
@@ -202,14 +202,7 @@ public class DocumentApi extends BaseHandler {
|
||||
case LIST -> listCompaniesDocuments(ex,user.get(),token.orElse(null));
|
||||
case TEMPLATES -> postTemplateList(ex,user.get());
|
||||
case null -> postDocument(ex,user.get());
|
||||
default -> {
|
||||
var docId = Long.parseLong(head);
|
||||
yield switch (path.pop()){
|
||||
case null -> postToDocument(ex,path,user.get(),docId);
|
||||
case PATH_SEND -> sendDocument(ex,path,user.get(),docId);
|
||||
default -> super.doPost(path,ex);
|
||||
};
|
||||
}
|
||||
default -> postToDocument(ex,path,user.get(),Long.parseLong(head));
|
||||
};
|
||||
} catch (NumberFormatException ignored) {
|
||||
return super.doPost(path,ex);
|
||||
@@ -225,6 +218,12 @@ public class DocumentApi extends BaseHandler {
|
||||
if (!(json.has(EMAIL) && json.get(EMAIL) instanceof String email)) throw missingFieldException(EMAIL);
|
||||
if (!(json.has(SUBJECT) && json.get(SUBJECT) instanceof String subject)) throw missingFieldException(SUBJECT);
|
||||
if (!(json.has(CONTENT) && json.get(CONTENT) instanceof String content)) throw missingFieldException(CONTENT);
|
||||
var settings = new CustomerSettings(doc.head(),doc.footer(),content);
|
||||
try {
|
||||
db.save(settings,doc);
|
||||
} catch (UmbrellaException e) {
|
||||
LOG.log(WARNING,e);
|
||||
}
|
||||
LOG.log(WARNING,"Updating settings of company-customer-document combination not implemented!");
|
||||
var attachment = new Attachment(doc.number()+".pdf",rendered.mimeType(),rendered.bytes());
|
||||
var message = new Message(user,subject,content,null,List.of(attachment));
|
||||
@@ -297,32 +296,32 @@ public class DocumentApi extends BaseHandler {
|
||||
return val -> message.format(new Object[]{val/100d});
|
||||
}
|
||||
|
||||
private DocumentData convert(Document document) throws Converter.ConversionError {
|
||||
private DocumentData convert(Document document) throws UmbrellaException {
|
||||
var currency = switch (document.currency()){
|
||||
case "€" -> Currency.EUR;
|
||||
case "$" -> Currency.USD;
|
||||
default -> throw new Converter.ConversionError("Unsupported currency: ",document.currency());
|
||||
default -> throw unprocessable("Unsupported currency: ",document.currency());
|
||||
};
|
||||
var typeCode = switch (document.type().name()){
|
||||
case "invoice" -> TypeCode.HANDELSRECHNUNG;
|
||||
default -> throw new Converter.ConversionError("Unsupported document type: ",document.type().name());
|
||||
default -> throw unprocessable("Unsupported document type: ",document.type().name());
|
||||
};
|
||||
var countryID = CountryCode.DE;
|
||||
LOG.log(WARNING,"countryID is hardcoded to be \"DE\", should be field of company!");
|
||||
var sender = document.sender();
|
||||
|
||||
var match = POST_CODE.matcher(sender.name());
|
||||
if (!match.find()) throw new Converter.ConversionError(ERROR_ADDRESS_MISSING, SENDER);
|
||||
if (!match.find()) throw unprocessable(ERROR_ADDRESS_MISSING, SENDER);
|
||||
var name = match.group(1).trim();
|
||||
var streetAddress = match.group(2).trim();
|
||||
var postCode = match.group(3);
|
||||
var city = match.group(4).trim();
|
||||
var taxNumber = sender.taxNumber();
|
||||
if (!taxNumber.startsWith("DE")) throw new Converter.ConversionError("Invalid sender tax number ({0})!",taxNumber);
|
||||
if (!taxNumber.startsWith("DE")) throw unprocessable("Invalid sender tax number ({0})!",taxNumber);
|
||||
var author = new Author(name,countryID,postCode,city,streetAddress,taxNumber);
|
||||
|
||||
match = POST_CODE.matcher(document.customer().name());
|
||||
if (!match.find()) throw new Converter.ConversionError(ERROR_ADDRESS_MISSING,FIELD_CUSTOMER);
|
||||
if (!match.find()) throw unprocessable(ERROR_ADDRESS_MISSING,FIELD_CUSTOMER);
|
||||
name = escapeHtmlEntities(match.group(1).trim());
|
||||
streetAddress = escapeHtmlEntities(match.group(2).trim());
|
||||
postCode = match.group(3);
|
||||
@@ -338,7 +337,7 @@ public class DocumentApi extends BaseHandler {
|
||||
try {
|
||||
deliveryDate = LocalDate.parse(document.delivery());
|
||||
} catch (RuntimeException ex) {
|
||||
throw new Converter.ConversionError("\"{0}\" is not a valid delivery date (cannot be parsed)!",document.delivery());
|
||||
throw unprocessable("\"{0}\" is not a valid delivery date (cannot be parsed)!",document.delivery());
|
||||
}
|
||||
var lineItems = new ArrayList<LineItem>();
|
||||
for (var entry : document.positions().entrySet()){
|
||||
@@ -346,11 +345,12 @@ public class DocumentApi extends BaseHandler {
|
||||
var pos = entry.getValue();
|
||||
|
||||
UnitCode unit = switch (pos.unit()){
|
||||
case "jährlich" -> UnitCode.per_year;
|
||||
case "pauschal" -> UnitCode.fixed;
|
||||
case "h", "Stunden" -> UnitCode.hours;
|
||||
case "Stück" -> UnitCode.pieces;
|
||||
default -> throw new Converter.ConversionError("No unit code defined for {0}",pos.unit());
|
||||
case "d" -> per_day;
|
||||
case "h", "Stunden" -> hours;
|
||||
case "jährlich" -> per_year;
|
||||
case "pauschal" -> fixed;
|
||||
case "Stück" -> pieces;
|
||||
default -> throw unprocessable("No unit code defined for {0}",pos.unit());
|
||||
};
|
||||
var percent = pos.tax();
|
||||
var taxType = percent == 0 ? TaxType.Z : TaxType.S;
|
||||
@@ -384,7 +384,7 @@ public class DocumentApi extends BaseHandler {
|
||||
pdfData.put(USER,user);
|
||||
pdfData.put(FIELD_PRICE_FORMAT, priceFormat(document.currency(),user.language()));
|
||||
Map<String,Object> data = pdfData;
|
||||
if (zugferd) try { // create additional data
|
||||
if (zugferd) {// create additional data
|
||||
data = Map.of(
|
||||
KEY_XML,Map.of(
|
||||
KEY_PROFILE,"EN16931",
|
||||
@@ -396,10 +396,8 @@ public class DocumentApi extends BaseHandler {
|
||||
),
|
||||
KEY_PRODUCER,"SRSoftware Umbrella"
|
||||
);
|
||||
} catch (Converter.ConversionError e){
|
||||
throw new UmbrellaException(500,"Failed to convert data: {0}",e.getMessage()).causedBy(e);
|
||||
}
|
||||
var source = optDoc.get();
|
||||
var source = optDoc.get();
|
||||
var rendered = source.render(data);
|
||||
if (rendered instanceof RenderError err) throw new UmbrellaException(500,"Failed to render {0}: {1}",source.name(),err.toString());
|
||||
if (!(rendered instanceof Content content)) throw new UmbrellaException(500,"Unknown result type ({0}) returned from render process!",rendered.getClass().getSimpleName());
|
||||
@@ -409,8 +407,8 @@ public class DocumentApi extends BaseHandler {
|
||||
}
|
||||
private boolean getRenderedDocument(HttpExchange ex, long docId, UmbrellaUser user) throws IOException, UmbrellaException {
|
||||
var document = getDocumentWithCompanyData(docId,user);
|
||||
var content = renderDocument(document,user);
|
||||
var headers = ex.getResponseHeaders();
|
||||
var content = renderDocument(document,user);
|
||||
var headers = ex.getResponseHeaders();
|
||||
headers.add(CONTENT_TYPE, MIME_PDF);
|
||||
headers.add(CONTENT_DISPOSITION,"attachment; filename=\""+document.number()+".pdf\"");
|
||||
return sendContent(ex,content.bytes());
|
||||
@@ -418,7 +416,7 @@ public class DocumentApi extends BaseHandler {
|
||||
|
||||
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);
|
||||
var resp = request(location, token.asMap(),MIME_FORM_URL,null);
|
||||
if (!(resp instanceof String s && s.startsWith("["))) throw new UmbrellaException(500,"{0} did not return JSON Array!",location);
|
||||
return new JSONArray(s);
|
||||
}
|
||||
@@ -428,10 +426,10 @@ public class DocumentApi extends BaseHandler {
|
||||
var json = json(ex);
|
||||
if (!json.has(COMPANY)) throw missingFieldException(COMPANY);
|
||||
long companyId = json.getLong(COMPANY);
|
||||
var company = companies.get(companyId);
|
||||
var company = companies.get(companyId);
|
||||
if (!companies.membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company);
|
||||
var docs = db.listDocs(companyId);
|
||||
var map = new HashMap<Long,Object>();
|
||||
var map = new HashMap<Long,Object>();
|
||||
for (var entry : docs.entrySet()) map.put(entry.getKey(),entry.getValue().summary());
|
||||
return sendContent(ex,new JSONObject(map).toString(2));
|
||||
} catch (IOException e) {
|
||||
@@ -529,6 +527,7 @@ public class DocumentApi extends BaseHandler {
|
||||
var head = path.pop();
|
||||
return switch (head){
|
||||
case POSITION -> postDocumentPosition(docId,ex,user);
|
||||
case PATH_SEND -> sendDocument(ex,path,user,docId);
|
||||
case null, default -> super.doPost(path,ex);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ public interface DocumentDb {
|
||||
|
||||
Document save(Document document) throws UmbrellaException;
|
||||
|
||||
CustomerSettings save(CustomerSettings settings,Document doc) throws UmbrellaException;
|
||||
|
||||
CustomerSettings save(long companyId, Type docType, String customerId, CustomerSettings settings) throws UmbrellaException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,7 @@ 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.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_SERVER_ERROR;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.model.Document.DEFAULT_THOUSANDS_SEPARATOR;
|
||||
@@ -409,6 +410,21 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomerSettings save(CustomerSettings settings, Document doc) throws UmbrellaException {
|
||||
var companyId = doc.companyId();
|
||||
var typeId = doc.type().id();
|
||||
var customerId = doc.customer().id();
|
||||
try{
|
||||
replaceInto(TABLE_CUSTOMER_SETTINGS, FIELD_COMPANY_ID, FIELD_DOC_TYPE_ID, FIELD_CUSTOMER_NUMBER, FIELD_DEFAULT_HEADER, FIELD_DEFAULT_FOOTER, FIELD_DEFAULT_MAIL)
|
||||
.values(companyId, typeId, customerId, settings.header(), settings.footer(), settings.mailText())
|
||||
.execute(db);
|
||||
return settings;
|
||||
} catch (SQLException e){
|
||||
throw new UmbrellaException(HTTP_SERVER_ERROR,"Failed to update customer settings");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document save(Document doc) throws UmbrellaException {
|
||||
if (doc.isNew()) try {
|
||||
|
||||
Reference in New Issue
Block a user