From 147f169c7be9d52320b8073471da7d2dc84ae407 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Sun, 31 Aug 2025 14:56:10 +0200 Subject: [PATCH] implemented creation of successor document Signed-off-by: Stephan Richter --- .../umbrella/core/model/Document.java | 4 +-- .../umbrella/documents/Constants.java | 2 +- .../umbrella/documents/DocumentApi.java | 35 +++++++++++++++++++ .../umbrella/documents/SqliteDb.java | 1 + frontend/src/routes/document/View.svelte | 17 +++++++-- 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Document.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Document.java index 2150a44..8aceb29 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Document.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Document.java @@ -61,7 +61,7 @@ public final class Document implements Mappable { private final Set dirtyFields = new HashSet<>(); - public Document(long id, long companyId, String number, Type type, LocalDate date, State state, Template template, String delivery, String head, String footer, String currency, String thousandsSeparator, Sender sender, Customer customer, PositionList positions) { + public Document(long id, long companyId, String number, Type type, LocalDate date, State state, Template template, String delivery, String head, String footer, String currency, String decimalSeparator, Sender sender, Customer customer, PositionList positions) { this.id = id; this.companyId = companyId; this.number = number; @@ -76,7 +76,7 @@ public final class Document implements Mappable { this.sender = sender; this.customer = customer; this.positions = positions; - this.decimalSeparator = thousandsSeparator; + this.decimalSeparator = decimalSeparator; positions.setDocId(id); if (id == 0) dirtyFields.add(ID); } diff --git a/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java b/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java index 371f315..7fac14b 100644 --- a/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java +++ b/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java @@ -12,7 +12,7 @@ public class Constants { public static final Pattern POST_CODE = compile("(.*\\w+.*)\n(.*\\d+.*)\n(\\d{5}) (\\w+)",DOTALL); - + public static final String CLONE = "clone"; public static final String CONFIG_DATABASE = "umbrella.modules.document.database"; public static final String CONFIG_TEMPLATES = "umbrella.modules.document.templates"; public static final String CONTACTS = "contacts"; diff --git a/documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java b/documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java index 6f24e94..f4e2350 100644 --- a/documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java +++ b/documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java @@ -459,6 +459,40 @@ public class DocumentApi extends BaseHandler implements DocumentService { return send(ex,db.save(doc).positions()); } + private boolean postCloneDoc(long docId, HttpExchange ex, UmbrellaUser user) throws IOException { + Type docType = null; + try { + docType = db.getType(Integer.parseInt(body(ex))); + } catch (NumberFormatException nfe){ + throw UmbrellaException.invalidFieldException(BODY,"document type id"); + } + + Document doc = getDocument(docId, user).a; + + var companySettings = db.getCompanySettings(doc.companyId(),docType); + var nextNumber = companySettings.nextDocId(); + + Document clone = new Document( + 0, + doc.companyId(), + nextNumber, + docType, + LocalDate.now(), + NEW, + doc.template(), + doc.delivery(), + doc.head(), + doc.footer(), + doc.currency(), + doc.decimalSeparator(), + doc.sender(), + doc.customer(), + new PositionList() + ); + clone = db.save(clone); + doc.positions().values().forEach(clone.positions()::add); + return sendContent(ex,db.save(clone)); + } private boolean postDocument(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException { var json = json(ex); @@ -522,6 +556,7 @@ public class DocumentApi extends BaseHandler implements DocumentService { private boolean postToDocument(HttpExchange ex, Path path, UmbrellaUser user, long docId) throws IOException, UmbrellaException { var head = path.pop(); return switch (head){ + case CLONE -> postCloneDoc(docId,ex,user); case POSITION -> postDocumentPosition(docId,ex,user); case PATH_SEND -> sendDocument(ex,path,user,docId); case null, default -> super.doPost(path,ex); diff --git a/documents/src/main/java/de/srsoftware/umbrella/documents/SqliteDb.java b/documents/src/main/java/de/srsoftware/umbrella/documents/SqliteDb.java index 0821e9e..a41c8f4 100644 --- a/documents/src/main/java/de/srsoftware/umbrella/documents/SqliteDb.java +++ b/documents/src/main/java/de/srsoftware/umbrella/documents/SqliteDb.java @@ -469,6 +469,7 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255) if (doc.positions().isDirty()) try { for (var entry : doc.positions().entrySet()){ var pos = entry.getValue(); + if (pos.docId() != doc.id()) pos.setDocId(doc.id()); 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) .values(pos.docId(),pos.num(),pos.itemCode(),pos.amount(),pos.description(),pos.title(),pos.unit(),pos.unitPrice(),pos.tax(),pos.timeId(),pos.optional()) diff --git a/frontend/src/routes/document/View.svelte b/frontend/src/routes/document/View.svelte index e81a9f8..378e776 100644 --- a/frontend/src/routes/document/View.svelte +++ b/frontend/src/routes/document/View.svelte @@ -56,8 +56,21 @@ } } - function createSuccessorDoc(type){ - console.log(type); + async function createSuccessorDoc(type){ + const url = api(`document/${id}/clone`); + const res = await fetch(url,{ + credentials :'include', + method : 'POST', + body : type + }); + if (res.ok) { + error = null; + let json = await res.json(); + router.navigate(`/document/${json.id}/view`); + loadDoc(); + } else { + error = await res.text(); + } } async function loadDoc(){