diff options
Diffstat (limited to 'src/components/InvoiceHeaderEditor.vue')
-rw-r--r-- | src/components/InvoiceHeaderEditor.vue | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/src/components/InvoiceHeaderEditor.vue b/src/components/InvoiceHeaderEditor.vue new file mode 100644 index 0000000..6fe8a25 --- /dev/null +++ b/src/components/InvoiceHeaderEditor.vue @@ -0,0 +1,192 @@ +<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" +import User from "./../classes/user" + +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 user = ref(new User()) +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 + } + } catch (err) { + toast.error('An unhandled exception occoured. Please check logs') + console.error(err) + } + + gettingData.value = false +} + +const getUser = async () => { + user.value = new User() + gettingData.value = true + + try { + const r = await axios.get('/user') + if (r.status === 200) { + user.value = r.data.data + } + } catch (err) { + toast.error('An unhandled exception occoured. Please check logs') + console.error(err) + } + + gettingData.value = false + console.log(user) +} + +const submit = async (e: Event) => { + e.preventDefault() + submitting.value = true + + try { + const c = toRaw(customer.value) + const u = toRaw(user.value) + + const res = await axios.post('/invoice', { + "invoicedate": new Date(toRaw(invoiceDate.value)).toISOString(), + "isdraft": true, + "BillingAddress": { + // NOTE: just c.BillingAddress doesn't work for some reason + "AddressText": c.BillingAddress.AddressText, + "City": c.BillingAddress.City, + "State": c.BillingAddress.State, + "PostalCode": c.BillingAddress.PostalCode, + "Country": c.BillingAddress.Country, + }, + "ShippingAddress": { + // TODO: don't use the billing address! + "AddressText": c.BillingAddress.AddressText, + "City": c.BillingAddress.City, + "State": c.BillingAddress.State, + "PostalCode": c.BillingAddress.PostalCode, + "Country": c.BillingAddress.Country, + }, + "customername": c.Name, + "customergstin": c.Gstin, + "customercontactname": c.ContactName, + "customerphone": c.Phone, + "customeremail": c.Email, + "customerwebsite": c.Website, + "issuerfirmname": u.FirmName, + "issuerfirmaddress": u.AddressText, + "issuerfirmgstin": u.Gstin, + "issuerfirmphone": u.Phone, + "issuerfirmemail": u.Email, + "issuerfirmwebsite": u.Website, + }) + + route.push({ name: "edit-invoice", 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(() => { + getUser() + 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 v-if="allCustomers.length === 0" selected disabled value="null">No customers added in OpenBills!</option> + <option v-else 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> |