Skip to content

Commit

Permalink
Merge pull request #1036 from AbleKSaju/feat-pricelist
Browse files Browse the repository at this point in the history
feat: PriceList functionality in POS
  • Loading branch information
akshayitzme authored Nov 29, 2024
2 parents 97a639e + 72839d9 commit 08284b7
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 45 deletions.
4 changes: 2 additions & 2 deletions models/baseModels/Invoice/Invoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import { AppliedCouponCodes } from '../AppliedCouponCodes/AppliedCouponCodes';
import { CouponCode } from '../CouponCode/CouponCode';
import { SalesInvoice } from '../SalesInvoice/SalesInvoice';
import { SalesInvoiceItem } from '../SalesInvoiceItem/SalesInvoiceItem';
import { PriceListItem } from '../PriceList/PriceListItem';
import { PricingRuleItem } from '../PricingRuleItem/PricingRuleItem';

export type TaxDetail = {
account: string;
Expand Down Expand Up @@ -1332,7 +1332,7 @@ export abstract class Invoice extends Transactional {
item: item.item as string,
unit: item.unit as string,
},
})) as PriceListItem[];
})) as PricingRuleItem[];

return docs.map((doc) => doc.parent) as string[];
}
Expand Down
44 changes: 5 additions & 39 deletions models/baseModels/InvoiceItem/InvoiceItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import { safeParseFloat } from 'utils/index';
import { Invoice } from '../Invoice/Invoice';
import { Item } from '../Item/Item';
import { StockTransfer } from 'models/inventory/StockTransfer';
import { PriceList } from '../PriceList/PriceList';
import { isPesa } from 'fyo/utils';
import { PricingRule } from '../PricingRule/PricingRule';
import { getItemRateFromPriceList } from 'models/helpers';

export abstract class InvoiceItem extends Doc {
item?: string;
Expand Down Expand Up @@ -629,7 +629,10 @@ async function getItemRate(doc: InvoiceItem): Promise<Money | undefined> {
let priceListRate: Money | undefined;

if (doc.fyo.singles.AccountingSettings?.enablePriceList) {
priceListRate = await getItemRateFromPriceList(doc);
priceListRate = await getItemRateFromPriceList(
doc,
doc.parentdoc?.priceList as string
);
}

if (priceListRate) {
Expand Down Expand Up @@ -675,43 +678,6 @@ async function getItemRateFromPricingRule(
return pricingRuleDoc.discountRate;
}

async function getItemRateFromPriceList(
doc: InvoiceItem
): Promise<Money | undefined> {
const priceListName = doc.parentdoc?.priceList;
const item = doc.item;
if (!priceListName || !item) {
return;
}

const priceList = await doc.fyo.doc.getDoc(
ModelNameEnum.PriceList,
priceListName
);

if (!(priceList instanceof PriceList)) {
return;
}

const unit = doc.unit;
const transferUnit = doc.transferUnit;
const plItem = priceList.priceListItem?.find((pli) => {
if (pli.item !== item) {
return false;
}

if (transferUnit && pli.unit !== transferUnit) {
return false;
} else if (unit && pli.unit !== unit) {
return false;
}

return true;
});

return plItem?.rate;
}

function getDiscountedTotalBeforeTaxation(
rate: Money,
quantity: number,
Expand Down
40 changes: 40 additions & 0 deletions models/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import { ValidationError } from 'fyo/utils/errors';
import { isPesa } from 'fyo/utils';
import { numberSeriesDefaultsMap } from './baseModels/Defaults/Defaults';
import { safeParseFloat } from 'utils/index';
import { PriceList } from './baseModels/PriceList/PriceList';
import { InvoiceItem } from './baseModels/InvoiceItem/InvoiceItem';
import { SalesInvoiceItem } from './baseModels/SalesInvoiceItem/SalesInvoiceItem';

export function getQuoteActions(
fyo: Fyo,
Expand Down Expand Up @@ -947,6 +950,43 @@ export async function getPricingRule(
return pricingRules;
}

export async function getItemRateFromPriceList(
doc: InvoiceItem | SalesInvoiceItem,
priceListName: string
): Promise<Money | undefined> {
const item = doc.item;
if (!priceListName || !item) {
return;
}

const priceList = await doc.fyo.doc.getDoc(
ModelNameEnum.PriceList,
priceListName
);

if (!(priceList instanceof PriceList)) {
return;
}

const unit = doc.unit;
const transferUnit = doc.transferUnit;
const plItem = priceList.priceListItem?.find((pli) => {
if (pli.item !== item) {
return false;
}

if (transferUnit && pli.unit !== transferUnit) {
return false;
} else if (unit && pli.unit !== unit) {
return false;
}

return true;
});

return plItem?.rate;
}

export function filterPricingRules(
pricingRuleDocsForItem: PricingRule[],
sinvDate: Date,
Expand Down
3 changes: 2 additions & 1 deletion src/components/POS/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export type ModalName =
| 'LoyaltyProgram'
| 'SavedInvoice'
| 'Alert'
| 'CouponCode';
| 'CouponCode'
| 'PriceList';

export type PosEmits =
| 'addItem'
Expand Down
10 changes: 9 additions & 1 deletion src/pages/POS/ClassicPOS.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
@set-coupons-count="(count) => emitEvent('setCouponsCount', count)"
/>

<PriceListModal
:open-modal="openPriceListModal"
@toggle-modal="emitEvent('toggleModal', 'PriceList')"
/>

<PaymentModal
:open-modal="openPaymentModal"
@toggle-modal="emitEvent('toggleModal', 'Payment')"
Expand Down Expand Up @@ -287,6 +292,7 @@ import AlertModal from './AlertModal.vue';
import PaymentModal from './PaymentModal.vue';
import Button from 'src/components/Button.vue';
import { defineComponent, PropType } from 'vue';
import PriceListModal from './PriceListModal.vue';
import { Item } from 'models/baseModels/Item/Item';
import Link from 'src/components/Controls/Link.vue';
import CouponCodeModal from './CouponCodeModal.vue';
Expand Down Expand Up @@ -318,8 +324,9 @@ export default defineComponent({
ItemsTable,
PaymentModal,
MultiLabelLink,
POSQuickActions,
PriceListModal,
CouponCodeModal,
POSQuickActions,
OpenPOSShiftModal,
SelectedItemTable,
SavedInvoiceModal,
Expand All @@ -336,6 +343,7 @@ export default defineComponent({
isPosShiftOpen: Boolean,
disablePayButton: Boolean,
openPaymentModal: Boolean,
openPriceListModal: Boolean,
openCouponCodeModal: Boolean,
openShiftCloseModal: Boolean,
openSavedInvoiceModal: Boolean,
Expand Down
8 changes: 8 additions & 0 deletions src/pages/POS/ModernPOS.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
@set-coupons-count="(count) => emitEvent('setCouponsCount', count)"
/>

<PriceListModal
:open-modal="openPriceListModal"
@toggle-modal="emitEvent('toggleModal', 'PriceList')"
/>

<PaymentModal
:open-modal="openPaymentModal"
@toggle-modal="emitEvent('toggleModal', 'Payment')"
Expand Down Expand Up @@ -297,6 +302,7 @@ import AlertModal from './AlertModal.vue';
import PaymentModal from './PaymentModal.vue';
import Button from 'src/components/Button.vue';
import KeyboardModal from './KeyboardModal.vue';
import PriceListModal from './PriceListModal.vue';
import { Item } from 'models/baseModels/Item/Item';
import Link from 'src/components/Controls/Link.vue';
import CouponCodeModal from './CouponCodeModal.vue';
Expand Down Expand Up @@ -327,6 +333,7 @@ export default defineComponent({
PaymentModal,
KeyboardModal,
MultiLabelLink,
PriceListModal,
POSQuickActions,
CouponCodeModal,
OpenPOSShiftModal,
Expand All @@ -348,6 +355,7 @@ export default defineComponent({
disablePayButton: Boolean,
openPaymentModal: Boolean,
openKeyboardModal: Boolean,
openPriceListModal: Boolean,
openCouponCodeModal: Boolean,
openShiftCloseModal: Boolean,
openSavedInvoiceModal: Boolean,
Expand Down
20 changes: 19 additions & 1 deletion src/pages/POS/POS.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
:open-payment-modal="openPaymentModal"
:item-discounts="(itemDiscounts as Money)"
:coupons="(coupons as AppliedCouponCodes)"
:open-price-list-modal="openPriceListModal"
:applied-coupons-count="appliedCouponsCount"
:open-shift-close-modal="openShiftCloseModal"
:open-coupon-code-modal="openCouponCodeModal"
Expand Down Expand Up @@ -66,6 +67,7 @@
:open-keyboard-modal="openKeyboardModal"
:item-discounts="(itemDiscounts as Money)"
:coupons="(coupons as AppliedCouponCodes)"
:open-price-list-modal="openPriceListModal"
:applied-coupons-count="appliedCouponsCount"
:open-shift-close-modal="openShiftCloseModal"
:open-coupon-code-modal="openCouponCodeModal"
Expand Down Expand Up @@ -124,6 +126,7 @@ import {
getPricingRule,
removeFreeItems,
getAddedLPWithGrandTotal,
getItemRateFromPriceList,
} from 'models/helpers';
import {
POSItem,
Expand Down Expand Up @@ -165,6 +168,7 @@ export default defineComponent({
openAlertModal: false,
openPaymentModal: false,
openKeyboardModal: false,
openPriceListModal: false,
openCouponCodeModal: false,
openShiftCloseModal: false,
openSavedInvoiceModal: false,
Expand Down Expand Up @@ -440,7 +444,10 @@ export default defineComponent({
}
if (existingItems.length) {
existingItems[0].rate = item.rate as Money;
if (!this.sinvDoc.priceList) {
existingItems[0].rate = item.rate as Money;
}
existingItems[0].quantity = (existingItems[0].quantity as number) + 1;
await this.applyPricingRule();
Expand All @@ -454,6 +461,17 @@ export default defineComponent({
item: item.name,
});
if (this.sinvDoc.priceList) {
let itemData = this.sinvDoc.items?.filter(
(val) => val.item == item.name
) as SalesInvoiceItem[];
itemData[0].rate = await getItemRateFromPriceList(
itemData[0],
this.sinvDoc.priceList
);
}
await this.applyPricingRule();
await this.sinvDoc.runFormulas();
},
Expand Down
49 changes: 48 additions & 1 deletion src/pages/POS/POSQuickActions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@
<div
class="p-0.5 rounded-md bg-gray-100"
:class="{
'bg-gray-100': loyaltyPoints,
'dark:bg-gray-600 cursor-not-allowed':
!sinvDoc?.party || !sinvDoc?.items?.length,
}"
Expand Down Expand Up @@ -249,6 +248,54 @@
{{ appliedCouponsCount }}
</div>
</div>

<div
class="relative group"
:class="{
hidden: !fyo.singles.AccountingSettings?.enablePriceList,
}"
>
<div
class="p-1 rounded-md bg-gray-100"
@click="$emit('toggleModal', 'PriceList')"
>
<svg
xmlns="http://www.w3.org/2000/svg"
height="23px"
viewBox="0 -960 960 960"
width="24px"
fill="#000"
>
<path
d="M180.31-164q-27.01 0-45.66-18.65Q116-201.3 116-228.31v-503.38q0-27.01 18.65-45.66Q153.3-796 180.31-796h599.38q27.01 0 45.66 18.65Q844-758.7 844-731.69v503.38q0 27.01-18.65 45.66Q806.7-164 779.69-164H180.31Zm0-52h599.38q4.62 0 8.46-3.85 3.85-3.84 3.85-8.46v-503.38q0-4.62-3.85-8.46-3.84-3.85-8.46-3.85H180.31q-4.62 0-8.46 3.85-3.85 3.84-3.85 8.46v503.38q0 4.62 3.85 8.46 3.84 3.85 8.46 3.85ZM221-297h172v-52H221v52Zm361-77.23L737.77-530 701-566.77l-119 119-51-51L494.23-462 582-374.23ZM221-454h172v-52H221v52Zm0-156h172v-52H221v52Zm-53 394v-528 528Z"
/>
</svg>
</div>

<span
class="
absolute
bottom-full
left-1/2
transform
-translate-x-1/2
mb-2
bg-gray-100
dark:bg-gray-800 dark:text-white
text-black text-xs
rounded-md
p-2
w-28
text-center
opacity-0
group-hover:opacity-100
transition-opacity
duration-300
"
>
Price List
</span>
</div>
</template>

<script lang="ts">
Expand Down
Loading

0 comments on commit 08284b7

Please sign in to comment.