[pos][minor] fixed sales_invoice.js for pos view
This commit is contained in:
commit
f3eae2344b
@ -261,13 +261,11 @@ class DocType(BuyingController):
|
|||||||
if d.purchase_order:
|
if d.purchase_order:
|
||||||
submitted = sql("select name from `tabPurchase Order` where docstatus = 1 and name = '%s'" % d.purchase_order)
|
submitted = sql("select name from `tabPurchase Order` where docstatus = 1 and name = '%s'" % d.purchase_order)
|
||||||
if not submitted:
|
if not submitted:
|
||||||
msgprint("Purchase Order : "+ cstr(d.purchase_order) +" is not submitted")
|
webnotes.throw("Purchase Order : "+ cstr(d.purchase_order) +" is not submitted")
|
||||||
raise Exception , "Validation Error."
|
|
||||||
if d.purchase_receipt:
|
if d.purchase_receipt:
|
||||||
submitted = sql("select name from `tabPurchase Receipt` where docstatus = 1 and name = '%s'" % d.purchase_receipt)
|
submitted = sql("select name from `tabPurchase Receipt` where docstatus = 1 and name = '%s'" % d.purchase_receipt)
|
||||||
if not submitted:
|
if not submitted:
|
||||||
msgprint("Purchase Receipt : "+ cstr(d.purchase_receipt) +" is not submitted")
|
webnotes.throw("Purchase Receipt : "+ cstr(d.purchase_receipt) +" is not submitted")
|
||||||
raise Exception , "Validation Error."
|
|
||||||
|
|
||||||
|
|
||||||
def update_against_document_in_jv(self):
|
def update_against_document_in_jv(self):
|
||||||
|
@ -16,7 +16,7 @@ erpnext.POS = Class.extend({
|
|||||||
<div class="col-sm-6">\
|
<div class="col-sm-6">\
|
||||||
<div class="pos-bill">\
|
<div class="pos-bill">\
|
||||||
<div class="item-cart">\
|
<div class="item-cart">\
|
||||||
<table class="table table-condensed table-hover" id="cart" style="table-layout: fixed;">\
|
<table class="table table-condensed table-hover" id="cart" style="table-layout: fixed;">\
|
||||||
<thead>\
|
<thead>\
|
||||||
<tr>\
|
<tr>\
|
||||||
<th style="width: 50%">Item</th>\
|
<th style="width: 50%">Item</th>\
|
||||||
@ -160,13 +160,10 @@ erpnext.POS = Class.extend({
|
|||||||
parent: this.wrapper.find(".barcode-area")
|
parent: this.wrapper.find(".barcode-area")
|
||||||
});
|
});
|
||||||
this.barcode.make_input();
|
this.barcode.make_input();
|
||||||
this.barcode.$input.on("keypress", function() {
|
this.barcode.$input.on("change", function() {
|
||||||
setTimeout(function() { me.barcode_timeout(); }, 1000);
|
setTimeout(me.add_item_thru_barcode(), 1000);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
barcode_timeout: function() {
|
|
||||||
me.add_item_thru_barcode();
|
|
||||||
},
|
|
||||||
make_item_list: function() {
|
make_item_list: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
wn.call({
|
wn.call({
|
||||||
@ -181,12 +178,13 @@ erpnext.POS = Class.extend({
|
|||||||
me.wrapper.find(".item-list").empty();
|
me.wrapper.find(".item-list").empty();
|
||||||
$.each(r.message, function(index, obj) {
|
$.each(r.message, function(index, obj) {
|
||||||
if (obj.image)
|
if (obj.image)
|
||||||
image = '<img src="' + obj.image + '" class="img-responsive" style="border: 1px solid #eee;">';
|
image = '<img src="' + obj.image + '" class="img-responsive" \
|
||||||
|
style="border:1px solid #eee;height:140px;width:122px;">';
|
||||||
else
|
else
|
||||||
image = '<div class="missing-image"><i class="icon-camera"></i></div>';
|
image = '<div class="missing-image"><i class="icon-camera"></i></div>';
|
||||||
|
|
||||||
$(repl('<div class="col-xs-3 pos-item" data-item_code="%(item_code)s">\
|
$(repl('<div class="col-xs-3 pos-item" data-item_code="%(item_code)s">\
|
||||||
%(item_image)s\
|
<div>%(item_image)s</div>\
|
||||||
<div class="small">%(item_code)s</div>\
|
<div class="small">%(item_code)s</div>\
|
||||||
<div class="small">%(item_name)s</div>\
|
<div class="small">%(item_name)s</div>\
|
||||||
<div class="small">%(item_price)s</div>\
|
<div class="small">%(item_price)s</div>\
|
||||||
@ -332,7 +330,6 @@ erpnext.POS = Class.extend({
|
|||||||
},
|
},
|
||||||
add_item_thru_barcode: function() {
|
add_item_thru_barcode: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
clearTimeout();
|
|
||||||
wn.call({
|
wn.call({
|
||||||
method: 'accounts.doctype.sales_invoice.pos.get_item_from_barcode',
|
method: 'accounts.doctype.sales_invoice.pos.get_item_from_barcode',
|
||||||
args: {barcode: this.barcode.$input.val()},
|
args: {barcode: this.barcode.$input.val()},
|
||||||
@ -363,6 +360,7 @@ erpnext.POS = Class.extend({
|
|||||||
$.each(child, function(i, d) {
|
$.each(child, function(i, d) {
|
||||||
for (var i in selected_items) {
|
for (var i in selected_items) {
|
||||||
if (d.item_code == selected_items[i]) {
|
if (d.item_code == selected_items[i]) {
|
||||||
|
// cur_frm.fields_dict["entries"].grid.grid_rows[d.idx].remove();
|
||||||
wn.model.clear_doc(d.doctype, d.name);
|
wn.model.clear_doc(d.doctype, d.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -401,6 +399,7 @@ erpnext.POS = Class.extend({
|
|||||||
"total_amount": $(".grand-total").text()
|
"total_amount": $(".grand-total").text()
|
||||||
});
|
});
|
||||||
dialog.show();
|
dialog.show();
|
||||||
|
cur_frm.pos.barcode.$input.focus();
|
||||||
|
|
||||||
dialog.get_input("total_amount").attr("disabled", "disabled");
|
dialog.get_input("total_amount").attr("disabled", "disabled");
|
||||||
|
|
||||||
|
@ -93,14 +93,13 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (cint(sys_defaults.fs_pos_view)===1)
|
|
||||||
cur_frm.cscript.pos_btn();
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// hide shown pos for submitted records
|
// hide shown pos for submitted records
|
||||||
if(cur_frm.pos_active) cur_frm.cscript.toggle_pos(false);
|
if(cur_frm.pos_active) cur_frm.cscript.toggle_pos(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(cint(sys_defaults.fs_pos_view)===1)
|
||||||
|
cur_frm.cscript.pos_btn();
|
||||||
},
|
},
|
||||||
|
|
||||||
pos_btn: function() {
|
pos_btn: function() {
|
||||||
@ -123,6 +122,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
},
|
},
|
||||||
|
|
||||||
toggle_pos: function(show) {
|
toggle_pos: function(show) {
|
||||||
|
// if(cint(sys_defaults.fs_pos_view)===0) return;
|
||||||
|
// if(!(this.frm.doc.is_pos && this.frm.doc.docstatus===0)) return;
|
||||||
|
|
||||||
if (!this.frm.doc.selling_price_list)
|
if (!this.frm.doc.selling_price_list)
|
||||||
msgprint(wn._("Please select Price List"))
|
msgprint(wn._("Please select Price List"))
|
||||||
else {
|
else {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"app_name": "ERPNext",
|
||||||
"modules": {
|
"modules": {
|
||||||
"Selling": {
|
"Selling": {
|
||||||
"link": "selling-home",
|
"link": "selling-home",
|
||||||
|
@ -95,7 +95,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
|||||||
return{
|
return{
|
||||||
query : "selling.doctype.sales_common.sales_common.get_batch_no",
|
query : "selling.doctype.sales_common.sales_common.get_batch_no",
|
||||||
filters: {
|
filters: {
|
||||||
'item': item.item_code,
|
'item_code': item.item_code,
|
||||||
'posting_date': me.frm.doc.posting_date
|
'posting_date': me.frm.doc.posting_date
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,7 +340,7 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
and batch_no like '%(txt)s'
|
and batch_no like '%(txt)s'
|
||||||
and exists(select * from `tabBatch`
|
and exists(select * from `tabBatch`
|
||||||
where name = sle.batch_no
|
where name = sle.batch_no
|
||||||
and expiry_date >= '%(posting_date)s'
|
and (ifnull(expiry_date, '')='' or expiry_date >= '%(posting_date)s')
|
||||||
and docstatus != 2)
|
and docstatus != 2)
|
||||||
%(mcond)s
|
%(mcond)s
|
||||||
group by batch_no having sum(actual_qty) > 0
|
group by batch_no having sum(actual_qty) > 0
|
||||||
@ -353,7 +353,7 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
return webnotes.conn.sql("""select name from tabBatch
|
return webnotes.conn.sql("""select name from tabBatch
|
||||||
where docstatus != 2
|
where docstatus != 2
|
||||||
and item = '%(item_code)s'
|
and item = '%(item_code)s'
|
||||||
and expiry_date >= '%(posting_date)s'
|
and (ifnull(expiry_date, '')='' or expiry_date >= '%(posting_date)s')
|
||||||
and name like '%(txt)s'
|
and name like '%(txt)s'
|
||||||
%(mcond)s
|
%(mcond)s
|
||||||
order by name desc
|
order by name desc
|
||||||
|
@ -128,6 +128,7 @@ class DocType(SellingController):
|
|||||||
self.validate_po()
|
self.validate_po()
|
||||||
self.validate_uom_is_integer("stock_uom", "qty")
|
self.validate_uom_is_integer("stock_uom", "qty")
|
||||||
self.validate_for_items()
|
self.validate_for_items()
|
||||||
|
self.validate_warehouse_user()
|
||||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||||
sales_com_obj.check_active_sales_items(self)
|
sales_com_obj.check_active_sales_items(self)
|
||||||
sales_com_obj.check_conversion_rate(self)
|
sales_com_obj.check_conversion_rate(self)
|
||||||
@ -147,6 +148,16 @@ class DocType(SellingController):
|
|||||||
if not self.doc.billing_status: self.doc.billing_status = 'Not Billed'
|
if not self.doc.billing_status: self.doc.billing_status = 'Not Billed'
|
||||||
if not self.doc.delivery_status: self.doc.delivery_status = 'Not Delivered'
|
if not self.doc.delivery_status: self.doc.delivery_status = 'Not Delivered'
|
||||||
|
|
||||||
|
|
||||||
|
def validate_warehouse_user(self):
|
||||||
|
from stock.utils import validate_warehouse_user
|
||||||
|
|
||||||
|
warehouses = list(set([d.reserved_warehouse for d in
|
||||||
|
self.doclist.get({"doctype": self.tname}) if d.reserved_warehouse]))
|
||||||
|
|
||||||
|
for w in warehouses:
|
||||||
|
validate_warehouse_user(w)
|
||||||
|
|
||||||
def validate_with_previous_doc(self):
|
def validate_with_previous_doc(self):
|
||||||
super(DocType, self).validate_with_previous_doc(self.tname, {
|
super(DocType, self).validate_with_previous_doc(self.tname, {
|
||||||
"Quotation": {
|
"Quotation": {
|
||||||
|
@ -272,6 +272,29 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
self.check_reserved_qty(sbom_test_records[0][2]["item_code"],
|
self.check_reserved_qty(sbom_test_records[0][2]["item_code"],
|
||||||
so.doclist[1].reserved_warehouse, 20.0)
|
so.doclist[1].reserved_warehouse, 20.0)
|
||||||
|
|
||||||
|
def test_warehouse_user(self):
|
||||||
|
webnotes.session.user = "test@example.com"
|
||||||
|
|
||||||
|
webnotes.bean("Profile", "test@example.com").get_controller()\
|
||||||
|
.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
|
||||||
|
|
||||||
|
webnotes.bean("Profile", "test2@example.com").get_controller()\
|
||||||
|
.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
|
||||||
|
|
||||||
|
|
||||||
|
from stock.utils import UserNotAllowedForWarehouse
|
||||||
|
so = webnotes.bean(copy = test_records[0])
|
||||||
|
so.doc.company = "_Test Company 1"
|
||||||
|
so.doc.conversion_rate = 0.02
|
||||||
|
so.doc.plc_conversion_rate = 0.02
|
||||||
|
so.doclist[1].reserved_warehouse = "_Test Warehouse 2 - _TC1"
|
||||||
|
self.assertRaises(UserNotAllowedForWarehouse, so.insert)
|
||||||
|
|
||||||
|
webnotes.session.user = "test2@example.com"
|
||||||
|
so.insert()
|
||||||
|
|
||||||
|
webnotes.session.user = "Administrator"
|
||||||
|
|
||||||
test_dependencies = ["Sales BOM"]
|
test_dependencies = ["Sales BOM"]
|
||||||
|
|
||||||
test_records = [
|
test_records = [
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
|
||||||
// License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
// render
|
|
||||||
wn.listview_settings['Purchase Receipt'] = {
|
|
||||||
add_fields: ["group_concat(`tabPurchase Receipt Item`.prevdoc_docname) \
|
|
||||||
as purchase_order_no"],
|
|
||||||
add_columns: [{"content":"purchase_order_no", width:"30%"}],
|
|
||||||
group_by: "`tabPurchase Receipt`.name",
|
|
||||||
prepare_data: function(data) {
|
|
||||||
if(data.purchase_order_no) {
|
|
||||||
data.purchase_order_no = $.unique(data.purchase_order_no.split(","));
|
|
||||||
var po_list = [];
|
|
||||||
$.each(data.purchase_order_no, function(i, v){
|
|
||||||
if(po_list.indexOf(v)==-1) po_list.push(
|
|
||||||
repl("<a href=\"#Form/Purchase Order/%(name)s\">%(name)s</a>",
|
|
||||||
{name: v}));
|
|
||||||
});
|
|
||||||
data.purchase_order_no = po_list.join(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
@ -41,12 +41,43 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
webnotes.conn.set_default("company", self.old_default_company)
|
webnotes.conn.set_default("company", self.old_default_company)
|
||||||
|
|
||||||
def test_warehouse_company_validation(self):
|
def test_warehouse_company_validation(self):
|
||||||
|
webnotes.session.user = "test2@example.com"
|
||||||
|
webnotes.bean("Profile", "test2@example.com").get_controller()\
|
||||||
|
.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
|
||||||
|
|
||||||
from stock.doctype.stock_ledger_entry.stock_ledger_entry import InvalidWarehouseCompany
|
from stock.doctype.stock_ledger_entry.stock_ledger_entry import InvalidWarehouseCompany
|
||||||
st1 = webnotes.bean(copy=test_records[0])
|
st1 = webnotes.bean(copy=test_records[0])
|
||||||
st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1"
|
st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1"
|
||||||
st1.insert()
|
st1.insert()
|
||||||
self.assertRaises(InvalidWarehouseCompany, st1.submit)
|
self.assertRaises(InvalidWarehouseCompany, st1.submit)
|
||||||
|
|
||||||
|
webnotes.session.user = "Administrator"
|
||||||
|
|
||||||
|
def test_warehouse_user(self):
|
||||||
|
from stock.utils import UserNotAllowedForWarehouse
|
||||||
|
|
||||||
|
webnotes.session.user = "test@example.com"
|
||||||
|
webnotes.bean("Profile", "test@example.com").get_controller()\
|
||||||
|
.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
|
||||||
|
|
||||||
|
webnotes.bean("Profile", "test2@example.com").get_controller()\
|
||||||
|
.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
|
||||||
|
|
||||||
|
st1 = webnotes.bean(copy=test_records[0])
|
||||||
|
st1.doc.company = "_Test Company 1"
|
||||||
|
st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1"
|
||||||
|
st1.insert()
|
||||||
|
self.assertRaises(UserNotAllowedForWarehouse, st1.submit)
|
||||||
|
|
||||||
|
webnotes.session.user = "test2@example.com"
|
||||||
|
st1 = webnotes.bean(copy=test_records[0])
|
||||||
|
st1.doc.company = "_Test Company 1"
|
||||||
|
st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1"
|
||||||
|
st1.insert()
|
||||||
|
st1.submit()
|
||||||
|
|
||||||
|
webnotes.session.user = "Administrator"
|
||||||
|
|
||||||
def test_material_receipt_gl_entry(self):
|
def test_material_receipt_gl_entry(self):
|
||||||
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
|
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
|
||||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
||||||
|
@ -25,12 +25,14 @@ class DocType(DocListController):
|
|||||||
self.doclist = doclist
|
self.doclist = doclist
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
|
from stock.utils import validate_warehouse_user
|
||||||
if not hasattr(webnotes, "new_stock_ledger_entries"):
|
if not hasattr(webnotes, "new_stock_ledger_entries"):
|
||||||
webnotes.new_stock_ledger_entries = []
|
webnotes.new_stock_ledger_entries = []
|
||||||
|
|
||||||
webnotes.new_stock_ledger_entries.append(self.doc)
|
webnotes.new_stock_ledger_entries.append(self.doc)
|
||||||
self.validate_mandatory()
|
self.validate_mandatory()
|
||||||
self.validate_item()
|
self.validate_item()
|
||||||
self.validate_warehouse_user()
|
validate_warehouse_user(self.doc.warehouse)
|
||||||
self.validate_warehouse_company()
|
self.validate_warehouse_company()
|
||||||
self.actual_amt_check()
|
self.actual_amt_check()
|
||||||
self.check_stock_frozen_date()
|
self.check_stock_frozen_date()
|
||||||
@ -52,16 +54,6 @@ class DocType(DocListController):
|
|||||||
|
|
||||||
self.doc.fields.pop('batch_bal')
|
self.doc.fields.pop('batch_bal')
|
||||||
|
|
||||||
def validate_warehouse_user(self):
|
|
||||||
if webnotes.session.user=="Administrator":
|
|
||||||
return
|
|
||||||
warehouse_users = [p[0] for p in webnotes.conn.sql("""select user from `tabWarehouse User`
|
|
||||||
where parent=%s""", self.doc.warehouse)]
|
|
||||||
|
|
||||||
if warehouse_users and not webnotes.session.user in warehouse_users:
|
|
||||||
webnotes.msgprint(_("User not allowed entry in the Warehouse") \
|
|
||||||
+ ": " + webnotes.session.user + " / " + self.doc.warehouse, raise_exception = 1)
|
|
||||||
|
|
||||||
def validate_warehouse_company(self):
|
def validate_warehouse_company(self):
|
||||||
warehouse_company = webnotes.conn.get_value("Warehouse", self.doc.warehouse, "company")
|
warehouse_company = webnotes.conn.get_value("Warehouse", self.doc.warehouse, "company")
|
||||||
if warehouse_company and warehouse_company != self.doc.company:
|
if warehouse_company and warehouse_company != self.doc.company:
|
||||||
|
@ -16,5 +16,9 @@ test_records = [
|
|||||||
"doctype": "Warehouse",
|
"doctype": "Warehouse",
|
||||||
"warehouse_name": "_Test Warehouse 2",
|
"warehouse_name": "_Test Warehouse 2",
|
||||||
"company": "_Test Company 1"
|
"company": "_Test Company 1"
|
||||||
|
}, {
|
||||||
|
"doctype": "Warehouse User",
|
||||||
|
"parentfield": "warehouse_users",
|
||||||
|
"user": "test2@example.com"
|
||||||
}]
|
}]
|
||||||
]
|
]
|
||||||
|
@ -8,6 +8,8 @@ from webnotes.utils import flt, cstr, nowdate, add_days, cint
|
|||||||
from webnotes.defaults import get_global_default
|
from webnotes.defaults import get_global_default
|
||||||
from webnotes.utils.email_lib import sendmail
|
from webnotes.utils.email_lib import sendmail
|
||||||
|
|
||||||
|
class UserNotAllowedForWarehouse(webnotes.ValidationError): pass
|
||||||
|
|
||||||
def validate_end_of_life(item_code, end_of_life=None, verbose=1):
|
def validate_end_of_life(item_code, end_of_life=None, verbose=1):
|
||||||
if not end_of_life:
|
if not end_of_life:
|
||||||
end_of_life = webnotes.conn.get_value("Item", item_code, "end_of_life")
|
end_of_life = webnotes.conn.get_value("Item", item_code, "end_of_life")
|
||||||
@ -152,6 +154,16 @@ def get_warehouse_list(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
wlist.append([w])
|
wlist.append([w])
|
||||||
return wlist
|
return wlist
|
||||||
|
|
||||||
|
def validate_warehouse_user(warehouse):
|
||||||
|
if webnotes.session.user=="Administrator":
|
||||||
|
return
|
||||||
|
warehouse_users = [p[0] for p in webnotes.conn.sql("""select user from `tabWarehouse User`
|
||||||
|
where parent=%s""", warehouse)]
|
||||||
|
|
||||||
|
if warehouse_users and not (webnotes.session.user in warehouse_users):
|
||||||
|
webnotes.throw(_("Not allowed entry in Warehouse") \
|
||||||
|
+ ": " + warehouse, UserNotAllowedForWarehouse)
|
||||||
|
|
||||||
def get_buying_amount(item_code, voucher_type, voucher_no, voucher_detail_no,
|
def get_buying_amount(item_code, voucher_type, voucher_no, voucher_detail_no,
|
||||||
stock_ledger_entries, item_sales_bom=None):
|
stock_ledger_entries, item_sales_bom=None):
|
||||||
if item_sales_bom and item_sales_bom.get(item_code):
|
if item_sales_bom and item_sales_bom.get(item_code):
|
||||||
|
0
utilities/demo/__init__.py
Normal file
0
utilities/demo/__init__.py
Normal file
3
utilities/demo/demo-login.css
Normal file
3
utilities/demo/demo-login.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
body, #container, .outer {
|
||||||
|
background-color: #888 !important;
|
||||||
|
}
|
25
utilities/demo/demo-login.html
Normal file
25
utilities/demo/demo-login.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<div class="container">
|
||||||
|
<div class="row" style="margin-top: 100px;">
|
||||||
|
<div class="col-sm-offset-3 col-sm-6">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
Start ERPNext Demo
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<p>
|
||||||
|
<input id="lead-email" type="email"
|
||||||
|
class="form-control" placeholder="Your Email Id">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<button type="submit" id="login_btn"
|
||||||
|
class="btn btn-primary btn-large">Launch Demo</button>
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<p class="text-muted small">Some functionality is disabled for the demo app. The demo data will be cleared regulary. To start your own ERPNext Trial, <a href="https://erpnext.com/pricing-and-signup">click here</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
</div>
|
||||||
|
</div>
|
27
utilities/demo/demo-login.js
Normal file
27
utilities/demo/demo-login.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
$(document).ready(function() {
|
||||||
|
$(".navbar, footer, .banner, #user-tools").toggle(false);
|
||||||
|
|
||||||
|
$("#login_btn").click(function() {
|
||||||
|
var me = this;
|
||||||
|
$(this).html("Logging In...").attr("disabled", "disabled");
|
||||||
|
wn.call({
|
||||||
|
"method": "login",
|
||||||
|
args: {
|
||||||
|
usr: "demo@erpnext.com",
|
||||||
|
pwd: "demo",
|
||||||
|
lead_email: $("#lead-email").val(),
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
$(me).attr("disabled", false);
|
||||||
|
if(r.exc) {
|
||||||
|
alert("Error, please contact support@erpnext.com");
|
||||||
|
} else {
|
||||||
|
console.log("Logged In");
|
||||||
|
window.location.href = "app.html";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
.attr("disabled", false);
|
||||||
|
})
|
13
utilities/demo/demo_control_panel.py
Normal file
13
utilities/demo/demo_control_panel.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
def on_login(self):
|
||||||
|
from webnotes.utils import validate_email_add
|
||||||
|
import conf
|
||||||
|
if hasattr(conf, "demo_notify_url"):
|
||||||
|
if webnotes.form_dict.lead_email and validate_email_add(webnotes.form_dict.lead_email):
|
||||||
|
import requests
|
||||||
|
response = requests.post(conf.demo_notify_url, data={
|
||||||
|
"cmd":"website.helpers.contact.send_message",
|
||||||
|
"subject":"Logged into Demo",
|
||||||
|
"sender": webnotes.form_dict.lead_email,
|
||||||
|
"message": "via demo.erpnext.com"
|
||||||
|
})
|
Can't render this file because it has a wrong number of fields in line 2.
|
Before Width: | Height: | Size: 221 KiB After Width: | Height: | Size: 221 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
@ -19,9 +19,9 @@ company_abbr = "WP"
|
|||||||
country = "United States"
|
country = "United States"
|
||||||
currency = "USD"
|
currency = "USD"
|
||||||
time_zone = "America/New York"
|
time_zone = "America/New York"
|
||||||
start_date = '2010-01-01'
|
start_date = '2013-01-01'
|
||||||
bank_name = "Citibank"
|
bank_name = "Citibank"
|
||||||
runs_for = 20
|
runs_for = None
|
||||||
prob = {
|
prob = {
|
||||||
"default": { "make": 0.6, "qty": (1,5) },
|
"default": { "make": 0.6, "qty": (1,5) },
|
||||||
"Sales Order": { "make": 0.4, "qty": (1,3) },
|
"Sales Order": { "make": 0.4, "qty": (1,3) },
|
||||||
@ -50,21 +50,24 @@ def setup():
|
|||||||
# make_opening_accounts()
|
# make_opening_accounts()
|
||||||
|
|
||||||
def simulate():
|
def simulate():
|
||||||
current_date = None
|
global runs_for
|
||||||
for i in xrange(runs_for):
|
current_date = webnotes.utils.getdate(start_date)
|
||||||
if not current_date:
|
|
||||||
# get last stock ledger posting date or use default
|
|
||||||
last_posting = webnotes.conn.sql("""select max(posting_date) from `tabStock Ledger Entry`""")
|
|
||||||
if last_posting[0][0]:
|
|
||||||
current_date = webnotes.utils.add_days(last_posting[0][0], 1)
|
|
||||||
else:
|
|
||||||
current_date = webnotes.utils.getdate(start_date)
|
|
||||||
else:
|
|
||||||
current_date = webnotes.utils.add_days(current_date, 1)
|
|
||||||
|
|
||||||
|
# continue?
|
||||||
|
last_posting = webnotes.conn.sql("""select max(posting_date) from `tabStock Ledger Entry`""")
|
||||||
|
if last_posting[0][0]:
|
||||||
|
current_date = webnotes.utils.add_days(last_posting[0][0], 1)
|
||||||
|
|
||||||
|
# run till today
|
||||||
|
if not runs_for:
|
||||||
|
runs_for = webnotes.utils.date_diff(webnotes.utils.nowdate(), current_date)
|
||||||
|
|
||||||
|
for i in xrange(runs_for):
|
||||||
print current_date.strftime("%Y-%m-%d")
|
print current_date.strftime("%Y-%m-%d")
|
||||||
|
webnotes.utils.current_date = current_date
|
||||||
|
|
||||||
if current_date.weekday() in (5, 6):
|
if current_date.weekday() in (5, 6):
|
||||||
|
current_date = webnotes.utils.add_days(current_date, 1)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
run_sales(current_date)
|
run_sales(current_date)
|
||||||
@ -73,6 +76,8 @@ def simulate():
|
|||||||
run_stock(current_date)
|
run_stock(current_date)
|
||||||
run_accounts(current_date)
|
run_accounts(current_date)
|
||||||
|
|
||||||
|
current_date = webnotes.utils.add_days(current_date, 1)
|
||||||
|
|
||||||
def run_sales(current_date):
|
def run_sales(current_date):
|
||||||
if can_make("Quotation"):
|
if can_make("Quotation"):
|
||||||
for i in xrange(how_many("Quotation")):
|
for i in xrange(how_many("Quotation")):
|
||||||
@ -136,7 +141,7 @@ def run_stock(current_date):
|
|||||||
for po in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Purchase Receipt")]:
|
for po in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Purchase Receipt")]:
|
||||||
pr = webnotes.bean(make_purchase_receipt(po))
|
pr = webnotes.bean(make_purchase_receipt(po))
|
||||||
pr.doc.posting_date = current_date
|
pr.doc.posting_date = current_date
|
||||||
pr.doc.fiscal_year = "2010"
|
pr.doc.fiscal_year = "2013"
|
||||||
pr.insert()
|
pr.insert()
|
||||||
pr.submit()
|
pr.submit()
|
||||||
webnotes.conn.commit()
|
webnotes.conn.commit()
|
||||||
@ -150,7 +155,7 @@ def run_stock(current_date):
|
|||||||
for so in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Delivery Note")]:
|
for so in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Delivery Note")]:
|
||||||
dn = webnotes.bean(make_delivery_note(so))
|
dn = webnotes.bean(make_delivery_note(so))
|
||||||
dn.doc.posting_date = current_date
|
dn.doc.posting_date = current_date
|
||||||
dn.doc.fiscal_year = "2010"
|
dn.doc.fiscal_year = "2013"
|
||||||
dn.insert()
|
dn.insert()
|
||||||
try:
|
try:
|
||||||
dn.submit()
|
dn.submit()
|
||||||
@ -173,7 +178,7 @@ def run_purchase(current_date):
|
|||||||
mr = webnotes.new_bean("Material Request")
|
mr = webnotes.new_bean("Material Request")
|
||||||
mr.doc.material_request_type = "Purchase"
|
mr.doc.material_request_type = "Purchase"
|
||||||
mr.doc.transaction_date = current_date
|
mr.doc.transaction_date = current_date
|
||||||
mr.doc.fiscal_year = "2010"
|
mr.doc.fiscal_year = "2013"
|
||||||
mr.doclist.append({
|
mr.doclist.append({
|
||||||
"doctype": "Material Request Item",
|
"doctype": "Material Request Item",
|
||||||
"parentfield": "indent_details",
|
"parentfield": "indent_details",
|
||||||
@ -192,7 +197,7 @@ def run_purchase(current_date):
|
|||||||
if row[0] != "Total":
|
if row[0] != "Total":
|
||||||
sq = webnotes.bean(make_supplier_quotation(row[0]))
|
sq = webnotes.bean(make_supplier_quotation(row[0]))
|
||||||
sq.doc.transaction_date = current_date
|
sq.doc.transaction_date = current_date
|
||||||
sq.doc.fiscal_year = "2010"
|
sq.doc.fiscal_year = "2013"
|
||||||
sq.insert()
|
sq.insert()
|
||||||
sq.submit()
|
sq.submit()
|
||||||
webnotes.conn.commit()
|
webnotes.conn.commit()
|
||||||
@ -205,7 +210,7 @@ def run_purchase(current_date):
|
|||||||
if row[0] != "Total":
|
if row[0] != "Total":
|
||||||
po = webnotes.bean(make_purchase_order(row[0]))
|
po = webnotes.bean(make_purchase_order(row[0]))
|
||||||
po.doc.transaction_date = current_date
|
po.doc.transaction_date = current_date
|
||||||
po.doc.fiscal_year = "2010"
|
po.doc.fiscal_year = "2013"
|
||||||
po.insert()
|
po.insert()
|
||||||
po.submit()
|
po.submit()
|
||||||
webnotes.conn.commit()
|
webnotes.conn.commit()
|
||||||
@ -261,11 +266,11 @@ def make_stock_entry_from_pro(pro_id, purpose, current_date):
|
|||||||
from stock.stock_ledger import NegativeStockError
|
from stock.stock_ledger import NegativeStockError
|
||||||
from stock.doctype.stock_entry.stock_entry import IncorrectValuationRateError, DuplicateEntryForProductionOrderError
|
from stock.doctype.stock_entry.stock_entry import IncorrectValuationRateError, DuplicateEntryForProductionOrderError
|
||||||
|
|
||||||
st = webnotes.bean(make_stock_entry(pro_id, purpose))
|
|
||||||
st.doc.posting_date = current_date
|
|
||||||
st.doc.fiscal_year = "2010"
|
|
||||||
st.doc.expense_adjustment_account = "Stock in Hand - WP"
|
|
||||||
try:
|
try:
|
||||||
|
st = webnotes.bean(make_stock_entry(pro_id, purpose))
|
||||||
|
st.doc.posting_date = current_date
|
||||||
|
st.doc.fiscal_year = "2013"
|
||||||
|
st.doc.expense_adjustment_account = "Stock in Hand - WP"
|
||||||
st.insert()
|
st.insert()
|
||||||
webnotes.conn.commit()
|
webnotes.conn.commit()
|
||||||
st.submit()
|
st.submit()
|
||||||
@ -282,7 +287,7 @@ def make_quotation(current_date):
|
|||||||
"customer": get_random("Customer"),
|
"customer": get_random("Customer"),
|
||||||
"order_type": "Sales",
|
"order_type": "Sales",
|
||||||
"transaction_date": current_date,
|
"transaction_date": current_date,
|
||||||
"fiscal_year": "2010"
|
"fiscal_year": "2013"
|
||||||
}])
|
}])
|
||||||
|
|
||||||
add_random_children(b, {
|
add_random_children(b, {
|
||||||
@ -349,8 +354,9 @@ def how_many(doctype):
|
|||||||
def install():
|
def install():
|
||||||
print "Creating Fresh Database..."
|
print "Creating Fresh Database..."
|
||||||
from webnotes.install_lib.install import Installer
|
from webnotes.install_lib.install import Installer
|
||||||
|
import conf
|
||||||
inst = Installer('root')
|
inst = Installer('root')
|
||||||
inst.import_from_db("demo", verbose = 1)
|
inst.import_from_db(conf.demo_db_name, verbose = 1)
|
||||||
|
|
||||||
def complete_setup():
|
def complete_setup():
|
||||||
print "Complete Setup..."
|
print "Complete Setup..."
|
||||||
@ -392,6 +398,7 @@ def make_bank_account():
|
|||||||
}).insert()
|
}).insert()
|
||||||
|
|
||||||
webnotes.set_value("Company", company, "default_bank_account", ba.doc.name)
|
webnotes.set_value("Company", company, "default_bank_account", ba.doc.name)
|
||||||
|
webnotes.conn.commit()
|
||||||
|
|
||||||
def import_data(dt, submit=False):
|
def import_data(dt, submit=False):
|
||||||
if not isinstance(dt, (tuple, list)):
|
if not isinstance(dt, (tuple, list)):
|
||||||
@ -399,7 +406,7 @@ def import_data(dt, submit=False):
|
|||||||
|
|
||||||
for doctype in dt:
|
for doctype in dt:
|
||||||
print "Importing", doctype.replace("_", " "), "..."
|
print "Importing", doctype.replace("_", " "), "..."
|
||||||
webnotes.form_dict = {}
|
webnotes.form_dict = webnotes._dict()
|
||||||
if submit:
|
if submit:
|
||||||
webnotes.form_dict["params"] = json.dumps({"_submit": 1})
|
webnotes.form_dict["params"] = json.dumps({"_submit": 1})
|
||||||
webnotes.uploaded_file = os.path.join(os.path.dirname(__file__), "demo_docs", doctype+".csv")
|
webnotes.uploaded_file = os.path.join(os.path.dirname(__file__), "demo_docs", doctype+".csv")
|
117
utilities/demo/make_erpnext_demo.py
Normal file
117
utilities/demo/make_erpnext_demo.py
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
if __name__=="__main__":
|
||||||
|
import sys
|
||||||
|
sys.path.extend([".", "lib", "app"])
|
||||||
|
|
||||||
|
import webnotes, os
|
||||||
|
|
||||||
|
def make_demo_app():
|
||||||
|
import utilities.demo.make_demo
|
||||||
|
utilities.demo.make_demo.make(reset=True)
|
||||||
|
|
||||||
|
def make_demo_user():
|
||||||
|
roles = ["Accounts Manager", "Analytics", "Expense Approver", "Accounts User",
|
||||||
|
"Leave Approver", "Blogger", "Customer", "Sales Manager", "Employee", "Support Manager",
|
||||||
|
"HR Manager", "HR User", "Maintenance Manager", "Maintenance User", "Material Manager",
|
||||||
|
"Material Master Manager", "Material User", "Partner", "Manufacturing Manager",
|
||||||
|
"Manufacturing User", "Projects User", "Purchase Manager", "Purchase Master Manager",
|
||||||
|
"Purchase User", "Quality Manager", "Report Manager", "Sales Master Manager",
|
||||||
|
"Sales User", "Supplier", "Support Team"]
|
||||||
|
|
||||||
|
def add_roles(bean):
|
||||||
|
for role in roles:
|
||||||
|
p.doclist.append({
|
||||||
|
"doctype": "UserRole",
|
||||||
|
"parentfield": "user_roles",
|
||||||
|
"role": role
|
||||||
|
})
|
||||||
|
|
||||||
|
# make demo user
|
||||||
|
if webnotes.conn.exists("Profile", "demo@erpnext.com"):
|
||||||
|
webnotes.delete_doc("Profile", "demo@erpnext.com")
|
||||||
|
|
||||||
|
p = webnotes.new_bean("Profile")
|
||||||
|
p.doc.email = "demo@erpnext.com"
|
||||||
|
p.doc.first_name = "Demo"
|
||||||
|
p.doc.last_name = "User"
|
||||||
|
p.doc.enabled = 1
|
||||||
|
p.doc.user_type = "ERPNext Demo"
|
||||||
|
p.doc.send_invite_email = 0
|
||||||
|
p.doc.new_password = "demo"
|
||||||
|
p.insert()
|
||||||
|
add_roles(p)
|
||||||
|
p.save()
|
||||||
|
|
||||||
|
# make system manager user
|
||||||
|
if webnotes.conn.exists("Profile", "admin@erpnext.com"):
|
||||||
|
webnotes.delete_doc("Profile", "admin@erpnext.com")
|
||||||
|
|
||||||
|
p = webnotes.new_bean("Profile")
|
||||||
|
p.doc.email = "admin@erpnext.com"
|
||||||
|
p.doc.first_name = "Admin"
|
||||||
|
p.doc.last_name = "User"
|
||||||
|
p.doc.enabled = 1
|
||||||
|
p.doc.user_type = "System User"
|
||||||
|
p.doc.send_invite_email = 0
|
||||||
|
p.doc.new_password = "admin010123"
|
||||||
|
p.insert()
|
||||||
|
roles.append("System Manager")
|
||||||
|
add_roles(p)
|
||||||
|
p.save()
|
||||||
|
|
||||||
|
# only read for newsletter
|
||||||
|
webnotes.conn.sql("""update `tabDocPerm` set `write`=0, `create`=0, `cancel`=0
|
||||||
|
where parent='Newsletter'""")
|
||||||
|
webnotes.conn.sql("""update `tabDocPerm` set `write`=0, `create`=0, `cancel`=0
|
||||||
|
where parent='Profile' and role='All'""")
|
||||||
|
|
||||||
|
webnotes.conn.commit()
|
||||||
|
|
||||||
|
def make_demo_login_page():
|
||||||
|
webnotes.conn.set_value("Website Settings", None, "home_page", "")
|
||||||
|
|
||||||
|
webnotes.conn.sql("""delete from `tabWeb Page` where name='demo-login'""")
|
||||||
|
p = webnotes.new_bean("Web Page")
|
||||||
|
p.doc.title = "Demo Login"
|
||||||
|
p.doc.published = 1
|
||||||
|
p.doc.description = "ERPNext Demo Login"
|
||||||
|
|
||||||
|
with open(os.path.join(os.path.dirname(__file__), "demo-login.html"), "r") as dfile:
|
||||||
|
p.doc.main_section = dfile.read()
|
||||||
|
|
||||||
|
p.doc.insert_code = 1
|
||||||
|
with open(os.path.join(os.path.dirname(__file__), "demo-login.js"), "r") as dfile:
|
||||||
|
p.doc.javascript = dfile.read()
|
||||||
|
|
||||||
|
p.doc.insert_style = 1
|
||||||
|
with open(os.path.join(os.path.dirname(__file__), "demo-login.css"), "r") as dfile:
|
||||||
|
p.doc.css = dfile.read()
|
||||||
|
|
||||||
|
p.insert()
|
||||||
|
|
||||||
|
webnotes.conn.set_value("Website Settings", None, "home_page", "demo-login")
|
||||||
|
webnotes.conn.set_value("Website Settings", None, "disable_signup", 1)
|
||||||
|
|
||||||
|
webnotes.conn.commit()
|
||||||
|
|
||||||
|
def make_demo_on_login_script():
|
||||||
|
webnotes.conn.sql("""delete from `tabCustom Script` where dt='Control Panel'""")
|
||||||
|
s = webnotes.new_bean("Custom Script")
|
||||||
|
s.doc.dt = "Control Panel"
|
||||||
|
s.doc.script_type = "Server"
|
||||||
|
with open(os.path.join(os.path.dirname(__file__), "demo_control_panel.py"), "r") as dfile:
|
||||||
|
s.doc.script = dfile.read()
|
||||||
|
s.insert()
|
||||||
|
|
||||||
|
cp = webnotes.bean("Control Panel")
|
||||||
|
cp.doc.custom_startup_code = """wn.ui.toolbar.show_banner('You are using ERPNext Demo. To start your own ERPNext Trial, <a href="https://erpnext.com/pricing-and-signup" target="_blank">click here</a>')"""
|
||||||
|
cp.save()
|
||||||
|
|
||||||
|
webnotes.conn.commit()
|
||||||
|
|
||||||
|
if __name__=="__main__":
|
||||||
|
# webnotes.connect()
|
||||||
|
webnotes.mute_emails = 1
|
||||||
|
make_demo_app()
|
||||||
|
make_demo_user()
|
||||||
|
make_demo_login_page()
|
||||||
|
make_demo_on_login_script()
|
@ -55,6 +55,8 @@ class TransactionBase(StatusUpdater):
|
|||||||
return self._party_type_and_name
|
return self._party_type_and_name
|
||||||
|
|
||||||
def get_customer_defaults(self):
|
def get_customer_defaults(self):
|
||||||
|
if not self.doc.customer: return {}
|
||||||
|
|
||||||
out = self.get_default_address_and_contact("customer")
|
out = self.get_default_address_and_contact("customer")
|
||||||
|
|
||||||
customer = webnotes.doc("Customer", self.doc.customer)
|
customer = webnotes.doc("Customer", self.doc.customer)
|
||||||
|
@ -4,6 +4,14 @@
|
|||||||
// update parent select
|
// update parent select
|
||||||
|
|
||||||
$.extend(cur_frm.cscript, {
|
$.extend(cur_frm.cscript, {
|
||||||
|
refresh: function(doc) {
|
||||||
|
cur_frm.add_custom_button("Auto Build Website", function() {
|
||||||
|
cur_frm.call({
|
||||||
|
doc: cur_frm.doc,
|
||||||
|
method: "make_website"
|
||||||
|
})
|
||||||
|
}, 'icon-magic')
|
||||||
|
},
|
||||||
onload_post_render: function(doc) {
|
onload_post_render: function(doc) {
|
||||||
this.set_parent_label_options();
|
this.set_parent_label_options();
|
||||||
},
|
},
|
||||||
|
@ -14,6 +14,26 @@ class DocType:
|
|||||||
self.validate_top_bar_items()
|
self.validate_top_bar_items()
|
||||||
self.validate_footer_items()
|
self.validate_footer_items()
|
||||||
|
|
||||||
|
def make_website(self):
|
||||||
|
# set item pages
|
||||||
|
for name in webnotes.conn.sql_list("""select name from tabItem where
|
||||||
|
ifnull(show_in_website, 0)=0 and is_sales_item ='Yes' """):
|
||||||
|
webnotes.msgprint("Setting 'Show in Website' for:" + name)
|
||||||
|
item = webnotes.bean("Item", name)
|
||||||
|
item.doc.show_in_website = 1
|
||||||
|
item.doc.website_warehouse = item.doc.default_warehouse
|
||||||
|
item.doc.website_image = item.doc.image
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
# set item group pages
|
||||||
|
for name in webnotes.conn.sql_list("""select name from `tabItem Group` where
|
||||||
|
ifnull(show_in_website, 0)=0 and exists (select name from tabItem where
|
||||||
|
ifnull(show_in_website, 0)=1)"""):
|
||||||
|
webnotes.msgprint("Setting 'Show in Website' for:" + name)
|
||||||
|
item_group = webnotes.bean("Item Group", name)
|
||||||
|
item_group.doc.show_in_website = 1
|
||||||
|
item_group.save()
|
||||||
|
|
||||||
def validate_top_bar_items(self):
|
def validate_top_bar_items(self):
|
||||||
"""validate url in top bar items"""
|
"""validate url in top bar items"""
|
||||||
for top_bar_item in self.doclist.get({"parentfield": "top_bar_items"}):
|
for top_bar_item in self.doclist.get({"parentfield": "top_bar_items"}):
|
||||||
|
Loading…
Reference in New Issue
Block a user