Added variant update functionality.
This commit is contained in:
@@ -88,3 +88,38 @@ pub async fn insert_variant(article_id: i64, variant: &Variant, pool: PgPool) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn update_variant(variant_id: i64, variant: &Variant, pool: PgPool) -> Option<Variant> {
|
||||||
|
let mut args = PgArguments::default();
|
||||||
|
args.add(&variant.id);
|
||||||
|
args.add(&variant.weight);
|
||||||
|
args.add(&variant.ean);
|
||||||
|
args.add(&variant.name);
|
||||||
|
args.add(&variant.description);
|
||||||
|
args.add(&variant.ingredients);
|
||||||
|
|
||||||
|
info!("Variant: {:#?}", variant);
|
||||||
|
|
||||||
|
let statement = format!(
|
||||||
|
"UPDATE {} SET weight = $2, ean = $3, name = $4, description = $5, ingredients = $6 WHERE id = $1 RETURNING *",
|
||||||
|
"variant",
|
||||||
|
);
|
||||||
|
|
||||||
|
let res = sqlx::query_with(
|
||||||
|
statement.as_str(),
|
||||||
|
args)
|
||||||
|
.fetch_one(&pool).await;
|
||||||
|
|
||||||
|
info!("{:#?}", res);
|
||||||
|
|
||||||
|
match res {
|
||||||
|
Ok(record) => {
|
||||||
|
let variant = from_postgres_row_small(record);
|
||||||
|
Some(variant)
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!("Error while updating variant: {}", variant_id);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ async function create() {
|
|||||||
|
|
||||||
const variant: Variant = new Variant(0, weight.value, ean.value, name.value, description.value, ingredients.value);
|
const variant: Variant = new Variant(0, weight.value, ean.value, name.value, description.value, ingredients.value);
|
||||||
|
|
||||||
await store.addVariant(store.article.id, variant);
|
await store.addVariant(variant);
|
||||||
|
|
||||||
closeDialog();
|
closeDialog();
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@ function clearVariables() {
|
|||||||
mdi-plus-thick
|
mdi-plus-thick
|
||||||
</v-icon>
|
</v-icon>
|
||||||
|
|
||||||
Artikel erstellen
|
Variante erstellen
|
||||||
|
|
||||||
<v-progress-circular v-if="loading" indeterminate :size="15" :width="2"></v-progress-circular>
|
<v-progress-circular v-if="loading" indeterminate :size="15" :width="2"></v-progress-circular>
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type {Variant} from "~/types/variant";
|
|
||||||
import {useLabelEditorStore} from "~/store/labelEditorStore";
|
import {useLabelEditorStore} from "~/store/labelEditorStore";
|
||||||
import type {Ref} from "vue";
|
import type {Ref} from "vue";
|
||||||
|
import {Variant} from "~/types/variant";
|
||||||
|
|
||||||
let store = useLabelEditorStore();
|
let store = useLabelEditorStore();
|
||||||
|
|
||||||
@@ -11,13 +11,51 @@
|
|||||||
|
|
||||||
let edit: Ref<boolean> = ref<boolean>(false);
|
let edit: Ref<boolean> = ref<boolean>(false);
|
||||||
|
|
||||||
|
JSON.parse(JSON.stringify(props.variant.weight))
|
||||||
|
let weight: Ref<string | null> = ref<string | null>(JSON.parse(JSON.stringify(props.variant.weight)));
|
||||||
|
let ean: Ref<string | null> = ref<string | null>(JSON.parse(JSON.stringify(props.variant.ean)));
|
||||||
|
let name: Ref<string | null> = ref<string | null>(JSON.parse(JSON.stringify(props.variant.name)));
|
||||||
|
let description: Ref<string | null> = ref<string | null>(JSON.parse(JSON.stringify(props.variant.description)));
|
||||||
|
let ingredients: Ref<string | null> = ref<string | null>(JSON.parse(JSON.stringify(props.variant.ingredients)));
|
||||||
|
|
||||||
|
function toggleEdit() {
|
||||||
|
if (edit.value) {
|
||||||
|
disableEdit();
|
||||||
|
} else {
|
||||||
|
enableEdit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableEdit() {
|
||||||
|
edit.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function disableEdit() {
|
||||||
|
edit.value = false;
|
||||||
|
weight.value = JSON.parse(JSON.stringify(props.variant.weight));
|
||||||
|
ean.value = JSON.parse(JSON.stringify(props.variant.ean));
|
||||||
|
name.value = JSON.parse(JSON.stringify(props.variant.name));
|
||||||
|
description.value = JSON.parse(JSON.stringify(props.variant.description));
|
||||||
|
ingredients.value = JSON.parse(JSON.stringify(props.variant.ingredients));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateVariant() {
|
||||||
|
if (weight.value != null) {
|
||||||
|
let updateVariant: Variant = new Variant(props.variant.id, weight.value, ean.value, name.value, description.value, ingredients.value);
|
||||||
|
|
||||||
|
await store.updateVariant(updateVariant);
|
||||||
|
|
||||||
|
disableEdit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-title>
|
<v-card-title>
|
||||||
<v-row>
|
<v-row>
|
||||||
{{ variant.name }}
|
{{ name }}
|
||||||
|
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
|
|
||||||
@@ -25,8 +63,8 @@
|
|||||||
|
|
||||||
<v-btn
|
<v-btn
|
||||||
:flat="true"
|
:flat="true"
|
||||||
size="small"
|
|
||||||
:disabled="!edit"
|
:disabled="!edit"
|
||||||
|
:hidden="edit"
|
||||||
>
|
>
|
||||||
<v-icon>mdi-delete-empty</v-icon>
|
<v-icon>mdi-delete-empty</v-icon>
|
||||||
<v-tooltip
|
<v-tooltip
|
||||||
@@ -41,8 +79,9 @@
|
|||||||
|
|
||||||
<v-btn
|
<v-btn
|
||||||
:flat="true"
|
:flat="true"
|
||||||
size="small"
|
|
||||||
:disabled="!edit"
|
:disabled="!edit"
|
||||||
|
:hidden="edit"
|
||||||
|
@click="disableEdit()"
|
||||||
>
|
>
|
||||||
<v-icon>mdi-cancel</v-icon>
|
<v-icon>mdi-cancel</v-icon>
|
||||||
<v-tooltip
|
<v-tooltip
|
||||||
@@ -55,8 +94,9 @@
|
|||||||
|
|
||||||
<v-btn
|
<v-btn
|
||||||
:flat="true"
|
:flat="true"
|
||||||
size="small"
|
|
||||||
:disabled="!edit"
|
:disabled="!edit"
|
||||||
|
:hidden="edit"
|
||||||
|
@click="updateVariant()"
|
||||||
>
|
>
|
||||||
<v-icon>mdi-content-save</v-icon>
|
<v-icon>mdi-content-save</v-icon>
|
||||||
<v-tooltip
|
<v-tooltip
|
||||||
@@ -71,7 +111,7 @@
|
|||||||
|
|
||||||
<v-btn
|
<v-btn
|
||||||
:flat="true"
|
:flat="true"
|
||||||
size="small"
|
@click="toggleEdit();"
|
||||||
>
|
>
|
||||||
<v-icon>mdi-pencil</v-icon>
|
<v-icon>mdi-pencil</v-icon>
|
||||||
<v-tooltip
|
<v-tooltip
|
||||||
@@ -93,30 +133,30 @@
|
|||||||
<v-col cols="2">
|
<v-col cols="2">
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-model.trim="variant.weight"
|
v-model.trim="weight"
|
||||||
label="Gewicht"
|
label="Gewicht"
|
||||||
:readonly="true"
|
:readonly="!edit"
|
||||||
/>
|
/>
|
||||||
</v-row>
|
</v-row>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-model.trim="variant.ean"
|
v-model.trim="ean"
|
||||||
label="EAN"
|
label="EAN"
|
||||||
:readonly="true"
|
:readonly="!edit"
|
||||||
/>
|
/>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-col cols="5">
|
<v-col cols="5">
|
||||||
<v-textarea
|
<v-textarea
|
||||||
:model-value="variant.description"
|
v-model.trim="description"
|
||||||
:tile=true
|
:tile=true
|
||||||
label="Beschreibung"
|
label="Beschreibung"
|
||||||
counter
|
counter
|
||||||
:persistentCounter=true
|
:persistentCounter=true
|
||||||
rows="6"
|
rows="6"
|
||||||
no-resize
|
no-resize
|
||||||
:readonly="true"
|
:readonly="!edit"
|
||||||
>
|
>
|
||||||
<template v-slot:counter="{ counter }">
|
<template v-slot:counter="{ counter }">
|
||||||
<span>{{ counter }} von {{ store.ingredientsMaxChars }} Zeichen.</span>
|
<span>{{ counter }} von {{ store.ingredientsMaxChars }} Zeichen.</span>
|
||||||
@@ -126,14 +166,14 @@
|
|||||||
|
|
||||||
<v-col cols="5">
|
<v-col cols="5">
|
||||||
<v-textarea
|
<v-textarea
|
||||||
:model-value="variant.ingredients"
|
v-model.trim="ingredients"
|
||||||
:tile=true
|
:tile=true
|
||||||
label="Zutaten"
|
label="Zutaten"
|
||||||
counter
|
counter
|
||||||
:persistentCounter=true
|
:persistentCounter=true
|
||||||
rows="6"
|
rows="6"
|
||||||
no-resize
|
no-resize
|
||||||
:readonly="true"
|
:readonly="!edit"
|
||||||
>
|
>
|
||||||
<template v-slot:counter="{ counter }">
|
<template v-slot:counter="{ counter }">
|
||||||
<span>{{ counter }} von {{ store.ingredientsMaxChars }} Zeichen.</span>
|
<span>{{ counter }} von {{ store.ingredientsMaxChars }} Zeichen.</span>
|
||||||
|
|||||||
@@ -168,10 +168,10 @@ export const useLabelEditorStore = defineStore('label_editor_store', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Variant
|
// Variant
|
||||||
async addVariant(articleID: number, variant: Variant) {
|
async addVariant(variant: Variant) {
|
||||||
if(this.article != null) {
|
if(this.article != null) {
|
||||||
try {
|
try {
|
||||||
let createdVariant = await $fetch<Variant>(this.config.public.url + '/article/' + articleID + '/variant', {
|
let createdVariant = await $fetch<Variant>(this.config.public.url + '/article/' + this.article.id + '/variant', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(variant),
|
body: JSON.stringify(variant),
|
||||||
});
|
});
|
||||||
@@ -186,5 +186,26 @@ export const useLabelEditorStore = defineStore('label_editor_store', {
|
|||||||
this.addNotification(true, 'Kann Variante nicht erstellen. Es ist kein Artikel ausgewählt.');
|
this.addNotification(true, 'Kann Variante nicht erstellen. Es ist kein Artikel ausgewählt.');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async updateVariant(variant: Variant) {
|
||||||
|
if(this.article != null) {
|
||||||
|
let variantIndex = this.article.variants.findIndex(i => i.id === variant.id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
let updatedVariant = await $fetch<Variant>(this.config.public.url + '/variant/' + variant.id, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(variant),
|
||||||
|
});
|
||||||
|
|
||||||
|
this.article.variants[variantIndex] = updatedVariant;
|
||||||
|
|
||||||
|
this.addNotification(false, 'Variante aktualisiert.');
|
||||||
|
} catch {
|
||||||
|
this.addNotification(true, 'Fehler beim aktualisieren der Variante.');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.addNotification(true, 'Kann Variante nicht aktualisiert werden. Es ist kein Artikel ausgewählt.');
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
+30
-1
@@ -15,7 +15,7 @@ use tower_http::cors::{AllowOrigin, Any, CorsLayer};
|
|||||||
use tracing::info;
|
use tracing::info;
|
||||||
use http::header::{AUTHORIZATION, ACCEPT, ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE, ACCESS_CONTROL_ALLOW_CREDENTIALS};
|
use http::header::{AUTHORIZATION, ACCEPT, ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE, ACCESS_CONTROL_ALLOW_CREDENTIALS};
|
||||||
use common::models::article;
|
use common::models::article;
|
||||||
use common::models::variant::{insert_variant, Variant};
|
use common::models::variant::{insert_variant, update_variant, Variant};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
@@ -49,6 +49,7 @@ async fn main() {
|
|||||||
.route("/article", post(create_article))
|
.route("/article", post(create_article))
|
||||||
.route("/article/{id}", get(get_article))
|
.route("/article/{id}", get(get_article))
|
||||||
.route("/article/{id}/variant", post(add_variant))
|
.route("/article/{id}/variant", post(add_variant))
|
||||||
|
.route("/variant/{id}", post(update_variant_route))
|
||||||
.with_state(pool)
|
.with_state(pool)
|
||||||
.layer(cors);
|
.layer(cors);
|
||||||
|
|
||||||
@@ -154,3 +155,31 @@ async fn add_variant(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn update_variant_route(
|
||||||
|
State(pool): State<PgPool>,
|
||||||
|
Path(variant_id): Path<i64>,
|
||||||
|
Json(payload): Json<Variant>,
|
||||||
|
) -> (StatusCode, Json<Variant>) {
|
||||||
|
info!("Update variant");
|
||||||
|
|
||||||
|
let update_variant = update_variant(variant_id, &payload, pool).await;
|
||||||
|
|
||||||
|
match update_variant {
|
||||||
|
Some(variant) => {
|
||||||
|
(StatusCode::OK, Json(variant))
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let variant = Variant {
|
||||||
|
id: 0,
|
||||||
|
weight: "".to_string(),
|
||||||
|
ean: None,
|
||||||
|
name: None,
|
||||||
|
description: None,
|
||||||
|
ingredients: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
(StatusCode::INTERNAL_SERVER_ERROR, Json(variant))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user