[pos][minor] fixed sales_invoice.js for pos view

This commit is contained in:
Akhilesh Darjee 2013-08-28 11:50:01 +05:30
commit f3eae2344b
38 changed files with 355 additions and 82 deletions

View File

@ -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):

View File

@ -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");

View File

@ -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 {

View File

@ -1,4 +1,5 @@
{ {
"app_name": "ERPNext",
"modules": { "modules": {
"Selling": { "Selling": {
"link": "selling-home", "link": "selling-home",

View File

@ -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
} }
} }

View File

@ -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,11 +353,11 @@ 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
limit %(start)s, %(page_len)s""" % {'item_code': filters['item_code'], limit %(start)s, %(page_len)s""" % {'item_code': filters['item_code'],
'posting_date': filters['posting_date'], 'txt': "%%%s%%" % txt, 'posting_date': filters['posting_date'], 'txt': "%%%s%%" % txt,
'mcond':get_match_cond(doctype, searchfield),'start': start, 'mcond':get_match_cond(doctype, searchfield),'start': start,
'page_len': page_len}) 'page_len': page_len})

View File

@ -126,8 +126,9 @@ class DocType(SellingController):
self.validate_mandatory() self.validate_mandatory()
self.validate_proj_cust() self.validate_proj_cust()
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": {

View File

@ -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 = [

View File

@ -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(", ");
}
}
};

View File

@ -41,11 +41,42 @@ 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`")

View File

@ -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:

View File

@ -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"
}] }]
] ]

View File

@ -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):

View File

View File

@ -0,0 +1,3 @@
body, #container, .outer {
background-color: #888 !important;
}

View 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>

View 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);
})

View 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"
})

View File

Can't render this file because it has a wrong number of fields in line 2.

View File

Before

Width:  |  Height:  |  Size: 221 KiB

After

Width:  |  Height:  |  Size: 221 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -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 # continue?
last_posting = webnotes.conn.sql("""select max(posting_date) from `tabStock Ledger Entry`""") last_posting = webnotes.conn.sql("""select max(posting_date) from `tabStock Ledger Entry`""")
if last_posting[0][0]: if last_posting[0][0]:
current_date = webnotes.utils.add_days(last_posting[0][0], 1) current_date = webnotes.utils.add_days(last_posting[0][0], 1)
else:
current_date = webnotes.utils.getdate(start_date) # run till today
else: if not runs_for:
current_date = webnotes.utils.add_days(current_date, 1) 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)
@ -72,6 +75,8 @@ def simulate():
run_manufacturing(current_date) run_manufacturing(current_date)
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"):
@ -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()
@ -273,7 +278,7 @@ def make_stock_entry_from_pro(pro_id, purpose, current_date):
except NegativeStockError: pass except NegativeStockError: pass
except IncorrectValuationRateError: pass except IncorrectValuationRateError: pass
except DuplicateEntryForProductionOrderError: pass except DuplicateEntryForProductionOrderError: pass
def make_quotation(current_date): def make_quotation(current_date):
b = webnotes.bean([{ b = webnotes.bean([{
"creation": current_date, "creation": current_date,
@ -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")

View 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()

View File

@ -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)

View File

@ -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();
}, },

View File

@ -13,6 +13,26 @@ class DocType:
self.set_home_page() self.set_home_page()
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"""