mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-04-07 13:41:23 +00:00
Invoice time support (#269)
* Changed invoice date to datetime * Fixed code style errors * Update TimeFormatsController.php * Update TimeFormatter.php * Update TimeFormatsController namespace * Fix missing comma in language file * Fix formatting --------- Co-authored-by: troky <troky2001@yahoo.com>
This commit is contained in:
committed by
GitHub
parent
32e03b98a3
commit
f52b73f517
20
resources/scripts/admin/stores/global.js
vendored
20
resources/scripts/admin/stores/global.js
vendored
@@ -21,6 +21,7 @@ export const useGlobalStore = (useWindow = false) => {
|
||||
// Global Lists
|
||||
timeZones: [],
|
||||
dateFormats: [],
|
||||
timeFormats: [],
|
||||
currencies: [],
|
||||
countries: [],
|
||||
languages: [],
|
||||
@@ -156,6 +157,25 @@ export const useGlobalStore = (useWindow = false) => {
|
||||
})
|
||||
},
|
||||
|
||||
fetchTimeFormats() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.timeFormats.length) {
|
||||
resolve(this.timeFormats)
|
||||
} else {
|
||||
axios
|
||||
.get('/api/v1/time/formats')
|
||||
.then((response) => {
|
||||
this.timeFormats = response.data.time_formats
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
fetchTimeZones() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.timeZones.length) {
|
||||
|
||||
8
resources/scripts/admin/stores/invoice.js
vendored
8
resources/scripts/admin/stores/invoice.js
vendored
@@ -499,7 +499,13 @@ export const useInvoiceStore = (useWindow = false) => {
|
||||
this.newInvoice.sales_tax_address_type = companyStore.selectedCompanySettings.sales_tax_address_type
|
||||
this.newInvoice.discount_per_item =
|
||||
companyStore.selectedCompanySettings.discount_per_item
|
||||
this.newInvoice.invoice_date = moment().format('YYYY-MM-DD')
|
||||
|
||||
let dateFormat = 'YYYY-MM-DD';
|
||||
if (companyStore.selectedCompanySettings.invoice_use_time === 'YES') {
|
||||
dateFormat += ' HH:mm'
|
||||
}
|
||||
|
||||
this.newInvoice.invoice_date = moment().format(dateFormat)
|
||||
if (companyStore.selectedCompanySettings.invoice_set_due_date_automatically === 'YES') {
|
||||
this.newInvoice.due_date = moment()
|
||||
.add(companyStore.selectedCompanySettings.invoice_due_date_days, 'days')
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
:content-loading="isLoading"
|
||||
:calendar-button="true"
|
||||
calendar-button-icon="calendar"
|
||||
:enableTime="enableTime"
|
||||
:time24hr="time24h"
|
||||
/>
|
||||
</BaseInputGroup>
|
||||
|
||||
@@ -61,8 +63,10 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import ExchangeRateConverter from '@/scripts/admin/components/estimate-invoice-common/ExchangeRateConverter.vue'
|
||||
import { useInvoiceStore } from '@/scripts/admin/stores/invoice'
|
||||
import { useCompanyStore } from '@/scripts/admin/stores/company'
|
||||
|
||||
const props = defineProps({
|
||||
v: {
|
||||
@@ -80,4 +84,17 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const invoiceStore = useInvoiceStore()
|
||||
const companyStore = useCompanyStore()
|
||||
|
||||
const enableTime = computed(() => {
|
||||
return (
|
||||
companyStore.selectedCompanySettings.invoice_use_time === 'YES'
|
||||
);
|
||||
})
|
||||
const time24h = computed(() => {
|
||||
return (
|
||||
companyStore.selectedCompanySettings.carbon_time_format.indexOf('H') > -1
|
||||
);
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
@@ -80,10 +80,11 @@
|
||||
label="display_date"
|
||||
value-prop="carbon_format_value"
|
||||
track-by="display_date"
|
||||
searchable
|
||||
:searchable="true"
|
||||
:invalid="v$.carbon_date_format.$error"
|
||||
class="w-full"
|
||||
/>
|
||||
|
||||
</BaseInputGroup>
|
||||
|
||||
<BaseInputGroup
|
||||
@@ -104,8 +105,36 @@
|
||||
class="w-full"
|
||||
/>
|
||||
</BaseInputGroup>
|
||||
|
||||
<BaseInputGroup
|
||||
:label="$t('settings.preferences.time_format')"
|
||||
:content-loading="isFetchingInitialData"
|
||||
:error="
|
||||
v$.carbon_time_format.$error &&
|
||||
v$.carbon_time_format.$errors[0].$message
|
||||
"
|
||||
required
|
||||
>
|
||||
<BaseMultiselect
|
||||
v-model="settingsForm.carbon_time_format"
|
||||
:content-loading="isFetchingInitialData"
|
||||
:options="globalStore.timeFormats"
|
||||
label="display_time"
|
||||
value-prop="carbon_format_value"
|
||||
track-by="display_time"
|
||||
:searchable="true"
|
||||
:invalid="v$.carbon_time_format.$error"
|
||||
class="w-full"
|
||||
/>
|
||||
</BaseInputGroup>
|
||||
</BaseInputGrid>
|
||||
|
||||
<BaseSwitchSection
|
||||
v-model="invoiceUseTimeField"
|
||||
:title="$t('settings.preferences.invoice_use_time')"
|
||||
:description="$t('settings.preferences.invoice_use_time_description')"
|
||||
/>
|
||||
|
||||
<BaseButton
|
||||
:content-loading="isFetchingInitialData"
|
||||
:disabled="isSaving"
|
||||
@@ -218,6 +247,33 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => settingsForm.carbon_time_format,
|
||||
(val) => {
|
||||
if (val) {
|
||||
const timeFormatObject = globalStore.timeFormats.find((d) => {
|
||||
return d.carbon_format_value === val
|
||||
})
|
||||
settingsForm.moment_time_format = timeFormatObject.moment_format_value
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const invoiceUseTimeField = computed({
|
||||
get: () => {
|
||||
return settingsForm.invoice_use_time === 'YES'
|
||||
},
|
||||
set: async (newValue) => {
|
||||
const value = newValue ? 'YES' : 'NO'
|
||||
let data = {
|
||||
settings: {
|
||||
invoice_use_time: value,
|
||||
},
|
||||
}
|
||||
settingsForm.invoice_use_time = value
|
||||
}
|
||||
})
|
||||
|
||||
const discountPerItemField = computed({
|
||||
get: () => {
|
||||
return settingsForm.discount_per_item === 'YES'
|
||||
@@ -271,12 +327,21 @@ const rules = computed(() => {
|
||||
moment_date_format: {
|
||||
required: helpers.withMessage(t('validation.required'), required),
|
||||
},
|
||||
carbon_time_format: {
|
||||
required: helpers.withMessage(t('validation.required'), required),
|
||||
},
|
||||
moment_time_format: {
|
||||
required: helpers.withMessage(t('validation.required'), required),
|
||||
},
|
||||
time_zone: {
|
||||
required: helpers.withMessage(t('validation.required'), required),
|
||||
},
|
||||
fiscal_year: {
|
||||
required: helpers.withMessage(t('validation.required'), required),
|
||||
},
|
||||
invoice_use_time: {
|
||||
required: helpers.withMessage(t('validation.required'), required),
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
@@ -292,6 +357,7 @@ async function setInitialData() {
|
||||
Promise.all([
|
||||
globalStore.fetchCurrencies(),
|
||||
globalStore.fetchDateFormats(),
|
||||
globalStore.fetchTimeFormats(),
|
||||
globalStore.fetchTimeZones(),
|
||||
]).then(([res1]) => {
|
||||
isFetchingInitialData.value = false
|
||||
|
||||
@@ -254,6 +254,14 @@ const carbonFormat = computed(() => {
|
||||
return companyStore.selectedCompanySettings?.carbon_date_format
|
||||
})
|
||||
|
||||
const carbonFormatWithTime = computed(() => {
|
||||
let format = companyStore.selectedCompanySettings?.carbon_date_format
|
||||
if (companyStore.selectedCompanySettings?.invoice_use_time === 'YES') {
|
||||
format += ' ' + companyStore.selectedCompanySettings?.carbon_time_format
|
||||
}
|
||||
return format.replace("g", "h").replace("a", "K");
|
||||
})
|
||||
|
||||
const hasIconSlot = computed(() => {
|
||||
return !!slots.icon
|
||||
})
|
||||
@@ -301,7 +309,7 @@ watch(
|
||||
config.altFormat = carbonFormat.value ? carbonFormat.value : 'd M Y'
|
||||
} else {
|
||||
config.altFormat = carbonFormat.value
|
||||
? `${carbonFormat.value} H:i `
|
||||
? `${carbonFormatWithTime.value}`
|
||||
: 'd M Y H:i'
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user