mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-04 05:58:27 +00:00
[webshop] Place Order - submits Quotation, creates Customer if required, creates and submits Sales Order
This commit is contained in:
@@ -136,6 +136,10 @@ img {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* buttons */
|
||||
.btn-default {
|
||||
color: #ffffff;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-06-19 15:57:32",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-07-05 14:55:05",
|
||||
"modified": "2013-07-10 18:42:29",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -44,6 +44,19 @@
|
||||
"fieldtype": "Check",
|
||||
"label": "Enable Shopping Cart"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "section_break_2",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "default_territory",
|
||||
@@ -52,6 +65,24 @@
|
||||
"options": "Territory",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "default_customer_group",
|
||||
"fieldtype": "Link",
|
||||
"label": "Default Customer Group",
|
||||
"options": "Customer Group",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "section_break_6",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "price_lists",
|
||||
@@ -60,14 +91,6 @@
|
||||
"options": "Shopping Cart Price List",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "sales_taxes_and_charges_masters",
|
||||
"fieldtype": "Table",
|
||||
"label": "Shopping Cart Taxes and Charges Masters",
|
||||
"options": "Shopping Cart Taxes and Charges Master",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "shipping_rules",
|
||||
@@ -78,11 +101,16 @@
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"reqd": 1
|
||||
"fieldname": "column_break_10",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "sales_taxes_and_charges_masters",
|
||||
"fieldtype": "Table",
|
||||
"label": "Shopping Cart Taxes and Charges Masters",
|
||||
"options": "Shopping Cart Taxes and Charges Master",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm"
|
||||
|
||||
@@ -3,17 +3,26 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from webnotes import msgprint, _
|
||||
import webnotes.defaults
|
||||
from webnotes.utils import flt, get_fullname, fmt_money
|
||||
from webnotes.utils import flt, get_fullname, fmt_money, cstr
|
||||
|
||||
class WebsitePriceListMissingError(webnotes.ValidationError): pass
|
||||
|
||||
def set_cart_count(quotation=None):
|
||||
if not quotation:
|
||||
quotation = _get_cart_quotation()
|
||||
webnotes.add_cookies["cart_count"] = cstr(len(quotation.doclist.get(
|
||||
{"parentfield": "quotation_details"})) or "")
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_cart_quotation(doclist=None):
|
||||
party = get_lead_or_customer()
|
||||
|
||||
if not doclist:
|
||||
doclist = _get_cart_quotation(party).doclist
|
||||
quotation = _get_cart_quotation(party)
|
||||
doclist = quotation.doclist
|
||||
set_cart_count(quotation)
|
||||
|
||||
return {
|
||||
"doclist": decorate_quotation_doclist(doclist),
|
||||
@@ -21,6 +30,26 @@ def get_cart_quotation(doclist=None):
|
||||
for address in get_address_docs(party)],
|
||||
"shipping_rules": get_applicable_shipping_rules(party)
|
||||
}
|
||||
|
||||
@webnotes.whitelist()
|
||||
def place_order():
|
||||
quotation = _get_cart_quotation()
|
||||
controller = quotation.make_controller()
|
||||
for fieldname in ["customer_address", "shipping_address_name"]:
|
||||
if not quotation.doc.fields.get(fieldname):
|
||||
msgprint(_("Please select a") + " " + _(controller.meta.get_label(fieldname)), raise_exception=True)
|
||||
|
||||
quotation.ignore_permissions = True
|
||||
quotation.submit()
|
||||
|
||||
from selling.doctype.quotation.quotation import _make_sales_order
|
||||
sales_order = webnotes.bean(_make_sales_order(quotation.doc.name, ignore_permissions=True))
|
||||
sales_order.ignore_permissions = True
|
||||
sales_order.insert()
|
||||
sales_order.submit()
|
||||
webnotes.add_cookies["cart_count"] = ""
|
||||
|
||||
return sales_order.doc.name
|
||||
|
||||
@webnotes.whitelist()
|
||||
def update_cart(item_code, qty, with_doclist=0):
|
||||
@@ -46,6 +75,8 @@ def update_cart(item_code, qty, with_doclist=0):
|
||||
quotation.ignore_permissions = True
|
||||
quotation.save()
|
||||
|
||||
set_cart_count(quotation)
|
||||
|
||||
if with_doclist:
|
||||
return get_cart_quotation(quotation.doclist)
|
||||
else:
|
||||
@@ -192,11 +223,47 @@ def _get_cart_quotation(party=None):
|
||||
"__islocal": 1,
|
||||
(party.doctype.lower()): party.name
|
||||
})
|
||||
|
||||
# map_contact_fields(qbean, party)
|
||||
|
||||
qbean.run_method("onload_post_render")
|
||||
apply_cart_settings(party, qbean)
|
||||
|
||||
return qbean
|
||||
|
||||
def update_party(fullname, company_name=None, mobile_no=None, phone=None):
|
||||
party = get_lead_or_customer()
|
||||
|
||||
if party.doctype == "Lead":
|
||||
party.company_name = company_name
|
||||
party.lead_name = fullname
|
||||
party.mobile_no = mobile_no
|
||||
party.phone = phone
|
||||
else:
|
||||
party.customer_name = company_name or fullname
|
||||
party.customer_type == "Company" if company_name else "Individual"
|
||||
|
||||
contact_name = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user,
|
||||
"customer": party.name})
|
||||
contact = webnotes.bean("Contact", contact_name)
|
||||
contact.doc.first_name = fullname
|
||||
contact.doc.last_name = None
|
||||
contact.doc.customer_name = party.customer_name
|
||||
contact.doc.mobile_no = mobile_no
|
||||
contact.doc.phone = phone
|
||||
contact.ignore_permissions = True
|
||||
contact.save()
|
||||
|
||||
party_bean = webnotes.bean(party.fields)
|
||||
party_bean.ignore_permissions = True
|
||||
party_bean.save()
|
||||
|
||||
qbean = _get_cart_quotation(party)
|
||||
qbean.doc.customer_name = company_name or fullname
|
||||
qbean.run_method("set_contact_fields")
|
||||
qbean.ignore_permissions = True
|
||||
qbean.save()
|
||||
|
||||
def apply_cart_settings(party=None, quotation=None):
|
||||
if not party:
|
||||
party = get_lead_or_customer()
|
||||
@@ -237,8 +304,8 @@ def set_taxes(quotation, cart_settings, billing_territory):
|
||||
quotation.doc.charge = cart_settings.get_tax_master(billing_territory)
|
||||
|
||||
# clear table
|
||||
quotation.doclist = quotation.doc.clear_table(quotation.doclist, "other_charges")
|
||||
|
||||
quotation.set_doclist(quotation.doclist.get({"parentfield": ["!=", "other_charges"]}))
|
||||
|
||||
# append taxes
|
||||
controller = quotation.make_controller()
|
||||
controller.append_taxes_from_master("other_charges", "charge")
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
<div class="pull-right hide" style="margin:4px;" id="user-tools-post-login">
|
||||
<a href="profile" title="My Profile" id="user-full-name"></a> |
|
||||
<a href="account" title="My Account">My Account</a> |
|
||||
{% if shopping_cart_enabled -%}
|
||||
<a href="cart" title="Shopping Cart"><i class="icon-shopping-cart"></i>
|
||||
<span class="cart-count"></span></a> |
|
||||
{%- endif %}
|
||||
<a href="server.py?cmd=web_logout" title="Sign Out"><i class="icon-signout"></i></a>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<p class="help">Item Code: <span itemprop="productID">{{ name }}</span></p>
|
||||
<h4>Product Description</h4>
|
||||
<div itemprop="description">
|
||||
{{ web_long_description or web_short_description or
|
||||
{{ web_long_description or web_short_description or description or
|
||||
"[No description given]" }}
|
||||
</div>
|
||||
<div style="min-height: 100px; margin: 10px 0;">
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
// js inside blog page
|
||||
|
||||
$(document).ready(function() {
|
||||
// make list of items in the cart
|
||||
// wn.cart.render();
|
||||
wn.cart.bind_events();
|
||||
wn.call({
|
||||
type: "POST",
|
||||
@@ -36,6 +34,7 @@ $(document).ready(function() {
|
||||
wn.cart.show_error("Oops!", "Something went wrong.");
|
||||
}
|
||||
} else {
|
||||
wn.cart.set_cart_count();
|
||||
wn.cart.render(r.message);
|
||||
}
|
||||
}
|
||||
@@ -75,6 +74,10 @@ $.extend(wn.cart, {
|
||||
$("#cart-add-billing-address").on("click", function() {
|
||||
window.location.href = "address?address_fieldname=customer_address";
|
||||
});
|
||||
|
||||
$(".btn-place-order").on("click", function() {
|
||||
wn.cart.place_order();
|
||||
});
|
||||
},
|
||||
|
||||
render: function(out) {
|
||||
@@ -282,5 +285,27 @@ $.extend(wn.cart, {
|
||||
|
||||
$address_wrapper.find('.accordion-body[data-address-name="'+ address_name +'"]')
|
||||
.collapse("show");
|
||||
},
|
||||
|
||||
place_order: function() {
|
||||
wn.call({
|
||||
type: "POST",
|
||||
method: "website.helpers.cart.place_order",
|
||||
callback: function(r) {
|
||||
if(r.exc) {
|
||||
var msg = "";
|
||||
if(r._server_messages) {
|
||||
msg = JSON.parse(r._server_messages || []).join("<br>");
|
||||
}
|
||||
|
||||
$("#cart-error")
|
||||
.empty()
|
||||
.html(msg || "Something went wrong!")
|
||||
.toggle(true);
|
||||
} else {
|
||||
window.location.href = "order?name=" + encodeURIComponent(r.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -112,12 +112,4 @@
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
<style>
|
||||
fieldset {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
@@ -13,8 +13,9 @@
|
||||
<div class="progress-bar progress-bar-info" style="width: 100%;"></div>
|
||||
</div>
|
||||
<div id="cart-container" class="hide">
|
||||
<button class="btn btn-success pull-right" type="button">Place Order</button>
|
||||
<button class="btn btn-success pull-right btn-place-order" type="button">Place Order</button>
|
||||
<div class="clearfix"></div>
|
||||
<div id="cart-error" class="alert alert-danger" style="display: none;"></div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col col-lg-9 col-sm-9">
|
||||
@@ -50,7 +51,7 @@
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
<button class="btn btn-success pull-right" type="button">Place Order</button>
|
||||
<button class="btn btn-success pull-right btn-place-order" type="button">Place Order</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -12,24 +12,28 @@
|
||||
<h2><i class="icon-user"></i> My Profile</h2>
|
||||
<hr>
|
||||
<div class="alert" id="message" style="display: none;"></div>
|
||||
<form class="form-horizontal">
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="fullname">Full Name</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="fullname" placeholder="Your Name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="password">Password</label>
|
||||
<div class="controls">
|
||||
<input type="password" id="password" placeholder="Password">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<button id="update_profile" type="submit" class="btn btn-default">Update</button>
|
||||
</div>
|
||||
</div>
|
||||
<form>
|
||||
<fieldset>
|
||||
<label>Full Name</label>
|
||||
<input type="text" id="fullname" placeholder="Your Name">
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label>Password</label>
|
||||
<input type="password" id="password" placeholder="Password">
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label>Company Name</label>
|
||||
<input type="text" id="company_name" placeholder="Company Name" value="{{ company_name }}">
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label>Mobile No</label>
|
||||
<input type="text" id="mobile_no" placeholder="Mobile No" value="{{ mobile_no }}">
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label>Phone</label>
|
||||
<input type="text" id="phone" placeholder="Phone" value="{{ phone }}">
|
||||
</fieldset>
|
||||
<button id="update_profile" type="submit" class="btn btn-default">Update</button>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
@@ -37,11 +41,14 @@ $(document).ready(function() {
|
||||
$("#fullname").val(getCookie("full_name") || "");
|
||||
$("#update_profile").click(function() {
|
||||
wn.call({
|
||||
method: "core.doctype.profile.profile.update_profile",
|
||||
method: "startup.webutils.update_profile",
|
||||
type: "POST",
|
||||
args: {
|
||||
fullname: $("#fullname").val(),
|
||||
password: $("#password").val()
|
||||
password: $("#password").val(),
|
||||
company_name: $("#company_name").val(),
|
||||
mobile_no: $("#mobile_no").val(),
|
||||
phone: $("#phone").val()
|
||||
},
|
||||
btn: this,
|
||||
msg: $("#message"),
|
||||
@@ -53,4 +60,4 @@ $(document).ready(function() {
|
||||
})
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user