=== Demfilz Quote Cart for WooCommerce ===
Contributors: demfilz
Tags: request a quote, quote, rfq, b2b, wholesale
Requires at least: 6.3
Tested up to: 7.1
Stable tag: 1.0.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Customers add products to a quote list and request a quote. Price it as a WooCommerce order, send it, and they accept and pay online.

== Description ==

Some products do not have one price. Freight, volume, site conditions and account terms change it, so trade, wholesale, B2B and made-to-order stores answer with a quote. This plugin gives WooCommerce the whole quote, from request to payment, in the free version:

1. The shopper adds products to a **quote list** (with options and quantities, from product pages and product grids) and sends a request with their details.
2. The request arrives as a WooCommerce order with the status **Quote request**. You price it in the normal order screen: change line prices, add shipping, fees or a coupon, recalculate tax.
3. You **send the quote** with one tick. The customer gets an email with the priced quote and a link to their quote page.
4. The customer **accepts and pays** on WooCommerce's own Pay for order page, at exactly the total you sent. Nothing is recalculated, so the shipping and fees you added stay put. Or they decline, with a reason.

**On the storefront**

* Add to quote buttons next to Add to cart, or instead of it (quote only), on all products, on chosen categories, or product by product.
* Rules for everyone, for guests only (catalogue mode for visitors, normal shopping for logged-in trade customers), or for logged-in customers only.
* Hide the prices of quote-only products, with your own text ("Price on request"). Prices are also left out of variation data, the Store API product data and the product's structured data for search engines, and price filters are switched off while prices are hidden, so a hidden price cannot be narrowed down by filtering.
* Products without a price (empty or zero) become quote only automatically, instead of showing nothing.
* Quote-only products are refused at every storefront add to cart route: the product form, add to cart links, AJAX and the cart and checkout blocks.
* Works with simple and variable products, classic themes and block themes, with or without JavaScript.
* `[dqcw_quote_link]` shows a link to the quote page with the number of products, which stays right on page-cached pages. Put it in a Shortcode block or widget in your header.

**The quote list and request form**

* A quote page (created on activation) with the products, editable quantities, a note per line, and optionally today's prices with an estimate.
* Name and email address, plus phone, company and delivery address, each off, optional or required. Logged-in customers get their saved details filled in.
* Guests allowed, or log in required.
* Spam protection without a captcha: a hidden honeypot field, a limit of five requests per hour per IP address (per /64 for IPv6) and an hourly ceiling for guest requests across the site.

**Quotes**

* Three order statuses, Quote request, Quote sent and Quote declined, with their own colours, a Quote column on the orders list and a WooCommerce > Quotes menu with the number of requests waiting.
* A Quote box on the order: valid until date (default 30 days from sending, per quote), a message to the customer, and "Send the quote to the customer when I update the order". The order action "Send quote to customer", or choosing the status Quote sent, does the same.
* Quotes for phone and email enquiries: create an order with Add order, give it the status Quote request, price it and send it.
* Quote terms (ABN, payment terms, lead times, what the price includes) printed under every sent quote.
* The customer's quote page: items, prices, totals, valid until date, your message, Accept and pay, Decline, and a printable version they can save as a PDF.
* Expired quotes cannot be accepted; the customer can ask for an updated quote with one click, and it comes back to you as a Quote request.
* Accepting checks the stock for the quoted quantities, so a quote accepted days later cannot be paid for goods you no longer have, and holds it with WooCommerce's stock reservation while the customer pays.
* My Account > Quotes lists every quote with its status, total and the next step. Open quotes stay out of My Account > Orders until accepted.
* Open and declined quotes are left out of WooCommerce Analytics, and accepted quotes waiting for payment are not auto-cancelled by WooCommerce's unpaid order clean-up.

**Emails**

Four WooCommerce emails you can switch on and off, edit and preview in WooCommerce > Settings > Emails, with templates you can override in your theme: New quote request (to you), Quote request received (to the customer), Your quote (to the customer, with the priced quote and the accept link) and Quote answered (to you, when a quote is accepted, declined or an update is asked for).

**Sensible defaults**

* Add to quote next to Add to cart on every product, products without a price quote only, prices of quote-only products hidden.
* Works with WooCommerce High-Performance Order Storage (HPOS) and the cart and checkout blocks.
* No external services and no tracking.

**For developers**

Actions: `dqcw_added_to_list`, `dqcw_request_created`, `dqcw_validate_request`, `dqcw_quote_sent`, `dqcw_quote_accepted`, `dqcw_quote_declined`, `dqcw_update_requested`.

Filters: `dqcw_product_mode`, `dqcw_supported_types`, `dqcw_form_fields`, `dqcw_rate_limit`, `dqcw_can_accept`, `dqcw_accept_redirect`, `dqcw_account_endpoint`.

Quote orders have `created_via` set to `dqcw` and the statuses `wc-dqcw-request`, `wc-dqcw-sent` and `wc-dqcw-declined`. Order meta: `_dqcw_state`, `_dqcw_requested_at`, `_dqcw_sent_at`, `_dqcw_valid_until` (Y-m-d), `_dqcw_message`, `_dqcw_answered_at`. Line notes are the order item meta `dqcw_note`. The product setting is the product meta `_dqcw_mode` (both, quote or off).

== Installation ==

1. Install and activate the plugin. WooCommerce must be active.
2. Right away, review WooCommerce > Settings > Quotes: by default Add to quote appears next to Add to cart on every product, and products without a price (empty or zero) become quote only for everyone.
3. A page called Quote is created with the `[dqcw_quote_cart]` shortcode. Add the page to your menu, and if you like put `[dqcw_quote_link]` in a Shortcode block or widget in your header for a link with the number of products.
4. Optional: open a product's Quote tab to override the store settings for that product, and add your quote terms under WooCommerce > Settings > Quotes > Quotes.

== Frequently Asked Questions ==

= How do I price and send a quote? =

Open the request from WooCommerce > Quotes (or the link in the email). Change the line prices in the items box, add a shipping line or fees if needed, and click Recalculate. In the Quote box, check the valid until date, add a message if you like, tick "Send the quote to the customer when I update the order" and click Update. The customer is emailed straight away.

= What happens when the customer accepts? =

The stock is reserved, the order moves to Pending payment, and the customer lands on WooCommerce's Pay for order page with the total you sent. They pay with any of your payment methods, including bank transfer. From then on it is a normal WooCommerce order with the normal emails.

= Can I change a quote after sending it? =

Yes. Edit the order and send it again: the customer gets the updated quote and the old one is replaced. Once the customer has accepted or declined, the quote is closed.

= Can customers see the price before they ask? =

Your choice. With "Hide prices" on, quote-only products show your text instead of the price. With it off, they see the price but can only request a quote. You can also show today's prices and an estimate in the quote list.

= Can logged-in trade customers shop normally while guests can only ask for quotes? =

Yes. Set "For" to "Visitors who are not logged in" and "On those products" to quote only. Logged-in customers see prices and Add to cart as usual.

= Do quotes count as sales? =

No. Quote requests, sent quotes and declined quotes are excluded from WooCommerce Analytics. An accepted quote counts once it is paid, like any order.

= Does it work with page caching? =

Yes. Adding to the quote list works on cached product pages (like WooCommerce's own add to cart, it needs no per-visitor code in the page), the quote page sends no-cache headers, and the quote count link updates itself from a cookie.

= Can I quote a phone or email enquiry? =

Yes. Use Add order in WooCommerce > Orders, add the products and the customer's details, set the status to Quote request and save. The order becomes a quote with the Quote box; price it and send it like any other.

= What are the limits? =

Simple and variable products can be quoted (not grouped or external products, and not out of stock ones). Quantities are whole numbers. A quote is in your store's currency. A quote that belongs to a customer account opens and is paid while logged in to that account, so a colleague cannot pay it from a forwarded link.

= Is the quote link safe to email? =

It carries the order key, like WooCommerce's own Pay for order links. Quotes that belong to a customer account also need that account to be logged in. Accepting and declining are buttons on the page, never plain links, so email scanners that open links cannot answer a quote by accident.

= What happens to quotes if I remove the plugin? =

They stay in your orders. While the plugin is inactive, orders with the quote statuses are not shown in the orders list (WooCommerce only lists statuses it knows); reactivate the plugin to see them again.

= Does it work with HPOS and the block checkout? =

Yes, with both order storage modes and with the cart and checkout blocks.

== Screenshots ==

1. Add to quote next to Add to cart on a product page.
2. The quote list and request form.
3. WooCommerce > Quotes: requests waiting to be priced.
4. Pricing a quote: the order screen with the Quote box.
5. The customer's quote page with Accept and pay.
6. Pay for order at the quoted total.
7. My Account > Quotes.
8. WooCommerce > Settings > Quotes.

== Changelog ==

= 1.0.0 =
* First release.

== Upgrade Notice ==

= 1.0.0 =
First release.
