mirror of
https://github.com/frappe/books.git
synced 2024-12-22 10:58:59 +00:00
Merge pull request #1040 from AbleKSaju/shortcuts
feat: shortcuts in POS
This commit is contained in:
commit
81aac9c0e2
@ -107,6 +107,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
showQuickView: false,
|
showQuickView: false,
|
||||||
linkValue: '',
|
linkValue: '',
|
||||||
|
focInp: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
suggestions: [],
|
suggestions: [],
|
||||||
highlightedIndex: -1,
|
highlightedIndex: -1,
|
||||||
@ -187,6 +188,15 @@ export default {
|
|||||||
const route = getFormRoute(this.linkSchemaName, name);
|
const route = getFormRoute(this.linkSchemaName, name);
|
||||||
await routeTo(route);
|
await routeTo(route);
|
||||||
},
|
},
|
||||||
|
async focusInputTag() {
|
||||||
|
this.focInp = true;
|
||||||
|
if (this.linkValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.$nextTick();
|
||||||
|
this.$refs.input.focus();
|
||||||
|
},
|
||||||
setLinkValue(value) {
|
setLinkValue(value) {
|
||||||
this.linkValue = value;
|
this.linkValue = value;
|
||||||
},
|
},
|
||||||
@ -282,6 +292,14 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!e.target.value || this.focInp) {
|
||||||
|
e.target.value = null;
|
||||||
|
this.focInp = false;
|
||||||
|
this.toggleDropdown(false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.toggleDropdown(true);
|
this.toggleDropdown(true);
|
||||||
this.updateSuggestions(e.target.value);
|
this.updateSuggestions(e.target.value);
|
||||||
},
|
},
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
@blur="onBlur"
|
@blur="onBlur"
|
||||||
@focus="(e) => !isReadOnly && $emit('focus', e)"
|
@focus="(e) => !isReadOnly && $emit('focus', e)"
|
||||||
@input="(e) => !isReadOnly && $emit('input', e)"
|
@input="(e) => !isReadOnly && $emit('input', e)"
|
||||||
|
@keydown.enter="setLoyaltyPoints"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -49,6 +50,7 @@ export default defineComponent({
|
|||||||
border: { type: Boolean, default: false },
|
border: { type: Boolean, default: false },
|
||||||
size: { type: String, default: 'large' },
|
size: { type: String, default: 'large' },
|
||||||
placeholder: String,
|
placeholder: String,
|
||||||
|
focusInput: Boolean,
|
||||||
showLabel: { type: Boolean, default: false },
|
showLabel: { type: Boolean, default: false },
|
||||||
containerStyles: { type: Object, default: () => ({}) },
|
containerStyles: { type: Object, default: () => ({}) },
|
||||||
textRight: {
|
textRight: {
|
||||||
@ -64,6 +66,15 @@ export default defineComponent({
|
|||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
async created() {
|
||||||
|
if (this.focusInput) {
|
||||||
|
await this.$nextTick();
|
||||||
|
(this.$refs.input as HTMLInputElement).focus();
|
||||||
|
if (this.value == 0) {
|
||||||
|
this.triggerChange('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
emits: ['focus', 'input', 'change'],
|
emits: ['focus', 'input', 'change'],
|
||||||
computed: {
|
computed: {
|
||||||
doc(): Doc | undefined {
|
doc(): Doc | undefined {
|
||||||
@ -191,6 +202,12 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
setLoyaltyPoints() {
|
||||||
|
const inputElement = this.$refs.input as HTMLInputElement;
|
||||||
|
if (inputElement && inputElement?.value) {
|
||||||
|
this.$emit('change', inputElement.value);
|
||||||
|
}
|
||||||
|
},
|
||||||
onBlur(e: FocusEvent) {
|
onBlur(e: FocusEvent) {
|
||||||
const target = e.target;
|
const target = e.target;
|
||||||
if (!(target instanceof HTMLInputElement)) {
|
if (!(target instanceof HTMLInputElement)) {
|
||||||
@ -227,7 +244,7 @@ export default defineComponent({
|
|||||||
triggerChange(value: unknown): void {
|
triggerChange(value: unknown): void {
|
||||||
value = this.parse(value);
|
value = this.parse(value);
|
||||||
|
|
||||||
if (value === '') {
|
if (value === '' || value == 0) {
|
||||||
value = null;
|
value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,14 @@ export default {
|
|||||||
this.setLinkValue();
|
this.setLinkValue();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
focusInput: Boolean,
|
||||||
|
},
|
||||||
|
async created() {
|
||||||
|
if (this.focusInput) {
|
||||||
|
this.focusInputTag();
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async setLinkValue(newValue, isInput) {
|
async setLinkValue(newValue, isInput) {
|
||||||
if (isInput) {
|
if (isInput) {
|
||||||
|
@ -8,15 +8,18 @@ export type ItemSerialNumbers = { [item: string]: string };
|
|||||||
|
|
||||||
export type DiscountType = 'percent' | 'amount';
|
export type DiscountType = 'percent' | 'amount';
|
||||||
|
|
||||||
export type ModalName =
|
export const modalNames = [
|
||||||
| 'Keyboard'
|
'Keyboard',
|
||||||
| 'Payment'
|
'Payment',
|
||||||
| 'ShiftClose'
|
'ShiftClose',
|
||||||
| 'LoyaltyProgram'
|
'LoyaltyProgram',
|
||||||
| 'SavedInvoice'
|
'SavedInvoice',
|
||||||
| 'Alert'
|
'Alert',
|
||||||
| 'CouponCode'
|
'CouponCode',
|
||||||
| 'PriceList';
|
'PriceList',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type ModalName = typeof modalNames[number];
|
||||||
|
|
||||||
export type PosEmits =
|
export type PosEmits =
|
||||||
| 'addItem'
|
| 'addItem'
|
||||||
|
@ -191,6 +191,49 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: t`Point of Sale`,
|
||||||
|
description: t`Applicable when POS is open`,
|
||||||
|
collapsed: false,
|
||||||
|
shortcuts: [
|
||||||
|
{
|
||||||
|
shortcut: [ShortcutKey.shift, 'V'],
|
||||||
|
description: t`Toggle between Grid and List view`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [ShortcutKey.shift, 'S'],
|
||||||
|
description: t`Open Sales Invoice List`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [ShortcutKey.shift, 'L'],
|
||||||
|
description: t`Set Loyalty Program`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [ShortcutKey.shift, 'C'],
|
||||||
|
description: t`Set Coupon Code`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [ShortcutKey.shift, 'P'],
|
||||||
|
description: t`Set Price List`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [ShortcutKey.pmod, ShortcutKey.shift, 'H'],
|
||||||
|
description: t`Open Saved or Submitted Invoice List.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [ShortcutKey.pmod, ShortcutKey.shift, 'S'],
|
||||||
|
description: t`If any entry form is open, save the details. Otherwise, save the invoice.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [ShortcutKey.pmod, ShortcutKey.shift, 'P'],
|
||||||
|
description: t`Create Payment.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [ShortcutKey.pmod, ShortcutKey.shift, ShortcutKey.delete],
|
||||||
|
description: t`If any entry form is open, your entry will be canceled. Otherwise the selected items will be removed.`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
:show-label="true"
|
:show-label="true"
|
||||||
:border="true"
|
:border="true"
|
||||||
:value="couponCode"
|
:value="couponCode"
|
||||||
|
:focus-input="true"
|
||||||
:df="coupons.fieldMap.coupons"
|
:df="coupons.fieldMap.coupons"
|
||||||
@change="updateCouponCode"
|
@change="updateCouponCode"
|
||||||
/>
|
/>
|
||||||
@ -161,15 +162,18 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateCouponCode(value: string) {
|
async updateCouponCode(value: string | Event) {
|
||||||
(this.validationError = false), (this.couponCode = value);
|
|
||||||
},
|
|
||||||
async setCouponCode() {
|
|
||||||
try {
|
try {
|
||||||
if (!this.couponCode) {
|
if (!value) {
|
||||||
throw new Error(t`Must be select a coupon code`);
|
return;
|
||||||
|
}
|
||||||
|
this.validationError = false;
|
||||||
|
|
||||||
|
if ((value as Event).type === 'keydown') {
|
||||||
|
value = ((value as Event).target as HTMLInputElement).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.couponCode = value as string;
|
||||||
const appliedCouponCodes = this.fyo.doc.getNewDoc(
|
const appliedCouponCodes = this.fyo.doc.getNewDoc(
|
||||||
ModelNameEnum.AppliedCouponCodes
|
ModelNameEnum.AppliedCouponCodes
|
||||||
);
|
);
|
||||||
@ -183,8 +187,6 @@ export default defineComponent({
|
|||||||
await this.sinvDoc.append('coupons', { coupons: this.couponCode });
|
await this.sinvDoc.append('coupons', { coupons: this.couponCode });
|
||||||
|
|
||||||
this.$emit('applyPricingRule');
|
this.$emit('applyPricingRule');
|
||||||
this.$emit('toggleModal', 'CouponCode');
|
|
||||||
|
|
||||||
this.couponCode = '';
|
this.couponCode = '';
|
||||||
this.validationError = false;
|
this.validationError = false;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -196,6 +198,9 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setCouponCode() {
|
||||||
|
this.$emit('toggleModal', 'CouponCode');
|
||||||
|
},
|
||||||
async removeAppliedCoupon(coupon: AppliedCouponCodes) {
|
async removeAppliedCoupon(coupon: AppliedCouponCodes) {
|
||||||
this.sinvDoc?.items?.map((item: InvoiceItem) => {
|
this.sinvDoc?.items?.map((item: InvoiceItem) => {
|
||||||
item.itemDiscountAmount = this.fyo.pesa(0);
|
item.itemDiscountAmount = this.fyo.pesa(0);
|
||||||
|
@ -20,13 +20,15 @@
|
|||||||
<p>{{ loyaltyPoints }}</p>
|
<p>{{ loyaltyPoints }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Data
|
<Int
|
||||||
v-if="sinvDoc.fieldMap"
|
v-if="sinvDoc.fieldMap"
|
||||||
class="flex-shrink-0 px-10 pb-10"
|
class="flex-shrink-0 px-10 pb-10"
|
||||||
:show-label="true"
|
:show-label="true"
|
||||||
:border="true"
|
:border="true"
|
||||||
|
:focus-input="true"
|
||||||
:value="sinvDoc.loyaltyPoints"
|
:value="sinvDoc.loyaltyPoints"
|
||||||
:df="sinvDoc.fieldMap.loyaltyPoints"
|
:df="sinvDoc.fieldMap.loyaltyPoints"
|
||||||
|
@keydown.enter="setLoyaltyPoints"
|
||||||
@change="updateLoyaltyPoints"
|
@change="updateLoyaltyPoints"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -52,7 +54,7 @@
|
|||||||
<Button
|
<Button
|
||||||
class="w-full bg-red-500 dark:bg-red-700"
|
class="w-full bg-red-500 dark:bg-red-700"
|
||||||
style="padding: 1.35rem"
|
style="padding: 1.35rem"
|
||||||
@click="$emit('toggleModal', 'LoyaltyProgram')"
|
@click="cancelLoyaltyProgram"
|
||||||
>
|
>
|
||||||
<slot>
|
<slot>
|
||||||
<p class="uppercase text-lg text-white font-semibold">
|
<p class="uppercase text-lg text-white font-semibold">
|
||||||
@ -67,20 +69,20 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Button from 'src/components/Button.vue';
|
import Button from 'src/components/Button.vue';
|
||||||
import Data from 'src/components/Controls/Data.vue';
|
|
||||||
import Modal from 'src/components/Modal.vue';
|
import Modal from 'src/components/Modal.vue';
|
||||||
import { SalesInvoice } from 'models/baseModels/SalesInvoice/SalesInvoice';
|
import { SalesInvoice } from 'models/baseModels/SalesInvoice/SalesInvoice';
|
||||||
import { defineComponent, inject } from 'vue';
|
import { defineComponent, inject } from 'vue';
|
||||||
import { t } from 'fyo';
|
import { t } from 'fyo';
|
||||||
import { showToast } from 'src/utils/interactive';
|
import { showToast } from 'src/utils/interactive';
|
||||||
import { ModelNameEnum } from 'models/types';
|
import { ModelNameEnum } from 'models/types';
|
||||||
|
import Int from 'src/components/Controls/Int.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'LoyaltyProgramModal',
|
name: 'LoyaltyProgramModal',
|
||||||
components: {
|
components: {
|
||||||
Modal,
|
Modal,
|
||||||
Button,
|
Button,
|
||||||
Data,
|
Int,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
loyaltyPoints: {
|
loyaltyPoints: {
|
||||||
@ -105,6 +107,14 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async keydownEnter(value: number) {
|
||||||
|
await this.updateLoyaltyPoints(value);
|
||||||
|
this.setLoyaltyPoints();
|
||||||
|
},
|
||||||
|
cancelLoyaltyProgram() {
|
||||||
|
this.$emit('setLoyaltyPoints', 0);
|
||||||
|
this.$emit('toggleModal', 'LoyaltyProgram');
|
||||||
|
},
|
||||||
async updateLoyaltyPoints(newValue: number) {
|
async updateLoyaltyPoints(newValue: number) {
|
||||||
try {
|
try {
|
||||||
const partyData = await this.fyo.db.get(
|
const partyData = await this.fyo.db.get(
|
||||||
@ -141,6 +151,12 @@ export default defineComponent({
|
|||||||
throw new Error(t`no need ${newValue} points to purchase this item`);
|
throw new Error(t`no need ${newValue} points to purchase this item`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newValue < 0) {
|
||||||
|
throw new Error(t`Points must be greater than 0`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('setLoyaltyPoints', this.sinvDoc.loyaltyPoints);
|
||||||
|
|
||||||
this.validationError = false;
|
this.validationError = false;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.validationError = true;
|
this.validationError = true;
|
||||||
@ -154,23 +170,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setLoyaltyPoints() {
|
setLoyaltyPoints() {
|
||||||
try {
|
this.$emit('toggleModal', 'LoyaltyProgram');
|
||||||
if (!this.sinvDoc.loyaltyPoints || this.sinvDoc.loyaltyPoints < 0) {
|
|
||||||
throw new Error(t`Points must be greater than 0`);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$emit('setLoyaltyPoints', this.sinvDoc.loyaltyPoints);
|
|
||||||
this.$emit('toggleModal', 'LoyaltyProgram');
|
|
||||||
|
|
||||||
this.validationError = false;
|
|
||||||
} catch (error) {
|
|
||||||
this.validationError = true;
|
|
||||||
|
|
||||||
showToast({
|
|
||||||
type: 'error',
|
|
||||||
message: t`${error as string}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -104,14 +104,15 @@ import ModernPOS from './ModernPOS.vue';
|
|||||||
import ClassicPOS from './ClassicPOS.vue';
|
import ClassicPOS from './ClassicPOS.vue';
|
||||||
import { ModelNameEnum } from 'models/types';
|
import { ModelNameEnum } from 'models/types';
|
||||||
import Button from 'src/components/Button.vue';
|
import Button from 'src/components/Button.vue';
|
||||||
import { computed, defineComponent } from 'vue';
|
|
||||||
import { showToast } from 'src/utils/interactive';
|
import { showToast } from 'src/utils/interactive';
|
||||||
import { Item } from 'models/baseModels/Item/Item';
|
import { Item } from 'models/baseModels/Item/Item';
|
||||||
import { ModalName } from 'src/components/POS/types';
|
|
||||||
import { Shipment } from 'models/inventory/Shipment';
|
import { Shipment } from 'models/inventory/Shipment';
|
||||||
import { routeTo, toggleSidebar } from 'src/utils/ui';
|
import { routeTo, toggleSidebar } from 'src/utils/ui';
|
||||||
|
import { shortcutsKey } from 'src/utils/injectionKeys';
|
||||||
import PageHeader from 'src/components/PageHeader.vue';
|
import PageHeader from 'src/components/PageHeader.vue';
|
||||||
|
import { computed, defineComponent, inject } from 'vue';
|
||||||
import { Payment } from 'models/baseModels/Payment/Payment';
|
import { Payment } from 'models/baseModels/Payment/Payment';
|
||||||
|
import { ModalName, modalNames } from 'src/components/POS/types';
|
||||||
import { InvoiceItem } from 'models/baseModels/InvoiceItem/InvoiceItem';
|
import { InvoiceItem } from 'models/baseModels/InvoiceItem/InvoiceItem';
|
||||||
import { SalesInvoice } from 'models/baseModels/SalesInvoice/SalesInvoice';
|
import { SalesInvoice } from 'models/baseModels/SalesInvoice/SalesInvoice';
|
||||||
import { SalesInvoiceItem } from 'models/baseModels/SalesInvoiceItem/SalesInvoiceItem';
|
import { SalesInvoiceItem } from 'models/baseModels/SalesInvoiceItem/SalesInvoiceItem';
|
||||||
@ -138,6 +139,8 @@ import {
|
|||||||
ItemSerialNumbers,
|
ItemSerialNumbers,
|
||||||
} from 'src/components/POS/types';
|
} from 'src/components/POS/types';
|
||||||
|
|
||||||
|
const COMPONENT_NAME = 'POS';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'POS',
|
name: 'POS',
|
||||||
components: {
|
components: {
|
||||||
@ -163,6 +166,11 @@ export default defineComponent({
|
|||||||
transferClearanceDate: computed(() => this.transferClearanceDate),
|
transferClearanceDate: computed(() => this.transferClearanceDate),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
shortcuts: inject(shortcutsKey),
|
||||||
|
};
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tableView: true,
|
tableView: true,
|
||||||
@ -242,10 +250,13 @@ export default defineComponent({
|
|||||||
this.setCouponCodeDoc();
|
this.setCouponCodeDoc();
|
||||||
this.setSinvDoc();
|
this.setSinvDoc();
|
||||||
this.setDefaultCustomer();
|
this.setDefaultCustomer();
|
||||||
|
this.setShortcuts();
|
||||||
|
|
||||||
await this.setItemQtyMap();
|
await this.setItemQtyMap();
|
||||||
await this.setItems();
|
await this.setItems();
|
||||||
},
|
},
|
||||||
deactivated() {
|
deactivated() {
|
||||||
|
this.shortcuts?.delete(COMPONENT_NAME);
|
||||||
toggleSidebar(true);
|
toggleSidebar(true);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -265,6 +276,74 @@ export default defineComponent({
|
|||||||
this.loyaltyProgram = party[0]?.loyaltyProgram as string;
|
this.loyaltyProgram = party[0]?.loyaltyProgram as string;
|
||||||
this.loyaltyPoints = party[0]?.loyaltyPoints as number;
|
this.loyaltyPoints = party[0]?.loyaltyPoints as number;
|
||||||
},
|
},
|
||||||
|
isModalOpen() {
|
||||||
|
for (const modal of modalNames) {
|
||||||
|
if (modal && this[`open${modal}Modal`]) {
|
||||||
|
this[`open${modal}Modal`] = false;
|
||||||
|
return `open${modal}Modal`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setShortcuts() {
|
||||||
|
this.shortcuts?.shift.set(COMPONENT_NAME, ['KeyS'], async () => {
|
||||||
|
await this.routeToSinvList();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.shortcuts?.shift.set(COMPONENT_NAME, ['KeyV'], () => {
|
||||||
|
this.toggleView();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.shortcuts?.shift.set(COMPONENT_NAME, ['KeyP'], () => {
|
||||||
|
this.toggleModal('PriceList');
|
||||||
|
});
|
||||||
|
|
||||||
|
this.shortcuts?.pmodShift.set(COMPONENT_NAME, ['KeyH'], () => {
|
||||||
|
this.toggleModal('SavedInvoice');
|
||||||
|
});
|
||||||
|
|
||||||
|
this.shortcuts?.pmodShift.set(COMPONENT_NAME, ['Backspace'], async () => {
|
||||||
|
const modalStatus = this.isModalOpen();
|
||||||
|
|
||||||
|
if (!modalStatus) {
|
||||||
|
await this.clearValues();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.shortcuts?.pmodShift.set(COMPONENT_NAME, ['KeyP'], () => {
|
||||||
|
if (!this.disablePayButton) {
|
||||||
|
this.toggleModal('Payment');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.shortcuts?.pmodShift.set(COMPONENT_NAME, ['KeyS'], async () => {
|
||||||
|
const modalStatus = this.isModalOpen();
|
||||||
|
|
||||||
|
if (!modalStatus && this.sinvDoc.party && this.sinvDoc.items?.length) {
|
||||||
|
await this.saveOrder();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.shortcuts?.shift.set(COMPONENT_NAME, ['KeyL'], () => {
|
||||||
|
if (
|
||||||
|
this.fyo.singles.AccountingSettings?.enablePriceList &&
|
||||||
|
this.loyaltyPoints &&
|
||||||
|
this.sinvDoc.party &&
|
||||||
|
this.sinvDoc.items?.length
|
||||||
|
) {
|
||||||
|
this.toggleModal('LoyaltyProgram', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.shortcuts?.shift.set(COMPONENT_NAME, ['KeyC'], () => {
|
||||||
|
if (
|
||||||
|
this.fyo.singles.AccountingSettings?.enableCouponCode &&
|
||||||
|
this.sinvDoc?.party &&
|
||||||
|
this.sinvDoc?.items?.length
|
||||||
|
) {
|
||||||
|
this.toggleModal('CouponCode');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
async saveOrder() {
|
async saveOrder() {
|
||||||
try {
|
try {
|
||||||
await this.validate();
|
await this.validate();
|
||||||
@ -482,6 +561,7 @@ export default defineComponent({
|
|||||||
await this.applyPricingRule();
|
await this.applyPricingRule();
|
||||||
await this.sinvDoc.runFormulas();
|
await this.sinvDoc.runFormulas();
|
||||||
},
|
},
|
||||||
|
|
||||||
async createTransaction(shouldPrint = false) {
|
async createTransaction(shouldPrint = false) {
|
||||||
try {
|
try {
|
||||||
await this.validate();
|
await this.validate();
|
||||||
@ -640,9 +720,10 @@ export default defineComponent({
|
|||||||
if (!hasPricingRules || !hasPricingRules.length) {
|
if (!hasPricingRules || !hasPricingRules.length) {
|
||||||
this.sinvDoc.pricingRuleDetail = undefined;
|
this.sinvDoc.pricingRuleDetail = undefined;
|
||||||
this.sinvDoc.isPricingRuleApplied = false;
|
this.sinvDoc.isPricingRuleApplied = false;
|
||||||
removeFreeItems(this.sinvDoc as SalesInvoice);
|
|
||||||
|
|
||||||
|
removeFreeItems(this.sinvDoc as SalesInvoice);
|
||||||
await this.sinvDoc.applyProductDiscount();
|
await this.sinvDoc.applyProductDiscount();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,9 +10,10 @@
|
|||||||
v-if="sinvDoc.fieldMap"
|
v-if="sinvDoc.fieldMap"
|
||||||
class="flex-shrink-0 w-full"
|
class="flex-shrink-0 w-full"
|
||||||
:border="true"
|
:border="true"
|
||||||
:value="priceList"
|
:value="sinvDoc?.priceList"
|
||||||
|
:focus-input="true"
|
||||||
:df="sinvDoc.fieldMap.priceList"
|
:df="sinvDoc.fieldMap.priceList"
|
||||||
@change="(value) => (priceList = value)"
|
@change="(value) => applyPriceList(value)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-10 flex justify-end items-center">
|
<div class="w-10 flex justify-end items-center">
|
||||||
@ -46,7 +47,7 @@
|
|||||||
<Button
|
<Button
|
||||||
class="w-full bg-red-500 dark:bg-red-700"
|
class="w-full bg-red-500 dark:bg-red-700"
|
||||||
style="padding: 1.35rem"
|
style="padding: 1.35rem"
|
||||||
@click="$emit('toggleModal', 'PriceList')"
|
@click="cancelPriceList"
|
||||||
>
|
>
|
||||||
<slot>
|
<slot>
|
||||||
<p class="uppercase text-lg text-white font-semibold">
|
<p class="uppercase text-lg text-white font-semibold">
|
||||||
@ -82,20 +83,17 @@ export default defineComponent({
|
|||||||
sinvDoc: inject('sinvDoc') as SalesInvoice,
|
sinvDoc: inject('sinvDoc') as SalesInvoice,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
priceList: '',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
async removePriceList() {
|
async removePriceList() {
|
||||||
this.priceList = '';
|
await this.sinvDoc.set('priceList', '');
|
||||||
await this.setPriceList();
|
|
||||||
},
|
},
|
||||||
async setPriceList() {
|
async applyPriceList(value?: string) {
|
||||||
try {
|
try {
|
||||||
await this.sinvDoc.set('priceList', this.priceList);
|
if (!value || value == this.sinvDoc.priceList) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.sinvDoc.set('priceList', value);
|
||||||
this.$emit('toggleModal', 'PriceList');
|
this.$emit('toggleModal', 'PriceList');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showToast({
|
showToast({
|
||||||
@ -104,6 +102,12 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
cancelPriceList() {
|
||||||
|
this.$emit('toggleModal', 'PriceList');
|
||||||
|
},
|
||||||
|
setPriceList() {
|
||||||
|
this.$emit('toggleModal', 'PriceList');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -224,6 +224,12 @@ export class Shortcuts {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get pmodShift() {
|
||||||
|
this.modMap['meta'] = true;
|
||||||
|
this.modMap['shift'] = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
get repeat() {
|
get repeat() {
|
||||||
this.modMap['repeat'] = true;
|
this.modMap['repeat'] = true;
|
||||||
return this;
|
return this;
|
||||||
|
Loading…
Reference in New Issue
Block a user