Merge branch 'develop'
@ -131,6 +131,7 @@
|
||||
"getCookies": true,
|
||||
"get_url_arg": true,
|
||||
"get_server_fields": true,
|
||||
"set_multiple": true
|
||||
"set_multiple": true,
|
||||
"QUnit": true
|
||||
}
|
||||
}
|
||||
|
46
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@frappe.io. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
@ -2,7 +2,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
__version__ = '8.2.4'
|
||||
__version__ = '8.3.0'
|
||||
|
||||
|
||||
def get_default_company(user=None):
|
||||
|
@ -62,13 +62,13 @@ class BankReconciliation(Document):
|
||||
|
||||
for d in entries:
|
||||
row = self.append('payment_entries', {})
|
||||
|
||||
d.amount = fmt_money(d.debit if d.debit else d.credit, 2, d.account_currency) + " " + (_("Dr") if d.debit else _("Cr"))
|
||||
amount = d.debit if d.debit else d.credit
|
||||
d.amount = fmt_money(amount, 2, d.account_currency) + " " + (_("Dr") if d.debit else _("Cr"))
|
||||
d.pop("credit")
|
||||
d.pop("debit")
|
||||
d.pop("account_currency")
|
||||
row.update(d)
|
||||
self.total_amount += flt(d.amount)
|
||||
self.total_amount += flt(amount)
|
||||
|
||||
def update_clearance_date(self):
|
||||
clearance_date_updated = False
|
||||
|
@ -3238,7 +3238,7 @@
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@ -3767,10 +3767,11 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-06-13 14:28:57.930167",
|
||||
"modified": "2017-06-29 10:48:09.707735",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
"name_case": "Title Case",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
|
@ -71,17 +71,19 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
});
|
||||
|
||||
if(!from_delivery_note && !is_delivered_by_supplier) {
|
||||
cur_frm.add_custom_button(__('Delivery'), cur_frm.cscript['Make Delivery Note'],
|
||||
__("Make"));
|
||||
cur_frm.add_custom_button(__('Delivery'),
|
||||
cur_frm.cscript['Make Delivery Note'], __("Make"));
|
||||
}
|
||||
}
|
||||
|
||||
if(doc.outstanding_amount!=0 && !cint(doc.is_return)) {
|
||||
cur_frm.add_custom_button(__('Payment'), this.make_payment_entry, __("Make"));
|
||||
cur_frm.add_custom_button(__('Payment'),
|
||||
this.make_payment_entry, __("Make"));
|
||||
}
|
||||
|
||||
if(doc.outstanding_amount>0 && !cint(doc.is_return)) {
|
||||
cur_frm.add_custom_button(__('Payment Request'), this.make_payment_request, __("Make"));
|
||||
cur_frm.add_custom_button(__('Payment Request'),
|
||||
this.make_payment_request, __("Make"));
|
||||
}
|
||||
|
||||
|
||||
@ -303,6 +305,23 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
}
|
||||
|
||||
this.frm.refresh_fields();
|
||||
},
|
||||
|
||||
company_address: function() {
|
||||
var me = this;
|
||||
if(this.frm.doc.company_address) {
|
||||
frappe.call({
|
||||
method: "frappe.contacts.doctype.address.address.get_address_display",
|
||||
args: {"address_dict": this.frm.doc.company_address },
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
me.frm.set_value("company_address_display", r.message)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.frm.set_value("company_address_display", "");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -324,12 +343,12 @@ cur_frm.cscript.hide_fields = function(doc) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
var item_fields_stock = ['batch_no', 'actual_batch_qty', 'actual_qty', 'expense_account',
|
||||
'warehouse', 'expense_account', 'quality_inspection']
|
||||
cur_frm.fields_dict['items'].grid.set_column_disp(item_fields_stock,
|
||||
(cint(doc.update_stock)==1 || cint(doc.is_return)==1 ? true : false));
|
||||
*/
|
||||
|
||||
|
||||
// India related fields
|
||||
if (frappe.boot.sysdefaults.country == 'India') unhide_field(['c_form_applicable', 'c_form_no']);
|
||||
@ -483,7 +502,7 @@ frappe.ui.form.on('Sales Invoice', {
|
||||
'Delivery Note': 'Delivery',
|
||||
'Sales Invoice': 'Sales Return',
|
||||
'Payment Request': 'Payment Request',
|
||||
'Payment': 'Payment Entry'
|
||||
'Payment Entry': 'Payment'
|
||||
},
|
||||
frm.fields_dict["timesheets"].grid.get_field("time_sheet").get_query = function(doc, cdt, cdn){
|
||||
return{
|
||||
|
@ -190,7 +190,7 @@
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
@ -200,37 +200,6 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "due_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": "Payment Due Date",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "due_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0,
|
||||
"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,
|
||||
@ -253,7 +222,7 @@
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@ -314,7 +283,7 @@
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
@ -345,7 +314,7 @@
|
||||
"options": "POS Profile",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@ -510,6 +479,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "due_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": "Payment Due Date",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "due_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"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,
|
||||
@ -844,6 +844,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "territory",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Territory",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Territory",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"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,
|
||||
@ -949,13 +980,13 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Company Address",
|
||||
"label": "Company Address Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Address",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@ -971,24 +1002,23 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "territory",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"fieldname": "company_address_display",
|
||||
"fieldtype": "Small Text",
|
||||
"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": "Territory",
|
||||
"label": "Company Address",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Territory",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"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,
|
||||
@ -1479,7 +1509,7 @@
|
||||
"options": "Sales Invoice Timesheet",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@ -1882,6 +1912,36 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fieldname": "sec_tax_breakup",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Item-wise Tax Breakup",
|
||||
"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,
|
||||
@ -1889,7 +1949,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "other_charges_calculation",
|
||||
"fieldtype": "HTML",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@ -1899,12 +1959,12 @@
|
||||
"in_standard_filter": 0,
|
||||
"label": "Taxes and Charges Calculation",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"no_copy": 1,
|
||||
"oldfieldtype": "HTML",
|
||||
"permlevel": 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,
|
||||
@ -2511,7 +2571,7 @@
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Outstanding Amount",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
@ -2984,7 +3044,7 @@
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@ -3597,7 +3657,7 @@
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
@ -4450,7 +4510,7 @@
|
||||
"options": "Print Format",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@ -4511,7 +4571,7 @@
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@ -4542,7 +4602,7 @@
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@ -4627,10 +4687,11 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-06-22 14:45:35.257640",
|
||||
"modified": "2017-07-04 17:11:09.477003",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
"name_case": "Title Case",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
|
@ -132,8 +132,7 @@ class SalesInvoice(SellingController):
|
||||
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
|
||||
self.check_credit_limit()
|
||||
|
||||
if self.update_stock:
|
||||
self.update_serial_no()
|
||||
self.update_serial_no()
|
||||
|
||||
if not cint(self.is_pos) == 1 and not self.is_return:
|
||||
self.update_against_document_in_jv()
|
||||
|
@ -1105,6 +1105,22 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.get(k), expected_values[d.item_code][i])
|
||||
|
||||
def test_item_wise_tax_breakup(self):
|
||||
si = create_sales_invoice(qty=100, rate=50, do_not_save=True)
|
||||
si.append("taxes", {
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Service Tax",
|
||||
"rate": 10
|
||||
})
|
||||
si.insert()
|
||||
|
||||
tax_breakup_html = '''\n<div class="tax-break-up" style="overflow-x: auto;">\n\t<table class="table table-bordered table-hover">\n\t\t<thead><tr><th class="text-left" style="min-width: 120px;">Item Name</th>\n<th class="text-right" style="min-width: 80px;">Taxable Amount</th>\n<th class="text-right" style="min-width: 80px;">_Test Account Service Tax - _TC</th></tr></thead>\n\t\t<tbody><tr><td>_Test Item</td><td class="text-right">\u20b9 5,000.00</td><td class="text-right">(10.0%) \u20b9 500.00</td></tr></tbody>\n\t</table>\n</div>'''
|
||||
|
||||
self.assertEqual(si.other_charges_calculation, tax_breakup_html)
|
||||
|
||||
|
||||
def create_sales_invoice(**args):
|
||||
si = frappe.new_doc("Sales Invoice")
|
||||
args = frappe._dict(args)
|
||||
|
@ -11,6 +11,7 @@
|
||||
"doctype": "DocType",
|
||||
"document_type": "Document",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
@ -1423,7 +1424,7 @@
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "eval:doc.serial_no || doc.batch_no",
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"depends_on": "eval: parent.update_stock",
|
||||
"fieldname": "warehouse_and_reference",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -2165,7 +2166,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-03 19:34:14.820285",
|
||||
"modified": "2017-07-06 17:54:03.347700",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
|
@ -10,7 +10,7 @@ from frappe.utils import (flt, getdate, get_first_day, get_last_day, date_diff,
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
|
||||
|
||||
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
|
||||
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
|
||||
company=None, reset_period_on_fy_change=True):
|
||||
"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
|
||||
Periodicity can be (Yearly, Quarterly, Monthly)"""
|
||||
@ -85,8 +85,8 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_v
|
||||
return period_list
|
||||
|
||||
def get_fiscal_year_data(from_fiscal_year, to_fiscal_year):
|
||||
fiscal_year = frappe.db.sql("""select min(year_start_date) as year_start_date,
|
||||
max(year_end_date) as year_end_date from `tabFiscal Year` where
|
||||
fiscal_year = frappe.db.sql("""select min(year_start_date) as year_start_date,
|
||||
max(year_end_date) as year_end_date from `tabFiscal Year` where
|
||||
name between %(from_fiscal_year)s and %(to_fiscal_year)s""",
|
||||
{'from_fiscal_year': from_fiscal_year, 'to_fiscal_year': to_fiscal_year}, as_dict=1)
|
||||
|
||||
@ -110,7 +110,7 @@ def get_label(periodicity, from_date, to_date):
|
||||
label = formatdate(from_date, "MMM YY") + "-" + formatdate(to_date, "MMM YY")
|
||||
|
||||
return label
|
||||
|
||||
|
||||
def get_data(company, root_type, balance_must_be, period_list, filters=None,
|
||||
accumulated_values=1, only_current_fiscal_year=True, ignore_closing_entries=False,
|
||||
ignore_accumulated_values_for_fy=False):
|
||||
@ -119,16 +119,16 @@ def get_data(company, root_type, balance_must_be, period_list, filters=None,
|
||||
return None
|
||||
|
||||
accounts, accounts_by_name, parent_children_map = filter_accounts(accounts)
|
||||
|
||||
|
||||
company_currency = frappe.db.get_value("Company", company, "default_currency")
|
||||
|
||||
gl_entries_by_account = {}
|
||||
for root in frappe.db.sql("""select lft, rgt from tabAccount
|
||||
where root_type=%s and ifnull(parent_account, '') = ''""", root_type, as_dict=1):
|
||||
|
||||
set_gl_entries_by_account(company,
|
||||
|
||||
set_gl_entries_by_account(company,
|
||||
period_list[0]["year_start_date"] if only_current_fiscal_year else None,
|
||||
period_list[-1]["to_date"],
|
||||
period_list[-1]["to_date"],
|
||||
root.lft, root.rgt, filters,
|
||||
gl_entries_by_account, ignore_closing_entries=ignore_closing_entries)
|
||||
|
||||
@ -136,7 +136,7 @@ def get_data(company, root_type, balance_must_be, period_list, filters=None,
|
||||
accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values)
|
||||
out = prepare_data(accounts, balance_must_be, period_list, company_currency)
|
||||
out = filter_out_zero_value_rows(out, parent_children_map)
|
||||
|
||||
|
||||
if out:
|
||||
add_total_row(out, root_type, balance_must_be, period_list, company_currency)
|
||||
|
||||
@ -151,13 +151,13 @@ def calculate_values(accounts_by_name, gl_entries_by_account, period_list, accum
|
||||
|
||||
if entry.posting_date <= period.to_date:
|
||||
if (accumulated_values or entry.posting_date >= period.from_date) and \
|
||||
(not ignore_accumulated_values_for_fy or
|
||||
(not ignore_accumulated_values_for_fy or
|
||||
entry.fiscal_year == period.to_date_fiscal_year):
|
||||
d[period.key] = d.get(period.key, 0.0) + flt(entry.debit) - flt(entry.credit)
|
||||
|
||||
if entry.posting_date < period_list[0].year_start_date:
|
||||
d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
|
||||
|
||||
|
||||
def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values):
|
||||
"""accumulate children's values in parent accounts"""
|
||||
for d in reversed(accounts):
|
||||
@ -165,7 +165,7 @@ def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accu
|
||||
for period in period_list:
|
||||
accounts_by_name[d.parent_account][period.key] = \
|
||||
accounts_by_name[d.parent_account].get(period.key, 0.0) + d.get(period.key, 0.0)
|
||||
|
||||
|
||||
accounts_by_name[d.parent_account]["opening_balance"] = \
|
||||
accounts_by_name[d.parent_account].get("opening_balance", 0.0) + d.get("opening_balance", 0.0)
|
||||
|
||||
@ -173,15 +173,15 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
|
||||
data = []
|
||||
year_start_date = period_list[0]["year_start_date"].strftime("%Y-%m-%d")
|
||||
year_end_date = period_list[-1]["year_end_date"].strftime("%Y-%m-%d")
|
||||
|
||||
|
||||
for d in accounts:
|
||||
# add to output
|
||||
has_value = False
|
||||
total = 0
|
||||
row = frappe._dict({
|
||||
"account_name": d.account_name,
|
||||
"account": d.name,
|
||||
"parent_account": d.parent_account,
|
||||
"account_name": _(d.account_name),
|
||||
"account": _(d.name),
|
||||
"parent_account": _(d.parent_account),
|
||||
"indent": flt(d.indent),
|
||||
"year_start_date": year_start_date,
|
||||
"year_end_date": year_end_date,
|
||||
@ -192,7 +192,7 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
|
||||
if d.get(period.key) and balance_must_be=="Credit":
|
||||
# change sign based on Debit or Credit, since calculation is done using (debit - credit)
|
||||
d[period.key] *= -1
|
||||
|
||||
|
||||
row[period.key] = flt(d.get(period.key, 0.0), 3)
|
||||
|
||||
if abs(row[period.key]) >= 0.005:
|
||||
@ -203,9 +203,9 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
|
||||
row["has_value"] = has_value
|
||||
row["total"] = total
|
||||
data.append(row)
|
||||
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def filter_out_zero_value_rows(data, parent_children_map, show_zero_values=False):
|
||||
data_with_value = []
|
||||
for d in data:
|
||||
@ -224,8 +224,8 @@ def filter_out_zero_value_rows(data, parent_children_map, show_zero_values=False
|
||||
|
||||
def add_total_row(out, root_type, balance_must_be, period_list, company_currency):
|
||||
total_row = {
|
||||
"account_name": "'" + _("Total {0} ({1})").format(root_type, balance_must_be) + "'",
|
||||
"account": "'" + _("Total {0} ({1})").format(root_type, balance_must_be) + "'",
|
||||
"account_name": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
|
||||
"account": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
|
||||
"currency": company_currency
|
||||
}
|
||||
|
||||
@ -235,11 +235,11 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency
|
||||
total_row.setdefault(period.key, 0.0)
|
||||
total_row[period.key] += row.get(period.key, 0.0)
|
||||
row[period.key] = ""
|
||||
|
||||
|
||||
total_row.setdefault("total", 0.0)
|
||||
total_row["total"] += flt(row["total"])
|
||||
row["total"] = ""
|
||||
|
||||
|
||||
if total_row.has_key("total"):
|
||||
out.append(total_row)
|
||||
|
||||
|
@ -278,7 +278,7 @@ class GrossProfitGenerator(object):
|
||||
inner join `tabSales Invoice Item` on `tabSales Invoice Item`.parent = `tabSales Invoice`.name
|
||||
{sales_team_table}
|
||||
where
|
||||
`tabSales Invoice`.docstatus = 1 and `tabSales Invoice`.is_return != 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,
|
||||
|
@ -270,6 +270,9 @@ def make_purchase_receipt(source_name, target_doc=None):
|
||||
doc = get_mapped_doc("Purchase Order", source_name, {
|
||||
"Purchase Order": {
|
||||
"doctype": "Purchase Receipt",
|
||||
"field_map": {
|
||||
"per_billed": "per_billed"
|
||||
},
|
||||
"validation": {
|
||||
"docstatus": ["=", 1],
|
||||
}
|
||||
|
@ -3,8 +3,10 @@
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
||||
from frappe.utils import nowdate
|
||||
|
||||
class TestRequestforQuotation(unittest.TestCase):
|
||||
@ -28,6 +30,31 @@ class TestRequestforQuotation(unittest.TestCase):
|
||||
self.assertEquals(sq1.get('items')[0].item_code, "_Test Item")
|
||||
self.assertEquals(sq1.get('items')[0].qty, 5)
|
||||
|
||||
def test_make_supplier_quotation_with_special_characters(self):
|
||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
||||
|
||||
frappe.delete_doc_if_exists("Supplier", "_Test Supplier '1", force=1)
|
||||
supplier = frappe.new_doc("Supplier")
|
||||
supplier.supplier_name = "_Test Supplier '1"
|
||||
supplier.supplier_type = "_Test Supplier Type"
|
||||
supplier.insert()
|
||||
|
||||
rfq = make_request_for_quotation(supplier_wt_appos)
|
||||
|
||||
sq = make_supplier_quotation(rfq.name, supplier_wt_appos[0].get("supplier"))
|
||||
sq.submit()
|
||||
|
||||
frappe.form_dict = frappe.local("form_dict")
|
||||
frappe.form_dict.name = rfq.name
|
||||
|
||||
self.assertEqual(
|
||||
check_supplier_has_docname_access(supplier_wt_appos[0].get('supplier')),
|
||||
True
|
||||
)
|
||||
|
||||
# reset form_dict
|
||||
frappe.form_dict.name = None
|
||||
|
||||
def test_make_supplier_quotation_from_portal(self):
|
||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import create_supplier_quotation
|
||||
rfq = make_request_for_quotation()
|
||||
@ -44,8 +71,11 @@ class TestRequestforQuotation(unittest.TestCase):
|
||||
self.assertEquals(supplier_quotation_doc.get('items')[0].amount, 500)
|
||||
|
||||
|
||||
def make_request_for_quotation():
|
||||
supplier_data = get_supplier_data()
|
||||
def make_request_for_quotation(supplier_data=None):
|
||||
"""
|
||||
:param supplier_data: List containing supplier data
|
||||
"""
|
||||
supplier_data = supplier_data if supplier_data else get_supplier_data()
|
||||
rfq = frappe.new_doc('Request for Quotation')
|
||||
rfq.transaction_date = nowdate()
|
||||
rfq.status = 'Draft'
|
||||
@ -77,3 +107,8 @@ def get_supplier_data():
|
||||
"supplier": "_Test Supplier 1",
|
||||
"supplier_name": "_Test Supplier 1"
|
||||
}]
|
||||
|
||||
supplier_wt_appos = [{
|
||||
"supplier": "_Test Supplier '1",
|
||||
"supplier_name": "_Test Supplier '1",
|
||||
}]
|
||||
|
8
erpnext/change_log/v8/v8_3_0.md
Normal file
@ -0,0 +1,8 @@
|
||||
### Production Order Enahancement
|
||||
- Show required items child table.
|
||||
- Source warehouse for each Raw Materials, in Production Order Item and BOM Item table.
|
||||
- Group warehouse allowed for Source and WIP warehouse.
|
||||
### GST Tax Invoice Print Format
|
||||
- Added print format to show tax(GST) breakup.
|
||||
- Total Stock Summary report.
|
||||
- Include Search Fields in Customer Query.
|
@ -137,7 +137,14 @@ def get_data():
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Assessment Result Tool"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Course wise Assessment Report",
|
||||
"doctype": "Assessment Result"
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -169,6 +169,7 @@ def create_variant(item, args):
|
||||
|
||||
return variant
|
||||
|
||||
|
||||
def copy_attributes_to_variant(item, variant):
|
||||
from frappe.model import no_value_fields
|
||||
|
||||
@ -181,8 +182,9 @@ def copy_attributes_to_variant(item, variant):
|
||||
exclude_fields += ['manufacturer', 'manufacturer_part_no']
|
||||
|
||||
for field in item.meta.fields:
|
||||
if field.fieldtype not in no_value_fields and (not field.no_copy)\
|
||||
and field.fieldname not in exclude_fields:
|
||||
# "Table" is part of `no_value_field` but we shouldn't ignore tables
|
||||
if (field.fieldtype == 'Table' or field.fieldtype not in no_value_fields) \
|
||||
and (not field.no_copy) and field.fieldname not in exclude_fields:
|
||||
if variant.get(field.fieldname) != item.get(field.fieldname):
|
||||
variant.set(field.fieldname, item.get(field.fieldname))
|
||||
variant.variant_of = item.name
|
||||
|
@ -68,14 +68,17 @@ def customer_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
fields = ["name", "customer_name", "customer_group", "territory"]
|
||||
|
||||
meta = frappe.get_meta("Customer")
|
||||
fields = fields + [f for f in meta.get_search_fields() if not f in fields]
|
||||
searchfields = meta.get_search_fields()
|
||||
searchfields = searchfields + [f for f in [searchfield or "name", "customer_name"] \
|
||||
if not f in searchfields]
|
||||
fields = fields + [f for f in searchfields if not f in fields]
|
||||
|
||||
fields = ", ".join(fields)
|
||||
searchfields = " or ".join([field + " like %(txt)s" for field in searchfields])
|
||||
|
||||
return frappe.db.sql("""select {fields} from `tabCustomer`
|
||||
where docstatus < 2
|
||||
and ({key} like %(txt)s
|
||||
or customer_name like %(txt)s) and disabled=0
|
||||
and ({scond}) and disabled=0
|
||||
{mcond}
|
||||
order by
|
||||
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
|
||||
@ -84,7 +87,7 @@ def customer_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
name, customer_name
|
||||
limit %(start)s, %(page_len)s""".format(**{
|
||||
"fields": fields,
|
||||
"key": searchfield,
|
||||
"scond": searchfields,
|
||||
"mcond": get_match_cond(doctype)
|
||||
}), {
|
||||
'txt': "%%%s%%" % txt,
|
||||
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
||||
import json
|
||||
import frappe, erpnext
|
||||
from frappe import _, scrub
|
||||
from frappe.utils import cint, flt, round_based_on_smallest_currency_fraction
|
||||
from frappe.utils import cint, flt, cstr, fmt_money, round_based_on_smallest_currency_fraction
|
||||
from erpnext.controllers.accounts_controller import validate_conversion_rate, \
|
||||
validate_taxes_and_charges, validate_inclusive_tax
|
||||
|
||||
@ -24,6 +24,9 @@ class calculate_taxes_and_totals(object):
|
||||
|
||||
if self.doc.doctype in ["Sales Invoice", "Purchase Invoice"]:
|
||||
self.calculate_total_advance()
|
||||
|
||||
if self.doc.meta.get_field("other_charges_calculation"):
|
||||
self.set_item_wise_tax_breakup()
|
||||
|
||||
def _calculate(self):
|
||||
self.calculate_item_values()
|
||||
@ -504,3 +507,105 @@ class calculate_taxes_and_totals(object):
|
||||
rate_with_margin = flt(item.price_list_rate) + flt(margin_value)
|
||||
|
||||
return rate_with_margin
|
||||
|
||||
def set_item_wise_tax_breakup(self):
|
||||
item_tax = {}
|
||||
tax_accounts = []
|
||||
company_currency = erpnext.get_company_currency(self.doc.company)
|
||||
|
||||
item_tax, tax_accounts = self.get_item_tax(item_tax, tax_accounts, company_currency)
|
||||
|
||||
headings = get_table_column_headings(tax_accounts)
|
||||
|
||||
distinct_items = self.get_distinct_items()
|
||||
|
||||
rows = get_table_rows(distinct_items, item_tax, tax_accounts, company_currency)
|
||||
|
||||
if not rows:
|
||||
self.doc.other_charges_calculation = ""
|
||||
else:
|
||||
self.doc.other_charges_calculation = '''
|
||||
<div class="tax-break-up" style="overflow-x: auto;">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead><tr>{headings}</tr></thead>
|
||||
<tbody>{rows}</tbody>
|
||||
</table>
|
||||
</div>'''.format(**{
|
||||
"headings": "\n".join(headings),
|
||||
"rows": "\n".join(rows)
|
||||
})
|
||||
|
||||
def get_item_tax(self, item_tax, tax_accounts, company_currency):
|
||||
for tax in self.doc.taxes:
|
||||
tax_amount_precision = tax.precision("tax_amount")
|
||||
tax_rate_precision = tax.precision("rate");
|
||||
|
||||
item_tax_map = self._load_item_tax_rate(tax.item_wise_tax_detail)
|
||||
for item_code, tax_data in item_tax_map.items():
|
||||
if not item_tax.get(item_code):
|
||||
item_tax[item_code] = {}
|
||||
|
||||
if isinstance(tax_data, list):
|
||||
tax_rate = ""
|
||||
if tax_data[0]:
|
||||
if tax.charge_type == "Actual":
|
||||
tax_rate = fmt_money(flt(tax_data[0], tax_amount_precision),
|
||||
tax_amount_precision, company_currency)
|
||||
else:
|
||||
tax_rate = cstr(flt(tax_data[0], tax_rate_precision)) + "%"
|
||||
|
||||
tax_amount = fmt_money(flt(tax_data[1], tax_amount_precision),
|
||||
tax_amount_precision, company_currency)
|
||||
|
||||
item_tax[item_code][tax.name] = [tax_rate, tax_amount]
|
||||
else:
|
||||
item_tax[item_code][tax.name] = [cstr(flt(tax_data, tax_rate_precision)) + "%", ""]
|
||||
tax_accounts.append([tax.name, tax.account_head])
|
||||
|
||||
return item_tax, tax_accounts
|
||||
|
||||
|
||||
def get_distinct_items(self):
|
||||
distinct_item_names = []
|
||||
distinct_items = []
|
||||
for item in self.doc.items:
|
||||
item_code = item.item_code or item.item_name
|
||||
if item_code not in distinct_item_names:
|
||||
distinct_item_names.append(item_code)
|
||||
distinct_items.append(item)
|
||||
|
||||
return distinct_items
|
||||
|
||||
def get_table_column_headings(tax_accounts):
|
||||
headings_name = [_("Item Name"), _("Taxable Amount")] + [d[1] for d in tax_accounts]
|
||||
headings = []
|
||||
for head in headings_name:
|
||||
if head == _("Item Name"):
|
||||
headings.append('<th style="min-width: 120px;" class="text-left">' + (head or "") + "</th>")
|
||||
else:
|
||||
headings.append('<th style="min-width: 80px;" class="text-right">' + (head or "") + "</th>")
|
||||
|
||||
return headings
|
||||
|
||||
def get_table_rows(distinct_items, item_tax, tax_accounts, company_currency):
|
||||
rows = []
|
||||
for item in distinct_items:
|
||||
item_tax_record = item_tax.get(item.item_code or item.item_name)
|
||||
if not item_tax_record:
|
||||
continue
|
||||
|
||||
taxes = []
|
||||
for head in tax_accounts:
|
||||
if item_tax_record[head[0]]:
|
||||
taxes.append("<td class='text-right'>(" + item_tax_record[head[0]][0] + ") "
|
||||
+ item_tax_record[head[0]][1] + "</td>")
|
||||
else:
|
||||
taxes.append("<td></td>")
|
||||
|
||||
rows.append("<tr><td>{item_name}</td><td class='text-right'>{taxable_amount}</td>{taxes}</tr>".format(**{
|
||||
"item_name": item.item_name,
|
||||
"taxable_amount": fmt_money(item.net_amount, item.precision("net_amount"), company_currency),
|
||||
"taxes": "\n".join(taxes)
|
||||
}))
|
||||
|
||||
return rows
|
58
erpnext/controllers/tests/test_item_variant.py
Normal file
@ -0,0 +1,58 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import json
|
||||
import unittest
|
||||
|
||||
from erpnext.controllers.item_variant import copy_attributes_to_variant, make_variant_item_code
|
||||
|
||||
# python 3 compatibility stuff
|
||||
try:
|
||||
unicode = unicode
|
||||
except NameError:
|
||||
# Python 3
|
||||
basestring = (str, bytes)
|
||||
else:
|
||||
# Python 2
|
||||
basestring = basestring
|
||||
|
||||
|
||||
def create_variant_with_tables(item, args):
|
||||
if isinstance(args, basestring):
|
||||
args = json.loads(args)
|
||||
|
||||
template = frappe.get_doc("Item", item)
|
||||
template.quality_parameters.append({
|
||||
"specification": "Moisture",
|
||||
"value": "< 5%",
|
||||
})
|
||||
variant = frappe.new_doc("Item")
|
||||
variant.variant_based_on = 'Item Attribute'
|
||||
variant_attributes = []
|
||||
|
||||
for d in template.attributes:
|
||||
variant_attributes.append({
|
||||
"attribute": d.attribute,
|
||||
"attribute_value": args.get(d.attribute)
|
||||
})
|
||||
|
||||
variant.set("attributes", variant_attributes)
|
||||
copy_attributes_to_variant(template, variant)
|
||||
make_variant_item_code(template.item_code, template.item_name, variant)
|
||||
|
||||
return variant
|
||||
|
||||
|
||||
def make_item_variant():
|
||||
frappe.delete_doc_if_exists("Item", "_Test Variant Item-S", force=1)
|
||||
variant = create_variant_with_tables("_Test Variant Item", '{"Test Size": "Small"}')
|
||||
variant.item_code = "_Test Variant Item-S"
|
||||
variant.item_name = "_Test Variant Item-S"
|
||||
variant.save()
|
||||
return variant
|
||||
|
||||
|
||||
class TestItemVariant(unittest.TestCase):
|
||||
def test_tables_in_template_copied_to_variant(self):
|
||||
variant = make_item_variant()
|
||||
self.assertNotEqual(variant.get("quality_parameters"), [])
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 261 KiB |
0
erpnext/docs/assets/img/regional/__init__.py
Normal file
0
erpnext/docs/assets/img/regional/india/__init__.py
Normal file
After Width: | Height: | Size: 215 KiB |
After Width: | Height: | Size: 185 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
BIN
erpnext/docs/assets/img/setup/stock-reco-data.png
Normal file
After Width: | Height: | Size: 95 KiB |
BIN
erpnext/docs/assets/img/setup/stock-reco-ledger.png
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
erpnext/docs/assets/img/setup/stock-reco-upload.gif
Normal file
After Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 291 KiB After Width: | Height: | Size: 228 KiB |
Before Width: | Height: | Size: 211 KiB After Width: | Height: | Size: 199 KiB |
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 173 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 28 KiB |
@ -640,8 +640,8 @@ attach them to the start of each source file to most effectively state
|
||||
the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.</p>
|
||||
|
||||
<pre><code> <one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
<pre><code> <one line="" to="" give="" the="" program's="" name="" and="" a="" brief="" idea="" of="" what="" it="" does.="">
|
||||
Copyright (C) <year> <name of="" author="">
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -38,15 +38,13 @@ Hinweis: Stellen Sie sicher, dass im Abschnitt "Weitere Informationen" "Ist Erö
|
||||
|
||||
Vervollständigen Sie die Buchungssätze auf der Soll- und Haben-Seite.
|
||||
|
||||
![Eröffnungsbuchung]({{docs_base_url}}/assets/old_images/erpnext/opening-entry-1.png)
|
||||
<img class="screenshot" alt="Opening Account" src="{{docs_base_url}}/assets/img/accounts/opening-6.png">
|
||||
|
||||
Um einen Eröffnungsstand einzupflegen, erstellen Sie einen Buchungssatz für ein Konto oder eine Gruppe von Konten.
|
||||
|
||||
Beispiel: Wenn Sie die Kontenstände von drei Bankkonten einpflegen möchten, dann erstellen Sie Buchungssätze der folgenden Art und Weise:
|
||||
|
||||
![Eröffnungsbuchung]({{docs_base_url}}/assets/old_images/erpnext/image-temp-opening.png)
|
||||
|
||||
![Eröffnungsbuchung]({{docs_base_url}}/assets/old_images/erpnext/opening-entry-2.png)
|
||||
<img class="screenshot" alt="Opening Account" src="{{docs_base_url}}/assets/img/accounts/opening-3.png">
|
||||
|
||||
Um einen Ausgleich herzustellen, wird ein temporäres Konto für Vermögen und Verbindlichkeiten verwendet. Wenn Sie einen Anfangsbestand in einem Verbindlichkeitenkonto einpflegen, können Sie zum Ausgleich ein temporäres Vermögenskonto verwenden.
|
||||
|
||||
@ -61,7 +59,8 @@ Sie können zwei Eröffnungsbuchungssätze erstellen:
|
||||
|
||||
Wenn Sie die Buchungen erstellt haben, schaut der Bericht zur Probebilanz in etwa wie folgt aus:
|
||||
|
||||
![Probebilanz]({{docs_base_url}}/assets/old_images/erpnext/trial-balance-1.png)
|
||||
<img class="screenshot" alt="Probebilanz" src="{{docs_base_url}}/assets/img/accounts/opening-4.png">
|
||||
|
||||
|
||||
### Offene Rechnungen
|
||||
|
||||
|
@ -3,10 +3,9 @@
|
||||
|
||||
Dieses Diagramm stellt dar, wie ERPNext die Informationen und Vorgänge in Ihrem Unternehmen über Schlüsselfunktionen nachverfolgt. Dieses Diagramm gibt nicht alle Funktionalitäten von ERPNext wieder.
|
||||
|
||||
![]({{docs_base_url}}/assets/old_images/erpnext/overview.png)
|
||||
|
||||
<img class="screenshot" alt="Hohe Auflösung" src="{{docs_base_url}}/assets/img/setup/overview.png">
|
||||
|
||||
[Hohe Auflösung]({{docs_base_url}}/assets/old_images/erpnext/overview.png)
|
||||
|
||||
_Anmerkung: Nicht alle Schritte sind zwingend erforderlich. ERPNext erlaubt es Ihnen nach eigenem Gutdünken Schritte auszulassen, wenn Sie den Prozess vereinfachen wollen._
|
||||
|
||||
|
@ -11,7 +11,8 @@ Wenn Sie bei Ihrer Tätigkeit bestimmte Prozesse an eine Drittpartei, bei der Si
|
||||
2. Erstellen Sie ein Lager für den Lieferanten, damit Sie die übergebenen Artikel nachverfolgen können (möglicherweise geben Sie ja Artikel im Wert einer Monatslieferung außer Haus).
|
||||
3. Stellen Sie für den bearbeiteten Artikel und der Artikelvorlage den Punkt "Ist Fremdvergabe" auf JA ein.
|
||||
|
||||
![Fremdvergabe]({{docs_base_url}}/assets/old_images/erpnext/subcontract.png)
|
||||
<img class="screenshot" alt="Fremdvergabe" src="{{docs_base_url}}/assets/img/manufacturing/subcontract.png">
|
||||
|
||||
|
||||
**Schritt 1:** Erstellen Sie für den bearbeiteten Artikel eine Stückliste, die den unbearbeiteten Artikel als Unterartikel enthält. Beispiel: Wenn Sie einen Stift herstellen, wird der bearbeitete Stift mit der Stückliste benannt, wbei der Tintentank, der Knopf und andere Artikel, die in die Fertigung eingehen als Unterartikel verwaltet werden.
|
||||
|
||||
|
@ -27,7 +27,7 @@ Sie sollten sich an eine spezielle Vorlage eines Tabellenblattes halten um den B
|
||||
|
||||
#### Schritt 2: Geben Sie Daten in die CSV-Datei ein.
|
||||
|
||||
![Lagerabgleichsdaten]({{docs_base_url}}/assets/old_images/erpnext/stock-reco-data.png)
|
||||
<img class="screenshot" alt="Bestandsabgleich" src="{{docs_base_url}}/assets/img/setup/stock-reco-data.png">
|
||||
|
||||
Das CSV-Format beachtet Groß- und Kleinschreibung. Verändern Sie nicht die Kopfbezeichnungen, die in der Vorlage vordefiniert wurden. In den Spalten "Artikelnummer" und "Lager" geben Sie bitte die richtige Artikelnummer und das Lager ein, so wie es in ERPNext bezeichnet wird. Für die Menge geben Sie den Lagerbestand, den Sie für diesen Artikel erfassen wollen, in einem bestimmten Lager ein. Wenn Sie die Menge oder den wertmäßigen Betrag eines Artikels nicht ändern wollen, dann lassen Sie den Eintrag leer.
|
||||
Anmerkung: Geben Sie keine "0" ein, wenn sie die Menge oder den wertmäßigen Betrag nicht ändern wollen. Sonst kalkuliert das System eine Menge von "0". Lassen Sie also das Feld leer!
|
||||
@ -52,11 +52,12 @@ Notiz: Wenn Sie die bewerteten Beträge eines Artikels eingeben, können Sie zum
|
||||
|
||||
#### Schritt 4: Überprüfen Sie die Daten zum Bestandsabgleich
|
||||
|
||||
![Bestandsabgleich Überprüfung]({{docs_base_url}}/assets/old_images/erpnext/stock-reco-upload.png)
|
||||
<img class="screenshot" alt="Bestandsabgleich Überprüfung" src="{{docs_base_url}}/assets/img/setup/stock-reco-upload.gif">
|
||||
|
||||
### Bericht zum Lagerbuch
|
||||
|
||||
![Bestandsabgleich Hauptbuch]({{docs_base_url}}/assets/old_images/erpnext/stock-reco-ledger.png)
|
||||
<img class="screenshot" alt="Bestandsabgleich" src="{{docs_base_url}}/assets/img/setup/stock-reco-ledger.png">
|
||||
|
||||
|
||||
##### So arbeitet der Bestandsabgleich
|
||||
|
||||
|
@ -7,7 +7,7 @@ Unten Sehen Sie ein Beispiel eines Worklflows.
|
||||
|
||||
Wenn ein Benutzer einen Urlaub beantragt, dann wird seine Anfrage an die Personalabteilung weiter geleitet. Die Personalabteilung, repräsentiert durch einen Mitarbeiter der Personalabteilung, wird diese Anfrage dann entweder genehmigen oder ablehnen. Wenn dieser Prozess abgeschlossen ist, dann bekommt der Vorgesetzte des Benutzers (der Urlaubsgenehmiger) eine Mitteilung, dass die Personalabteilung den Antrag genehmigt oder abgelehnt hat. Der Vorgesetzte, der die genehmigende Instanz ist, wird dann den Antrag entweder genehmigen oder ablehnen. Dementsprechend bekommt der Benutzer dann eine Genehmigung oder eine Ablehnung.
|
||||
|
||||
![Workflow]({{docs_base_url}}/assets/old_images/erpnext/workflow-leave-fl.jpg)
|
||||
<img class="screenshot" alt="Workflow" src="{{docs_base_url}}/assets/img/setup/workflow-leave-fl.jpg">
|
||||
|
||||
Um einen Workflow und Übergangsregeln zu erstellen, gehen Sie zu:
|
||||
|
||||
@ -37,14 +37,14 @@ Gehen Sie in das Modul Personalwesen und klicken Sie auf Urlaubsantrag. Beantrag
|
||||
|
||||
Wenn ein Urlaubsantrag übertragen wird, steht der Status in der Ecke der rechten Seite auf "Beantragt".
|
||||
|
||||
![Workflow Mitarbeiter LA]({{docs_base_url}}/assets/old_images/erpnext/workflow-employee-la.png)
|
||||
<img class="screenshot" alt="Workflow" src="{{docs_base_url}}/assets/img/setup/workflow-3.png">
|
||||
|
||||
Wenn sich ein Mitarbeiter der Personalabteilung anmeldet, dann kann er den Antrag genehmigen oder ablehnen. Wenn eine Genehmigung erfolgt, wechselt der Status in der rechten Ecke zu "Genehmigt". Es wird jedoch ein blaues Informationssymbol angezeigt, welches aussagt, dass der Urlaubsantrag noch anhängig ist.
|
||||
|
||||
![Urlaubsgenehmiger]({{docs_base_url}}/assets/old_images/erpnext/workflow-hr-user-la.png)
|
||||
<img class="screenshot" alt="Workflow" src="{{docs_base_url}}/assets/img/setup/workflow-4.png">
|
||||
|
||||
Wenn der Urlaubsgenehmiger die Seite mit den Urlaubsanträgen öffnet, kann er den Status von "Genehmigt" auf "Abgelehnt" ändern.
|
||||
|
||||
![Workflow Urlaubsgenehmiger]({{docs_base_url}}/assets/old_images/erpnext/workflow-leave-approver-la.png)
|
||||
<img class="screenshot" alt="Workflow" src="{{docs_base_url}}/assets/img/setup/workflow-5.png">
|
||||
|
||||
{next}
|
||||
|
@ -6,7 +6,7 @@ functions. This diagram does not cover all the features of ERPNext.
|
||||
![]({{docs_base_url}}/assets/old_images/erpnext/overview.png)
|
||||
|
||||
|
||||
[Full Resolution]({{docs_base_url}}/assets/old_images/erpnext/overview.png)
|
||||
<img class="screenshot" alt="Workflow" src="{{docs_base_url}}/assets/img/setup/overview.png">
|
||||
|
||||
_Note: Not all of the steps are mandatory. ERPNext allows you to freely skip
|
||||
steps if you want to simplify the process._
|
||||
|
@ -17,9 +17,15 @@ by:
|
||||
|
||||
* Select the Item to be produced.
|
||||
* The default BOM for that item will be fetched by the system. You can also change BOM.
|
||||
* Enter the Qty to manufacture.
|
||||
* If the selected BOM has operartion mentioned in it, the system shall fetch all operations from BOM.
|
||||
* Mention the Planned Start Date (an Estimated Date at which you want the Production to begin.)
|
||||
* Select Warehouses. Work-in-Progress Warehouse is where your Items will be transferred when you begin production and Target Warehouse is where you store finished Items before they are shipped.
|
||||
* Select Warehouses:
|
||||
* Source Warehouses: The warehouse where you store your raw materials. Each required item can have separate source warehouse. Group warehouse also can be selected as source warehouse. On submission of Production Order, the raw mateirals will be reserved in these warehouses for production usage.
|
||||
* Work-in-Progress Warehouse: The warehouse where your Items will be transferred when you begin production. Group Warehouse can also be selected as Work-in-Progress warehouse.
|
||||
* Target Warehouse: The warehouse where you store finished Items before they are shipped.
|
||||
* Scrap Warehouse: Scrap Items will be stored in this warehouse.
|
||||
* Required Items: All the required items (raw materials) will be fetched from BOM and populated in this table. Here you can also change the default source warehouse for any item. And during the production, you can track transferred raw materials from this table.
|
||||
|
||||
> Note : You can save a Production Order without selecting the warehouses, but warehouses are mandatory for submitting a Production Order
|
||||
|
||||
|
0
erpnext/docs/user/manual/en/regional/__init__.py
Normal file
@ -14,6 +14,13 @@ Go to the Company master and add the GSTIN to your default address.
|
||||
|
||||
<img class="screenshot" alt="GST in Company" src="{{docs_base_url}}/assets/img/regional/india/gstin-company.gif">
|
||||
|
||||
**Include GSTIN number in the Address Template**
|
||||
|
||||
Open Address Template record for India, add GSTIN number and State Code there if not exists.
|
||||
|
||||
<img class="screenshot" alt="GST in Company" src="{{docs_base_url}}/assets/img/regional/india/address-template-gstin.png">
|
||||
|
||||
|
||||
### 2. Setting up HSN Codes
|
||||
|
||||
According to the GST Law, your itemised invoices must contain the HSN Code related to that Item. ERPNext comes pre-installed with all 12,000+ HSN Codes so that you can easily select the relevant HSN Code in your Item
|
||||
@ -54,6 +61,12 @@ For **Sales Invoice**,
|
||||
|
||||
<img class="screenshot" alt="GST Invoice" src="{{docs_base_url}}/assets/img/regional/india/gst-invoice.gif">
|
||||
|
||||
### 6. Print GST Tax Invoice
|
||||
|
||||
To print Tax Invoice as per GSTN guidelines, please select **GST Tax Invoice** print format. This print format includes company address, GSTIN numbers, HSN/SAC Code and item-wise tax breakup. And while printing select correct value of Invoice Copy field, to mention whether it is for the Customer, Supplier or Transporter.
|
||||
|
||||
<img class="screenshot" alt="Sample GST Tax Invoice" src="{{docs_base_url}}/assets/img/regional/india/sample-gst-tax-invoice.png">
|
||||
|
||||
### Reports
|
||||
|
||||
ERPNext comes with most of your reports you need to prepare your GST Returns. Go to Accounts > GST India head for the list.
|
||||
|
@ -91,5 +91,5 @@ To setup Email Digests, go to:
|
||||
|
||||
#### Figure 4: Set up Email Digest
|
||||
|
||||
![Email Digest]({{docs_base_url}}/assets/old_images/erpnext/email-digest.png)
|
||||
<img class="screenshot" alt="Email Digest" src="{{docs_base_url}}/assets/img/setup/email/email-digest.png">
|
||||
|
||||
|
@ -31,7 +31,7 @@ A predefined template of an spreadsheet file should be followed for importing it
|
||||
|
||||
#### Step 2: Enter Data in csv file.
|
||||
|
||||
![Stock Reco Data]({{docs_base_url}}/assets/old_images/erpnext/stock-reco-data.png)
|
||||
<img class="screenshot" alt="Stock Reconciliation" src="{{docs_base_url}}/assets/img/setup/stock-reco-data.png">
|
||||
|
||||
The csv format is case-sensitive. Do not edit the headers which are preset in the template. In the Item Code and Warehouse column, enter exact Item Code and Warehouse as created in your ERPNext account. For quatity, enter stock level you wish to set for that item, in a specific warehouse.
|
||||
|
||||
@ -59,11 +59,12 @@ report. The report will show you all types of rates.
|
||||
|
||||
#### Step 4: Review the reconciliation data
|
||||
|
||||
![Stock Reco Review]({{docs_base_url}}/assets/old_images/erpnext/stock-reco-upload.png)
|
||||
<img class="screenshot" alt="Stock Reconciliation" src="{{docs_base_url}}/assets/img/setup/stock-reco-upload.gif">
|
||||
|
||||
### Stock Ledger Report
|
||||
|
||||
![Stock Reco Ledger]({{docs_base_url}}/assets/old_images/erpnext/stock-reco-ledger.png)
|
||||
<img class="screenshot" alt="Stock Reconciliation" src="{{docs_base_url}}/assets/img/setup//stock-reco-ledger.png">
|
||||
|
||||
|
||||
**How Stock Reconciliation Works**
|
||||
|
||||
|
@ -11,7 +11,7 @@ will get an indication that the HR department has Accepted or Rejected. The
|
||||
Manager, who is the approving authority, will either Approve or Reject this
|
||||
request. Accordingly,the user will get his Approved or Rejected status.
|
||||
|
||||
![Workflow]({{docs_base_url}}/assets/old_images/erpnext/workflow-leave-fl.jpg)
|
||||
<img class="screenshot" alt="Workflow" src="{{docs_base_url}}/assets/img/setup/workflow-leave-fl.jpg">
|
||||
|
||||
To make this Workflow and transition rules go to :
|
||||
|
||||
@ -46,15 +46,15 @@ workflow transition step that says from submitted you can cancel.
|
||||
|
||||
When a Leave Application is saved by Employee, the status of the document changes to "Applied"
|
||||
|
||||
![Workflow Employee LA]({{docs_base_url}}/assets/img/setup/workflow-3.png)
|
||||
<img class="screenshot" alt="Workflow" src="{{docs_base_url}}/assets/img/setup/workflow-3.png">
|
||||
|
||||
When the HR User logs in, he can either Approve or Reject. If approved the
|
||||
status of the document changes to "Approved by HR". However, it is yet to be approved by Leave Approver.
|
||||
|
||||
![Leave Approver]({{docs_base_url}}/assets/img/setup/workflow-4.png)
|
||||
<img class="screenshot" alt="Workflow" src="{{docs_base_url}}/assets/img/setup/workflow-4.png">
|
||||
|
||||
When the Leave Approver opens the Leave Application page, he can finally "Approve" or "Reject" the Leave Application.
|
||||
|
||||
![Workflow Leave Approver]({{docs_base_url}}/assets/img/setup/workflow-5.png)
|
||||
<img class="screenshot" alt="Workflow" src="{{docs_base_url}}/assets/img/setup/workflow-5.png">
|
||||
|
||||
{next}
|
||||
|
@ -37,9 +37,9 @@ These numbers help to track individual units or batches of Items which you sell.
|
||||
|
||||
### Re Ordering
|
||||
|
||||
* **Re-order level** suggests the amount of stock balance in the Warehouse.
|
||||
* **Re-order Qty** suggests the amount of stock to be ordered to maintain minimum stock levels.
|
||||
* **Minimum Order Qty** is the minimum quantity for which a Material Request / Purchase Order must be made.
|
||||
***Re-order level** suggests the amount of stock balance in the Warehouse.
|
||||
***Re-order Qty** suggests the amount of stock to be ordered to maintain minimum stock levels.
|
||||
***Minimum Order Qty** is the minimum quantity for which a Material Request / Purchase Order must be made.
|
||||
|
||||
### Item Tax
|
||||
|
||||
@ -55,6 +55,8 @@ Inspection Criteria: If a Quality Inspection is prepared for this Item, then thi
|
||||
|
||||
### Purchase Details
|
||||
|
||||
<img alt="Item Purchase Details" class="screenshot" src="{{docs_base_url}}/assets/img/stock/item-purchase.png">
|
||||
|
||||
<img class="screenshot" alt="Purchase details" src="{{docs_base_url}}/assets/img/stock/item-purchase.png">
|
||||
|
||||
* **Lead time days:** Lead time days are the number of days required for the Item to reach the warehouse.
|
||||
@ -79,9 +81,13 @@ Inspection Criteria: If a Quality Inspection is prepared for this Item, then thi
|
||||
|
||||
* **Default Income Account:** Income account selected here will be fetched automatically in sales invoice for this item.
|
||||
|
||||
* **Cost Centre:** Cost center selected here will be fetched automatically in sales invoice for this item.
|
||||
<img class="screenshot" alt="Sales details" src="{{docs_base_url}}/assets/img/stock/item-sales.png)">
|
||||
|
||||
* **Customer Codes:** Track Item Code assigned by the Customers for this Item. This will help you in searching item while creating Sales Order based on the Item Code in the Customer's Purchase Order.
|
||||
<img class="screenshot" alt="Sales details" src="{{docs_base_url}}/assets/img/stock/item-sales.png">
|
||||
|
||||
***Cost Centre:** Cost center selected here will be fetched automatically in sales invoice for this item.
|
||||
|
||||
***Customer Codes:** Track Item Code assigned by the Customers for this Item. This will help you in searching item while creating Sales Order based on the Item Code in the Customer's Purchase Order.
|
||||
|
||||
<img class="screenshot" alt="Sales details" src="{{docs_base_url}}/assets/img/stock/item-sales.png)">
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
Global-search.md
|
||||
|
||||
|
||||
Global search is a word-processing operation in which a complete computer file or set of files is searched for every occurrence of a particular word or other sequence of characters.
|
||||
|
||||
We have made the Awesome Bar of ERPNext lot more powerful by adding Global Search feature.
|
||||
Global Search helps users find information quickly. It’s located in the upper right-hand corner in ERPNext. Simply entering a few characters in the Search will show results from several different record types (Contact, Customer, Issues etc.) related to that keyword. You can also customise the fields based on which search will be shown.
|
||||
|
||||
### Using Awesome bar for Global Search.
|
||||
|
||||
<img alt="Global Search" class="screenshot" src="{{docs_base_url}}/assets/img/articles/Global Search .gif">
|
||||
|
||||
### Enable Global Search for fields in a Doctype.
|
||||
|
||||
<img alt="Global Search" class="screenshot" src="{{docs_base_url}}/assets/img/articles/Enable Global Search .gif">
|
||||
|
@ -5,12 +5,24 @@ frappe.provide("erpnext.bom");
|
||||
|
||||
frappe.ui.form.on("BOM", {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch('buying_price_list', 'currency', 'currency');
|
||||
frm.fields_dict["items"].grid.get_field("bom_no").get_query = function(doc, cdt, cdn){
|
||||
frm.add_fetch('buying_price_list', 'currency', 'currency')
|
||||
|
||||
frm.set_query("bom_no", "items", function() {
|
||||
return {
|
||||
filters: {'currency': frm.doc.currency}
|
||||
filters: {
|
||||
'currency': frm.doc.currency,
|
||||
'company': frm.doc.company
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query("source_warehouse", "items", function() {
|
||||
return {
|
||||
filters: {
|
||||
'company': frm.doc.company,
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onload_post_render: function(frm) {
|
||||
|
@ -408,6 +408,7 @@ class BOM(WebsiteGenerator):
|
||||
self.add_to_cur_exploded_items(frappe._dict({
|
||||
'item_code' : d.item_code,
|
||||
'item_name' : d.item_name,
|
||||
'source_warehouse': d.source_warehouse,
|
||||
'description' : d.description,
|
||||
'image' : d.image,
|
||||
'stock_uom' : d.stock_uom,
|
||||
@ -427,7 +428,8 @@ class BOM(WebsiteGenerator):
|
||||
def get_child_exploded_items(self, bom_no, stock_qty):
|
||||
""" Add all items from Flat BOM of child BOM"""
|
||||
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
|
||||
child_fb_items = frappe.db.sql("""select bom_item.item_code, bom_item.item_name, bom_item.description,
|
||||
child_fb_items = frappe.db.sql("""select bom_item.item_code, bom_item.item_name,
|
||||
bom_item.description, bom_item.source_warehouse,
|
||||
bom_item.stock_uom, bom_item.stock_qty, bom_item.rate,
|
||||
bom_item.stock_qty / ifnull(bom.quantity, 1) as qty_consumed_per_unit
|
||||
from `tabBOM Explosion Item` bom_item, tabBOM bom
|
||||
@ -437,9 +439,10 @@ class BOM(WebsiteGenerator):
|
||||
self.add_to_cur_exploded_items(frappe._dict({
|
||||
'item_code' : d['item_code'],
|
||||
'item_name' : d['item_name'],
|
||||
'source_warehouse' : d['source_warehouse'],
|
||||
'description' : d['description'],
|
||||
'stock_uom' : d['stock_uom'],
|
||||
'stock_qty' : d['qty_consumed_per_unit']*stock_qty,
|
||||
'stock_qty' : d['qty_consumed_per_unit'] * stock_qty,
|
||||
'rate' : flt(d['rate']),
|
||||
}))
|
||||
|
||||
@ -493,6 +496,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
|
||||
item.default_warehouse,
|
||||
item.expense_account as expense_account,
|
||||
item.buying_cost_center as cost_center
|
||||
{select_columns}
|
||||
from
|
||||
`tab{table}` bom_item, `tabBOM` bom, `tabItem` item
|
||||
where
|
||||
@ -501,18 +505,20 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
|
||||
and bom_item.parent = bom.name
|
||||
and item.name = bom_item.item_code
|
||||
and is_stock_item = 1
|
||||
{conditions}
|
||||
group by item_code, stock_uom"""
|
||||
{where_conditions}
|
||||
group by item_code, stock_uom"""
|
||||
|
||||
if fetch_exploded:
|
||||
query = query.format(table="BOM Explosion Item",
|
||||
conditions="""and item.is_sub_contracted_item = 0""")
|
||||
where_conditions="""and item.is_sub_contracted_item = 0""",
|
||||
select_columns = ", bom_item.source_warehouse")
|
||||
items = frappe.db.sql(query, { "qty": qty, "bom": bom }, as_dict=True)
|
||||
elif fetch_scrap_items:
|
||||
query = query.format(table="BOM Scrap Item", conditions="")
|
||||
query = query.format(table="BOM Scrap Item", where_conditions="", select_columns="")
|
||||
items = frappe.db.sql(query, { "qty": qty, "bom": bom }, as_dict=True)
|
||||
else:
|
||||
query = query.format(table="BOM Item", conditions="")
|
||||
query = query.format(table="BOM Item", where_conditions="",
|
||||
select_columns = ", bom_item.source_warehouse")
|
||||
items = frappe.db.sql(query, { "qty": qty, "bom": bom }, as_dict=True)
|
||||
|
||||
for item in items:
|
||||
|
@ -8,7 +8,8 @@
|
||||
"parentfield": "items",
|
||||
"stock_qty": 1.0,
|
||||
"rate": 5000.0,
|
||||
"stock_uom": "_Test UOM"
|
||||
"stock_uom": "_Test UOM",
|
||||
"source_warehouse": "_Test Warehouse - _TC"
|
||||
},
|
||||
{
|
||||
"amount": 2000.0,
|
||||
@ -17,7 +18,8 @@
|
||||
"parentfield": "items",
|
||||
"stock_qty": 2.0,
|
||||
"rate": 1000.0,
|
||||
"stock_uom": "_Test UOM"
|
||||
"stock_uom": "_Test UOM",
|
||||
"source_warehouse": "_Test Warehouse - _TC"
|
||||
}
|
||||
],
|
||||
"docstatus": 1,
|
||||
@ -48,7 +50,8 @@
|
||||
"parentfield": "items",
|
||||
"stock_qty": 1.0,
|
||||
"rate": 5000.0,
|
||||
"stock_uom": "_Test UOM"
|
||||
"stock_uom": "_Test UOM",
|
||||
"source_warehouse": "_Test Warehouse - _TC"
|
||||
},
|
||||
{
|
||||
"amount": 2000.0,
|
||||
@ -57,7 +60,8 @@
|
||||
"parentfield": "items",
|
||||
"stock_qty": 2.0,
|
||||
"rate": 1000.0,
|
||||
"stock_uom": "_Test UOM"
|
||||
"stock_uom": "_Test UOM",
|
||||
"source_warehouse": "_Test Warehouse - _TC"
|
||||
}
|
||||
],
|
||||
"docstatus": 1,
|
||||
@ -86,7 +90,8 @@
|
||||
"parentfield": "items",
|
||||
"stock_qty": 1.0,
|
||||
"rate": 5000.0,
|
||||
"stock_uom": "_Test UOM"
|
||||
"stock_uom": "_Test UOM",
|
||||
"source_warehouse": "_Test Warehouse - _TC"
|
||||
},
|
||||
{
|
||||
"amount": 2000.0,
|
||||
@ -96,7 +101,8 @@
|
||||
"parentfield": "items",
|
||||
"stock_qty": 3.0,
|
||||
"rate": 1000.0,
|
||||
"stock_uom": "_Test UOM"
|
||||
"stock_uom": "_Test UOM",
|
||||
"source_warehouse": "_Test Warehouse - _TC"
|
||||
}
|
||||
],
|
||||
"docstatus": 1,
|
||||
@ -126,7 +132,8 @@
|
||||
"parentfield": "items",
|
||||
"stock_qty": 2.0,
|
||||
"rate": 3000.0,
|
||||
"stock_uom": "_Test UOM"
|
||||
"stock_uom": "_Test UOM",
|
||||
"source_warehouse": "_Test Warehouse - _TC"
|
||||
}
|
||||
],
|
||||
"docstatus": 1,
|
||||
|
@ -7,9 +7,9 @@
|
||||
"beta": 0,
|
||||
"creation": "2013-03-07 11:42:57",
|
||||
"custom": 0,
|
||||
"default_print_format": "Standard",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
@ -104,6 +104,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "source_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Source Warehouse",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Warehouse",
|
||||
"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,
|
||||
@ -481,7 +512,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-06-02 19:29:34.498719",
|
||||
"modified": "2017-07-04 17:51:18.151002",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "BOM Explosion Item",
|
||||
|
@ -22,7 +22,7 @@
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
@ -113,7 +113,7 @@
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
@ -136,6 +136,37 @@
|
||||
"unique": 0,
|
||||
"width": "150px"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "source_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Source Warehouse",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Warehouse",
|
||||
"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,
|
||||
@ -729,7 +760,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-05-23 15:59:37.946963",
|
||||
"modified": "2017-07-04 17:42:37.218408",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "BOM Item",
|
||||
|
@ -327,7 +327,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-05-23 16:04:32.442287",
|
||||
"modified": "2017-07-04 16:04:32.442287",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "BOM Scrap Item",
|
||||
|
@ -7,7 +7,72 @@ frappe.ui.form.on("Production Order", {
|
||||
'Timesheet': 'Make Timesheet',
|
||||
'Stock Entry': 'Make Stock Entry',
|
||||
}
|
||||
|
||||
// Set query for warehouses
|
||||
frm.set_query("wip_warehouse", function(doc) {
|
||||
return {
|
||||
filters: {
|
||||
'company': frm.doc.company,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query("source_warehouse", "required_items", function() {
|
||||
return {
|
||||
filters: {
|
||||
'company': frm.doc.company,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query("fg_warehouse", function() {
|
||||
return {
|
||||
filters: {
|
||||
'company': frm.doc.company,
|
||||
'is_group': 0
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query("scrap_warehouse", function() {
|
||||
return {
|
||||
filters: {
|
||||
'company': frm.doc.company,
|
||||
'is_group': 0
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Set query for BOM
|
||||
frm.set_query("bom_no", function() {
|
||||
if (frm.doc.production_item) {
|
||||
return{
|
||||
query: "erpnext.controllers.queries.bom",
|
||||
filters: {item: cstr(frm.doc.production_item)}
|
||||
}
|
||||
} else msgprint(__("Please enter Production Item first"));
|
||||
});
|
||||
|
||||
// Set query for FG Item
|
||||
frm.set_query("production_item", function() {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.item_query",
|
||||
filters:{
|
||||
'is_stock_item': 1,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Set query for FG Item
|
||||
frm.set_query("project", function() {
|
||||
return{
|
||||
filters:[
|
||||
['Project', 'status', 'not in', 'Completed, Cancelled']
|
||||
]
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
if (!frm.doc.status)
|
||||
frm.doc.status = 'Draft';
|
||||
@ -28,9 +93,8 @@ frappe.ui.form.on("Production Order", {
|
||||
function(doc) { return (frm.doc.qty==doc.completed_qty) ? "green" : "orange" })
|
||||
|
||||
erpnext.production_order.set_custom_buttons(frm);
|
||||
erpnext.production_order.setup_company_filter(frm);
|
||||
erpnext.production_order.setup_bom_filter(frm);
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
erpnext.toggle_naming_series();
|
||||
erpnext.production_order.set_custom_buttons(frm);
|
||||
@ -53,6 +117,7 @@ frappe.ui.form.on("Production Order", {
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
show_progress: function(frm) {
|
||||
var bars = [];
|
||||
var message = '';
|
||||
@ -85,10 +150,83 @@ frappe.ui.form.on("Production Order", {
|
||||
}
|
||||
}
|
||||
frm.dashboard.add_progress(__('Status'), bars, message);
|
||||
},
|
||||
|
||||
production_item: function(frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.production_order.production_order.get_item_details",
|
||||
args: {
|
||||
item: frm.doc.production_item,
|
||||
project: frm.doc.project
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
erpnext.in_production_item_onchange = true;
|
||||
$.each(["description", "stock_uom", "project", "bom_no"], function(i, field) {
|
||||
frm.set_value(field, r.message[field]);
|
||||
});
|
||||
|
||||
if(r.message["set_scrap_wh_mandatory"]){
|
||||
frm.toggle_reqd("scrap_warehouse", true);
|
||||
}
|
||||
erpnext.in_production_item_onchange = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
project: function(frm) {
|
||||
if(!erpnext.in_production_item_onchange) {
|
||||
frm.trigger("production_item");
|
||||
}
|
||||
},
|
||||
|
||||
bom_no: function(frm) {
|
||||
return frm.call({
|
||||
doc: frm.doc,
|
||||
method: "get_items_and_operations_from_bom",
|
||||
callback: function(r) {
|
||||
if(r.message["set_scrap_wh_mandatory"]){
|
||||
frm.toggle_reqd("scrap_warehouse", true);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
use_multi_level_bom: function(frm) {
|
||||
if(frm.doc.bom_no) {
|
||||
frm.trigger("bom_no");
|
||||
}
|
||||
},
|
||||
|
||||
qty: function(frm) {
|
||||
frm.trigger('bom_no');
|
||||
},
|
||||
|
||||
before_submit: function(frm) {
|
||||
frm.toggle_reqd(["fg_warehouse", "wip_warehouse"], true);
|
||||
frm.fields_dict.required_items.grid.toggle_reqd("source_warehouse", true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
frappe.ui.form.on("Production Order Item", {
|
||||
source_warehouse: function(frm, cdt, cdn) {
|
||||
var row = locals[cdt][cdn];
|
||||
if(row.source_warehouse) {
|
||||
frappe.call({
|
||||
"method": "erpnext.stock.utils.get_latest_stock_qty",
|
||||
args: {
|
||||
item_code: row.item_code,
|
||||
warehouse: row.source_warehouse
|
||||
},
|
||||
callback: function (r) {
|
||||
frappe.model.set_value(row.doctype, row.name,
|
||||
"available_qty_at_source_warehouse", r.message);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
frappe.ui.form.on("Production Order Operation", {
|
||||
workstation: function(frm, cdt, cdn) {
|
||||
@ -119,38 +257,45 @@ erpnext.production_order = {
|
||||
var doc = frm.doc;
|
||||
if (doc.docstatus === 1) {
|
||||
if (doc.status != 'Stopped' && doc.status != 'Completed') {
|
||||
frm.add_custom_button(__('Stop'), cur_frm.cscript['Stop Production Order'], __("Status"));
|
||||
frm.add_custom_button(__('Stop'), function() {
|
||||
erpnext.production_order.stop_production_order(frm, "Stopped");
|
||||
}, __("Status"));
|
||||
} else if (doc.status == 'Stopped') {
|
||||
frm.add_custom_button(__('Re-open'), cur_frm.cscript['Unstop Production Order'], __("Status"));
|
||||
frm.add_custom_button(__('Re-open'), function() {
|
||||
erpnext.production_order.stop_production_order(frm, "Resumed");
|
||||
}, __("Status"));
|
||||
}
|
||||
|
||||
|
||||
if(!frm.doc.skip_transfer){
|
||||
if ((flt(doc.material_transferred_for_manufacturing) < flt(doc.qty)) && frm.doc.status != 'Stopped') {
|
||||
if ((flt(doc.material_transferred_for_manufacturing) < flt(doc.qty))
|
||||
&& frm.doc.status != 'Stopped') {
|
||||
frm.has_start_btn = true;
|
||||
var btn = frm.add_custom_button(__('Start'),
|
||||
cur_frm.cscript['Transfer Raw Materials']);
|
||||
btn.addClass('btn-primary');
|
||||
}
|
||||
var start_btn = frm.add_custom_button(__('Start'), function() {
|
||||
erpnext.production_order.make_se(frm, 'Material Transfer for Manufacture');
|
||||
});
|
||||
start_btn.addClass('btn-primary');
|
||||
}
|
||||
}
|
||||
|
||||
if(!frm.doc.skip_transfer){
|
||||
if ((flt(doc.produced_qty) < flt(doc.material_transferred_for_manufacturing)) && frm.doc.status != 'Stopped') {
|
||||
if ((flt(doc.produced_qty) < flt(doc.material_transferred_for_manufacturing))
|
||||
&& frm.doc.status != 'Stopped') {
|
||||
frm.has_finish_btn = true;
|
||||
var btn = frm.add_custom_button(__('Finish'),
|
||||
cur_frm.cscript['Update Finished Goods']);
|
||||
var finish_btn = frm.add_custom_button(__('Finish'), function() {
|
||||
erpnext.production_order.make_se(frm, 'Manufacture');
|
||||
});
|
||||
|
||||
if(doc.material_transferred_for_manufacturing==doc.qty) {
|
||||
// all materials transferred for manufacturing,
|
||||
// make this primary
|
||||
btn.addClass('btn-primary');
|
||||
// all materials transferred for manufacturing, make this primary
|
||||
finish_btn.addClass('btn-primary');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((flt(doc.produced_qty) < flt(doc.qty)) && frm.doc.status != 'Stopped') {
|
||||
frm.has_finish_btn = true;
|
||||
var btn = frm.add_custom_button(__('Finish'),
|
||||
var finish_btn = frm.add_custom_button(__('Finish'),
|
||||
cur_frm.cscript['Update Finished Goods']);
|
||||
btn.addClass('btn-primary');
|
||||
finish_btn.addClass('btn-primary');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -162,8 +307,8 @@ erpnext.production_order = {
|
||||
doc.planned_operating_cost = 0.0;
|
||||
for(var i=0;i<op.length;i++) {
|
||||
var planned_operating_cost = flt(flt(op[i].hour_rate) * flt(op[i].time_in_mins) / 60, 2);
|
||||
frappe.model.set_value('Production Order Operation',op[i].name, "planned_operating_cost", planned_operating_cost);
|
||||
|
||||
frappe.model.set_value('Production Order Operation', op[i].name,
|
||||
"planned_operating_cost", planned_operating_cost);
|
||||
doc.planned_operating_cost += planned_operating_cost;
|
||||
}
|
||||
refresh_field('planned_operating_cost');
|
||||
@ -176,37 +321,10 @@ erpnext.production_order = {
|
||||
frm.set_value("total_operating_cost", (flt(frm.doc.additional_operating_cost) + variable_cost))
|
||||
},
|
||||
|
||||
setup_company_filter: function(frm) {
|
||||
var company_filter = function(doc) {
|
||||
return {
|
||||
filters: {
|
||||
'company': frm.doc.company,
|
||||
'is_group': 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frm.fields_dict.source_warehouse.get_query = company_filter;
|
||||
frm.fields_dict.fg_warehouse.get_query = company_filter;
|
||||
frm.fields_dict.wip_warehouse.get_query = company_filter;
|
||||
},
|
||||
|
||||
setup_bom_filter: function(frm) {
|
||||
frm.set_query("bom_no", function(doc) {
|
||||
if (doc.production_item) {
|
||||
return{
|
||||
query: "erpnext.controllers.queries.bom",
|
||||
filters: {item: cstr(doc.production_item)}
|
||||
}
|
||||
} else frappe.msgprint(__("Please enter Production Item first"));
|
||||
});
|
||||
},
|
||||
|
||||
set_default_warehouse: function(frm) {
|
||||
if (!(frm.doc.wip_warehouse || frm.doc.fg_warehouse)) {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.production_order.production_order.get_default_warehouse",
|
||||
|
||||
callback: function(r) {
|
||||
if(!r.exe) {
|
||||
frm.set_value("wip_warehouse", r.message.wip_warehouse);
|
||||
@ -215,45 +333,15 @@ erpnext.production_order = {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$.extend(cur_frm.cscript, {
|
||||
before_submit: function() {
|
||||
cur_frm.toggle_reqd(["fg_warehouse", "wip_warehouse"], true);
|
||||
},
|
||||
|
||||
production_item: function(doc) {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.production_order.production_order.get_item_details",
|
||||
args: {
|
||||
item: doc.production_item,
|
||||
project: doc.project
|
||||
},
|
||||
callback: function(r) {
|
||||
$.each(["description", "stock_uom", "project", "bom_no"], function(i, field) {
|
||||
cur_frm.set_value(field, r.message[field]);
|
||||
});
|
||||
|
||||
if(r.message["set_scrap_wh_mandatory"]){
|
||||
cur_frm.toggle_reqd("scrap_warehouse", true);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
project: function(doc) {
|
||||
cur_frm.cscript.production_item(doc)
|
||||
},
|
||||
|
||||
make_se: function(purpose) {
|
||||
var me = this;
|
||||
if(!this.frm.doc.skip_transfer){
|
||||
|
||||
make_se: function(frm, purpose) {
|
||||
if(!frm.doc.skip_transfer){
|
||||
var max = (purpose === "Manufacture") ?
|
||||
flt(this.frm.doc.material_transferred_for_manufacturing) - flt(this.frm.doc.produced_qty) :
|
||||
flt(this.frm.doc.qty) - flt(this.frm.doc.material_transferred_for_manufacturing);
|
||||
flt(frm.doc.material_transferred_for_manufacturing) - flt(frm.doc.produced_qty) :
|
||||
flt(frm.doc.qty) - flt(frm.doc.material_transferred_for_manufacturing);
|
||||
} else {
|
||||
var max = flt(this.frm.doc.qty) - flt(this.frm.doc.produced_qty);
|
||||
var max = flt(frm.doc.qty) - flt(frm.doc.produced_qty);
|
||||
}
|
||||
|
||||
frappe.prompt({fieldtype:"Float", label: __("Qty for {0}", [purpose]), fieldname:"qty",
|
||||
@ -266,7 +354,7 @@ $.extend(cur_frm.cscript, {
|
||||
frappe.call({
|
||||
method:"erpnext.manufacturing.doctype.production_order.production_order.make_stock_entry",
|
||||
args: {
|
||||
"production_order_id": me.frm.doc.name,
|
||||
"production_order_id": frm.doc.name,
|
||||
"purpose": purpose,
|
||||
"qty": data.qty
|
||||
},
|
||||
@ -277,59 +365,20 @@ $.extend(cur_frm.cscript, {
|
||||
});
|
||||
}, __("Select Quantity"), __("Make"));
|
||||
},
|
||||
|
||||
bom_no: function() {
|
||||
return this.frm.call({
|
||||
doc: this.frm.doc,
|
||||
method: "set_production_order_operations",
|
||||
|
||||
stop_production_order: function(frm, status) {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.production_order.production_order.stop_unstop",
|
||||
args: {
|
||||
production_order: frm.doc.name,
|
||||
status: status
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message["set_scrap_wh_mandatory"]){
|
||||
cur_frm.toggle_reqd("scrap_warehouse", true);
|
||||
if(r.message) {
|
||||
frm.set_value("status", r.message);
|
||||
frm.reload_doc();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
use_multi_level_bom: function() {
|
||||
if(this.frm.doc.bom_no) {
|
||||
this.frm.trigger("bom_no");
|
||||
}
|
||||
},
|
||||
|
||||
qty: function() {
|
||||
frappe.ui.form.trigger("Production Order", 'bom_no')
|
||||
},
|
||||
});
|
||||
|
||||
cur_frm.cscript['Stop Production Order'] = function() {
|
||||
$c_obj(cur_frm.doc, 'stop_unstop', 'Stopped', function(r, rt) {cur_frm.refresh();});
|
||||
}
|
||||
|
||||
cur_frm.cscript['Unstop Production Order'] = function() {
|
||||
$c_obj(cur_frm.doc, 'stop_unstop', 'Unstopped', function(r, rt) {cur_frm.refresh();});
|
||||
}
|
||||
|
||||
cur_frm.cscript['Transfer Raw Materials'] = function() {
|
||||
cur_frm.cscript.make_se('Material Transfer for Manufacture');
|
||||
}
|
||||
|
||||
cur_frm.cscript['Update Finished Goods'] = function() {
|
||||
cur_frm.cscript.make_se('Manufacture');
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['production_item'].get_query = function(doc) {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.item_query",
|
||||
filters:{
|
||||
'is_stock_item': 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['project'].get_query = function(doc, dt, dn) {
|
||||
return{
|
||||
filters:[
|
||||
['Project', 'status', 'not in', 'Completed, Cancelled']
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
@ -95,7 +95,7 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "status",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nDraft\nSubmitted\nNot Started\nStopped\nUnstopped\nIn Process\nCompleted\nCancelled",
|
||||
"options": "\nDraft\nSubmitted\nNot Started\nIn Process\nCompleted\nStopped\nCancelled",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
@ -139,38 +139,6 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Project",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "project",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"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,
|
||||
@ -266,37 +234,6 @@
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Sales Order",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"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,
|
||||
@ -329,37 +266,6 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Check if material transfer entry is not required",
|
||||
"fieldname": "skip_transfer",
|
||||
"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": "Skip Material Transfer",
|
||||
"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,
|
||||
@ -427,6 +333,100 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Sales Order",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"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": "project",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Project",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "project",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"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,
|
||||
"description": "Check if material transfer entry is not required",
|
||||
"fieldname": "skip_transfer",
|
||||
"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": "Skip Material Transfer",
|
||||
"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,
|
||||
@ -457,38 +457,6 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fieldname": "source_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Source Warehouse (for reserving Items)",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Warehouse",
|
||||
"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,
|
||||
@ -519,34 +487,6 @@
|
||||
"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,
|
||||
"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,
|
||||
@ -579,6 +519,34 @@
|
||||
"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,
|
||||
"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,
|
||||
@ -616,7 +584,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "time",
|
||||
"fieldname": "required_items_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -625,10 +593,9 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Time",
|
||||
"label": "Required Items",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "fa fa-time",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -647,9 +614,8 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "expected_delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"fieldname": "required_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@ -657,10 +623,43 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Expected Delivery Date",
|
||||
"label": "Required Items",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Production Order Item",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"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": "time",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Time",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "fa fa-time",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
@ -708,7 +707,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "planned_end_date",
|
||||
"fieldname": "actual_start_date",
|
||||
"fieldtype": "Datetime",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -717,9 +716,9 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Planned End Date",
|
||||
"label": "Actual Start Date",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -767,7 +766,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "actual_start_date",
|
||||
"fieldname": "planned_end_date",
|
||||
"fieldtype": "Datetime",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -776,9 +775,9 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Actual Start Date",
|
||||
"label": "Planned End Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -821,6 +820,36 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "expected_delivery_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": "Expected Delivery Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"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,
|
||||
@ -1070,67 +1099,6 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fieldname": "required_items_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Required Items",
|
||||
"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": "required_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Required Items",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Production Order Item",
|
||||
"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,
|
||||
|
@ -3,24 +3,21 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
import json
|
||||
from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate
|
||||
from frappe import _
|
||||
from frappe.utils import time_diff_in_seconds
|
||||
from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate
|
||||
from frappe.model.document import Document
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
|
||||
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, get_bom_items_as_dict
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from erpnext.stock.doctype.item.item import validate_end_of_life
|
||||
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError, NotInWorkingHoursError
|
||||
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
|
||||
from erpnext.projects.doctype.timesheet.timesheet import OverlapError
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry import get_additional_costs
|
||||
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
|
||||
from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
|
||||
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
|
||||
from erpnext.stock.utils import get_bin
|
||||
from frappe.utils.csvutils import getlink
|
||||
from erpnext.stock.utils import get_bin, validate_warehouse_company, get_latest_stock_qty
|
||||
from erpnext.utilities.transaction_base import validate_uom_is_integer
|
||||
|
||||
class OverProductionError(frappe.ValidationError): pass
|
||||
class StockOverProductionError(frappe.ValidationError): pass
|
||||
@ -38,15 +35,19 @@ class ProductionOrder(Document):
|
||||
validate_bom_no(self.production_item, self.bom_no)
|
||||
|
||||
self.validate_sales_order()
|
||||
self.validate_warehouse()
|
||||
self.validate_warehouse_belongs_to_company()
|
||||
self.calculate_operating_cost()
|
||||
self.validate_qty()
|
||||
self.validate_operation_time()
|
||||
self.status = self.get_status()
|
||||
|
||||
from erpnext.utilities.transaction_base import validate_uom_is_integer
|
||||
validate_uom_is_integer(self, "stock_uom", ["qty", "produced_qty"])
|
||||
|
||||
if not self.get("required_items"):
|
||||
self.set_required_items()
|
||||
else:
|
||||
self.set_available_qty()
|
||||
|
||||
def validate_sales_order(self):
|
||||
if self.sales_order:
|
||||
so = frappe.db.sql("""select name, delivery_date, project from `tabSales Order`
|
||||
@ -64,11 +65,14 @@ class ProductionOrder(Document):
|
||||
else:
|
||||
frappe.throw(_("Sales Order {0} is not valid").format(self.sales_order))
|
||||
|
||||
def validate_warehouse(self):
|
||||
from erpnext.stock.utils import validate_warehouse_company
|
||||
def validate_warehouse_belongs_to_company(self):
|
||||
warehouses = [self.fg_warehouse, self.wip_warehouse]
|
||||
for d in self.get("required_items"):
|
||||
if d.source_warehouse not in warehouses:
|
||||
warehouses.append(d.source_warehouse)
|
||||
|
||||
for w in [self.source_warehouse, self.fg_warehouse, self.wip_warehouse]:
|
||||
validate_warehouse_company(w, self.company)
|
||||
for wh in warehouses:
|
||||
validate_warehouse_company(wh, self.company)
|
||||
|
||||
def calculate_operating_cost(self):
|
||||
self.planned_operating_cost, self.actual_operating_cost = 0.0, 0.0
|
||||
@ -79,7 +83,8 @@ class ProductionOrder(Document):
|
||||
self.planned_operating_cost += flt(d.planned_operating_cost)
|
||||
self.actual_operating_cost += flt(d.actual_operating_cost)
|
||||
|
||||
variable_cost = self.actual_operating_cost if self.actual_operating_cost else self.planned_operating_cost
|
||||
variable_cost = self.actual_operating_cost if self.actual_operating_cost \
|
||||
else self.planned_operating_cost
|
||||
self.total_operating_cost = flt(self.additional_operating_cost) + flt(variable_cost)
|
||||
|
||||
def validate_production_order_against_so(self):
|
||||
@ -101,22 +106,16 @@ class ProductionOrder(Document):
|
||||
# total qty in SO
|
||||
so_qty = flt(so_item_qty) + flt(dnpi_qty)
|
||||
|
||||
allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings", "over_production_allowance_percentage"))
|
||||
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)
|
||||
|
||||
def stop_unstop(self, status):
|
||||
""" Called from client side on Stop/Unstop event"""
|
||||
status = self.update_status(status)
|
||||
self.update_planned_qty()
|
||||
frappe.msgprint(_("Production Order status is {0}").format(status))
|
||||
self.notify_update()
|
||||
|
||||
frappe.throw(_("Cannot produce more Item {0} than Sales Order quantity {1}")
|
||||
.format(self.production_item, so_qty), OverProductionError)
|
||||
|
||||
def update_status(self, status=None):
|
||||
'''Update status of production order if unknown'''
|
||||
if not status:
|
||||
if status != "Stopped":
|
||||
status = self.get_status(status)
|
||||
|
||||
if status != self.status:
|
||||
@ -167,7 +166,6 @@ class ProductionOrder(Document):
|
||||
self.db_set(fieldname, qty)
|
||||
|
||||
def before_submit(self):
|
||||
self.set_required_items()
|
||||
self.make_time_logs()
|
||||
|
||||
def on_submit(self):
|
||||
@ -184,10 +182,10 @@ class ProductionOrder(Document):
|
||||
self.validate_cancel()
|
||||
|
||||
frappe.db.set(self,'status', 'Cancelled')
|
||||
self.clear_required_items()
|
||||
self.delete_timesheet()
|
||||
self.update_completed_qty_in_material_request()
|
||||
self.update_planned_qty()
|
||||
self.update_reserved_qty_for_production()
|
||||
|
||||
def validate_cancel(self):
|
||||
if self.status == "Stopped":
|
||||
@ -214,12 +212,11 @@ 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
|
||||
|
||||
self.set('operations', [])
|
||||
|
||||
if self.use_multi_level_bom:
|
||||
bom_list = frappe.get_doc("BOM", self.bom_no).traverse_tree()
|
||||
@ -240,8 +237,6 @@ class ProductionOrder(Document):
|
||||
self.set('operations', operations)
|
||||
self.calculate_time()
|
||||
|
||||
return check_if_scrap_warehouse_mandatory(self.bom_no)
|
||||
|
||||
def calculate_time(self):
|
||||
bom_qty = frappe.db.get_value("BOM", self.bom_no, "quantity")
|
||||
|
||||
@ -403,62 +398,60 @@ class ProductionOrder(Document):
|
||||
update bin reserved_qty_for_production
|
||||
called from Stock Entry for production, after submit, cancel
|
||||
'''
|
||||
if self.docstatus==1 and self.source_warehouse:
|
||||
if self.material_transferred_for_manufacturing == self.produced_qty:
|
||||
# clear required items table and save document
|
||||
self.clear_required_items()
|
||||
else:
|
||||
# calculate transferred qty based on submitted
|
||||
# stock entries
|
||||
self.update_transaferred_qty_for_required_items()
|
||||
if self.docstatus==1:
|
||||
# calculate transferred qty based on submitted stock entries
|
||||
self.update_transaferred_qty_for_required_items()
|
||||
|
||||
# update in bin
|
||||
self.update_reserved_qty_for_production()
|
||||
|
||||
def clear_required_items(self):
|
||||
'''Remove the required_items table and update the bins'''
|
||||
items = [d.item_code for d in self.required_items]
|
||||
self.required_items = []
|
||||
|
||||
self.update_child_table('required_items')
|
||||
|
||||
# completed, update reserved qty in bin
|
||||
self.update_reserved_qty_for_production(items)
|
||||
# update in bin
|
||||
self.update_reserved_qty_for_production()
|
||||
|
||||
def update_reserved_qty_for_production(self, items=None):
|
||||
'''update reserved_qty_for_production in bins'''
|
||||
if not self.source_warehouse:
|
||||
return
|
||||
|
||||
if not items:
|
||||
items = [d.item_code for d in self.required_items]
|
||||
|
||||
for item in items:
|
||||
stock_bin = get_bin(item, self.source_warehouse)
|
||||
stock_bin.update_reserved_qty_for_production()
|
||||
for d in self.required_items:
|
||||
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)
|
||||
|
||||
def set_required_items(self):
|
||||
'''set required_items for production to keep track of reserved qty'''
|
||||
if self.source_warehouse:
|
||||
self.required_items = []
|
||||
if self.bom_no and self.qty:
|
||||
item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty,
|
||||
fetch_exploded = self.use_multi_level_bom)
|
||||
|
||||
for item in item_dict.values():
|
||||
self.append('required_items', {'item_code': item.item_code,
|
||||
'required_qty': item.qty})
|
||||
|
||||
#print frappe.as_json(self.required_items)
|
||||
self.append('required_items', {
|
||||
'item_code': item.item_code,
|
||||
'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):
|
||||
'''update transferred qty from submitted stock entries for that item against
|
||||
the production order'''
|
||||
|
||||
for d in self.required_items:
|
||||
transferred_qty = frappe.db.sql('''select count(qty)
|
||||
transferred_qty = frappe.db.sql('''select sum(qty)
|
||||
from `tabStock Entry` entry, `tabStock Entry Detail` detail
|
||||
where
|
||||
entry.production_order = %s
|
||||
entry.purpose = "Material Transfer for Manufacture"
|
||||
and entry.purpose = "Material Transfer for Manufacture"
|
||||
and entry.docstatus = 1
|
||||
and detail.parent = entry.name
|
||||
and detail.item_code = %s''', (self.name, d.item_code))[0][0]
|
||||
@ -496,10 +489,12 @@ def get_item_details(item, project = None):
|
||||
|
||||
if not res["bom_no"]:
|
||||
if project:
|
||||
frappe.throw(_("Default BOM for {0} not found for Project {1}").format(item, project))
|
||||
frappe.throw(_("Default BOM for {0} not found").format(item))
|
||||
res = get_item_details(item)
|
||||
frappe.msgprint(_("Default BOM not found for Item {0} and Project {1}").format(item, project))
|
||||
else:
|
||||
frappe.throw(_("Default BOM for {0} not found").format(item))
|
||||
|
||||
res['project'] = frappe.db.get_value('BOM', res['bom_no'], 'project')
|
||||
res['project'] = project or frappe.db.get_value('BOM', res['bom_no'], 'project')
|
||||
res.update(check_if_scrap_warehouse_mandatory(res["bom_no"]))
|
||||
|
||||
return res
|
||||
@ -507,16 +502,21 @@ def get_item_details(item, project = None):
|
||||
@frappe.whitelist()
|
||||
def check_if_scrap_warehouse_mandatory(bom_no):
|
||||
res = {"set_scrap_wh_mandatory": False }
|
||||
bom = frappe.get_doc("BOM", bom_no)
|
||||
if bom_no:
|
||||
bom = frappe.get_doc("BOM", bom_no)
|
||||
|
||||
if len(bom.scrap_items) > 0:
|
||||
res["set_scrap_wh_mandatory"] = True
|
||||
if len(bom.scrap_items) > 0:
|
||||
res["set_scrap_wh_mandatory"] = True
|
||||
|
||||
return res
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_stock_entry(production_order_id, purpose, qty=None):
|
||||
production_order = frappe.get_doc("Production Order", production_order_id)
|
||||
if not frappe.db.get_value("Warehouse", production_order.wip_warehouse, "is_group"):
|
||||
wip_warehouse = production_order.wip_warehouse
|
||||
else:
|
||||
wip_warehouse = None
|
||||
|
||||
stock_entry = frappe.new_doc("Stock Entry")
|
||||
stock_entry.purpose = purpose
|
||||
@ -528,12 +528,10 @@ def make_stock_entry(production_order_id, purpose, qty=None):
|
||||
stock_entry.fg_completed_qty = qty or (flt(production_order.qty) - flt(production_order.produced_qty))
|
||||
|
||||
if purpose=="Material Transfer for Manufacture":
|
||||
if production_order.source_warehouse:
|
||||
stock_entry.from_warehouse = production_order.source_warehouse
|
||||
stock_entry.to_warehouse = production_order.wip_warehouse
|
||||
stock_entry.to_warehouse = wip_warehouse
|
||||
stock_entry.project = production_order.project
|
||||
else:
|
||||
stock_entry.from_warehouse = production_order.wip_warehouse
|
||||
stock_entry.from_warehouse = wip_warehouse
|
||||
stock_entry.to_warehouse = production_order.fg_warehouse
|
||||
additional_costs = get_additional_costs(production_order, fg_qty=stock_entry.fg_completed_qty)
|
||||
stock_entry.project = production_order.project
|
||||
@ -601,3 +599,18 @@ def make_new_timesheet(source_name, target_doc=None):
|
||||
frappe.throw(_("Already completed"))
|
||||
|
||||
return ts
|
||||
|
||||
@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
|
@ -8,7 +8,7 @@ import frappe
|
||||
from frappe.utils import flt, time_diff_in_hours, now, add_days, cint
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||
from erpnext.manufacturing.doctype.production_order.production_order \
|
||||
import make_stock_entry, ItemHasVariantError
|
||||
import make_stock_entry, ItemHasVariantError, stop_unstop
|
||||
from erpnext.stock.doctype.stock_entry import test_stock_entry
|
||||
from erpnext.stock.doctype.item.test_item import get_total_projected_qty
|
||||
from erpnext.stock.utils import get_bin
|
||||
@ -228,10 +228,46 @@ class TestProductionOrder(unittest.TestCase):
|
||||
cint(bin1_on_start_production.reserved_qty_for_production))
|
||||
self.assertEqual(cint(bin1_on_end_production.projected_qty),
|
||||
cint(bin1_on_end_production.projected_qty))
|
||||
|
||||
def test_reserved_qty_for_stopped_production(self):
|
||||
test_stock_entry.make_stock_entry(item_code="_Test Item",
|
||||
target= self.warehouse, qty=100, basic_rate=100)
|
||||
test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
|
||||
target= self.warehouse, qty=100, basic_rate=100)
|
||||
|
||||
# required_items removed
|
||||
self.pro_order.reload()
|
||||
self.assertEqual(len(self.pro_order.required_items), 0)
|
||||
# 0 0 0
|
||||
|
||||
self.test_reserved_qty_for_production_submit()
|
||||
|
||||
#2 0 -2
|
||||
|
||||
s = frappe.get_doc(make_stock_entry(self.pro_order.name,
|
||||
"Material Transfer for Manufacture", 1))
|
||||
|
||||
s.submit()
|
||||
|
||||
#1 -1 0
|
||||
|
||||
bin1_on_start_production = get_bin(self.item, self.warehouse)
|
||||
|
||||
# reserved_qty_for_producion updated
|
||||
self.assertEqual(cint(self.bin1_at_start.reserved_qty_for_production) + 1,
|
||||
cint(bin1_on_start_production.reserved_qty_for_production))
|
||||
|
||||
# projected qty will now be 2 less (becuase of item movement)
|
||||
self.assertEqual(cint(self.bin1_at_start.projected_qty),
|
||||
cint(bin1_on_start_production.projected_qty) + 2)
|
||||
|
||||
# STOP
|
||||
stop_unstop(self.pro_order.name, "Stopped")
|
||||
|
||||
bin1_on_stop_production = get_bin(self.item, self.warehouse)
|
||||
|
||||
# no change in reserved / projected
|
||||
self.assertEqual(cint(bin1_on_stop_production.reserved_qty_for_production),
|
||||
cint(self.bin1_at_start.reserved_qty_for_production))
|
||||
self.assertEqual(cint(bin1_on_stop_production.projected_qty) + 1,
|
||||
cint(self.bin1_at_start.projected_qty))
|
||||
|
||||
def test_scrap_material_qty(self):
|
||||
prod_order = make_prod_order_test_record(planned_start_date=now(), qty=2)
|
||||
@ -286,10 +322,11 @@ def make_prod_order_test_record(**args):
|
||||
pro_order.company = args.company or "_Test Company"
|
||||
pro_order.stock_uom = args.stock_uom or "_Test UOM"
|
||||
pro_order.use_multi_level_bom=0
|
||||
pro_order.set_production_order_operations()
|
||||
|
||||
pro_order.get_items_and_operations_from_bom()
|
||||
|
||||
if args.source_warehouse:
|
||||
pro_order.source_warehouse = args.source_warehouse
|
||||
for item in pro_order.get("required_items"):
|
||||
item.source_warehouse = args.source_warehouse
|
||||
|
||||
if args.planned_start_date:
|
||||
pro_order.planned_start_date = args.planned_start_date
|
||||
|
@ -13,6 +13,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -43,6 +44,157 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "source_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 1,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Source Warehouse",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Warehouse",
|
||||
"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_3",
|
||||
"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": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "item_name",
|
||||
"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": "Item Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"columns": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text",
|
||||
"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": "Description",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"columns": 0,
|
||||
"fieldname": "qty_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Qty",
|
||||
"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,
|
||||
@ -72,6 +224,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -99,6 +252,95 @@
|
||||
"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_9",
|
||||
"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": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "available_qty_at_source_warehouse",
|
||||
"fieldtype": "Float",
|
||||
"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": "Available Qty at Source Warehouse",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"columns": 0,
|
||||
"fieldname": "available_qty_at_wip_warehouse",
|
||||
"fieldtype": "Float",
|
||||
"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": "Available Qty at WIP Warehouse",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
@ -111,7 +353,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-03-28 14:18:36.342161",
|
||||
"modified": "2017-05-15 17:37:20.212361",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Order Item",
|
||||
|
@ -13,6 +13,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -42,6 +43,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -74,6 +76,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -85,7 +88,7 @@
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "BOM",
|
||||
"length": 0,
|
||||
@ -104,6 +107,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -135,6 +139,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -163,6 +168,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -193,6 +199,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -224,6 +231,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -256,6 +264,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -285,6 +294,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -314,6 +324,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -343,6 +354,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -371,6 +383,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -403,6 +416,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -434,6 +448,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -464,6 +479,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -493,6 +509,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -522,6 +539,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -552,6 +570,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -580,6 +599,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -610,6 +630,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -651,7 +672,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-03-27 15:56:29.010336",
|
||||
"modified": "2017-05-29 18:02:04.252419",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Order Operation",
|
||||
|
@ -410,4 +410,7 @@ erpnext.patches.v8_0.save_system_settings
|
||||
erpnext.patches.v8_1.delete_deprecated_reports
|
||||
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
|
||||
erpnext.patches.v8_1.removed_roles_from_gst_report_non_indian_account
|
||||
erpnext.patches.v8_1.gst_fixes #2017-07-06
|
||||
erpnext.patches.v8_0.update_production_orders
|
||||
erpnext.patches.v8_1.remove_sales_invoice_from_returned_serial_no
|
@ -73,7 +73,7 @@ def validate_parent_account_for_warehouse(company=None):
|
||||
if not company:
|
||||
return
|
||||
|
||||
if cint(erpnext.is_perpetual_inventory_enabled(company)):
|
||||
if cint(erpnext.is_perpetual_inventory_enabled(company.name)):
|
||||
parent_account = frappe.db.sql("""select name from tabAccount
|
||||
where account_type='Stock' and company=%s and is_group=1
|
||||
and (warehouse is null or warehouse = '')""", company.name)
|
||||
|
44
erpnext/patches/v8_0/update_production_orders.py
Normal file
@ -0,0 +1,44 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
# reload schema
|
||||
for doctype in ("Production Order", "Production Order Item", "Production Order Operation",
|
||||
"BOM Item", "BOM Explosion Item", "BOM"):
|
||||
frappe.reload_doctype(doctype)
|
||||
|
||||
# fetch all draft and submitted production orders
|
||||
fields = ["name"]
|
||||
if "source_warehouse" in frappe.db.get_table_columns("Production Order"):
|
||||
fields.append("source_warehouse")
|
||||
|
||||
pro_orders = frappe.get_all("Production Order", filters={"docstatus": ["!=", 2]}, fields=fields)
|
||||
|
||||
for p in pro_orders:
|
||||
pro_order = frappe.get_doc("Production Order", p.name)
|
||||
|
||||
# set required items table
|
||||
pro_order.set_required_items()
|
||||
|
||||
for item in pro_order.get("required_items"):
|
||||
# set source warehouse based on parent
|
||||
if not item.source_warehouse and "source_warehouse" in fields:
|
||||
item.source_warehouse = pro_order.get("source_warehouse")
|
||||
item.db_update()
|
||||
|
||||
if pro_order.docstatus == 1:
|
||||
# update transferred qty based on Stock Entry, it also updates db
|
||||
pro_order.update_transaferred_qty_for_required_items()
|
||||
|
||||
# Set status where it was 'Unstopped', as it is deprecated
|
||||
if pro_order.status == "Unstopped":
|
||||
status = pro_order.get_status()
|
||||
pro_order.db_set("status", status)
|
||||
elif pro_order.status == "Stopped":
|
||||
pro_order.update_reserved_qty_for_production()
|
||||
|
||||
|
||||
|
58
erpnext/patches/v8_1/gst_fixes.py
Normal file
@ -0,0 +1,58 @@
|
||||
import frappe
|
||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
||||
from erpnext.regional.india.setup import update_address_template
|
||||
|
||||
def execute():
|
||||
company = frappe.get_all('Company', filters = {'country': 'India'})
|
||||
if not company:
|
||||
return
|
||||
|
||||
update_existing_custom_fields()
|
||||
add_custom_fields()
|
||||
update_address_template()
|
||||
frappe.reload_doc("regional", "print_format", "gst_tax_invoice")
|
||||
|
||||
def update_existing_custom_fields():
|
||||
frappe.db.sql("""update `tabCustom Field` set label = 'HSN/SAC'
|
||||
where fieldname='gst_hsn_code' and label='GST HSN Code'
|
||||
""")
|
||||
|
||||
frappe.db.sql("""update `tabCustom Field` set print_hide = 1
|
||||
where fieldname in ('customer_gstin', 'supplier_gstin', 'company_gstin')
|
||||
""")
|
||||
|
||||
frappe.db.sql("""update `tabCustom Field` set insert_after = 'address_display'
|
||||
where fieldname in ('customer_gstin', 'supplier_gstin')
|
||||
""")
|
||||
|
||||
frappe.db.sql("""update `tabCustom Field` set insert_after = 'company_address_display'
|
||||
where fieldname = 'company_gstin'
|
||||
""")
|
||||
|
||||
frappe.db.sql("""update `tabCustom Field` set insert_after = 'description'
|
||||
where fieldname='gst_hsn_code' and dt in ('Sales Invoice Item', 'Purchase Invoice Item')
|
||||
""")
|
||||
|
||||
def add_custom_fields():
|
||||
hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
|
||||
fieldtype='Data', options='item_code.gst_hsn_code', insert_after='description')
|
||||
|
||||
custom_fields = {
|
||||
'Address': [
|
||||
dict(fieldname='gst_state_number', label='GST State Number',
|
||||
fieldtype='Int', insert_after='gst_state'),
|
||||
],
|
||||
'Sales Invoice': [
|
||||
dict(fieldname='invoice_copy', label='Invoice Copy',
|
||||
fieldtype='Select', insert_after='project', print_hide=1,
|
||||
options='ORIGINAL FOR RECIPIENT\nDUPLICATE FOR TRANSPORTER\nTRIPLICATE FOR SUPPLIER'),
|
||||
],
|
||||
'Sales Order Item': [hsn_sac_field],
|
||||
'Delivery Note Item': [hsn_sac_field],
|
||||
'Purchase Order Item': [hsn_sac_field],
|
||||
'Purchase Receipt Item': [hsn_sac_field]
|
||||
}
|
||||
|
||||
for doctype, fields in custom_fields.items():
|
||||
for df in fields:
|
||||
create_custom_field(doctype, df)
|
@ -0,0 +1,18 @@
|
||||
# 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("Serial No")
|
||||
|
||||
frappe.db.sql("""
|
||||
update
|
||||
`tabSerial No`
|
||||
set
|
||||
sales_invoice = NULL
|
||||
where
|
||||
sales_invoice in (select return_against from
|
||||
`tabSales Invoice` where docstatus =1 and is_return=1)
|
||||
and sales_invoice is not null and sales_invoice !='' """)
|
@ -215,7 +215,7 @@ if(!erpnext.taxes.flags[cur_frm.cscript.tax_table]) {
|
||||
erpnext.taxes.set_conditional_mandatory_rate_or_amount(open_form);
|
||||
} else {
|
||||
// apply in current row
|
||||
erpnext.taxes.set_conditional_mandatory_rate_or_amount(frm.get_field('taxes').grid.get_grid_row(cdn));
|
||||
erpnext.taxes.set_conditional_mandatory_rate_or_amount(frm.get_field('taxes').grid.get_row(cdn));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -634,5 +634,92 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
}
|
||||
|
||||
this.calculate_outstanding_amount(false)
|
||||
},
|
||||
|
||||
show_item_wise_taxes: function() {
|
||||
if(this.frm.fields_dict.other_charges_calculation) {
|
||||
this.frm.toggle_display("other_charges_calculation", this.frm.doc.other_charges_calculation);
|
||||
}
|
||||
},
|
||||
|
||||
set_item_wise_tax_breakup: function() {
|
||||
if(this.frm.fields_dict.other_charges_calculation) {
|
||||
var html = this.get_item_wise_taxes_html();
|
||||
// console.log(html);
|
||||
this.frm.set_value("other_charges_calculation", html);
|
||||
this.show_item_wise_taxes();
|
||||
}
|
||||
},
|
||||
|
||||
get_item_wise_taxes_html: function() {
|
||||
var item_tax = {};
|
||||
var tax_accounts = [];
|
||||
var company_currency = this.get_company_currency();
|
||||
|
||||
$.each(this.frm.doc["taxes"] || [], function(i, tax) {
|
||||
var tax_amount_precision = precision("tax_amount", tax);
|
||||
var tax_rate_precision = precision("rate", tax);
|
||||
$.each(JSON.parse(tax.item_wise_tax_detail || '{}'),
|
||||
function(item_code, tax_data) {
|
||||
if(!item_tax[item_code]) item_tax[item_code] = {};
|
||||
if($.isArray(tax_data)) {
|
||||
var tax_rate = "";
|
||||
if(tax_data[0] != null) {
|
||||
tax_rate = (tax.charge_type === "Actual") ?
|
||||
format_currency(flt(tax_data[0], tax_amount_precision),
|
||||
company_currency, tax_amount_precision) :
|
||||
(flt(tax_data[0], tax_rate_precision) + "%");
|
||||
}
|
||||
var tax_amount = format_currency(flt(tax_data[1], tax_amount_precision),
|
||||
company_currency, tax_amount_precision);
|
||||
|
||||
item_tax[item_code][tax.name] = [tax_rate, tax_amount];
|
||||
} else {
|
||||
item_tax[item_code][tax.name] = [flt(tax_data, tax_rate_precision) + "%", ""];
|
||||
}
|
||||
});
|
||||
tax_accounts.push([tax.name, tax.account_head]);
|
||||
});
|
||||
|
||||
var headings = $.map([__("Item Name"), __("Taxable Amount")].concat($.map(tax_accounts,
|
||||
function(head) { return head[1]; })), function(head) {
|
||||
if(head==__("Item Name")) {
|
||||
return '<th style="min-width: 100px;" class="text-left">' + (head || "") + "</th>";
|
||||
} else {
|
||||
return '<th style="min-width: 80px;" class="text-right">' + (head || "") + "</th>";
|
||||
}
|
||||
}
|
||||
).join("\n");
|
||||
|
||||
var distinct_item_names = [];
|
||||
var distinct_items = [];
|
||||
$.each(this.frm.doc["items"] || [], function(i, item) {
|
||||
if(distinct_item_names.indexOf(item.item_code || item.item_name)===-1) {
|
||||
distinct_item_names.push(item.item_code || item.item_name);
|
||||
distinct_items.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
var rows = $.map(distinct_items, function(item) {
|
||||
var item_tax_record = item_tax[item.item_code || item.item_name];
|
||||
if(!item_tax_record) { return null; }
|
||||
return repl("<tr><td>%(item_name)s</td><td class='text-right'>%(taxable_amount)s</td>%(taxes)s</tr>", {
|
||||
item_name: item.item_name,
|
||||
taxable_amount: format_currency(item.net_amount,
|
||||
company_currency, precision("net_amount", item)),
|
||||
taxes: $.map(tax_accounts, function(head) {
|
||||
return item_tax_record[head[0]] ?
|
||||
"<td class='text-right'>(" + item_tax_record[head[0]][0] + ") " + item_tax_record[head[0]][1] + "</td>" :
|
||||
"<td></td>";
|
||||
}).join("\n")
|
||||
});
|
||||
}).join("\n");
|
||||
|
||||
if(!rows) return "";
|
||||
return '<div class="tax-break-up" style="overflow-x: auto;">\
|
||||
<table class="table table-bordered table-hover">\
|
||||
<thead><tr>' + headings + '</tr></thead> \
|
||||
<tbody>' + rows + '</tbody> \
|
||||
</table></div>';
|
||||
}
|
||||
})
|
||||
|
@ -374,6 +374,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
|
||||
validate: function() {
|
||||
this.calculate_taxes_and_totals(false);
|
||||
this.set_item_wise_tax_breakup();
|
||||
},
|
||||
|
||||
company: function() {
|
||||
@ -936,69 +937,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
});
|
||||
},
|
||||
|
||||
get_item_wise_taxes_html: function() {
|
||||
var item_tax = {};
|
||||
var tax_accounts = [];
|
||||
var company_currency = this.get_company_currency();
|
||||
|
||||
$.each(this.frm.doc["taxes"] || [], function(i, tax) {
|
||||
var tax_amount_precision = precision("tax_amount", tax);
|
||||
var tax_rate_precision = precision("rate", tax);
|
||||
$.each(JSON.parse(tax.item_wise_tax_detail || '{}'),
|
||||
function(item_code, tax_data) {
|
||||
if(!item_tax[item_code]) item_tax[item_code] = {};
|
||||
if($.isArray(tax_data)) {
|
||||
var tax_rate = "";
|
||||
if(tax_data[0] != null) {
|
||||
tax_rate = (tax.charge_type === "Actual") ?
|
||||
format_currency(flt(tax_data[0], tax_amount_precision), company_currency, tax_amount_precision) :
|
||||
(flt(tax_data[0], tax_rate_precision) + "%");
|
||||
}
|
||||
var tax_amount = format_currency(flt(tax_data[1], tax_amount_precision), company_currency,
|
||||
tax_amount_precision);
|
||||
|
||||
item_tax[item_code][tax.name] = [tax_rate, tax_amount];
|
||||
} else {
|
||||
item_tax[item_code][tax.name] = [flt(tax_data, tax_rate_precision) + "%", ""];
|
||||
}
|
||||
});
|
||||
tax_accounts.push([tax.name, tax.account_head]);
|
||||
});
|
||||
|
||||
var headings = $.map([__("Item Name")].concat($.map(tax_accounts, function(head) { return head[1]; })),
|
||||
function(head) { return '<th style="min-width: 100px;">' + (head || "") + "</th>" }).join("\n");
|
||||
|
||||
var distinct_item_names = [];
|
||||
var distinct_items = [];
|
||||
$.each(this.frm.doc["items"] || [], function(i, item) {
|
||||
if(distinct_item_names.indexOf(item.item_code || item.item_name)===-1) {
|
||||
distinct_item_names.push(item.item_code || item.item_name);
|
||||
distinct_items.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
var rows = $.map(distinct_items, function(item) {
|
||||
var item_tax_record = item_tax[item.item_code || item.item_name];
|
||||
if(!item_tax_record) { return null; }
|
||||
return repl("<tr><td>%(item_name)s</td>%(taxes)s</tr>", {
|
||||
item_name: item.item_name,
|
||||
taxes: $.map(tax_accounts, function(head) {
|
||||
return item_tax_record[head[0]] ?
|
||||
"<td>(" + item_tax_record[head[0]][0] + ") " + item_tax_record[head[0]][1] + "</td>" :
|
||||
"<td></td>";
|
||||
}).join("\n")
|
||||
});
|
||||
}).join("\n");
|
||||
|
||||
if(!rows) return "";
|
||||
return '<p><a class="h6 text-muted" href="#" onclick="$(\'.tax-break-up\').toggleClass(\'hide\'); return false;">'
|
||||
+ __("Show tax break-up") + '</a></p>\
|
||||
<div class="tax-break-up hide" style="overflow-x: auto;"><table class="table table-bordered table-hover">\
|
||||
<thead><tr>' + headings + '</tr></thead> \
|
||||
<tbody>' + rows + '</tbody> \
|
||||
</table></div>';
|
||||
},
|
||||
|
||||
validate_company_and_party: function() {
|
||||
var me = this;
|
||||
var valid = true;
|
||||
@ -1046,18 +984,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
}
|
||||
},
|
||||
|
||||
show_item_wise_taxes: function() {
|
||||
if(this.frm.fields_dict.other_charges_calculation) {
|
||||
var html = this.get_item_wise_taxes_html();
|
||||
if (html) {
|
||||
this.frm.toggle_display("other_charges_calculation", true);
|
||||
$(this.frm.fields_dict.other_charges_calculation.wrapper).html(html);
|
||||
} else {
|
||||
this.frm.toggle_display("other_charges_calculation", false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
is_recurring: function() {
|
||||
// set default values for recurring documents
|
||||
if(this.frm.doc.is_recurring && this.frm.doc.__islocal) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
frappe.provide("erpnext.wiz");
|
||||
frappe.provide("erpnext.setup");
|
||||
|
||||
frappe.pages['setup-wizard'].on_page_load = function(wrapper) {
|
||||
if(frappe.sys_defaults.company) {
|
||||
@ -7,459 +7,398 @@ frappe.pages['setup-wizard'].on_page_load = function(wrapper) {
|
||||
}
|
||||
};
|
||||
|
||||
function load_erpnext_slides() {
|
||||
$.extend(erpnext.wiz, {
|
||||
select_domain: {
|
||||
domains: ["all"],
|
||||
title: __('Select your Domain'),
|
||||
fields: [
|
||||
{fieldname:'domain', label: __('Domain'), fieldtype:'Select',
|
||||
options: [
|
||||
{"label": __("Distribution"), "value": "Distribution"},
|
||||
{"label": __("Education"), "value": "Education"},
|
||||
{"label": __("Manufacturing"), "value": "Manufacturing"},
|
||||
{"label": __("Retail"), "value": "Retail"},
|
||||
{"label": __("Services"), "value": "Services"}
|
||||
], reqd:1},
|
||||
],
|
||||
help: __('Select the nature of your business.'),
|
||||
onload: function(slide) {
|
||||
slide.get_input("domain").on("change", function() {
|
||||
frappe.wiz.domain = $(this).val();
|
||||
frappe.wizard.refresh_slides();
|
||||
});
|
||||
var erpnext_slides = [
|
||||
{
|
||||
// Domain
|
||||
name: 'domain',
|
||||
domains: ["all"],
|
||||
title: __('Select your Domain'),
|
||||
fields: [
|
||||
{
|
||||
fieldname: 'domain', label: __('Domain'), fieldtype: 'Select',
|
||||
options: [
|
||||
{ "label": __("Distribution"), "value": "Distribution" },
|
||||
{ "label": __("Education"), "value": "Education" },
|
||||
{ "label": __("Manufacturing"), "value": "Manufacturing" },
|
||||
{ "label": __("Retail"), "value": "Retail" },
|
||||
{ "label": __("Services"), "value": "Services" }
|
||||
], reqd: 1
|
||||
},
|
||||
css_class: "single-column"
|
||||
],
|
||||
help: __('Select the nature of your business.'),
|
||||
onload: function (slide) {
|
||||
slide.get_input("domain").on("change", function () {
|
||||
frappe.setup.domain = $(this).val();
|
||||
frappe.wizard.refresh_slides();
|
||||
});
|
||||
},
|
||||
org: {
|
||||
domains: ["all"],
|
||||
title: __("The Organization"),
|
||||
icon: "fa fa-building",
|
||||
fields: [
|
||||
{fieldname:'company_name',
|
||||
label: frappe.wiz.domain==='Education' ?
|
||||
__('Institute Name') : __('Company Name'),
|
||||
fieldtype:'Data', reqd:1},
|
||||
{fieldname:'company_abbr',
|
||||
label: frappe.wiz.domain==='Education' ?
|
||||
__('Institute Abbreviation') : __('Company Abbreviation'),
|
||||
fieldtype:'Data'},
|
||||
{fieldname:'company_tagline',
|
||||
label: __('What does it do?'),
|
||||
fieldtype:'Data',
|
||||
placeholder: frappe.wiz.domain==='Education' ?
|
||||
__('e.g. "Primary School" or "University"') :
|
||||
__('e.g. "Build tools for builders"'),
|
||||
reqd:1},
|
||||
{fieldname:'bank_account', label: __('Bank Name'), fieldtype:'Data', reqd:1},
|
||||
{fieldname:'chart_of_accounts', label: __('Chart of Accounts'),
|
||||
options: "", fieldtype: 'Select'},
|
||||
},
|
||||
|
||||
// TODO remove this
|
||||
{fieldtype: "Section Break"},
|
||||
{fieldname:'fy_start_date', label:__('Financial Year Start Date'), fieldtype:'Date',
|
||||
description: __('Your financial year begins on'), reqd:1},
|
||||
{fieldname:'fy_end_date', label:__('Financial Year End Date'), fieldtype:'Date',
|
||||
description: __('Your financial year ends on'), reqd:1},
|
||||
],
|
||||
help: (frappe.wiz.domain==='Education' ?
|
||||
__('The name of the institute for which you are setting up this system.'):
|
||||
__('The name of your company for which you are setting up this system.')),
|
||||
{
|
||||
// Brand
|
||||
name: 'brand',
|
||||
domains: ["all"],
|
||||
icon: "fa fa-bookmark",
|
||||
title: __("The Brand"),
|
||||
help: __('Upload your letter head and logo. (you can edit them later).'),
|
||||
fields: [
|
||||
{
|
||||
fieldtype: "Attach Image", fieldname: "attach_logo",
|
||||
label: __("Attach Logo"),
|
||||
description: __("100px by 100px"),
|
||||
is_private: 0
|
||||
},
|
||||
{
|
||||
fieldname: 'company_name',
|
||||
label: frappe.setup.domain === 'Education' ?
|
||||
__('Institute Name') : __('Company Name'),
|
||||
fieldtype: 'Data', reqd: 1
|
||||
},
|
||||
{
|
||||
fieldname: 'company_abbr',
|
||||
label: frappe.setup.domain === 'Education' ?
|
||||
__('Institute Abbreviation') : __('Company Abbreviation'),
|
||||
fieldtype: 'Data'
|
||||
}
|
||||
],
|
||||
onload: function(slide) {
|
||||
this.bind_events(slide);
|
||||
},
|
||||
bind_events: function (slide) {
|
||||
slide.get_input("company_name").on("change", function () {
|
||||
var parts = slide.get_input("company_name").val().split(" ");
|
||||
var abbr = $.map(parts, function (p) { return p ? p.substr(0, 1) : null }).join("");
|
||||
slide.get_field("company_abbr").set_input(abbr.slice(0, 5).toUpperCase());
|
||||
}).val(frappe.boot.sysdefaults.company_name || "").trigger("change");
|
||||
|
||||
onload: function(slide) {
|
||||
erpnext.wiz.org.load_chart_of_accounts(slide);
|
||||
erpnext.wiz.org.bind_events(slide);
|
||||
erpnext.wiz.org.set_fy_dates(slide);
|
||||
slide.get_input("company_abbr").on("change", function () {
|
||||
if (slide.get_input("company_abbr").val().length > 5) {
|
||||
frappe.msgprint("Company Abbreviation cannot have more than 5 characters");
|
||||
slide.get_field("company_abbr").set_input("");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
// Organisation
|
||||
name: 'organisation',
|
||||
domains: ["all"],
|
||||
title: __("Your Organization"),
|
||||
icon: "fa fa-building",
|
||||
help: (frappe.setup.domain === 'Education' ?
|
||||
__('The name of the institute for which you are setting up this system.') :
|
||||
__('The name of your company for which you are setting up this system.')),
|
||||
fields: [
|
||||
{
|
||||
fieldname: 'company_tagline',
|
||||
label: __('What does it do?'),
|
||||
fieldtype: 'Data',
|
||||
placeholder: frappe.setup.domain === 'Education' ?
|
||||
__('e.g. "Primary School" or "University"') :
|
||||
__('e.g. "Build tools for builders"'),
|
||||
reqd: 1
|
||||
},
|
||||
{ fieldname: 'bank_account', label: __('Bank Name'), fieldtype: 'Data', reqd: 1 },
|
||||
{
|
||||
fieldname: 'chart_of_accounts', label: __('Chart of Accounts'),
|
||||
options: "", fieldtype: 'Select'
|
||||
},
|
||||
|
||||
validate: function() {
|
||||
// validate fiscal year start and end dates
|
||||
if (this.values.fy_start_date=='Invalid date' || this.values.fy_end_date=='Invalid date') {
|
||||
frappe.msgprint(__("Please enter valid Financial Year Start and End Dates"));
|
||||
return false;
|
||||
{ fieldtype: "Section Break", label: "Financial Year" },
|
||||
{ fieldname: 'fy_start_date', label: __('Start Date'), fieldtype: 'Date', reqd: 1 },
|
||||
{ fieldtype: "Column Break" },
|
||||
{ fieldname: 'fy_end_date', label: __('End Date'), fieldtype: 'Date', reqd: 1 },
|
||||
],
|
||||
|
||||
onload: function (slide) {
|
||||
this.load_chart_of_accounts(slide);
|
||||
this.bind_events(slide);
|
||||
this.set_fy_dates(slide);
|
||||
},
|
||||
|
||||
validate: function () {
|
||||
// validate fiscal year start and end dates
|
||||
if (this.values.fy_start_date == 'Invalid date' || this.values.fy_end_date == 'Invalid date') {
|
||||
frappe.msgprint(__("Please enter valid Financial Year Start and End Dates"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((this.values.company_name || "").toLowerCase() == "company") {
|
||||
frappe.msgprint(__("Company Name cannot be Company"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
set_fy_dates: function (slide) {
|
||||
var country = frappe.wizard.values.country;
|
||||
|
||||
if (country) {
|
||||
var fy = erpnext.setup.fiscal_years[country];
|
||||
var current_year = moment(new Date()).year();
|
||||
var next_year = current_year + 1;
|
||||
if (!fy) {
|
||||
fy = ["01-01", "12-31"];
|
||||
next_year = current_year;
|
||||
}
|
||||
|
||||
if ((this.values.company_name || "").toLowerCase() == "company") {
|
||||
frappe.msgprint(__("Company Name cannot be Company"));
|
||||
return false;
|
||||
var year_start_date = current_year + "-" + fy[0];
|
||||
if (year_start_date > frappe.datetime.get_today()) {
|
||||
next_year = current_year;
|
||||
current_year -= 1;
|
||||
}
|
||||
slide.get_field("fy_start_date").set_value(current_year + '-' + fy[0]);
|
||||
slide.get_field("fy_end_date").set_value(next_year + '-' + fy[1]);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
|
||||
css_class: "single-column",
|
||||
|
||||
set_fy_dates: function(slide) {
|
||||
var country = frappe.wizard.values.country;
|
||||
load_chart_of_accounts: function (slide) {
|
||||
var country = frappe.wizard.values.country;
|
||||
|
||||
if(country) {
|
||||
var fy = erpnext.wiz.fiscal_years[country];
|
||||
var current_year = moment(new Date()).year();
|
||||
var next_year = current_year + 1;
|
||||
if(!fy) {
|
||||
fy = ["01-01", "12-31"];
|
||||
next_year = current_year;
|
||||
}
|
||||
|
||||
var year_start_date = current_year + "-" + fy[0];
|
||||
if(year_start_date > frappe.datetime.get_today()) {
|
||||
next_year = current_year
|
||||
current_year -= 1;
|
||||
}
|
||||
slide.get_field("fy_start_date").set_input(current_year + "-" + fy[0]);
|
||||
slide.get_field("fy_end_date").set_input(next_year + "-" + fy[1]);
|
||||
}
|
||||
if (country) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.get_charts_for_country",
|
||||
args: { "country": country },
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
slide.get_input("chart_of_accounts").empty()
|
||||
.add_options(r.message);
|
||||
|
||||
},
|
||||
|
||||
load_chart_of_accounts: function(slide) {
|
||||
var country = frappe.wizard.values.country;
|
||||
|
||||
if(country) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.get_charts_for_country",
|
||||
args: {"country": country},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
slide.get_input("chart_of_accounts").empty()
|
||||
.add_options(r.message);
|
||||
|
||||
if (r.message.length===1) {
|
||||
var field = slide.get_field("chart_of_accounts");
|
||||
field.set_value(r.message[0]);
|
||||
field.df.hidden = 1;
|
||||
field.refresh();
|
||||
}
|
||||
if (r.message.length === 1) {
|
||||
var field = slide.get_field("chart_of_accounts");
|
||||
field.set_value(r.message[0]);
|
||||
field.df.hidden = 1;
|
||||
field.refresh();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
bind_events: function(slide) {
|
||||
slide.get_input("company_name").on("change", function() {
|
||||
var parts = slide.get_input("company_name").val().split(" ");
|
||||
var abbr = $.map(parts, function(p) { return p ? p.substr(0,1) : null }).join("");
|
||||
slide.get_field("company_abbr").set_input(abbr.slice(0, 5).toUpperCase());
|
||||
}).val(frappe.boot.sysdefaults.company_name || "").trigger("change");
|
||||
|
||||
slide.get_input("company_abbr").on("change", function() {
|
||||
if(slide.get_input("company_abbr").val().length > 5) {
|
||||
frappe.msgprint("Company Abbreviation cannot have more than 5 characters");
|
||||
slide.get_field("company_abbr").set_input("");
|
||||
}
|
||||
});
|
||||
|
||||
// TODO remove this
|
||||
slide.get_input("fy_start_date").on("change", function() {
|
||||
var year_end_date =
|
||||
frappe.datetime.add_days(frappe.datetime.add_months(
|
||||
frappe.datetime.user_to_obj(slide.get_input("fy_start_date").val()), 12), -1);
|
||||
slide.get_input("fy_end_date").val(frappe.datetime.obj_to_user(year_end_date));
|
||||
|
||||
});
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
branding: {
|
||||
domains: ["all"],
|
||||
icon: "fa fa-bookmark",
|
||||
title: __("The Brand"),
|
||||
help: __('Upload your letter head and logo. (you can edit them later).'),
|
||||
fields: [
|
||||
{fieldtype:"Attach Image", fieldname:"attach_letterhead",
|
||||
label: __("Attach Letterhead"),
|
||||
description: __("Keep it web friendly 900px (w) by 100px (h)"),
|
||||
is_private: 0
|
||||
},
|
||||
{fieldtype: "Column Break"},
|
||||
{fieldtype:"Attach Image", fieldname:"attach_logo",
|
||||
label:__("Attach Logo"),
|
||||
description: __("100px by 100px"),
|
||||
is_private: 0
|
||||
},
|
||||
],
|
||||
|
||||
css_class: "two-column"
|
||||
},
|
||||
|
||||
users: {
|
||||
domains: ["all"],
|
||||
icon: "fa fa-money",
|
||||
title: __("Add Users"),
|
||||
help: __("Add users to your organization, other than yourself"),
|
||||
fields: [],
|
||||
before_load: function(slide) {
|
||||
slide.fields = [];
|
||||
for(var i=1; i<5; i++) {
|
||||
slide.fields = slide.fields.concat([
|
||||
{fieldtype:"Section Break"},
|
||||
{fieldtype:"Data", fieldname:"user_fullname_"+ i,
|
||||
label:__("Full Name")},
|
||||
{fieldtype:"Data", fieldname:"user_email_" + i,
|
||||
label:__("Email Address"), placeholder:__("user@example.com"),
|
||||
options: "Email"},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype: "Check", fieldname: "user_sales_" + i,
|
||||
label:__("Sales"), "default": 1,
|
||||
hidden: frappe.wiz.domain==='Education' ? 1 : 0},
|
||||
{fieldtype: "Check", fieldname: "user_purchaser_" + i,
|
||||
label:__("Purchaser"), "default": 1,
|
||||
hidden: frappe.wiz.domain==='Education' ? 1 : 0},
|
||||
{fieldtype: "Check", fieldname: "user_accountant_" + i,
|
||||
label:__("Accountant"), "default": 1,
|
||||
hidden: frappe.wiz.domain==='Education' ? 1 : 0},
|
||||
]);
|
||||
}
|
||||
},
|
||||
css_class: "two-column"
|
||||
},
|
||||
|
||||
taxes: {
|
||||
domains: ['manufacturing', 'services', 'retail', 'distribution'],
|
||||
icon: "fa fa-money",
|
||||
title: __("Add Taxes"),
|
||||
help: __("List your tax heads (e.g. VAT, Customs etc; they should have unique names) and their standard rates. This will create a standard template, which you can edit and add more later."),
|
||||
"fields": [],
|
||||
before_load: function(slide) {
|
||||
slide.fields = [];
|
||||
for(var i=1; i<4; i++) {
|
||||
slide.fields = slide.fields.concat([
|
||||
{fieldtype:"Section Break"},
|
||||
{fieldtype:"Data", fieldname:"tax_"+ i, label:__("Tax") + " " + i,
|
||||
placeholder:__("e.g. VAT") + " " + i},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Float", fieldname:"tax_rate_" + i, label:__("Rate (%)"), placeholder:__("e.g. 5")},
|
||||
]);
|
||||
}
|
||||
},
|
||||
css_class: "two-column"
|
||||
},
|
||||
|
||||
customers: {
|
||||
domains: ['manufacturing', 'services', 'retail', 'distribution'],
|
||||
icon: "fa fa-group",
|
||||
title: __("Your Customers"),
|
||||
help: __("List a few of your customers. They could be organizations or individuals."),
|
||||
fields: [],
|
||||
before_load: function(slide) {
|
||||
slide.fields = [];
|
||||
for(var i=1; i<6; i++) {
|
||||
slide.fields = slide.fields.concat([
|
||||
{fieldtype:"Section Break"},
|
||||
{fieldtype:"Data", fieldname:"customer_" + i, label:__("Customer") + " " + i,
|
||||
placeholder:__("Customer Name")},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Data", fieldname:"customer_contact_" + i,
|
||||
label:__("Contact Name") + " " + i, placeholder:__("Contact Name")}
|
||||
])
|
||||
}
|
||||
slide.fields[1].reqd = 1;
|
||||
},
|
||||
css_class: "two-column"
|
||||
},
|
||||
|
||||
suppliers: {
|
||||
domains: ['manufacturing', 'services', 'retail', 'distribution'],
|
||||
icon: "fa fa-group",
|
||||
title: __("Your Suppliers"),
|
||||
help: __("List a few of your suppliers. They could be organizations or individuals."),
|
||||
fields: [],
|
||||
before_load: function(slide) {
|
||||
slide.fields = [];
|
||||
for(var i=1; i<6; i++) {
|
||||
slide.fields = slide.fields.concat([
|
||||
{fieldtype:"Section Break"},
|
||||
{fieldtype:"Data", fieldname:"supplier_" + i, label:__("Supplier")+" " + i,
|
||||
placeholder:__("Supplier Name")},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Data", fieldname:"supplier_contact_" + i,
|
||||
label:__("Contact Name") + " " + i, placeholder:__("Contact Name")},
|
||||
])
|
||||
}
|
||||
slide.fields[1].reqd = 1;
|
||||
},
|
||||
css_class: "two-column"
|
||||
},
|
||||
|
||||
items: {
|
||||
domains: ['manufacturing', 'services', 'retail', 'distribution'],
|
||||
icon: "fa fa-barcode",
|
||||
title: __("Your Products or Services"),
|
||||
help: __("List your products or services that you buy or sell. Make sure to check the Item Group, Unit of Measure and other properties when you start."),
|
||||
fields: [],
|
||||
before_load: function(slide) {
|
||||
slide.fields = [];
|
||||
for(var i=1; i<6; i++) {
|
||||
slide.fields = slide.fields.concat([
|
||||
{fieldtype:"Section Break", show_section_border: true},
|
||||
{fieldtype:"Data", fieldname:"item_" + i, label:__("Item") + " " + i,
|
||||
placeholder:__("A Product or Service")},
|
||||
{fieldtype:"Select", label:__("Group"), fieldname:"item_group_" + i,
|
||||
options:[__("Products"), __("Services"),
|
||||
__("Raw Material"), __("Consumable"), __("Sub Assemblies")],
|
||||
"default": __("Products")},
|
||||
{fieldtype:"Select", fieldname:"item_uom_" + i, label:__("UOM"),
|
||||
options:[__("Unit"), __("Nos"), __("Box"), __("Pair"), __("Kg"), __("Set"),
|
||||
__("Hour"), __("Minute"), __("Litre"), __("Meter"), __("Gram")],
|
||||
"default": __("Unit")},
|
||||
{fieldtype: "Check", fieldname: "is_sales_item_" + i, label:__("We sell this Item"), default: 1},
|
||||
{fieldtype: "Check", fieldname: "is_purchase_item_" + i, label:__("We buy this Item")},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Currency", fieldname:"item_price_" + i, label:__("Rate")},
|
||||
{fieldtype:"Attach Image", fieldname:"item_img_" + i, label:__("Attach Image"), is_private: 0},
|
||||
])
|
||||
}
|
||||
slide.fields[1].reqd = 1;
|
||||
|
||||
// dummy data
|
||||
slide.fields.push({fieldtype: "Section Break"});
|
||||
slide.fields.push({fieldtype: "Check", fieldname: "add_sample_data",
|
||||
label: __("Add a few sample records"), "default": 1});
|
||||
slide.fields.push({fieldtype: "Check", fieldname: "setup_website",
|
||||
label: __("Setup a simple website for my organization"), "default": 1});
|
||||
},
|
||||
css_class: "two-column"
|
||||
},
|
||||
|
||||
program: {
|
||||
domains: ["education"],
|
||||
title: __("Program"),
|
||||
help: __("Example: Masters in Computer Science"),
|
||||
fields: [],
|
||||
before_load: function(slide) {
|
||||
slide.fields = [];
|
||||
for(var i=1; i<6; i++) {
|
||||
slide.fields = slide.fields.concat([
|
||||
{fieldtype:"Section Break", show_section_border: true},
|
||||
{fieldtype:"Data", fieldname:"program_" + i, label:__("Program") + " " + i, placeholder: __("Program Name")},
|
||||
])
|
||||
}
|
||||
slide.fields[1].reqd = 1;
|
||||
},
|
||||
css_class: "single-column"
|
||||
},
|
||||
|
||||
course: {
|
||||
domains: ["education"],
|
||||
title: __("Course"),
|
||||
help: __("Example: Basic Mathematics"),
|
||||
fields: [],
|
||||
before_load: function(slide) {
|
||||
slide.fields = [];
|
||||
for(var i=1; i<6; i++) {
|
||||
slide.fields = slide.fields.concat([
|
||||
{fieldtype:"Section Break", show_section_border: true},
|
||||
{fieldtype:"Data", fieldname:"course_" + i, label:__("Course") + " " + i, placeholder: __("Course Name")},
|
||||
])
|
||||
}
|
||||
slide.fields[1].reqd = 1;
|
||||
},
|
||||
css_class: "single-column"
|
||||
},
|
||||
bind_events: function (slide) {
|
||||
slide.get_input("fy_start_date").on("change", function () {
|
||||
var start_date = slide.form.fields_dict.fy_start_date.get_value();
|
||||
var year_end_date =
|
||||
frappe.datetime.add_days(frappe.datetime.add_months(start_date, 12), -1);
|
||||
slide.form.fields_dict.fy_end_date.set_value(year_end_date);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
instructor: {
|
||||
domains: ["education"],
|
||||
title: __("Instructor"),
|
||||
help: __("People who teach at your organisation"),
|
||||
fields: [],
|
||||
before_load: function(slide) {
|
||||
slide.fields = [];
|
||||
for(var i=1; i<6; i++) {
|
||||
slide.fields = slide.fields.concat([
|
||||
{fieldtype:"Section Break", show_section_border: true},
|
||||
{fieldtype:"Data", fieldname:"instructor_" + i, label:__("Instructor") + " " + i, placeholder: __("Instructor Name")},
|
||||
])
|
||||
}
|
||||
slide.fields[1].reqd = 1;
|
||||
},
|
||||
css_class: "single-column"
|
||||
},
|
||||
{
|
||||
// Taxes
|
||||
name: 'taxes',
|
||||
domains: ['manufacturing', 'services', 'retail', 'distribution'],
|
||||
icon: "fa fa-money",
|
||||
title: __("Add Taxes"),
|
||||
help: __("List your tax heads (e.g. VAT, Customs etc; they should have unique names) and their standard rates. This will create a standard template, which you can edit and add more later."),
|
||||
add_more: 1,
|
||||
max_count: 4,
|
||||
fields: [
|
||||
{fieldtype:"Section Break"},
|
||||
{fieldtype:"Data", fieldname:"tax", label:__("Tax"),
|
||||
placeholder:__("e.g. VAT")},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Float", fieldname:"tax_rate", label:__("Rate (%)"), placeholder:__("e.g. 5")}
|
||||
]
|
||||
},
|
||||
|
||||
room: {
|
||||
domains: ["education"],
|
||||
title: __("Room"),
|
||||
help: __("Classrooms/ Laboratories etc where lectures can be scheduled."),
|
||||
fields: [],
|
||||
before_load: function(slide) {
|
||||
slide.fields = [];
|
||||
for(var i=1; i<4; i++) {
|
||||
slide.fields = slide.fields.concat([
|
||||
{fieldtype:"Section Break", show_section_border: true},
|
||||
{fieldtype:"Data", fieldname:"room_" + i, label:__("Room") + " " + i},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Int", fieldname:"room_capacity_" + i, label:__("Room") + " " + i + " Capacity"},
|
||||
])
|
||||
}
|
||||
slide.fields[1].reqd = 1;
|
||||
},
|
||||
css_class: "two-column"
|
||||
},
|
||||
});
|
||||
{
|
||||
// Customers
|
||||
name: 'customers',
|
||||
domains: ['manufacturing', 'services', 'retail', 'distribution'],
|
||||
icon: "fa fa-group",
|
||||
title: __("Add Customers"),
|
||||
help: __("List a few of your customers. They could be organizations or individuals."),
|
||||
add_more: 1,
|
||||
max_count: 6,
|
||||
fields: [
|
||||
{fieldtype:"Section Break"},
|
||||
{fieldtype:"Data", fieldname:"customer", label:__("Customer"),
|
||||
placeholder:__("Customer Name")},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Data", fieldname:"customer_contact",
|
||||
label:__("Contact Name"), placeholder:__("Contact Name")}
|
||||
],
|
||||
},
|
||||
|
||||
// Source: https://en.wikipedia.org/wiki/Fiscal_year
|
||||
// default 1st Jan - 31st Dec
|
||||
{
|
||||
// Suppliers
|
||||
name: 'suppliers',
|
||||
domains: ['manufacturing', 'services', 'retail', 'distribution'],
|
||||
icon: "fa fa-group",
|
||||
title: __("Your Suppliers"),
|
||||
help: __("List a few of your suppliers. They could be organizations or individuals."),
|
||||
add_more: 1,
|
||||
max_count: 6,
|
||||
fields: [
|
||||
{fieldtype:"Section Break"},
|
||||
{fieldtype:"Data", fieldname:"supplier", label:__("Supplier"),
|
||||
placeholder:__("Supplier Name")},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Data", fieldname:"supplier_contact",
|
||||
label:__("Contact Name"), placeholder:__("Contact Name")},
|
||||
]
|
||||
},
|
||||
|
||||
erpnext.wiz.fiscal_years = {
|
||||
"Afghanistan": ["12-20", "12-21"],
|
||||
"Australia": ["07-01", "06-30"],
|
||||
"Bangladesh": ["07-01", "06-30"],
|
||||
"Canada": ["04-01", "03-31"],
|
||||
"Costa Rica": ["10-01", "09-30"],
|
||||
"Egypt": ["07-01", "06-30"],
|
||||
"Hong Kong": ["04-01", "03-31"],
|
||||
"India": ["04-01", "03-31"],
|
||||
"Iran": ["06-23", "06-22"],
|
||||
"Italy": ["07-01", "06-30"],
|
||||
"Myanmar": ["04-01", "03-31"],
|
||||
"New Zealand": ["04-01", "03-31"],
|
||||
"Pakistan": ["07-01", "06-30"],
|
||||
"Singapore": ["04-01", "03-31"],
|
||||
"South Africa": ["03-01", "02-28"],
|
||||
"Thailand": ["10-01", "09-30"],
|
||||
"United Kingdom": ["04-01", "03-31"],
|
||||
};
|
||||
}
|
||||
{
|
||||
// Products
|
||||
name: 'products',
|
||||
domains: ['manufacturing', 'services', 'retail', 'distribution'],
|
||||
icon: "fa fa-barcode",
|
||||
title: __("Your Products or Services"),
|
||||
help: __("List your products or services that you buy or sell. Make sure to check the Item Group, Unit of Measure and other properties when you start."),
|
||||
add_more: 1,
|
||||
max_count: 6,
|
||||
fields: [
|
||||
{fieldtype:"Section Break", show_section_border: true},
|
||||
{fieldtype:"Data", fieldname:"item", label:__("Item"),
|
||||
placeholder:__("A Product or Service")},
|
||||
{fieldtype:"Select", label:__("Group"), fieldname:"item_group",
|
||||
options:[__("Products"), __("Services"),
|
||||
__("Raw Material"), __("Consumable"), __("Sub Assemblies")],
|
||||
"default": __("Products")},
|
||||
{fieldtype:"Select", fieldname:"item_uom", label:__("UOM"),
|
||||
options:[__("Unit"), __("Nos"), __("Box"), __("Pair"), __("Kg"), __("Set"),
|
||||
__("Hour"), __("Minute"), __("Litre"), __("Meter"), __("Gram")],
|
||||
"default": __("Unit")},
|
||||
{fieldtype: "Check", fieldname: "is_sales_item", label:__("We sell this Item"), default: 1},
|
||||
{fieldtype: "Check", fieldname: "is_purchase_item", label:__("We buy this Item")},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Currency", fieldname:"item_price", label:__("Rate")},
|
||||
{fieldtype:"Attach Image", fieldname:"item_img", label:__("Attach Image"), is_private: 0},
|
||||
],
|
||||
get_item_count: function() {
|
||||
return this.item_count;
|
||||
}
|
||||
},
|
||||
|
||||
frappe.wiz.on("before_load", function() {
|
||||
load_erpnext_slides();
|
||||
{
|
||||
// Program
|
||||
name: 'program',
|
||||
domains: ["education"],
|
||||
title: __("Program"),
|
||||
help: __("Example: Masters in Computer Science"),
|
||||
add_more: 1,
|
||||
max_count: 6,
|
||||
fields: [
|
||||
{fieldtype:"Section Break", show_section_border: true},
|
||||
{fieldtype:"Data", fieldname:"program", label:__("Program"), placeholder: __("Program Name")},
|
||||
],
|
||||
},
|
||||
|
||||
frappe.wiz.add_slide(erpnext.wiz.select_domain);
|
||||
frappe.wiz.add_slide(erpnext.wiz.org);
|
||||
frappe.wiz.add_slide(erpnext.wiz.branding);
|
||||
{
|
||||
// Course
|
||||
name: 'course',
|
||||
domains: ["education"],
|
||||
title: __("Course"),
|
||||
help: __("Example: Basic Mathematics"),
|
||||
add_more: 1,
|
||||
max_count: 6,
|
||||
fields: [
|
||||
{fieldtype:"Section Break", show_section_border: true},
|
||||
{fieldtype:"Data", fieldname:"course", label:__("Course"), placeholder: __("Course Name")},
|
||||
]
|
||||
},
|
||||
|
||||
if (!(frappe.boot.limits && frappe.boot.limits.users===1)) {
|
||||
frappe.wiz.add_slide(erpnext.wiz.users);
|
||||
{
|
||||
// Instructor
|
||||
name: 'instructor',
|
||||
domains: ["education"],
|
||||
title: __("Instructor"),
|
||||
help: __("People who teach at your organisation"),
|
||||
add_more: 1,
|
||||
max_count: 6,
|
||||
fields: [
|
||||
{fieldtype:"Section Break", show_section_border: true},
|
||||
{fieldtype:"Data", fieldname:"instructor", label:__("Instructor"), placeholder: __("Instructor Name")},
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// Room
|
||||
name: 'room',
|
||||
domains: ["education"],
|
||||
title: __("Room"),
|
||||
help: __("Classrooms/ Laboratories etc where lectures can be scheduled."),
|
||||
add_more: 1,
|
||||
max_count: 4,
|
||||
fields: [
|
||||
{fieldtype:"Section Break", show_section_border: true},
|
||||
{fieldtype:"Data", fieldname:"room", label:__("Room")},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Int", fieldname:"room_capacity", label:__("Room") + " Capacity"},
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
// last slide: Bootstrap
|
||||
name: 'bootstrap',
|
||||
domains: ["all"],
|
||||
title: __("Bootstrap"),
|
||||
fields: [{fieldtype: "Section Break"},
|
||||
{fieldtype: "Check", fieldname: "add_sample_data",
|
||||
label: __("Add a few sample records"), "default": 1},
|
||||
{fieldtype: "Check", fieldname: "setup_website",
|
||||
label: __("Setup a simple website for my organization"), "default": 1}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
frappe.wiz.add_slide(erpnext.wiz.taxes);
|
||||
frappe.wiz.add_slide(erpnext.wiz.customers);
|
||||
frappe.wiz.add_slide(erpnext.wiz.suppliers);
|
||||
frappe.wiz.add_slide(erpnext.wiz.items);
|
||||
frappe.wiz.add_slide(erpnext.wiz.program);
|
||||
frappe.wiz.add_slide(erpnext.wiz.course);
|
||||
frappe.wiz.add_slide(erpnext.wiz.instructor);
|
||||
frappe.wiz.add_slide(erpnext.wiz.room);
|
||||
// Source: https://en.wikipedia.org/wiki/Fiscal_year
|
||||
// default 1st Jan - 31st Dec
|
||||
|
||||
if(frappe.wizard && frappe.wizard.domain && frappe.wizard.domain !== 'Education') {
|
||||
frappe.wiz.welcome_page = "#welcome-to-erpnext";
|
||||
erpnext.setup.fiscal_years = {
|
||||
"Afghanistan": ["12-20", "12-21"],
|
||||
"Australia": ["07-01", "06-30"],
|
||||
"Bangladesh": ["07-01", "06-30"],
|
||||
"Canada": ["04-01", "03-31"],
|
||||
"Costa Rica": ["10-01", "09-30"],
|
||||
"Egypt": ["07-01", "06-30"],
|
||||
"Hong Kong": ["04-01", "03-31"],
|
||||
"India": ["04-01", "03-31"],
|
||||
"Iran": ["06-23", "06-22"],
|
||||
"Italy": ["07-01", "06-30"],
|
||||
"Myanmar": ["04-01", "03-31"],
|
||||
"New Zealand": ["04-01", "03-31"],
|
||||
"Pakistan": ["07-01", "06-30"],
|
||||
"Singapore": ["04-01", "03-31"],
|
||||
"South Africa": ["03-01", "02-28"],
|
||||
"Thailand": ["10-01", "09-30"],
|
||||
"United Kingdom": ["04-01", "03-31"],
|
||||
};
|
||||
|
||||
frappe.setup.on("before_load", function () {
|
||||
erpnext_slides.map(frappe.setup.add_slide);
|
||||
|
||||
// change header brand
|
||||
let $brand = $('header .setup-wizard-brand');
|
||||
if($brand.find('.erpnext-icon').length === 0) {
|
||||
$brand.find('.frappe-icon').hide();
|
||||
$brand.append(`<span>
|
||||
<img src="/assets/erpnext/images/erp-icon.svg" class="brand-icon erpnext-icon"
|
||||
style="width:36px;"><span class="brand-name">ERPNext</span></span>`);
|
||||
}
|
||||
});
|
||||
|
||||
var test_values_edu = {
|
||||
"language":"english",
|
||||
"domain":"Education",
|
||||
"country":"India",
|
||||
"timezone":"Asia/Kolkata",
|
||||
"currency":"INR",
|
||||
"first_name":"Tester",
|
||||
"email":"test@example.com",
|
||||
"password":"test",
|
||||
"company_name":"Hogwarts",
|
||||
"company_abbr":"HS",
|
||||
"company_tagline":"School for magicians",
|
||||
"bank_account":"Gringotts Wizarding Bank",
|
||||
"fy_start_date":"2016-04-01",
|
||||
"fy_end_date":"2017-03-31"
|
||||
"language": "english",
|
||||
"domain": "Education",
|
||||
"country": "India",
|
||||
"timezone": "Asia/Kolkata",
|
||||
"currency": "INR",
|
||||
"first_name": "Tester",
|
||||
"email": "test@example.com",
|
||||
"password": "test",
|
||||
"company_name": "Hogwarts",
|
||||
"company_abbr": "HS",
|
||||
"company_tagline": "School for magicians",
|
||||
"bank_account": "Gringotts Wizarding Bank",
|
||||
"fy_start_date": "2016-04-01",
|
||||
"fy_end_date": "2017-03-31"
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
{{ address_line1 }}<br>{% if address_line2 %}{{ address_line2 }}<br>{% endif -%}{{ city }}<br>
|
||||
{% if state %}{{ state }}<br>{% endif -%}
|
||||
{% if pincode %}{{ pincode }}<br>{% endif -%}
|
||||
{% if gst_state %}{{ gst_state }}{% endif -%},
|
||||
{% if gst_state_number %}State Code: {{ gst_state_number }}<br>{% endif -%}
|
||||
{% if pincode %}PIN: {{ pincode }}<br>{% endif -%}
|
||||
{{ country }}<br>
|
||||
{% if gstin %}GSTIN: {{ gstin }}<br>{% endif -%}
|
||||
{% if phone %}Phone: {{ phone }}<br>{% endif -%}
|
||||
{% if fax %}Fax: {{ fax }}<br>{% endif -%}
|
||||
{% if email_id %}Email: {{ email_id }}<br>{% endif -%}
|
||||
{% if email_id %}Email: {{ email_id }}<br>{% endif -%}
|
||||
{% if gstin %}GSTIN: {{ gstin }}<br>{% endif -%}
|
@ -14,6 +14,7 @@ def setup(company=None, patch=True):
|
||||
add_custom_roles_for_reports()
|
||||
add_hsn_codes()
|
||||
update_address_template()
|
||||
add_print_formats()
|
||||
if not patch:
|
||||
make_fixtures()
|
||||
|
||||
@ -69,50 +70,57 @@ def add_permissions():
|
||||
add_permission(doctype, 'Accounts Manager', 0)
|
||||
add_permission(doctype, 'All', 0)
|
||||
|
||||
def add_print_formats():
|
||||
frappe.reload_doc("regional", "print_format", "gst_tax_invoice")
|
||||
|
||||
def make_custom_fields():
|
||||
hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
|
||||
fieldtype='Data', options='item_code.gst_hsn_code', insert_after='description')
|
||||
|
||||
custom_fields = {
|
||||
'Address': [
|
||||
dict(fieldname='gstin', label='Party GSTIN', fieldtype='Data',
|
||||
insert_after='fax'),
|
||||
dict(fieldname='gst_state', label='GST State', fieldtype='Select',
|
||||
options='\n'.join(states), insert_after='gstin')
|
||||
options='\n'.join(states), insert_after='gstin'),
|
||||
dict(fieldname='gst_state_number', label='GST State Number',
|
||||
fieldtype='Int', insert_after='gst_state'),
|
||||
],
|
||||
'Purchase Invoice': [
|
||||
dict(fieldname='supplier_gstin', label='Supplier GSTIN',
|
||||
fieldtype='Data', insert_after='supplier_address',
|
||||
options='supplier_address.gstin'),
|
||||
options='supplier_address.gstin', print_hide=1),
|
||||
dict(fieldname='company_gstin', label='Company GSTIN',
|
||||
fieldtype='Data', insert_after='shipping_address',
|
||||
options='shipping_address.gstin'),
|
||||
options='shipping_address.gstin', print_hide=1),
|
||||
],
|
||||
'Sales Invoice': [
|
||||
dict(fieldname='customer_gstin', label='Customer GSTIN',
|
||||
fieldtype='Data', insert_after='shipping_address',
|
||||
options='shipping_address_name.gstin'),
|
||||
options='shipping_address_name.gstin', print_hide=1),
|
||||
dict(fieldname='company_gstin', label='Company GSTIN',
|
||||
fieldtype='Data', insert_after='company_address',
|
||||
options='company_address.gstin'),
|
||||
options='company_address.gstin', print_hide=1),
|
||||
dict(fieldname='invoice_copy', label='Invoice Copy',
|
||||
fieldtype='Select', insert_after='project', print_hide=1,
|
||||
options='ORIGINAL FOR RECIPIENT\nDUPLICATE FOR TRANSPORTER\nTRIPLICATE FOR SUPPLIER')
|
||||
],
|
||||
'Item': [
|
||||
dict(fieldname='gst_hsn_code', label='GST HSN Code',
|
||||
dict(fieldname='gst_hsn_code', label='HSN/SAC',
|
||||
fieldtype='Link', options='GST HSN Code', insert_after='item_group'),
|
||||
],
|
||||
'Sales Invoice Item': [
|
||||
dict(fieldname='gst_hsn_code', label='GST HSN Code',
|
||||
fieldtype='Data', options='item_code.gst_hsn_code',
|
||||
insert_after='income_account'),
|
||||
],
|
||||
'Purchase Invoice Item': [
|
||||
dict(fieldname='gst_hsn_code', label='GST HSN Code',
|
||||
fieldtype='Data', options='item_code.gst_hsn_code',
|
||||
insert_after='expense_account'),
|
||||
]
|
||||
'Sales Order Item': [hsn_sac_field],
|
||||
'Delivery Note Item': [hsn_sac_field],
|
||||
'Sales Invoice Item': [hsn_sac_field],
|
||||
'Purchase Order Item': [hsn_sac_field],
|
||||
'Purchase Receipt Item': [hsn_sac_field],
|
||||
'Purchase Invoice Item': [hsn_sac_field]
|
||||
}
|
||||
|
||||
for doctype, fields in custom_fields.items():
|
||||
for df in fields:
|
||||
create_custom_field(doctype, df)
|
||||
|
||||
|
||||
def make_fixtures():
|
||||
docs = [
|
||||
{'doctype': 'Salary Component', 'salary_component': 'Professional Tax', 'description': 'Professional Tax', 'type': 'Deduction'},
|
||||
|
@ -7,6 +7,7 @@ def validate_gstin_for_india(doc, method):
|
||||
return
|
||||
|
||||
if doc.gstin:
|
||||
doc.gstin = doc.gstin.upper()
|
||||
if doc.gstin != "NA":
|
||||
p = re.compile("[0-9]{2}[a-zA-Z]{5}[0-9]{4}[a-zA-Z]{1}[1-9A-Za-z]{1}[Z]{1}[0-9a-zA-Z]{1}")
|
||||
if not p.match(doc.gstin):
|
||||
@ -16,7 +17,8 @@ def validate_gstin_for_india(doc, method):
|
||||
if doc.state in states:
|
||||
doc.gst_state = doc.state
|
||||
|
||||
if doc.gst_state:
|
||||
state_number = state_numbers[doc.gst_state]
|
||||
if state_number != doc.gstin[:2]:
|
||||
frappe.throw(_("First 2 digits of GSTIN should match with State number {0}").format(state_number))
|
||||
if doc.gst_state:
|
||||
doc.gst_state_number = state_numbers[doc.gst_state]
|
||||
if doc.gst_state_number != doc.gstin[:2]:
|
||||
frappe.throw(_("First 2 digits of GSTIN should match with State number {0}")
|
||||
.format(doc.gst_state_number))
|
0
erpnext/regional/print_format/__init__.py
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"align_labels_left": 0,
|
||||
"creation": "2017-07-04 16:26:21.120187",
|
||||
"custom_format": 0,
|
||||
"disabled": 0,
|
||||
"doc_type": "Sales Invoice",
|
||||
"docstatus": 0,
|
||||
"doctype": "Print Format",
|
||||
"font": "Default",
|
||||
"format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"<div class=\\\"print-heading\\\">\\n\\t<h2>\\n\\t\\tSALES INVOICE<br>\\n\\t\\t<small>{{ doc.name }}</small>\\n\\t</h2>\\n</div>\\n<h2 class=\\\"text-right\\\">\\n\\t{% if doc.invoice_copy -%}\\n\\t\\t<small><i>({{ doc.invoice_copy }})</i></small>\\n\\t{% endif -%}\\n</h2>\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"company\", \"label\": \"Company\"}, {\"print_hide\": 0, \"fieldname\": \"company_address_display\", \"label\": \"Company Address\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"posting_date\", \"label\": \"Date\"}, {\"print_hide\": 0, \"fieldname\": \"due_date\", \"label\": \"Payment Due Date\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"options\": \"<hr>\", \"fieldname\": \"_custom_html\", \"fieldtype\": \"HTML\", \"label\": \"Custom HTML\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Address\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"customer_name\", \"label\": \"Customer Name\"}, {\"print_hide\": 0, \"fieldname\": \"address_display\", \"label\": \"Address\"}, {\"print_hide\": 0, \"fieldname\": \"contact_display\", \"label\": \"Contact\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"shipping_address\", \"label\": \"Shipping Address\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"item_code\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"200px\"}, {\"print_hide\": 0, \"fieldname\": \"gst_hsn_code\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"uom\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"items\", \"label\": \"Items\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"label\": \"Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"300px\"}], \"print_hide\": 0, \"fieldname\": \"taxes\", \"label\": \"Sales Taxes and Charges\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"grand_total\", \"label\": \"Grand Total\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\", \"label\": \"Rounded Total\"}, {\"print_hide\": 0, \"fieldname\": \"in_words\", \"label\": \"In Words\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"other_charges_calculation\", \"align\": \"left\", \"label\": \"Item-wise Tax Breakup\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Terms\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"terms\", \"label\": \"Terms and Conditions Details\"}]",
|
||||
"idx": 0,
|
||||
"line_breaks": 0,
|
||||
"modified": "2017-07-06 13:45:55.033384",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "GST Tax Invoice",
|
||||
"owner": "Administrator",
|
||||
"print_format_builder": 1,
|
||||
"print_format_type": "Server",
|
||||
"show_section_headings": 0,
|
||||
"standard": "Yes"
|
||||
}
|
@ -114,13 +114,17 @@ def get_student_guardians(student):
|
||||
return guardians
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_student_group_students(student_group):
|
||||
def get_student_group_students(student_group, include_inactive=0):
|
||||
"""Returns List of student, student_name in Student Group.
|
||||
|
||||
:param student_group: Student Group.
|
||||
"""
|
||||
students = frappe.get_list("Student Group Student", fields=["student", "student_name"] ,
|
||||
filters={"parent": student_group, "active": 1}, order_by= "group_roll_number")
|
||||
if include_inactive:
|
||||
students = frappe.get_list("Student Group Student", fields=["student", "student_name"] ,
|
||||
filters={"parent": student_group}, order_by= "group_roll_number")
|
||||
else:
|
||||
students = frappe.get_list("Student Group Student", fields=["student", "student_name"] ,
|
||||
filters={"parent": student_group, "active": 1}, order_by= "group_roll_number")
|
||||
return students
|
||||
|
||||
@frappe.whitelist()
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:title",
|
||||
@ -13,6 +14,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -23,6 +25,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Academic Year",
|
||||
@ -42,6 +45,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -52,6 +56,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Term Name",
|
||||
@ -70,6 +75,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -80,6 +86,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Term Start Date",
|
||||
@ -98,6 +105,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -108,6 +116,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Term End Date",
|
||||
@ -126,6 +135,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -136,6 +146,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Title",
|
||||
@ -154,17 +165,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": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-11-07 05:45:48.577744",
|
||||
"modified": "2017-06-30 08:21:45.897056",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Academic Term",
|
||||
@ -181,7 +192,6 @@
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
@ -196,8 +206,11 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "name",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "title",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "field:academic_year_name",
|
||||
@ -12,16 +13,20 @@
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "academic_year_name",
|
||||
"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": "Academic Year Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@ -30,6 +35,7 @@
|
||||
"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,
|
||||
@ -37,16 +43,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "year_start_date",
|
||||
"fieldtype": "Date",
|
||||
"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": "Year Start Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@ -55,6 +65,7 @@
|
||||
"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,
|
||||
@ -62,16 +73,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "year_end_date",
|
||||
"fieldtype": "Date",
|
||||
"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": "Year End Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@ -80,6 +95,7 @@
|
||||
"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,
|
||||
@ -87,17 +103,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": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-07-25 05:24:23.090530",
|
||||
"modified": "2017-06-30 08:21:46.121105",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Academic Year",
|
||||
@ -128,8 +144,11 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "field:assessment_criteria",
|
||||
@ -13,6 +14,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -22,7 +24,9 @@
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Assessment Criteria",
|
||||
"length": 0,
|
||||
@ -40,6 +44,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
@ -49,6 +54,8 @@
|
||||
"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": "Assessment Criteria Group",
|
||||
@ -68,17 +75,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": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-03 05:53:39.248759",
|
||||
"modified": "2017-06-30 08:21:46.211641",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Assessment Criteria",
|
||||
@ -109,6 +116,8 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:assessment_criteria_group",
|
||||
@ -13,6 +14,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -23,7 +25,8 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Assessment Criteria Group",
|
||||
"length": 0,
|
||||
@ -41,17 +44,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": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-01 17:39:12.453618",
|
||||
"modified": "2017-06-30 08:21:46.323964",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Assessment Criteria Group",
|
||||
@ -82,6 +85,8 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:assessment_group_name",
|
||||
@ -12,6 +13,7 @@
|
||||
"editable_grid": 1,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -23,7 +25,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": "Assessment Group Name",
|
||||
"length": 0,
|
||||
@ -41,6 +43,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -70,6 +73,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -98,6 +102,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -109,7 +114,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": "Parent Assessment Group",
|
||||
"length": 0,
|
||||
@ -128,6 +133,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -157,6 +163,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -186,6 +193,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -216,17 +224,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": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-24 15:18:54.725368",
|
||||
"modified": "2017-06-30 08:21:46.411222",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Assessment Group",
|
||||
@ -257,6 +265,7 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
|
@ -633,7 +633,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-06-05 23:40:30.434741",
|
||||
"modified": "2017-06-30 08:21:46.535547",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Assessment Plan",
|
||||
@ -664,6 +664,7 @@
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
|
@ -11,6 +11,7 @@ class AssessmentPlan(Document):
|
||||
def validate(self):
|
||||
self.validate_overlap()
|
||||
self.validate_max_score()
|
||||
self.validate_assessment_criteria()
|
||||
|
||||
def validate_overlap(self):
|
||||
"""Validates overlap for Student Group, Instructor, Room"""
|
||||
@ -37,3 +38,13 @@ class AssessmentPlan(Document):
|
||||
max_score += d.maximum_score
|
||||
if self.maximum_assessment_score != max_score:
|
||||
frappe.throw(_("Sum of Scores of Assessment Criteria needs to be {0}.".format(self.maximum_assessment_score)))
|
||||
|
||||
def validate_assessment_criteria(self):
|
||||
assessment_criteria_list = frappe.db.sql_list(''' select apc.assessment_criteria
|
||||
from `tabAssessment Plan` ap , `tabAssessment Plan Criteria` apc
|
||||
where ap.name = apc.parent and ap.course=%s and ap.student_group=%s and ap.assessment_group=%s
|
||||
and ap.name != %s''', (self.course, self.student_group, self.assessment_group, self.name))
|
||||
for d in self.assessment_criteria:
|
||||
if d.assessment_criteria in assessment_criteria_list:
|
||||
frappe.throw(_("You have already assessed for the assessment criteria {}.")
|
||||
.format(frappe.bold(d.assessment_criteria)))
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "",
|
||||
@ -13,6 +14,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -23,6 +25,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Assessment Criteria",
|
||||
@ -42,6 +45,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -52,6 +56,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "",
|
||||
@ -70,6 +75,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -80,6 +86,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Maximum Score",
|
||||
@ -98,17 +105,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-01 17:11:47.164623",
|
||||
"modified": "2017-06-30 08:21:46.732666",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Assessment Plan Criteria",
|
||||
@ -118,6 +125,8 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "RES.######",
|
||||
@ -13,6 +14,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -43,6 +45,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,
|
||||
@ -100,6 +104,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -130,6 +135,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -160,6 +166,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -188,6 +195,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -219,6 +227,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -247,6 +256,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -276,6 +286,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -305,6 +316,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -333,6 +345,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -362,6 +375,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -390,6 +404,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -419,6 +434,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -448,17 +464,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": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-21 08:03:46.054604",
|
||||
"modified": "2017-06-30 08:21:46.875594",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Assessment Result",
|
||||
@ -489,6 +505,7 @@
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "",
|
||||
@ -13,6 +14,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -23,6 +25,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Assessment Criteria",
|
||||
@ -42,6 +45,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -52,6 +56,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Maximum Score",
|
||||
@ -70,6 +75,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -80,6 +86,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "",
|
||||
@ -98,6 +105,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -108,6 +116,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Score",
|
||||
@ -126,6 +135,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -136,6 +146,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Grade",
|
||||
@ -154,17 +165,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-01 18:33:06.006040",
|
||||
"modified": "2017-06-30 08:21:47.068704",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Assessment Result Detail",
|
||||
@ -174,6 +185,8 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
|
@ -26,7 +26,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": "Assessment Plan",
|
||||
"length": 0,
|
||||
@ -86,7 +86,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": "Student Group",
|
||||
"length": 0,
|
||||
@ -175,7 +175,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-05-02 15:12:30.953036",
|
||||
"modified": "2017-06-30 08:21:47.184562",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Assessment Result Tool",
|
||||
@ -206,6 +206,7 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
|
@ -14,6 +14,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -43,6 +44,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -73,6 +75,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -102,6 +105,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -130,6 +134,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -159,6 +164,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -188,6 +194,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -216,6 +223,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -245,6 +253,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -274,6 +283,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -304,6 +314,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -345,7 +356,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-04-12 20:44:42.048564",
|
||||
"modified": "2017-06-30 08:21:47.260549",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Course",
|
||||
@ -396,6 +407,7 @@
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"search_fields": "course_name",
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
|