aboutsummaryrefslogtreecommitdiff
path: root/src/components/InvoiceHeaderEditor.vue
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/InvoiceHeaderEditor.vue')
-rw-r--r--src/components/InvoiceHeaderEditor.vue192
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>