Browse Source

implemented adding positions to document

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
feature/document
Stephan Richter 4 months ago
parent
commit
31916d83df
  1. 29
      documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java
  2. 15
      frontend/src/routes/document/PositionSelector.svelte
  3. 1
      frontend/src/routes/document/View.svelte
  4. 1
      translations/src/main/resources/de.json

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

@ -14,6 +14,7 @@ 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.DEBUG;
import static java.lang.System.Logger.Level.WARNING; import static java.lang.System.Logger.Level.WARNING;
import static java.net.HttpURLConnection.*; import static java.net.HttpURLConnection.*;
import static java.util.stream.Collectors.toMap;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.configuration.Configuration; import de.srsoftware.configuration.Configuration;
@ -30,6 +31,7 @@ import de.srsoftware.umbrella.documents.model.*;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -165,7 +167,7 @@ public class DocumentApi extends BaseHandler {
} }
private boolean getDocStates(HttpExchange ex) throws IOException { private boolean getDocStates(HttpExchange ex) throws IOException {
var map = Stream.of(Document.State.values()).collect(Collectors.toMap(Document.State::code, Document.State::name)); var map = Stream.of(Document.State.values()).collect(toMap(Document.State::code, Document.State::name));
return sendContent(ex,map); return sendContent(ex,map);
} }
@ -173,7 +175,7 @@ public class DocumentApi extends BaseHandler {
private boolean getDocTypes(HttpExchange ex) throws UmbrellaException, IOException { private boolean getDocTypes(HttpExchange ex) throws UmbrellaException, IOException {
var types = db.listTypes(); var types = db.listTypes();
var map = types.values().stream().collect(Collectors.toMap(Type::id, Type::name)); var map = types.values().stream().collect(toMap(Type::id, Type::name));
return sendContent(ex,map); return sendContent(ex,map);
} }
@ -255,8 +257,25 @@ public class DocumentApi extends BaseHandler {
return sendContent(ex,saved.toMap()); return sendContent(ex,saved.toMap());
} }
private boolean postDocumentPosition(long docId, HttpExchange ex, UmbrellaUser user) throws IOException { private boolean postDocumentPosition(long docId, HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException {
return notImplemented(ex,"postDocumentPosition",this); 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 json = json(ex);
if (!(json.has(FIELD_AMOUNT) && json.get(FIELD_AMOUNT) instanceof Number amount)) throw missingFieldException(FIELD_AMOUNT);
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(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);
var unitPrice =json.has(FIELD_UNIT_PRICE) && json.get(FIELD_UNIT_PRICE) instanceof Number num ? num : 0L;
int tax = json.has(FIELD_TAX) && json.get(FIELD_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;
var pos = new Position(doc.positions().size()+1,itemCode,amount.doubleValue(),unit,title,description,unitPrice.longValue(),tax,timeId,false);
doc.positions().add(pos);
return sendContent(ex,db.save(doc).positions().entrySet().stream().collect(toMap(Map.Entry::getKey,entry -> entry.getValue().renderToMap())));
} }
private boolean postTemplateList(HttpExchange ex, UmbrellaUser user) throws UmbrellaException, IOException { private boolean postTemplateList(HttpExchange ex, UmbrellaUser user) throws UmbrellaException, IOException {
@ -269,7 +288,7 @@ public class DocumentApi extends BaseHandler {
} }
private boolean postToDocument(HttpExchange ex, Path path, UmbrellaUser user, long docId) throws IOException { private boolean postToDocument(HttpExchange ex, Path path, UmbrellaUser user, long docId) throws IOException, UmbrellaException {
var head = path.pop(); var head = path.pop();
return switch (head){ return switch (head){
case POSITION -> postDocumentPosition(docId,ex,user); case POSITION -> postDocumentPosition(docId,ex,user);

15
frontend/src/routes/document/PositionSelector.svelte

@ -15,18 +15,18 @@
function estimateSelected(estimate){ function estimateSelected(estimate){
select({ select({
code:t('estimated_time'), item_code:t('estimated_time'),
subject:estimate.name, title:estimate.name,
description:estimate.description.source, description:estimate.description.source,
amount:estimate.estimated_time, amount:estimate.estimated_time,
unit:doc.currency+"/h" unit:t('document.hours')
}); });
} }
function itemSelected(item){ function itemSelected(item){
select({ select({
code:item.code, item_code:item.code,
subject:item.name, title:item.name,
description:item.description.source, description:item.description.source,
amount:1, amount:1,
unit:item.unit, unit:item.unit,
@ -37,11 +37,12 @@
function timeSelected(time){ function timeSelected(time){
select({ select({
code:t('document.timetrack'), item_code:t('document.timetrack'),
title:time.subject, title:time.subject,
description:time.description.source, description:time.description.source,
amount:time.duration, amount:time.duration,
unit:doc.currency+"/h" unit:t('document.hours'),
time_id:time.id
}); });
} }
</script> </script>

1
frontend/src/routes/document/View.svelte

@ -71,6 +71,7 @@
body:JSON.stringify(selected) body:JSON.stringify(selected)
}); });
if (resp.ok){ if (resp.ok){
doc.positions = await resp.json();
} else { } else {
error = await resp.text(); error = await resp.text();
} }

1
translations/src/main/resources/de.json

@ -23,6 +23,7 @@
"footer": "Fuß-Text", "footer": "Fuß-Text",
"gross_sum": "Brutto-Summe", "gross_sum": "Brutto-Summe",
"head": "Kopf-Text", "head": "Kopf-Text",
"hours": "Stunden",
"items": "Artikel", "items": "Artikel",
"list": "Dokumente", "list": "Dokumente",
"list_of": "Dokumente von {0}", "list_of": "Dokumente von {0}",

Loading…
Cancel
Save