Compare commits

..

8 Commits

Author SHA1 Message Date
Brown-Harry Boma
40a43d3260 Replace create_custom_fields with create_custom_field (#11420) 2017-11-02 17:58:05 +05:30
Brown-Harry Boma
a829b3cc82 v8.x.x Allow Doctypes with space in name to be filtered in General Ledger (#11264)
* Set transaction type in pricing rule only if unavailable

* Use scrub instead for party_type with space
2017-10-25 11:58:45 +05:30
Brown-Harry Boma
757c2f692b [Fix]Setup Wizard Errors (#11289) 2017-10-25 11:52:08 +05:30
Brown-Harry Boma
85a9e2ed28 Check credit or debit in_account_currency is set before setting (#11253)
* Check credit or debit in_account_currency is set before setting

* Add paying party option to confirm custom doctype can pay
2017-10-21 11:25:40 +05:30
Brown-Harry Boma
f55a33890f Set transaction type in pricing rule only if unavailable (#11228) 2017-10-18 11:07:26 +05:30
Prateeksha Singh
ec992df81a [fix] Check for stock_qty, else use qty (#10937) 2017-09-27 18:33:01 +05:30
Prateeksha Singh
6f191eda99 [fix] batch qty checked against stock_qty field (#10906) 2017-09-27 15:34:23 +05:30
rohitwaghchaure
3318926b23 [hotfix] Wrong calculation of total in taxes and totals (#10924) 2017-09-27 13:32:27 +05:30
42 changed files with 374 additions and 586 deletions

View File

@@ -4,7 +4,7 @@ import inspect
import frappe
from erpnext.hooks import regional_overrides
__version__ = '9.0.7'
__version__ = '8.11.6'
def get_default_company(user=None):
'''Get default company for user'''

View File

@@ -765,7 +765,6 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
pe.append("references", {
"reference_doctype": dt,
"reference_name": dn,
"bill_no": doc.get("bill_no"),
"due_date": doc.get("due_date"),
"total_amount": grand_total,
"outstanding_amount": outstanding_amount,

View File

@@ -30,8 +30,7 @@ class PaymentReconciliation(Document):
return payment_entries
def get_jv_entries(self):
dr_or_cr = "credit_in_account_currency" if self.party_type == "Customer" \
else "debit_in_account_currency"
dr_or_cr = self.get_dr_or_cr()
bank_account_condition = "t2.against_account like %(bank_cash_account)s" \
if self.bank_cash_account else "1=1"
@@ -73,13 +72,13 @@ class PaymentReconciliation(Document):
row = self.append('payments', {})
row.update(e)
def get_invoice_entries(self):
def get_invoice_entries(self, paying_party=False):
#Fetch JVs, Sales and Purchase Invoices for 'invoices' to reconcile against
condition = self.check_condition()
non_reconciled_invoices = get_outstanding_invoices(self.party_type, self.party,
self.receivable_payable_account, condition=condition)
self.receivable_payable_account, condition=condition, paying_party=paying_party)
self.add_invoice_entries(non_reconciled_invoices)
@@ -103,8 +102,7 @@ class PaymentReconciliation(Document):
self.get_invoice_entries()
self.validate_invoice()
dr_or_cr = "credit_in_account_currency" \
if self.party_type == "Customer" else "debit_in_account_currency"
dr_or_cr = self.get_dr_or_cr()
lst = []
for e in self.get('payments'):
@@ -184,3 +182,12 @@ class PaymentReconciliation(Document):
cond += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_amount))
return cond
def get_dr_or_cr(self):
'''Return credit_in_account_currency if not set and party is customer.'''
if hasattr(self, "dr_or_cr"):
return self.dr_or_cr
if self.party_type == 'Customer':
return "credit_in_account_currency"
else:
return "debit_in_account_currency"

View File

@@ -1023,7 +1023,7 @@
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"precision": "2",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -1284,7 +1284,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-09-27 08:31:38.432574",
"modified": "2017-08-31 16:34:41.614743",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Pricing Rule",

View File

@@ -348,6 +348,7 @@ def apply_internal_priority(pricing_rules, field_set, args):
return filtered_rules or pricing_rules
def set_transaction_type(args):
if args.transaction_type:return
if args.doctype in ("Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"):
args.transaction_type = "selling"
elif args.doctype in ("Material Request", "Supplier Quotation", "Purchase Order",

View File

@@ -417,7 +417,6 @@ def make_contact(args,customer):
'link_doctype': 'Customer',
'link_name': customer
})
doc.flags.ignore_mandatory = True
doc.save(ignore_permissions=True)
def make_address(args, customer):
@@ -442,7 +441,6 @@ def make_address(args, customer):
address.is_primary_address = 1
address.is_shipping_address = 1
address.update(args)
address.flags.ignore_mandatory = True
address.save(ignore_permissions = True)
def make_email_queue(email_queue):

View File

@@ -699,7 +699,7 @@
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"precision": "2",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -2166,7 +2166,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-09-27 08:31:37.827893",
"modified": "2017-07-17 17:54:48.246507",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",

View File

@@ -135,6 +135,66 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "disabled",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Disabled",
"length": 0,
"no_copy": 1,
"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": "submit_on_creation",
"fieldtype": "Check",
"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": "Submit on Creation",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -226,12 +286,12 @@
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "submit_on_creation",
"fieldtype": "Check",
"fieldname": "next_schedule_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -239,44 +299,14 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Submit on Creation",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "disabled",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Disabled",
"label": "Next Schedule Date",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -290,7 +320,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_10",
"fieldname": "frequency_detail",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -299,95 +329,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "from_date",
"fieldtype": "Date",
"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": "From Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "to_date",
"fieldtype": "Date",
"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": "To Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_13",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -433,6 +375,35 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_12",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
@@ -464,36 +435,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "next_schedule_date",
"fieldtype": "Date",
"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": "Next Schedule Date",
"length": 0,
"no_copy": 1,
"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,
@@ -749,7 +690,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-10-03 17:20:26.919630",
"modified": "2017-09-14 12:09:38.471458",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Subscription",
@@ -759,7 +700,7 @@
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 1,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
@@ -779,7 +720,7 @@
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 1,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
@@ -799,7 +740,7 @@
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 1,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,

View File

@@ -9,7 +9,7 @@ from frappe import _
from frappe.desk.form import assign_to
from dateutil.relativedelta import relativedelta
from frappe.utils.user import get_system_managers
from frappe.utils import cstr, getdate, split_emails, add_days, today, get_last_day, get_first_day
from frappe.utils import cstr, getdate, split_emails, add_days, today
from frappe.model.document import Document
month_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, 'Yearly': 12}
@@ -24,23 +24,12 @@ class Subscription(Document):
self.set_next_schedule_date()
def on_submit(self):
# self.update_subscription_id()
self.update_subscription_data()
self.update_subscription_id()
def on_update_after_submit(self):
self.update_subscription_data()
self.validate_dates()
self.set_next_schedule_date()
def before_cancel(self):
self.unlink_subscription_id()
def unlink_subscription_id(self):
doc = frappe.get_doc(self.reference_doctype, self.reference_document)
if doc.meta.get_field('subscription'):
doc.subscription = None
doc.db_update()
def validate_dates(self):
if self.end_date and getdate(self.start_date) > getdate(self.end_date):
frappe.throw(_("End date must be greater than start date"))
@@ -75,21 +64,6 @@ class Subscription(Document):
self.next_schedule_date = get_next_schedule_date(self.start_date,
self.frequency, self.repeat_on_day)
def update_subscription_data(self):
update_doc = False
doc = frappe.get_doc(self.reference_doctype, self.reference_document)
if frappe.get_meta(self.reference_doctype).get_field("from_date"):
doc.from_date = self.from_date
doc.to_date = self.to_date
update_doc = True
if not doc.subscription:
doc.subscription = self.name
update_doc = True
if update_doc:
doc.db_update()
def update_subscription_id(self):
doc = frappe.get_doc(self.reference_doctype, self.reference_document)
if not doc.meta.get_field('subscription'):
@@ -138,9 +112,6 @@ def get_subscription_entries(date):
def create_documents(data, schedule_date):
try:
doc = make_new_document(data, schedule_date)
if doc.from_date:
update_subscription_period(data, doc)
if data.notify_by_email and data.recipients:
print_format = data.print_format or "Standard"
send_notification(doc, print_format, data.recipients)
@@ -155,13 +126,6 @@ def create_documents(data, schedule_date):
if data.reference_document and not frappe.flags.in_test:
notify_error_to_user(data)
def update_subscription_period(data, doc):
from_date = doc.from_date
to_date = doc.to_date
frappe.db.set_value('Subscription', data.name, 'from_date', from_date)
frappe.db.set_value('Subscription', data.name, 'to_date', to_date)
def disabled_subscription(data):
subscription = frappe.get_doc('Subscription', data.name)
subscription.db_set('disabled', 1)
@@ -196,24 +160,9 @@ def update_doc(new_document, reference_doc, args, schedule_date):
if new_document.meta.get_field('set_posting_time'):
new_document.set('set_posting_time', 1)
mcount = month_map.get(args.frequency)
if new_document.meta.get_field('subscription'):
new_document.set('subscription', args.name)
if args.from_date and args.to_date:
from_date = get_next_date(args.from_date, mcount)
if (cstr(get_first_day(args.from_date)) == cstr(args.from_date)) and \
(cstr(get_last_day(args.to_date)) == cstr(args.to_date)):
to_date = get_last_day(get_next_date(args.to_date, mcount))
else:
to_date = get_next_date(args.to_date, mcount)
if new_document.meta.get_field('from_date'):
new_document.set('from_date', from_date)
new_document.set('to_date', to_date)
new_document.run_method("on_recurring", reference_doc=reference_doc, subscription_doc=args)
for data in new_document.meta.fields:
if data.fieldtype == 'Date' and data.reqd:

View File

@@ -8,7 +8,6 @@ from frappe import _
from frappe.model.document import Document
from frappe.utils import cstr, cint
from frappe.contacts.doctype.address.address import get_default_address
from frappe.utils.nestedset import get_root_of
from erpnext.setup.doctype.customer_group.customer_group import get_parent_customer_groups
class IncorrectCustomerGroup(frappe.ValidationError): pass
@@ -137,7 +136,7 @@ def get_tax_template(posting_date, args):
if key=="use_for_shopping_cart":
conditions.append("use_for_shopping_cart = {0}".format(1 if value else 0))
if key == 'customer_group':
if not value: value = get_root_of("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:

View File

@@ -113,7 +113,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
});
this.page.add_menu_item(__("Sync Offline Invoices"), function () {
me.freeze_screen = true;
me.sync_sales_invoice()
});
@@ -1685,7 +1684,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
set_interval_for_si_sync: function () {
var me = this;
setInterval(function () {
me.freeze_screen = false;
me.sync_sales_invoice()
}, 60000)
},
@@ -1699,12 +1697,9 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.freeze = this.customer_doc.display
}
freeze_screen = this.freeze_screen || false;
if ((this.si_docs.length || this.email_queue_list || this.customers_list) && !this.freeze) {
frappe.call({
method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
freeze: freeze_screen,
args: {
doc_list: me.si_docs,
email_queue_list: me.email_queue_list,

View File

@@ -320,15 +320,11 @@ def set_taxes(party, party_type, posting_date, company, customer_group=None, sup
from erpnext.accounts.doctype.tax_rule.tax_rule import get_tax_template, get_party_details
args = {
party_type.lower(): party,
"customer_group": customer_group,
"supplier_type": supplier_type,
"company": company
}
if customer_group:
args['customer_group'] = customer_group
if supplier_type:
args['supplier_type'] = supplier_type
if billing_address or shipping_address:
args.update(get_party_details(party, party_type, {"billing_address": billing_address, \
"shipping_address": shipping_address }))

View File

@@ -83,7 +83,7 @@ frappe.query_reports["General Ledger"] = {
return;
}
var fieldname = party_type.toLowerCase() + "_name";
var fieldname = frappe.model.scrub(party_type)+"_name";
frappe.db.get_value(party_type, party, fieldname, function(value) {
frappe.query_report_filters_by_name.party_name.set_value(value[fieldname]);
});

View File

@@ -569,11 +569,11 @@ def get_stock_rbnb_difference(posting_date, company):
# Amount should be credited
return flt(stock_rbnb) + flt(sys_bal)
def get_outstanding_invoices(party_type, party, account, condition=None):
def get_outstanding_invoices(party_type, party, account, condition=None, paying_party=False):
outstanding_invoices = []
precision = frappe.get_precision("Sales Invoice", "outstanding_amount")
if party_type=="Customer":
if party_type=="Customer" or paying_party:
dr_or_cr = "debit_in_account_currency - credit_in_account_currency"
payment_dr_or_cr = "payment_gl_entry.credit_in_account_currency - payment_gl_entry.debit_in_account_currency"
else:

View File

@@ -2,29 +2,29 @@
// For license information, please see license.txt
frappe.query_reports["Quoted Item Comparison"] = {
filters: [
"filters": [
{
fieldtype: "Link",
label: __("Supplier Quotation"),
options: "Supplier Quotation",
fieldname: "supplier_quotation",
default: "",
get_query: () => {
"fieldname": "supplier_quotation",
"label": __("Supplier Quotation"),
"fieldtype": "Link",
"options": "Supplier Quotation",
"default": "",
"get_query": function () {
return { filters: { "docstatus": ["<", 2] } }
}
},
{
reqd: 1,
default: "",
options: "Item",
label: __("Item"),
fieldname: "item",
fieldtype: "Link",
get_query: () => {
let quote = frappe.query_report_filters_by_name.supplier_quotation.get_value();
"fieldname": "item",
"label": __("Item"),
"fieldtype": "Link",
"options": "Item",
"default": "",
"reqd": 1,
"get_query": function () {
var quote = frappe.query_report_filters_by_name.supplier_quotation.get_value();
if (quote != "") {
return {
query: "erpnext.stock.doctype.quality_inspection.quality_inspection.item_query",
query: "erpnext.buying.doctype.quality_inspection.quality_inspection.item_query",
filters: {
"from": "Supplier Quotation Item",
"parent": quote
@@ -39,50 +39,47 @@ frappe.query_reports["Quoted Item Comparison"] = {
}
}
],
onload: (report) => {
onload: function (report) {
// Create a button for setting the default supplier
report.page.add_inner_button(__("Select Default Supplier"), () => {
let reporter = frappe.query_reports["Quoted Item Comparison"];
report.page.add_inner_button(__("Select Default Supplier"), function () {
var reporter = frappe.query_reports["Quoted Item Comparison"];
//Always make a new one so that the latest values get updated
reporter.make_default_supplier_dialog(report);
report.dialog.show();
setTimeout(function () { report.dialog.input.focus(); }, 1000);
}, 'Tools');
},
make_default_supplier_dialog: (report) => {
"make_default_supplier_dialog": function (report) {
// Get the name of the item to change
if(!report.data) return;
let filters = report.get_values();
let item_code = filters.item;
var filters = report.get_values();
var item_code = filters.item;
// Get a list of the suppliers (with a blank as well) for the user to select
let suppliers = $.map(report.data, (row, idx)=>{ return row.supplier_name })
var select_options = "";
for (let supplier of report.data) {
select_options += supplier.supplier_name + '\n'
}
// Create a dialog window for the user to pick their supplier
let dialog = new frappe.ui.Dialog({
var d = new frappe.ui.Dialog({
title: __('Select Default Supplier'),
fields: [
{
reqd: 1,
label: 'Supplier',
fieldtype: 'Link',
options: 'Supplier',
fieldname: 'supplier',
get_query: () => {
return {
filters: {
'name': ['in', suppliers]
}
}
}
}
{ fieldname: 'supplier', fieldtype: 'Select', label: 'Supplier', reqd: 1, options: select_options },
{ fieldname: 'ok_button', fieldtype: 'Button', label: 'Set Default Supplier' },
]
});
dialog.set_primary_action("Set Default Supplier", () => {
let values = dialog.get_values();
if(values) {
// On the user clicking the ok button
d.fields_dict.ok_button.input.onclick = function () {
var btn = d.fields_dict.ok_button.input;
var v = report.dialog.get_values();
if (v) {
$(btn).set_working();
// Set the default_supplier field of the appropriate Item to the selected supplier
frappe.call({
method: "frappe.client.set_value",
@@ -90,17 +87,17 @@ frappe.query_reports["Quoted Item Comparison"] = {
doctype: "Item",
name: item_code,
fieldname: "default_supplier",
value: values.supplier,
value: v.supplier,
},
freeze: true,
callback: (r) => {
callback: function (r) {
$(btn).done_working();
frappe.msgprint("Successfully Set Supplier");
dialog.hide();
report.dialog.hide();
}
});
}
});
dialog.show();
}
report.dialog = d;
}
}

View File

@@ -8,55 +8,53 @@ import frappe
def execute(filters=None):
qty_list = get_quantity_list(filters.item)
data = get_quote_list(filters.item, qty_list)
columns = get_columns(qty_list)
return columns, data
def get_quote_list(item, qty_list):
out = []
if not item:
return []
suppliers = []
price_data = []
company_currency = frappe.db.get_default("currency")
float_precision = cint(frappe.db.get_default("float_precision")) or 2
# Get the list of suppliers
for root in frappe.db.sql("""select parent, qty, rate from `tabSupplier Quotation Item`
where item_code=%s and docstatus < 2""", item, as_dict=1):
for splr in frappe.db.sql("""select supplier from `tabSupplier Quotation`
where name =%s and docstatus < 2""", root.parent, as_dict=1):
ip = frappe._dict({
if item:
price_data = []
suppliers = []
company_currency = frappe.db.get_default("currency")
float_precision = cint(frappe.db.get_default("float_precision")) or 2
# Get the list of suppliers
for root in frappe.db.sql("""select parent, qty, rate from `tabSupplier Quotation Item` where item_code=%s and docstatus < 2""", item, as_dict=1):
for splr in frappe.db.sql("""SELECT supplier from `tabSupplier Quotation` where name =%s and docstatus < 2""", root.parent, as_dict=1):
ip = frappe._dict({
"supplier": splr.supplier,
"qty": root.qty,
"parent": root.parent,
"rate": root.rate
"rate": root.rate})
price_data.append(ip)
suppliers.append(splr.supplier)
#Add a row for each supplier
for root in set(suppliers):
supplier_currency = frappe.db.get_value("Supplier", root, "default_currency")
if supplier_currency:
exchange_rate = get_exchange_rate(supplier_currency, company_currency)
else:
exchange_rate = 1
row = frappe._dict({
"supplier_name": root
})
price_data.append(ip)
suppliers.append(splr.supplier)
#Add a row for each supplier
for root in set(suppliers):
supplier_currency = frappe.db.get_value("Supplier", root, "default_currency")
if supplier_currency:
exchange_rate = get_exchange_rate(supplier_currency, company_currency)
else:
exchange_rate = 1
row = frappe._dict({
"supplier_name": root
})
for col in qty_list:
# Get the quantity for this row
for item_price in price_data:
if str(item_price.qty) == col.key and item_price.supplier == root:
row[col.key] = flt(item_price.rate * exchange_rate, float_precision)
row[col.key + "QUOTE"] = item_price.parent
break
else:
row[col.key] = ""
row[col.key + "QUOTE"] = ""
out.append(row)
for col in qty_list:
# Get the quantity for this row
for item_price in price_data:
if str(item_price.qty) == col.key and item_price.supplier == root:
row[col.key] = flt(item_price.rate * exchange_rate, float_precision)
row[col.key + "QUOTE"] = item_price.parent
break
else:
row[col.key] = ""
row[col.key + "QUOTE"] = ""
out.append(row)
return out
@@ -64,8 +62,7 @@ def get_quantity_list(item):
out = []
if item:
qty_list = frappe.db.sql("""select distinct qty from `tabSupplier Quotation Item`
where ifnull(item_code,'')=%s and docstatus < 2""", item, as_dict=1)
qty_list = frappe.db.sql("""select distinct qty from `tabSupplier Quotation Item` where ifnull(item_code,'')=%s and docstatus < 2""", item, as_dict=1)
qty_list.sort(reverse=False)
for qt in qty_list:
col = frappe._dict({
@@ -101,4 +98,4 @@ def get_columns(qty_list):
"width": 90
})
return columns
return columns

View File

@@ -1,4 +1,4 @@
- POS - Online & Offline
#### POS
- Now user has an option to enable or disable Offline POS mode from POS Settings
- Provision to select the Item's serial number from the dropdown while adding item in the cart
- Indicator for stock availability in Online POS Mode.
@@ -6,25 +6,3 @@
#### Subscription
- Setup recurring documents using **Subscription**
- User can schedule the subscription for doctypes other than Sales Invoice, Purchase Invoice etc.
#### Healthcare Domain
- Clinic / Practice Management
- Patient
- Physician, Physician scheduling
- Appointment
- Vital Signs
- Consultation
- Medical Code Standards
- Patient Medical Record
- Laboratory
- Sample Collection
- Lab Test
- Patient Portal
#### School Fees Management
- Fee Structure
- Fee Schedule
- Payment against Fees
#### Setup Wizard
- Broken into 2 parts with a fresh looks

View File

@@ -195,7 +195,7 @@ def copy_attributes_to_variant(item, variant):
if variant.attributes:
variant.description += "\n"
for d in variant.attributes:
variant.description += "<div>" + d.attribute + ": " + cstr(d.attribute_value) + "</div>"
variant.description += "<p>" + d.attribute + ": " + cstr(d.attribute_value) + "</p>"
def make_variant_item_code(template_item_code, template_item_name, variant):
"""Uses template's item code and abbreviations to make variant's item code"""

View File

@@ -81,7 +81,7 @@ website_route_rules = [
{"from_route": "/supplier-quotations/<path:name>", "to_route": "order",
"defaults": {
"doctype": "Supplier Quotation",
"parents": [{"label": _("Supplier Quotation"), "route": "supplier-quotations"}]
"parents": [{"label": _("Supplier Quotation"), "route": "quotations"}]
}
},
{"from_route": "/quotations", "to_route": "Quotation"},

View File

@@ -36,7 +36,7 @@ def execute(filters=None):
status_map = {"Present": "P", "Absent": "A", "Half Day": "HD", "On Leave": "L", "None": "", "Holiday":"<b>H</b>"}
if status == "None" and holiday_map:
emp_holiday_list = emp_det.holiday_list if emp_det.holiday_list else default_holiday_list
if emp_holiday_list in holiday_map and (day+1) in holiday_map[emp_holiday_list]:
if (day+1) in holiday_map[emp_holiday_list]:
status = "Holiday"
row.append(status_map[status])
@@ -45,7 +45,7 @@ def execute(filters=None):
elif status == "Absent":
total_a += 1
elif status == "On Leave":
total_l += 1
total_l += 1
elif status == "Half Day":
total_p += 0.5
total_a += 0.5

View File

@@ -95,8 +95,8 @@ class BOM(WebsiteGenerator):
self.validate_bom_currecny(item)
ret = self.get_bom_material_detail({
"item_code": item.item_code,
"item_name": item.item_name,
"item_code": item.item_code,
"item_name": item.item_name,
"bom_no": item.bom_no,
"stock_qty": item.stock_qty
})
@@ -312,7 +312,7 @@ class BOM(WebsiteGenerator):
li.append("{0} on row {1}".format(i.item_code, i.idx))
duplicate_list = '<br>' + '<br>'.join(li)
frappe.throw(_("Same item has been entered multiple times. {0}").format(duplicate_list))
frappe.throw(_("Same item has been entered multiple times. {list}").format(list=duplicate_list))
def check_recursion(self):
""" Check whether recursion occurs in any bom"""
@@ -346,7 +346,7 @@ class BOM(WebsiteGenerator):
count = 0
if not bom_list:
bom_list = []
if self.name not in bom_list:
bom_list.append(self.name)

View File

@@ -51,9 +51,9 @@ class ProductionOrder(Document):
def validate_sales_order(self):
if self.sales_order:
so = frappe.db.sql("""
select so.name, so_item.delivery_date, so.project
select so.name, so_item.delivery_date, so.project
from `tabSales Order` so, `tabSales Order Item` so_item
where so.name=%s and so.name=so_item.parent
where so.name=%s and so.name=so_item.parent
and so.docstatus = 1 and so_item.item_code=%s
""", (self.sales_order, self.production_item), as_dict=1)
@@ -112,7 +112,7 @@ class ProductionOrder(Document):
allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings",
"over_production_allowance_percentage"))
if total_qty > so_qty + (allowance_percentage/100 * so_qty):
frappe.throw(_("Cannot produce more Item {0} than Sales Order quantity {1}")
.format(self.production_item, so_qty), OverProductionError)
@@ -217,27 +217,27 @@ class ProductionOrder(Document):
def set_production_order_operations(self):
"""Fetch operations from BOM and set in 'Production Order'"""
self.set('operations', [])
if not self.bom_no \
or cint(frappe.db.get_single_value("Manufacturing Settings", "disable_capacity_planning")):
return
if self.use_multi_level_bom:
bom_list = frappe.get_doc("BOM", self.bom_no).traverse_tree()
else:
bom_list = [self.bom_no]
operations = frappe.db.sql("""
select
select
operation, description, workstation, idx,
base_hour_rate as hour_rate, time_in_mins,
base_hour_rate as hour_rate, time_in_mins,
"Pending" as status, parent as bom
from
`tabBOM Operation`
where
parent in (%s) order by idx
""" % ", ".join(["%s"]*len(bom_list)), tuple(bom_list), as_dict=1)
self.set('operations', operations)
self.calculate_time()
@@ -277,7 +277,7 @@ class ProductionOrder(Document):
timesheet.set('time_logs', [])
for i, d in enumerate(self.operations):
if d.status != 'Completed':
self.set_start_end_time_for_workstation(d, i)
@@ -370,8 +370,8 @@ class ProductionOrder(Document):
self.actual_start_date = None
self.actual_end_date = None
if self.get("operations"):
self.actual_start_date = min([d.actual_start_time for d in self.get("operations") if d.actual_start_time])
self.actual_end_date = max([d.actual_end_time for d in self.get("operations") if d.actual_end_time])
self.actual_start_date = min([d.actual_start_time for d in self.get("operations")])
self.actual_end_date = max([d.actual_end_time for d in self.get("operations")])
def delete_timesheet(self):
for timesheet in frappe.get_all("Timesheet", ["name"], {"production_order": self.name}):
@@ -411,18 +411,18 @@ class ProductionOrder(Document):
if d.source_warehouse:
stock_bin = get_bin(d.item_code, d.source_warehouse)
stock_bin.update_reserved_qty_for_production()
def get_items_and_operations_from_bom(self):
self.set_required_items()
self.set_production_order_operations()
return check_if_scrap_warehouse_mandatory(self.bom_no)
def set_available_qty(self):
for d in self.get("required_items"):
if d.source_warehouse:
d.available_qty_at_source_warehouse = get_latest_stock_qty(d.item_code, d.source_warehouse)
if self.wip_warehouse:
d.available_qty_at_wip_warehouse = get_latest_stock_qty(d.item_code, self.wip_warehouse)
@@ -439,7 +439,7 @@ class ProductionOrder(Document):
'required_qty': item.qty,
'source_warehouse': item.source_warehouse or item.default_warehouse
})
self.set_available_qty()
def update_transaferred_qty_for_required_items(self):
@@ -463,12 +463,12 @@ class ProductionOrder(Document):
def get_item_details(item, project = None):
res = frappe.db.sql("""
select stock_uom, description
from `tabItem`
where disabled=0
from `tabItem`
where disabled=0
and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s)
and name=%s
""", (nowdate(), item), as_dict=1)
if not res:
return {}
@@ -611,14 +611,14 @@ def make_new_timesheet(source_name, target_doc=None):
@frappe.whitelist()
def stop_unstop(production_order, status):
""" Called from client side on Stop/Unstop event"""
if not frappe.has_permission("Production Order", "write"):
frappe.throw(_("Not permitted"), frappe.PermissionError)
pro_order = frappe.get_doc("Production Order", production_order)
pro_order.update_status(status)
pro_order.update_planned_qty()
frappe.msgprint(_("Production Order has been {0}").format(status))
pro_order.notify_update()
return pro_order.status

View File

@@ -408,8 +408,6 @@ erpnext.patches.v8_0.update_stock_qty_value_in_bom_item
erpnext.patches.v8_0.update_sales_cost_in_project
erpnext.patches.v8_0.save_system_settings
erpnext.patches.v8_1.delete_deprecated_reports
erpnext.patches.v9_0.remove_subscription_module
erpnext.patches.v8_7.make_subscription_from_recurring_data
erpnext.patches.v8_1.setup_gst_india #2017-06-27
execute:frappe.reload_doc('regional', 'doctype', 'gst_hsn_code')
erpnext.patches.v8_1.removed_roles_from_gst_report_non_indian_account
@@ -434,16 +432,16 @@ erpnext.patches.v8_5.update_customer_group_in_POS_profile
erpnext.patches.v8_6.update_timesheet_company_from_PO
erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
erpnext.patches.v8_5.remove_project_type_property_setter
erpnext.patches.v8_7.add_more_gst_fields #21-09-2017
erpnext.patches.v8_7.add_more_gst_fields
erpnext.patches.v8_7.fix_purchase_receipt_status
erpnext.patches.v8_6.rename_bom_update_tool
erpnext.patches.v8_7.set_offline_in_pos_settings #11-09-17
erpnext.patches.v8_9.add_setup_progress_actions #08-09-2017 #26-09-2017
erpnext.patches.v8_9.add_setup_progress_actions #08-09-2017
erpnext.patches.v8_9.rename_company_sales_target_field
erpnext.patches.v8_8.set_bom_rate_as_per_uom
erpnext.patches.v9_0.remove_subscription_module
erpnext.patches.v8_7.make_subscription_from_recurring_data
erpnext.patches.v8_9.set_print_zero_amount_taxes
erpnext.patches.v8_9.set_default_customer_group
erpnext.patches.v8_9.remove_employee_from_salary_structure_parent
erpnext.patches.v8_9.delete_gst_doctypes_for_outside_india_accounts
erpnext.patches.v8_9.update_billing_gstin_for_indian_account
erpnext.patches.v9_0.fix_subscription_next_date

View File

@@ -8,15 +8,9 @@ from frappe.utils import today
def execute():
frappe.reload_doc('accounts', 'doctype', 'subscription')
frappe.reload_doc('selling', 'doctype', 'sales_order')
frappe.reload_doc('selling', 'doctype', 'quotation')
frappe.reload_doc('buying', 'doctype', 'purchase_order')
frappe.reload_doc('buying', 'doctype', 'supplier_quotation')
frappe.reload_doc('accounts', 'doctype', 'sales_invoice')
frappe.reload_doc('accounts', 'doctype', 'purchase_invoice')
frappe.reload_doc('stock', 'doctype', 'purchase_receipt')
frappe.reload_doc('stock', 'doctype', 'delivery_note')
frappe.reload_doc('accounts', 'doctype', 'journal_entry')
frappe.reload_doc('accounts', 'doctype', 'payment_entry')
for doctype in ['Sales Order', 'Sales Invoice',
'Purchase Invoice', 'Purchase Invoice']:

View File

@@ -9,27 +9,27 @@ def execute():
frappe.reload_doc("setup", "doctype", "setup_progress_action")
actions = [
{"action_name": "Add Company", "action_doctype": "Company", "min_doc_count": 1, "is_completed": 1,
{"action_name": _("Add Company"), "action_doctype": "Company", "min_doc_count": 1, "is_completed": 1,
"domains": '[]' },
{"action_name": "Set Sales Target", "action_doctype": "Company", "min_doc_count": 99,
{"action_name": _("Set Sales Target"), "action_doctype": "Company", "min_doc_count": 99,
"action_document": frappe.defaults.get_defaults().get("company") or '',
"action_field": "monthly_sales_target", "is_completed": 0,
"domains": '["Manufacturing", "Services", "Retail", "Distribution"]' },
{"action_name": "Add Customers", "action_doctype": "Customer", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Customers"), "action_doctype": "Customer", "min_doc_count": 1, "is_completed": 0,
"domains": '["Manufacturing", "Services", "Retail", "Distribution"]' },
{"action_name": "Add Suppliers", "action_doctype": "Supplier", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Suppliers"), "action_doctype": "Supplier", "min_doc_count": 1, "is_completed": 0,
"domains": '["Manufacturing", "Services", "Retail", "Distribution"]' },
{"action_name": "Add Products", "action_doctype": "Item", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Products"), "action_doctype": "Item", "min_doc_count": 1, "is_completed": 0,
"domains": '["Manufacturing", "Services", "Retail", "Distribution"]' },
{"action_name": "Add Programs", "action_doctype": "Program", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Programs"), "action_doctype": "Program", "min_doc_count": 1, "is_completed": 0,
"domains": '["Education"]' },
{"action_name": "Add Instructors", "action_doctype": "Instructor", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Instructors"), "action_doctype": "Instructor", "min_doc_count": 1, "is_completed": 0,
"domains": '["Education"]' },
{"action_name": "Add Courses", "action_doctype": "Course", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Courses"), "action_doctype": "Course", "min_doc_count": 1, "is_completed": 0,
"domains": '["Education"]' },
{"action_name": "Add Rooms", "action_doctype": "Room", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Rooms"), "action_doctype": "Room", "min_doc_count": 1, "is_completed": 0,
"domains": '["Education"]' },
{"action_name": "Add Users", "action_doctype": "User", "min_doc_count": 4, "is_completed": 0,
{"action_name": _("Add Users"), "action_doctype": "User", "min_doc_count": 4, "is_completed": 0,
"domains": '[]' }
]

View File

@@ -1,15 +0,0 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
company = frappe.get_all('Company', filters = {'country': 'India'})
if company:
for doctype in ['Sales Invoice', 'Delivery Note']:
frappe.db.sql(""" update `tab{0}`
set billing_address_gstin = (select gstin from `tabAddress`
where name = customer_address)
where customer_address is not null and customer_address != ''""".format(doctype))

View File

@@ -1,27 +0,0 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doctype('Subscription')
doctypes = ('Purchase Order', 'Sales Order', 'Purchase Invoice', 'Sales Invoice')
for data in frappe.get_all('Subscription', fields = ["name", "reference_doctype", "reference_document"],
filters = {'reference_doctype': ('in', doctypes)}):
doc = frappe.get_doc('Subscription', data.name)
fields = ['transaction_date']
if doc.reference_doctype in ['Sales Invoice', 'Purchase Invoice']:
fields = ['posting_date']
fields.extend(['from_date', 'to_date'])
reference_data = frappe.db.get_value(data.reference_doctype,
data.reference_document, fields, as_dict=1)
if reference_data:
doc.start_date = reference_data.get('posting_date') or reference_data.get('transaction_date')
doc.from_date = reference_data.get('from_date')
doc.to_date = reference_data.get('to_date')
doc.set_next_schedule_date()
doc.db_update()

View File

@@ -96,17 +96,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
if(this.show_dialog) {
let d = this.item;
if (d.has_serial_no && d.serial_no) {
this.dialog.set_value('serial_no', d.serial_no);
} else if (d.batch_no) {
this.dialog.fields_dict.batches.df.data.push({
'batch_no': d.batch_no,
'actual_qty': d.actual_qty,
'selected_qty': d.qty
});
this.dialog.fields_dict.batches.grid.refresh();
}
this.dialog.set_value('serial_no', d.serial_no);
}
this.dialog.show();
@@ -126,10 +116,8 @@ erpnext.SerialNoBatchSelector = Class.extend({
}
values.batches.map((batch, i) => {
if(!batch.selected_qty || batch.selected_qty === 0 ) {
if (!this.show_dialog) {
frappe.throw(__("Please select quantity on row " + (i+1)));
return false;
}
frappe.throw(__("Please select quantity on row " + (i+1)));
return false;
}
});
return true;
@@ -137,11 +125,9 @@ erpnext.SerialNoBatchSelector = Class.extend({
} else {
let serial_nos = values.serial_no || '';
if (!serial_nos || !serial_nos.replace(/\s/g, '').length) {
if (!this.show_dialog) {
frappe.throw(__("Please enter serial numbers for serialized item "
+ values.item_code));
return false;
}
frappe.throw(__("Please enter serial numbers for serialized item "
+ values.item_code));
return false;
}
return true;
}

View File

@@ -84,13 +84,34 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-09-29 14:38:52.220743",
"modified_by": "Administrator",
"modified": "2017-08-31 14:38:52.220743",
"modified_by": "ewdszx@ed.ews",
"module": "Regional",
"name": "GST HSN Code",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"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": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,

View File

@@ -83,13 +83,34 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2017-09-29 14:39:15.625952",
"modified_by": "Administrator",
"modified": "2017-08-31 14:39:15.625952",
"modified_by": "ewdszx@ed.ews",
"module": "Regional",
"name": "GST Settings",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 0,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe, os, json
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
from frappe.permissions import add_permission
from erpnext.regional.india import states
@@ -12,7 +12,7 @@ def setup(company=None, patch=True):
make_custom_fields()
add_permissions()
add_custom_roles_for_reports()
frappe.enqueue('erpnext.regional.india.setup.add_hsn_sac_codes')
add_hsn_sac_codes()
add_print_formats()
if not patch:
update_address_template()
@@ -47,14 +47,12 @@ def add_hsn_sac_codes():
def create_hsn_codes(data, code_field):
for d in data:
hsn_code = frappe.new_doc('GST HSN Code')
hsn_code.description = d["description"]
hsn_code.hsn_code = d[code_field]
hsn_code.name = d[code_field]
try:
if not frappe.db.exists("GST HSN Code", d[code_field]):
hsn_code = frappe.new_doc('GST HSN Code')
hsn_code.description = d["description"]
hsn_code.hsn_code = d[code_field]
hsn_code.name = d[code_field]
hsn_code.db_insert()
except frappe.DuplicateEntryError:
pass
def add_custom_roles_for_reports():
for report_name in ('GST Sales Register', 'GST Purchase Register',
@@ -72,6 +70,7 @@ def add_custom_roles_for_reports():
def add_permissions():
for doctype in ('GST HSN Code', 'GST Settings'):
add_permission(doctype, 'Accounts Manager', 0)
add_permission(doctype, 'All', 0)
def add_print_formats():
@@ -112,15 +111,12 @@ def make_custom_fields():
]
sales_invoice_gst_fields = [
dict(fieldname='billing_address_gstin', label='Billing Address GSTIN',
fieldtype='Data', insert_after='customer_address',
options='customer_address.gstin', print_hide=1),
dict(fieldname='customer_gstin', label='Customer GSTIN',
fieldtype='Data', insert_after='shipping_address',
options='shipping_address_name.gstin', print_hide=1),
dict(fieldname='place_of_supply', label='Place of Supply',
fieldtype='Data', insert_after='customer_gstin', print_hide=1,
options='shipping_address_name.gst_state_number', read_only=0),
options='shipping_address_name.gst_state_number', read_only=1),
dict(fieldname='company_gstin', label='Company GSTIN',
fieldtype='Data', insert_after='company_address',
options='company_address.gstin', print_hide=1)
@@ -152,7 +148,11 @@ def make_custom_fields():
'Purchase Invoice Item': [hsn_sac_field]
}
create_custom_fields(custom_fields)
for dt, data in custom_fields.iteritems():
for df in data:
create_custom_field(dt, df)
# create_custom_fields(custom_fields)
def make_fixtures():
docs = [

View File

@@ -8,7 +8,6 @@ from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register i
def execute(filters=None):
return _execute(filters, additional_table_columns=[
dict(fieldtype='Data', label='Customer GSTIN', width=120),
dict(fieldtype='Data', label='Billing Address GSTIN', width=140),
dict(fieldtype='Data', label='Company GSTIN', width=120),
dict(fieldtype='Data', label='Place of Supply', width=120),
dict(fieldtype='Data', label='Reverse Charge', width=120),
@@ -18,7 +17,6 @@ def execute(filters=None):
dict(fieldtype='Data', label='HSN Code', width=120)
], additional_query_columns=[
'customer_gstin',
'billing_address_gstin',
'company_gstin',
'place_of_supply',
'reverse_charge',

View File

@@ -8,7 +8,6 @@ from erpnext.accounts.report.sales_register.sales_register import _execute
def execute(filters=None):
return _execute(filters, additional_table_columns=[
dict(fieldtype='Data', label='Customer GSTIN', width=120),
dict(fieldtype='Data', label='Billing Address GSTIN', width=140),
dict(fieldtype='Data', label='Company GSTIN', width=120),
dict(fieldtype='Data', label='Place of Supply', width=120),
dict(fieldtype='Data', label='Reverse Charge', width=120),
@@ -17,7 +16,6 @@ def execute(filters=None):
dict(fieldtype='Data', label='E-Commerce GSTIN', width=130)
], additional_query_columns=[
'customer_gstin',
'billing_address_gstin',
'company_gstin',
'place_of_supply',
'reverse_charge',

View File

@@ -684,7 +684,7 @@
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"precision": "2",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -1583,7 +1583,7 @@
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-09-27 08:31:37.485134",
"modified": "2017-05-10 17:14:45.736424",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation Item",

View File

@@ -714,7 +714,7 @@
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"precision": "2",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -745,7 +745,7 @@
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"precision": "2",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
@@ -1963,7 +1963,7 @@
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-09-27 08:31:37.129537",
"modified": "2017-07-28 14:04:04.289428",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order Item",

View File

@@ -20,12 +20,6 @@ frappe.pages['point-of-sale'].on_page_load = function(wrapper) {
});
};
frappe.pages['point-of-sale'].refresh = function(wrapper) {
if (wrapper.pos) {
cur_frm = wrapper.pos.frm;
}
}
erpnext.pos.PointOfSale = class PointOfSale {
constructor(wrapper) {
this.wrapper = $(wrapper).find('.layout-main-section');
@@ -89,7 +83,6 @@ erpnext.pos.PointOfSale = class PointOfSale {
this.cart = new POSCart({
frm: this.frm,
wrapper: this.wrapper.find('.cart-container'),
pos_profile: this.pos_profile,
events: {
on_customer_change: (customer) => this.frm.set_value('customer', customer),
on_field_change: (item_code, field, value) => {
@@ -99,17 +92,6 @@ erpnext.pos.PointOfSale = class PointOfSale {
if (value == 'Pay') {
if (!this.payment) {
this.make_payment_modal();
} else {
const mop_field = this.payment.default_mop;
let amount = 0.0;
this.frm.doc.payments.map(p => {
if (p.mode_of_payment == mop_field) {
amount = p.amount;
return;
}
});
this.payment.dialog.set_value(mop_field, flt(amount));
}
this.payment.open_modal();
}
@@ -208,7 +190,6 @@ erpnext.pos.PointOfSale = class PointOfSale {
this.update_item_in_frm(item)
.then(() => {
// update cart
this.remove_item_from_cart(item);
this.update_cart_data(item);
});
}, true);
@@ -228,18 +209,12 @@ erpnext.pos.PointOfSale = class PointOfSale {
return this.frm.script_manager
.trigger('qty', item.doctype, item.name)
.then(() => {
if (field === 'qty') {
this.remove_item_from_cart(item);
if (field === 'qty' && value === 0) {
frappe.model.clear_doc(item.doctype, item.name);
}
});
}
remove_item_from_cart(item) {
if (item.qty === 0) {
frappe.model.clear_doc(item.doctype, item.name);
}
}
make_payment_modal() {
this.payment = new Payment({
frm: this.frm,
@@ -382,11 +357,10 @@ erpnext.pos.PointOfSale = class PointOfSale {
};
class POSCart {
constructor({frm, wrapper, pos_profile, events}) {
constructor({frm, wrapper, events}) {
this.frm = frm;
this.wrapper = wrapper;
this.events = events;
this.pos_profile = pos_profile;
this.make();
this.bind_events();
}
@@ -448,12 +422,6 @@ class POSCart {
this.$taxes_and_totals.html(this.get_taxes_and_totals());
this.numpad && this.numpad.reset_value();
this.customer_field.set_value("");
this.wrapper.find('.grand-total-value').text(
format_currency(this.frm.doc.grand_total, this.frm.currency));
const customer = this.frm.doc.customer || this.pos_profile.customer;
this.customer_field.set_value(customer);
}
get_grand_total() {
@@ -510,8 +478,6 @@ class POSCart {
}
update_taxes_and_totals() {
if (!this.frm.doc.taxes) { return; }
const currency = this.frm.doc.currency;
this.frm.refresh_field('taxes');
@@ -540,7 +506,6 @@ class POSCart {
}
make_customer_field() {
let customer = this.frm.doc.customer || this.pos_profile['customer'];
this.customer_field = frappe.ui.form.make_control({
df: {
fieldtype: 'Link',
@@ -548,6 +513,7 @@ class POSCart {
fieldname: 'customer',
options: 'Customer',
reqd: 1,
default: this.frm.doc.customer,
onchange: () => {
this.events.on_customer_change(this.customer_field.get_value());
}
@@ -555,10 +521,6 @@ class POSCart {
parent: this.wrapper.find('.customer-field'),
render_input: true
});
if (customer) {
this.customer_field.set_value(customer);
}
}
make_numpad() {
@@ -774,7 +736,7 @@ class POSCart {
this.wrapper.find('.discount_amount').on('change', (e) => {
frappe.model.set_value(this.frm.doctype, this.frm.docname,
'discount_amount', flt(e.target.value));
'discount_amount', e.target.value);
this.frm.trigger('discount_amount')
.then(() => {
let discount_wrapper = this.wrapper.find('.additional_discount_percentage');
@@ -949,7 +911,7 @@ class POSItems {
}
if(batch_no) {
this.events.update_cart(items[0].item_code,
'batch_no', batch_no);
'batch_no', serial_no);
this.search_field.set_value('');
}
});
@@ -1196,10 +1158,6 @@ class Payment {
const me = this;
let fields = this.frm.doc.payments.map(p => {
if (p.default) {
this.default_mop = p.mode_of_payment;
}
return {
fieldtype: 'Currency',
label: __(p.mode_of_payment),

View File

@@ -3,15 +3,12 @@
from __future__ import unicode_literals
import frappe, json
from frappe.utils.nestedset import get_root_of
@frappe.whitelist()
def get_items(start, page_length, price_list, item_group, search_value=""):
serial_no = ""
batch_no = ""
item_code = search_value
if not frappe.db.exists('Item Group', item_group):
item_group = get_root_of('Item Group')
if search_value:
# search serial no
@@ -34,7 +31,7 @@ def get_items(start, page_length, price_list, item_group, search_value=""):
ON
(item_det.item_code=i.name or item_det.item_code=i.variant_of)
where
i.disabled = 0 and i.has_variants = 0 and i.is_sales_item = 1
i.disabled = 0 and i.has_variants = 0
and i.item_group in (select name from `tabItem Group` where lft >= {lft} and rgt <= {rgt})
and (i.item_code like %(item_code)s
or i.item_name like %(item_code)s or i.barcode like %(item_code)s)

View File

@@ -1,6 +1,6 @@
from __future__ import unicode_literals
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
from frappe import _
@@ -21,11 +21,13 @@ def make_custom_fields():
'Sales Invoice': [
dict(fieldname='appointment', label='Patient Appointment',
fieldtype='Link', options='Patient Appointment',
insert_after='customer')
insert_after='customer',print_hide=0)
]
}
create_custom_fields(custom_fields)
for dt, data in custom_fields.iteritems():
for df in data:
create_custom_field(dt, df)
def create_medical_departments():
@@ -191,21 +193,21 @@ def create_healthcare_item_groups():
def create_lab_test_items():
records = [
{"doctype": "Item", "item_code": "MCH", "item_name": "MCH", "item_group": "Laboratory",
"stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
"stock_uom": "Unit", "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
{"doctype": "Item", "item_code": "LDL", "item_name": "LDL", "item_group": "Laboratory",
"stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
"stock_uom": "Unit", "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
{"doctype": "Item", "item_code": "GTT", "item_name": "GTT", "item_group": "Laboratory",
"stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
"stock_uom": "Unit", "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
{"doctype": "Item", "item_code": "HDL", "item_name": "HDL", "item_group": "Laboratory",
"stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
"stock_uom": "Unit", "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
{"doctype": "Item", "item_code": "BILT", "item_name": "BILT", "item_group": "Laboratory",
"stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
"stock_uom": "Unit", "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
{"doctype": "Item", "item_code": "BILD", "item_name": "BILD", "item_group": "Laboratory",
"stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
"stock_uom": "Unit", "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
{"doctype": "Item", "item_code": "BP", "item_name": "BP", "item_group": "Laboratory",
"stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
"stock_uom": "Unit", "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
{"doctype": "Item", "item_code": "BS", "item_name": "BS", "item_group": "Laboratory",
"stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1}
"stock_uom": "Unit", "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1}
]
insert_record(records)

View File

@@ -23,27 +23,27 @@ def install(country=None):
# Setup Progress
{'doctype': "Setup Progress", "actions": [
{"action_name": "Add Company", "action_doctype": "Company", "min_doc_count": 1, "is_completed": 1,
{"action_name": _("Add Company"), "action_doctype": "Company", "min_doc_count": 1, "is_completed": 1,
"domains": '[]' },
{"action_name": "Set Sales Target", "action_doctype": "Company", "min_doc_count": 99,
{"action_name": _("Set Sales Target"), "action_doctype": "Company", "min_doc_count": 99,
"action_document": frappe.defaults.get_defaults().get("company") or '',
"action_field": "monthly_sales_target", "is_completed": 0,
"domains": '["Manufacturing", "Services", "Retail", "Distribution"]' },
{"action_name": "Add Customers", "action_doctype": "Customer", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Customers"), "action_doctype": "Customer", "min_doc_count": 1, "is_completed": 0,
"domains": '["Manufacturing", "Services", "Retail", "Distribution"]' },
{"action_name": "Add Suppliers", "action_doctype": "Supplier", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Suppliers"), "action_doctype": "Supplier", "min_doc_count": 1, "is_completed": 0,
"domains": '["Manufacturing", "Services", "Retail", "Distribution"]' },
{"action_name": "Add Products", "action_doctype": "Item", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Products"), "action_doctype": "Item", "min_doc_count": 1, "is_completed": 0,
"domains": '["Manufacturing", "Services", "Retail", "Distribution"]' },
{"action_name": "Add Programs", "action_doctype": "Program", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Programs"), "action_doctype": "Program", "min_doc_count": 1, "is_completed": 0,
"domains": '["Education"]' },
{"action_name": "Add Instructors", "action_doctype": "Instructor", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Instructors"), "action_doctype": "Instructor", "min_doc_count": 1, "is_completed": 0,
"domains": '["Education"]' },
{"action_name": "Add Courses", "action_doctype": "Course", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Courses"), "action_doctype": "Course", "min_doc_count": 1, "is_completed": 0,
"domains": '["Education"]' },
{"action_name": "Add Rooms", "action_doctype": "Room", "min_doc_count": 1, "is_completed": 0,
{"action_name": _("Add Rooms"), "action_doctype": "Room", "min_doc_count": 1, "is_completed": 0,
"domains": '["Education"]' },
{"action_name": "Add Users", "action_doctype": "User", "min_doc_count": 4, "is_completed": 0,
{"action_name": _("Add Users"), "action_doctype": "User", "min_doc_count": 4, "is_completed": 0,
"domains": '[]' }
]},

View File

@@ -713,7 +713,7 @@
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"precision": "2",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -1956,7 +1956,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-09-27 08:31:38.768846",
"modified": "2017-05-10 17:14:50.456930",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note Item",

View File

@@ -85,7 +85,7 @@ rfq = Class.extend({
frappe.unfreeze();
if(r.message){
$('.btn-sm').hide()
window.location.href = "/supplier-quotations/" + encodeURIComponent(r.message);
window.location.href = "/quotations/" + encodeURIComponent(r.message);
}
}
})

View File

@@ -20,7 +20,7 @@ def get_slide_settings():
# Initial state of slides
return [
frappe._dict(
action_name='Add Company',
action_name=_('Add Company'),
title=_("Setup Company") if domain != 'Education' else _("Setup Institution"),
help=_('Setup your ' + ('company' if domain != 'Education' else 'institution') + ' and brand.'),
# image_src="/assets/erpnext/images/illustrations/shop.jpg",
@@ -58,7 +58,7 @@ def get_slide_settings():
]
),
frappe._dict(
action_name='Add Customers',
action_name=_('Add Customers'),
domains=('Manufacturing', 'Services', 'Retail', 'Distribution'),
title=_("Add Customers"),
help=_("List a few of your customers. They could be organizations or individuals."),
@@ -82,7 +82,7 @@ def get_slide_settings():
]
),
frappe._dict(
action_name='Add Suppliers',
action_name=_('Add Suppliers'),
domains=('Manufacturing', 'Services', 'Retail', 'Distribution'),
icon="fa fa-group",
title=_("Your Suppliers"),
@@ -111,7 +111,7 @@ def get_slide_settings():
]
),
frappe._dict(
action_name='Add Products',
action_name=_('Add Products'),
domains=['Manufacturing', 'Services', 'Retail', 'Distribution'],
icon="fa fa-barcode",
title=_("Your Products or Services"),
@@ -142,7 +142,7 @@ def get_slide_settings():
# School slides begin
frappe._dict(
action_name='Add Programs',
action_name=_('Add Programs'),
domains=("Education"),
title=_("Program"),
help=_("Example: Masters in Computer Science"),
@@ -163,7 +163,7 @@ def get_slide_settings():
),
frappe._dict(
action_name='Add Courses',
action_name=_('Add Courses'),
domains=["Education"],
title=_("Course"),
help=_("Example: Basic Mathematics"),
@@ -183,7 +183,7 @@ def get_slide_settings():
]
),
frappe._dict(
action_name='Add Instructors',
action_name=_('Add Instructors'),
domains=["Education"],
title=_("Instructor"),
help=_("People who teach at your organisation"),
@@ -203,7 +203,7 @@ def get_slide_settings():
]
),
frappe._dict(
action_name='Add Rooms',
action_name=_('Add Rooms'),
domains=["Education"],
title=_("Room"),
help=_("Classrooms/ Laboratories etc where lectures can be scheduled."),
@@ -222,7 +222,7 @@ def get_slide_settings():
# School slides end
frappe._dict(
action_name='Add Users',
action_name=_('Add Users'),
title=_("Add Users"),
help=_("Add users to your organization, other than yourself."),
fields=[