A Frappe application to manage a complete Bottled Water Business — including package sales, water order delivery, bottle rental/return, OTP-based customer login, and Stripe payment integration.
- License: MIT
# From your frappe-bench directory
bench get-app bottled_water_system
bench --site your-site-name install-app bottled_water_system
bench migrateDefines the different types of water bottles offered (e.g., 5 Gallon, 1.5 Litre).
| Field | Type | Description |
|---|---|---|
| name1 | Data | Display name of the bottle type |
Represents a sellable/rentable bottle product linked to a Frappe Item.
| Field | Type | Description |
|---|---|---|
| item | Link (Item) | Linked ERPNext Item |
| price | Float | Security deposit / rental price |
| bottle_type | Link (Bottle Type) | Type of bottle |
Defines subscription/bulk packages that customers can purchase.
| Field | Type | Description |
|---|---|---|
| enabled | Check | Whether the package is active |
| package_name | Data | Display name |
| bottle_quantity | Int | Number of bottles in the package |
| item | Link (Item) | Linked ERPNext Item |
| display_order | Float | Ordering on the frontend |
| bottle_type | Link (Bottle Type) | Type of bottle included |
| water_bottle_product | Link (Water Bottle Product) | Associated bottle product |
| description | Small Text | Package description |
Tracks each customer's bottle package purchase and remaining bottle balance.
| Field | Type | Description |
|---|---|---|
| customer | Link (Customer) | Purchasing customer |
| item | Link (Item) | Package item |
| status | Select | Active / Exhausted |
| purchase_date | Date | Date of purchase |
| bottles_purchased | Int | Bottles per package |
| bottles_remaining | Int | Remaining bottles |
| bottle_type | Link (Bottle Type) | Bottle type |
| bottles_ordered | Int | Total bottles ordered so far |
| bottle_package | Link (Bottle Package) | Reference to the package |
| water_bottle_product | Link (Water Bottle Product) | Associated product |
| sales_invoice | Link (Sales Invoice) | Linked Sales Invoice |
| package_quantity | Int | Quantity of packages purchased |
| total_bottles | Int | Total bottle count |
Records individual water delivery requests placed by customers.
| Field | Type | Description |
|---|---|---|
| customer | Link (Customer) | Customer placing the order |
| order_date | Date | Date order was placed |
| delivery_date | Date | Requested delivery date |
| bottle_quantity | Int | Number of bottles ordered |
| consumed_from | Link (Customer Package Purchase) | Package being consumed |
| item | Link (Item) | Ordered item |
| remarks | Small Text | Additional notes |
| status | Select | Pending / Delivered / Cancelled |
| delivered_quantity | Int | Bottles actually delivered |
| outstanding_quantity | Int | Remaining to be delivered |
| bottle_type | Link (Bottle Type) | Type of bottle |
| address | Link (Address) | Delivery address |
| assigned_to | Link (User) | Delivery boy assigned |
Tracks the physical bottle inventory held by each customer (rental bottles).
| Field | Type | Description |
|---|---|---|
| customer | Link (Customer) | Customer |
| water_bottle_product | Link (Water Bottle Product) | Product rented |
| available_quantity | Int | Bottles currently with customer |
| status | Select | Active / Inactive |
| total_quantity | Int | Total bottles ever issued |
| total_security_deposit | Float | Total security deposit paid |
| customer_security_deposit | Table (Customer Security Deposit Table) | Deposit history |
| returned_quantity | Int | Total bottles returned |
| customer_security_deposit_return | Table (Customer Security Deposit Return) | Return history |
| security_deposit_return | Float | Total security returned |
| balance_security_deposit | Float | Remaining security balance |
| bottle_product_ledger | Table (Bottle Product Ledger) | Transaction ledger |
| total_available_bottles | Float | Available count |
| customer_hand | Float | Bottles with customer |
| company_hand | Float | Bottles back with company |
Records a bottle return event by a customer, optionally with security refund.
| Field | Type | Description |
|---|---|---|
| customer | Link (Customer) | Customer returning bottles |
| water_bottle_product | Link (Water Bottle Product) | Product being returned |
| return_date | Date | Date of return |
| quantity_returned | Int | Number of bottles returned |
| item | Link (Item) | Item reference |
| bottle_type | Link (Bottle Type) | Bottle type |
| payment_entry | Link (Payment Entry) | Security refund payment |
| security_return | Currency | Amount refunded |
| with_security_return | Check | Whether security is refunded |
| water_order | Link (Water Order) | Related water order |
A line-item ledger entry tracking bottle movements for a customer.
| Field | Type | Description |
|---|---|---|
| water_order | Link (Water Order) | Related order |
| bottle_transaction_type | Select | Transaction type (Issue / Return) |
| ordered_quantity | Float | Ordered count |
| delivered_quantity | Float | Delivered count |
| outstanding_quantity | Float | Outstanding count |
| bottle_return | Link (Bottle Return) | Related return |
| return_quantity | Float | Quantity returned |
One row per security deposit payment made by a customer.
| Field | Type | Description |
|---|---|---|
| posting_date | Date | Date of deposit |
| quantity | Float | Bottles deposited for |
| security_deposit | Currency | Amount deposited |
| payment_entry | Link (Payment Entry) | Payment reference |
Tracks individual security deposit refunds.
| Field | Type | Description |
|---|---|---|
| posting_date | Date | Date of return |
| quantity | Float | Bottles for which deposit returned |
| payment_entry | Link (Payment Entry) | Payment reference |
| security_return | Currency | Amount returned |
| bottle_return | Link (Bottle Return) | Related bottle return |
Stores OTP records for mobile-number-based customer authentication.
| Field | Type | Description |
|---|---|---|
| mobile_number | Data | Customer's mobile number |
| otp | Data | Generated 6-digit OTP |
| otp_expiry | Datetime | OTP validity (5 minutes) |
| is_verified | Check | Whether OTP was verified |
Stores card details for Stripe-based payment processing.
| Field | Type | Description |
|---|---|---|
| card_number | Data | Card number |
| cvc | Int | CVC code |
| expiry_month | Data | Expiry month |
| expiry_date | Data | Expiry year |
Global configuration for the app. See Settings section below.
All endpoints follow the Frappe REST convention:
POST /api/method/bottled_water_system.api.<module>.<function_name>
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | bottled_water_system.api.account.send_otp |
Guest | Send a 6-digit OTP via SMS to the given mobile number (expires in 5 min) |
| POST | bottled_water_system.api.account.verify_otp |
Guest | Verify OTP entered by the user |
| POST | bottled_water_system.api.account.complete_registration_and_login |
Guest | Register a new customer with name, email, birth date & gender, then log them in |
| POST | bottled_water_system.api.account.logout_user |
Guest | Log out the currently authenticated user |
| POST | bottled_water_system.api.account.create_address |
Auth | Create a delivery address with geo-coordinates for the logged-in customer |
| GET | bottled_water_system.api.account.get_addresses |
Auth | Retrieve all delivery addresses for the logged-in customer |
Parameters:
send_otp(mobile_number)verify_otp(mobile_number, input_otp)complete_registration_and_login(mobile_number, full_name, email, birth_date, gender)create_address(address_title, address_type, address_line1, city, country, latitude, longitude)
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | bottled_water_system.api.common.get_genders |
Guest | Returns list of gender options |
| GET | bottled_water_system.api.common.get_countries |
Auth | Returns list of countries |
| GET | bottled_water_system.api.common.get_customer |
Auth | Returns the Customer linked to the logged-in user |
| GET | bottled_water_system.api.common.get_company_currency |
Auth | Returns the default company currency |
| GET | bottled_water_system.api.common.get_customer_info |
Auth | Returns full profile info of the logged-in customer |
| GET | bottled_water_system.api.common.get_item_image |
Auth | Returns the image URL for a given item |
Parameters:
get_item_image(item)
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | bottled_water_system.api.package.get_packages |
Auth | Returns all enabled bottle packages |
| POST | bottled_water_system.api.package.package_purchase |
Auth | Purchase one or more bottle packages; creates a Sales Invoice |
| GET | bottled_water_system.api.package.get_customer_package_purchases |
Auth | Returns the logged-in customer's package purchase history |
| GET | bottled_water_system.api.package.get_water_bottle_product |
Auth | Returns all available water bottle products |
Parameters:
package_purchase(bottle_packages)— JSON array of packages to purchase
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | bottled_water_system.api.order.place_water_order |
Auth | Place a water delivery order against an existing package purchase |
| GET | bottled_water_system.api.order.get_customer_water_order |
Auth | Retrieve all water orders for the logged-in customer |
| POST | bottled_water_system.api.order.check_available_qty |
Auth | Check remaining bottle quantity for a customer's package |
| POST | bottled_water_system.api.order.water_order_delivery |
Auth | Mark a water order as delivered (used by admin/delivery boy) |
Parameters:
place_water_order(package_name, bottle_quantity, delivery_date, address)check_available_qty(customer, package_name)water_order_delivery(water_order, delivered_quantity)
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | bottled_water_system.api.rent_bottles.rent_water_bottle_product |
Guest | Rent water bottles for a customer; collects security deposit |
| GET | bottled_water_system.api.rent_bottles.get_security_deposit |
Auth | Get the security deposit amount for a product and quantity |
| POST | bottled_water_system.api.rent_bottles.bottle_return |
Auth | Record bottle returns for a water order |
| GET | bottled_water_system.api.rent_bottles.get_security_return_list |
Auth | Get list of pending security deposit returns for the customer |
| POST | bottled_water_system.api.rent_bottles.security_return |
Auth | Process a security deposit refund for returned bottles |
| GET | bottled_water_system.api.rent_bottles.get_customer_water_bottle |
Auth | Retrieve the customer's current bottle inventory and deposit status |
Parameters:
rent_water_bottle_product(customer_water_bottle)— JSON objectget_security_deposit(water_bottle_product, quantity)bottle_return(customer, water_order, bottle_returns)—bottle_returnsis a JSON arraysecurity_return(customer, water_bottle_product, quantity)
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | bottled_water_system.api.payment_gateway.make_payment |
Auth | Charge a Stripe card token and submit a Sales Invoice |
| POST | bottled_water_system.api.payment_gateway.create_client_secret |
Auth | Create a Stripe PaymentIntent and return its client secret for front-end confirmation |
Parameters:
make_payment(token, is_bottle_rent, sales_invoice, customer_water_bottle)create_client_secret(amount, currency)
Note: Stripe Publishable Key and Secret Key must be configured in Bottled Water Settings.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | bottled_water_system.api.water_delivery_boy.get_water_orders_for_delivery_boy |
Auth | All water orders assigned to the logged-in delivery boy |
| GET | bottled_water_system.api.water_delivery_boy.get_pending_water_orders_for_delivery_boy |
Auth | Pending (undelivered) orders for the delivery boy |
| GET | bottled_water_system.api.water_delivery_boy.get_delivered_water_orders_for_delivery_boy |
Auth | Completed delivery orders for the delivery boy |
| GET | bottled_water_system.api.water_delivery_boy.get_bottle_return_for_delivery_boy |
Auth | Bottle return records relevant to the delivery boy |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | bottled_water_system.api.after_install.create_role |
Auth | Creates default roles required by the app (called automatically after install) |
Navigate to Bottled Water Settings (Single Doctype) to configure:
| Setting | Description |
|---|---|
| Award Bottle to New Users | Toggle to automatically give free bottles on new customer registration |
| Award Bottle Quantity | Number of free bottles to award |
| Award Bottle Product | Which Water Bottle Product to award |
| Mode of Payment | Default mode of payment for security deposits |
| Publishable Key | Stripe publishable API key |
| Secret Key | Stripe secret API key |
| Currency | Default currency for Stripe payments |
| Account SID | Twilio Account SID (for SMS OTP) |
| Auth Token | Twilio Auth Token |
| Twilio Phone Number | Sender number for OTP SMS |
The app adds the following custom fields to the Address doctype via fixtures:
| Field | Description |
|---|---|
custom_latitude |
GPS latitude of the delivery address |
custom_longitude |
GPS longitude of the delivery address |
The following custom role is created on installation:
- Water Delivery Boy — assigned to delivery personnel; restricts access to delivery-related orders only.
An App to manage Bottled Water Business
mit