diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py index bfea0bb5a0..0538323561 100644 --- a/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -261,13 +261,11 @@ class DocType(BuyingController): if d.purchase_order: submitted = sql("select name from `tabPurchase Order` where docstatus = 1 and name = '%s'" % d.purchase_order) if not submitted: - msgprint("Purchase Order : "+ cstr(d.purchase_order) +" is not submitted") - raise Exception , "Validation Error." + webnotes.throw("Purchase Order : "+ cstr(d.purchase_order) +" is not submitted") if d.purchase_receipt: submitted = sql("select name from `tabPurchase Receipt` where docstatus = 1 and name = '%s'" % d.purchase_receipt) if not submitted: - msgprint("Purchase Receipt : "+ cstr(d.purchase_receipt) +" is not submitted") - raise Exception , "Validation Error." + webnotes.throw("Purchase Receipt : "+ cstr(d.purchase_receipt) +" is not submitted") def update_against_document_in_jv(self): diff --git a/accounts/doctype/sales_invoice/pos.js b/accounts/doctype/sales_invoice/pos.js index 1c21fbefb6..0bae8a30d3 100644 --- a/accounts/doctype/sales_invoice/pos.js +++ b/accounts/doctype/sales_invoice/pos.js @@ -16,7 +16,7 @@ erpnext.POS = Class.extend({
\
\
\ - \ +
\ \ \ \ @@ -160,13 +160,10 @@ erpnext.POS = Class.extend({ parent: this.wrapper.find(".barcode-area") }); this.barcode.make_input(); - this.barcode.$input.on("keypress", function() { - setTimeout(function() { me.barcode_timeout(); }, 1000); + this.barcode.$input.on("change", function() { + setTimeout(me.add_item_thru_barcode(), 1000); }); }, - barcode_timeout: function() { - me.add_item_thru_barcode(); - }, make_item_list: function() { var me = this; wn.call({ @@ -181,12 +178,13 @@ erpnext.POS = Class.extend({ me.wrapper.find(".item-list").empty(); $.each(r.message, function(index, obj) { if (obj.image) - image = ''; + image = ''; else image = '
'; $(repl('
\ - %(item_image)s\ +
%(item_image)s
\
%(item_code)s
\
%(item_name)s
\
%(item_price)s
\ @@ -332,7 +330,6 @@ erpnext.POS = Class.extend({ }, add_item_thru_barcode: function() { var me = this; - clearTimeout(); wn.call({ method: 'accounts.doctype.sales_invoice.pos.get_item_from_barcode', args: {barcode: this.barcode.$input.val()}, @@ -363,6 +360,7 @@ erpnext.POS = Class.extend({ $.each(child, function(i, d) { for (var i in selected_items) { 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); } } @@ -401,6 +399,7 @@ erpnext.POS = Class.extend({ "total_amount": $(".grand-total").text() }); dialog.show(); + cur_frm.pos.barcode.$input.focus(); dialog.get_input("total_amount").attr("disabled", "disabled"); diff --git a/accounts/doctype/sales_invoice/sales_invoice.js b/accounts/doctype/sales_invoice/sales_invoice.js index e2eeeac309..85550c48a8 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.js +++ b/accounts/doctype/sales_invoice/sales_invoice.js @@ -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 { // hide shown pos for submitted records 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() { @@ -123,6 +122,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte }, 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) msgprint(wn._("Please select Price List")) else { diff --git a/config.json b/config.json index c9d1aa71f8..5412b017b2 100644 --- a/config.json +++ b/config.json @@ -1,4 +1,5 @@ { + "app_name": "ERPNext", "modules": { "Selling": { "link": "selling-home", diff --git a/selling/doctype/sales_common/sales_common.js b/selling/doctype/sales_common/sales_common.js index dea94b8f3d..5c0c96ad56 100644 --- a/selling/doctype/sales_common/sales_common.js +++ b/selling/doctype/sales_common/sales_common.js @@ -95,7 +95,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ return{ query : "selling.doctype.sales_common.sales_common.get_batch_no", filters: { - 'item': item.item_code, + 'item_code': item.item_code, 'posting_date': me.frm.doc.posting_date } } diff --git a/selling/doctype/sales_common/sales_common.py b/selling/doctype/sales_common/sales_common.py index 3c43c1ede7..baa8850a58 100644 --- a/selling/doctype/sales_common/sales_common.py +++ b/selling/doctype/sales_common/sales_common.py @@ -340,7 +340,7 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters): and batch_no like '%(txt)s' and exists(select * from `tabBatch` where name = sle.batch_no - and expiry_date >= '%(posting_date)s' + and (ifnull(expiry_date, '')='' or expiry_date >= '%(posting_date)s') and docstatus != 2) %(mcond)s 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 where docstatus != 2 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' %(mcond)s order by name desc limit %(start)s, %(page_len)s""" % {'item_code': filters['item_code'], 'posting_date': filters['posting_date'], 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype, searchfield),'start': start, - 'page_len': page_len}) \ No newline at end of file + 'page_len': page_len}) diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py index a9bb7a2140..8e3ed701ff 100644 --- a/selling/doctype/sales_order/sales_order.py +++ b/selling/doctype/sales_order/sales_order.py @@ -126,8 +126,9 @@ class DocType(SellingController): self.validate_mandatory() self.validate_proj_cust() 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_warehouse_user() sales_com_obj = get_obj(dt = 'Sales Common') sales_com_obj.check_active_sales_items(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.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): super(DocType, self).validate_with_previous_doc(self.tname, { "Quotation": { diff --git a/selling/doctype/sales_order/test_sales_order.py b/selling/doctype/sales_order/test_sales_order.py index 9fd16e8c29..7b72271bec 100644 --- a/selling/doctype/sales_order/test_sales_order.py +++ b/selling/doctype/sales_order/test_sales_order.py @@ -272,6 +272,29 @@ class TestSalesOrder(unittest.TestCase): self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 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_records = [ diff --git a/stock/doctype/purchase_receipt/purchase_receipt_list.js b/stock/doctype/purchase_receipt/purchase_receipt_list.js deleted file mode 100644 index bc0c9f6e00..0000000000 --- a/stock/doctype/purchase_receipt/purchase_receipt_list.js +++ /dev/null @@ -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("%(name)s", - {name: v})); - }); - data.purchase_order_no = po_list.join(", "); - } - } -}; diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py index f33cfa35d3..b9b32306d8 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -41,11 +41,42 @@ class TestStockEntry(unittest.TestCase): webnotes.conn.set_default("company", self.old_default_company) 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 st1 = webnotes.bean(copy=test_records[0]) st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1" st1.insert() 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): webnotes.conn.sql("delete from `tabStock Ledger Entry`") diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 71d426f48e..58fc828f2d 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -25,12 +25,14 @@ class DocType(DocListController): self.doclist = doclist def validate(self): + from stock.utils import validate_warehouse_user if not hasattr(webnotes, "new_stock_ledger_entries"): webnotes.new_stock_ledger_entries = [] + webnotes.new_stock_ledger_entries.append(self.doc) self.validate_mandatory() self.validate_item() - self.validate_warehouse_user() + validate_warehouse_user(self.doc.warehouse) self.validate_warehouse_company() self.actual_amt_check() self.check_stock_frozen_date() @@ -52,16 +54,6 @@ class DocType(DocListController): 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): warehouse_company = webnotes.conn.get_value("Warehouse", self.doc.warehouse, "company") if warehouse_company and warehouse_company != self.doc.company: diff --git a/stock/doctype/warehouse/test_warehouse.py b/stock/doctype/warehouse/test_warehouse.py index 4e47d5636b..ed72562078 100644 --- a/stock/doctype/warehouse/test_warehouse.py +++ b/stock/doctype/warehouse/test_warehouse.py @@ -16,5 +16,9 @@ test_records = [ "doctype": "Warehouse", "warehouse_name": "_Test Warehouse 2", "company": "_Test Company 1" + }, { + "doctype": "Warehouse User", + "parentfield": "warehouse_users", + "user": "test2@example.com" }] ] diff --git a/stock/utils.py b/stock/utils.py index 5376342979..f04b663236 100644 --- a/stock/utils.py +++ b/stock/utils.py @@ -8,6 +8,8 @@ from webnotes.utils import flt, cstr, nowdate, add_days, cint from webnotes.defaults import get_global_default 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): if not 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]) 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, stock_ledger_entries, item_sales_bom=None): if item_sales_bom and item_sales_bom.get(item_code): diff --git a/utilities/demo/__init__.py b/utilities/demo/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/utilities/demo/demo-login.css b/utilities/demo/demo-login.css new file mode 100644 index 0000000000..f3464a3a2d --- /dev/null +++ b/utilities/demo/demo-login.css @@ -0,0 +1,3 @@ +body, #container, .outer { + background-color: #888 !important; +} \ No newline at end of file diff --git a/utilities/demo/demo-login.html b/utilities/demo/demo-login.html new file mode 100644 index 0000000000..ef24678e27 --- /dev/null +++ b/utilities/demo/demo-login.html @@ -0,0 +1,25 @@ +
+
+
+
+
+ Start ERPNext Demo +
+
+

+ +

+

+ +

+
+

Some functionality is disabled for the demo app. The demo data will be cleared regulary. To start your own ERPNext Trial, click here

+
+
+
+
+
+
+
diff --git a/utilities/demo/demo-login.js b/utilities/demo/demo-login.js new file mode 100644 index 0000000000..229d1690e5 --- /dev/null +++ b/utilities/demo/demo-login.js @@ -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); +}) \ No newline at end of file diff --git a/utilities/demo/demo_control_panel.py b/utilities/demo/demo_control_panel.py new file mode 100644 index 0000000000..c70913ee68 --- /dev/null +++ b/utilities/demo/demo_control_panel.py @@ -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" + }) diff --git a/utilities/demo_docs/Address.csv b/utilities/demo/demo_docs/Address.csv similarity index 100% rename from utilities/demo_docs/Address.csv rename to utilities/demo/demo_docs/Address.csv diff --git a/utilities/demo_docs/BOM.csv b/utilities/demo/demo_docs/BOM.csv similarity index 100% rename from utilities/demo_docs/BOM.csv rename to utilities/demo/demo_docs/BOM.csv diff --git a/utilities/demo_docs/Contact.csv b/utilities/demo/demo_docs/Contact.csv similarity index 100% rename from utilities/demo_docs/Contact.csv rename to utilities/demo/demo_docs/Contact.csv diff --git a/utilities/demo_docs/Customer.csv b/utilities/demo/demo_docs/Customer.csv similarity index 100% rename from utilities/demo_docs/Customer.csv rename to utilities/demo/demo_docs/Customer.csv diff --git a/utilities/demo_docs/Employee.csv b/utilities/demo/demo_docs/Employee.csv similarity index 100% rename from utilities/demo_docs/Employee.csv rename to utilities/demo/demo_docs/Employee.csv diff --git a/utilities/demo_docs/Fiscal_Year.csv b/utilities/demo/demo_docs/Fiscal_Year.csv similarity index 100% rename from utilities/demo_docs/Fiscal_Year.csv rename to utilities/demo/demo_docs/Fiscal_Year.csv diff --git a/utilities/demo_docs/Item.csv b/utilities/demo/demo_docs/Item.csv similarity index 100% rename from utilities/demo_docs/Item.csv rename to utilities/demo/demo_docs/Item.csv diff --git a/utilities/demo_docs/Item_Price.csv b/utilities/demo/demo_docs/Item_Price.csv similarity index 100% rename from utilities/demo_docs/Item_Price.csv rename to utilities/demo/demo_docs/Item_Price.csv diff --git a/utilities/demo_docs/Lead.csv b/utilities/demo/demo_docs/Lead.csv similarity index 100% rename from utilities/demo_docs/Lead.csv rename to utilities/demo/demo_docs/Lead.csv diff --git a/utilities/demo_docs/Profile.csv b/utilities/demo/demo_docs/Profile.csv similarity index 100% rename from utilities/demo_docs/Profile.csv rename to utilities/demo/demo_docs/Profile.csv diff --git a/utilities/demo_docs/Salary_Structure.csv b/utilities/demo/demo_docs/Salary_Structure.csv similarity index 100% rename from utilities/demo_docs/Salary_Structure.csv rename to utilities/demo/demo_docs/Salary_Structure.csv diff --git a/utilities/demo_docs/Stock Reconcilation Template.csv b/utilities/demo/demo_docs/Stock Reconcilation Template.csv similarity index 100% rename from utilities/demo_docs/Stock Reconcilation Template.csv rename to utilities/demo/demo_docs/Stock Reconcilation Template.csv diff --git a/utilities/demo_docs/Supplier.csv b/utilities/demo/demo_docs/Supplier.csv similarity index 100% rename from utilities/demo_docs/Supplier.csv rename to utilities/demo/demo_docs/Supplier.csv diff --git a/utilities/demo_docs/bearing-block.png b/utilities/demo/demo_docs/bearing-block.png similarity index 100% rename from utilities/demo_docs/bearing-block.png rename to utilities/demo/demo_docs/bearing-block.png diff --git a/utilities/demo_docs/wind-turbine.png b/utilities/demo/demo_docs/wind-turbine.png similarity index 100% rename from utilities/demo_docs/wind-turbine.png rename to utilities/demo/demo_docs/wind-turbine.png diff --git a/utilities/make_demo.py b/utilities/demo/make_demo.py similarity index 92% rename from utilities/make_demo.py rename to utilities/demo/make_demo.py index 2884144135..3d7d6487d4 100644 --- a/utilities/make_demo.py +++ b/utilities/demo/make_demo.py @@ -19,9 +19,9 @@ company_abbr = "WP" country = "United States" currency = "USD" time_zone = "America/New York" -start_date = '2010-01-01' +start_date = '2013-01-01' bank_name = "Citibank" -runs_for = 20 +runs_for = None prob = { "default": { "make": 0.6, "qty": (1,5) }, "Sales Order": { "make": 0.4, "qty": (1,3) }, @@ -50,21 +50,24 @@ def setup(): # make_opening_accounts() def simulate(): - current_date = None - for i in xrange(runs_for): - 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) - + global runs_for + current_date = webnotes.utils.getdate(start_date) + + # 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") + webnotes.utils.current_date = current_date if current_date.weekday() in (5, 6): + current_date = webnotes.utils.add_days(current_date, 1) continue run_sales(current_date) @@ -72,6 +75,8 @@ def simulate(): run_manufacturing(current_date) run_stock(current_date) run_accounts(current_date) + + current_date = webnotes.utils.add_days(current_date, 1) def run_sales(current_date): 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")]: pr = webnotes.bean(make_purchase_receipt(po)) pr.doc.posting_date = current_date - pr.doc.fiscal_year = "2010" + pr.doc.fiscal_year = "2013" pr.insert() pr.submit() 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")]: dn = webnotes.bean(make_delivery_note(so)) dn.doc.posting_date = current_date - dn.doc.fiscal_year = "2010" + dn.doc.fiscal_year = "2013" dn.insert() try: dn.submit() @@ -173,7 +178,7 @@ def run_purchase(current_date): mr = webnotes.new_bean("Material Request") mr.doc.material_request_type = "Purchase" mr.doc.transaction_date = current_date - mr.doc.fiscal_year = "2010" + mr.doc.fiscal_year = "2013" mr.doclist.append({ "doctype": "Material Request Item", "parentfield": "indent_details", @@ -192,7 +197,7 @@ def run_purchase(current_date): if row[0] != "Total": sq = webnotes.bean(make_supplier_quotation(row[0])) sq.doc.transaction_date = current_date - sq.doc.fiscal_year = "2010" + sq.doc.fiscal_year = "2013" sq.insert() sq.submit() webnotes.conn.commit() @@ -205,7 +210,7 @@ def run_purchase(current_date): if row[0] != "Total": po = webnotes.bean(make_purchase_order(row[0])) po.doc.transaction_date = current_date - po.doc.fiscal_year = "2010" + po.doc.fiscal_year = "2013" po.insert() po.submit() 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.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: + 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() webnotes.conn.commit() st.submit() @@ -273,7 +278,7 @@ def make_stock_entry_from_pro(pro_id, purpose, current_date): except NegativeStockError: pass except IncorrectValuationRateError: pass except DuplicateEntryForProductionOrderError: pass - + def make_quotation(current_date): b = webnotes.bean([{ "creation": current_date, @@ -282,7 +287,7 @@ def make_quotation(current_date): "customer": get_random("Customer"), "order_type": "Sales", "transaction_date": current_date, - "fiscal_year": "2010" + "fiscal_year": "2013" }]) add_random_children(b, { @@ -349,8 +354,9 @@ def how_many(doctype): def install(): print "Creating Fresh Database..." from webnotes.install_lib.install import Installer + import conf inst = Installer('root') - inst.import_from_db("demo", verbose = 1) + inst.import_from_db(conf.demo_db_name, verbose = 1) def complete_setup(): print "Complete Setup..." @@ -392,6 +398,7 @@ def make_bank_account(): }).insert() webnotes.set_value("Company", company, "default_bank_account", ba.doc.name) + webnotes.conn.commit() def import_data(dt, submit=False): if not isinstance(dt, (tuple, list)): @@ -399,7 +406,7 @@ def import_data(dt, submit=False): for doctype in dt: print "Importing", doctype.replace("_", " "), "..." - webnotes.form_dict = {} + webnotes.form_dict = webnotes._dict() if submit: webnotes.form_dict["params"] = json.dumps({"_submit": 1}) webnotes.uploaded_file = os.path.join(os.path.dirname(__file__), "demo_docs", doctype+".csv") diff --git a/utilities/demo/make_erpnext_demo.py b/utilities/demo/make_erpnext_demo.py new file mode 100644 index 0000000000..31dc400874 --- /dev/null +++ b/utilities/demo/make_erpnext_demo.py @@ -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, click here')""" + 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() \ No newline at end of file diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py index d2bffcfeac..aace0cb78e 100644 --- a/utilities/transaction_base.py +++ b/utilities/transaction_base.py @@ -55,6 +55,8 @@ class TransactionBase(StatusUpdater): return self._party_type_and_name def get_customer_defaults(self): + if not self.doc.customer: return {} + out = self.get_default_address_and_contact("customer") customer = webnotes.doc("Customer", self.doc.customer) diff --git a/website/doctype/website_settings/website_settings.js b/website/doctype/website_settings/website_settings.js index 0d0dab68c0..21b55be5ea 100644 --- a/website/doctype/website_settings/website_settings.js +++ b/website/doctype/website_settings/website_settings.js @@ -4,6 +4,14 @@ // update parent select $.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) { this.set_parent_label_options(); }, diff --git a/website/doctype/website_settings/website_settings.py b/website/doctype/website_settings/website_settings.py index 3b27c7ccc1..5d6c874d70 100644 --- a/website/doctype/website_settings/website_settings.py +++ b/website/doctype/website_settings/website_settings.py @@ -13,6 +13,26 @@ class DocType: self.set_home_page() self.validate_top_bar_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): """validate url in top bar items"""
Item