diff --git a/.travis.yml b/.travis.yml index 80d979f602a..cae50cb9087 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,11 +51,14 @@ before_script: - bench start & - sleep 10 -script: - - set -e - - bench run-tests - - sleep 5 - - bench reinstall --yes - - bench --verbose run-setup-wizard-ui-test - - bench execute erpnext.setup.utils.enable_all_roles_and_domains - - bench run-ui-tests --app erpnext +jobs: + include: + - stage: test + script: + - set -e + - bench run-tests + - # stage + script: + - bench --verbose run-setup-wizard-ui-test + - bench execute erpnext.setup.utils.enable_all_roles_and_domains + - bench run-ui-tests --app erpnext diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 1c9b0b45305..61381b27033 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from erpnext.hooks import regional_overrides -__version__ = '8.11.2' +__version__ = '8.11.4' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index 304af373081..47e214e1b48 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -36,7 +36,7 @@ class GLEntry(Document): validate_balance_type(self.account, adv_adj) # Update outstanding amt on against voucher - if self.against_voucher_type in ['Journal Entry', 'Sales Invoice', 'Purchase Invoice'] \ + if self.against_voucher_type in ['Journal Entry', 'Sales Invoice', 'Purchase Invoice', 'Fees'] \ and self.against_voucher and update_outstanding == 'Yes' and not from_repost: update_outstanding_amt(self.account, self.party_type, self.party, self.against_voucher_type, self.against_voucher) @@ -196,7 +196,7 @@ def update_outstanding_amt(account, party_type, party, against_voucher_type, aga frappe.throw(_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal))) # Update outstanding amt on against voucher - if against_voucher_type in ["Sales Invoice", "Purchase Invoice"]: + if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]: ref_doc = frappe.get_doc(against_voucher_type, against_voucher) ref_doc.db_set('outstanding_amount', bal) ref_doc.set_status(update=True) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index dc37574ea6a..61ede97122c 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -12,7 +12,8 @@ frappe.ui.form.on('Payment Entry', { setup: function(frm) { frm.set_query("paid_from", function() { - var party_account_type = frm.doc.party_type=="Customer" ? "Receivable" : "Payable"; + var party_account_type = in_list(["Customer", "Student"], frm.doc.party_type) ? + "Receivable" : "Payable"; var account_types = in_list(["Pay", "Internal Transfer"], frm.doc.payment_type) ? ["Bank", "Cash"] : party_account_type; @@ -28,13 +29,14 @@ frappe.ui.form.on('Payment Entry', { frm.set_query("party_type", function() { return{ "filters": { - "name": ["in",["Customer","Supplier", "Employee"]], + "name": ["in",["Customer","Supplier", "Employee", "Student"]], } } }); frm.set_query("paid_to", function() { - var party_account_type = frm.doc.party_type=="Customer" ? "Receivable" : "Payable"; + var party_account_type = in_list(["Customer", "Student"], frm.doc.party_type) ? + "Receivable" : "Payable"; var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ? ["Bank", "Cash"] : party_account_type; @@ -72,6 +74,8 @@ frappe.ui.form.on('Payment Entry', { var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"]; } else if (frm.doc.party_type=="Employee") { var doctypes = ["Expense Claim", "Journal Entry"]; + } else if (frm.doc.party_type=="Student") { + var doctypes = ["Fees"]; } else { var doctypes = ["Journal Entry"]; } @@ -85,7 +89,7 @@ frappe.ui.form.on('Payment Entry', { child = locals[cdt][cdn]; filters = {"docstatus": 1, "company": doc.company}; party_type_doctypes = ['Sales Invoice', 'Sales Order', 'Purchase Invoice', - 'Purchase Order', 'Expense Claim']; + 'Purchase Order', 'Expense Claim', 'Fees']; if (in_list(party_type_doctypes, child.reference_doctype)) { filters[doc.party_type.toLowerCase()] = doc.party; @@ -207,19 +211,13 @@ frappe.ui.form.on('Payment Entry', { frm.set_value(field, null); }); } else { - if(!frm.doc.party) - { - if (frm.doc.payment_type=="Receive"){ - frm.set_value("party_type", "Customer"); - } - } - else - { - frm.events.party(frm); + if(frm.doc.party) { + frm.events.party(frm); } - if(frm.doc.mode_of_payment) + if(frm.doc.mode_of_payment) { frm.events.mode_of_payment(frm); + } } }, @@ -254,6 +252,7 @@ frappe.ui.form.on('Payment Entry', { date: frm.doc.posting_date }, callback: function(r, rt) { + console.log(r, rt); if(r.message) { if(frm.doc.payment_type == "Receive") { frm.set_value("paid_from", r.message.party_account); @@ -502,6 +501,8 @@ frappe.ui.form.on('Payment Entry', { c.due_date = d.due_date c.total_amount = d.invoice_amount; c.outstanding_amount = d.outstanding_amount; + c.bill_no = d.bill_no; + if(!in_list(["Sales Order", "Purchase Order", "Expense Claim"], d.voucher_type)) { if(flt(d.outstanding_amount) > 0) total_positive_outstanding += flt(d.outstanding_amount); diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 7ae9bde4625..195a27f69af 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -100,8 +100,8 @@ class PaymentEntry(AccountsController): if not self.party: frappe.throw(_("Party is mandatory")) - self.party_name = frappe.db.get_value(self.party_type, self.party, - self.party_type.lower() + "_name") + _party_name = "title" if self.party_type == "Student" else self.party_type.lower() + "_name" + self.party_name = frappe.db.get_value(self.party_type, self.party, _party_name) if self.party: if not self.party_balance: @@ -149,7 +149,7 @@ class PaymentEntry(AccountsController): frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party)) if self.party_account: - party_account_type = "Receivable" if self.party_type=="Customer" else "Payable" + party_account_type = "Receivable" if self.party_type in ("Customer", "Student") else "Payable" self.validate_account_type(self.party_account, [party_account_type]) def validate_bank_accounts(self): @@ -182,7 +182,9 @@ class PaymentEntry(AccountsController): frappe.throw(_("{0} is mandatory").format(self.meta.get_label(field))) def validate_reference_documents(self): - if self.party_type == "Customer": + if self.party_type == "Student": + valid_reference_doctypes = ("Fees") + elif self.party_type == "Customer": valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry") elif self.party_type == "Supplier": valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry") @@ -209,15 +211,17 @@ class PaymentEntry(AccountsController): else: self.validate_journal_entry() - if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim"): - if self.party_type=="Customer": + if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim", "Fees"): + if self.party_type == "Customer": ref_party_account = ref_doc.debit_to + elif self.party_type == "Student": + ref_party_account = ref_doc.receivable_account elif self.party_type=="Supplier": ref_party_account = ref_doc.credit_to elif self.party_type=="Employee": ref_party_account = ref_doc.payable_account - if ref_party_account != self.party_account: + if ref_party_account != self.party_account: frappe.throw(_("{0} {1} is associated with {2}, but Party Account is {3}") .format(d.reference_doctype, d.reference_name, ref_party_account, self.party_account)) @@ -398,7 +402,7 @@ class PaymentEntry(AccountsController): "account_currency": self.party_account_currency }) - dr_or_cr = "credit" if self.party_type == "Customer" else "debit" + dr_or_cr = "credit" if self.party_type in ["Customer", "Student"] else "debit" for d in self.get("references"): gle = party_gl_dict.copy() @@ -484,9 +488,14 @@ class PaymentEntry(AccountsController): doc = frappe.get_doc("Expense Claim", d.reference_name) update_reimbursed_amount(doc) + def on_recurring(self, reference_doc, subscription_doc): + self.reference_no = reference_doc.name + self.reference_date = nowdate() + @frappe.whitelist() def get_outstanding_reference_documents(args): - args = json.loads(args) + if isinstance(args, basestring): + args = json.loads(args) party_account_currency = get_account_currency(args.get("party_account")) company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency") @@ -494,10 +503,12 @@ def get_outstanding_reference_documents(args): # Get negative outstanding sales /purchase invoices total_field = "base_grand_total" if party_account_currency == company_currency else "grand_total" - negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), - args.get("party"), args.get("party_account"), total_field) + negative_outstanding_invoices = [] + if (args.get("party_type") != "Student"): + negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), + args.get("party"), args.get("party_account"), total_field) - # Get positive outstanding sales /purchase invoices + # Get positive outstanding sales /purchase invoices/ Fees outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"), args.get("party_account")) @@ -510,10 +521,14 @@ def get_outstanding_reference_documents(args): d["exchange_rate"] = get_exchange_rate( party_account_currency, company_currency, d.posting_date ) + if d.voucher_type in ("Purchase Invoice"): + d["bill_no"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "bill_no") # Get all SO / PO which are not fully billed or aginst which full advance not paid - orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"), args.get("party"), - party_account_currency, company_currency) + orders_to_be_billed = [] + if (args.get("party_type") != "Student"): + orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"), + args.get("party"), party_account_currency, company_currency) return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed @@ -628,7 +643,11 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre total_amount = outstanding_amount = exchange_rate = None ref_doc = frappe.get_doc(reference_doctype, reference_name) - if reference_doctype != "Journal Entry": + if reference_doctype == "Fees": + total_amount = ref_doc.get("grand_total") + exchange_rate = 1 + outstanding_amount = ref_doc.get("outstanding_amount") + elif reference_doctype != "Journal Entry": if party_account_currency == ref_doc.company_currency: if ref_doc.doctype == "Expense Claim": total_amount = ref_doc.total_sanctioned_amount @@ -671,19 +690,23 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount= party_type = "Supplier" elif dt in ("Expense Claim"): party_type = "Employee" + elif dt in ("Fees"): + party_type = "Student" # party account if dt == "Sales Invoice": party_account = doc.debit_to elif dt == "Purchase Invoice": party_account = doc.credit_to + elif dt == "Fees": + party_account = doc.receivable_account else: party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company) party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account) # payment type - if (dt == "Sales Order" or (dt=="Sales Invoice" and doc.outstanding_amount > 0)) \ + if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees") and doc.outstanding_amount > 0)) \ or (dt=="Purchase Invoice" and doc.outstanding_amount < 0): payment_type = "Receive" else: @@ -699,6 +722,9 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount= elif dt in ("Expense Claim"): grand_total = doc.total_sanctioned_amount outstanding_amount = doc.total_sanctioned_amount - doc.total_amount_reimbursed + elif dt == "Fees": + grand_total = doc.grand_total + outstanding_amount = doc.outstanding_amount else: total_field = "base_grand_total" if party_account_currency == doc.company_currency else "grand_total" grand_total = flt(doc.get(total_field)) diff --git a/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js b/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js index 7dea76db800..4f27b74d4b8 100644 --- a/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js +++ b/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js @@ -9,9 +9,9 @@ QUnit.test("test payment entry", function(assert) { {customer: 'Test Customer 1'}, {items: [ [ + {'item_code': 'Test Product 1'}, {'qty': 1}, {'rate': 101}, - {'item_code': 'Test Product 1'}, ] ]} ]); @@ -19,11 +19,12 @@ QUnit.test("test payment entry", function(assert) { () => cur_frm.save(), () => frappe.tests.click_button('Submit'), () => frappe.tests.click_button('Yes'), - () => frappe.timeout(0.5), + () => frappe.timeout(1), () => frappe.tests.click_button('Close'), - () => frappe.timeout(0.5), + () => frappe.timeout(1), () => frappe.click_button('Make'), - () => frappe.click_link('Payment', 1), + () => frappe.timeout(1), + () => frappe.click_link('Payment'), () => frappe.timeout(2), () => { assert.equal(frappe.get_route()[1], 'Payment Entry', @@ -35,16 +36,19 @@ QUnit.test("test payment entry", function(assert) { assert.equal(cur_frm.doc.references[0].allocated_amount, 101, 'amount allocated against sales invoice'); }, + () => frappe.timeout(1), () => cur_frm.set_value('paid_amount', 100), + () => frappe.timeout(1), () => { - cur_frm.doc.references[0].allocated_amount = 101; + frappe.model.set_value("Payment Entry Reference", cur_frm.doc.references[0].name, + "allocated_amount", 101); }, + () => frappe.timeout(1), () => frappe.click_button('Write Off Difference Amount'), + () => frappe.timeout(1), () => { - assert.equal(cur_frm.doc.difference_amount, 0, - 'difference amount is zero'); - assert.equal(cur_frm.doc.deductions[0].amount, 1, - 'Write off amount = 1'); + assert.equal(cur_frm.doc.difference_amount, 0, 'difference amount is zero'); + assert.equal(cur_frm.doc.deductions[0].amount, 1, 'Write off amount = 1'); }, () => done() ]); diff --git a/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry_write_off.js b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry_write_off.js index 133f1362988..9849d767271 100644 --- a/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry_write_off.js +++ b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry_write_off.js @@ -7,7 +7,7 @@ QUnit.test("test payment entry", function(assert) { () => { return frappe.tests.make('Sales Invoice', [ {customer: 'Test Customer 1'}, - {company: '_Test Company'}, + {company: 'For Testing'}, {currency: 'INR'}, {selling_price_list: '_Test Price List'}, {items: [ @@ -29,12 +29,12 @@ QUnit.test("test payment entry", function(assert) { () => frappe.timeout(1), () => frappe.click_link('Payment'), () => frappe.timeout(2), - () => cur_frm.set_value("paid_to", "_Test Cash - _TC"), + () => cur_frm.set_value("paid_to", "_Test Cash - FT"), () => frappe.timeout(0.5), () => { assert.equal(frappe.get_route()[1], 'Payment Entry', 'made payment entry'); assert.equal(cur_frm.doc.party, 'Test Customer 1', 'customer set in payment entry'); - assert.equal(cur_frm.doc.paid_from, 'Debtors - _TC', 'customer account set in payment entry'); + assert.equal(cur_frm.doc.paid_from, 'Debtors - FT', 'customer account set in payment entry'); assert.equal(cur_frm.doc.paid_amount, 100, 'paid amount set in payment entry'); assert.equal(cur_frm.doc.references[0].allocated_amount, 100, 'amount allocated against sales invoice'); @@ -50,10 +50,10 @@ QUnit.test("test payment entry", function(assert) { assert.equal(cur_frm.doc.difference_amount, 5, 'difference amount is 5'); }, () => { - frappe.db.set_value("Company", "_Test Company", "write_off_account", "_Test Write Off - _TC"); + frappe.db.set_value("Company", "For Testing", "write_off_account", "_Test Write Off - FT"); frappe.timeout(1); - frappe.db.set_value("Company", "_Test Company", - "exchange_gain_loss_account", "_Test Exchange Gain/Loss - _TC"); + frappe.db.set_value("Company", "For Testing", + "exchange_gain_loss_account", "_Test Exchange Gain/Loss - FT"); }, () => frappe.timeout(1), () => frappe.click_button('Write Off Difference Amount'), diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json index 8104e9b3fc6..da17bb3fc85 100644 --- a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json +++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, "beta": 0, @@ -12,6 +13,7 @@ "engine": "InnoDB", "fields": [ { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -42,6 +44,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -72,6 +75,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -101,6 +105,38 @@ "unique": 0 }, { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "", + "fieldname": "bill_no", + "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": "Supplier Invoice No", + "length": 0, + "no_copy": 1, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "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, @@ -129,6 +165,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -158,6 +195,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -187,6 +225,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -216,10 +255,12 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "depends_on": "eval:(doc.reference_doctype=='Purchase Invoice')", "fieldname": "exchange_rate", "fieldtype": "Float", "hidden": 0, @@ -245,17 +286,17 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "idx": 0, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 0, "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2017-02-17 16:47:17.156256", + "modified": "2017-09-04 17:37:01.192312", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry Reference", diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 44a3644a0cf..807ad280dbe 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -35,7 +35,6 @@ class PaymentRequest(Document): def on_submit(self): send_mail = True - self.make_communication_entry() ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart") \ @@ -45,6 +44,7 @@ class PaymentRequest(Document): if send_mail: self.set_payment_request_url() self.send_email() + self.make_communication_entry() def on_cancel(self): self.check_if_payment_entry_exists() @@ -69,8 +69,11 @@ class PaymentRequest(Document): self.db_set('status', 'Initiated') def get_payment_url(self): - data = frappe.db.get_value(self.reference_doctype, self.reference_name, - ["company", "customer_name"], as_dict=1) + if self.reference_doctype != "Fees": + data = frappe.db.get_value(self.reference_doctype, self.reference_name, ["company", "customer_name"], as_dict=1) + else: + data = frappe.db.get_value(self.reference_doctype, self.reference_name, ["student_name"], as_dict=1) + data.update({"company": frappe.defaults.get_defaults().company}) controller = get_payment_gateway_controller(self.payment_gateway) controller.validate_transaction_currency(self.currency) @@ -277,6 +280,9 @@ def get_amount(ref_doc, dt): else: grand_total = flt(ref_doc.outstanding_amount) / ref_doc.conversion_rate + if dt == "Fees": + grand_total = ref_doc.outstanding_amount + if grand_total > 0 : return grand_total diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index 066809ededd..fb28d13ea1f 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -2072,6 +2072,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "base_rounding_adjustment", + "fieldtype": "Currency", + "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": "Rounding Adjustment (Company Currency)", + "length": 0, + "no_copy": 1, + "options": "Company:company:default_currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "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, @@ -2166,6 +2197,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "rounding_adjustment", + "fieldtype": "Currency", + "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": "Rounding Adjustment", + "length": 0, + "no_copy": 1, + "options": "currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "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, diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 180ad8900d5..a564d923387 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -15,6 +15,7 @@ from erpnext.stock import get_warehouse_account_map from erpnext.accounts.general_ledger import make_gl_entries, merge_similar_entries, delete_gl_entries from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt from erpnext.buying.utils import check_for_closed_status +from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center form_grid_templates = { "items": "templates/form_grid/item_grid.html" @@ -353,6 +354,7 @@ class PurchaseInvoice(BuyingController): self.make_payment_gl_entries(gl_entries) self.make_write_off_gl_entry(gl_entries) + self.make_gle_for_rounding_adjustment(gl_entries) return gl_entries @@ -604,6 +606,21 @@ class PurchaseInvoice(BuyingController): }) ) + def make_gle_for_rounding_adjustment(self, gl_entries): + if self.rounding_adjustment: + round_off_account, round_off_cost_center = \ + get_round_off_account_and_cost_center(self.company) + + gl_entries.append( + self.get_gl_dict({ + "account": round_off_account, + "against": self.supplier, + "debit_in_account_currency": self.rounding_adjustment, + "debit": self.base_rounding_adjustment, + "cost_center": round_off_cost_center, + } + )) + def on_cancel(self): self.check_for_closed_status() diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index f1ba18c07a0..25f2426e2e7 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -1670,36 +1670,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "net_total", - "fieldtype": "Currency", - "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": "Net Total", - "length": 0, - "no_copy": 0, - "options": "currency", - "permlevel": 0, - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "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, @@ -1731,6 +1701,36 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "net_total", + "fieldtype": "Currency", + "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": "Net Total", + "length": 0, + "no_copy": 0, + "options": "currency", + "permlevel": 0, + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "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, @@ -2337,6 +2337,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "base_rounding_adjustment", + "fieldtype": "Currency", + "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": "Rounding Adjustment (Company Currency)", + "length": 0, + "no_copy": 1, + "options": "Company:company:default_currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "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, @@ -2463,6 +2494,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "rounding_adjustment", + "fieldtype": "Currency", + "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": "Rounding Adjustment", + "length": 0, + "no_copy": 1, + "options": "currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "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, diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 3f8a1fb6c65..678988db6ee 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -20,6 +20,7 @@ from erpnext.accounts.doctype.asset.depreciation \ from erpnext.stock.doctype.batch.batch import set_batch_nos from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos, get_delivery_note_serial_no from erpnext.setup.doctype.company.company import update_company_current_month_sales +from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center form_grid_templates = { "items": "templates/form_grid/item_grid.html" @@ -625,6 +626,7 @@ class SalesInvoice(SellingController): self.make_gle_for_change_amount(gl_entries) self.make_write_off_gl_entry(gl_entries) + self.make_gle_for_rounding_adjustment(gl_entries) return gl_entries @@ -804,6 +806,21 @@ class SalesInvoice(SellingController): }, write_off_account_currency) ) + def make_gle_for_rounding_adjustment(self, gl_entries): + if self.rounding_adjustment: + round_off_account, round_off_cost_center = \ + get_round_off_account_and_cost_center(self.company) + + gl_entries.append( + self.get_gl_dict({ + "account": round_off_account, + "against": self.customer, + "credit_in_account_currency": self.rounding_adjustment, + "credit": self.base_rounding_adjustment, + "cost_center": round_off_cost_center, + } + )) + def update_billing_status_in_dn(self, update_modified=True): updated_delivery_notes = [] for d in self.get("items"): diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 60e1dbc8490..da33a7807a1 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -224,12 +224,12 @@ class TestSalesInvoice(unittest.TestCase): si.save() # with inclusive tax and additional discount - self.assertEquals(si.net_total, 4298.24) + self.assertEquals(si.net_total, 4298.25) self.assertEquals(si.grand_total, 4900.00) def test_sales_invoice_discount_amount(self): si = frappe.copy_doc(test_records[3]) - si.discount_amount = 104.95 + si.discount_amount = 104.94 si.append("taxes", { "charge_type": "On Previous Row Amount", "account_head": "_Test Account Service Tax - _TC", @@ -294,7 +294,7 @@ class TestSalesInvoice(unittest.TestCase): "_Test Account Customs Duty - _TC": [125, 116.35, 1585.40], "_Test Account Shipping Charges - _TC": [100, 100, 1685.40], "_Test Account Discount - _TC": [-180.33, -168.54, 1516.86], - "_Test Account Service Tax - _TC": [-18.03, -16.86, 1500] + "_Test Account Service Tax - _TC": [-18.03, -16.85, 1500.01] } for d in si.get("taxes"): @@ -303,10 +303,12 @@ class TestSalesInvoice(unittest.TestCase): self.assertEquals(si.base_grand_total, 1500) self.assertEquals(si.grand_total, 1500) + self.assertEquals(si.rounding_adjustment, -0.01) def test_discount_amount_gl_entry(self): + frappe.db.set_value("Company", "_Test Company", "round_off_account", "Round Off - _TC") si = frappe.copy_doc(test_records[3]) - si.discount_amount = 104.95 + si.discount_amount = 104.94 si.append("taxes", { "doctype": "Sales Taxes and Charges", "charge_type": "On Previous Row Amount", @@ -336,7 +338,8 @@ class TestSalesInvoice(unittest.TestCase): [test_records[3]["taxes"][5]["account_head"], 0.0, 116.35], [test_records[3]["taxes"][6]["account_head"], 0.0, 100], [test_records[3]["taxes"][7]["account_head"], 168.54, 0.0], - ["_Test Account Service Tax - _TC", 16.86, 0.0] + ["_Test Account Service Tax - _TC", 16.85, 0.0], + ["Round Off - _TC", 0.01, 0.0] ]) for gle in gl_entries: @@ -432,13 +435,12 @@ class TestSalesInvoice(unittest.TestCase): expected_values = { "keys": ["price_list_rate", "discount_percentage", "rate", "amount", "base_price_list_rate", "base_rate", "base_amount", "net_rate", "net_amount"], - "_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 62.5, 62.5, 625.0, 50, 499.98], - "_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 190.66, 190.66, 953.3, 150, 750], + "_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 62.5, 62.5, 625.0, 50, 499.97600115194473], + "_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 190.66, 190.66, 953.3, 150, 749.9968530500239], } # check if children are saved - self.assertEquals(len(si.get("items")), - len(expected_values)-1) + self.assertEquals(len(si.get("items")), len(expected_values)-1) # check if item values are calculated for d in si.get("items"): @@ -446,28 +448,28 @@ class TestSalesInvoice(unittest.TestCase): self.assertEquals(d.get(k), expected_values[d.item_code][i]) # check net total - self.assertEquals(si.base_net_total, 1249.98) + self.assertEquals(si.net_total, 1249.97) self.assertEquals(si.total, 1578.3) # check tax calculation expected_values = { "keys": ["tax_amount", "total"], - "_Test Account Excise Duty - _TC": [140, 1389.98], - "_Test Account Education Cess - _TC": [2.8, 1392.78], - "_Test Account S&H Education Cess - _TC": [1.4, 1394.18], - "_Test Account CST - _TC": [27.88, 1422.06], - "_Test Account VAT - _TC": [156.25, 1578.31], - "_Test Account Customs Duty - _TC": [125, 1703.31], - "_Test Account Shipping Charges - _TC": [100, 1803.31], - "_Test Account Discount - _TC": [-180.33, 1622.98] + "_Test Account Excise Duty - _TC": [140, 1389.97], + "_Test Account Education Cess - _TC": [2.8, 1392.77], + "_Test Account S&H Education Cess - _TC": [1.4, 1394.17], + "_Test Account CST - _TC": [27.88, 1422.05], + "_Test Account VAT - _TC": [156.25, 1578.30], + "_Test Account Customs Duty - _TC": [125, 1703.30], + "_Test Account Shipping Charges - _TC": [100, 1803.30], + "_Test Account Discount - _TC": [-180.33, 1622.97] } for d in si.get("taxes"): for i, k in enumerate(expected_values["keys"]): self.assertEquals(d.get(k), expected_values[d.account_head][i]) - self.assertEquals(si.base_grand_total, 1622.98) - self.assertEquals(si.grand_total, 1622.98) + self.assertEquals(si.base_grand_total, 1622.97) + self.assertEquals(si.grand_total, 1622.97) def test_sales_invoice_calculation_export_currency_with_tax_inclusive_price(self): # prepare @@ -495,7 +497,7 @@ class TestSalesInvoice(unittest.TestCase): "base_rate": 2500, "base_amount": 25000, "net_rate": 40, - "net_amount": 399.98, + "net_amount": 399.9808009215558, "base_net_rate": 2000, "base_net_amount": 19999 }, @@ -509,7 +511,7 @@ class TestSalesInvoice(unittest.TestCase): "base_rate": 7500, "base_amount": 37500, "net_rate": 118.01, - "net_amount": 590.05, + "net_amount": 590.0531205155963, "base_net_rate": 5900.5, "base_net_amount": 29502.5 } @@ -545,8 +547,11 @@ class TestSalesInvoice(unittest.TestCase): for i, k in enumerate(expected_values["keys"]): self.assertEquals(d.get(k), expected_values[d.account_head][i]) - self.assertEquals(si.base_grand_total, 60794.5) - self.assertEquals(si.grand_total, 1215.89) + self.assertEquals(si.base_grand_total, 60795) + self.assertEquals(si.grand_total, 1215.90) + self.assertEquals(si.rounding_adjustment, 0.01) + self.assertEquals(si.base_rounding_adjustment, 0.50) + def test_outstanding(self): w = self.make() @@ -1313,6 +1318,40 @@ class TestSalesInvoice(unittest.TestCase): current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales") self.assertEqual(current_month_sales, existing_current_month_sales) + def test_rounding_adjustment(self): + si = create_sales_invoice(rate=24900, do_not_save=True) + for tax in ["Tax 1", "Tax2"]: + si.append("taxes", { + "charge_type": "On Net Total", + "account_head": "_Test Account Service Tax - _TC", + "description": tax, + "rate": 14, + "cost_center": "_Test Cost Center - _TC", + "included_in_print_rate": 1 + }) + si.save() + + self.assertEqual(si.net_total, 19453.13) + self.assertEqual(si.grand_total, 24900) + self.assertEqual(si.total_taxes_and_charges, 5446.88) + self.assertEqual(si.rounding_adjustment, -0.01) + + expected_values = dict((d[0], d) for d in [ + [si.debit_to, 24900, 0.0], + ["_Test Account Service Tax - _TC", 0.0, 5446.88], + ["Sales - _TC", 0.0, 19453.13], + ["Round Off - _TC", 0.01, 0.0] + ]) + + gl_entries = frappe.db.sql("""select account, debit, credit + from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s + order by account asc""", si.name, as_dict=1) + + for gle in gl_entries: + self.assertEquals(expected_values[gle.account][0], gle.account) + self.assertEquals(expected_values[gle.account][1], gle.debit) + self.assertEquals(expected_values[gle.account][2], gle.credit) + def create_sales_invoice(**args): si = frappe.new_doc("Sales Invoice") args = frappe._dict(args) diff --git a/erpnext/docs/assets/img/subscription/__init__.py b/erpnext/accounts/doctype/subscription/__init__.py similarity index 100% rename from erpnext/docs/assets/img/subscription/__init__.py rename to erpnext/accounts/doctype/subscription/__init__.py diff --git a/erpnext/accounts/doctype/subscription/subscription.js b/erpnext/accounts/doctype/subscription/subscription.js new file mode 100644 index 00000000000..c9b3c6480dd --- /dev/null +++ b/erpnext/accounts/doctype/subscription/subscription.js @@ -0,0 +1,77 @@ +// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Subscription', { + setup: function(frm) { + if(frm.doc.__islocal) { + var last_route = frappe.route_history.slice(-2, -1)[0]; + if(frappe.dynamic_link && frappe.dynamic_link.doc + && frappe.dynamic_link.doc.name==last_route[2]) { + frm.set_value('reference_doctype', last_route[1]); + frm.set_value('reference_document', last_route[2]); + } + } + + frm.fields_dict['reference_document'].get_query = function() { + return { + filters: { + "docstatus": 1 + } + }; + }; + + frm.fields_dict['print_format'].get_query = function() { + return { + filters: { + "doc_type": frm.doc.reference_doctype + } + }; + }; + }, + + refresh: function(frm) { + if(frm.doc.docstatus == 1) { + let label = __('View {0}', [frm.doc.reference_doctype]); + frm.add_custom_button(__(label), + function() { + frappe.route_options = { + "subscription": frm.doc.name, + }; + frappe.set_route("List", frm.doc.reference_doctype); + } + ); + + if(frm.doc.status != 'Stopped') { + frm.add_custom_button(__("Stop"), + function() { + frm.events.stop_resume_subscription(frm, "Stopped"); + } + ); + } + + if(frm.doc.status == 'Stopped') { + frm.add_custom_button(__("Resume"), + function() { + frm.events.stop_resume_subscription(frm, "Resumed"); + } + ); + } + } + }, + + stop_resume_subscription: function(frm, status) { + frappe.call({ + method: "erpnext.accounts.doctype.subscription.subscription.stop_resume_subscription", + args: { + subscription: frm.doc.name, + status: status + }, + callback: function(r) { + if(r.message) { + frm.set_value("status", r.message); + frm.reload_doc(); + } + } + }); + } +}); \ No newline at end of file diff --git a/erpnext/subscription/doctype/subscription/subscription.json b/erpnext/accounts/doctype/subscription/subscription.json similarity index 94% rename from erpnext/subscription/doctype/subscription/subscription.json rename to erpnext/accounts/doctype/subscription/subscription.json index 6cfee1e44f7..85779533ea2 100644 --- a/erpnext/subscription/doctype/subscription/subscription.json +++ b/erpnext/accounts/doctype/subscription/subscription.json @@ -148,7 +148,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, "label": "Disabled", "length": 0, @@ -619,24 +619,24 @@ }, { "allow_bulk_edit": 0, - "allow_on_submit": 0, + "allow_on_submit": 1, "bold": 0, "collapsible": 0, "columns": 0, "default": "Draft", "fieldname": "status", "fieldtype": "Select", - "hidden": 1, + "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, "label": "Status", "length": 0, "no_copy": 0, - "options": "\nDraft\nSubmitted\nCancelled\nCompleted", + "options": "\nDraft\nStopped\nSubmitted\nCancelled\nCompleted", "permlevel": 0, "precision": "", "print_hide": 0, @@ -690,9 +690,9 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-08-29 15:45:16.157643", + "modified": "2017-09-14 12:09:38.471458", "modified_by": "Administrator", - "module": "Subscription", + "module": "Accounts", "name": "Subscription", "name_case": "", "owner": "Administrator", @@ -700,7 +700,7 @@ { "amend": 0, "apply_user_permissions": 0, - "cancel": 1, + "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -716,6 +716,46 @@ "share": 1, "submit": 1, "write": 1 + }, + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User", + "set_user_permissions": 0, + "share": 1, + "submit": 1, + "write": 1 + }, + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 1, + "write": 1 } ], "quick_entry": 0, diff --git a/erpnext/subscription/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py similarity index 82% rename from erpnext/subscription/doctype/subscription/subscription.py rename to erpnext/accounts/doctype/subscription/subscription.py index be36211ec27..c9df7d461e5 100644 --- a/erpnext/subscription/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -71,13 +71,16 @@ class Subscription(Document): doc.db_set('subscription', self.name) - def update_status(self): + def update_status(self, status=None): self.status = { '0': 'Draft', '1': 'Submitted', '2': 'Cancelled' }[cstr(self.docstatus or 0)] + if status and status != 'Resumed': + self.status = status + def get_next_schedule_date(start_date, frequency, repeat_on_day): mcount = month_map.get(frequency) if mcount: @@ -93,11 +96,10 @@ def make_subscription_entry(date=None): schedule_date = getdate(data.next_schedule_date) while schedule_date <= getdate(today()): create_documents(data, schedule_date) - schedule_date = get_next_schedule_date(schedule_date, data.frequency, data.repeat_on_day) - if schedule_date: + if schedule_date and not frappe.db.get_value('Subscription', data.name, 'disabled'): frappe.db.set_value('Subscription', data.name, 'next_schedule_date', schedule_date) def get_subscription_entries(date): @@ -105,23 +107,29 @@ def get_subscription_entries(date): where docstatus = 1 and next_schedule_date <=%s and reference_document is not null and reference_document != '' and next_schedule_date <= ifnull(end_date, '2199-12-31') - and ifnull(disabled, 0) = 0""", (date), as_dict=1) + and ifnull(disabled, 0) = 0 and status != 'Stopped' """, (date), as_dict=1) def create_documents(data, schedule_date): try: doc = make_new_document(data, schedule_date) - if data.notify_by_email: - send_notification(doc, data.print_format, data.recipients) + if data.notify_by_email and data.recipients: + print_format = data.print_format or "Standard" + send_notification(doc, print_format, data.recipients) frappe.db.commit() except Exception: frappe.db.rollback() frappe.db.begin() frappe.log_error(frappe.get_traceback()) + disabled_subscription(data) frappe.db.commit() if data.reference_document and not frappe.flags.in_test: notify_error_to_user(data) +def disabled_subscription(data): + subscription = frappe.get_doc('Subscription', data.name) + subscription.db_set('disabled', 1) + def notify_error_to_user(data): party = '' party_type = '' @@ -134,7 +142,7 @@ def notify_error_to_user(data): if party_type: party = frappe.db.get_value(data.reference_doctype, data.reference_document, party_type) - notify_errors(data.reference_document, data.reference_doctype, party, data.owner) + notify_errors(data.reference_document, data.reference_doctype, party, data.owner, data.name) def make_new_document(args, schedule_date): doc = frappe.get_doc(args.reference_doctype, args.reference_document) @@ -168,32 +176,32 @@ def get_next_date(dt, mcount, day=None): def send_notification(new_rv, print_format='Standard', recipients=None): """Notify concerned persons about recurring document generation""" - recipients = recipients or new_rv.notification_email_address - print_format = print_format or new_rv.recurring_print_format + print_format = print_format frappe.sendmail(recipients, subject= _("New {0}: #{1}").format(new_rv.doctype, new_rv.name), message = _("Please find attached {0} #{1}").format(new_rv.doctype, new_rv.name), attachments = [frappe.attach_print(new_rv.doctype, new_rv.name, file_name=new_rv.name, print_format=print_format)]) -def notify_errors(doc, doctype, party, owner): +def notify_errors(doc, doctype, party, owner, name): recipients = get_system_managers(only_name=True) frappe.sendmail(recipients + [frappe.db.get_value("User", owner, "email")], - subject="[Urgent] Error while creating recurring %s for %s" % (doctype, doc), + subject=_("[Urgent] Error while creating recurring %s for %s" % (doctype, doc)), message = frappe.get_template("templates/emails/recurring_document_failed.html").render({ - "type": doctype, + "type": _(doctype), "name": doc, - "party": party or "" + "party": party or "", + "subscription": name })) - assign_task_to_owner(doc, doctype, "Recurring Invoice Failed", recipients) + assign_task_to_owner(name, "Recurring Documents Failed", recipients) -def assign_task_to_owner(doc, doctype, msg, users): +def assign_task_to_owner(name, msg, users): for d in users: args = { + 'doctype' : 'Subscription', 'assign_to' : d, - 'doctype' : doctype, - 'name' : doc, + 'name' : name, 'description' : msg, 'priority' : 'High' } @@ -205,3 +213,16 @@ def make_subscription(doctype, docname): doc.reference_doctype = doctype doc.reference_document = docname return doc + +@frappe.whitelist() +def stop_resume_subscription(subscription, status): + doc = frappe.get_doc('Subscription', subscription) + frappe.msgprint(_("Subscription has been {0}").format(status)) + if status == 'Resumed': + doc.next_schedule_date = get_next_schedule_date(today(), + doc.frequency, doc.repeat_on_day) + + doc.update_status(status) + doc.save() + + return doc.status \ No newline at end of file diff --git a/erpnext/subscription/doctype/subscription/subscription_list.js b/erpnext/accounts/doctype/subscription/subscription_list.js similarity index 55% rename from erpnext/subscription/doctype/subscription/subscription_list.js rename to erpnext/accounts/doctype/subscription/subscription_list.js index 6a33638b391..71e3cce79d5 100644 --- a/erpnext/subscription/doctype/subscription/subscription_list.js +++ b/erpnext/accounts/doctype/subscription/subscription_list.js @@ -1,10 +1,14 @@ frappe.listview_settings['Subscription'] = { add_fields: ["next_schedule_date"], get_indicator: function(doc) { - if(doc.next_schedule_date >= frappe.datetime.get_today() ) { + if(doc.disabled) { + return [__("Disabled"), "red"]; + } else if(doc.next_schedule_date >= frappe.datetime.get_today() && doc.status != 'Stopped') { return [__("Active"), "green"]; } else if(doc.docstatus === 0) { return [__("Draft"), "red", "docstatus,=,0"]; + } else if(doc.status === 'Stopped') { + return [__("Stopped"), "red"]; } else { return [__("Expired"), "darkgrey"]; } diff --git a/erpnext/subscription/doctype/subscription/test_subscription.js b/erpnext/accounts/doctype/subscription/test_subscription.js similarity index 100% rename from erpnext/subscription/doctype/subscription/test_subscription.js rename to erpnext/accounts/doctype/subscription/test_subscription.js diff --git a/erpnext/subscription/doctype/subscription/test_subscription.py b/erpnext/accounts/doctype/subscription/test_subscription.py similarity index 96% rename from erpnext/subscription/doctype/subscription/test_subscription.py rename to erpnext/accounts/doctype/subscription/test_subscription.py index 28f8be7257d..b74163c92e9 100644 --- a/erpnext/subscription/doctype/subscription/test_subscription.py +++ b/erpnext/accounts/doctype/subscription/test_subscription.py @@ -10,7 +10,7 @@ from erpnext.accounts.utils import get_fiscal_year from erpnext.accounts.report.financial_statements import get_months from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order -from erpnext.subscription.doctype.subscription.subscription import make_subscription_entry +from erpnext.accounts.doctype.subscription.subscription import make_subscription_entry class TestSubscription(unittest.TestCase): def test_daily_subscription(self): diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.py b/erpnext/accounts/doctype/tax_rule/tax_rule.py index 7324532a397..2d91a3c85f0 100644 --- a/erpnext/accounts/doctype/tax_rule/tax_rule.py +++ b/erpnext/accounts/doctype/tax_rule/tax_rule.py @@ -135,7 +135,8 @@ def get_tax_template(posting_date, args): for key, value in args.iteritems(): if key=="use_for_shopping_cart": conditions.append("use_for_shopping_cart = {0}".format(1 if value else 0)) - if key == 'customer_group' and value: + if key == 'customer_group': + if not value: value = _("All Customer Groups") customer_group_condition = get_customer_group_condition(value) conditions.append("ifnull({0}, '') in ('', {1})".format(key, customer_group_condition)) else: diff --git a/erpnext/accounts/doctype/tax_rule/test_tax_rule.py b/erpnext/accounts/doctype/tax_rule/test_tax_rule.py index 383b02b1287..5ad7970a6e3 100644 --- a/erpnext/accounts/doctype/tax_rule/test_tax_rule.py +++ b/erpnext/accounts/doctype/tax_rule/test_tax_rule.py @@ -39,7 +39,7 @@ class TestTaxRule(unittest.TestCase): sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01") tax_rule1.save() - self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial"}), + self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial", "use_for_shopping_cart":0}), "_Test Sales Taxes and Charges Template") def test_conflict_with_overlapping_dates(self): diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index 45d2ef2fc63..d370c496fbc 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -137,14 +137,7 @@ def round_off_debit_credit(gl_map): make_round_off_gle(gl_map, debit_credit_diff) def make_round_off_gle(gl_map, debit_credit_diff): - round_off_account, round_off_cost_center = frappe.db.get_value("Company", gl_map[0].company, - ["round_off_account", "round_off_cost_center"]) or [None, None] - if not round_off_account: - frappe.throw(_("Please mention Round Off Account in Company")) - - if not round_off_cost_center: - frappe.throw(_("Please mention Round Off Cost Center in Company")) - + round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(gl_map[0].company) round_off_gle = frappe._dict() for k in ["voucher_type", "voucher_no", "company", @@ -166,6 +159,17 @@ def make_round_off_gle(gl_map, debit_credit_diff): gl_map.append(round_off_gle) +def get_round_off_account_and_cost_center(company): + round_off_account, round_off_cost_center = frappe.db.get_value("Company", company, + ["round_off_account", "round_off_cost_center"]) or [None, None] + if not round_off_account: + frappe.throw(_("Please mention Round Off Account in Company")) + + if not round_off_cost_center: + frappe.throw(_("Please mention Round Off Cost Center in Company")) + + return round_off_account, round_off_cost_center + def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None, adv_adj=False, update_outstanding="Yes"): diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index a11f77d05cc..be0b6f7b727 100644 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -269,9 +269,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.calculate_outstanding_amount(); } - if (this.frm.doc.customer) { - this.party_field.$input.val(this.frm.doc.customer); - } + this.set_customer_value_in_party_field(); if (!this.frm.doc.write_off_account) { this.frm.doc.write_off_account = doc.write_off_account @@ -282,6 +280,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ } }, + set_customer_value_in_party_field: function() { + if (this.frm.doc.customer) { + this.party_field.$input.val(this.frm.doc.customer); + } + }, + get_invoice_doc: function (si_docs) { var me = this; this.si_docs = this.get_doc_from_localstorage(); @@ -695,6 +699,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ set_focus: function () { if (this.default_customer || this.frm.doc.customer) { + this.set_customer_value_in_party_field(); this.serach_item.$input.focus(); } else { this.party_field.$input.focus(); diff --git a/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json b/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json index 051a1238d92..5debb5c9782 100644 --- a/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json +++ b/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json @@ -1,5 +1,5 @@ { - "align_labels_left": 0, + "align_labels_right": 0, "creation": "2017-08-08 12:33:04.773099", "custom_format": 1, "disabled": 0, @@ -10,7 +10,7 @@ "html": "\n\n
\n\t{{ doc.company }}
\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t{{ _(\"GSTIN\") }}:{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"
GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n
\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{{ _(\"Customer\") }}:
\n\t\t{{ doc.customer_name }}
\n\t\t{{ customer_address }}\n\t{% endif %}\n
| {{ _(\"Item\") }} | \n\t\t\t{{ _(\"Qty\") }} | \n\t\t\t{{ _(\"Amount\") }} | \n\t\t
|---|---|---|
| \n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t {{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t {{ _(\"HSN/SAC\") }}: {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t {{ _(\"Serial No\") }}: {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t | \n\t\t\t{{ item.qty }} @ {{ item.rate }} | \n\t\t\t{{ item.get_formatted(\"amount\") }} | \n\t\t
| \n\t\t\t\t{{ _(\"Net Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"net_total\") }}\n\t\t\t | \n\t\t
| \n\t\t\t\t{{ row.description }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t | \n\t\t
| \n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t | \n\t\t
| \n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t | \n\t\t
Tax Breakup:
\n{{ doc.terms or \"\" }}
\n{{ _(\"Thank you, please visit again.\") }}
", "idx": 0, "line_breaks": 0, - "modified": "2017-08-29 15:54:19.467642", + "modified": "2017-09-14 15:54:19.467642", "modified_by": "Administrator", "module": "Accounts", "name": "GST POS Invoice", diff --git a/erpnext/accounts/print_format/point_of_sale/point_of_sale.json b/erpnext/accounts/print_format/point_of_sale/point_of_sale.json index 4e69cad06bc..49696d253fc 100644 --- a/erpnext/accounts/print_format/point_of_sale/point_of_sale.json +++ b/erpnext/accounts/print_format/point_of_sale/point_of_sale.json @@ -1,5 +1,5 @@ { - "align_labels_left": 0, + "align_labels_right": 0, "creation": "2016-05-05 17:16:18.564460", "custom_format": 1, "disabled": 0, @@ -10,7 +10,7 @@ "html": "\n\n\n\t{{ company }}
\n\t{{ __(\"POS No : \") }} {{ offline_pos_name }}
\n
\n\t{{ __(\"Customer\") }}: {{ customer }}
\n
\n\t{{ __(\"Date\") }}: {{ dateutil.global_date_format(posting_date) }}
\n
| {{ __(\"Item\") }} | \n\t\t\t{{ __(\"Qty\") }} | \n\t\t\t{{ __(\"Amount\") }} | \n\t\t
|---|---|---|
| \n\t\t\t\t{{ item.item_name }}\n\t\t\t | \n\t\t\t{{ format_number(item.qty, null,precision(\"difference\")) }} @ {{ format_currency(item.rate, currency) }} | \n\t\t\t{{ format_currency(item.amount, currency) }} | \n\t\t
| \n\t\t\t\t{{ __(\"Net Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(total, currency) }}\n\t\t\t | \n\t\t
| \n\t\t\t\t{{ row.description }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(row.tax_amount, currency) }}\n\t\t\t | \n\t\t
| \n\t\t\t\t{{ __(\"Discount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(discount_amount, currency) }}\n\t\t\t | \n\t\t
| \n\t\t\t\t{{ __(\"Grand Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(grand_total, currency) }}\n\t\t\t | \n\t\t
| \n\t\t\t\t{{ __(\"Paid Amount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(paid_amount, currency) }}\n\t\t\t | \n\t\t
{{ terms }}
\n{{ __(\"Thank you, please visit again.\") }}
", "idx": 0, "line_breaks": 0, - "modified": "2017-09-01 14:27:04.871233", + "modified": "2017-09-14 14:36:04.740728", "modified_by": "Administrator", "module": "Accounts", "name": "Point of Sale", diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index d81c1ebc88e..b0c49dfbd81 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -142,10 +142,16 @@ def get_data(company, root_type, balance_must_be, period_list, filters=None, return out + def calculate_values(accounts_by_name, gl_entries_by_account, period_list, accumulated_values, ignore_accumulated_values_for_fy): for entries in gl_entries_by_account.values(): for entry in entries: d = accounts_by_name.get(entry.account) + if not d: + frappe.msgprint( + _("Could not retrieve information for {0}.".format(entry.account)), title="Error", + raise_exception=1 + ) for period in period_list: # check if posting date is within the period diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index e2106e2d628..07f6979c40c 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -17,7 +17,6 @@ def execute(filters=None): gross_profit_data = GrossProfitGenerator(filters) data = [] - source = gross_profit_data.grouped_data if filters.get("group_by") != "Invoice" else gross_profit_data.data group_wise_columns = frappe._dict({ "invoice": ["parent", "customer", "customer_group", "posting_date","item_code", "item_name","item_group", "brand", "description", \ @@ -45,7 +44,7 @@ def execute(filters=None): columns = get_columns(group_wise_columns, filters) - for src in source: + for src in gross_profit_data.grouped_data: row = [] for col in group_wise_columns.get(scrub(filters.group_by)): row.append(src.get(col)) @@ -103,6 +102,7 @@ class GrossProfitGenerator(object): self.load_stock_ledger_entries() self.load_product_bundle() self.load_non_stock_items() + self.get_returned_invoice_items() self.process() def process(self): @@ -143,40 +143,68 @@ class GrossProfitGenerator(object): row.gross_profit_percent = 0.0 # add to grouped - if self.filters.group_by != "Invoice": - self.grouped.setdefault(row.get(scrub(self.filters.group_by)), []).append(row) - - self.data.append(row) + self.grouped.setdefault(row.get(scrub(self.filters.group_by)), []).append(row) if self.grouped: self.get_average_rate_based_on_group_by() - else: - self.grouped_data = [] def get_average_rate_based_on_group_by(self): # sum buying / selling totals for group self.grouped_data = [] for key in self.grouped.keys(): - for i, row in enumerate(self.grouped[key]): - if i==0: - new_row = row - else: - new_row.qty += row.qty - new_row.buying_amount += row.buying_amount - new_row.base_amount += row.base_amount + if self.filters.get("group_by") != "Invoice": + for i, row in enumerate(self.grouped[key]): + if i==0: + new_row = row + else: + new_row.qty += row.qty + new_row.buying_amount += row.buying_amount + new_row.base_amount += row.base_amount + new_row = self.set_average_rate(new_row) + self.grouped_data.append(new_row) + else: + for i, row in enumerate(self.grouped[key]): + if row.parent in self.returned_invoices \ + and row.item_code in self.returned_invoices[row.parent]: + returned_item_rows = self.returned_invoices[row.parent][row.item_code] + for returned_item_row in returned_item_rows: + row.qty += returned_item_row.qty + row.base_amount += returned_item_row.base_amount + row.buying_amount = row.qty * row.buying_rate + if row.qty: + row = self.set_average_rate(row) + self.grouped_data.append(row) - new_row.gross_profit = new_row.base_amount - new_row.buying_amount - new_row.gross_profit_percent = ((new_row.gross_profit / new_row.base_amount) * 100.0) \ - if new_row.base_amount else 0 - new_row.buying_rate = (new_row.buying_amount / new_row.qty) \ - if new_row.qty else 0 - new_row.base_rate = (new_row.base_amount / new_row.qty) \ - if new_row.qty else 0 + def set_average_rate(self, new_row): + new_row.gross_profit = new_row.base_amount - new_row.buying_amount + new_row.gross_profit_percent = ((new_row.gross_profit / new_row.base_amount) * 100.0) \ + if new_row.base_amount else 0 + new_row.buying_rate = (new_row.buying_amount / new_row.qty) if new_row.qty else 0 + new_row.base_rate = (new_row.base_amount / new_row.qty) if new_row.qty else 0 + return new_row - self.grouped_data.append(new_row) + def get_returned_invoice_items(self): + returned_invoices = frappe.db.sql(""" + select + si.name, si_item.item_code, si_item.qty, si_item.base_amount, si.return_against + from + `tabSales Invoice` si, `tabSales Invoice Item` si_item + where + si.name = si_item.parent + and si.docstatus = 1 + and si.is_return = 1 + """, as_dict=1) + + self.returned_invoices = frappe._dict() + for inv in returned_invoices: + self.returned_invoices.setdefault(inv.return_against, frappe._dict())\ + .setdefault(inv.item_code, []).append(inv) def skip_row(self, row, product_bundles): - if self.filters.get("group_by") != "Invoice" and not row.get(scrub(self.filters.get("group_by"))): + if self.filters.get("group_by") != "Invoice": + if not row.get(scrub(self.filters.get("group_by"))): + return True + elif row.get("is_return") == 1: return True def get_buying_amount_from_product_bundle(self, row, product_bundle): @@ -268,20 +296,26 @@ class GrossProfitGenerator(object): sales_person_cols = "" sales_team_table = "" - self.si_list = frappe.db.sql("""select `tabSales Invoice Item`.parenttype, `tabSales Invoice Item`.parent, - `tabSales Invoice`.posting_date, `tabSales Invoice`.posting_time, `tabSales Invoice`.project, `tabSales Invoice`.update_stock, - `tabSales Invoice`.customer, `tabSales Invoice`.customer_group, `tabSales Invoice`.territory, - `tabSales Invoice Item`.item_code, `tabSales Invoice Item`.item_name, `tabSales Invoice Item`.description, - `tabSales Invoice Item`.warehouse, `tabSales Invoice Item`.item_group, `tabSales Invoice Item`.brand, - `tabSales Invoice Item`.dn_detail, `tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.stock_qty as qty, - `tabSales Invoice Item`.base_net_rate, `tabSales Invoice Item`.base_net_amount, `tabSales Invoice Item`.name as "item_row" + self.si_list = frappe.db.sql(""" + select + `tabSales Invoice Item`.parenttype, `tabSales Invoice Item`.parent, + `tabSales Invoice`.posting_date, `tabSales Invoice`.posting_time, + `tabSales Invoice`.project, `tabSales Invoice`.update_stock, + `tabSales Invoice`.customer, `tabSales Invoice`.customer_group, + `tabSales Invoice`.territory, `tabSales Invoice Item`.item_code, + `tabSales Invoice Item`.item_name, `tabSales Invoice Item`.description, + `tabSales Invoice Item`.warehouse, `tabSales Invoice Item`.item_group, + `tabSales Invoice Item`.brand, `tabSales Invoice Item`.dn_detail, + `tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.stock_qty as qty, + `tabSales Invoice Item`.base_net_rate, `tabSales Invoice Item`.base_net_amount, + `tabSales Invoice Item`.name as "item_row", `tabSales Invoice`.is_return {sales_person_cols} from - `tabSales Invoice` - inner join `tabSales Invoice Item` on `tabSales Invoice Item`.parent = `tabSales Invoice`.name + `tabSales Invoice` inner join `tabSales Invoice Item` + on `tabSales Invoice Item`.parent = `tabSales Invoice`.name {sales_team_table} where - `tabSales Invoice`.docstatus = 1 {conditions} {match_cond} + `tabSales Invoice`.docstatus=1 {conditions} {match_cond} order by `tabSales Invoice`.posting_date desc, `tabSales Invoice`.posting_time desc""" .format(conditions=conditions, sales_person_cols=sales_person_cols, diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index b21027ee359..710099ee102 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -91,10 +91,10 @@ def get_conditions(filters): conditions = "" for opts in (("company", " and company=%(company)s"), - ("supplier", " and pi.supplier = %(supplier)s"), - ("item_code", " and pi_item.item_code = %(item_code)s"), - ("from_date", " and pi.posting_date>=%(from_date)s"), - ("to_date", " and pi.posting_date<=%(to_date)s"), + ("supplier", " and `tabPurchase Invoice`.supplier = %(supplier)s"), + ("item_code", " and `tabPurchase Invoice Item`.item_code = %(item_code)s"), + ("from_date", " and `tabPurchase Invoice`.posting_date>=%(from_date)s"), + ("to_date", " and `tabPurchase Invoice`.posting_date<=%(to_date)s"), ("mode_of_payment", " and ifnull(mode_of_payment, '') = %(mode_of_payment)s")): if filters.get(opts[0]): conditions += opts[1] @@ -104,20 +104,29 @@ def get_conditions(filters): def get_items(filters, additional_query_columns): conditions = get_conditions(filters) match_conditions = frappe.build_match_conditions("Purchase Invoice") + + if match_conditions: + match_conditions = " and {0} ".format(match_conditions) + if additional_query_columns: additional_query_columns = ', ' + ', '.join(additional_query_columns) return frappe.db.sql(""" select - pi_item.name, pi_item.parent, pi.posting_date, pi.credit_to, pi.company, - pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name, - pi_item.item_group, pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt, - pi_item.po_detail, pi_item.expense_account, pi_item.stock_qty, pi_item.stock_uom, - pi_item.base_net_rate, pi_item.base_net_amount, - pi.supplier_name, pi.mode_of_payment {0} - from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item - where pi.name = pi_item.parent and pi.docstatus = 1 %s %s - order by pi.posting_date desc, pi_item.item_code desc + `tabPurchase Invoice Item`.`name`, `tabPurchase Invoice Item`.`parent`, + `tabPurchase Invoice`.posting_date, `tabPurchase Invoice`.credit_to, `tabPurchase Invoice`.company, + `tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total, `tabPurchase Invoice Item`.`item_code`, + `tabPurchase Invoice Item`.`item_name`, `tabPurchase Invoice Item`.`item_group`, + `tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`, + `tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`, + `tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`, + `tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_rate`, + `tabPurchase Invoice Item`.`base_net_amount`, + `tabPurchase Invoice`.supplier_name, `tabPurchase Invoice`.mode_of_payment {0} + from `tabPurchase Invoice`, `tabPurchase Invoice Item` + where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and + `tabPurchase Invoice`.docstatus = 1 %s %s + order by `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc """.format(additional_query_columns) % (conditions, match_conditions), filters, as_dict=1) def get_aii_accounts(): diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index eb500226888..9892e03f3fe 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -93,37 +93,49 @@ def get_conditions(filters): conditions = "" for opts in (("company", " and company=%(company)s"), - ("customer", " and si.customer = %(customer)s"), - ("item_code", " and si_item.item_code = %(item_code)s"), - ("from_date", " and si.posting_date>=%(from_date)s"), - ("to_date", " and si.posting_date<=%(to_date)s")): + ("customer", " and `tabSales Invoice`.customer = %(customer)s"), + ("item_code", " and `tabSales Invoice Item`.item_code = %(item_code)s"), + ("from_date", " and `tabSales Invoice`.posting_date>=%(from_date)s"), + ("to_date", " and `tabSales Invoice`.posting_date<=%(to_date)s")): if filters.get(opts[0]): conditions += opts[1] if filters.get("mode_of_payment"): conditions += """ and exists(select name from `tabSales Invoice Payment` - where parent=si.name - and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)""" + where parent=si.name + and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)""" return conditions def get_items(filters, additional_query_columns): + conditions = get_conditions(filters) + match_conditions = frappe.build_match_conditions("Sales Invoice") + + if match_conditions: + match_conditions = " and {0} ".format(match_conditions) + if additional_query_columns: additional_query_columns = ', ' + ', '.join(additional_query_columns) - conditions = get_conditions(filters) return frappe.db.sql(""" select - si_item.name, si_item.parent, si.posting_date, si.debit_to, si.project, - si.customer, si.remarks, si.territory, si.company, si.base_net_total, - si_item.item_code, si_item.item_name, si_item.item_group, si_item.sales_order, - si_item.delivery_note, si_item.income_account, si_item.cost_center, - si_item.stock_qty, si_item.stock_uom, si_item.base_net_rate, si_item.base_net_amount, - si.customer_name, si.customer_group, si_item.so_detail, si.update_stock {0} - from `tabSales Invoice` si, `tabSales Invoice Item` si_item - where si.name = si_item.parent and si.docstatus = 1 %s - order by si.posting_date desc, si_item.item_code desc - """.format(additional_query_columns or '') % conditions, filters, as_dict=1) + `tabSales Invoice Item`.name, `tabSales Invoice Item`.parent, + `tabSales Invoice`.posting_date, `tabSales Invoice`.debit_to, + `tabSales Invoice`.project, `tabSales Invoice`.customer, `tabSales Invoice`.remarks, + `tabSales Invoice`.territory, `tabSales Invoice`.company, `tabSales Invoice`.base_net_total, + `tabSales Invoice Item`.item_code, `tabSales Invoice Item`.item_name, + `tabSales Invoice Item`.item_group, `tabSales Invoice Item`.sales_order, + `tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.income_account, + `tabSales Invoice Item`.cost_center, `tabSales Invoice Item`.stock_qty, + `tabSales Invoice Item`.stock_uom, `tabSales Invoice Item`.base_net_rate, + `tabSales Invoice Item`.base_net_amount, `tabSales Invoice`.customer_name, + `tabSales Invoice`.customer_group, `tabSales Invoice Item`.so_detail, + `tabSales Invoice`.update_stock {0} + from `tabSales Invoice`, `tabSales Invoice Item` + where `tabSales Invoice`.name = `tabSales Invoice Item`.parent + and `tabSales Invoice`.docstatus = 1 %s %s + order by `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_code desc + """.format(additional_query_columns or '') % (conditions, match_conditions), filters, as_dict=1) def get_delivery_notes_against_sales_order(item_list): so_dn_map = frappe._dict() diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 1e91ffa32db..2eebf54eea0 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -2102,6 +2102,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "base_rounding_adjustment", + "fieldtype": "Currency", + "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": "Rounding Adjustment (Company Currency)", + "length": 0, + "no_copy": 1, + "options": "Company:company:default_currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "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, @@ -2227,6 +2258,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "rounding_adjustment", + "fieldtype": "Currency", + "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": "Rounding Adjustment", + "length": 0, + "no_copy": 1, + "options": "currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "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, diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index 26c8c611670..56f3059f2e9 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -295,6 +295,7 @@ def make_purchase_receipt(source_name, target_doc=None): "field_map": { "name": "purchase_order_item", "parent": "purchase_order", + "bom": "bom" }, "postprocess": update_item, "condition": lambda doc: abs(doc.received_qty) < abs(doc.qty) and doc.delivered_by_supplier!=1 diff --git a/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js index f831b4f42ff..1a9cd351dc7 100644 --- a/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js +++ b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js @@ -12,7 +12,7 @@ QUnit.test("Test: Request for Quotation", function (assert) { () => frappe.new_doc("Request for Quotation"), () => frappe.timeout(1), () => cur_frm.set_value("transaction_date", "04-04-2017"), - () => cur_frm.set_value("company", "_Test Company"), + () => cur_frm.set_value("company", "For Testing"), // Add Suppliers () => { cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view(); @@ -62,7 +62,7 @@ QUnit.test("Test: Request for Quotation", function (assert) { }, () => frappe.timeout(2), () => { - cur_frm.fields_dict.items.grid.grid_rows[0].doc.warehouse = "_Test Warehouse - _TC"; + cur_frm.fields_dict.items.grid.grid_rows[0].doc.warehouse = "_Test Warehouse - FT"; }, () => frappe.click_button('Save'), () => frappe.timeout(1), @@ -104,7 +104,7 @@ QUnit.test("Test: Request for Quotation", function (assert) { () => frappe.timeout(1), () => frappe.click_button('Make Supplier Quotation'), () => frappe.timeout(1), - () => cur_frm.set_value("company", "_Test Company"), + () => cur_frm.set_value("company", "For Testing"), () => cur_frm.fields_dict.items.grid.grid_rows[0].doc.rate = 4.99, () => frappe.timeout(1), () => frappe.click_button('Save'), diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py index b2b90637b6a..c715fbd2a62 100644 --- a/erpnext/buying/doctype/supplier/supplier.py +++ b/erpnext/buying/doctype/supplier/supplier.py @@ -16,7 +16,7 @@ class Supplier(TransactionBase): def onload(self): """Load address and contacts in `__onload`""" - load_address_and_contact(self, "supplier") + load_address_and_contact(self) self.load_dashboard_info() def load_dashboard_info(self): diff --git a/erpnext/buying/doctype/supplier/test_supplier.js b/erpnext/buying/doctype/supplier/test_supplier.js index a953a8dd135..99a5bc616dc 100644 --- a/erpnext/buying/doctype/supplier/test_supplier.js +++ b/erpnext/buying/doctype/supplier/test_supplier.js @@ -13,8 +13,8 @@ QUnit.test("test: supplier", function(assert) { {credit_days_based_on: 'Fixed Days'}, {accounts: [ [ - {'company': "Test Company"}, - {'account': "Creditors - TC"} + {'company': "For Testing"}, + {'account': "Creditors - FT"} ]] } ]); @@ -68,7 +68,7 @@ QUnit.test("test: supplier", function(assert) { assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Name correct"); assert.ok(cur_frm.doc.supplier_type == 'Hardware', "Type correct"); assert.ok(cur_frm.doc.default_currency == 'INR', "Currency correct"); - assert.ok(cur_frm.doc.accounts[0].account == 'Creditors - '+frappe.get_abbr('Test Company'), " Account Head abbr correct"); + assert.ok(cur_frm.doc.accounts[0].account == 'Creditors - '+frappe.get_abbr('For Testing'), " Account Head abbr correct"); assert.ok($('.address-box:nth-child(3) p').text().includes('Shipping City 3'), "Address correct"); assert.ok($('.col-sm-6+ .col-sm-6 .h6').text().includes('Contact 3'), "Contact correct"); }, diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json index eed0c15cadf..f9ff0a64730 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json @@ -1676,6 +1676,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "base_rounding_adjustment", + "fieldtype": "Currency", + "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": "Rounding Adjustment (Company Currency", + "length": 0, + "no_copy": 1, + "options": "Company:company:default_currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "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, @@ -1801,6 +1832,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "rounding_adjustment", + "fieldtype": "Currency", + "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": "Rounding Adjustment", + "length": 0, + "no_copy": 1, + "options": "currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "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, diff --git a/erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_item_wise_discount.js b/erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_item_wise_discount.js index bc07b753b33..b151824ba68 100644 --- a/erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_item_wise_discount.js +++ b/erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_item_wise_discount.js @@ -8,13 +8,13 @@ QUnit.test("test: supplier quotation with item wise discount", function(assert){ () => { return frappe.tests.make('Supplier Quotation', [ {supplier: 'Test Supplier'}, - {company: 'Test Company'}, + {company: 'For Testing'}, {items: [ [ {"item_code": 'Test Product 4'}, {"qty": 5}, {"uom": 'Unit'}, - {"warehouse": 'All Warehouses - TC'}, + {"warehouse": 'All Warehouses - FT'}, {'discount_percentage': 10}, ] ]} diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py index 6d16e9202e6..7c0f540154b 100644 --- a/erpnext/config/accounts.py +++ b/erpnext/config/accounts.py @@ -32,6 +32,12 @@ def get_data(): "label": _("POS"), "description": _("Point of Sale") }, + { + "type": "doctype", + "name": "Subscription", + "label": _("Subscription"), + "description": _("To make recurring documents") + }, { "type": "report", "name": "Accounts Receivable", diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py index 029ef747407..ef1ff103fa7 100644 --- a/erpnext/config/desktop.py +++ b/erpnext/config/desktop.py @@ -261,5 +261,12 @@ def get_data(): "icon": "octicon octicon-mortar-board", "type": "module", "label": _("Schools") + }, + { + "module_name": "Healthcare", + "color": "#FF888B", + "icon": "octicon octicon-plus", + "type": "module", + "label": _("Healthcare") } ] diff --git a/erpnext/config/healthcare.py b/erpnext/config/healthcare.py new file mode 100644 index 00000000000..f4bf4f7bd23 --- /dev/null +++ b/erpnext/config/healthcare.py @@ -0,0 +1,157 @@ +from __future__ import unicode_literals +from frappe import _ + +def get_data(): + + return [ + { + "label": _("Consultation"), + "icon": "icon-star", + "items": [ + { + "type": "doctype", + "name": "Patient Appointment", + "description": _("Patient Appointment"), + }, + { + "type": "doctype", + "name": "Consultation", + "label": _("Consultation"), + }, + { + "type": "doctype", + "name": "Vital Signs", + "label": _("Vital Signs"), + "description": _("Record Patient Vitals"), + }, + { + "type": "page", + "name": "medical_record", + "label": _("Patient Medical Record"), + }, + { + "type": "page", + "name": "appointment-analytic", + "label": _("Appointment Analytics"), + } + ] + }, + { + "label": _("Laboratory"), + "icon": "icon-list", + "items": [ + { + "type": "doctype", + "name": "Lab Test", + "description": _("Results"), + }, + { + "type": "doctype", + "name": "Sample Collection", + "label": _("Sample Collection"), + }, + { + "type": "report", + "name": "Lab Test Report", + "is_query_report": True + } + ] + }, + { + "label": _("Masters"), + "icon": "icon-list", + "items": [ + { + "type": "doctype", + "name": "Patient", + "label": _("Patient"), + }, + { + "type": "doctype", + "name": "Physician", + "label": "Physician", + }, + { + "type": "doctype", + "name": "Physician Schedule", + "label": _("Physician Schedule"), + }, + { + "type": "doctype", + "name": "Medical Code Standard", + "label": _("Medical Code Standard"), + }, + { + "type": "doctype", + "name": "Medical Code", + "label": _("Medical Code"), + } + ] + }, + { + "label": _("Setup"), + "icon": "icon-cog", + "items": [ + { + "type": "doctype", + "name": "Healthcare Settings", + "label": _("Healthcare Settings"), + }, + { + "type": "doctype", + "name": "Medical Department", + "label": "Medical Department" + }, + { + "type": "doctype", + "name": "Appointment Type", + "description": _("Appointment Type Master"), + }, + { + "type": "doctype", + "name": "Prescription Dosage", + "description": _("Prescription Dosage") + }, + { + "type": "doctype", + "name": "Prescription Duration", + "description": _("Prescription Period") + }, + { + "type": "doctype", + "name": "Complaint", + "description": _("Complaint") + }, + { + "type": "doctype", + "name": "Diagnosis", + "description": _("Diagnosis") + }, + { + "type": "doctype", + "name": "Lab Test Sample", + "description": _("Test Sample Master."), + }, + { + "type": "doctype", + "name": "Lab Test UOM", + "description": _("Lab Test UOM.") + }, + { + "type": "doctype", + "name": "Antibiotic", + "description": _("Antibiotic.") + }, + { + "type": "doctype", + "name": "Sensitivity", + "description": _("Sensitivity Naming.") + }, + { + "type": "doctype", + "name": "Lab Test Template", + "description": _("Lab Test Configurations.") + } + ] + } + ] diff --git a/erpnext/config/schools.py b/erpnext/config/schools.py index b984578ca1e..dbdcd3561d4 100644 --- a/erpnext/config/schools.py +++ b/erpnext/config/schools.py @@ -154,6 +154,10 @@ def get_data(): "type": "doctype", "name": "Fees" }, + { + "type": "doctype", + "name": "Fee Schedule" + }, { "type": "doctype", "name": "Fee Structure" diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 5a0b967bd1d..9cc061677e0 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -16,6 +16,8 @@ from erpnext.controllers.stock_controller import StockController class BuyingController(StockController): def __setup__(self): if hasattr(self, "taxes"): + self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings", + "print_taxes_with_zero_amount")) self.print_templates = { "taxes": "templates/print_formats/includes/taxes.html" } diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index 11c07909760..7ada8ccc2f2 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -227,21 +227,30 @@ def get_project_name(doctype, txt, searchfield, start, page_len, filters): "_txt": txt.replace('%', '') }) + def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len, filters, as_dict): return frappe.db.sql(""" select `tabDelivery Note`.name, `tabDelivery Note`.customer, `tabDelivery Note`.posting_date from `tabDelivery Note` where `tabDelivery Note`.`%(key)s` like %(txt)s and - `tabDelivery Note`.docstatus = 1 and `tabDelivery Note`.is_return = 0 + `tabDelivery Note`.docstatus = 1 and status not in ("Stopped", "Closed") %(fcond)s - and (`tabDelivery Note`.per_billed < 100 or `tabDelivery Note`.grand_total = 0) + and ( + (`tabDelivery Note`.is_return = 0 and `tabDelivery Note`.per_billed < 100) + or `tabDelivery Note`.grand_total = 0 + or ( + `tabDelivery Note`.is_return = 1 + and return_against in (select name from `tabDelivery Note` where per_billed < 100) + ) + ) %(mcond)s order by `tabDelivery Note`.`%(key)s` asc """ % { "key": searchfield, "fcond": get_filters_cond(doctype, filters, []), "mcond": get_match_cond(doctype), "txt": "%(txt)s" - }, { "txt": ("%%%s%%" % txt) }, as_dict=as_dict) + }, {"txt": ("%%%s%%" % txt)}, as_dict=as_dict) + def get_batch_no(doctype, txt, searchfield, start, page_len, filters): cond = "" diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 10b3607df91..d881f18b33b 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -14,6 +14,8 @@ from erpnext.controllers.stock_controller import StockController class SellingController(StockController): def __setup__(self): if hasattr(self, "taxes"): + self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings", + "print_taxes_with_zero_amount")) self.print_templates = { "taxes": "templates/print_formats/includes/taxes.html" } @@ -177,6 +179,9 @@ class SellingController(StockController): return for it in self.get("items"): + if not it.item_code: + continue + last_purchase_rate, is_stock_item = frappe.db.get_value("Item", it.item_code, ["last_purchase_rate", "is_stock_item"]) last_purchase_rate_in_sales_uom = last_purchase_rate / (it.conversion_factor or 1) if flt(it.base_rate) < flt(last_purchase_rate_in_sales_uom): diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index c627664ea5b..e85e56b4d6c 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -121,9 +121,10 @@ class calculate_taxes_and_totals(object): cumulated_tax_fraction += tax.tax_fraction_for_current_item if cumulated_tax_fraction and not self.discount_amount_applied and item.qty: - item.net_amount = flt(item.amount / (1 + cumulated_tax_fraction), item.precision("net_amount")) + item.net_amount = flt(item.amount / (1 + cumulated_tax_fraction)) item.net_rate = flt(item.net_amount / item.qty, item.precision("net_rate")) - item.discount_percentage = flt(item.discount_percentage, item.precision("discount_percentage")) + item.discount_percentage = flt(item.discount_percentage, + item.precision("discount_percentage")) self._set_in_company_currency(item, ["net_rate", "net_amount"]) @@ -173,6 +174,7 @@ class calculate_taxes_and_totals(object): self.doc.round_floats_in(self.doc, ["total", "base_total", "net_total", "base_net_total"]) def calculate_taxes(self): + self.doc.rounding_adjustment = 0 # maintain actual tax rate based on idx actual_tax_dict = dict([[tax.idx, flt(tax.tax_amount, tax.precision("tax_amount"))] for tax in self.doc.get("taxes") if tax.charge_type == "Actual"]) @@ -222,7 +224,9 @@ class calculate_taxes_and_totals(object): # adjust Discount Amount loss in last tax iteration if i == (len(self.doc.get("taxes")) - 1) and self.discount_amount_applied \ and self.doc.discount_amount and self.doc.apply_discount_on == "Grand Total": - self.adjust_discount_amount_loss(tax) + self.doc.rounding_adjustment = flt(self.doc.grand_total + - flt(self.doc.discount_amount) - tax.total, + self.doc.precision("rounding_adjustment")) def get_tax_amount_if_for_valuation_or_deduction(self, tax_amount, tax): # if just for valuation, do not add the tax amount in total @@ -277,36 +281,26 @@ class calculate_taxes_and_totals(object): tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount, tax.precision("tax_amount")) - def adjust_discount_amount_loss(self, tax): - discount_amount_loss = self.doc.grand_total - flt(self.doc.discount_amount) - tax.total - tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount + - discount_amount_loss, tax.precision("tax_amount")) - tax.total = flt(tax.total + discount_amount_loss, tax.precision("total")) - - self._set_in_company_currency(tax, ["total", "tax_amount_after_discount_amount"]) - def manipulate_grand_total_for_inclusive_tax(self): # if fully inclusive taxes and diff - if self.doc.get("taxes") and all(cint(t.included_in_print_rate) for t in self.doc.get("taxes")): + if self.doc.get("taxes") and any([cint(t.included_in_print_rate) for t in self.doc.get("taxes")]): last_tax = self.doc.get("taxes")[-1] - diff = self.doc.total - flt(last_tax.total, self.doc.precision("grand_total")) - - if diff and abs(diff) <= (2.0 / 10**last_tax.precision("tax_amount")): - last_tax.tax_amount += diff - last_tax.tax_amount_after_discount_amount += diff - last_tax.total += diff - - self._set_in_company_currency(last_tax, - ["total", "tax_amount", "tax_amount_after_discount_amount"]) + non_inclusive_tax_amount = sum([flt(d.tax_amount_after_discount_amount) + for d in self.doc.get("taxes") if not d.included_in_print_rate]) + diff = self.doc.total + non_inclusive_tax_amount \ + - flt(last_tax.total, last_tax.precision("total")) + if diff and abs(diff) <= (5.0 / 10**last_tax.precision("tax_amount")): + self.doc.rounding_adjustment = flt(flt(self.doc.rounding_adjustment) + + flt(diff), self.doc.precision("rounding_adjustment")) def calculate_totals(self): - self.doc.grand_total = flt(self.doc.get("taxes")[-1].total - if self.doc.get("taxes") else self.doc.net_total) + self.doc.grand_total = flt(self.doc.get("taxes")[-1].total) + flt(self.doc.rounding_adjustment) \ + if self.doc.get("taxes") else flt(self.doc.net_total) - self.doc.total_taxes_and_charges = flt(self.doc.grand_total - self.doc.net_total, - self.doc.precision("total_taxes_and_charges")) + self.doc.total_taxes_and_charges = flt(self.doc.grand_total - self.doc.net_total + - flt(self.doc.rounding_adjustment), self.doc.precision("total_taxes_and_charges")) - self._set_in_company_currency(self.doc, ["total_taxes_and_charges"]) + self._set_in_company_currency(self.doc, ["total_taxes_and_charges", "rounding_adjustment"]) if self.doc.doctype in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]: self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate) \ @@ -326,13 +320,22 @@ class calculate_taxes_and_totals(object): if (self.doc.taxes_and_charges_added or self.doc.taxes_and_charges_deducted) \ else self.doc.base_net_total - self._set_in_company_currency(self.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"]) + self._set_in_company_currency(self.doc, + ["taxes_and_charges_added", "taxes_and_charges_deducted"]) self.doc.round_floats_in(self.doc, ["grand_total", "base_grand_total"]) + self.set_rounded_total() + + def set_rounded_total(self): + if frappe.db.get_single_value("Global Defaults", "disable_rounded_total"): + self.doc.rounded_total = self.doc.base_rounded_total = 0 + return + if self.doc.meta.get_field("rounded_total"): self.doc.rounded_total = round_based_on_smallest_currency_fraction(self.doc.grand_total, self.doc.currency, self.doc.precision("rounded_total")) + if self.doc.meta.get_field("base_rounded_total"): company_currency = erpnext.get_company_currency(self.doc.company) @@ -525,7 +528,7 @@ def get_itemised_tax_breakup_html(doc): for tax in doc.taxes: if getattr(tax, "category", None) and tax.category=="Valuation": continue - if tax.description not in tax_accounts: + if tax.description not in tax_accounts and tax.tax_amount_after_discount_amount: tax_accounts.append(tax.description) headers = get_itemised_tax_breakup_header(doc.doctype + " Item", tax_accounts) @@ -565,26 +568,21 @@ def get_itemised_tax(taxes): if getattr(tax, "category", None) and tax.category=="Valuation": continue - tax_amount_precision = tax.precision("tax_amount") - tax_rate_precision = tax.precision("rate") - item_tax_map = json.loads(tax.item_wise_tax_detail) if tax.item_wise_tax_detail else {} - - for item_code, tax_data in item_tax_map.items(): - itemised_tax.setdefault(item_code, frappe._dict()) + if item_tax_map: + for item_code, tax_data in item_tax_map.items(): + itemised_tax.setdefault(item_code, frappe._dict()) - if isinstance(tax_data, list): - precision = tax_amount_precision if tax.charge_type == "Actual" else tax_rate_precision - - itemised_tax[item_code][tax.description] = frappe._dict(dict( - tax_rate=flt(tax_data[0]), - tax_amount=flt(tax_data[1]) - )) - else: - itemised_tax[item_code][tax.description] = frappe._dict(dict( - tax_rate=flt(tax_data), - tax_amount=0.0 - )) + if isinstance(tax_data, list): + itemised_tax[item_code][tax.description] = frappe._dict(dict( + tax_rate=flt(tax_data[0]), + tax_amount=flt(tax_data[1]) + )) + else: + itemised_tax[item_code][tax.description] = frappe._dict(dict( + tax_rate=flt(tax_data), + tax_amount=0.0 + )) return itemised_tax diff --git a/erpnext/crm/doctype/item/test_item.js b/erpnext/crm/doctype/item/test_item.js index 58cf549fef8..c9b14ca1a96 100644 --- a/erpnext/crm/doctype/item/test_item.js +++ b/erpnext/crm/doctype/item/test_item.js @@ -19,7 +19,7 @@ QUnit.test("test: item", function (assert) { {is_stock_item: is_stock_item}, {standard_rate: keyboard_cost}, {opening_stock: no_of_items_to_stock}, - {default_warehouse: "Stores - RB"} + {default_warehouse: "Stores - FT"} ] ), () => { @@ -45,7 +45,7 @@ QUnit.test("test: item", function (assert) { {is_stock_item: is_stock_item}, {standard_rate: screen_cost}, {opening_stock: no_of_items_to_stock}, - {default_warehouse: "Stores - RB"} + {default_warehouse: "Stores - FT"} ] ), @@ -57,7 +57,7 @@ QUnit.test("test: item", function (assert) { {is_stock_item: is_stock_item}, {standard_rate: CPU_cost}, {opening_stock: no_of_items_to_stock}, - {default_warehouse: "Stores - RB"} + {default_warehouse: "Stores - FT"} ] ), @@ -66,7 +66,7 @@ QUnit.test("test: item", function (assert) { "Item", [ {item_code: "Laptop"}, {item_group: "Products"}, - {default_warehouse: "Stores - RB"} + {default_warehouse: "Stores - FT"} ] ), () => frappe.tests.make( @@ -85,7 +85,7 @@ QUnit.test("test: item", function (assert) { {is_stock_item: is_stock_item}, {standard_rate: scrap_cost}, {opening_stock: no_of_items_to_stock}, - {default_warehouse: "Stores - RB"} + {default_warehouse: "Stores - FT"} ] ), () => frappe.tests.make( diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index a05bacd3f65..eb6e8763e14 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -20,7 +20,7 @@ class Lead(SellingController): def onload(self): customer = frappe.db.get_value("Customer", {"lead_name": self.name}) self.get("__onload").is_customer = customer - load_address_and_contact(self, "lead") + load_address_and_contact(self) def validate(self): self._prev = frappe._dict({ diff --git a/erpnext/demo/data/drug_list.json b/erpnext/demo/data/drug_list.json new file mode 100644 index 00000000000..51b029c1dd7 --- /dev/null +++ b/erpnext/demo/data/drug_list.json @@ -0,0 +1,5420 @@ +[ + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Atocopherol", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Atocopherol", + "item_group": "Drug", + "item_name": "Atocopherol", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:16.577151", + "name": "Atocopherol", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Abacavir", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Abacavir", + "item_group": "Drug", + "item_name": "Abacavir", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:16.678257", + "name": "Abacavir", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Abciximab", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Abciximab", + "item_group": "Drug", + "item_name": "Abciximab", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:16.695413", + "name": "Abciximab", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Acacia", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Acacia", + "item_group": "Drug", + "item_name": "Acacia", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:16.797774", + "name": "Acacia", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Acamprosate", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Acamprosate", + "item_group": "Drug", + "item_name": "Acamprosate", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:16.826952", + "name": "Acamprosate", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Acarbose", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Acarbose", + "item_group": "Drug", + "item_name": "Acarbose", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:16.843890", + "name": "Acarbose", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Acebrofylline", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Acebrofylline", + "item_group": "Drug", + "item_name": "Acebrofylline", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:16.969984", + "name": "Acebrofylline", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Acebrofylline (SR)", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Acebrofylline (SR)", + "item_group": "Drug", + "item_name": "Acebrofylline (SR)", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:16.987354", + "name": "Acebrofylline (SR)", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Aceclofenac", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Aceclofenac", + "item_group": "Drug", + "item_name": "Aceclofenac", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.004369", + "name": "Aceclofenac", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Ash", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Ash", + "item_group": "Drug", + "item_name": "Ash", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.021192", + "name": "Ash", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Asparaginase", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Asparaginase", + "item_group": "Drug", + "item_name": "Asparaginase", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.038058", + "name": "Asparaginase", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Aspartame", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Aspartame", + "item_group": "Drug", + "item_name": "Aspartame", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.054463", + "name": "Aspartame", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Aspartic Acid", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Aspartic Acid", + "item_group": "Drug", + "item_name": "Aspartic Acid", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.071001", + "name": "Aspartic Acid", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Bleomycin", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Bleomycin", + "item_group": "Drug", + "item_name": "Bleomycin", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.087170", + "name": "Bleomycin", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Bleomycin Sulphate", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Bleomycin Sulphate", + "item_group": "Drug", + "item_name": "Bleomycin Sulphate", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.103691", + "name": "Bleomycin Sulphate", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Blue cap contains", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Blue cap contains", + "item_group": "Drug", + "item_name": "Blue cap contains", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.120040", + "name": "Blue cap contains", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Boran", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Boran", + "item_group": "Drug", + "item_name": "Boran", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.135964", + "name": "Boran", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Borax", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Borax", + "item_group": "Drug", + "item_name": "Borax", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.152575", + "name": "Borax", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Chlorbutanol", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Chlorbutanol", + "item_group": "Drug", + "item_name": "Chlorbutanol", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.168998", + "name": "Chlorbutanol", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Chlorbutol", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Chlorbutol", + "item_group": "Drug", + "item_name": "Chlorbutol", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.185316", + "name": "Chlorbutol", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Chlordiazepoxide", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Chlordiazepoxide", + "item_group": "Drug", + "item_name": "Chlordiazepoxide", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.208361", + "name": "Chlordiazepoxide", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Chlordiazepoxide and Clidinium Bromide", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Chlordiazepoxide and Clidinium Bromide", + "item_group": "Drug", + "item_name": "Chlordiazepoxide and Clidinium Bromide", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.224341", + "name": "Chlordiazepoxide and Clidinium Bromide", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Chlorhexidine", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Chlorhexidine", + "item_group": "Drug", + "item_name": "Chlorhexidine", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.240634", + "name": "Chlorhexidine", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Chlorhexidine 40%", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Chlorhexidine 40%", + "item_group": "Drug", + "item_name": "Chlorhexidine 40%", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.256922", + "name": "Chlorhexidine 40%", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Chlorhexidine Acetate", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Chlorhexidine Acetate", + "item_group": "Drug", + "item_name": "Chlorhexidine Acetate", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.274789", + "name": "Chlorhexidine Acetate", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Chlorhexidine Gluconate", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Chlorhexidine Gluconate", + "item_group": "Drug", + "item_name": "Chlorhexidine Gluconate", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.295371", + "name": "Chlorhexidine Gluconate", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Chlorhexidine HCL", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Chlorhexidine HCL", + "item_group": "Drug", + "item_name": "Chlorhexidine HCL", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.312916", + "name": "Chlorhexidine HCL", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Chlorhexidine Hydrochloride", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Chlorhexidine Hydrochloride", + "item_group": "Drug", + "item_name": "Chlorhexidine Hydrochloride", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.329570", + "name": "Chlorhexidine Hydrochloride", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Chloride", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Chloride", + "item_group": "Drug", + "item_name": "Chloride", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.346088", + "name": "Chloride", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Fosfomycin Tromethamine", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Fosfomycin Tromethamine", + "item_group": "Drug", + "item_name": "Fosfomycin Tromethamine", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.362777", + "name": "Fosfomycin Tromethamine", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Fosinopril", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Fosinopril", + "item_group": "Drug", + "item_name": "Fosinopril", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.379465", + "name": "Fosinopril", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Iodochlorhydroxyquinoline", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Iodochlorhydroxyquinoline", + "item_group": "Drug", + "item_name": "Iodochlorhydroxyquinoline", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.396068", + "name": "Iodochlorhydroxyquinoline", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Iodochlorohydroxyquinoline", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Iodochlorohydroxyquinoline", + "item_group": "Drug", + "item_name": "Iodochlorohydroxyquinoline", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.412734", + "name": "Iodochlorohydroxyquinoline", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Ipratropium", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Ipratropium", + "item_group": "Drug", + "item_name": "Ipratropium", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.429333", + "name": "Ipratropium", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Mebeverine hydrochloride", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Mebeverine hydrochloride", + "item_group": "Drug", + "item_name": "Mebeverine hydrochloride", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.445814", + "name": "Mebeverine hydrochloride", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Mecetronium ethylsulphate", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Mecetronium ethylsulphate", + "item_group": "Drug", + "item_name": "Mecetronium ethylsulphate", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.461696", + "name": "Mecetronium ethylsulphate", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Meclizine", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Meclizine", + "item_group": "Drug", + "item_name": "Meclizine", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.478020", + "name": "Meclizine", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Oxaprozin", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Oxaprozin", + "item_group": "Drug", + "item_name": "Oxaprozin", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.496221", + "name": "Oxaprozin", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Oxazepam", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Oxazepam", + "item_group": "Drug", + "item_name": "Oxazepam", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.511933", + "name": "Oxazepam", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Oxcarbazepine", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Oxcarbazepine", + "item_group": "Drug", + "item_name": "Oxcarbazepine", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.528472", + "name": "Oxcarbazepine", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Oxetacaine", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Oxetacaine", + "item_group": "Drug", + "item_name": "Oxetacaine", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.544177", + "name": "Oxetacaine", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Oxethazaine", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Oxethazaine", + "item_group": "Drug", + "item_name": "Oxethazaine", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.560193", + "name": "Oxethazaine", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Suxamethonium Chloride", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Suxamethonium Chloride", + "item_group": "Drug", + "item_name": "Suxamethonium Chloride", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.576447", + "name": "Suxamethonium Chloride", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Tacrolimus", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Tacrolimus", + "item_group": "Drug", + "item_name": "Tacrolimus", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.593481", + "name": "Tacrolimus", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Ubiquinol", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Ubiquinol", + "item_group": "Drug", + "item_name": "Ubiquinol", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.609930", + "name": "Ubiquinol", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Vitamin B12", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Vitamin B12", + "item_group": "Drug", + "item_name": "Vitamin B12", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.626225", + "name": "Vitamin B12", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Vitamin B1Hydrochloride", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Vitamin B1Hydrochloride", + "item_group": "Drug", + "item_name": "Vitamin B1Hydrochloride", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.642423", + "name": "Vitamin B1Hydrochloride", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Vitamin B1Monohydrate", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Vitamin B1Monohydrate", + "item_group": "Drug", + "item_name": "Vitamin B1Monohydrate", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.658946", + "name": "Vitamin B1Monohydrate", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Vitamin B2", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Vitamin B2", + "item_group": "Drug", + "item_name": "Vitamin B2", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.675234", + "name": "Vitamin B2", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Vitamin B3", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Vitamin B3", + "item_group": "Drug", + "item_name": "Vitamin B3", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.691598", + "name": "Vitamin B3", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Vitamin D4", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Vitamin D4", + "item_group": "Drug", + "item_name": "Vitamin D4", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.707840", + "name": "Vitamin D4", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Vitamin E", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Vitamin E", + "item_group": "Drug", + "item_name": "Vitamin E", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.723859", + "name": "Vitamin E", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Wheat Germ Oil", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Wheat Germ Oil", + "item_group": "Drug", + "item_name": "Wheat Germ Oil", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.739829", + "name": "Wheat Germ Oil", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Wheatgrass extr", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Wheatgrass extr", + "item_group": "Drug", + "item_name": "Wheatgrass extr", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.757695", + "name": "Wheatgrass extr", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Whey Protein", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Whey Protein", + "item_group": "Drug", + "item_name": "Whey Protein", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.774098", + "name": "Whey Protein", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Xylometazoline", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Xylometazoline", + "item_group": "Drug", + "item_name": "Xylometazoline", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.790224", + "name": "Xylometazoline", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Xylometazoline Hydrochloride", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Xylometazoline Hydrochloride", + "item_group": "Drug", + "item_name": "Xylometazoline Hydrochloride", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.806359", + "name": "Xylometazoline Hydrochloride", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Yeast", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Yeast", + "item_group": "Drug", + "item_name": "Yeast", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.823305", + "name": "Yeast", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Yellow Fever Vaccine", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Yellow Fever Vaccine", + "item_group": "Drug", + "item_name": "Yellow Fever Vaccine", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.840250", + "name": "Yellow Fever Vaccine", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Zafirlukast", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Zafirlukast", + "item_group": "Drug", + "item_name": "Zafirlukast", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.856856", + "name": "Zafirlukast", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Zaleplon", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Zaleplon", + "item_group": "Drug", + "item_name": "Zaleplon", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.873287", + "name": "Zaleplon", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Zaltoprofen", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Zaltoprofen", + "item_group": "Drug", + "item_name": "Zaltoprofen", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.889263", + "name": "Zaltoprofen", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + }, + { + "asset_category": null, + "attributes": [], + "barcode": null, + "brand": null, + "buying_cost_center": null, + "country_of_origin": null, + "create_new_batch": 0, + "customer_code": "", + "customer_items": [], + "customs_tariff_number": null, + "default_bom": null, + "default_material_request_type": null, + "default_supplier": null, + "default_warehouse": null, + "delivered_by_supplier": 0, + "description": "Zanamivir", + "disabled": 0, + "docstatus": 0, + "doctype": "Item", + "end_of_life": null, + "expense_account": null, + "gst_hsn_code": null, + "has_batch_no": 0, + "has_serial_no": 0, + "has_variants": 0, + "image": null, + "income_account": null, + "inspection_required_before_delivery": 0, + "inspection_required_before_purchase": 0, + "is_fixed_asset": 0, + "is_purchase_item": 1, + "is_sales_item": 1, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "Zanamivir", + "item_group": "Drug", + "item_name": "Zanamivir", + "last_purchase_rate": 0.0, + "lead_time_days": 0, + "manufacturer": null, + "manufacturer_part_no": null, + "max_discount": 0.0, + "min_order_qty": 0.0, + "modified": "2017-07-06 12:53:17.905022", + "name": "Zanamivir", + "naming_series": null, + "net_weight": 0.0, + "opening_stock": 0.0, + "publish_in_hub": 1, + "quality_parameters": [], + "reorder_levels": [], + "route": null, + "safety_stock": 0.0, + "selling_cost_center": null, + "serial_no_series": null, + "show_in_website": 0, + "show_variant_in_website": 0, + "slideshow": null, + "standard_rate": 0.0, + "stock_uom": "Nos", + "supplier_items": [], + "synced_with_hub": 0, + "taxes": [], + "thumbnail": null, + "tolerance": 0.0, + "total_projected_qty": 0.0, + "uoms": [ + { + "conversion_factor": 1.0, + "uom": "Nos" + } + ], + "valuation_method": null, + "valuation_rate": 0.0, + "variant_based_on": null, + "variant_of": null, + "warranty_period": null, + "web_long_description": null, + "website_image": null, + "website_item_groups": [], + "website_specifications": [], + "website_warehouse": null, + "weight_uom": null, + "weightage": 0 + } +] diff --git a/erpnext/demo/data/item.json b/erpnext/demo/data/item.json index e2085220d4b..fe12ce892a0 100644 --- a/erpnext/demo/data/item.json +++ b/erpnext/demo/data/item.json @@ -167,6 +167,7 @@ "item_group": "Products", "item_name": "Wind Turbine-S", "variant_of": "Wind Turbine", + "valuation_rate": 300, "attributes":[ { "attribute": "Size", @@ -183,6 +184,7 @@ "item_group": "Products", "item_name": "Wind Turbine-M", "variant_of": "Wind Turbine", + "valuation_rate": 300, "attributes":[ { "attribute": "Size", @@ -199,6 +201,7 @@ "item_group": "Products", "item_name": "Wind Turbine-L", "variant_of": "Wind Turbine", + "valuation_rate": 300, "attributes":[ { "attribute": "Size", diff --git a/erpnext/demo/data/patient.json b/erpnext/demo/data/patient.json new file mode 100644 index 00000000000..6d95a202021 --- /dev/null +++ b/erpnext/demo/data/patient.json @@ -0,0 +1,27 @@ +[ + { + "patient_name": "lila", + "gender": "Female" + }, + { + "patient_name": "charline", + "gender": "Female" + }, + { + "patient_name": "soren", + "last_name": "le gall", + "gender": "Male" + }, + { + "patient_name": "fanny", + "gender": "Female" + }, + { + "patient_name": "julie", + "gender": "Female" + }, + { + "patient_name": "louka", + "gender": "Male" + } +] diff --git a/erpnext/demo/data/physician.json b/erpnext/demo/data/physician.json new file mode 100644 index 00000000000..3afea993e60 --- /dev/null +++ b/erpnext/demo/data/physician.json @@ -0,0 +1,17 @@ +[ + { + "doctype": "Physician", + "first_name": "Eddie Jessup", + "department": "Pathology" + }, + { + "doctype": "Physician", + "first_name": "Deepshi Garg", + "department": "ENT" + }, + { + "doctype": "Physician", + "first_name": "Amit Jain", + "department": "Microbiology" + } +] diff --git a/erpnext/demo/demo.py b/erpnext/demo/demo.py index 9fde2646c8a..35256b580fa 100644 --- a/erpnext/demo/demo.py +++ b/erpnext/demo/demo.py @@ -4,7 +4,7 @@ import frappe, sys import erpnext import frappe.utils from erpnext.demo.user import hr, sales, purchase, manufacturing, stock, accounts, projects, fixed_asset, schools -from erpnext.demo.setup import education, manufacture, setup_data +from erpnext.demo.setup import education, manufacture, setup_data, healthcare """ Make a demo @@ -30,6 +30,8 @@ def make(domain='Manufacturing', days=100): manufacture.setup_data() elif domain== 'Education': education.setup_data() + elif domain== 'Healthcare': + healthcare.setup_data() site = frappe.local.site frappe.destroy() diff --git a/erpnext/demo/domains.py b/erpnext/demo/domains.py index 5743e27bf29..456eb5df32d 100644 --- a/erpnext/demo/domains.py +++ b/erpnext/demo/domains.py @@ -15,5 +15,8 @@ data = { }, 'Education': { 'company_name': 'Whitmore College' + }, + 'Healthcare': { + 'company_name': 'ABC Hospital Ltd.' } } \ No newline at end of file diff --git a/erpnext/demo/setup/healthcare.py b/erpnext/demo/setup/healthcare.py new file mode 100644 index 00000000000..d645e309f87 --- /dev/null +++ b/erpnext/demo/setup/healthcare.py @@ -0,0 +1,166 @@ +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +import frappe, json +from frappe.utils.make_random import get_random +import datetime +from erpnext.demo.setup.setup_data import import_json +from frappe.utils import getdate +from erpnext.healthcare.doctype.lab_test.lab_test import create_test_from_template + +def setup_data(): + frappe.flags.mute_emails = True + make_masters() + make_patient() + make_lab_test() + make_consulation() + make_appointment() + consulation_on_appointment() + lab_test_on_consultation() + frappe.db.commit() + frappe.clear_cache() + +def make_masters(): + import_json("Physician") + import_drug() + frappe.db.commit() + +def make_patient(): + file_path = get_json_path("Patient") + with open(file_path, "r") as open_file: + patient_data = json.loads(open_file.read()) + count = 1 + + for d in enumerate(patient_data): + patient = frappe.new_doc("Patient") + patient.patient_name = d[1]['patient_name'].title() + patient.sex = d[1]['gender'] + patient.blood_group = "A Positive" + patient.date_of_birth = datetime.datetime(1990, 3, 25) + patient.email_id = d[1]['patient_name'] + "_" + patient.date_of_birth.strftime('%m/%d/%Y') + "@example.com" + if count <5: + patient.insert() + frappe.db.commit() + count+=1 + +def make_appointment(): + i = 1 + while i <= 4: + physician = get_random("Physician") + department = frappe.get_value("Physician", physician, "department") + patient = get_random("Patient") + patient_sex = frappe.get_value("Patient", patient, "sex") + appointment = frappe.new_doc("Patient Appointment") + startDate = datetime.datetime.now() + for x in random_date(startDate,0): + appointment_datetime = x + appointment.appointment_datetime = appointment_datetime + appointment.appointment_time = appointment_datetime + appointment.appointment_date = appointment_datetime + appointment.patient = patient + appointment.patient_sex = patient_sex + appointment.physician = physician + appointment.department = department + appointment.save(ignore_permissions = True) + i += 1 + +def make_consulation(): + for i in xrange(3): + physician = get_random("Physician") + department = frappe.get_value("Physician", physician, "department") + patient = get_random("Patient") + patient_sex = frappe.get_value("Patient", patient, "sex") + consultation = set_consultation(patient, patient_sex, physician, department, getdate(), i) + consultation.save(ignore_permissions=True) + +def consulation_on_appointment(): + for i in xrange(3): + appointment = get_random("Patient Appointment") + appointment = frappe.get_doc("Patient Appointment",appointment) + consultation = set_consultation(appointment.patient, appointment.patient_sex, appointment.physician, appointment.department, appointment.appointment_date, i) + consultation.appointment = appointment.name + consultation.save(ignore_permissions=True) + +def set_consultation(patient, patient_sex, physician, department, consultation_date, i): + consultation = frappe.new_doc("Consultation") + consultation.patient = patient + consultation.patient_sex = patient_sex + consultation.physician = physician + consultation.visit_department = department + consultation.consultation_date = consultation_date + if i > 2 and patient_sex=='Female': + consultation.symptoms = "Having chest pains for the last week." + consultation.diagnosis = """This patient's description of dull, aching, + exertion related substernal chest pain is suggestive of ischemic + cardiac origin. Her findings of a FH of early ASCVD, hypertension, + and early surgical menopause are pertinent risk factors for development + of coronary artery disease. """ + else: + consultation = append_drug_rx(consultation) + consultation = append_test_rx(consultation) + return consultation + +def make_lab_test(): + physician = get_random("Physician") + patient = get_random("Patient") + patient_sex = frappe.get_value("Patient", patient, "sex") + template = get_random("Lab Test Template") + set_lab_test(patient, patient_sex, physician, template) + +def lab_test_on_consultation(): + i = 1 + while i <= 2: + test_rx = get_random("Lab Prescription", filters={'test_created': 0}) + test_rx = frappe.get_doc("Lab Prescription", test_rx) + consultation = frappe.get_doc("Consultation", test_rx.parent) + set_lab_test(consultation.patient, consultation.patient_sex, consultation.physician, test_rx.test_code, test_rx.name) + i += 1 + +def set_lab_test(patient, patient_sex, physician, template, rx=None): + lab_test = frappe.new_doc("Lab Test") + lab_test.physician = physician + lab_test.patient = patient + lab_test.patient_sex = patient_sex + lab_test.template = template + lab_test.prescription = rx + create_test_from_template(lab_test) + +def append_test_rx(consultation): + i = 1 + while i <= 2: + test_rx = consultation.append("test_prescription") + test_rx.test_code = get_random("Lab Test Template") + i += 1 + return consultation + +def append_drug_rx(consultation): + i = 1 + while i <= 3: + drug = get_random("Item", filters={"item_group":"Drug"}) + drug = frappe.get_doc("Item", drug) + drug_rx = consultation.append("drug_prescription") + drug_rx.drug_code = drug.item_code + drug_rx.drug_name = drug.item_name + drug_rx.dosage = get_random("Prescription Dosage") + drug_rx.period = get_random("Prescription Duration") + i += 1 + return consultation + +def random_date(start,l): + current = start + while l >= 0: + curr = current + datetime.timedelta(minutes=60) + yield curr + l-=1 + +def import_drug(): + frappe.flags.in_import = True + data = json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data', 'drug_list.json')).read()) + for d in data: + doc = frappe.new_doc("Item") + doc.update(d) + doc.insert() + frappe.flags.in_import = False + +def get_json_path(doctype): + return frappe.get_app_path('erpnext', 'demo', 'data', frappe.scrub(doctype) + '.json') diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py index cec425ce6b9..c4df777c88b 100644 --- a/erpnext/demo/setup/setup_data.py +++ b/erpnext/demo/setup/setup_data.py @@ -184,7 +184,8 @@ def setup_user_roles(): user.add_roles('HR User', 'HR Manager', 'Accounts User', 'Accounts Manager', 'Stock User', 'Stock Manager', 'Sales User', 'Sales Manager', 'Purchase User', 'Purchase Manager', 'Projects User', 'Manufacturing User', 'Manufacturing Manager', - 'Support Team', 'Academics User') + 'Support Team', 'Academics User', 'Physician', 'Healthcare Administrator', 'Laboratory User', + 'Nursing User', 'Patient') if not frappe.db.get_global('demo_hr_user'): user = frappe.get_doc('User', 'CharmaineGaudreau@example.com') @@ -387,5 +388,3 @@ def import_json(doctype, submit=False, values=None): frappe.db.commit() frappe.flags.in_import = False - - diff --git a/erpnext/docs/assets/img/subscription/subscription.gif b/erpnext/docs/assets/img/accounts/subscription.gif similarity index 100% rename from erpnext/docs/assets/img/subscription/subscription.gif rename to erpnext/docs/assets/img/accounts/subscription.gif diff --git a/erpnext/docs/assets/img/subscription/subscription.png b/erpnext/docs/assets/img/accounts/subscription.png similarity index 100% rename from erpnext/docs/assets/img/subscription/subscription.png rename to erpnext/docs/assets/img/accounts/subscription.png diff --git a/erpnext/docs/assets/img/healthcare/._.DS_Store b/erpnext/docs/assets/img/healthcare/._.DS_Store new file mode 100755 index 00000000000..77c0a115d2c Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._.DS_Store differ diff --git a/erpnext/docs/assets/img/healthcare/._appointment_1.png b/erpnext/docs/assets/img/healthcare/._appointment_1.png new file mode 100755 index 00000000000..9185da5b7ce Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._appointment_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/._appointment_2.png b/erpnext/docs/assets/img/healthcare/._appointment_2.png new file mode 100755 index 00000000000..901903ac3bf Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._appointment_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/._appointment_3.png b/erpnext/docs/assets/img/healthcare/._appointment_3.png new file mode 100755 index 00000000000..acac3260799 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._appointment_3.png differ diff --git a/erpnext/docs/assets/img/healthcare/._consultation_1.png b/erpnext/docs/assets/img/healthcare/._consultation_1.png new file mode 100755 index 00000000000..26693f48525 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._consultation_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/._consultation_2.png b/erpnext/docs/assets/img/healthcare/._consultation_2.png new file mode 100755 index 00000000000..ddb28b02829 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._consultation_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/._consultation_3.png b/erpnext/docs/assets/img/healthcare/._consultation_3.png new file mode 100755 index 00000000000..75615ee82cf Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._consultation_3.png differ diff --git a/erpnext/docs/assets/img/healthcare/._consultation_4.png b/erpnext/docs/assets/img/healthcare/._consultation_4.png new file mode 100755 index 00000000000..a18b518d04c Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._consultation_4.png differ diff --git a/erpnext/docs/assets/img/healthcare/._home.png b/erpnext/docs/assets/img/healthcare/._home.png new file mode 100755 index 00000000000..38c9eafb70b Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._home.png differ diff --git a/erpnext/docs/assets/img/healthcare/._lab_test_1.png b/erpnext/docs/assets/img/healthcare/._lab_test_1.png new file mode 100755 index 00000000000..36be754257c Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._lab_test_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/._lab_test_2.png b/erpnext/docs/assets/img/healthcare/._lab_test_2.png new file mode 100755 index 00000000000..684798b4bd6 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._lab_test_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/._medical_code_1.png b/erpnext/docs/assets/img/healthcare/._medical_code_1.png new file mode 100755 index 00000000000..a27e93348ef Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._medical_code_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/._medical_record_1.png b/erpnext/docs/assets/img/healthcare/._medical_record_1.png new file mode 100755 index 00000000000..df79c91aef6 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._medical_record_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/._medical_record_2.png b/erpnext/docs/assets/img/healthcare/._medical_record_2.png new file mode 100755 index 00000000000..89916673154 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._medical_record_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/._module.png b/erpnext/docs/assets/img/healthcare/._module.png new file mode 100755 index 00000000000..f8a4a0ff686 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._module.png differ diff --git a/erpnext/docs/assets/img/healthcare/._patient_1.png b/erpnext/docs/assets/img/healthcare/._patient_1.png new file mode 100755 index 00000000000..589703e587c Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._patient_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/._patient_2.png b/erpnext/docs/assets/img/healthcare/._patient_2.png new file mode 100755 index 00000000000..0ac360ae142 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._patient_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/._patient_3.png b/erpnext/docs/assets/img/healthcare/._patient_3.png new file mode 100755 index 00000000000..d8e0ed2cc85 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._patient_3.png differ diff --git a/erpnext/docs/assets/img/healthcare/._physician_1.png b/erpnext/docs/assets/img/healthcare/._physician_1.png new file mode 100755 index 00000000000..bf7889bc997 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._physician_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/._physician_2.png b/erpnext/docs/assets/img/healthcare/._physician_2.png new file mode 100755 index 00000000000..a726f9a85ba Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._physician_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/._physician_schedule_1.png b/erpnext/docs/assets/img/healthcare/._physician_schedule_1.png new file mode 100755 index 00000000000..6dba9d58aad Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._physician_schedule_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/._physician_schedule_2.png b/erpnext/docs/assets/img/healthcare/._physician_schedule_2.png new file mode 100755 index 00000000000..02eec95ea6c Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._physician_schedule_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/._sample_collection_1.png b/erpnext/docs/assets/img/healthcare/._sample_collection_1.png new file mode 100755 index 00000000000..c72cbf7759e Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._sample_collection_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/._vitals_1.png b/erpnext/docs/assets/img/healthcare/._vitals_1.png new file mode 100755 index 00000000000..cae923b68cd Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._vitals_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/._vitals_2.png b/erpnext/docs/assets/img/healthcare/._vitals_2.png new file mode 100755 index 00000000000..77846b9a1c7 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/._vitals_2.png differ diff --git a/erpnext/subscription/__init__.py b/erpnext/docs/assets/img/healthcare/__init__.py old mode 100644 new mode 100755 similarity index 100% rename from erpnext/subscription/__init__.py rename to erpnext/docs/assets/img/healthcare/__init__.py diff --git a/erpnext/docs/assets/img/healthcare/appointment_1.png b/erpnext/docs/assets/img/healthcare/appointment_1.png new file mode 100755 index 00000000000..afd308df75a Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/appointment_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/appointment_2.png b/erpnext/docs/assets/img/healthcare/appointment_2.png new file mode 100755 index 00000000000..104a919748b Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/appointment_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/appointment_3.png b/erpnext/docs/assets/img/healthcare/appointment_3.png new file mode 100755 index 00000000000..004a978862a Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/appointment_3.png differ diff --git a/erpnext/docs/assets/img/healthcare/consultation_1.png b/erpnext/docs/assets/img/healthcare/consultation_1.png new file mode 100755 index 00000000000..a7bc60da3bf Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/consultation_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/consultation_2.png b/erpnext/docs/assets/img/healthcare/consultation_2.png new file mode 100755 index 00000000000..fd5ceee2397 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/consultation_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/consultation_3.png b/erpnext/docs/assets/img/healthcare/consultation_3.png new file mode 100755 index 00000000000..e2804a91709 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/consultation_3.png differ diff --git a/erpnext/docs/assets/img/healthcare/consultation_4.png b/erpnext/docs/assets/img/healthcare/consultation_4.png new file mode 100755 index 00000000000..3f9817ca4e0 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/consultation_4.png differ diff --git a/erpnext/docs/assets/img/healthcare/home.png b/erpnext/docs/assets/img/healthcare/home.png new file mode 100755 index 00000000000..afe57a3640b Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/home.png differ diff --git a/erpnext/docs/assets/img/healthcare/lab_test_1.png b/erpnext/docs/assets/img/healthcare/lab_test_1.png new file mode 100755 index 00000000000..b2ddbeb3245 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/lab_test_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/lab_test_2.png b/erpnext/docs/assets/img/healthcare/lab_test_2.png new file mode 100755 index 00000000000..c06732a5ec7 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/lab_test_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/medical_code_1.png b/erpnext/docs/assets/img/healthcare/medical_code_1.png new file mode 100755 index 00000000000..4497e5a2d43 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/medical_code_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/medical_record_1.png b/erpnext/docs/assets/img/healthcare/medical_record_1.png new file mode 100755 index 00000000000..60586525907 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/medical_record_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/medical_record_2.png b/erpnext/docs/assets/img/healthcare/medical_record_2.png new file mode 100755 index 00000000000..a482704180a Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/medical_record_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/module.png b/erpnext/docs/assets/img/healthcare/module.png new file mode 100755 index 00000000000..c795df15bcd Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/module.png differ diff --git a/erpnext/docs/assets/img/healthcare/patient_1.png b/erpnext/docs/assets/img/healthcare/patient_1.png new file mode 100755 index 00000000000..03728aff62d Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/patient_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/patient_2.png b/erpnext/docs/assets/img/healthcare/patient_2.png new file mode 100755 index 00000000000..2a632c7a8b1 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/patient_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/patient_3.png b/erpnext/docs/assets/img/healthcare/patient_3.png new file mode 100755 index 00000000000..738ce2ccbd5 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/patient_3.png differ diff --git a/erpnext/docs/assets/img/healthcare/physician_1.png b/erpnext/docs/assets/img/healthcare/physician_1.png new file mode 100755 index 00000000000..f5705151cc8 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/physician_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/physician_2.png b/erpnext/docs/assets/img/healthcare/physician_2.png new file mode 100755 index 00000000000..7b3d1edf3a4 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/physician_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/physician_schedule_1.png b/erpnext/docs/assets/img/healthcare/physician_schedule_1.png new file mode 100755 index 00000000000..a9102e24937 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/physician_schedule_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/physician_schedule_2.png b/erpnext/docs/assets/img/healthcare/physician_schedule_2.png new file mode 100755 index 00000000000..d9105688ff4 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/physician_schedule_2.png differ diff --git a/erpnext/docs/assets/img/healthcare/sample_collection_1.png b/erpnext/docs/assets/img/healthcare/sample_collection_1.png new file mode 100755 index 00000000000..76238474ccf Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/sample_collection_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/vitals_1.png b/erpnext/docs/assets/img/healthcare/vitals_1.png new file mode 100755 index 00000000000..43bf5bfcd94 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/vitals_1.png differ diff --git a/erpnext/docs/assets/img/healthcare/vitals_2.png b/erpnext/docs/assets/img/healthcare/vitals_2.png new file mode 100755 index 00000000000..3e2129ae358 Binary files /dev/null and b/erpnext/docs/assets/img/healthcare/vitals_2.png differ diff --git a/erpnext/docs/user/manual/en/accounts/index.txt b/erpnext/docs/user/manual/en/accounts/index.txt index 6a0da3a8945..41cb243dc66 100644 --- a/erpnext/docs/user/manual/en/accounts/index.txt +++ b/erpnext/docs/user/manual/en/accounts/index.txt @@ -6,6 +6,7 @@ purchase-invoice payments journal-entry payment-entry +subscription multi-currency-accounting advance-payment-entry payment-request diff --git a/erpnext/docs/user/manual/en/accounts/subscription.md b/erpnext/docs/user/manual/en/accounts/subscription.md new file mode 100644 index 00000000000..9afab58e257 --- /dev/null +++ b/erpnext/docs/user/manual/en/accounts/subscription.md @@ -0,0 +1,24 @@ +# Subscription + +If you have a contract with the Customer where your organization gives bill to the Customer on a monthly, quarterly, half-yearly or annual basis, you can use subscription feature to make auto invoicing. + +
+
+#### Scenario
+
+Subscription for your hosted ERPNext account requires yearly renewal. We use Sales Invoice for generating proforma invoices. To automate proforma invoicing for renewal, we set original Sales Invoice on the subscription form. Recurring proforma invoice is created automatically just before customer's account is about to expire, and requires renewal. This recurring Proforma Invoice is also emailed automatically to the customer.
+
+To set the subscription for the sales invoice
+Goto Subscription > select base doctype "Sales Invoice" > select base docname "Invoice No" > Save
+
+
+
+**From Date and To Date**: This defines contract period with the customer.
+
+**Repeat on Day**: If frequency is set as Monthly, then it will be day of the month on which recurring invoice will be generated.
+
+**Notify By Email**: If you want to notify the user about auto recurring invoice.
+
+**Print Format**: Select a print format to define document view which should be emailed to customer.
+
+**Disabled**: It will stop to make auto recurring documents against the subscription
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/customize-erpnext/articles/creating-custom-link-field.md b/erpnext/docs/user/manual/en/customize-erpnext/articles/creating-custom-link-field.md
index 829015db6d6..9a480bdca5a 100644
--- a/erpnext/docs/user/manual/en/customize-erpnext/articles/creating-custom-link-field.md
+++ b/erpnext/docs/user/manual/en/customize-erpnext/articles/creating-custom-link-field.md
@@ -11,7 +11,7 @@ You can insert Custom Link Field by following steps below.
####Step 2: Select Form
-In Customize Form, select Document Type (Quotation, Sales Order, Purchase Invoice Item etc.). Once field are updated in table, open field before which you wish to insert Custom Field. Then click on "Insert Above" to insert new Custom Field.
+In Customize Form, select Document Type (Quotation, Sales Order, Purchase Invoice Item etc.). Once fields are updated in the accompanying table below, open a field above the one you wish to insert your Custom Field. Then click on "Insert Above" to insert the new Custom Field.
@@ -26,4 +26,4 @@ To set field as Link, enter values as below.
-
\ No newline at end of file
+
diff --git a/erpnext/docs/user/manual/en/healthcare/._.DS_Store b/erpnext/docs/user/manual/en/healthcare/._.DS_Store
new file mode 100755
index 00000000000..ed70b669b54
Binary files /dev/null and b/erpnext/docs/user/manual/en/healthcare/._.DS_Store differ
diff --git a/erpnext/subscription/doctype/__init__.py b/erpnext/docs/user/manual/en/healthcare/__init__.py
old mode 100644
new mode 100755
similarity index 100%
rename from erpnext/subscription/doctype/__init__.py
rename to erpnext/docs/user/manual/en/healthcare/__init__.py
diff --git a/erpnext/docs/user/manual/en/healthcare/appointment.md b/erpnext/docs/user/manual/en/healthcare/appointment.md
new file mode 100755
index 00000000000..a5cea36b20e
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/appointment.md
@@ -0,0 +1,38 @@
+# Patient Appointment
+ERPNext Healthcare allows you to book Patient appointments for any date and if configured, send them alerts via Email or SMS.
+
+You can create a Patient Appointment from
+> Healthcare > Patient Appointment > New Patient Appointment
+
+You can book appointments for a registered Patient by searching and selecting the Patient field. You can search the Patient by Patient ID, Name, Email or Mobile number. You can also register a new Patient from the Appointment screen by selecting "Create a new patient" in the Patient field.
+
+
+
+If you have a front desk executive to manage your appointments, you can configure a user role to have access to Patient Appointment so that she can do the bookings by selecting the Physician whom the Patient wish to consult and the date for booking. "Check Availability" button will pop up all the available time slots with status indicators for the date. She can select a time slot and "Book" the Appointment for the Patient.
+
+
+
+After Booking, the scheduled time of the Appointment and duration will be updated and seved in the document.
+
+
+
+You can configure ERPNext to send an SMS alert to the Patient about the booking confirmation or a reminder on the day of Appointment by doing necessary configurations in -
+
+> Healthcare > Healthcare Settings > Out Patient SMS Alerts
+
+The screen also allows the executive to select a Referring Physician so that you can track the source the appointment.
+
+### Actions
+ * Billing: If you collect the consultation fee while booking the Appointment itself you can do so by using the "Create > Invoice" button. This will take you to the ERPNext Accounts Sales Invoice screen.
+
+ * Vital Signs: "Create > Vital Signs" button will take you to the new Vital Signs screen to record the vitals of the Patient.
+
+ * Consultation: From the Appointment screen you can directly create a Consultation to record the details of patient encounter.
+
+ * View Patient Medical Record.
+
+> Note: User should have privileges (User Role) to view the buttons
+
+A Patient can also book an appointment with a Physician by checking the Physician's availability directly through the **ERPNext Portal**.
+
+{next}
diff --git a/erpnext/docs/user/manual/en/healthcare/consultation.md b/erpnext/docs/user/manual/en/healthcare/consultation.md
new file mode 100755
index 00000000000..a98713bcb56
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/consultation.md
@@ -0,0 +1,28 @@
+# Consultation
+ERPNext Healthcare allows you to record Patient encounters through the Consultation document. You can create a Consultation based on a previously booked Appointment or directly by creating a new Consultation
+>Healthcare > Consultation > Consultation
+
+If you are creating the Consultation document from an Appointment, Patient and other related data will automatically be populated else you can search the Patient by name, email phone number etc. The Patient Details section will list the latest Vital Signs record of the patient and other information captured in the Patient screen.
+
+
+
+### Assessment
+
+Encounter Impression section allows you to select (or create new) Complaints and your assessment based on the presented complaints. You can opt to include the captured data in Consultation print by selecting the "In Print" flag
+
+
+
+### Prescriptions
+
+You can prescribe medicines in the Drug Prescription section by selecting the drug codes (Stock Item) and appropriate dosages. If you are not managing Stock and Items are not configured, you can simply enter the Medicine name and strength in the Strength field which will printed.
+
+Prescribing a laboratory investigation is similar and if you have Lab Tests configured, you can select from the list. Or key in the Lab Test name to be printed as part of the Prescription.
+
+
+
+### Medical Coding
+You can also attach one or more Medical Codes to designate the Diagnosis in the Medical Coding Section. You will have to select the Medical Code Standard you wish to encode the diagnosis and then select the Code by searching the Code itself or the Code Description.
+
+
+
+{next}
diff --git a/erpnext/docs/user/manual/en/healthcare/index.md b/erpnext/docs/user/manual/en/healthcare/index.md
new file mode 100755
index 00000000000..85e3b6fec89
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/index.md
@@ -0,0 +1,13 @@
+# Healthcare
+
+ERPNext Healthcare helps you manage your Clinic or Practice efficiently by scheduling **Appointments** and recording **Patient Encounters** (Consultations). You can easily pull out a **Patient's Health Record** anytime to review all the history of treatments assisting you in providing effective, high quality care.
+
+
+
+Patients can view various documents relevant to them and book Appointments via the **ERPNext Portal**. The healthcare module is integrated with **Accounts** and **Human Resources** modules, helping you in **Billing**, **Payroll Management** etc. and benefit from other rich features of ERPNext. You can configure the **Selling** and **Stock** modules manage your Pharmacy.
+
+ERPNext Healthcare also includes features for effectively managing the functions of an associated **Laboratory** by helping you record **Sample Collection**, emailing and printing **Lab Test** results etc. ERPNext Healthcare allows you to upload **Medical Code Standards** like **ICD10** and attach to Consultations.
+
+### Topics
+
+{index}
diff --git a/erpnext/docs/user/manual/en/healthcare/index.txt b/erpnext/docs/user/manual/en/healthcare/index.txt
new file mode 100755
index 00000000000..471d91d5c91
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/index.txt
@@ -0,0 +1,12 @@
+patient
+appointment
+vital_signs
+consultation
+medical_record
+sample_collection
+lab_test
+invoicing
+physician
+physician_schedule
+medical_codes
+setup
diff --git a/erpnext/docs/user/manual/en/healthcare/invoicing.md b/erpnext/docs/user/manual/en/healthcare/invoicing.md
new file mode 100755
index 00000000000..bc9dead49f4
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/invoicing.md
@@ -0,0 +1,8 @@
+# Invoicing
+Billing is an integral part of any undertaking and ERPNext Healthcare achieves this by making use of the ERPNext Accounts module.
+
+> Note: All transactions of a Patient is booked against the Customer which it is linked to.
+
+All ERPNext Healthcare documents which require Invoicing will have buttons which would take you to the Sales Invoice with the Items configured for the service. You can then proceed by following the ERPNExt Accounts module workflows. Please note that your User account should have appropriate privileges to access the Accounts documents.
+
+{next}
diff --git a/erpnext/docs/user/manual/en/healthcare/lab_test.md b/erpnext/docs/user/manual/en/healthcare/lab_test.md
new file mode 100755
index 00000000000..bdf0cfcee34
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/lab_test.md
@@ -0,0 +1,22 @@
+# Lab Test
+
+ERPNext Healthcare allows you to manage a clinical laboratory efficiently by allowing you to enter Lab Tests and print or email test results, manage samples collected, create Invoice etc. ERPNext Healthcare comes pre-packed with some sample tests, you can reconfigure Lab Test Templates for each Test and its result format or crate new ones. You can do this in
+>Healthcare > Setup > Lab Text Templates
+
+Once you have all necessary Lab Test Templates configured, you can start creating Lab Tests by selecting a Test Template every time you create a Test. To create a new Lab Test
+>Healthcare > Laboratory > Lab Test > New Lab Test
+
+
+
+You can record the test results in the Lab Test document as the results gets ready.
+
+
+
+> Note: To create Sample Collection documents for every Lab Test, check "Manage Sample Collection" flag in Healthcare Settings and select Sample in the Lab Test Template
+
+In many Laboratories, approval of Lab Tests is a must before printing and submitting the document. ERPNext Healthcare allows you to create Users with Role "Lab Test Approver" for this. You will also have to enable this in
+>Healthcare Settings > Laboratory Settings > Require Lab Test Approval
+
+This will ensure that emailing or printing of Lab Tests can only be done after Approval of the Lab Test by the Lab Test Approver.
+
+{next}
diff --git a/erpnext/docs/user/manual/en/healthcare/medical_codes.md b/erpnext/docs/user/manual/en/healthcare/medical_codes.md
new file mode 100755
index 00000000000..c0997b1ebe1
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/medical_codes.md
@@ -0,0 +1,9 @@
+# Medical Code Standards
+Medical Coding are in many countries required for regulatory compliance and many of the Medical Insurance companies do that pricing based on Medical Code standards. ERPNext Healthcare offers support, however limited, to encode diagnosis and assessments recorded as part of Consultation. This can be done if you configure the Medical Code Standard and related Medical Codes - this is easily done by data import as the code data tends to be quite large. You can create as many Medical Code Standards you wish
+> Healthcare > Masters > Medical Code Standard
+
+Medical Code Standard document is used to name the Code Standard and act as a container for all the medical codes which are standardized under it. Medical Codes and descriptions can then be imported to the Medical Code document, after ensuring that you set the Medical Code Standard field to the appropriate Standard name.
+
+
+
+{next}
diff --git a/erpnext/docs/user/manual/en/healthcare/medical_record.md b/erpnext/docs/user/manual/en/healthcare/medical_record.md
new file mode 100755
index 00000000000..9d2697d6004
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/medical_record.md
@@ -0,0 +1,13 @@
+# Patient Medical Record
+The maintenance of complete and accurate medical records is a requirement of healthcare providers and is critical in rendering effective, high quality care. ERPNext Healthcare allows you to draw up the treatment history of a Patient anytime by merely selecting the Patient. "Medical Record" button is available in various screens so that you can easily switch to the Medical Record page to view the patient history.
+
+Medical Record automatically keeps track of all Consultations, recorded Vital Signs, Lab Investigations etc. Complaints, Diagnosis etc. captured as part of consultation are easily viewable but to look at the details of other documents, links are provided.
+
+
+
+##### Adding notes manually to Medical Record
+In the Patient screen Create > Medical Record will allow you to record notes to the Medical Record manually. You can also attach files when doing this, and the Medical Record will display links to the attached file along side the notes. Create > Medical Record button is also made available in the Consultation screen
+
+
+
+{next}
diff --git a/erpnext/docs/user/manual/en/healthcare/patient.md b/erpnext/docs/user/manual/en/healthcare/patient.md
new file mode 100755
index 00000000000..ed6810e88f2
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/patient.md
@@ -0,0 +1,43 @@
+# Patient
+
+In ERPNext Healthcare, the Patient document corresponds any individual who is the recipient of healthcare services you provide. For every ERPNext Healthcare document, it is important to have a Patient associated with it. You can create a new Patient from
+> Healthcare > Masters > Patient > New Patient
+
+
+
+The Patient document holds most details that are required to identify and qualify a patient. You can enter as much information available while creating the Patient. All information in the patient document is presented on the Consultation screen for easy lookup and you can always update this information. Other data like observations, vital signs etc. are not part of the Patient document. These could be recorded during patient encounters and will be available as part of the Patient Medical Record.
+
+
+
+### Patient as a Customer
+
+ERPNext Accounts makes use of "Customer" document for booking all transactions. So, you may want to associate every Patient to be associated with a Customer in ERPNext. By default, ERPNext Healthcare creates a Customer alongside a Patient and links to it - every transaction against a Patient is booked against the associated Customer. If, for some reason you do not intend to use the ERPNext Accounts module you can turn this behavior off by unchecking this flag
+>Healthcare > Setup > Healthcare Settings > Manage Customer
+
+In many cases, you may want to associate multiple Patients to a single Customer against whom you want to book the transactions. For instance, a Veterinarian would require the care services provided to different pets of an individual invoiced against a single Customer.
+
+
+
+The Patient Relation section of the Patient allows you to select how a Patient is related to another Patient in the system. This is optional, but will be quite handy if you want to use ERPNext in a fertility clinic, for example.
+
+### Registration Fee
+Many clinical facilities collect a registration fee during Registration. You can turn this feature on and set the registration fee amount by checking this flag
+> Healthcare > Setup > Healthcare Settings > Collect Fee for Patient Registration
+
+If you have this enabled, all new Patients you create will by default be in Disabled mode and will be enabled only after Invoicing the Registration Fee. To create Invoice and record the payment receipt, you can use the "Invoice Patient Registration" button in the Patient document.
+
+> Note: For all ERPNext Healthcare documents, "Disabled" Patients are filtered out.
+
+### Grant access to Patient Portal
+ERPNext Healthcare allows you to create a portal user associated with a Patient by simply entering the user email id. A welcome email will be sent to the Patient email address to "Complete" registration.
+
+### Actions
+From the Patient document, the following links are enabled
+
+* Vital Signs: "Create > Vital Signs" button will take you to the new Vital Signs screen to record the vitals of the Patient.
+
+* View Patient Medical Record.
+
+* Consultation: You can directly create a new Consultation to record the details of patient encounter.
+
+> Note: User should have privileges (User Role) to view the buttons
diff --git a/erpnext/docs/user/manual/en/healthcare/physician.md b/erpnext/docs/user/manual/en/healthcare/physician.md
new file mode 100755
index 00000000000..7b7995bcd97
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/physician.md
@@ -0,0 +1,18 @@
+# Physician
+ERPNext Healthcare allows you to create multiple physicians and optionally link to a User with appropriate Roles. You can create a Physician here -
+>Healthcare > Masters > Physician
+
+Linking a User to the Physician makes the system populate the Physician field in all documents to the Physician associated with the logged in User.
+>Note: You should also relate the User to an Employee to utilize the various features of Human Resources module.
+
+
+
+### Scheduling and Availability
+Each Physician can have a "Physician Schedule" and a "Time per Appointment" on the basis of which, the scheduler will book Appointments. Also, you can select appropriate Income Accounts for a Physician to book all Consultation charges into separate accounts.
+
+
+
+### Referring Physicians
+You may also want to manage a list of Doctors who refers Patients to your facility. You can manage such data in the Physician document itself by leaving out the User link.
+
+{next}
diff --git a/erpnext/docs/user/manual/en/healthcare/physician_schedule.md b/erpnext/docs/user/manual/en/healthcare/physician_schedule.md
new file mode 100755
index 00000000000..0da7896014f
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/physician_schedule.md
@@ -0,0 +1,13 @@
+# Physician Schedule
+Physician Schedule will help you to configure the availability and work hours of Physicians. You can then select an applicable schedule for each Physician.
+
+You can create Physician Schedule from -
+> Healthcare > Masters > Physician Schedule
+
+
+
+After naming the schedule you can use the "Add Time Slots" button to create time slots for each day of the week. These time slots will then be displayed while checking the availability of a Physician when booking an Appointment.
+
+
+
+{next}
diff --git a/erpnext/docs/user/manual/en/healthcare/sample_collection.md b/erpnext/docs/user/manual/en/healthcare/sample_collection.md
new file mode 100755
index 00000000000..3473dafd105
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/sample_collection.md
@@ -0,0 +1,13 @@
+# Sample Collection
+It's critical for a Laboratory to manage collected samples and you may want to ID the sample, print stickers etc. ERPNext Healthcare "Sample Collection" document helps you to easily manage the sample collection process by creating a sample collection document for every Lab Test automatically. You will have to turn on the flag in Healthcare Settings to enable this feature.
+> Healthcare Settings > Laboratory Settings > Manage Sample Collection
+
+
+
+> Note: You will have to select a Sample in the Lab Test Template for the system to automatically create a Sample Collection document
+
+You will have to enter the sample collected date and time to Submit the document signaling that the sample is collected.
+
+Printing on sample identification tags is also possible. By default a sample sticker print template is made available, but you can always create a custom Print Format by using "Customize" button in the print preview.
+
+{next}
diff --git a/erpnext/subscription/doctype/subscription/__init__.py b/erpnext/docs/user/manual/en/healthcare/setup/__init__.py
old mode 100644
new mode 100755
similarity index 100%
rename from erpnext/subscription/doctype/subscription/__init__.py
rename to erpnext/docs/user/manual/en/healthcare/setup/__init__.py
diff --git a/erpnext/docs/user/manual/en/healthcare/setup/index.md b/erpnext/docs/user/manual/en/healthcare/setup/index.md
new file mode 100755
index 00000000000..721f521eda8
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/setup/index.md
@@ -0,0 +1,7 @@
+# Setup
+
+Once you setup ERPNext (Company, Chart Of Accounts etc.), you can start with setting up your domain. To setup Healthcare module, User should have Healthcare Admin Role enabled. You can configure each of the departments as detailed in the Topics below.
+
+### Topics
+
+{index}
diff --git a/erpnext/docs/user/manual/en/healthcare/setup/index.txt b/erpnext/docs/user/manual/en/healthcare/setup/index.txt
new file mode 100755
index 00000000000..f2423811eca
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/setup/index.txt
@@ -0,0 +1,3 @@
+Setting up Practice Management
+Setting up Laboratory
+Setting up Pharmacy (Stock)
diff --git a/erpnext/docs/user/manual/en/healthcare/setup/setup_laboratory.md b/erpnext/docs/user/manual/en/healthcare/setup/setup_laboratory.md
new file mode 100755
index 00000000000..93e53b8a8e5
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/setup/setup_laboratory.md
@@ -0,0 +1,67 @@
+# Laboratory
+
+If you wish to use features of Laboratory, you can create Users with "Laboratory User". Lab Tests, Sample Collection etc. are only visible to users with this Role enabled.
+
+### Laboratory Settings
+> Healthcare > Setup > Healthcare Settings > Laboratory Settings
+
+* Manage Sample Collection - If this flag is enabled, every time you create a Lab Test, a Sample Collection document will be created.
+
+* Require Lab Test Approval - Turning this on will restrict printing and emailing of Lab Tests only if the documents are in Approved status. You can use this flag to ensure that every Test result leaves your facility after verification.
+
+* Enable the third option if you want the name and designation of the Employee associated with the User who submits the document to be printed in the Lab Test Report.
+
+##### SMS Alerts
+You can configure ERPNext Healthcare to alert Patients via SMS when the Lab Test result gets ready (Submit) and when you Email the result. You an configure the templates for the SMS as registered with your provider here.
+> Healthcare > Setup > Healthcare Settings > Laboratory SMS Alerts
+
+
+### Lab Test Templates
+Whenever you create a new Lab Test, the Lab Test document is loaded based on the template configured for that particular test. This means, you will have to have separate templates configured for each Lab Test.
+
+Here's how you can configure various types of templates.
+> Healthcare > Setup > Lab Test Template > New Lab Test Template
+
+After providing the Name for the Test you will have to select a Code and Item group for creating the mapped Item. ERPNext Healthcare maps every Lab Test (every other billable healthcare service) to an Item with "Maintain Stock" set to false. This way, the Accounts Module will invoice the Item and you can see the Sales related reports of Selling Module. You can also set selling rate of the Lab Test here - this will update the Selling Price List.
+
+> The Standard Selling Rate field behaves similar to the Item Standard Selling Rate, updating this will not update the Selling Price List
+
+The Is Billable flag in Lab Test Template creates the Item, but as Disabled. Likewise, unchecking this flag will Enable the Item.
+
+###### Result Format
+Following are the result formats available in ERPNext Healthcare
+
+* Single - select this format for results which require only a single input, result UOM and normal value
+* Compound - allows you to configure results which require multiple input fields with corresponding event names, result UOMs and normal values
+* Descriptive - this format is helpful for results which have multiple result components and corresponding result entry fields.
+* Grouped - You can group test templates which are already configured and combine as a single test. For such templates select "Grouped".
+* No Result - Select this if you don not need to enter or manage test result. Also, no Lab Test document will be created. e.g., Sub Tests for Grouped results.
+
+###### Normal values
+For Single and Compound result formats, you can set the normal values.
+
+###### Sample
+You will have to select the Sample required for the test. You can also mention the quantity of sample that needs to be collected. These details will be used when creating the Sample Collection document for the Lab Test.
+
+### Medical Department
+To organize your clinic into departments, you can create multiple Medical Departments. You can select appropriate departments in Lab Test Template and will be included in the Lab Test result print.
+> Healthcare > Setup > Medical Department > New Medical Department
+
+### Lab Test Sample
+You can create various masters for Samples that are to be collected for a Lab Test.
+> Healthcare > Setup > Lab Test Sample > New Lab Test Sample
+
+
+### Lab Test UOM
+You can create various masters for Unit of Measures to be used in Lab Test document.
+> Healthcare > Setup > Lab Test UOM > New Lab Test UOM
+
+### Antibiotic
+You can create masters for a list of Antibiotics.
+> Healthcare > Setup > Antibiotic > New Antibiotic
+
+### Sensitivity
+You can create masters for a list of Sensitivity to various Antibiotics.
+> Healthcare > Setup > Sensitivity > New Sensitivity
+
+{next}
diff --git a/erpnext/docs/user/manual/en/healthcare/setup/setup_pharmacy.md b/erpnext/docs/user/manual/en/healthcare/setup/setup_pharmacy.md
new file mode 100755
index 00000000000..7f9c7199370
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/setup/setup_pharmacy.md
@@ -0,0 +1,4 @@
+# Pharmacy
+ERPNext Healthcare do not have a Pharmacy module - but you can configure the Stock module to manage your stock and Accounts and Buying modules for Billing and Purchases. The stock module allows you to configure Items with serial numbers and Batches. Expiry dates can be set if you turn on the "Has Batch No" check. You can also configure the auto reorder levels if required.
+
+{next}
diff --git a/erpnext/docs/user/manual/en/healthcare/setup/setup_practice.md b/erpnext/docs/user/manual/en/healthcare/setup/setup_practice.md
new file mode 100755
index 00000000000..81604826a4f
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/setup/setup_practice.md
@@ -0,0 +1,38 @@
+# Clinic / Practice
+Configuring ERPNext Healthcare for your practice is simple.
+> Healthcare > Setup > Healthcare Settings > Out Patient Settings
+
+By default Patient document uses the patient name as the name, but you can opt to use a naming series if required.
+
+The "Manage Customer" option will enable the system to create and link a Customer whenever a new Patient is created. This Customer is used while booking all transactions.
+
+Here, you can also select the default Medical Code Standard to use.
+
+###### Collect Fee for Patient Registration
+If you enable this, all new Patients you create will by default be in Disabled mode and will be enabled only after Invoicing the Registration Fee. To create Invoice and record the payment receipt, you can use the "Invoice Patient Registration" button in the Patient document. Also note that all ERPNext Healthcare documents, "Disabled" Patients are filtered out. You can set the registration fee to be collected here.
+
+###### Consultation Fee validity
+Many healthcare facilities do not charge for follow up consultations within a time period after the first visit. You can configure the number of free visits allowed as well as the time period for free consultations here.
+
+### Medical Department
+To organize your clinic into departments, you can create multiple Medical Departments.
+> Healthcare > Setup > Medical Department > New Medical Department
+
+### Appointment Type
+You can create masters for various type of Appointments. This is optional and not considered while appointment scheduling.
+> Healthcare > Setup > Appointment Type > New Appointment Type
+
+### Prescription Dosage & Duration
+You can configure different dosages to be used while prescribing medication to patients. You can name the Prescription dosage in anyway you want (for example, BID or I-0-I), and then set the strength of the drug and the times at which it should be administered.
+> Healthcare > Setup > Prescription Dosage > New Prescription Dosage
+
+> Healthcare > Setup > Prescription Duration > New Prescription Duration
+
+### Complaint and Diagnosis
+To ease the data entry while recording the encounter impression, ERPNext Healthcare allows you to save each of the Complaint / Diagnosis data you enter, from the Consultation screen itself. This way, the database keeps building a list of all complaints and diagnosis you entered. Later on, every time you start keying in, you will be able to select the previously entered word / sentence from the search field. You can also configure the masters manually.
+
+> Healthcare > Setup > Complaints > New Complaint
+
+> Healthcare > Setup > Diagnosis > New Diagnosis
+
+{next}
diff --git a/erpnext/docs/user/manual/en/healthcare/vital_signs.md b/erpnext/docs/user/manual/en/healthcare/vital_signs.md
new file mode 100755
index 00000000000..21b25d96d18
--- /dev/null
+++ b/erpnext/docs/user/manual/en/healthcare/vital_signs.md
@@ -0,0 +1,13 @@
+# Vital Signs
+ERPNext Healthcare allows you to record Vital Signs of Patients and manage this information as part of the Patient's health record. You can create a new document and record Vital Signs of a Patient from most of the Healthcare documents or directly by
+> Healthcare > Consultation > Vital Signs > New Vital Signs
+
+
+
+You can select the Patient for whom you are recording the vitals and start by entering each of the fields. Normal values or ranges are provided for ease of assessment. Also present is an auto BMI calculator.
+
+
+
+All recorded Vital Signs are made available in the Patient Medical Record and the last recorded Vital Sign is displayed on the left hand side pane for easy review.
+
+{next}
diff --git a/erpnext/healthcare/__init__.py b/erpnext/healthcare/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/healthcare/doctype/__init__.py b/erpnext/healthcare/doctype/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/healthcare/doctype/antibiotic/__init__.py b/erpnext/healthcare/doctype/antibiotic/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/healthcare/doctype/antibiotic/antibiotic.js b/erpnext/healthcare/doctype/antibiotic/antibiotic.js
new file mode 100644
index 00000000000..42e6adb6030
--- /dev/null
+++ b/erpnext/healthcare/doctype/antibiotic/antibiotic.js
@@ -0,0 +1,5 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Antibiotic', {
+});
diff --git a/erpnext/healthcare/doctype/antibiotic/antibiotic.json b/erpnext/healthcare/doctype/antibiotic/antibiotic.json
new file mode 100644
index 00000000000..d481036ee60
--- /dev/null
+++ b/erpnext/healthcare/doctype/antibiotic/antibiotic.json
@@ -0,0 +1,115 @@
+{
+ "allow_copy": 1,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:antibiotic_name",
+ "beta": 1,
+ "creation": "2016-02-23 11:11:30.749731",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 0,
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "antibiotic_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": "Antibiotic 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
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-08-31 13:44:43.199657",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Antibiotic",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Healthcare Administrator",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Laboratory User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 0
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Healthcare",
+ "search_fields": "antibiotic_name",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "antibiotic_name",
+ "track_changes": 0,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/antibiotic/antibiotic.py b/erpnext/healthcare/doctype/antibiotic/antibiotic.py
new file mode 100644
index 00000000000..8236c8ab73a
--- /dev/null
+++ b/erpnext/healthcare/doctype/antibiotic/antibiotic.py
@@ -0,0 +1,9 @@
+# -*- 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 Antibiotic(Document):
+ pass
diff --git a/erpnext/healthcare/doctype/antibiotic/test_antibiotic.js b/erpnext/healthcare/doctype/antibiotic/test_antibiotic.js
new file mode 100644
index 00000000000..b92103d7509
--- /dev/null
+++ b/erpnext/healthcare/doctype/antibiotic/test_antibiotic.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Antibiotic", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Antibiotic
+ () => frappe.tests.make('Antibiotic', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/healthcare/doctype/antibiotic/test_antibiotic.py b/erpnext/healthcare/doctype/antibiotic/test_antibiotic.py
new file mode 100644
index 00000000000..6ac4f4f9fc0
--- /dev/null
+++ b/erpnext/healthcare/doctype/antibiotic/test_antibiotic.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+import unittest
+
+class TestAntibiotic(unittest.TestCase):
+ pass
diff --git a/erpnext/healthcare/doctype/appointment_type/__init__.py b/erpnext/healthcare/doctype/appointment_type/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/healthcare/doctype/appointment_type/appointment_type.js b/erpnext/healthcare/doctype/appointment_type/appointment_type.js
new file mode 100644
index 00000000000..15916a5134a
--- /dev/null
+++ b/erpnext/healthcare/doctype/appointment_type/appointment_type.js
@@ -0,0 +1,5 @@
+// Copyright (c) 2016, ESS LLP and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Appointment Type', {
+});
diff --git a/erpnext/healthcare/doctype/appointment_type/appointment_type.json b/erpnext/healthcare/doctype/appointment_type/appointment_type.json
new file mode 100644
index 00000000000..4b34892ffd3
--- /dev/null
+++ b/erpnext/healthcare/doctype/appointment_type/appointment_type.json
@@ -0,0 +1,145 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 1,
+ "autoname": "field:appointment_type",
+ "beta": 1,
+ "creation": "2016-07-22 11:52:34.953019",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 0,
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "appointment_type",
+ "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": "Type",
+ "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": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "ip",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Is Inpatient",
+ "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": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-08-31 13:46:57.142289",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Appointment Type",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Healthcare Administrator",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Physician",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Healthcare",
+ "search_fields": "appointment_type",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "",
+ "track_changes": 0,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/appointment_type/appointment_type.py b/erpnext/healthcare/doctype/appointment_type/appointment_type.py
new file mode 100644
index 00000000000..1dacffab357
--- /dev/null
+++ b/erpnext/healthcare/doctype/appointment_type/appointment_type.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, ESS LLP and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class AppointmentType(Document):
+ pass
diff --git a/erpnext/healthcare/doctype/appointment_type/test_appointment_type.js b/erpnext/healthcare/doctype/appointment_type/test_appointment_type.js
new file mode 100644
index 00000000000..93274e55c7b
--- /dev/null
+++ b/erpnext/healthcare/doctype/appointment_type/test_appointment_type.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Appointment Type", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Appointment Type
+ () => frappe.tests.make('Appointment Type', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/healthcare/doctype/appointment_type/test_appointment_type.py b/erpnext/healthcare/doctype/appointment_type/test_appointment_type.py
new file mode 100644
index 00000000000..04452e470e2
--- /dev/null
+++ b/erpnext/healthcare/doctype/appointment_type/test_appointment_type.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, ESS LLP and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+# test_records = frappe.get_test_records('Appointment Type')
+
+class TestAppointmentType(unittest.TestCase):
+ pass
diff --git a/erpnext/healthcare/doctype/codification_table/__init__.py b/erpnext/healthcare/doctype/codification_table/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/healthcare/doctype/codification_table/codification_table.json b/erpnext/healthcare/doctype/codification_table/codification_table.json
new file mode 100644
index 00000000000..c4117782ffd
--- /dev/null
+++ b/erpnext/healthcare/doctype/codification_table/codification_table.json
@@ -0,0 +1,135 @@
+{
+ "allow_copy": 1,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 1,
+ "creation": "2017-06-22 13:09:23.159579",
+ "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": "medical_code",
+ "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": "Medical Code",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Medical Code",
+ "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": "code",
+ "fieldtype": "Read Only",
+ "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": "Code",
+ "length": 0,
+ "no_copy": 0,
+ "options": "medical_code.code",
+ "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": "description",
+ "fieldtype": "Read Only",
+ "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": "Description",
+ "length": 0,
+ "no_copy": 0,
+ "options": "medical_code.description",
+ "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": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2017-08-31 14:06:50.281545",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Codification Table",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Healthcare",
+ "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/healthcare/doctype/codification_table/codification_table.py b/erpnext/healthcare/doctype/codification_table/codification_table.py
new file mode 100644
index 00000000000..ae29c03bbbd
--- /dev/null
+++ b/erpnext/healthcare/doctype/codification_table/codification_table.py
@@ -0,0 +1,9 @@
+# -*- 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 CodificationTable(Document):
+ pass
diff --git a/erpnext/healthcare/doctype/complaint/__init__.py b/erpnext/healthcare/doctype/complaint/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/healthcare/doctype/complaint/complaint.js b/erpnext/healthcare/doctype/complaint/complaint.js
new file mode 100644
index 00000000000..5a2d219fe3b
--- /dev/null
+++ b/erpnext/healthcare/doctype/complaint/complaint.js
@@ -0,0 +1,5 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Complaint', {
+});
diff --git a/erpnext/healthcare/doctype/complaint/complaint.json b/erpnext/healthcare/doctype/complaint/complaint.json
new file mode 100644
index 00000000000..0899a399715
--- /dev/null
+++ b/erpnext/healthcare/doctype/complaint/complaint.json
@@ -0,0 +1,116 @@
+{
+ "allow_copy": 1,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:complaints",
+ "beta": 1,
+ "creation": "2017-02-15 12:25:28.045267",
+ "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": "complaints",
+ "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": "Complaints",
+ "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
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-08-31 13:44:31.848346",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Complaint",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Healthcare Administrator",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Physician",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Healthcare",
+ "search_fields": "complaints",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "complaints",
+ "track_changes": 0,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/complaint/complaint.py b/erpnext/healthcare/doctype/complaint/complaint.py
new file mode 100644
index 00000000000..717f9dbb4ae
--- /dev/null
+++ b/erpnext/healthcare/doctype/complaint/complaint.py
@@ -0,0 +1,9 @@
+# -*- 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 Complaint(Document):
+ pass
diff --git a/erpnext/healthcare/doctype/complaint/test_complaint.js b/erpnext/healthcare/doctype/complaint/test_complaint.js
new file mode 100644
index 00000000000..9ff44d8da46
--- /dev/null
+++ b/erpnext/healthcare/doctype/complaint/test_complaint.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Complaint", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Complaint
+ () => frappe.tests.make('Complaint', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/healthcare/doctype/complaint/test_complaint.py b/erpnext/healthcare/doctype/complaint/test_complaint.py
new file mode 100644
index 00000000000..2b9273a9675
--- /dev/null
+++ b/erpnext/healthcare/doctype/complaint/test_complaint.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+import unittest
+
+class TestComplaint(unittest.TestCase):
+ pass
diff --git a/erpnext/healthcare/doctype/consultation/__init__.py b/erpnext/healthcare/doctype/consultation/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/healthcare/doctype/consultation/consultation.js b/erpnext/healthcare/doctype/consultation/consultation.js
new file mode 100644
index 00000000000..15a1c7f2340
--- /dev/null
+++ b/erpnext/healthcare/doctype/consultation/consultation.js
@@ -0,0 +1,317 @@
+// Copyright (c) 2016, ESS LLP and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Consultation', {
+ setup: function(frm) {
+ frm.get_field('drug_prescription').grid.editable_fields = [
+ {fieldname: 'drug_code', columns: 2},
+ {fieldname: 'drug_name', columns: 2},
+ {fieldname: 'dosage', columns: 2},
+ {fieldname: 'period', columns: 2}
+ ];
+ frm.get_field('test_prescription').grid.editable_fields = [
+ {fieldname: 'test_code', columns: 2},
+ {fieldname: 'test_name', columns: 4},
+ {fieldname: 'test_comment', columns: 4}
+ ];
+ },
+ onload: function(frm){
+ if(frm.doc.patient){
+ frappe.call({
+ "method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail",
+ args: {
+ patient: frm.doc.patient
+ },
+ callback: function (data) {
+ var age = null;
+ if(data.message.dob){
+ age = calculate_age(data.message.dob);
+ }
+ frappe.model.set_value(frm.doctype,frm.docname, "patient_age", age);
+ show_details(data.message);
+ }
+ });
+ }
+ },
+ refresh: function(frm) {
+ refresh_field('drug_prescription');
+ refresh_field('test_prescription');
+
+ frm.add_custom_button(__('Medical Record'), function() {
+ if (frm.doc.patient) {
+ frappe.route_options = {"patient": frm.doc.patient};
+ frappe.set_route("medical_record");
+ } else {
+ frappe.msgprint("Please select Patient");
+ }
+ },"View");
+ frm.add_custom_button(__('Vital Signs'), function() {
+ btn_create_vital_signs(frm);
+ },"Create");
+ frm.add_custom_button(__('Medical Record'), function() {
+ create_medical_record(frm);
+ },"Create");
+
+ frm.set_query("patient", function () {
+ return {
+ filters: {"disabled": 0}
+ };
+ });
+ frm.set_query("drug_code", "drug_prescription", function() {
+ return {
+ filters: {
+ is_stock_item:'1'
+ }
+ };
+ });
+ frm.set_query("test_code", "test_prescription", function() {
+ return {
+ filters: {
+ is_billable:'1'
+ }
+ };
+ });
+ frm.set_query("medical_code", "codification_table", function() {
+ return {
+ filters: {
+ medical_code_standard: frappe.defaults.get_default("default_medical_code_standard")
+ }
+ };
+ });
+ frm.set_query("appointment", function() {
+ return {
+ filters: {
+ // Scheduled filter for demo ...
+ status:['in',["Open","Scheduled"]]
+ }
+ };
+ });
+ if(!frm.doc.__islocal && !frm.doc.invoice && (frappe.user.has_role("Accounts User"))){
+ frm.add_custom_button(__('Invoice'), function() {
+ btn_invoice_consultation(frm);
+ },__("Create"));
+ }
+ frm.set_df_property("appointment", "read_only", frm.doc.__islocal ? 0:1);
+ frm.set_df_property("patient", "read_only", frm.doc.__islocal ? 0:1);
+ frm.set_df_property("patient_age", "read_only", frm.doc.__islocal ? 0:1);
+ frm.set_df_property("patient_sex", "read_only", frm.doc.__islocal ? 0:1);
+ frm.set_df_property("type", "read_only", frm.doc.__islocal ? 0:1);
+ frm.set_df_property("physician", "read_only", frm.doc.__islocal ? 0:1);
+ frm.set_df_property("visit_department", "read_only", frm.doc.__islocal ? 0:1);
+ frm.set_df_property("consultation_date", "read_only", frm.doc.__islocal ? 0:1);
+ frm.set_df_property("consultation_time", "read_only", frm.doc.__islocal ? 0:1);
+ }
+});
+
+var btn_invoice_consultation = function(frm){
+ var doc = frm.doc;
+ frappe.call({
+ method:
+ "erpnext.healthcare.doctype.consultation.consultation.create_invoice",
+ args: {company: doc.company, patient: doc.patient, physician: doc.physician, consultation_id: doc.name },
+ callback: function(data){
+ if(!data.exc){
+ if(data.message){
+ frappe.set_route("Form", "Sales Invoice", data.message);
+ }
+ cur_frm.reload_doc();
+ }
+ }
+ });
+};
+
+var create_medical_record = function (frm) {
+ if(!frm.doc.patient){
+ frappe.throw("Please select patient");
+ }
+ frappe.route_options = {
+ "patient": frm.doc.patient,
+ "status": "Open",
+ "reference_doctype": "Patient Medical Record",
+ "reference_owner": frm.doc.owner
+ };
+ frappe.new_doc("Patient Medical Record");
+};
+
+var btn_create_vital_signs = function (frm) {
+ if(!frm.doc.patient){
+ frappe.throw("Please select patient");
+ }
+ frappe.route_options = {
+ "patient": frm.doc.patient,
+ };
+ frappe.new_doc("Vital Signs");
+};
+
+var show_details = function(data){
+ var personal_details = "";
+ var age = null;
+ if(data.dob){
+ age = calculate_age(data.dob);
+ personal_details += "{%= __("Select Patient") %}
+ +| \n {%- if row.drug_name -%}{{ row.drug_name }}{%- endif -%}\n | \n \t\n {%- if row.dosage -%}{{ row.dosage }}{%- endif -%}\n | \n \t\n {%- if row.period -%}{{ row.period }}{%- endif -%}\n\t\t | \n\n\t\t\t \n {%- if row.comment -%}{{ row.comment }}{%- endif -%}\n \n\t\t | \n
| \n {%- if row.test_name -%}{{ row.test_name }}{%- endif -%}\n | \n\n\t\t\t \n {%- if row.test_comment -%}{{ row.test_comment }}{%- endif -%}\n \n\t\t | \n
| Name of Test | \nResult | \nNormal Range | \n
|---|---|---|
| {{ doc.test_name }} | ||
| \n {%- if doc.normal_test_items|length > 1 %} {%- endif -%}\n {%- if row.test_name -%}{{ row.test_name }}\n {%- else -%} {%- endif -%}\n {%- if row.test_event -%} {{ row.test_event }}{%- endif -%}\n | \n\n\n {%- if row.result_value -%}{{ row.result_value }}{%- endif -%} \n {%- if row.test_uom -%}{{ row.test_uom }}{%- endif -%}\n | \n\n\n \n {%- if row.normal_range -%}{{ row.normal_range }}{%- endif -%}\n \n | \n
| Name of Test | \nResult | \n
|---|---|
| {{ doc.test_name }} | |
| {{ row.test_particulars }} | \n\n {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}\n | \n
| Antibiotic | \nSensitivity | \n
| {{ row.antibiotic }} | \n{{ row.antibiotic_sensitivity }} | \n
| {{doc.name}} {{doc.patient}} \n{% if doc.patient_age %}{{doc.patient_age}}, {% endif %} {% if doc.patient_sex %}{{doc.patient_sex}}{% endif %} {% if doc.collected_time %}{{doc.collected_time}} {% endif %} {% if doc.collected_by %} {{doc.collected_by}} {% endif %} | \n{% if column == 0 %}{% set column = column+1 %}\n{% elif column == 2%}
| Student | -Student Name | - {% for c in criteria %} -{{ c.assessment_criteria }} | - {% endfor %} -Total Marks | - -|
|---|---|---|---|---|
| {{ c.maximum_score }} | - {% endfor %} -{{max_total_score}} | -|||
| {{ s.student }} | -{{ s.student_name }} | - {% for c in criteria %} -- - | - {% endfor %} -- {% if(s.assessment_details) { %} {{s.assessment_details.total_score}} {% } %} - | -|
| Student | +Student Name | + {% for c in criteria %} +{{ c.assessment_criteria }} | + {% endfor %} +Comments | +Total Marks | + +
| Score ({{ c.maximum_score }}) | + {% endfor %} +Score ({{max_total_score}}) | +|||
| {{ s.student }} | +{{ s.student_name }} | + {% for c in criteria %} ++ + {% if(s.assessment_details) { %} + {{s.assessment_details[c.assessment_criteria][1]}} + {% } %} + + + | + {% endfor %} ++ + | + + {% if(s.assessment_details) { %} + {{s.assessment_details.total_score[1]}} + {% } %} + + + {% if(s.assessment_details) { %} + {{s.assessment_details.total_score[0]}} + {% } %} + + + + + + + | +
An error occured while creating recurring {{ type }} {{ name }} for {{ party }}.
This could be because of some invalid Email Addresses in the {{ type }}.
-To stop sending repetitive error notifications from the system, we have unchecked -"Convert into Recurring" field in the {{ type }} {{ name }}.
-Please correct the {{ type }} and make the {{ type }} recurring again.
+To stop sending repetitive error notifications from the system, we have checked "Disabled" field in the subscription {{ subscription}} for the {{ type }} {{ name }}.
+Please correct the {{ type }} and unchcked "Disabled" in the {{ subscription }} for making recurring again.
It is necessary to take this action today itself for the above mentioned recurring {{ type }} to be generated. If delayed, you will have to manually change the "Repeat on Day of Month" field -of this {{ type }} for generating the recurring {{ type }}.
+of this {{ type }} for generating the recurring {{ type }} in the subscription {{ subscription }}.[This email is autogenerated]
diff --git a/erpnext/templates/includes/healthcare/appointment_row_template.html b/erpnext/templates/includes/healthcare/appointment_row_template.html new file mode 100644 index 00000000000..53be5e67647 --- /dev/null +++ b/erpnext/templates/includes/healthcare/appointment_row_template.html @@ -0,0 +1,23 @@ + diff --git a/erpnext/templates/includes/healthcare/lab_test_row_template.html b/erpnext/templates/includes/healthcare/lab_test_row_template.html new file mode 100644 index 00000000000..d6c9b54b09c --- /dev/null +++ b/erpnext/templates/includes/healthcare/lab_test_row_template.html @@ -0,0 +1,20 @@ + diff --git a/erpnext/templates/includes/healthcare/prescription_row_template.html b/erpnext/templates/includes/healthcare/prescription_row_template.html new file mode 100644 index 00000000000..13ce3bc16b8 --- /dev/null +++ b/erpnext/templates/includes/healthcare/prescription_row_template.html @@ -0,0 +1,15 @@ + diff --git a/erpnext/templates/print_formats/includes/taxes.html b/erpnext/templates/print_formats/includes/taxes.html index b7827635afa..41f216e7b43 100644 --- a/erpnext/templates/print_formats/includes/taxes.html +++ b/erpnext/templates/print_formats/includes/taxes.html @@ -1,7 +1,7 @@ {%- macro render_discount_amount(doc) -%} {%- if doc.discount_amount -%}No Item found
-