diff --git a/.travis.yml b/.travis.yml index 40afeee8d46..365eb67f3dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -63,6 +63,7 @@ install: - tar -xf /tmp/wkhtmltox.tar.xz -C /tmp - sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf - sudo chmod o+x /usr/local/bin/wkhtmltopdf + - sudo apt-get install libcups2-dev - cd ~/frappe-bench diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py index a20f5c08726..8c4efbebe88 100644 --- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py +++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py @@ -70,7 +70,7 @@ class ShippingRule(Document): def get_shipping_amount_from_rules(self, value): for condition in self.get("conditions"): - if not condition.to_value or (flt(condition.from_value) <= value <= flt(condition.to_value)): + if not condition.to_value or (flt(condition.from_value) <= flt(value) <= flt(condition.to_value)): return condition.shipping_amount return 0.0 diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index 2ba319d05e5..feb598a2e51 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -162,33 +162,34 @@ def validate_account_for_perpetual_inventory(gl_map): frappe.throw(_("Account: {0} can only be updated via Stock Transactions") .format(account), StockAccountInvalidTransaction) - elif account_bal != stock_bal: - precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"), - currency=frappe.get_cached_value('Company', gl_map[0].company, "default_currency")) + # This has been comment for a temporary, will add this code again on release of immutable ledger + # elif account_bal != stock_bal: + # precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"), + # currency=frappe.get_cached_value('Company', gl_map[0].company, "default_currency")) - diff = flt(stock_bal - account_bal, precision) - error_reason = _("Stock Value ({0}) and Account Balance ({1}) are out of sync for account {2} and it's linked warehouses.").format( - stock_bal, account_bal, frappe.bold(account)) - error_resolution = _("Please create adjustment Journal Entry for amount {0} ").format(frappe.bold(diff)) - stock_adjustment_account = frappe.db.get_value("Company",gl_map[0].company,"stock_adjustment_account") + # diff = flt(stock_bal - account_bal, precision) + # error_reason = _("Stock Value ({0}) and Account Balance ({1}) are out of sync for account {2} and it's linked warehouses.").format( + # stock_bal, account_bal, frappe.bold(account)) + # error_resolution = _("Please create adjustment Journal Entry for amount {0} ").format(frappe.bold(diff)) + # stock_adjustment_account = frappe.db.get_value("Company",gl_map[0].company,"stock_adjustment_account") - db_or_cr_warehouse_account =('credit_in_account_currency' if diff < 0 else 'debit_in_account_currency') - db_or_cr_stock_adjustment_account = ('debit_in_account_currency' if diff < 0 else 'credit_in_account_currency') + # db_or_cr_warehouse_account =('credit_in_account_currency' if diff < 0 else 'debit_in_account_currency') + # db_or_cr_stock_adjustment_account = ('debit_in_account_currency' if diff < 0 else 'credit_in_account_currency') - journal_entry_args = { - 'accounts':[ - {'account': account, db_or_cr_warehouse_account : abs(diff)}, - {'account': stock_adjustment_account, db_or_cr_stock_adjustment_account : abs(diff) }] - } + # journal_entry_args = { + # 'accounts':[ + # {'account': account, db_or_cr_warehouse_account : abs(diff)}, + # {'account': stock_adjustment_account, db_or_cr_stock_adjustment_account : abs(diff) }] + # } - frappe.msgprint(msg="""{0}

{1}

""".format(error_reason, error_resolution), - raise_exception=StockValueAndAccountBalanceOutOfSync, - title=_('Values Out Of Sync'), - primary_action={ - 'label': _('Make Journal Entry'), - 'client_action': 'erpnext.route_to_adjustment_jv', - 'args': journal_entry_args - }) + # frappe.msgprint(msg="""{0}

{1}

""".format(error_reason, error_resolution), + # raise_exception=StockValueAndAccountBalanceOutOfSync, + # title=_('Values Out Of Sync'), + # primary_action={ + # 'label': _('Make Journal Entry'), + # 'client_action': 'erpnext.route_to_adjustment_jv', + # 'args': journal_entry_args + # }) def validate_cwip_accounts(gl_map): cwip_enabled = any([cint(ac.enable_cwip_accounting) for ac in frappe.db.get_all("Asset Category","enable_cwip_accounting")]) diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py index b6d588ed967..62a04f37b11 100644 --- a/erpnext/buying/doctype/supplier/supplier.py +++ b/erpnext/buying/doctype/supplier/supplier.py @@ -56,3 +56,23 @@ class Supplier(TransactionBase): def after_rename(self, olddn, newdn, merge=False): if frappe.defaults.get_global_default('supp_master_name') == 'Supplier Name': frappe.db.set(self, "supplier_name", newdn) + + def create_onboarding_docs(self, args): + defaults = frappe.defaults.get_defaults() + for i in range(1, args.get('max_count')): + supplier = args.get('supplier_name_' + str(i)) + if supplier: + try: + doc = frappe.get_doc({ + 'doctype': self.doctype, + 'supplier_name': supplier, + 'supplier_group': _('Local'), + 'company': defaults.get('company') + }).insert() + + if args.get('supplier_email_' + str(i)): + from erpnext.selling.doctype.customer.customer import create_contact + create_contact(supplier, 'Supplier', + doc.name, args.get('supplier_email_' + str(i))) + except frappe.NameError: + pass \ No newline at end of file diff --git a/erpnext/buying/setup_wizard_slide/add_a_few_suppliers/add_a_few_suppliers.json b/erpnext/buying/setup_wizard_slide/add_a_few_suppliers/add_a_few_suppliers.json new file mode 100644 index 00000000000..006d139eb02 --- /dev/null +++ b/erpnext/buying/setup_wizard_slide/add_a_few_suppliers/add_a_few_suppliers.json @@ -0,0 +1,49 @@ +{ + "add_more_button": 1, + "app": "ERPNext", + "creation": "2019-11-15 14:45:32.626641", + "docstatus": 0, + "doctype": "Setup Wizard Slide", + "domains": [], + "help_links": [ + { + "label": "Supplier", + "video_id": "zsrrVDk6VBs" + } + ], + "idx": 0, + "image_src": "/assets/erpnext/images/illustrations/supplier.png", + "max_count": 3, + "modified": "2019-11-26 18:26:25.498325", + "modified_by": "Administrator", + "name": "Add A Few Suppliers", + "owner": "Administrator", + "ref_doctype": "Supplier", + "slide_desc": "", + "slide_fields": [ + { + "align": "", + "fieldname": "supplier_name", + "fieldtype": "Data", + "label": "Supplier Name", + "placeholder": "", + "reqd": 1 + }, + { + "align": "", + "fieldtype": "Column Break", + "reqd": 0 + }, + { + "align": "", + "fieldname": "supplier_email", + "fieldtype": "Data", + "label": "Supplier Email", + "reqd": 1 + } + ], + "slide_order": 50, + "slide_title": "Add A Few Suppliers", + "slide_type": "Create", + "submit_method": "" +} \ No newline at end of file diff --git a/erpnext/config/stock.py b/erpnext/config/stock.py index 441a3ab4ec3..e24d7b88df1 100644 --- a/erpnext/config/stock.py +++ b/erpnext/config/stock.py @@ -241,6 +241,10 @@ def get_data(): "type": "doctype", "name": "Quality Inspection Template", }, + { + "type": "doctype", + "name": "Quick Stock Balance", + }, ] }, { diff --git a/erpnext/hooks.py b/erpnext/hooks.py index e4b5e3012f5..ed5bf9b5d82 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -40,8 +40,6 @@ after_install = "erpnext.setup.install.after_install" boot_session = "erpnext.startup.boot.boot_session" notification_config = "erpnext.startup.notifications.get_notification_config" get_help_messages = "erpnext.utilities.activation.get_help_messages" -get_user_progress_slides = "erpnext.utilities.user_progress.get_user_progress_slides" -update_and_get_user_progress = "erpnext.utilities.user_progress_utils.update_default_domain_actions_and_get_state" leaderboards = "erpnext.startup.leaderboard.get_leaderboards" @@ -302,7 +300,7 @@ scheduler_events = { "erpnext.support.doctype.service_level_agreement.service_level_agreement.check_agreement_status", "erpnext.crm.doctype.email_campaign.email_campaign.send_email_to_leads_or_contacts", "erpnext.crm.doctype.email_campaign.email_campaign.set_email_campaign_status", - "erpnext.selling.doctype.quotation.set_expired_status" + "erpnext.selling.doctype.quotation.quotation.set_expired_status" ], "daily_long": [ "erpnext.setup.doctype.email_digest.email_digest.send", diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js index 174641048b8..db3819eff2d 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.js +++ b/erpnext/hr/doctype/leave_application/leave_application.js @@ -60,7 +60,6 @@ frappe.ui.form.on("Leave Application", { } } }); - $("div").remove(".form-dashboard-section"); frm.dashboard.add_section( frappe.render_template('leave_application_dashboard', { data: leave_details diff --git a/erpnext/patches/v8_9/add_setup_progress_actions.py b/erpnext/patches/v8_9/add_setup_progress_actions.py index fe123111bce..77501073cf4 100644 --- a/erpnext/patches/v8_9/add_setup_progress_actions.py +++ b/erpnext/patches/v8_9/add_setup_progress_actions.py @@ -5,6 +5,9 @@ from frappe import _ def execute(): """Add setup progress actions""" + if not frappe.db.exists('DocType', 'Setup Progress') or not frappe.db.exists('DocType', 'Setup Progress Action'): + return + frappe.reload_doc("setup", "doctype", "setup_progress") frappe.reload_doc("setup", "doctype", "setup_progress_action") diff --git a/erpnext/public/images/illustrations/collaboration.png b/erpnext/public/images/illustrations/collaboration.png new file mode 100644 index 00000000000..12c67e394cc Binary files /dev/null and b/erpnext/public/images/illustrations/collaboration.png differ diff --git a/erpnext/public/images/illustrations/customer.png b/erpnext/public/images/illustrations/customer.png new file mode 100644 index 00000000000..b2ddbf3bb47 Binary files /dev/null and b/erpnext/public/images/illustrations/customer.png differ diff --git a/erpnext/public/images/illustrations/letterhead.png b/erpnext/public/images/illustrations/letterhead.png new file mode 100644 index 00000000000..37df6d7f6fc Binary files /dev/null and b/erpnext/public/images/illustrations/letterhead.png differ diff --git a/erpnext/public/images/illustrations/onboard.png b/erpnext/public/images/illustrations/onboard.png new file mode 100644 index 00000000000..094aa3f8ddf Binary files /dev/null and b/erpnext/public/images/illustrations/onboard.png differ diff --git a/erpnext/public/images/illustrations/product.png b/erpnext/public/images/illustrations/product.png new file mode 100644 index 00000000000..f864b7af60e Binary files /dev/null and b/erpnext/public/images/illustrations/product.png differ diff --git a/erpnext/public/images/illustrations/supplier.png b/erpnext/public/images/illustrations/supplier.png new file mode 100644 index 00000000000..87f7789600f Binary files /dev/null and b/erpnext/public/images/illustrations/supplier.png differ diff --git a/erpnext/public/images/illustrations/user.png b/erpnext/public/images/illustrations/user.png new file mode 100644 index 00000000000..7dd7db210d4 Binary files /dev/null and b/erpnext/public/images/illustrations/user.png differ diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less index 8ed5f1adb05..abe48685f03 100644 --- a/erpnext/public/less/erpnext.less +++ b/erpnext/public/less/erpnext.less @@ -426,7 +426,7 @@ body[data-route="pos"] { .collapse-btn { cursor: pointer; } - + @media (max-width: @screen-xs) { .page-actions { max-width: 110px; diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 67e20b1e891..57308cea41b 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -204,6 +204,40 @@ class Customer(TransactionBase): else: frappe.msgprint(_("Multiple Loyalty Program found for the Customer. Please select manually.")) + def create_onboarding_docs(self, args): + defaults = frappe.defaults.get_defaults() + for i in range(1, args.get('max_count')): + customer = args.get('customer_name_' + str(i)) + if customer: + try: + doc = frappe.get_doc({ + 'doctype': self.doctype, + 'customer_name': customer, + 'customer_type': 'Company', + 'customer_group': _('Commercial'), + 'territory': defaults.get('country'), + 'company': defaults.get('company') + }).insert() + + if args.get('customer_email_' + str(i)): + create_contact(customer, self.doctype, + doc.name, args.get("customer_email_" + str(i))) + except frappe.NameError: + pass + +def create_contact(contact, party_type, party, email): + """Create contact based on given contact name""" + contact = contact.split(' ') + + contact = frappe.get_doc({ + 'doctype': 'Contact', + 'first_name': contact[0], + 'last_name': len(contact) > 1 and contact[1] or "" + }) + contact.append('email_ids', dict(email_id=email, is_primary=1)) + contact.append('links', dict(link_doctype=party_type, link_name=party)) + contact.insert() + @frappe.whitelist() def get_loyalty_programs(doc): ''' returns applicable loyalty programs for a customer ''' diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index e508476576d..1c9b30b8289 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -309,7 +309,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ child: item, args: { "batch_no": item.batch_no, - "stock_qty": item.stock_qty, + "stock_qty": item.stock_qty || item.qty, //if stock_qty field is not available fetch qty (in case of Packed Items table) "warehouse": item.warehouse, "item_code": item.item_code, "has_serial_no": has_serial_no diff --git a/erpnext/selling/setup_wizard_slide/add_a_few_customers/add_a_few_customers.json b/erpnext/selling/setup_wizard_slide/add_a_few_customers/add_a_few_customers.json new file mode 100644 index 00000000000..a0bb6fe26df --- /dev/null +++ b/erpnext/selling/setup_wizard_slide/add_a_few_customers/add_a_few_customers.json @@ -0,0 +1,49 @@ +{ + "add_more_button": 1, + "app": "ERPNext", + "creation": "2019-11-15 14:44:10.065014", + "docstatus": 0, + "doctype": "Setup Wizard Slide", + "domains": [], + "help_links": [ + { + "label": "Customers", + "video_id": "zsrrVDk6VBs" + } + ], + "idx": 0, + "image_src": "/assets/erpnext/images/illustrations/customer.png", + "max_count": 3, + "modified": "2019-11-26 18:26:15.888794", + "modified_by": "Administrator", + "name": "Add A Few Customers", + "owner": "Administrator", + "ref_doctype": "Customer", + "slide_desc": "", + "slide_fields": [ + { + "align": "", + "fieldname": "customer_name", + "fieldtype": "Data", + "label": "Customer Name", + "placeholder": "", + "reqd": 1 + }, + { + "align": "", + "fieldtype": "Column Break", + "reqd": 0 + }, + { + "align": "", + "fieldname": "customer_email", + "fieldtype": "Data", + "label": "Email ID", + "reqd": 1 + } + ], + "slide_order": 40, + "slide_title": "Add A Few Customers", + "slide_type": "Create", + "submit_method": "" +} \ No newline at end of file diff --git a/erpnext/setup/doctype/setup_progress/__init__.py b/erpnext/setup/doctype/setup_progress/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/erpnext/setup/doctype/setup_progress/setup_progress.js b/erpnext/setup/doctype/setup_progress/setup_progress.js deleted file mode 100644 index 5c78bd50758..00000000000 --- a/erpnext/setup/doctype/setup_progress/setup_progress.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Setup Progress', { - refresh: function() { - - } -}); diff --git a/erpnext/setup/doctype/setup_progress/setup_progress.json b/erpnext/setup/doctype/setup_progress/setup_progress.json deleted file mode 100644 index 09072d4665b..00000000000 --- a/erpnext/setup/doctype/setup_progress/setup_progress.json +++ /dev/null @@ -1,123 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2017-08-27 21:01:42.032109", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "actions_sb", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Actions", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "actions", - "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Actions", - "length": 0, - "no_copy": 0, - "options": "Setup Progress Action", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 1, - "is_submittable": 0, - "issingle": 1, - "istable": 0, - "max_attachments": 0, - "modified": "2017-09-21 11:52:56.106659", - "modified_by": "Administrator", - "module": "Setup", - "name": "Setup Progress", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 0, - "role": "All", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 1, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/setup/doctype/setup_progress/setup_progress.py b/erpnext/setup/doctype/setup_progress/setup_progress.py deleted file mode 100644 index e1402f5844b..00000000000 --- a/erpnext/setup/doctype/setup_progress/setup_progress.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -import frappe, json -from frappe.model.document import Document - -class SetupProgress(Document): - pass - -def get_setup_progress(): - if not getattr(frappe.local, "setup_progress", None): - frappe.local.setup_progress = frappe.get_doc("Setup Progress", "Setup Progress") - - return frappe.local.setup_progress - -def get_action_completed_state(action_name): - for d in get_setup_progress().actions: - if d.action_name == action_name: - return d.is_completed - -def update_action_completed_state(action_name): - action_table_doc = [d for d in get_setup_progress().actions - if d.action_name == action_name][0] - update_action(action_table_doc) - -def update_action(doc): - doctype = doc.action_doctype - docname = doc.action_document - field = doc.action_field - - if not doc.is_completed: - if doc.min_doc_count: - if frappe.db.count(doctype) >= doc.min_doc_count: - doc.is_completed = 1 - doc.save() - if docname and field: - d = frappe.get_doc(doctype, docname) - if d.get(field): - doc.is_completed = 1 - doc.save() - -def update_domain_actions(domain): - for d in get_setup_progress().actions: - domains = json.loads(d.domains) - if domains == [] or domain in domains: - update_action(d) - -def get_domain_actions_state(domain): - state = {} - for d in get_setup_progress().actions: - domains = json.loads(d.domains) - if domains == [] or domain in domains: - state[d.action_name] = d.is_completed - return state - -@frappe.whitelist() -def set_action_completed_state(action_name): - action_table_doc = [d for d in get_setup_progress().actions - if d.action_name == action_name][0] - action_table_doc.is_completed = 1 - action_table_doc.save() diff --git a/erpnext/setup/doctype/setup_progress/test_setup_progress.js b/erpnext/setup/doctype/setup_progress/test_setup_progress.js deleted file mode 100644 index 9e84e0cb154..00000000000 --- a/erpnext/setup/doctype/setup_progress/test_setup_progress.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Setup Progress", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Setup Progress - () => frappe.tests.make('Setup Progress', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/setup/doctype/setup_progress/test_setup_progress.py b/erpnext/setup/doctype/setup_progress/test_setup_progress.py deleted file mode 100644 index 89262191436..00000000000 --- a/erpnext/setup/doctype/setup_progress/test_setup_progress.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt -from __future__ import unicode_literals - -import unittest - -class TestSetupProgress(unittest.TestCase): - pass diff --git a/erpnext/setup/doctype/setup_progress_action/__init__.py b/erpnext/setup/doctype/setup_progress_action/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/erpnext/setup/doctype/setup_progress_action/setup_progress_action.json b/erpnext/setup/doctype/setup_progress_action/setup_progress_action.json deleted file mode 100644 index e9abcbcd1ac..00000000000 --- a/erpnext/setup/doctype/setup_progress_action/setup_progress_action.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2017-08-27 21:00:40.715360", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "action_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Action Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "action_doctype", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Action Doctype", - "length": 0, - "no_copy": 0, - "options": "DocType", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "action_document", - "fieldtype": "Dynamic Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Action Document", - "length": 0, - "no_copy": 0, - "options": "action_doctype", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "action_field", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Action Field", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "min_doc_count", - "fieldtype": "Int", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Min Doc Count", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "domains", - "fieldtype": "Code", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Domains", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "is_completed", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Is Completed", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 1, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2017-09-01 14:34:59.685730", - "modified_by": "Administrator", - "module": "Setup", - "name": "Setup Progress Action", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 1, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/setup/doctype/setup_progress_action/setup_progress_action.py b/erpnext/setup/doctype/setup_progress_action/setup_progress_action.py deleted file mode 100644 index 24af94347e5..00000000000 --- a/erpnext/setup/doctype/setup_progress_action/setup_progress_action.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -from frappe.model.document import Document - -class SetupProgressAction(Document): - pass diff --git a/erpnext/setup/setup_wizard_slide/welcome_to_erpnext!/welcome_to_erpnext!.json b/erpnext/setup/setup_wizard_slide/welcome_to_erpnext!/welcome_to_erpnext!.json new file mode 100644 index 00000000000..1da9dd44e2b --- /dev/null +++ b/erpnext/setup/setup_wizard_slide/welcome_to_erpnext!/welcome_to_erpnext!.json @@ -0,0 +1,22 @@ +{ + "add_more_button": 0, + "app": "ERPNext", + "creation": "2019-11-26 17:01:26.671859", + "docstatus": 0, + "doctype": "Setup Wizard Slide", + "domains": [], + "help_links": [], + "idx": 0, + "image_src": "/assets/erpnext/images/illustrations/onboard.png", + "max_count": 0, + "modified": "2019-11-26 17:17:29.813299", + "modified_by": "Administrator", + "name": "Welcome to ERPNext!", + "owner": "Administrator", + "slide_desc": "Setting up an ERP can be overwhelming. But don't worry, we have got your back!
\nLet's setup your company.\nThis wizard will help you onboard to ERPNext in a short time!", + "slide_fields": [], + "slide_module": "Setup", + "slide_order": 10, + "slide_title": "Welcome to ERPNext!", + "slide_type": "Information" +} \ No newline at end of file diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 7495dffec24..189261cb2de 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -884,6 +884,54 @@ class Item(WebsiteGenerator): if not enabled: frappe.msgprint(msg=_("You have to enable auto re-order in Stock Settings to maintain re-order levels."), title=_("Enable Auto Re-Order"), indicator="orange") + def create_onboarding_docs(self, args): + defaults = frappe.defaults.get_defaults() + for i in range(1, args.get('max_count')): + item = args.get('item_' + str(i)) + if item: + default_warehouse = '' + default_warehouse = frappe.db.get_value('Warehouse', filters={ + 'warehouse_name': _('Finished Goods'), + 'company': defaults.get('company_name') + }) + + try: + frappe.get_doc({ + 'doctype': self.doctype, + 'item_code': item, + 'item_name': item, + 'description': item, + 'show_in_website': 1, + 'is_sales_item': 1, + 'is_purchase_item': 1, + 'is_stock_item': 1, + 'item_group': _('Products'), + 'stock_uom': _(args.get('item_uom_' + str(i))), + 'item_defaults': [{ + 'default_warehouse': default_warehouse, + 'company': defaults.get('company_name') + }] + }).insert() + + except frappe.NameError: + pass + else: + if args.get('item_price_' + str(i)): + item_price = flt(args.get('tem_price_' + str(i))) + + price_list_name = frappe.db.get_value('Price List', {'selling': 1}) + make_item_price(item, price_list_name, item_price) + price_list_name = frappe.db.get_value('Price List', {'buying': 1}) + make_item_price(item, price_list_name, item_price) + +def make_item_price(item, price_list_name, item_price): + frappe.get_doc({ + 'doctype': 'Item Price', + 'price_list': price_list_name, + 'item_code': item, + 'price_list_rate': item_price + }).insert() + def get_timeline_data(doctype, name): '''returns timeline data based on stock ledger entry''' out = {} diff --git a/erpnext/stock/doctype/packed_item/packed_item.json b/erpnext/stock/doctype/packed_item/packed_item.json index b089e759a0f..2ac5c426c03 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.json +++ b/erpnext/stock/doctype/packed_item/packed_item.json @@ -18,6 +18,7 @@ "serial_no", "column_break_11", "batch_no", + "actual_batch_qty", "section_break_13", "actual_qty", "projected_qty", @@ -189,15 +190,26 @@ "oldfieldtype": "Data", "print_hide": 1, "read_only": 1 + }, + { + "depends_on": "batch_no", + "fieldname": "actual_batch_qty", + "fieldtype": "Float", + "label": "Actual Batch Quantity", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 } ], "idx": 1, "istable": 1, - "modified": "2019-08-27 18:17:37.167512", + "modified": "2019-11-26 20:09:59.400960", "modified_by": "Administrator", "module": "Stock", "name": "Packed Item", "owner": "Administrator", "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", "track_changes": 1 } diff --git a/erpnext/stock/doctype/quick_stock_balance/quick_stock_balance.js b/erpnext/stock/doctype/quick_stock_balance/quick_stock_balance.js index a6f7343388c..f261fd99790 100644 --- a/erpnext/stock/doctype/quick_stock_balance/quick_stock_balance.js +++ b/erpnext/stock/doctype/quick_stock_balance/quick_stock_balance.js @@ -16,7 +16,7 @@ frappe.ui.form.on('Quick Stock Balance', { frm.add_custom_button(__('Stock Balance Report'), () => { frappe.set_route('query-report', 'Stock Balance', { 'item_code': frm.doc.item, 'warehouse': frm.doc.warehouse }); - }).addClass("btn-primary"); + }); } }, diff --git a/erpnext/stock/setup_wizard_slide/add_a_few_products_you_buy_or_sell/add_a_few_products_you_buy_or_sell.json b/erpnext/stock/setup_wizard_slide/add_a_few_products_you_buy_or_sell/add_a_few_products_you_buy_or_sell.json new file mode 100644 index 00000000000..c536f7b2cab --- /dev/null +++ b/erpnext/stock/setup_wizard_slide/add_a_few_products_you_buy_or_sell/add_a_few_products_you_buy_or_sell.json @@ -0,0 +1,57 @@ +{ + "add_more_button": 1, + "app": "ERPNext", + "creation": "2019-11-15 14:41:12.007359", + "docstatus": 0, + "doctype": "Setup Wizard Slide", + "domains": [], + "help_links": [], + "idx": 0, + "image_src": "/assets/erpnext/images/illustrations/product.png", + "max_count": 3, + "modified": "2019-11-26 18:26:35.305755", + "modified_by": "Administrator", + "name": "Add A Few Products You Buy Or Sell", + "owner": "Administrator", + "ref_doctype": "Item", + "slide_desc": "", + "slide_fields": [ + { + "align": "", + "fieldname": "item", + "fieldtype": "Data", + "label": "Item", + "placeholder": "Product Name", + "reqd": 1 + }, + { + "align": "", + "fieldtype": "Column Break", + "reqd": 1 + }, + { + "align": "", + "fieldname": "uom", + "fieldtype": "Link", + "label": "UOM", + "options": "UOM", + "reqd": 1 + }, + { + "align": "", + "fieldtype": "Column Break", + "reqd": 0 + }, + { + "align": "", + "fieldname": "item_price", + "fieldtype": "Currency", + "label": "Item Price", + "reqd": 1 + } + ], + "slide_order": 30, + "slide_title": "Add A Few Products You Buy Or Sell", + "slide_type": "Create", + "submit_method": "" +} \ No newline at end of file diff --git a/erpnext/utilities/user_progress.py b/erpnext/utilities/user_progress.py deleted file mode 100644 index 5cec3ca3846..00000000000 --- a/erpnext/utilities/user_progress.py +++ /dev/null @@ -1,287 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from __future__ import unicode_literals -import frappe, erpnext -from frappe import _ -from erpnext.setup.doctype.setup_progress.setup_progress import get_action_completed_state - -def get_slide_settings(): - defaults = frappe.defaults.get_defaults() - domain = frappe.get_cached_value('Company', erpnext.get_default_company(), 'domain') - company = defaults.get("company") or '' - currency = defaults.get("currency") or '' - - doc = frappe.get_doc("Setup Progress") - item = [d for d in doc.get("actions") if d.action_name == "Set Sales Target"] - - if len(item): - item = item[0] - if not item.action_document: - item.action_document = company - doc.save() - - # Initial state of slides - return [ - frappe._dict( - action_name='Add Company', - title=_("Setup Company") if domain != 'Education' else _("Setup Institution"), - help=_('Setup your ' + ('company' if domain != 'Education' else 'institution') + ' and brand.'), - # image_src="/assets/erpnext/images/illustrations/shop.jpg", - fields=[], - done_state_title=_("You added " + company), - done_state_title_route=["Form", "Company", company], - help_links=[ - { - "label": _("Chart of Accounts"), - "url": ["https://erpnext.com/docs/user/manual/en/accounts/chart-of-accounts"] - }, - { - "label": _("Opening Balances"), - "video_id": "U5wPIvEn-0c" - } - ] - ), - frappe._dict( - action_name='Set Sales Target', - domains=('Manufacturing', 'Services', 'Retail', 'Distribution'), - title=_("Set a Target"), - help=_("Set a sales goal you'd like to achieve for your company."), - fields=[ - {"fieldtype":"Currency", "fieldname":"monthly_sales_target", - "label":_("Monthly Sales Target (" + currency + ")"), "reqd":1}, - ], - submit_method="erpnext.utilities.user_progress_utils.set_sales_target", - done_state_title=_("Go to " + company), - done_state_title_route=["Form", "Company", company], - help_links=[ - { - "label": _('Learn More'), - "url": ["https://erpnext.com/docs/user/manual/en/setting-up/setting-company-sales-goal"] - } - ] - ), - frappe._dict( - action_name='Add Customers', - domains=('Manufacturing', 'Services', 'Retail', 'Distribution'), - title=_("Add Customers"), - help=_("List a few of your customers. They could be organizations or individuals."), - fields=[ - {"fieldtype":"Section Break"}, - {"fieldtype":"Data", "fieldname":"customer", "label":_("Customer"), - "placeholder":_("Customer Name")}, - {"fieldtype":"Column Break"}, - {"fieldtype":"Data", "fieldname":"customer_contact", - "label":_("Contact Name"), "placeholder":_("Contact Name")} - ], - add_more=1, max_count=3, mandatory_entry=1, - submit_method="erpnext.utilities.user_progress_utils.create_customers", - done_state_title=_("Go to Customers"), - done_state_title_route=["List", "Customer"], - help_links=[ - { - "label": _('Learn More'), - "url": ["https://erpnext.com/docs/user/manual/en/CRM/customer.html"] - } - ] - ), - - frappe._dict( - action_name='Add Letterhead', - domains=('Manufacturing', 'Services', 'Retail', 'Distribution', 'Education'), - title=_("Add Letterhead"), - help=_("Upload your letter head (Keep it web friendly as 900px by 100px)"), - fields=[ - {"fieldtype":"Attach Image", "fieldname":"letterhead", - "is_private": 0, - "align": "center" - }, - ], - mandatory_entry=1, - submit_method="erpnext.utilities.user_progress_utils.create_letterhead", - done_state_title=_("Go to Letterheads"), - done_state_title_route=["List", "Letter Head"] - ), - - frappe._dict( - action_name='Add Suppliers', - domains=('Manufacturing', 'Services', 'Retail', 'Distribution'), - icon="fa fa-group", - title=_("Your Suppliers"), - help=_("List a few of your suppliers. They could be organizations or individuals."), - fields=[ - {"fieldtype":"Section Break"}, - {"fieldtype":"Data", "fieldname":"supplier", "label":_("Supplier"), - "placeholder":_("Supplier Name")}, - {"fieldtype":"Column Break"}, - {"fieldtype":"Data", "fieldname":"supplier_contact", - "label":_("Contact Name"), "placeholder":_("Contact Name")}, - ], - add_more=1, max_count=3, mandatory_entry=1, - submit_method="erpnext.utilities.user_progress_utils.create_suppliers", - done_state_title=_("Go to Suppliers"), - done_state_title_route=["List", "Supplier"], - help_links=[ - { - "label": _('Learn More'), - "url": ["https://erpnext.com/docs/user/manual/en/buying/supplier"] - }, - { - "label": _('Customers and Suppliers'), - "video_id": "zsrrVDk6VBs" - }, - ] - ), - frappe._dict( - action_name='Add Products', - domains=['Manufacturing', 'Services', 'Retail', 'Distribution'], - icon="fa fa-barcode", - title=_("Your Products or Services"), - help=_("List your products or services that you buy or sell."), - fields=[ - {"fieldtype":"Section Break", "show_section_border": 1}, - {"fieldtype":"Data", "fieldname":"item", "label":_("Item"), - "placeholder":_("A Product")}, - {"fieldtype":"Column Break"}, - {"fieldtype":"Select", "fieldname":"item_uom", "label":_("UOM"), - "options":[_("Unit"), _("Nos"), _("Box"), _("Pair"), _("Kg"), _("Set"), - _("Hour"), _("Minute"), _("Litre"), _("Meter"), _("Gram")], - "default": _("Unit"), "static": 1}, - {"fieldtype":"Column Break"}, - {"fieldtype":"Currency", "fieldname":"item_price", "label":_("Rate"), "static": 1} - ], - add_more=1, max_count=3, mandatory_entry=1, - submit_method="erpnext.utilities.user_progress_utils.create_items", - done_state_title=_("Go to Items"), - done_state_title_route=["List", "Item"], - help_links=[ - { - "label": _("Explore Sales Cycle"), - "video_id": "1eP90MWoDQM" - }, - ] - ), - - # Education slides begin - frappe._dict( - action_name='Add Programs', - domains=("Education"), - title=_("Program"), - help=_("Example: Masters in Computer Science"), - fields=[ - {"fieldtype":"Section Break", "show_section_border": 1}, - {"fieldtype":"Data", "fieldname":"program", "label":_("Program"), "placeholder": _("Program Name")}, - ], - add_more=1, max_count=3, mandatory_entry=1, - submit_method="erpnext.utilities.user_progress_utils.create_program", - done_state_title=_("Go to Programs"), - done_state_title_route=["List", "Program"], - help_links=[ - { - "label": _("Student Application"), - "video_id": "l8PUACusN3E" - }, - ] - - ), - frappe._dict( - action_name='Add Courses', - domains=["Education"], - title=_("Course"), - help=_("Example: Basic Mathematics"), - fields=[ - {"fieldtype":"Section Break", "show_section_border": 1}, - {"fieldtype":"Data", "fieldname":"course", "label":_("Course"), "placeholder": _("Course Name")}, - ], - add_more=1, max_count=3, mandatory_entry=1, - submit_method="erpnext.utilities.user_progress_utils.create_course", - done_state_title=_("Go to Courses"), - done_state_title_route=["List", "Course"], - help_links=[ - { - "label": _('Add Students'), - "route": ["List", "Student"] - } - ] - ), - frappe._dict( - action_name='Add Instructors', - domains=["Education"], - title=_("Instructor"), - help=_("People who teach at your organisation"), - fields=[ - {"fieldtype":"Section Break", "show_section_border": 1}, - {"fieldtype":"Data", "fieldname":"instructor", "label":_("Instructor"), "placeholder": _("Instructor Name")}, - ], - add_more=1, max_count=3, mandatory_entry=1, - submit_method="erpnext.utilities.user_progress_utils.create_instructor", - done_state_title=_("Go to Instructors"), - done_state_title_route=["List", "Instructor"], - help_links=[ - { - "label": _('Student Batches'), - "route": ["List", "Student Batch"] - } - ] - ), - frappe._dict( - action_name='Add Rooms', - domains=["Education"], - title=_("Room"), - help=_("Classrooms/ Laboratories etc where lectures can be scheduled."), - fields=[ - {"fieldtype":"Section Break", "show_section_border": 1}, - {"fieldtype":"Data", "fieldname":"room", "label":_("Room")}, - {"fieldtype":"Column Break"}, - {"fieldtype":"Int", "fieldname":"room_capacity", "label":_("Room Capacity"), "static": 1}, - ], - add_more=1, max_count=3, mandatory_entry=1, - submit_method="erpnext.utilities.user_progress_utils.create_room", - done_state_title=_("Go to Rooms"), - done_state_title_route=["List", "Room"], - help_links=[] - ), - # Education slides end - - frappe._dict( - action_name='Add Users', - title=_("Add Users"), - help=_("Add users to your organization, other than yourself."), - fields=[ - {"fieldtype":"Section Break"}, - {"fieldtype":"Data", "fieldname":"user_email", "label":_("Email ID"), - "placeholder":_("user@example.com"), "options": "Email", "static": 1}, - {"fieldtype":"Column Break"}, - {"fieldtype":"Data", "fieldname":"user_fullname", - "label":_("Full Name"), "static": 1}, - ], - add_more=1, max_count=3, mandatory_entry=1, - submit_method="erpnext.utilities.user_progress_utils.create_users", - done_state_title=_("Go to Users"), - done_state_title_route=["List", "User"], - help_links=[ - { - "label": _('Learn More'), - "url": ["https://erpnext.com/docs/user/manual/en/setting-up/users-and-permissions"] - }, - { - "label": _('Users and Permissions'), - "video_id": "8Slw1hsTmUI" - }, - ] - ) - ] - -def get_user_progress_slides(): - slides = [] - slide_settings = get_slide_settings() - - domains = frappe.get_active_domains() - for s in slide_settings: - if not s.domains or any(d in domains for d in s.domains): - s.mark_as_done_method = "erpnext.setup.doctype.setup_progress.setup_progress.set_action_completed_state" - s.done = get_action_completed_state(s.action_name) or 0 - slides.append(s) - - return slides - diff --git a/erpnext/utilities/user_progress_utils.py b/erpnext/utilities/user_progress_utils.py deleted file mode 100644 index b7c24a71ba6..00000000000 --- a/erpnext/utilities/user_progress_utils.py +++ /dev/null @@ -1,240 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from __future__ import unicode_literals -import frappe, erpnext - -import json -from frappe import _ -from frappe.utils import flt -from erpnext.setup.doctype.setup_progress.setup_progress import update_domain_actions, get_domain_actions_state - -@frappe.whitelist() -def set_sales_target(args_data): - args = json.loads(args_data) - defaults = frappe.defaults.get_defaults() - frappe.db.set_value("Company", defaults.get("company"), "monthly_sales_target", args.get('monthly_sales_target')) - -@frappe.whitelist() -def create_customers(args_data): - args = json.loads(args_data) - defaults = frappe.defaults.get_defaults() - for i in range(1,4): - customer = args.get("customer_" + str(i)) - if customer: - try: - doc = frappe.get_doc({ - "doctype":"Customer", - "customer_name": customer, - "customer_type": "Company", - "customer_group": _("Commercial"), - "territory": defaults.get("country"), - "company": defaults.get("company") - }).insert() - - if args.get("customer_contact_" + str(i)): - create_contact(args.get("customer_contact_" + str(i)), - "Customer", doc.name) - except frappe.NameError: - pass - -@frappe.whitelist() -def create_letterhead(args_data): - args = json.loads(args_data) - letterhead = args.get("letterhead") - if letterhead: - try: - frappe.get_doc({ - "doctype":"Letter Head", - "content":"""

""".format(letterhead.encode('utf-8')), - "letter_head_name": _("Standard"), - "is_default": 1 - }).insert() - except frappe.NameError: - pass - -@frappe.whitelist() -def create_suppliers(args_data): - args = json.loads(args_data) - defaults = frappe.defaults.get_defaults() - for i in range(1,4): - supplier = args.get("supplier_" + str(i)) - if supplier: - try: - doc = frappe.get_doc({ - "doctype":"Supplier", - "supplier_name": supplier, - "supplier_group": _("Local"), - "company": defaults.get("company") - }).insert() - - if args.get("supplier_contact_" + str(i)): - create_contact(args.get("supplier_contact_" + str(i)), - "Supplier", doc.name) - except frappe.NameError: - pass - -def create_contact(contact, party_type, party): - """Create contact based on given contact name""" - contact = contact .split(" ") - - contact = frappe.get_doc({ - "doctype":"Contact", - "first_name":contact[0], - "last_name": len(contact) > 1 and contact[1] or "" - }) - contact.append('links', dict(link_doctype=party_type, link_name=party)) - contact.insert() - -@frappe.whitelist() -def create_items(args_data): - args = json.loads(args_data) - defaults = frappe.defaults.get_defaults() - for i in range(1,4): - item = args.get("item_" + str(i)) - if item: - default_warehouse = "" - default_warehouse = frappe.db.get_value("Warehouse", filters={ - "warehouse_name": _("Finished Goods"), - "company": defaults.get("company_name") - }) - - try: - frappe.get_doc({ - "doctype":"Item", - "item_code": item, - "item_name": item, - "description": item, - "show_in_website": 1, - "is_sales_item": 1, - "is_purchase_item": 1, - "is_stock_item": 1, - "item_group": _("Products"), - "stock_uom": _(args.get("item_uom_" + str(i))), - "item_defaults": [{ - "default_warehouse": default_warehouse, - "company": defaults.get("company_name") - }] - }).insert() - - except frappe.NameError: - pass - else: - if args.get("item_price_" + str(i)): - item_price = flt(args.get("item_price_" + str(i))) - - price_list_name = frappe.db.get_value("Price List", {"selling": 1}) - make_item_price(item, price_list_name, item_price) - price_list_name = frappe.db.get_value("Price List", {"buying": 1}) - make_item_price(item, price_list_name, item_price) - - -def make_item_price(item, price_list_name, item_price): - frappe.get_doc({ - "doctype": "Item Price", - "price_list": price_list_name, - "item_code": item, - "price_list_rate": item_price - }).insert() - -# Education -@frappe.whitelist() -def create_program(args_data): - args = json.loads(args_data) - for i in range(1,4): - if args.get("program_" + str(i)): - program = frappe.new_doc("Program") - program.program_code = args.get("program_" + str(i)) - program.program_name = args.get("program_" + str(i)) - try: - program.save() - except frappe.DuplicateEntryError: - pass - -@frappe.whitelist() -def create_course(args_data): - args = json.loads(args_data) - for i in range(1,4): - if args.get("course_" + str(i)): - course = frappe.new_doc("Course") - course.course_code = args.get("course_" + str(i)) - course.course_name = args.get("course_" + str(i)) - try: - course.save() - except frappe.DuplicateEntryError: - pass - -@frappe.whitelist() -def create_instructor(args_data): - args = json.loads(args_data) - for i in range(1,4): - if args.get("instructor_" + str(i)): - instructor = frappe.new_doc("Instructor") - instructor.instructor_name = args.get("instructor_" + str(i)) - try: - instructor.save() - except frappe.DuplicateEntryError: - pass - -@frappe.whitelist() -def create_room(args_data): - args = json.loads(args_data) - for i in range(1,4): - if args.get("room_" + str(i)): - room = frappe.new_doc("Room") - room.room_name = args.get("room_" + str(i)) - room.seating_capacity = args.get("room_capacity_" + str(i)) - try: - room.save() - except frappe.DuplicateEntryError: - pass - -@frappe.whitelist() -def create_users(args_data): - if frappe.session.user == 'Administrator': - return - args = json.loads(args_data) - defaults = frappe.defaults.get_defaults() - for i in range(1,4): - email = args.get("user_email_" + str(i)) - fullname = args.get("user_fullname_" + str(i)) - if email: - if not fullname: - fullname = email.split("@")[0] - - parts = fullname.split(" ", 1) - - user = frappe.get_doc({ - "doctype": "User", - "email": email, - "first_name": parts[0], - "last_name": parts[1] if len(parts) > 1 else "", - "enabled": 1, - "user_type": "System User" - }) - - # default roles - user.append_roles("Projects User", "Stock User", "Support Team") - user.flags.delay_emails = True - - if not frappe.db.get_value("User", email): - user.insert(ignore_permissions=True) - - # create employee - emp = frappe.get_doc({ - "doctype": "Employee", - "employee_name": fullname, - "user_id": email, - "status": "Active", - "company": defaults.get("company") - }) - emp.flags.ignore_mandatory = True - emp.insert(ignore_permissions = True) - -# Ennumerate the setup hooks you're going to need, apart from the slides - -@frappe.whitelist() -def update_default_domain_actions_and_get_state(): - domain = frappe.get_cached_value('Company', erpnext.get_default_company(), 'domain') - update_domain_actions(domain) - return get_domain_actions_state(domain) diff --git a/requirements.txt b/requirements.txt index 28ba9f676ff..c277545fab5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ +braintree==3.57.1 frappe -unidecode -pygithub -googlemaps -python-stdnum -braintree -gocardless_pro -woocommerce -pandas -plaid-python \ No newline at end of file +gocardless-pro==1.11.0 +googlemaps==3.1.1 +pandas==0.24.2 +plaid-python==3.4.0 +PyGithub==1.44.1 +python-stdnum==1.12 +Unidecode==1.1.1 +WooCommerce==2.1.1