Templates
Template Setup Guides

Jobly - Business Management Like Jobber Template

Template page link: https://zeroqode.com/template/jobly---service-business-template-1550405095050x994159001944719400

Introduction

Jobly template is built without code to help you run a better service business. A robust service business management app like Jobber and Kickserv that allows professional home service businesses to manage major aspects of their business such as work requests, quotes, jobs, invoices, customers, locations, scheduling etc.

For Company owners: Create and/or access your company's account, then add team members to your account so they can use the app to view their schedules, clock in and out, and more.

For Employees: To use the app, your company must have an Owner account, and employees must be added to the account as an authorized user.

FEATURES:

  • Advanced scheduling with support for recurring and one-time jobs

  • Customer center with password-less login system

  • Fully responsive pages and user dashboard

  • Admin Dashboard for Management

  • Social sign-up Facebook & Google

  • Instant invoice payments with Stripe

Payments: See the documentation on how to set Stripe Payments in Bubble App.

Data Structure

Organization

Organisations are the service businesses who use the application to manage their customers. They store basic information about the organisation like name, logo, contact, address as well as fields containing list of all customers and list of users who are team members.

User

Users are team members who must be part of an organization. They store the usual profile info (Photo, Name, Email Address), their organization and also have a role field which is used for access control.

Customer

Customers are simply put the customers of an organisation. They store personal and contact info and have fields for list of requests, quotes, jobs, invoices and locations related to them. The balance field stores the amount the customer owes the organisation and if negative, represents their deposit or what the company owes them. The access_token field stores a hash used for secure login.

Location

Locations are work sites (with separate addresses) of customers. They store address info and the customer they belong to. Customers' requests, quotes and jobs can be tied to specific locations but invoices cannot.

Work Data Types

The four following data types request, quote, job and invoice are the key "work" data types.

Request

Requests are work requests made by customers new or old who are looking to get some services rendered to them. It has fields for start_date and end_date for assessment and a boolean for whether or not an assessment is required. It also has a field for team members (users) assigned to do the assessment.

Quote

Quotes are usually (but not necessarily) follows-ups of work requests above. In addition to other self explanatory fields it has the job_converts field which is a list of jobs which are based off of the quote in question, a change_requests field which is a list changes requested by the customers, and charge_group which handles the list of items/products/services to be billed for and related figures.

Job

Jobs are the most robust data type in this group. They can be created from quotes or directly and are of two types recurring or onetime which are variables under the field job_type.

Other key fields are explained below:

visits: This is a list of schedules which are of type visit. They are specific to jobs and are created using API workflows.

visits_count: This is an integer that stores the number of visits above. During creation of the job this number is set even before all the visits are created in the back-end. This helps in UX such that a "loading state" is displayed where the repeating group of visits should be indicating that they are currently being created.

recurring_duration_mode: This can be either week or month. The value determines which API workflow is used to create the visits in the backend as can be seeing in the workflow for creating a new job.

recurring_duration: This is a number which determines how many weeks or months the job would last for.

recurring_repeat: This is a number that determines how often during the duration above the job will take place. The recurring_duration divided by recurring_repeat is what gives the visits_count.

schedule_text: This is concatenated from the inputs where some of the values above are gotten during creation. It is usually something like: Monthly on the 23rd of every month or Weekly on Fridays.

billing_type: This can either be visit or fixed and determines in part how invoices that include the job will be generated.

When it is visit, the user will need to select one or more visits whose charges (sum of) will be added to the total for that job at the point of invoice creation. For example for a job with weekly visits whose charges includes two items of $10 each (total $20), when two of its visits are selected during job selection stage of invoice creation, on the invoice creation page there will be two line items from it called "Weekly Service" totaling $20 each.

When it is fixed, there will be no visits to select during job selection stage. On the invoice creation page, the default charges of that job will be listed in the line items. For example for a job with weekly visits whose default charges includes two items Clean ($10) and Cut ($15), when the job is selected during job selection stage of invoice creation, on the invoice creation page there will be two line items from it Clean ($10) and Cut ($15) totaling $25.

invoice_timing: This is dictates when or how invoices should be generated. For both visit and fixed billing type it can be set to As needed, Once when job is completed or Monthly on the last day of the month. Additionally for visit type it can be set to After every visit.

invoice_reminders: This is a list of reminders which are created when the invoice_timing is set to Monthly on the last day of the month.

invoice_on_completion: This is a boolean which when set to yes will prompt you to generate an invoice for the job when you mark it as completed. During job creation it is set to yes when the job_type is onetime and the checkbox to remind you to invoice on completion is checked or when the job_type is recurring and the dropdowns for invoice_timing are set to Once when job is completed.

default_charge_lines: This is a list of charge_lines. Charge_lines are essentially duplicates of the original charges that a job has (upon creation). They are used in the creation of additional visits such that they display same items the original job has but allow you to edit the quantity or add extra items.

charge_group: This like a bill which contains a list of charges as well as discount and tax applied however in the case of jobs it doesn't include either tax or discount and the sub_total is the real Total. Charges are basically line items which contain an item, description, quantity, price, total.

Invoice

Invoices are meant for customers and may or may not be based off existing jobs for the customers. The amount field has the same value as the total field of the invoice's charge_group. The balance field starts out the same and reduces as payments are received/recorded from the customer.

Schedule

Schedules are basically to-dos which can be assigned to team members and have a type of either visit or task. They also have the following fields which are specific to visit type.

job: This is the job that this schedule/visit is attached to.

charge_lines: These are similar data types to charges. Each of them takes one of the charges from the job the schedule is attached to and has a different quantity and total. They make it possible for each visit to have independent quantities and as a result, costs.

service_charge: This is a special kind of charge with a special kind of which there are only two, Weekly Service and Monthly Service. They are used when the job has a billing_type of visit. This means when you select multiple visits to invoice, each will be reflected on the invoice charges as a separate Weekly/Monthly Service.

Reminder

Reminders are invoice reminders created for jobs which have the billing timing set to recur monthly.

Time_entry

Time_entries are simply entries of time spent on work. They have duration values in different fields for easy formatting and a user field containing the team member who spent said time. They can be attached to a job or not in which case the title will simply be General.

Charge

Charges are like line items on an invoice or bill. They contain an item and the quantity, unit price and total as well as title and description.

Charge_group

Charge_groups are simply groups of charges with a total which is set in the sub_total field and with some optional fields attached to them. The following fields apply to charge_groups used for invoices:

discount_type: This value can either be percentage or flat and determines how the discount_number below would be treated.

discount_number: This value can either be a rate express like 0.05 (5%) or an amount like 50 depending on the discount_type.

tax: This is the tax rate applied to the charge group.

total: This is the final amount due to be paid on the invoice after deducting discount and adding tax to the sub_total.

Tax_rate

Tax_rates are just taxes like VAT or Sales tax. They have a name and a rate field.

Transaction

Transactions are basically used to consolidate 3 other data types for easy handling. They are payments, deposits and invoices. Each transaction can have only one of those 3 data types which can easily be known from the type field whose value is either payment, deposit or invoice.

Payment

Payments are records of funds collected from a customer via a certain method and optionally for a particular invoice.

Deposit

Deposits are records of funds collected from a customer via a certain method and optionally for a particular invoice.

Note

Notes are additional information for invoices, requests, quotes or jobs and contain a text field and a list of files/attachments. They contain only one of either invoices, requests, quotes or jobs they are attached to.

Plan

Plans are the pricing plans for the whole app. They contain stripe plan_ids for monthly or yearly plans used to subscribe users to a Stripe product plan and an important level field used for access control (Limiting access to certain parts of the app for users on certain plans).

Email

Emails are used for record keeping of all emails sent from within the app to customers. Emails are sent for quotes, invoices, payments and deposits.

Change_requests

These are changes/revisions which customers have requested to be made to quotes that have been sent to them.

App_payment

These are used to record subscription payments made by customers.

Pages

Index

This is the main landing page of the template and contains basic information for new customers to learn more about the application. It has a header, hero, client showcase, video section, features listing section, call-to-action and footer.

Pricing

The pricing page contains the pricing tables which has 4 paid plans with a list of features. The pricing displayed can be toggled from yearly to monthly pricing.

Element

State

Note

Group billing mode switch

mode

Determines whether pricing displayed is per month or per year. Values are yearly or monthly

Signup

This contains the sign up form and allows users to sign up with email or Google. During the sign up process an organization is created for the user with the subscription_due date set to 14 days in the future allowing for the trial period.

Login

This contains the login form and allows users to login with email of Google.

Customer-Center

This is the self-service dashboard for organisations' customers. They can view their work requests, quotes, invoices and jobs from here. It also allows customers make new work requests, request changes to quotes and make payments for invoices.

Dashboard

This is the most important page of this application where most of the functionality is. It is the dashboard for organisations users to manage their service business. This page is designed like a SPA (Single Page Application). It is broken into major sub pages listed below:

This template now been updated to feature a separate page for each of the following groups below. You can choose to use the /dashboard page which has all the sub groups below or you can choose to remove the /dashboard and use the individual pages created for each of the groups below.

Dashboard Group

This shows the user recommended actions, assignments for the day and a preview of outstanding balances, past due invoices, upcoming jobs and time entries for the day. This page is only accessible by users with level 3 & above.

Schedule Group

This shows a list of all schedules (both of type visit & task) that the user has access to. Users on level 1 can only see schedules assigned to them as defined in the privacy roles.

Work Group

The work group is where users manage requests, quotes, jobs and invoices. For each of those 4 data types there is a list view, detailed view and edit/create form. This page is only accessible by users with level 3 & above.

Customers Group

The customers group is where users manage customers and locations. For each of those 2 data types there is a list view, detailed view and edit/create form. This page is only accessible by users with level 3 & above.

Timesheet Group

The timesheet shows all time entries for a the selected day for a selected user. Here a user can edit or add new time entries that may or may not be attached to a job. They can also delete time entries from here. This page is only accessible by users with level 3 & above.

Management Group

This is where users can see reports (of which there are 8) and approve timesheet entries up to a select date.

Settings Group

Here users can manage various aspects of their organization's usage of the platform. They include company information, account & billing, team members, payments and notifications.

Specific References

Signing up

Users are able to sign up with email or Google. During the sign up process an organization is created for the user with the subscription_due date set to 14 days in the future allowing for the trial period. A plan is also set on the organization. This plan can be specified from the plan parameter on the signup page url. If the parameter doesn't exist, the unlimited plan is set on the organization.

Authentication

You would need to create an app/project in the developer console of each social network:

Google: https://console.developers.google.com

Ensure that you add all live & test URLs for these pages /signup, /signin & /dashboard as authorized redirect URLs.

You can check the Bubble forum or the developer guides of the social networks if you’re having trouble.

Navigation is straightforward on all pages except for the ones below which are a little more complex.

Dashboard (Single Page Application)

Navigation in this page makes use of custom states and conditions. The custom states are handled by the singular main menu and multiple sub menus for different sub pages. The buttons inside the main menu group set the state "current" of main menu to a value which makes one of the sub menus (and its corresponding sub page) to become visible. In the same way the buttons inside these sub menus set the state "current" of the sub menu to a value which makes one of the sub groups within the sub page to become visible.

Example:

  • User clicks Button Customer

  • Custom state "current" of main menu is set to customer

  • Customers sub menu and Customers Group become visible

  • Customers sub menu "current" has default value of people

  • Group showing list of people is visible

  • Customer click Button People in Customers sub menu

  • Customers sub menu "current" is set to locations

  • Group showing list of locations becomes visible

  • User clicks Button New Location

  • Customers sub menu "current" is set to locations-create

  • Group to add and edit location becomes visible

Dashboard_lite and other individual pages (Work, Schedule, Timesheet, Management, Customers, Settings)

Navigation in these pages makes use of custom states and conditions. It also makes use of Javascript and plugins for AJAX-style navigation and URL handling/deeplinking.

How this works is when the page is loaded the URL's path is split with a JS call and each part is used to fetch a different thing and set a different state. In this implementation there are 3 parts named one, two and three.

  • The first part 'one' comes right after the page name and is usually set as the state of the sub menu group for that page. For example when you load the URL https://example.com/work/overview, the value of the first part one = overview and overview is set as the value of the work sub menu custom state current.

  • The second part 'two' either carries an id of an object such as requests or quotes or it carries the value new and triggers workflow actions for creating an object. For example when you load the URL https://example.com/work/requests/214625, the value of the first part one = requests and requests is set as the value of the work sub menu custom state current. Then the value of the second part two = 214625. This is used to search and fetch the request and is passed to a workflow that handles the viewing of a request. In another example when you load the URL https://example.com/work/requests/new, the value of the first part one = requests but because part two = new, requests is not set as the value of the work sub menu custom state current. Instead this triggers the show of the customer selection popup which handles the next steps for creating a new request.

  • The third part 'three' only carries the value of edit when the second part carries the id of an object. The presence of edit triggers a workflow for editing the object instead of viewing it. For example when you load the URL https://example.com/work/requests/214625/edit, the value of the first part one = requests and requests is set as the value of the work sub menu custom state current. Then the value of the second part two = 214625. This is used to search and fetch the request but because three = edit the fetched request is passed to a triggered workflow for editing the request object.

As for the URLs, there are various buttons or groups that are clicked for viewing, editing and creating objects. The workflows for these contains first an action for replacing the URL of the browser and then next it triggers a custom event called Deeplinking. This event runs a javascript that splits the URL into parts, sets the values of some JStoBubble elements which then trigger their own events that result in the viewing, edit or creation events being triggered as described above.

Customer-Center

Navigation in the customer-centre makes use of custom states and conditions. It also makes use of Javascript and plugins for AJAX-style navigation and URL handling.

How this works is when the page is loaded the URL's path is split with a JS call and each part is used to fetch a different thing and set a different state. In this implementation there are 3 major parts namely organisation, main and sub.

In a URL https://example.com/customer-centre/org/main/sub

org is the username or the organisation. The organisation with that username is searched and set as a state on the page when it is loaded.

main can either be one of requests, quotes, jobs or invoices. It can also be login or confirmation when the customer is not logged in.

sub when available is the ID of the data type specified in main.

The url of the customer centre is constructed like this for data list view:

website home url + customer-centre + organisation's username + data type

Example: https://servo.com/customer-centre/klinhomes/invoices

The url of the customer centre is constructed like this for data detailed view:

website home url + customer-centre + organisation's username + data type + object ID

Example: https://servo.com/customer-centre/klinhomes/invoices/345299

In the list view of the 4 major data types requests, quotes, jobs and invoices, there is search & filtering functionality. To allow for this, a "base" repeating group is first used to filter the data with sorting and dates and then the main repeating group can further filter the first repeating group's data with statuses. The search&autocorrect also has it's datasource defined similarly to the main repeating group. When the search&autocorrect is in use, the main repeating group shows the result of the search&autocorrect's search.

Account & Billing

Subscriptions are handle via the organization data type of each team using the app. The organization data type stores the stripe customer ID, stripe subscription ID, subscription due date as well as the plan data type representing the plan the organization is on.

When choosing or changing a plan, the user can select either monthly or yearly billing. If monthly, the monthly_id or the chosen plan is used in the Stripe workflow and if yearly, the yearly_id is used.

When an organization's subscription is renewed or paid for the first time, the subscription due date is pushed forward 1 month or year in the future as appropriate via API workflow triggered by Stripe webhook. If the user subscribes to a new plan, the API workflow finds the plan with matching ID and updates the organization's plan field.

Payments

This template uses Stripe for payments powered by Bubble's Stripe plugin and Stripe.js plugin.

To setup your stripe account, go to https://stripe.com, create an account. You will be allowed to access your dashboard once you have successfully verified your email address and activated your account.

Click on Developers and then, API keys. Copy your API keys. Ensure to use a live API key when your template goes live.

Webhooks

This template uses two Stripe webhooks. One for invoice payment successful which renews or updates subscription plan and one for unsuccessful which cancels the plan.

To configure them

PDF Downloads

PDF downloads are powered by an API call which converts PDF formatted pages within the templates to PDF. These pages are invoice_view, job_view, quote_view. This API is deployed on heroku and you are meant to make your own deployment by following the steps below:

  • Click on the purple Deploy to Heroku button and follow the prompts from there

  • After that go to Bubble > Plugins > API Connector > PDF Generate > Render and replace the URL with that of your own Heroku app.

Notes

You will find over notes for this template in Bubble. They are for workflows and fields that need explaining. Mostly in User data fields, dashboard workflows and API workflows.

Things to Note:

Overlapping Elements

The Dashboard page has many overlapping elements as a single page application. All major sub pages, data views and forms are overlapping each other. In addition, in major repeating groups, there exist desktop and mobile versions overlapping each other.

You will find other overlapping elements of note within these groups. Simply copy the element name and search for it. Note that this is for minor groups not easily locatable in the elements tree.

Page

Element

Dashboard

Group Set Job Scheduling

Dashboard

Group Set Job Invoicing

Dashboard

Sub menus

Header (Reusable)

Header

Header (Reusable)

Group Inner Mobile

Header (Reusable)

Group Inner Desktop

Custom Code

Schedule, Work, Customers, Management, Timesheet & Settings Page

  • Popstate custom event workflow: The custom javascript used here does not need to be changed. It is used for navigating between tabs. It also relies on the JavascriptToBubble elements which must not be removed or edited.

Work & Customers Page

  • Deeplink custom event workflow: The custom javascript used here does not need to be changed. It is used for navigating between tabs. It also relies on the JavascriptToBubble elements which must not be removed or edited.

Customer-centre Page

  • Page is loaded workflow: The custom javascript used here does not need to be changed. It is used for navigating between tabs. It also relies on the JavascriptToBubble elements which must not be removed or edited.

Tip: You can find the above workflows & elements using the search bars in design tab or workflow tab as the case may be.

Demo to preview the template