Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: point of sale #709

Merged
merged 54 commits into from
Dec 4, 2023
Merged

feat: point of sale #709

merged 54 commits into from
Dec 4, 2023

Conversation

akshayitzme
Copy link
Collaborator

@akshayitzme akshayitzme commented Aug 16, 2023

This PR brings the Point of Sale feature to Frappe Books!

  • Update / Create Schemas for POS

    New Schemas & Models
    • Cash Denominations (abstract)
    • Opening Cash
      (extends: Cash Denominations, to let the user enter opening cash amount in denomination wise)
    • Closing Cash
      (extends: Cash Denominations, to let the user enter closing cash amount in denomination wise)

    • POS Shift Amounts (abstract)
    • Opening Amounts
      (extends: POS Shift Amounts, records Opening Amounts of Cash and Transfer)
    • Closing Amounts
      (extends: POS Shift Amounts, records Closing Amounts of Cash and Transfer)

    • Pos Shift (single, stores POS Shift Opening and Closing Amounts and Date, is Pos Shift Open flag)

  • POS User Interface

    New Pages
    • POS Page
    • POS Shift Open Modal
    • POS Shift Close Modal
    • Payment Modal (for payment entry)
    New Components
    • Floating Label Input Base
    • Floating Label Currency Input
    • Floating Label Float Input

POS Features & Functionalities

Enable/Disable POS

  • Set Enable POS Checkbox to Read Only if POS Shift is Open

POS Opening Shift

  • Enter Opening Cash by Denomination wise.
  • Fill in Default Cash Denominations

Items Table (table below the Item Search)

  • List Items and its Rate, Available Qty, and Unit
  • List only the Items that have trackItem enabled
  • Search an Item
  • Search / Set Customer
  • Fetch Default Customer if is set
  • Add an Item by pressing enter.
  • Add an Item by clicking on Search Suggestions
  • Add an Item by clicking on the Item Table
  • throw ValidationError if the user tries to add a zero quantity Item
  • Show Scrollbar on Y axis if Items > Available Space

Selected Items Table (table below the Party Search)

  • Add +1 Qty to the existing Item when the user clicks on the item or presses enter in the search
  • Add a new row of the same item if the selected quantity exceeds the quantity available in the Batch
  • Delete a row by clicking the delete icon
  • Expand / Shrink the Selected Item Row by clicking the arrow up / down icon.
  • Set Quantity, Rate, Unit, Transfer Quantity (for Unit Conversion)
  • Set Discount Amount / Discount Percent either one at a time
  • Show field to select Batch if the Item is Batched (for SINV, SHPM)
  • Show Available Quantity in Batch
  • Show field to select Serial Number if the Item hasSerialNumber (for SHPM)
  • Show Scrollbar on Y axis if Selected Items > Available space

Action Buttons & Totals Display

  • Show Cumulated Item Quantity
  • Show Grand Total, update it when Items are added, deleted, or existing item values are updated.
  • Set Additional Discounts (FB doesn't have the option to set additional discount on the transaction, ✔ Set the field to Read Only for now)
  • Show Cumulated Item discounts
  • Cancel Button clears the Selected Items
  • Pay button opens up the Payment Modal

Payment Modal

  • Set either one of Cash or Transfer amount.
  • Fill Cash Amount when the Cash button is clicked
  • Fill Transfer Amount when the Transfer button is clicked
  • Set Transfer Ref No, Clearance Date if Transfer Amount is set
  • Show Balance amount if the customer pays < Grand Total
  • Show Paid Change if the user pays > Grand Total (only to denote how much amount in balance should be given to the customer. Payment entry amount will be Grand Total)
  • Shows Net Total
  • Shows Taxes and Charges
  • Shows Total Amount
  • Shows cumulated Discount Amount
  • Shows Grand Total
  • Cancel Button should close the Payment Modal
  • Validate SINV item Qty, if Item is in Stock and Serial Number status.
  • Submit Button should Submit the Invoice, Create Payment, Create Shipment
  • Submit and Print Should redirect the user to the Print View after Invoice Submission
  • Hide Discount fields if Discounts not Enabled
  • Hide Unit Conversion fields if not enabled

Close POS Shift

  • Close POS Shift Button should open POS Shift Close Modal
  • Show Cash Denomination Table to set Closing Cash Amount in Denomination wise
  • Set Closing Cash and Transfer Amount
  • Write off the Excess amount in Counter Cash
  • Handle the case if Counter Cash < Expected Amount
  • Clicking Cancel closes the POS Shift Close Modal
  • Clicking Submit should close the POS Shift, clear the Opening and Closing Amounts

Effects on Accounts (feel free to evaluate)

When POS Shift is Opened

  • Users can mention the Opening Amounts of Cash and Transfer payment methods when creating a POS Shift.

  • If an Opening Cash Amount is set, a Journal Entry will be created to transfer the Opening Cash Amount from Cash account to Counter Cash account (Counter Cash Account must be set beforehand in the POS Settings).

    Opening Amounts

    Payment Method Amount
    Cash 100

    Journal Entry

    Account Dr Cr
    Counter Cash 100 0
    Cash 0 100

SINV Payments

  • SINV Payments are made to Counter Cash Account.

When POS Shift is Closed

  • When the POS Shift Closes the total transacted cash amount is transferred from Counter Cash Account to Cash Account. also creates write-off entries if any mismatch occurs between the total transacted Cash Amount and Closing Cash Amount (cash in the counter)
  1. Expected and Closing Amounts are equal

    Payment Method Closing Amount Expected Amount Difference
    Cash 100 100 0

    Journal Entry

    Account Dr Cr
    Cash 100 0
    Counter Cash 0 100
  2. Closing Amount < Expected Amount (shortage of Cash)

    Payment Method Closing Amount Expected Amount Difference
    Cash 50 100 -50

    Journal Entry

    Account Dr Cr
    Cash 50 0
    Counter Cash 0 50
    Cash 50 0
    Write Off 0 50
  3. Closing Amount > Expected Amount (excess of Cash)

    Payment Method Closing Amount Expected Amount Difference
    Cash 150 100 50

    Journal Entry

    Account Dr Cr
    Cash 150 0
    Counter Cash 0 150
    Write Off 50 0
    Cash 0 50

References

POS Icon Source: store-3-fill - RemixIcon

@18alantom
Copy link
Member

@akshayitzme regarding the 3 failing tests cases. I'd suggest debugging the DB state using the CI env.

A thing to check is, have prior async statements been awaited. I think this might be the cause. I've faced similar issues before where this was the root cause.

Reasoning:

CI takes 1m 15.4s to execute the test, local (mine) takes 15.2s.

This could mean that on the faster computer, a non-awaited statement has a higher chance of executing completely before getPOSTransactionAmount has been called, which means that when it executes the DB is in the expected state.

Where as on the slower computer (∵ of slower IOPS), the non-awaited statement hasn't completed its execution when getPOSTransactionAmount is called.

Debugging:

Start with the test file (testPointOfSale.spec.ts). I think non awaited statements should've been caught by the linter. If the test file doesn't have it, then check the code that's being run while running the test.

One way to substantiate this hypothesis is to place a sufficiently long sleep statement before getPOSTransactionAmount is called, this should cause the failing test to pass as the non awaited statement would've executed completely.

@akshayitzme
Copy link
Collaborator Author

@akshayitzme regarding the 3 failing tests cases. I'd suggest debugging the DB state using the CI env.

A thing to check is, have prior async statements been awaited. I think this might be the cause. I've faced similar issues before where this was the root cause.

Reasoning:

CI takes 1m 15.4s to execute the test, local (mine) takes 15.2s.

This could mean that on the faster computer, a non-awaited statement has a higher chance of executing completely before getPOSTransactionAmount has been called, which means that when it executes the DB is in the expected state.

Where as on the slower computer (∵ of slower IOPS), the non-awaited statement hasn't completed its execution when getPOSTransactionAmount is called.

Debugging:

Start with the test file (testPointOfSale.spec.ts). I think non awaited statements should've been caught by the linter. If the test file doesn't have it, then check the code that's being run while running the test.

One way to substantiate this hypothesis is to place a sufficiently long sleep statement before getPOSTransactionAmount is called, this should cause the failing test to pass as the non awaited statement would've executed completely.

Thanks! .. I'll check

@akshayitzme
Copy link
Collaborator Author

@18alantom, regarding the previously failed unit tests,

I crafted a Linux VM with 1024 MB RAM and one processor core. adjusted the Processor Execution Cap accordingly to emulate a slower IOPS machine. a dry run of the unit test took 2m 11s to complete ( 💯 perfect !).

I ran the tests against this branch. Yep, got em.

I checked for any missing async/await. Couldn't find any.
After some debugging, found that the issue was triggering on the fromDate and toDate in the getPOSTransactionAmount function.

Solution:
I refactored the code to find Sales Invoices created from POS between the given dates. used luxon to get the date in ISO Date format (yyyy-mm-dd).

that fixed the failing tests.

@18alantom, Could you review this PR when you get time ?

@akshayitzme akshayitzme marked this pull request as ready for review September 19, 2023 03:47
src/pages/POS/POS.vue Outdated Show resolved Hide resolved
src/utils/pos.ts Outdated Show resolved Hide resolved
@akshayitzme akshayitzme merged commit 82a2c5e into frappe:master Dec 4, 2023
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants