Browse Source

working on document view/edit

feature/document
Stephan Richter 4 months ago
parent
commit
90c27382a1
  1. 1
      backend/build.gradle.kts
  2. 1
      company/build.gradle.kts
  3. 10
      company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java
  4. 18
      company/src/main/java/de/srsoftware/umbrella/company/SqliteDb.java
  5. 2
      company/src/main/java/de/srsoftware/umbrella/company/api/CompanyDb.java
  6. 8
      contact/build.gradle.kts
  7. 10
      contact/src/main/java/de/srsoftware/umbrella/contact/Constants.java
  8. 10
      contact/src/main/java/de/srsoftware/umbrella/contact/ContactDb.java
  9. 27
      contact/src/main/java/de/srsoftware/umbrella/contact/ContactModule.java
  10. 36
      contact/src/main/java/de/srsoftware/umbrella/contact/SqliteDb.java
  11. 1
      core/src/main/java/de/srsoftware/umbrella/core/Constants.java
  12. 11
      core/src/main/java/de/srsoftware/umbrella/core/api/CompanyService.java
  13. 11
      core/src/main/java/de/srsoftware/umbrella/core/api/ContactService.java
  14. 4
      core/src/main/java/de/srsoftware/umbrella/core/exceptions/UmbrellaException.java
  15. 31
      core/src/main/java/de/srsoftware/umbrella/core/model/Company.java
  16. 21
      core/src/main/java/de/srsoftware/umbrella/core/model/Contact.java
  17. 20
      documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java
  18. 4
      frontend/src/routes/document/Add.svelte
  19. 7
      frontend/src/routes/document/StateSelector.svelte
  20. 74
      frontend/src/routes/document/View.svelte
  21. 3
      settings.gradle.kts
  22. 5
      translations/src/main/resources/de.json

1
backend/build.gradle.kts

@ -12,6 +12,7 @@ application{
dependencies{ dependencies{
implementation(project(":company")) implementation(project(":company"))
implementation(project(":contact"))
implementation(project(":core")) implementation(project(":core"))
implementation(project(":documents")) implementation(project(":documents"))
implementation(project(":legacy")) implementation(project(":legacy"))

1
company/build.gradle.kts

@ -4,5 +4,6 @@ dependencies{
implementation(project(":core")) implementation(project(":core"))
implementation("de.srsoftware:configuration.api:1.0.2") implementation("de.srsoftware:configuration.api:1.0.2")
implementation("de.srsoftware:tools.jdbc:1.3.2") implementation("de.srsoftware:tools.jdbc:1.3.2")
implementation("de.srsoftware:tools.util:2.0.3")
} }

10
company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java

@ -38,6 +38,16 @@ public class CompanyModule implements CompanyService {
return members; return members;
} }
@Override
public Collection<Company> listCompaniesOf(UmbrellaUser user) throws UmbrellaException {
return companyDb.listCompaniesOf(user.id());
}
@Override
public boolean membership(long companyId, long userId) throws UmbrellaException {
return companyDb.getMembers(companyId).contains(userId);
}
@Override @Override
public UserService userService() { public UserService userService() {
return users; return users;

18
company/src/main/java/de/srsoftware/umbrella/company/SqliteDb.java

@ -6,6 +6,7 @@ import static de.srsoftware.tools.jdbc.Query.select;
import static de.srsoftware.umbrella.company.Constants.TABLE_COMPANIES; import static de.srsoftware.umbrella.company.Constants.TABLE_COMPANIES;
import static de.srsoftware.umbrella.company.Constants.TABLE_COMPANIES_USERS; import static de.srsoftware.umbrella.company.Constants.TABLE_COMPANIES_USERS;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException;
import de.srsoftware.umbrella.company.api.CompanyDb; import de.srsoftware.umbrella.company.api.CompanyDb;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
@ -32,7 +33,20 @@ public class SqliteDb implements CompanyDb {
rs.close(); rs.close();
return ids; return ids;
} catch (SQLException e) { } catch (SQLException e) {
throw new UmbrellaException("Failed to load members of company {0}",companyId); throw databaseException("Failed to load members of company {0}",companyId);
}
}
@Override
public Collection<Company> listCompaniesOf(long userId) throws UmbrellaException {
try {
var rs = select("*").from(TABLE_COMPANIES).leftJoin(ID,TABLE_COMPANIES_USERS,COMPANY_ID).where(USER_ID,equal(userId)).exec(db);
var companies = new HashSet<Company>();
while (rs.next()) companies.add(Company.of(rs));
rs.close();
return companies;
} catch (SQLException e) {
throw databaseException("Failed to load companies for user {0}",userId);
} }
} }
@ -46,7 +60,7 @@ public class SqliteDb implements CompanyDb {
if (company == null) throw new UmbrellaException("Could not load company {0}",companyId); if (company == null) throw new UmbrellaException("Could not load company {0}",companyId);
return company; return company;
} catch (SQLException e){ } catch (SQLException e){
throw new UmbrellaException("Could not load company {0}",companyId); throw databaseException("Could not load company {0}",companyId);
} }
} }
} }

2
company/src/main/java/de/srsoftware/umbrella/company/api/CompanyDb.java

@ -8,5 +8,7 @@ import java.util.Collection;
public interface CompanyDb { public interface CompanyDb {
Collection<Long> getMembers(long companyId) throws UmbrellaException; Collection<Long> getMembers(long companyId) throws UmbrellaException;
Collection<Company> listCompaniesOf(long id) throws UmbrellaException;
Company load(long companyId) throws UmbrellaException; Company load(long companyId) throws UmbrellaException;
} }

8
contact/build.gradle.kts

@ -0,0 +1,8 @@
description = "Umbrella : Documents"
dependencies{
implementation(project(":core"))
implementation("de.srsoftware:configuration.api:1.0.2")
implementation("de.srsoftware:tools.jdbc:1.3.2")
implementation("de.srsoftware:tools.util:2.0.3")
}

10
contact/src/main/java/de/srsoftware/umbrella/contact/Constants.java

@ -0,0 +1,10 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.contact;
public class Constants {
private Constants(){}
public static final String CONFIG_DATABASE = "umbrella.modules.contact.database";
public static final String TABLE_CONTACTS_USERS = "contacts_users";
public static final String TABLE_CONTACTS = "contacts";
}

10
contact/src/main/java/de/srsoftware/umbrella/contact/ContactDb.java

@ -0,0 +1,10 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.contact;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.Contact;
import java.util.Collection;
public interface ContactDb {
Collection<Contact> listContactsOf(long id) throws UmbrellaException;
}

27
contact/src/main/java/de/srsoftware/umbrella/contact/ContactModule.java

@ -0,0 +1,27 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.contact;
import static de.srsoftware.umbrella.contact.Constants.CONFIG_DATABASE;
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
import de.srsoftware.configuration.Configuration;
import de.srsoftware.umbrella.core.api.ContactService;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.Contact;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.util.Collection;
public class ContactModule implements ContactService {
private final ContactDb contactDb;
public ContactModule(Configuration config) throws UmbrellaException {
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
contactDb = new SqliteDb(connect(dbFile));
}
@Override
public Collection<Contact> listContactsOf(UmbrellaUser user) throws UmbrellaException {
return contactDb.listContactsOf(user.id());
}
}

36
contact/src/main/java/de/srsoftware/umbrella/contact/SqliteDb.java

@ -0,0 +1,36 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.contact;
import static de.srsoftware.tools.jdbc.Condition.equal;
import static de.srsoftware.tools.jdbc.Query.select;
import static de.srsoftware.umbrella.contact.Constants.TABLE_CONTACTS;
import static de.srsoftware.umbrella.contact.Constants.TABLE_CONTACTS_USERS;
import static de.srsoftware.umbrella.core.Constants.*;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.Contact;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashSet;
public class SqliteDb implements ContactDb{
private final Connection conn;
public SqliteDb(Connection connection) {
conn = connection;
}
@Override
public Collection<Contact> listContactsOf(long userId) throws UmbrellaException{
try {
var rs = select("*").from(TABLE_CONTACTS).leftJoin(ID,TABLE_CONTACTS_USERS,USER_ID).where(USER_ID,equal(userId)).exec(conn);
var contacts = new HashSet<Contact>();
while (rs.next()) contacts.add(Contact.of(rs));
rs.close();
return contacts;
} catch (SQLException e) {
throw UmbrellaException.databaseException("Failed to load contacts og user {0}",userId);
}
}
}

1
core/src/main/java/de/srsoftware/umbrella/core/Constants.java

@ -6,6 +6,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
public class Constants { public class Constants {
private Constants(){}
public static final String ADDRESS = "address"; public static final String ADDRESS = "address";
public static final String ATTACHMENTS = "attachments"; public static final String ATTACHMENTS = "attachments";
public static final String AUTHORIZATION = "Authorization"; public static final String AUTHORIZATION = "Authorization";

11
core/src/main/java/de/srsoftware/umbrella/core/api/CompanyService.java

@ -7,8 +7,13 @@ import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.util.Collection; import java.util.Collection;
public interface CompanyService { public interface CompanyService {
public Collection<UmbrellaUser> getMembers(long companyId) throws UmbrellaException;
public UserService userService();
Company get(long companyId) throws UmbrellaException; Company get(long companyId) throws UmbrellaException;
Collection<UmbrellaUser> getMembers(long companyId) throws UmbrellaException;
Collection<Company> listCompaniesOf(UmbrellaUser user) throws UmbrellaException;
boolean membership(long companyId, long userId) throws UmbrellaException;
UserService userService();
} }

11
core/src/main/java/de/srsoftware/umbrella/core/api/ContactService.java

@ -0,0 +1,11 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.core.api;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.Contact;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.util.Collection;
public interface ContactService {
Collection<Contact> listContactsOf(UmbrellaUser user) throws UmbrellaException;
}

4
core/src/main/java/de/srsoftware/umbrella/core/exceptions/UmbrellaException.java

@ -25,6 +25,10 @@ public class UmbrellaException extends Exception{
return this; return this;
} }
public static UmbrellaException databaseException(String message, Object fills) {
return new UmbrellaException(HTTP_SERVER_ERROR,message,fills);
}
public static UmbrellaException invalidFieldException(String field,String expected){ public static UmbrellaException invalidFieldException(String field,String expected){
return new UmbrellaException(HTTP_UNPROCESSABLE, ERROR_INVALID_FIELD, field, expected); return new UmbrellaException(HTTP_UNPROCESSABLE, ERROR_INVALID_FIELD, field, expected);
} }

31
core/src/main/java/de/srsoftware/umbrella/core/model/Company.java

@ -1,15 +1,19 @@
/* © SRSoftware 2025 */ /* © SRSoftware 2025 */
package de.srsoftware.umbrella.core.model; package de.srsoftware.umbrella.core.model;
import static de.srsoftware.tools.Optionals.emptyIfNull;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static java.util.Map.entry;
import de.srsoftware.tools.Mappable;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Map;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; 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 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) implements Mappable {
public static Company of(JSONObject json) throws UmbrellaException { public static Company of(JSONObject json) throws UmbrellaException {
try { try {
@ -54,4 +58,29 @@ public record Company(long id, String name, String address, String court, String
throw new UmbrellaException(500,"Failed to convert ResultSet to Company!").causedBy(e); throw new UmbrellaException(500,"Failed to convert ResultSet to Company!").causedBy(e);
} }
} }
@Override
public String toString() {
return name;
}
@Override
public Map<String, Object> toMap() {
return Map.ofEntries(
entry(ID,id),
entry(NAME,name),
entry(ADDRESS,emptyIfNull(address)),
entry(FIELD_COURT,emptyIfNull(court)),
entry(FIELD_TAX_NUMBER,emptyIfNull(taxId)),
entry(FIELD_PHONE,emptyIfNull(phone)),
entry(DECIMAL_SEPARATOR,emptyIfNull(decimalSeparator)),
entry(THOUSANDS_SEPARATOR,emptyIfNull(thousandsSeparator)),
entry(LAST_CUSTOMER_NUMBER,lastCustomerNumber),
entry(DECIMALS,decimals),
entry(CUSTOMER_NUMBER_PREFIX,emptyIfNull(customerNumberPrefix)),
entry(FIELD_CURRENCY,emptyIfNull(currency)),
entry(EMAIL,emptyIfNull(email)),
entry(FIELD_BANK_ACCOUNT,emptyIfNull(bankAccount))
);
}
} }

21
core/src/main/java/de/srsoftware/umbrella/core/model/Contact.java

@ -0,0 +1,21 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.core.model;
import static de.srsoftware.umbrella.core.Constants.DATA;
import static de.srsoftware.umbrella.core.Constants.ID;
import de.srsoftware.tools.Mappable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
public record Contact(long id, String vcard) implements Mappable {
public static Contact of(ResultSet rs) throws SQLException {
return new Contact(rs.getLong(ID),rs.getString(DATA));
}
@Override
public Map<String, Object> toMap() {
return Map.of();
}
}

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

@ -21,13 +21,13 @@ import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.api.CompanyService; import de.srsoftware.umbrella.core.api.CompanyService;
import de.srsoftware.umbrella.core.api.UserService; import de.srsoftware.umbrella.core.api.UserService;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.Company;
import de.srsoftware.umbrella.core.model.Token; import de.srsoftware.umbrella.core.model.Token;
import de.srsoftware.umbrella.core.model.UmbrellaUser; import de.srsoftware.umbrella.core.model.UmbrellaUser;
import de.srsoftware.umbrella.documents.model.*; 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 org.json.JSONArray; import org.json.JSONArray;
@ -92,7 +92,7 @@ public class DocumentApi extends BaseHandler {
} }
private boolean getCompanies(HttpExchange ex, UmbrellaUser user, Token token) throws IOException, UmbrellaException { private boolean getCompanies(HttpExchange ex, UmbrellaUser user, Token token) throws IOException, UmbrellaException {
return sendContent(ex,getLegacyCompanies(ex,user,token)); return sendContent(ex,companies.listCompaniesOf(user).stream().map(Company::toMap));
} }
private boolean getContacts(HttpExchange ex, UmbrellaUser user, Token token) throws IOException, UmbrellaException { private boolean getContacts(HttpExchange ex, UmbrellaUser user, Token token) throws IOException, UmbrellaException {
@ -120,14 +120,6 @@ public class DocumentApi extends BaseHandler {
return sendContent(ex,doc.renderToMap()); return sendContent(ex,doc.renderToMap());
} }
private HashMap<Long, Map<String, Object>> getLegacyCompanies(HttpExchange ex, UmbrellaUser umbrellaUser, Token token) throws IOException, UmbrellaException {
var location = config.get("umbrella.modules.company.baseUrl").map(s -> s+"/json").orElseThrow(() -> new UmbrellaException(500,"umbrella.modules.company.baseUrl not configured!"));
var resp = request(location, token.asMap(),MIME_FORM_URL,null);
if (!(resp instanceof JSONObject json)) throw new UmbrellaException(500,"{0} did not return JSON!",location);
var result = new HashMap<Long, Map<String,Object>>();
for (var key : json.keySet()) result.put(Long.parseLong(key),json.getJSONObject(key).toMap());
return result;
}
private JSONArray getLegacyContacts(HttpExchange ex, UmbrellaUser umbrellaUser, Token token) throws IOException, UmbrellaException { 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 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);
@ -140,9 +132,8 @@ public class DocumentApi extends BaseHandler {
var json = json(ex); var json = json(ex);
if (!json.has(COMPANY)) throw missingFieldException(COMPANY); if (!json.has(COMPANY)) throw missingFieldException(COMPANY);
long companyId = json.getLong(COMPANY); long companyId = json.getLong(COMPANY);
var companies = getLegacyCompanies(ex,user, token);
var company = companies.get(companyId); var company = companies.get(companyId);
if (company == null) return forbidden(ex); if (!companies.membership(companyId,user.id())) throw new UmbrellaException(HTTP_FORBIDDEN,"You are mot a member of company {0}",company);
var docs = db.listDocs(companyId); 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()); for (var entry : docs.entrySet()) map.put(entry.getKey(),entry.getValue().summary());
@ -159,10 +150,7 @@ public class DocumentApi extends BaseHandler {
if (!senderData.has(FIELD_COMPANY) || !(senderData.get(FIELD_COMPANY) instanceof Number companyId)) throw missingFieldException(FIELD_COMPANY); if (!senderData.has(FIELD_COMPANY) || !(senderData.get(FIELD_COMPANY) instanceof Number companyId)) throw missingFieldException(FIELD_COMPANY);
var company = companies.get(companyId.longValue()); var company = companies.get(companyId.longValue());
var members = companies.getMembers(companyId.longValue()); if (!companies.membership(companyId.longValue(),user.id())) throw new UmbrellaException(HTTP_FORBIDDEN,"You are mot a member of company {0}",company);
var isMember = false;
for (var member : members) isMember |= user.equals(member);
if (!isMember) 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_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); if (!json.has(FIELD_TYPE) || !(json.get(FIELD_TYPE) instanceof Number docTypeId)) throw missingFieldException(FIELD_TYPE);

4
frontend/src/routes/document/Add.svelte

@ -24,7 +24,9 @@
var resp = await fetch(url,{ credentials: 'include'}); var resp = await fetch(url,{ credentials: 'include'});
if (resp.ok){ if (resp.ok){
const companies = await resp.json(); const companies = await resp.json();
company = companies[document.sender.company]; for (let c of companies) {
if (c.id == document.sender.company) company = c;
}
document.sender.name = ''; document.sender.name = '';
if (company.name) document.sender.name += company.name+"\n"; if (company.name) document.sender.name += company.name+"\n";
if (company.address) document.sender.name += company.address+"\n"; if (company.address) document.sender.name += company.address+"\n";

7
frontend/src/routes/document/StateSelector.svelte

@ -0,0 +1,7 @@
<script>
import { t } from '../../translations.svelte.js';
</script>
<select>
<option>{t('document.select_type')}</option>
</select>

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

@ -2,7 +2,7 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { t } from '../../translations.svelte.js'; import { t } from '../../translations.svelte.js';
import { useTinyRouter } from 'svelte-tiny-router'; import { useTinyRouter } from 'svelte-tiny-router';
import StateSelector from './StateSelector.svelte';
let { id } = $props(); let { id } = $props();
let error = null; let error = null;
let doc = $state(null); let doc = $state(null);
@ -20,13 +20,67 @@
onMount(loadDoc); onMount(loadDoc);
</script> </script>
{#if error}
<span class="error">{error}</span>
{/if}
<fieldset> {#if doc}
{#if error} <fieldset>
<span class="error">{error}</span> <legend>{t('document.customer')}</legend>
{/if} <div>
{#if doc} {#each doc.customer.name.split("\n") as line}
<legend>{t('document.type_'+doc.type)} {doc.number}</legend> {line}<br/>
{/each}
{/if} </div>
</fieldset> <div>
<span>{t('document.customer_number',doc.customer.id)}</span>
</div>
<div>
<span>{t('document.tax_id',doc.customer.tax_id)}</span>
</div>
<div>
<span>{t('document.email',doc.customer.email)}</span>
</div>
</fieldset>
<fieldset>
<legend>{t('document.sender')}</legend>
<div>
{#each doc.sender.name.split("\n") as line}
{line}<br/>
{/each}
</div>
<div>
<span>{t('document.court',doc.sender.court)}</span>
</div>
<div>
<span>{t('document.tax_id',doc.sender.tax_id)}</span>
</div>
<div>
<span>{t('document.bank_account',doc.sender.bank_account)}</span>
</div>
</fieldset>
<fieldset>
<legend>{t('document.type_'+doc.type)}</legend>
<div>{t('document.number')}: {doc.number}</div>
<div>{t('document.state')}: <StateSelector /></div>
<div>{t('document.date')}: {doc.date}</div>
<div>{t('document.delivery')}: {doc.delivery}</div>
<div>{t('document.template')}: {doc.template.name} <span class="error">SElektor hier!</span></div>
</fieldset>
<fieldset>
<legend>{t('document.head')}</legend>
{doc.head}
</fieldset>
<fieldset>
<legend>{t('document.positions')}</legend>
<span class="error">laden!</span>
</fieldset>
<fieldset>
<legend>{t('document.footer')}</legend>
{doc.footer}
</fieldset>
<fieldset>
<legend>{t('document.actions')}</legend>
<span class="error">laden!</span>
</fieldset>
{/if}

3
settings.gradle.kts

@ -9,4 +9,5 @@ include("translations")
include("user") include("user")
include("web") include("web")
include("company") include("company")
include("contact")

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

@ -2,9 +2,13 @@
"document": { "document": {
"actions": "Aktionen", "actions": "Aktionen",
"add_new": "{0} anlegen", "add_new": "{0} anlegen",
"bank_account": "Bankverbindung: {0}",
"court": "Amtsgericht: {0}",
"create_new": "neues Dokument", "create_new": "neues Dokument",
"customer": "Kunde", "customer": "Kunde",
"customer_number": "Kundennummer: {0}",
"date": "Datum", "date": "Datum",
"email": "E-Mail: {0}",
"gross_sum": "Brutto-Summe", "gross_sum": "Brutto-Summe",
"list": "Dokumente", "list": "Dokumente",
"list_of": "Dokumente von {0}", "list_of": "Dokumente von {0}",
@ -17,6 +21,7 @@
"state_new":"neu", "state_new":"neu",
"state_payed": "bezahlt", "state_payed": "bezahlt",
"state_sent": "versendet", "state_sent": "versendet",
"tax_id": "Steuernummer: {0}",
"type": "Dokumententyp", "type": "Dokumententyp",
"type_confirmation": "Bestätigung", "type_confirmation": "Bestätigung",
"type_invoice": "Rechnung", "type_invoice": "Rechnung",

Loading…
Cancel
Save