Bugzilla – Attachment 189263 Details for
Bug 41214
Cash register should only show if UseCashRegisters sys pref is enabled
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 41214: Only show cash register if UseCashRegisters sys pref is enabled
Bug-41214-Only-show-cash-register-if-UseCashRegist.patch (text/plain), 20.66 KB, created by
Pedro Amorim
on 2025-11-07 11:13:32 UTC
(
hide
)
Description:
Bug 41214: Only show cash register if UseCashRegisters sys pref is enabled
Filename:
MIME Type:
Creator:
Pedro Amorim
Created:
2025-11-07 11:13:32 UTC
Size:
20.66 KB
patch
obsolete
>From 7fce063436e8ba1038278fe32e89dad5b4c18e2c Mon Sep 17 00:00:00 2001 >From: Pedro Amorim <pedro.amorim@openfifth.co.uk> >Date: Fri, 7 Nov 2025 10:24:44 +0000 >Subject: [PATCH] Bug 41214: Only show cash register if UseCashRegisters sys > pref is enabled > >Test plan: >1) Add a new account: >http://localhost:8081/cgi-bin/koha/sip2/accounts/add >2) Notice the 'cash register' field does not show >3) Enable UseCashRegisters sys pref >4) Repeat 1 (or edit an existing account). Refresh the page. >5) Notice the 'cash register' field now shows >--- > .../prog/js/vue/components/FormElement.vue | 380 +++++++++--------- > .../prog/js/vue/components/SIP2/Main.vue | 20 +- > .../components/SIP2/SIP2AccountResource.vue | 4 + > .../prog/js/vue/composables/base-resource.js | 1 + > .../intranet-tmpl/prog/js/vue/stores/sip2.js | 3 + > 5 files changed, 220 insertions(+), 188 deletions(-) > >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/FormElement.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/FormElement.vue >index fbdec2a7648..023ff9772a6 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/FormElement.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/FormElement.vue >@@ -1,198 +1,202 @@ > <template> >- <label >- v-if="attr.label" >- :for="getElementId" >- :class="{ required: attr.required }" >- :style="{ ...attr.style }" >- >{{ attr.label }}:</label >- > >- <template v-if="attr.type == 'number'"> >- <InputNumber >- :id="getElementId" >- v-model="resource[attr.name]" >- :placeholder="attr.placeholder || attr.label" >- :required="attr.required ? true : false" >- :size="attr.size" >- :maxlength="attr.maxlength" >- :disabled="disabled" >- @update:modelValue="checkForInputError()" >- /> >- </template> >- <template v-else-if="attr.type == 'text'"> >- <InputText >- :id="getElementId" >- v-model="resource[attr.name]" >- :placeholder="attr.placeholder || attr.label" >- :required="attr.required ? true : false" >- :disabled="disabled" >- @update:modelValue="checkForInputError()" >- /> >- </template> >- <template v-else-if="attr.type == 'textarea'"> >- <TextArea >- :id="getElementId" >- v-model="resource[attr.name]" >- :rows="attr.textAreaRows" >- :cols="attr.textAreaCols" >- :placeholder="attr.placeholder || attr.label" >- :required="attr.required ? true : false" >- :disabled="disabled" >- @update:modelValue="checkForInputError()" >- /> >- </template> >- <template v-else-if="attr.type == 'checkbox'"> >- <InputCheckbox >- :id="getElementId" >- type="checkbox" >- v-model="resource[attr.name]" >- :changeMethod="attr.onChange && attr.onChange.bind(this, resource)" >- :disabled="disabled" >- /> >- </template> >- <template v-else-if="attr.type == 'radio'"> >- <template >- v-for="(option, index) in attr.options" >- :key="`radio-option-${index}`" >+ <template v-if="display"> >+ <label >+ v-if="attr.label" >+ :for="getElementId" >+ :class="{ required: attr.required }" >+ :style="{ ...attr.style }" >+ >{{ attr.label }}:</label > > >- <label >- v-if="option.description" >- :for="attr.name + '_' + option.value" >- >{{ option.description }}: >+ <template v-if="attr.type == 'number'"> >+ <InputNumber >+ :id="getElementId" >+ v-model="resource[attr.name]" >+ :placeholder="attr.placeholder || attr.label" >+ :required="attr.required ? true : false" >+ :size="attr.size" >+ :maxlength="attr.maxlength" >+ :disabled="disabled" >+ @update:modelValue="checkForInputError()" >+ /> >+ </template> >+ <template v-else-if="attr.type == 'text'"> >+ <InputText >+ :id="getElementId" >+ v-model="resource[attr.name]" >+ :placeholder="attr.placeholder || attr.label" >+ :required="attr.required ? true : false" >+ :disabled="disabled" >+ @update:modelValue="checkForInputError()" >+ /> >+ </template> >+ <template v-else-if="attr.type == 'textarea'"> >+ <TextArea >+ :id="getElementId" >+ v-model="resource[attr.name]" >+ :rows="attr.textAreaRows" >+ :cols="attr.textAreaCols" >+ :placeholder="attr.placeholder || attr.label" >+ :required="attr.required ? true : false" >+ :disabled="disabled" >+ @update:modelValue="checkForInputError()" >+ /> >+ </template> >+ <template v-else-if="attr.type == 'checkbox'"> >+ <InputCheckbox >+ :id="getElementId" >+ type="checkbox" >+ v-model="resource[attr.name]" >+ :changeMethod=" >+ attr.onChange && attr.onChange.bind(this, resource) >+ " >+ :disabled="disabled" >+ /> >+ </template> >+ <template v-else-if="attr.type == 'radio'"> >+ <template >+ v-for="(option, index) in attr.options" >+ :key="`radio-option-${index}`" >+ > >+ <label >+ v-if="option.description" >+ :for="attr.name + '_' + option.value" >+ >{{ option.description }}: >+ <InputRadio >+ :name="attr.name" >+ :id="attr.name + '_' + option.value" >+ :value="option.value" >+ :checked=" >+ (!Object.keys(resource).includes(attr.name) && >+ attr.default == option.value) || >+ (Object.keys(resource).includes(attr.name) && >+ option.value == resource[attr.name]) >+ " >+ v-model="resource[attr.name]" >+ @change=" >+ attr.onChange && attr.onChange.bind(this, resource) >+ " >+ /> >+ </label> >+ </template> >+ </template> >+ <template v-else-if="attr.type == 'boolean'"> >+ <label class="radio" :for="getElementId + '_yes'" >+ >{{ $__("Yes") }}: >+ <InputRadio >+ type="radio" >+ :name="attr.name" >+ :id="attr.name + '_yes'" >+ :value="true" >+ :checked="resource[attr.name] == true" >+ v-model="resource[attr.name]" >+ /> >+ </label> >+ <label class="radio" :for="getElementId + '_no'" >+ >{{ $__("No") }}: > <InputRadio >+ type="radio" > :name="attr.name" >- :id="attr.name + '_' + option.value" >- :value="option.value" >- :checked=" >- (!Object.keys(resource).includes(attr.name) && >- attr.default == option.value) || >- (Object.keys(resource).includes(attr.name) && >- option.value == resource[attr.name]) >- " >+ :id="attr.name + '_no'" >+ :checked="resource[attr.name] == false" >+ :value="false" > v-model="resource[attr.name]" >- @change=" >- attr.onChange && attr.onChange.bind(this, resource) >- " > /> > </label> > </template> >- </template> >- <template v-else-if="attr.type == 'boolean'"> >- <label class="radio" :for="getElementId + '_yes'" >- >{{ $__("Yes") }}: >- <InputRadio >- type="radio" >- :name="attr.name" >- :id="attr.name + '_yes'" >- :value="true" >- :checked="resource[attr.name] == true" >+ <template v-else-if="attr.type == 'select'"> >+ <v-select >+ :id="getElementId" > v-model="resource[attr.name]" >- /> >- </label> >- <label class="radio" :for="getElementId + '_no'" >- >{{ $__("No") }}: >- <InputRadio >- type="radio" >- :name="attr.name" >- :id="attr.name + '_no'" >- :checked="resource[attr.name] == false" >- :value="false" >+ :label="attr.selectLabel" >+ :reduce="av => selectRequiredKey(av)" >+ :options="selectOptions" >+ :required="!resource[attr.name] && attr.required" >+ :disabled="disabled" >+ :multiple="attr.allowMultipleChoices" >+ @option:selected="attr.onSelected && attr.onSelected(resource)" >+ > >+ <template v-if="attr.required" #search="{ attributes, events }"> >+ <input >+ :required="!resource[attr.name]" >+ class="vs__search" >+ v-bind="attributes" >+ v-on="events" >+ /> >+ </template> >+ </v-select> >+ </template> >+ <template v-else-if="attr.type == 'vendor'"> >+ <component >+ :is="requiredComponent" >+ :id="getElementId" >+ v-bind="getComponentProps()" >+ v-on="getEventHandlers()" > v-model="resource[attr.name]" >- /> >- </label> >- </template> >- <template v-else-if="attr.type == 'select'"> >- <v-select >- :id="getElementId" >- v-model="resource[attr.name]" >- :label="attr.selectLabel" >- :reduce="av => selectRequiredKey(av)" >- :options="selectOptions" >- :required="!resource[attr.name] && attr.required" >- :disabled="disabled" >- :multiple="attr.allowMultipleChoices" >- @option:selected="attr.onSelected && attr.onSelected(resource)" >+ ></component> >+ </template> >+ <template v-else-if="attr.type == 'date'"> >+ <component >+ :is="requiredComponent" >+ :id="getElementId" >+ v-bind="getComponentProps()" >+ v-on="getEventHandlers()" >+ v-model="resource[attr.name]" >+ ></component> >+ </template> >+ <template v-else-if="attr.type == 'component' && attr.componentPath"> >+ <component >+ v-if="isVModelRequired(attr.componentPath)" >+ :is="requiredComponent" >+ v-bind="getComponentProps()" >+ v-model="resource[attr.name]" >+ v-on="getEventHandlers()" >+ ></component> >+ <component >+ v-else >+ :is="requiredComponent" >+ v-bind="getComponentProps()" >+ v-on="getEventHandlers()" >+ ></component> >+ </template> >+ <template >+ v-else-if="attr.type == 'relationshipWidget' && attr.componentProps" > > >- <template v-if="attr.required" #search="{ attributes, events }"> >- <input >- :required="!resource[attr.name]" >- class="vs__search" >- v-bind="attributes" >- v-on="events" >- /> >- </template> >- </v-select> >- </template> >- <template v-else-if="attr.type == 'vendor'"> >- <component >- :is="requiredComponent" >- :id="getElementId" >- v-bind="getComponentProps()" >- v-on="getEventHandlers()" >- v-model="resource[attr.name]" >- ></component> >- </template> >- <template v-else-if="attr.type == 'date'"> >- <component >- :is="requiredComponent" >- :id="getElementId" >- v-bind="getComponentProps()" >- v-on="getEventHandlers()" >- v-model="resource[attr.name]" >- ></component> >- </template> >- <template v-else-if="attr.type == 'component' && attr.componentPath"> >- <component >- v-if="isVModelRequired(attr.componentPath)" >- :is="requiredComponent" >- v-bind="getComponentProps()" >- v-model="resource[attr.name]" >- v-on="getEventHandlers()" >- ></component> >- <component >- v-else >- :is="requiredComponent" >- v-bind="getComponentProps()" >- v-on="getEventHandlers()" >- ></component> >- </template> >- <template >- v-else-if="attr.type == 'relationshipWidget' && attr.componentProps" >- > >- <component >- :is="requiredComponent" >- :title="attr.group ? null : attr.label" >- :apiClient="attr.apiClient" >- :name="attr.name" >- v-bind="getComponentProps()" >- v-on="getEventHandlers()" >- ></component> >- </template> >- <template v-else-if="attr.type == 'relationshipSelect'"> >- <FormRelationshipSelect >- v-bind="attr" >- :resource="resource" >- ></FormRelationshipSelect> >- </template> >- <template v-else-if="attr.type == 'additional_fields'"> >- <AdditionalFieldsEntry >- :resource="resource" >- :additional_field_values="resource.extended_attributes" >- :extended_attributes_resource_type=" >- attr.extended_attributes_resource_type >- " >- @additional-fields-changed="additionalFieldsChanged" >- ></AdditionalFieldsEntry> >- </template> >- <template v-else> >- <span>{{ >- $__("Programming error: unknown type %s").format(attr.type) >- }}</span> >+ <component >+ :is="requiredComponent" >+ :title="attr.group ? null : attr.label" >+ :apiClient="attr.apiClient" >+ :name="attr.name" >+ v-bind="getComponentProps()" >+ v-on="getEventHandlers()" >+ ></component> >+ </template> >+ <template v-else-if="attr.type == 'relationshipSelect'"> >+ <FormRelationshipSelect >+ v-bind="attr" >+ :resource="resource" >+ ></FormRelationshipSelect> >+ </template> >+ <template v-else-if="attr.type == 'additional_fields'"> >+ <AdditionalFieldsEntry >+ :resource="resource" >+ :additional_field_values="resource.extended_attributes" >+ :extended_attributes_resource_type=" >+ attr.extended_attributes_resource_type >+ " >+ @additional-fields-changed="additionalFieldsChanged" >+ ></AdditionalFieldsEntry> >+ </template> >+ <template v-else> >+ <span>{{ >+ $__("Programming error: unknown type %s").format(attr.type) >+ }}</span> >+ </template> >+ <ToolTip v-if="attr.toolTip" :toolTip="attr.toolTip"></ToolTip> >+ <span v-if="attr.required" class="required">{{ $__("Required") }}</span> >+ <span style="margin-left: 5px" class="error" v-if="fieldInputError"> >+ {{ attr.formErrorMessage }} >+ </span> > </template> >- <ToolTip v-if="attr.toolTip" :toolTip="attr.toolTip"></ToolTip> >- <span v-if="attr.required" class="required">{{ $__("Required") }}</span> >- <span style="margin-left: 5px" class="error" v-if="fieldInputError"> >- {{ attr.formErrorMessage }} >- </span> > </template> > > <script> >@@ -273,7 +277,14 @@ export default { > return disabledAttr || false; > } > }); >- >+ const display = computed(() => { >+ const displayAttr = props.display ?? props.attr.display ?? true; >+ if (typeof displayAttr === "function") { >+ return displayAttr(props.resource); >+ } else { >+ return displayAttr || false; >+ } >+ }); > const fieldInputError = ref(false); > const checkForInputError = () => { > if (props.attr.formErrorHandler) { >@@ -292,6 +303,7 @@ export default { > requiredComponent, > selectOptions, > disabled, >+ display, > fieldInputError, > checkForInputError, > }; >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/SIP2/Main.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/SIP2/Main.vue >index 271c33715ee..efaf3cbd86c 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/SIP2/Main.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/SIP2/Main.vue >@@ -26,13 +26,14 @@ import Breadcrumbs from "../Breadcrumbs.vue"; > import { storeToRefs } from "pinia"; > import Help from "../Help.vue"; > import LeftMenu from "../LeftMenu.vue"; >+import { APIClient } from "../../fetch/api-client.js"; > import Dialog from "../Dialog.vue"; > import "vue-select/dist/vue-select.css"; > > export default { > setup() { > const SIP2Store = inject("SIP2Store"); >- const { authorisedValues } = storeToRefs(SIP2Store); >+ const { sysprefs, authorisedValues } = storeToRefs(SIP2Store); > const { loadAuthorisedValues } = SIP2Store; > > const mainStore = inject("mainStore"); >@@ -43,9 +44,20 @@ export default { > > onBeforeMount(() => { > loading(); >- loadAuthorisedValues(authorisedValues.value, SIP2Store).then(() => { >- loaded(); >- initialized.value = true; >+ const fetchAuthorised = () => { >+ return loadAuthorisedValues( >+ authorisedValues.value, >+ SIP2Store >+ ).then(() => { >+ loaded(); >+ initialized.value = true; >+ }); >+ }; >+ >+ const client = APIClient.sysprefs; >+ return client.sysprefs.get("UseCashRegisters").then(result => { >+ sysprefs.value.UseCashRegisters = result.value; >+ return fetchAuthorised(); > }); > }); > >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/SIP2/SIP2AccountResource.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/SIP2/SIP2AccountResource.vue >index 99c7dfea2ac..e4e0742c8ab 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/SIP2/SIP2AccountResource.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/SIP2/SIP2AccountResource.vue >@@ -20,6 +20,9 @@ export default { > }, > emits: ["select-resource"], > setup(props) { >+ const SIP2Store = inject("SIP2Store"); >+ const { sysprefs } = storeToRefs(SIP2Store); >+ > const explodeValues = (value, delimiter) => { > if (!value) return null; > return Array.isArray(value) ? value : value.split(delimiter); >@@ -420,6 +423,7 @@ export default { > relationshipOptionLabelAttr: "name", // attr of the related resource used for display > relationshipRequiredKey: "cash_register_id", > hideIn: ["List"], >+ display: account => sysprefs.value.UseCashRegisters == 1, > group: "Details", > toolTip: __( > "Only required if system preference UseCashRegisters is enabled" >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/composables/base-resource.js b/koha-tmpl/intranet-tmpl/prog/js/vue/composables/base-resource.js >index df7a2244be8..aa9cad84059 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/composables/base-resource.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/composables/base-resource.js >@@ -1,6 +1,7 @@ > import { computed, inject, ref } from "vue"; > import { useRoute, useRouter } from "vue-router"; > import { build_url } from "../composables/datatables"; >+import { isRef } from "vue"; > import { storeToRefs } from "pinia"; > import { > $__, >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/sip2.js b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/sip2.js >index c06f5d72fbc..11630134052 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/sip2.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/sip2.js >@@ -4,6 +4,9 @@ import { withAuthorisedValueActions } from "../composables/authorisedValues"; > > export const useSIP2Store = defineStore("sip2", () => { > const store = reactive({ >+ sysprefs: { >+ UseCashRegisters: 0, >+ }, > authorisedValues: { > av_lost: "LOST", > }, >-- >2.39.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 41214
: 189263 |
189322