diff options
Diffstat (limited to 'src/components/invoice_header_editor.vue')
-rw-r--r-- | src/components/invoice_header_editor.vue | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/components/invoice_header_editor.vue b/src/components/invoice_header_editor.vue new file mode 100644 index 0000000..0a39ce5 --- /dev/null +++ b/src/components/invoice_header_editor.vue @@ -0,0 +1,151 @@ +<script setup lang="ts"> +import { ref, toRaw, onMounted } from 'vue' +import { useRouter } from 'vue-router' +import axios from 'axios' +import { useToast } from 'vue-toast-notification' +import Customer from "./../classes/customer" + +const toast = useToast({ + position: 'top-right' +}) + +const route = useRouter() + +const gettingData = ref(true) // for when getting all/one customer(s) +const submitting = ref(false) // shows spinner on continue button +const allCustomers = ref([]) + +const customer = ref(new Customer()) +const customerSelection = ref(null) +const invoiceDate = ref(new Date().toISOString().substr(0, 10)) + +const getAllCustomers = async () => { + allCustomers.value = [] + gettingData.value = true + + try { + const r = await axios.get('/customer') + if (r.status === 200) { + allCustomers.value = r.data.data + } else if (r.status === 204) { + toast.warning('No customers found') + } + } catch (err) { + toast.error('An unhandled exception occoured. Please check logs') + console.error(err) + } + + gettingData.value = false +} + +const submit = async (e: Event) => { + e.preventDefault() + submitting.value = true + + try { + const c = toRaw(customer.value) + + const res = await axios.post('/invoice', { + "invoicedate": new Date(toRaw(invoiceDate.value)).toISOString(), + "isdraft": true, + "billingaddress": c.BillingAddress, + "shippingaddress": c.BillingAddress, // TODO + "customername": c.Name, + "customergstin": c.Gstin, + "customercontactname": c.ContactName, + "customerphone": c.Phone, + "customeremail": c.Email, + "customerwebsite": c.Website, + }) + + route.push({ name: "edit-draft", params: { id: res.data.data.ID }}) + } catch (err: any) { + const statusCode: any = err.request.status + const res: any = JSON.parse(err.request.response) + + switch (statusCode) { + case 400: + toast.error(res.error) + break + case 409: + toast.error(res.error) + break + default: + console.error(err) + toast.error('An unhandled exception occoured. Please check logs') + } + } + + submitting.value = false +} + +// when customer is selected, +// get the whole customer object from server +const refreshCustomer = async () => { + gettingData.value = true + + const c: any = toRaw(customerSelection.value) + + try { + const r = await axios.get(`/customer/${c.ID}`) + customer.value = r.data.data + } catch (err) { + toast.error('An unhandled exception occoured. Please check logs') + console.error(err) + } + + gettingData.value = false +} + +onMounted(() => { + getAllCustomers() +}) +</script> + +<template> + <form class="row g-3" v-on:submit="submit"> + <div class="col-md-3"><!-- spacer --></div> + + <div class="col-md-3"> + <label for="item-brand-input" class="form-label">Customer</label> + <select + v-model="customerSelection" + @change="refreshCustomer()" + class="form-select" + aria-label="Select Brand" + id="item-brand-input" + > + <option selected disabled value="null">Select Customer</option> + <option v-for="customer in allCustomers" :value="customer" :key="customer['id']"> + {{ customer["Name"] }} + </option> + </select> + </div> + + <div class="col-md-2"> + <label for="invoice-date" class="form-label">Invoice Date</label> + <input + type="date" + id="invoice-date" + class="form-control" + v-model="invoiceDate"/> + </div> + + <div class="col-md-1 d-flex align-items-end justify-content-start"> + <button + type="submit" + class="btn btn-primary btn-block" + :class="{ disabled: submitting || gettingData || customerSelection === null }" + > + Continue + <div v-if="submitting" class="spinner-border spinner-border-sm ms-1" role="status"> + <span class="sr-only"></span> + </div> + </button> + </div> + + <div class="col-md-2"><!-- spacer --></div> + <p>TODO: add address info / shipping address selector</p> + + </form> +</template> |