implemented deletion of positions
This commit is contained in:
@@ -63,14 +63,14 @@ public class DocumentApi extends BaseHandler {
|
|||||||
var user = users.loadUser(token);
|
var user = users.loadUser(token);
|
||||||
if (user.isEmpty()) return unauthorized(ex);
|
if (user.isEmpty()) return unauthorized(ex);
|
||||||
var head = path.pop();
|
var head = path.pop();
|
||||||
return switch (head){
|
long docId = Long.parseLong(head);
|
||||||
default -> {
|
return switch (path.pop()){
|
||||||
try {
|
case POSITION -> deletePosition(ex,docId,user.get());
|
||||||
yield deleteDocument(ex,Long.parseLong(head),user.get());
|
case null -> deleteDocument(ex,docId,user.get());
|
||||||
} catch (NumberFormatException ignored) {}
|
default -> super.doDelete(path,ex);
|
||||||
yield super.doDelete(path,ex);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
return super.doDelete(path,ex);
|
||||||
} catch (UmbrellaException e) {
|
} catch (UmbrellaException e) {
|
||||||
return send(ex,e);
|
return send(ex,e);
|
||||||
}
|
}
|
||||||
@@ -84,6 +84,17 @@ public class DocumentApi extends BaseHandler {
|
|||||||
return sendContent(ex,db.deleteDoc(docId));
|
return sendContent(ex,db.deleteDoc(docId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean deletePosition(HttpExchange ex, long docId, UmbrellaUser user) 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());
|
||||||
|
if (doc.state() != NEW) throw new UmbrellaException(HTTP_BAD_REQUEST,"This document has already been sent");
|
||||||
|
var json = json(ex);
|
||||||
|
if (!(json.has(POSITION) && json.get(POSITION) instanceof Number number)) throw missingFieldException(POSITION);
|
||||||
|
db.dropPosition(docId,number.longValue());
|
||||||
|
return send(ex,db.loadDoc(docId).positions());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||||
addCors(ex);
|
addCors(ex);
|
||||||
@@ -301,7 +312,7 @@ public class DocumentApi extends BaseHandler {
|
|||||||
var pos = new Position(doc.positions().size()+1,itemCode,amount.doubleValue(),unit,title,description,unitPrice.longValue(),tax,timeId,false);
|
var pos = new Position(doc.positions().size()+1,itemCode,amount.doubleValue(),unit,title,description,unitPrice.longValue(),tax,timeId,false);
|
||||||
doc.positions().add(pos);
|
doc.positions().add(pos);
|
||||||
|
|
||||||
return sendContent(ex,db.save(doc).positions());
|
return send(ex,db.save(doc).positions());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean postTemplateList(HttpExchange ex, UmbrellaUser user) throws UmbrellaException, IOException {
|
private boolean postTemplateList(HttpExchange ex, UmbrellaUser user) throws UmbrellaException, IOException {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import LineEditor from '../../Components/LineEditor.svelte';
|
import LineEditor from '../../Components/LineEditor.svelte';
|
||||||
import MarkdownEditor from '../../Components/MarkdownEditor.svelte';
|
import MarkdownEditor from '../../Components/MarkdownEditor.svelte';
|
||||||
import PriceEditor from '../../Components/PriceEditor.svelte';
|
import PriceEditor from '../../Components/PriceEditor.svelte';
|
||||||
var { currency, editable, pos = $bindable(null), submit = (key,newVal) => {}, movePos = (number,step) => {} } = $props();
|
var { currency, editable, pos = $bindable(null), submit = (key,newVal) => {}, movePos = (number,step) => {}, drop = (number) => {} } = $props();
|
||||||
let prefix = `pos.${pos.number}`
|
let prefix = `pos.${pos.number}`
|
||||||
|
|
||||||
function moveup(){
|
function moveup(){
|
||||||
@@ -21,14 +21,14 @@
|
|||||||
.move{
|
.move{
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr > *:nth-child(1){
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
{#if pos}
|
{#if pos}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="move">
|
|
||||||
{#if editable && pos.number>1}
|
|
||||||
<span onclick={moveup}>⏫</span>
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
<td>{pos.number}</td>
|
<td>{pos.number}</td>
|
||||||
<td class="item">
|
<td class="item">
|
||||||
<LineEditor bind:value={pos.item} editable={editable} onSet={(val) => submit(`${prefix}.item`,val)} />
|
<LineEditor bind:value={pos.item} editable={editable} onSet={(val) => submit(`${prefix}.item`,val)} />
|
||||||
@@ -54,6 +54,10 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="move">
|
<td class="move">
|
||||||
{#if editable}
|
{#if editable}
|
||||||
|
{#if pos.number>1}
|
||||||
|
<span onclick={moveup}>⏫</span>
|
||||||
|
{/if}
|
||||||
|
<span onclick={() => drop(pos.number)}>❌</span>
|
||||||
<span onclick={movedown}>⏬</span>
|
<span onclick={movedown}>⏬</span>
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -8,6 +8,13 @@
|
|||||||
|
|
||||||
let editable = $derived(document.state == 1);
|
let editable = $derived(document.state == 1);
|
||||||
|
|
||||||
|
async function updatePositions(resp){
|
||||||
|
let json = await resp.json();
|
||||||
|
document.positions = {};
|
||||||
|
setTimeout(() => document.positions = json,100)
|
||||||
|
error = null;
|
||||||
|
}
|
||||||
|
|
||||||
async function movePos(number,step){
|
async function movePos(number,step){
|
||||||
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/document/${document.id}/position`;
|
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/document/${document.id}/position`;
|
||||||
const resp = await fetch(url,{
|
const resp = await fetch(url,{
|
||||||
@@ -16,10 +23,21 @@
|
|||||||
body:JSON.stringify({position:number,move:step})
|
body:JSON.stringify({position:number,move:step})
|
||||||
});
|
});
|
||||||
if (resp.ok){
|
if (resp.ok){
|
||||||
let json = await resp.json();
|
updatePositions(resp);
|
||||||
document.positions = {};
|
} else {
|
||||||
setTimeout(() => document.positions = json,10)
|
error = await resp.text();
|
||||||
error = null;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function drop(number){
|
||||||
|
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/document/${document.id}/position`;
|
||||||
|
const resp = await fetch(url,{
|
||||||
|
method: 'DELETE',
|
||||||
|
credentials:'include',
|
||||||
|
body:JSON.stringify({position:number})
|
||||||
|
});
|
||||||
|
if (resp.ok){
|
||||||
|
updatePositions(resp);
|
||||||
} else {
|
} else {
|
||||||
error = await resp.text();
|
error = await resp.text();
|
||||||
}
|
}
|
||||||
@@ -30,7 +48,6 @@
|
|||||||
<table class="positions">
|
<table class="positions">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
|
||||||
<th>{t('document.pos')}</th>
|
<th>{t('document.pos')}</th>
|
||||||
<th>{t('document.code')}</th>
|
<th>{t('document.code')}</th>
|
||||||
<th>{t('document.title_or_desc')}</th>
|
<th>{t('document.title_or_desc')}</th>
|
||||||
@@ -43,10 +60,9 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each Object.entries(document.positions) as [id,pos]}
|
{#each Object.entries(document.positions) as [id,pos]}
|
||||||
<Position currency={document.currency} bind:pos={document.positions[id]} editable={editable} {submit} {movePos} />
|
<Position currency={document.currency} bind:pos={document.positions[id]} editable={editable} {submit} {movePos} {drop} />
|
||||||
{/each}
|
{/each}
|
||||||
<tr class="sums">
|
<tr class="sums">
|
||||||
<td></td>
|
|
||||||
<td colspan="2"></td>
|
<td colspan="2"></td>
|
||||||
<td>{t('document.net_sum')}</td>
|
<td>{t('document.net_sum')}</td>
|
||||||
<td>{document.net_sum/100} {document.currency}</td>
|
<td>{document.net_sum/100} {document.currency}</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user