mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-16 03:12:38 +00:00
Compare commits
83 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
537db4c2c7 | ||
|
|
f4c5cf5bd0 | ||
|
|
bd5e01b09b | ||
|
|
d8c6449f3a | ||
|
|
75789b65c2 | ||
|
|
443691aaf8 | ||
|
|
174900506e | ||
|
|
84da00da2f | ||
|
|
78a17355be | ||
|
|
d257af910b | ||
|
|
2f22d2b307 | ||
|
|
d6cb617520 | ||
|
|
aaf378e340 | ||
|
|
96d6498226 | ||
|
|
66456dae34 | ||
|
|
af9bdfeaa3 | ||
|
|
aab1182c73 | ||
|
|
de1e29bf1b | ||
|
|
1892454036 | ||
|
|
84a44f7758 | ||
|
|
6674ba8bd1 | ||
|
|
5de499e5d5 | ||
|
|
271b7cd4f9 | ||
|
|
19f09b0b69 | ||
|
|
d8e91982ca | ||
|
|
7ff6e378dd | ||
|
|
7de5d3bb1d | ||
|
|
1b16bca843 | ||
|
|
6a418f2a9b | ||
|
|
d52c64ff11 | ||
|
|
3a5ca927e7 | ||
|
|
148fccd45a | ||
|
|
3061fc92fd | ||
|
|
1fb285c165 | ||
|
|
b36dc5e906 | ||
|
|
a067ddbc20 | ||
|
|
f4d9af1ab9 | ||
|
|
b1ac979ac5 | ||
|
|
7a294e6ef5 | ||
|
|
5e801955f1 | ||
|
|
aa25e95510 | ||
|
|
f9509a084a | ||
|
|
ec3be9eebf | ||
|
|
c5e0d22464 | ||
|
|
0154538c06 | ||
|
|
1b344ca81e | ||
|
|
4a15711b04 | ||
|
|
0d82b6979e | ||
|
|
bc7c387a0d | ||
|
|
35cd1d325f | ||
|
|
7b833802a9 | ||
|
|
d86ace41a1 | ||
|
|
b488475d92 | ||
|
|
8eda0cc8ba | ||
|
|
9d0092f89a | ||
|
|
e3d6d21ec5 | ||
|
|
ab5e77ecf1 | ||
|
|
41f60546a1 | ||
|
|
cda4d50063 | ||
|
|
a90274fed9 | ||
|
|
1ce56316ea | ||
|
|
7cf945c975 | ||
|
|
4bc12b68e4 | ||
|
|
4dc5f0efaf | ||
|
|
96abfd2ab9 | ||
|
|
75443a94ee | ||
|
|
cc884578b5 | ||
|
|
179e0c1d8d | ||
|
|
34d6340be6 | ||
|
|
77940493a8 | ||
|
|
a5b53e9480 | ||
|
|
f773af6053 | ||
|
|
119a50e228 | ||
|
|
11ec2c50e0 | ||
|
|
1e74519726 | ||
|
|
05ed86a00e | ||
|
|
d40ae81fc9 | ||
|
|
44f7b157ff | ||
|
|
3499ba08df | ||
|
|
51a397c97f | ||
|
|
bb34c57603 | ||
|
|
f7e6934d7c | ||
|
|
21cbbae88f |
@@ -4,7 +4,7 @@ import inspect
|
||||
import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
|
||||
__version__ = '9.2.13'
|
||||
__version__ = '9.2.24'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
"label": "Depreciation Method",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nStraight Line\nDouble Declining Balance",
|
||||
"options": "\nStraight Line\nDouble Declining Balance\nManual",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@@ -228,7 +228,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-17 16:09:52.955332",
|
||||
"modified": "2017-11-30 16:09:52.955332",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Asset Category",
|
||||
@@ -284,4 +284,4 @@
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,20 +253,24 @@ frappe.ui.form.on('Payment Entry', {
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
if(r.message) {
|
||||
if(frm.doc.payment_type == "Receive") {
|
||||
frm.set_value("paid_from", r.message.party_account);
|
||||
frm.set_value("paid_from_account_currency", r.message.party_account_currency);
|
||||
frm.set_value("paid_from_account_balance", r.message.account_balance);
|
||||
} else if (frm.doc.payment_type == "Pay"){
|
||||
frm.set_value("paid_to", r.message.party_account);
|
||||
frm.set_value("paid_to_account_currency", r.message.party_account_currency);
|
||||
frm.set_value("paid_to_account_balance", r.message.account_balance);
|
||||
}
|
||||
frm.set_value("party_balance", r.message.party_balance);
|
||||
frm.events.get_outstanding_documents(frm);
|
||||
frm.events.hide_unhide_fields(frm);
|
||||
frm.events.set_dynamic_labels(frm);
|
||||
frm.set_party_account_based_on_party = false;
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
if(frm.doc.payment_type == "Receive") {
|
||||
frm.set_value("paid_from", r.message.party_account);
|
||||
frm.set_value("paid_from_account_currency", r.message.party_account_currency);
|
||||
frm.set_value("paid_from_account_balance", r.message.account_balance);
|
||||
} else if (frm.doc.payment_type == "Pay"){
|
||||
frm.set_value("paid_to", r.message.party_account);
|
||||
frm.set_value("paid_to_account_currency", r.message.party_account_currency);
|
||||
frm.set_value("paid_to_account_balance", r.message.account_balance);
|
||||
}
|
||||
},
|
||||
() => frm.set_value("party_balance", r.message.party_balance),
|
||||
() => frm.events.get_outstanding_documents(frm),
|
||||
() => frm.events.hide_unhide_fields(frm),
|
||||
() => frm.events.set_dynamic_labels(frm),
|
||||
() => { frm.set_party_account_based_on_party = false; }
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -404,7 +408,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
}
|
||||
|
||||
// Make read only if Accounts Settings doesn't allow stale rates
|
||||
frm.set_df_property("source_exchange_rate", "read_only", erpnext.stale_rate_allowed());
|
||||
frm.set_df_property("source_exchange_rate", "read_only", erpnext.stale_rate_allowed() ? 0 : 1);
|
||||
},
|
||||
|
||||
target_exchange_rate: function(frm) {
|
||||
@@ -425,7 +429,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_paid_amount_based_on_received_amount = false;
|
||||
|
||||
// Make read only if Accounts Settings doesn't allow stale rates
|
||||
frm.set_df_property("target_exchange_rate", "read_only", erpnext.stale_rate_allowed());
|
||||
frm.set_df_property("target_exchange_rate", "read_only", erpnext.stale_rate_allowed() ? 0 : 1);
|
||||
},
|
||||
|
||||
paid_amount: function(frm) {
|
||||
|
||||
@@ -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": "Series",
|
||||
"length": 0,
|
||||
@@ -432,7 +432,7 @@
|
||||
"options": "<pre><h5>Message Example</h5>\n\n<p>Dear {{ doc.contact_person }},</p>\n\n<p>Requesting payment for {{ doc.doctype }}, {{ doc.name }} for {{ doc.grand_total }}.</p>\n\n<a href=\"{{ payment_url }}\"> click here to pay </a>\n\n</pre>\n",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@@ -728,7 +728,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-06-13 14:29:20.388372",
|
||||
"modified": "2017-12-02 15:50:41.775006",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Request",
|
||||
|
||||
@@ -24,11 +24,11 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) {
|
||||
|
||||
frappe.ui.form.on('POS Profile', {
|
||||
setup: function(frm) {
|
||||
frm.set_query("online_print_format", function() {
|
||||
frm.set_query("print_format_for_online", function() {
|
||||
return {
|
||||
filters: [
|
||||
['Print Format', 'doc_type', '=', 'Sales Invoice'],
|
||||
['Print Format', 'print_format_type', '!=', 'Js'],
|
||||
['Print Format', 'print_format_type', '=', 'Server'],
|
||||
]
|
||||
};
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ class POSProfile(Document):
|
||||
|
||||
def check_for_duplicate(self):
|
||||
res = frappe.db.sql("""select name, user from `tabPOS Profile`
|
||||
where ifnull(user, '') = %s and name != %s and company = %s""",
|
||||
where ifnull(user, '') = %s and name != %s and company = %s and ifnull(disabled, 0) != 1""",
|
||||
(self.user, self.name, self.company))
|
||||
if res:
|
||||
if res[0][1]:
|
||||
|
||||
@@ -12,8 +12,5 @@ class POSSettings(Document):
|
||||
|
||||
def set_link_for_pos(self):
|
||||
link = 'pos' if self.use_pos_in_offline_mode else 'point-of-sale'
|
||||
desktop_icon = frappe.db.get_value('Desktop Icon',
|
||||
{'standard': 1, 'module_name': 'POS'}, 'name')
|
||||
|
||||
if desktop_icon:
|
||||
frappe.db.set_value('Desktop Icon', desktop_icon, 'link', link)
|
||||
frappe.db.sql(""" update `tabDesktop Icon` set link = '{0}'
|
||||
where module_name like '%pos%'""".format(link))
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "hash",
|
||||
@@ -10,20 +11,24 @@
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Valuation and Total",
|
||||
"default": "Total",
|
||||
"fieldname": "category",
|
||||
"fieldtype": "Select",
|
||||
"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": "Consider Tax or Charge for",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -34,6 +39,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,
|
||||
@@ -41,6 +47,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -52,7 +59,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Add or Deduct",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -63,6 +72,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,
|
||||
@@ -70,6 +80,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -80,7 +91,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -91,6 +104,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,
|
||||
@@ -98,6 +112,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -109,7 +124,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reference Row #",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -119,6 +136,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,
|
||||
@@ -126,6 +144,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -137,7 +156,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Is this Tax included in Basic Rate?",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -146,6 +167,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 1,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -153,6 +175,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -163,13 +186,16 @@
|
||||
"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,
|
||||
@@ -177,6 +203,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -187,7 +214,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Account Head",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -198,6 +227,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,
|
||||
@@ -205,6 +235,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -216,7 +247,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Cost Center",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -227,6 +260,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,
|
||||
@@ -234,17 +268,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text Editor",
|
||||
"fieldtype": "Small 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,
|
||||
@@ -255,6 +292,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "300px",
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -263,6 +301,7 @@
|
||||
"width": "300px"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -273,7 +312,9 @@
|
||||
"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,
|
||||
@@ -281,6 +322,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,
|
||||
@@ -288,6 +330,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -298,7 +341,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rate",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -308,6 +353,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,
|
||||
@@ -315,6 +361,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -325,7 +372,9 @@
|
||||
"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,
|
||||
@@ -333,6 +382,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,
|
||||
@@ -340,6 +390,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -350,7 +401,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -361,6 +414,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,
|
||||
@@ -368,6 +422,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -378,7 +433,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Tax Amount After Discount Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -388,6 +445,7 @@
|
||||
"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,
|
||||
@@ -395,6 +453,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -405,7 +464,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -416,6 +477,7 @@
|
||||
"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,
|
||||
@@ -423,6 +485,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -433,7 +496,9 @@
|
||||
"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,
|
||||
@@ -441,6 +506,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,
|
||||
@@ -448,6 +514,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -458,7 +525,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amount (Company Currency)",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -468,6 +537,7 @@
|
||||
"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,
|
||||
@@ -475,6 +545,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -485,7 +556,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Total (Company Currency)",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -495,6 +568,7 @@
|
||||
"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,
|
||||
@@ -502,6 +576,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -512,7 +587,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Tax Amount After Discount Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -522,6 +599,7 @@
|
||||
"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,
|
||||
@@ -529,6 +607,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -539,7 +618,9 @@
|
||||
"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 Detail ",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -549,6 +630,7 @@
|
||||
"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,
|
||||
@@ -556,6 +638,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -565,8 +648,10 @@
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Parenttype",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -576,6 +661,7 @@
|
||||
"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,
|
||||
@@ -583,17 +669,17 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 1,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-08-26 03:20:22.118330",
|
||||
"modified": "2017-12-05 13:37:44.483509",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Taxes and Charges",
|
||||
@@ -602,5 +688,7 @@
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -247,7 +247,7 @@ class SalesInvoice(SellingController):
|
||||
super(SalesInvoice, self).set_missing_values(for_validate)
|
||||
|
||||
if pos:
|
||||
return {"print_format": pos.get("print_format") }
|
||||
return {"print_format": pos.get("print_format_for_online") }
|
||||
|
||||
def update_time_sheet(self, sales_invoice):
|
||||
for d in self.timesheets:
|
||||
|
||||
@@ -36,8 +36,14 @@
|
||||
<br>{%= data[i][__("Voucher No")] %}</td>
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
{%= data[i][__("Customer Name")] || data[i][__("Customer")] || data[i][__("Supplier Name")] || data[i][__("Supplier")] %}<br>{%= __("Remarks") %}:
|
||||
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
||||
{% if(data[i][__("Customer Name")] && data[i][__("Customer Name")] != data[i][__("Customer")]) { %}
|
||||
<br> {%= data[i][__("Customer Name")] %}
|
||||
{% } else if(data[i][__("Supplier Name")] != data[i][__("Supplier")]) { %}
|
||||
<br> {%= data[i][__("Supplier Name")] %}
|
||||
{% } %}
|
||||
{% } %}
|
||||
<br>{%= __("Remarks") %}:
|
||||
{%= data[i][__("Remarks")] %}
|
||||
</td>
|
||||
<td style="text-align: right">
|
||||
@@ -66,8 +72,13 @@
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
||||
<br>{%= __("Remarks") %}:
|
||||
{% if(data[i][__("Customer Name")] && data[i][__("Customer Name")] != data[i][__("Customer")]) { %}
|
||||
<br> {%= data[i][__("Customer Name")] %}
|
||||
{% } else if(data[i][__("Supplier Name")] != data[i][__("Supplier")]) { %}
|
||||
<br> {%= data[i][__("Supplier Name")] %}
|
||||
{% } %}
|
||||
{% } %}
|
||||
<br>{%= __("Remarks") %}:
|
||||
{%= data[i][__("Remarks")] %}
|
||||
</td>
|
||||
{% } else { %}
|
||||
|
||||
@@ -86,17 +86,20 @@ def get_accumulated_depreciations(assets, filters):
|
||||
for d in assets:
|
||||
asset = frappe.get_doc("Asset", d.name)
|
||||
|
||||
asset_depreciations.setdefault(d.asset_category, frappe._dict({
|
||||
"accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
|
||||
"depreciation_amount_during_the_period": 0,
|
||||
"depreciation_eliminated_during_the_period": 0
|
||||
}))
|
||||
if d.asset_category in asset_depreciations:
|
||||
asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] += asset.opening_accumulated_depreciation
|
||||
else:
|
||||
asset_depreciations.setdefault(d.asset_category, frappe._dict({
|
||||
"accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
|
||||
"depreciation_amount_during_the_period": 0,
|
||||
"depreciation_eliminated_during_the_period": 0
|
||||
}))
|
||||
|
||||
depr = asset_depreciations[d.asset_category]
|
||||
|
||||
for schedule in asset.get("schedules"):
|
||||
if getdate(schedule.schedule_date) < getdate(filters.from_date):
|
||||
if not asset.disposal_date and getdate(asset.disposal_date) >= getdate(filters.from_date):
|
||||
if not asset.disposal_date or getdate(asset.disposal_date) >= getdate(filters.from_date):
|
||||
depr.accumulated_depreciation_as_on_from_date += flt(schedule.depreciation_amount)
|
||||
elif getdate(schedule.schedule_date) <= getdate(filters.to_date):
|
||||
depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)
|
||||
|
||||
@@ -83,7 +83,7 @@ frappe.query_reports["General Ledger"] = {
|
||||
return;
|
||||
}
|
||||
|
||||
var fieldname = party_type.toLowerCase() + "_name";
|
||||
var fieldname = frappe.scrub(party_type) + "_name";
|
||||
frappe.db.get_value(party_type, party, fieldname, function(value) {
|
||||
frappe.query_report_filters_by_name.party_name.set_value(value[fieldname]);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
frappe.query_reports["Sales Payment Summary"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname":"from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.datetime.get_today(),
|
||||
"reqd": 1,
|
||||
"width": "80"
|
||||
},
|
||||
{
|
||||
"fieldname":"to_date",
|
||||
"label": __("To Date"),
|
||||
"fieldtype": "Date",
|
||||
"reqd": 1,
|
||||
"default": frappe.datetime.get_today()
|
||||
},
|
||||
{
|
||||
"fieldname":"company",
|
||||
"label": __("Company"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"default": frappe.defaults.get_user_default("Company")
|
||||
},
|
||||
{
|
||||
"fieldname":"owner",
|
||||
"label": __("Owner"),
|
||||
"fieldtype": "Link",
|
||||
"options": "User",
|
||||
"defaults": user
|
||||
},
|
||||
{
|
||||
"fieldname":"is_pos",
|
||||
"label": __("POS?"),
|
||||
"fieldtype": "Check"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"add_total_row": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2017-11-03 16:31:45.757516",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-11-04 05:15:35.892659",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Payment Summary",
|
||||
"owner": "Administrator",
|
||||
"ref_doctype": "Sales Invoice",
|
||||
"report_name": "Sales Payment Summary",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Accounts Manager"
|
||||
},
|
||||
{
|
||||
"role": "Accounts User"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import cstr
|
||||
|
||||
def execute(filters=None):
|
||||
columns, data = [], []
|
||||
columns=get_columns()
|
||||
data=get_sales_payment_data(filters, columns)
|
||||
return columns, data
|
||||
|
||||
def get_columns():
|
||||
return [
|
||||
_("Date") + ":Date:80",
|
||||
_("Owner") + "::150",
|
||||
_("Payment Mode") + "::140",
|
||||
_("Sales and Returns") + ":Currency/currency:120",
|
||||
_("Taxes") + ":Currency/currency:120",
|
||||
_("Payments") + ":Currency/currency:120",
|
||||
_("Outstanding Amount") + ":Currency/currency:150",
|
||||
]
|
||||
|
||||
def get_sales_payment_data(filters, columns):
|
||||
sales_invoice_data = get_sales_invoice_data(filters)
|
||||
data = []
|
||||
mode_of_payments = get_mode_of_payments(filters)
|
||||
for inv in sales_invoice_data:
|
||||
mode_of_payment = inv["owner"]+cstr(inv["posting_date"])
|
||||
row = [inv.posting_date, inv.owner,", ".join(mode_of_payments.get(mode_of_payment, [])),
|
||||
inv.net_total,
|
||||
inv.total_taxes, (inv.net_total + inv.total_taxes - inv.outstanding_amount),
|
||||
inv.outstanding_amount]
|
||||
data.append(row)
|
||||
return data
|
||||
|
||||
def get_conditions(filters):
|
||||
conditions = ""
|
||||
if filters.get("from_date"): conditions += "a.posting_date >= %(from_date)s"
|
||||
if filters.get("to_date"): conditions += " and a.posting_date <= %(to_date)s"
|
||||
if filters.get("company"): conditions += " and a.company=%(company)s"
|
||||
if filters.get("customer"): conditions += " and a.customer = %(customer)s"
|
||||
if filters.get("owner"): conditions += " and a.owner = %(owner)s"
|
||||
if filters.get("is_pos"): conditions += " and a.is_pos = %(is_pos)s"
|
||||
return conditions
|
||||
|
||||
def get_sales_invoice_data(filters):
|
||||
conditions = get_conditions(filters)
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
a.posting_date, a.owner,
|
||||
sum(a.net_total) as "net_total",
|
||||
sum(a.total_taxes_and_charges) as "total_taxes",
|
||||
sum(a.base_paid_amount) as "paid_amount",
|
||||
sum(a.outstanding_amount) as "outstanding_amount"
|
||||
from `tabSales Invoice` a
|
||||
where a.docstatus = 1
|
||||
and {conditions}
|
||||
group by
|
||||
a.owner, a.posting_date
|
||||
""".format(conditions=conditions), filters, as_dict=1)
|
||||
|
||||
def get_mode_of_payments(filters):
|
||||
mode_of_payments = {}
|
||||
invoice_list = get_invoices(filters)
|
||||
invoice_list_names = ",".join(['"' + invoice['name'] + '"' for invoice in invoice_list])
|
||||
if invoice_list:
|
||||
inv_mop = frappe.db.sql("""select a.owner,a.posting_date,b.mode_of_payment
|
||||
from `tabSales Invoice` a, `tabSales Invoice Payment` b
|
||||
where a.name = b.parent
|
||||
and a.name in ({invoice_list_names})
|
||||
union
|
||||
select a.owner,a.posting_date,b.mode_of_payment
|
||||
from `tabSales Invoice` a, `tabPayment Entry` b,`tabPayment Entry Reference` c
|
||||
where a.name = c.reference_name
|
||||
and b.name = c.parent
|
||||
and a.name in ({invoice_list_names})
|
||||
""".format(invoice_list_names=invoice_list_names), as_dict=1)
|
||||
for d in inv_mop:
|
||||
mode_of_payments.setdefault(d["owner"]+cstr(d["posting_date"]), []).append(d.mode_of_payment)
|
||||
return mode_of_payments
|
||||
|
||||
def get_invoices(filters):
|
||||
conditions = get_conditions(filters)
|
||||
return frappe.db.sql("""select a.name
|
||||
from `tabSales Invoice` a
|
||||
where a.docstatus = 1 and {conditions}""".format(conditions=conditions),
|
||||
filters, as_dict=1)
|
||||
@@ -134,8 +134,12 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
|
||||
"account": "'" + _("Total") + "'",
|
||||
"account_name": "'" + _("Total") + "'",
|
||||
"warn_if_negative": True,
|
||||
"opening_debit": 0.0,
|
||||
"opening_credit": 0.0,
|
||||
"debit": 0.0,
|
||||
"credit": 0.0,
|
||||
"closing_debit": 0.0,
|
||||
"closing_credit": 0.0,
|
||||
"parent_account": None,
|
||||
"indent": 0,
|
||||
"has_value": True,
|
||||
@@ -156,7 +160,10 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
|
||||
|
||||
total_row["debit"] += d["debit"]
|
||||
total_row["credit"] += d["credit"]
|
||||
|
||||
total_row["opening_debit"] += d["opening_debit"]
|
||||
total_row["opening_credit"] += d["opening_credit"]
|
||||
total_row["closing_debit"] += (d["opening_debit"] + d["debit"])
|
||||
total_row["closing_credit"] += (d["opening_credit"] + d["credit"])
|
||||
|
||||
return total_row
|
||||
|
||||
|
||||
@@ -593,7 +593,9 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
|
||||
select ifnull(sum({payment_dr_or_cr}), 0)
|
||||
from `tabGL Entry` payment_gl_entry
|
||||
where payment_gl_entry.against_voucher_type = invoice_gl_entry.voucher_type
|
||||
and payment_gl_entry.against_voucher = invoice_gl_entry.against_voucher
|
||||
and if(invoice_gl_entry.voucher_type='Journal Entry',
|
||||
payment_gl_entry.against_voucher = invoice_gl_entry.voucher_no,
|
||||
payment_gl_entry.against_voucher = invoice_gl_entry.against_voucher)
|
||||
and payment_gl_entry.party_type = invoice_gl_entry.party_type
|
||||
and payment_gl_entry.party = invoice_gl_entry.party
|
||||
and payment_gl_entry.account = invoice_gl_entry.account
|
||||
|
||||
@@ -51,6 +51,7 @@ class PurchaseOrder(BuyingController):
|
||||
self.validate_with_previous_doc()
|
||||
self.validate_for_subcontracting()
|
||||
self.validate_minimum_order_qty()
|
||||
self.validate_bom_for_subcontracting_items()
|
||||
self.create_raw_materials_supplied("supplied_items")
|
||||
self.set_received_qty_for_drop_ship_items()
|
||||
|
||||
@@ -95,6 +96,13 @@ class PurchaseOrder(BuyingController):
|
||||
frappe.throw(_("Item {0}: Ordered qty {1} cannot be less than minimum order qty {2} (defined in Item).").format(item_code,
|
||||
qty, itemwise_min_order_qty.get(item_code)))
|
||||
|
||||
def validate_bom_for_subcontracting_items(self):
|
||||
if self.is_subcontracted == "Yes":
|
||||
for item in self.items:
|
||||
if not item.bom:
|
||||
frappe.throw(_("BOM is not specified for subcontracting item {0} at row {1}"\
|
||||
.format(item.item_code, item.idx)))
|
||||
|
||||
def get_schedule_dates(self):
|
||||
for d in self.get('items'):
|
||||
if d.material_request_item and not d.schedule_date:
|
||||
|
||||
@@ -468,6 +468,12 @@ def get_data():
|
||||
"name": "Customer Credit Balance",
|
||||
"doctype": "Customer"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Sales Payment Summary",
|
||||
"doctype": "Sales Invoice"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -171,7 +171,7 @@ class BuyingController(StockController):
|
||||
for item in self.get("items"):
|
||||
if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
|
||||
item.rm_supp_cost = 0.0
|
||||
if item.item_code in self.sub_contracted_items:
|
||||
if item.bom and item.item_code in self.sub_contracted_items:
|
||||
self.update_raw_materials_supplied(item, raw_material_table)
|
||||
|
||||
if [item.item_code, item.name] not in parent_items:
|
||||
|
||||
@@ -56,7 +56,7 @@ def validate_item_variant_attributes(item, args=None):
|
||||
if not args:
|
||||
args = {d.attribute.lower():d.attribute_value for d in item.attributes}
|
||||
|
||||
attribute_values, numeric_values = get_attribute_values()
|
||||
attribute_values, numeric_values = get_attribute_values(item)
|
||||
|
||||
for attribute, value in args.items():
|
||||
if not value:
|
||||
@@ -96,16 +96,17 @@ def validate_item_attribute_value(attributes_list, attribute, attribute_value, i
|
||||
frappe.throw(_("Value {0} for Attribute {1} does not exist in the list of valid Item Attribute Values for Item {2}").format(
|
||||
attribute_value, attribute, item), InvalidItemAttributeValueError, title=_('Invalid Attribute'))
|
||||
|
||||
def get_attribute_values():
|
||||
def get_attribute_values(item):
|
||||
if not frappe.flags.attribute_values:
|
||||
attribute_values = {}
|
||||
numeric_values = {}
|
||||
for t in frappe.get_all("Item Attribute Value", fields=["parent", "attribute_value"]):
|
||||
attribute_values.setdefault(t.parent.lower(), []).append(t.attribute_value)
|
||||
|
||||
for t in frappe.get_all('Item Attribute',
|
||||
fields=["name", "from_range", "to_range", "increment"], filters={'numeric_values': 1}):
|
||||
numeric_values[t.name.lower()] = t
|
||||
for t in frappe.get_all('Item Variant Attribute',
|
||||
fields=["attribute", "from_range", "to_range", "increment"],
|
||||
filters={'numeric_values': 1, 'parent': item.variant_of}):
|
||||
numeric_values[t.attribute.lower()] = t
|
||||
|
||||
frappe.flags.attribute_values = attribute_values
|
||||
frappe.flags.numeric_values = numeric_values
|
||||
|
||||
@@ -399,7 +399,8 @@ class calculate_taxes_and_totals(object):
|
||||
|
||||
for tax in self.doc.get("taxes"):
|
||||
if tax.charge_type == "Actual":
|
||||
actual_taxes_dict.setdefault(tax.idx, tax.tax_amount)
|
||||
tax_amount = self.get_tax_amount_if_for_valuation_or_deduction(tax.tax_amount, tax)
|
||||
actual_taxes_dict.setdefault(tax.idx, tax_amount)
|
||||
elif tax.row_id in actual_taxes_dict:
|
||||
actual_tax_amount = flt(actual_taxes_dict.get(tax.row_id, 0)) * flt(tax.rate) / 100
|
||||
actual_taxes_dict.setdefault(tax.idx, actual_tax_amount)
|
||||
|
||||
@@ -5,6 +5,7 @@ def get_data():
|
||||
'fieldname': 'prevdoc_docname',
|
||||
'non_standard_fieldnames': {
|
||||
'Supplier Quotation': 'opportunity',
|
||||
'Quotation': 'opportunity'
|
||||
},
|
||||
'transactions': [
|
||||
{
|
||||
|
||||
@@ -348,8 +348,10 @@ def setup_budget():
|
||||
budget.action_if_annual_budget_exceeded = "Warn"
|
||||
expense_ledger_count = frappe.db.count("Account", {"is_group": "0", "root_type": "Expense"})
|
||||
|
||||
add_random_children(budget, "accounts", rows=random.randint(10, expense_ledger_count), randomize = { "account": ("Account", {"is_group": "0", "root_type": "Expense"})
|
||||
}, unique="account")
|
||||
add_random_children(budget, "accounts", rows=random.randint(10, expense_ledger_count),
|
||||
randomize = {
|
||||
"account": ("Account", {"is_group": "0", "root_type": "Expense"})
|
||||
}, unique="account")
|
||||
|
||||
for d in budget.accounts:
|
||||
d.budget_amount = random.randint(5, 100) * 10000
|
||||
@@ -361,6 +363,7 @@ def setup_pos_profile():
|
||||
company_abbr = frappe.db.get_value("Company", erpnext.get_default_company(), "abbr")
|
||||
pos = frappe.new_doc('POS Profile')
|
||||
pos.user = frappe.db.get_global('demo_accounts_user')
|
||||
pos.pos_profile_name = "Demo POS Profile"
|
||||
pos.naming_series = 'SINV-'
|
||||
pos.update_stock = 0
|
||||
pos.write_off_account = 'Cost of Goods Sold - '+ company_abbr
|
||||
|
||||
@@ -139,6 +139,7 @@ var btn_create_vital_signs = function (frm) {
|
||||
}
|
||||
frappe.route_options = {
|
||||
"patient": frm.doc.patient,
|
||||
"appointment": frm.doc.appointment
|
||||
};
|
||||
frappe.new_doc("Vital Signs");
|
||||
};
|
||||
|
||||
@@ -216,7 +216,7 @@
|
||||
"label": "Gender",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nMale\nFemale",
|
||||
"options": "\nMale\nFemale\nOther",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
@@ -1004,7 +1004,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-10-05 12:13:52.596750",
|
||||
"modified": "2017-11-22 14:03:30.434304",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Consultation",
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"columns": 0,
|
||||
"fieldname": "patient_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
@@ -185,7 +185,7 @@
|
||||
"label": "Gender",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nMale\nFemale",
|
||||
"options": "\nMale\nFemale\nOther",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
@@ -1388,7 +1388,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-10-05 12:14:57.078823",
|
||||
"modified": "2017-11-22 14:32:27.994634",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Lab Test",
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
"label": "Gender",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nMale\nFemale",
|
||||
"options": "\nMale\nFemale\nOther",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@@ -185,7 +185,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "DOB",
|
||||
"label": "Date of birth",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@@ -353,37 +353,6 @@
|
||||
"set_only_once": 1,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"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": "Company",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 1,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -884,7 +853,7 @@
|
||||
"label": "Marital Status",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Single\nMarried\nDivorced\nWidow",
|
||||
"options": "\nSingle\nMarried\nDivorced\nWidow",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@@ -1274,7 +1243,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 50,
|
||||
"modified": "2017-10-04 17:41:03.219934",
|
||||
"modified": "2017-11-24 12:39:33.061005",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Patient",
|
||||
|
||||
@@ -69,7 +69,10 @@ class Patient(Document):
|
||||
frappe.db.set_value("Patient", self.name, "disabled", 0)
|
||||
send_registration_sms(self)
|
||||
if(frappe.get_value("Healthcare Settings", None, "registration_fee")>0):
|
||||
sales_invoice = make_invoice(self.name, self.company)
|
||||
company = frappe.defaults.get_user_default('company')
|
||||
if not company:
|
||||
company = frappe.db.get_value("Global Defaults", None, "default_company")
|
||||
sales_invoice = make_invoice(self.name, company)
|
||||
sales_invoice.save(ignore_permissions=True)
|
||||
return {'invoice': sales_invoice.name}
|
||||
|
||||
@@ -110,7 +113,7 @@ def make_invoice(patient, company):
|
||||
return sales_invoice
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_patient_detail(patient, company=None):
|
||||
def get_patient_detail(patient):
|
||||
patient_dict = frappe.db.sql("""select * from tabPatient where name=%s""", (patient), as_dict=1)
|
||||
if not patient_dict:
|
||||
frappe.throw("Patient not found")
|
||||
|
||||
@@ -185,6 +185,7 @@ var btn_create_vital_signs = function (frm) {
|
||||
}
|
||||
frappe.route_options = {
|
||||
"patient": frm.doc.patient,
|
||||
"appointment": frm.doc.name,
|
||||
};
|
||||
frappe.new_doc("Vital Signs");
|
||||
};
|
||||
|
||||
@@ -165,6 +165,100 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "patient_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": "Patient Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "patient.patient_name",
|
||||
"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": "patient_sex",
|
||||
"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": "Gender",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "patient.sex",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 1,
|
||||
"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": "patient_age",
|
||||
"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": "Patient Age",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"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,
|
||||
@@ -440,158 +534,6 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_2",
|
||||
"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,
|
||||
"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": "patient_details",
|
||||
"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": "Patient Details",
|
||||
"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,
|
||||
"depends_on": "patient",
|
||||
"fieldname": "patient_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": "Patient 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": "patient_sex",
|
||||
"fieldtype": "Data",
|
||||
"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": "Gender",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "patient.sex",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 1,
|
||||
"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": "patient_age",
|
||||
"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": "Patient Age",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"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,
|
||||
@@ -756,7 +698,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-10-25 23:33:36.060803",
|
||||
"modified": "2017-11-22 16:32:57.240736",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Patient Appointment",
|
||||
|
||||
@@ -43,6 +43,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "patient_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": "Patient Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "patient.patient_name",
|
||||
"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,
|
||||
@@ -751,7 +782,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-10-04 16:08:36.340607",
|
||||
"modified": "2017-11-22 17:31:16.620650",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Vital Signs",
|
||||
|
||||
@@ -519,6 +519,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
|
||||
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
|
||||
query = """select
|
||||
bom_item.item_code,
|
||||
bom_item.idx,
|
||||
item.item_name,
|
||||
sum(bom_item.stock_qty/ifnull(bom.quantity, 1)) * %(qty)s as qty,
|
||||
item.description,
|
||||
|
||||
@@ -157,6 +157,7 @@ frappe.ui.form.on("Production Order", {
|
||||
item: frm.doc.production_item,
|
||||
project: frm.doc.project
|
||||
},
|
||||
freeze: true,
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
erpnext.in_production_item_onchange = true;
|
||||
@@ -184,6 +185,7 @@ frappe.ui.form.on("Production Order", {
|
||||
return frm.call({
|
||||
doc: frm.doc,
|
||||
method: "get_items_and_operations_from_bom",
|
||||
freeze: true,
|
||||
callback: function(r) {
|
||||
if(r.message["set_scrap_wh_mandatory"]){
|
||||
frm.toggle_reqd("scrap_warehouse", true);
|
||||
|
||||
@@ -43,10 +43,7 @@ class ProductionOrder(Document):
|
||||
|
||||
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()
|
||||
self.set_required_items(reset_only_qty = len(self.get("required_items")))
|
||||
|
||||
def validate_sales_order(self):
|
||||
if self.sales_order:
|
||||
@@ -57,6 +54,19 @@ class ProductionOrder(Document):
|
||||
and so.docstatus = 1 and so_item.item_code=%s
|
||||
""", (self.sales_order, self.production_item), as_dict=1)
|
||||
|
||||
if not so:
|
||||
so = frappe.db.sql("""
|
||||
select
|
||||
so.name, so_item.delivery_date, so.project
|
||||
from
|
||||
`tabSales Order` so, `tabSales Order Item` so_item, `tabPacked Item` packed_item
|
||||
where so.name=%s
|
||||
and so.name=so_item.parent
|
||||
and so.name=packed_item.parent
|
||||
and so_item.item_code = packed_item.parent_item
|
||||
and so.docstatus = 1 and packed_item.item_code=%s
|
||||
""", (self.sales_order, self.production_item), as_dict=1)
|
||||
|
||||
if len(so):
|
||||
if not self.expected_delivery_date:
|
||||
self.expected_delivery_date = so[0].delivery_date
|
||||
@@ -431,19 +441,27 @@ class ProductionOrder(Document):
|
||||
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):
|
||||
def set_required_items(self, reset_only_qty=False):
|
||||
'''set required_items for production to keep track of reserved qty'''
|
||||
self.required_items = []
|
||||
if not reset_only_qty:
|
||||
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 sorted(item_dict.values(), key=lambda d: d['idx']):
|
||||
self.append('required_items', {
|
||||
'item_code': item.item_code,
|
||||
'required_qty': item.qty,
|
||||
'source_warehouse': item.source_warehouse or item.default_warehouse
|
||||
})
|
||||
if reset_only_qty:
|
||||
for d in self.get("required_items"):
|
||||
d.required_qty = item_dict.get(d.item_code).get("qty")
|
||||
else:
|
||||
for item in sorted(item_dict.values(), key=lambda d: d['idx']):
|
||||
self.append('required_items', {
|
||||
'item_code': item.item_code,
|
||||
'item_name': item.item_name,
|
||||
'description': item.description,
|
||||
'required_qty': item.qty,
|
||||
'source_warehouse': item.source_warehouse or item.default_warehouse
|
||||
})
|
||||
|
||||
self.set_available_qty()
|
||||
|
||||
|
||||
@@ -15,62 +15,66 @@ def get_item_list(prod_list, filters):
|
||||
out = []
|
||||
|
||||
#Add a row for each item/qty
|
||||
for prod_order in prod_list:
|
||||
prod_details = frappe.db.get_value("Production Order", prod_order.name,
|
||||
["bom_no", "source_warehouse", "qty", "produced_qty"], as_dict=1)
|
||||
|
||||
for prod_details in prod_list:
|
||||
desc = frappe.db.get_value("BOM", prod_details.bom_no, "description")
|
||||
|
||||
item_list = frappe.db.sql("""SELECT
|
||||
bom_item.item_code as item_code,
|
||||
ifnull(ledger.actual_qty*bom.quantity/bom_item.stock_qty,0) as build_qty
|
||||
FROM
|
||||
`tabBOM` as bom, `tabBOM Item` AS bom_item
|
||||
LEFT JOIN `tabBin` AS ledger
|
||||
ON bom_item.item_code = ledger.item_code
|
||||
AND ledger.warehouse = ifnull(%(warehouse)s,%(filterhouse)s)
|
||||
WHERE
|
||||
bom.name = bom_item.parent
|
||||
and bom.name = %(bom)s
|
||||
GROUP BY
|
||||
bom_item.item_code""",
|
||||
{"bom": prod_details.bom_no, "warehouse": prod_details.source_warehouse,
|
||||
"filterhouse": filters.warehouse}, as_dict=1)
|
||||
|
||||
stock_qty = 0
|
||||
count = 0
|
||||
buildable_qty = prod_details.qty
|
||||
for item in item_list:
|
||||
count = count + 1
|
||||
if item.build_qty >= (prod_details.qty - prod_details.produced_qty):
|
||||
stock_qty = stock_qty + 1
|
||||
elif buildable_qty >= item.build_qty:
|
||||
buildable_qty = item.build_qty
|
||||
|
||||
if count == stock_qty:
|
||||
build = "Y"
|
||||
else:
|
||||
build = "N"
|
||||
|
||||
row = frappe._dict({
|
||||
"production_order": prod_order.name,
|
||||
"status": prod_order.status,
|
||||
"req_items": cint(count),
|
||||
"instock": stock_qty,
|
||||
"description": desc,
|
||||
"bom_no": prod_details.bom_no,
|
||||
"qty": prod_details.qty,
|
||||
"buildable_qty": buildable_qty,
|
||||
"ready_to_build": build
|
||||
})
|
||||
|
||||
out.append(row)
|
||||
|
||||
for prod_item_details in frappe.db.get_values("Production Order Item",
|
||||
{"parent": prod_details.name}, ["item_code", "source_warehouse"], as_dict=1):
|
||||
|
||||
item_list = frappe.db.sql("""SELECT
|
||||
bom_item.item_code as item_code,
|
||||
ifnull(ledger.actual_qty*bom.quantity/bom_item.stock_qty,0) as build_qty
|
||||
FROM
|
||||
`tabBOM` as bom, `tabBOM Item` AS bom_item
|
||||
LEFT JOIN `tabBin` AS ledger
|
||||
ON bom_item.item_code = ledger.item_code
|
||||
AND ledger.warehouse = ifnull(%(warehouse)s,%(filterhouse)s)
|
||||
WHERE
|
||||
bom.name = bom_item.parent
|
||||
and bom_item.item_code = %(item_code)s
|
||||
and bom.name = %(bom)s
|
||||
GROUP BY
|
||||
bom_item.item_code""",
|
||||
{"bom": prod_details.bom_no, "warehouse": prod_item_details.source_warehouse,
|
||||
"filterhouse": filters.warehouse, "item_code": prod_item_details.item_code}, as_dict=1)
|
||||
|
||||
stock_qty = 0
|
||||
count = 0
|
||||
buildable_qty = prod_details.qty
|
||||
for item in item_list:
|
||||
count = count + 1
|
||||
if item.build_qty >= (prod_details.qty - prod_details.produced_qty):
|
||||
stock_qty = stock_qty + 1
|
||||
elif buildable_qty >= item.build_qty:
|
||||
buildable_qty = item.build_qty
|
||||
|
||||
if count == stock_qty:
|
||||
build = "Y"
|
||||
else:
|
||||
build = "N"
|
||||
|
||||
row = frappe._dict({
|
||||
"production_order": prod_details.name,
|
||||
"status": prod_details.status,
|
||||
"req_items": cint(count),
|
||||
"instock": stock_qty,
|
||||
"description": desc,
|
||||
"source_warehouse": prod_item_details.source_warehouse,
|
||||
"item_code": prod_item_details.item_code,
|
||||
"bom_no": prod_details.bom_no,
|
||||
"qty": prod_details.qty,
|
||||
"buildable_qty": buildable_qty,
|
||||
"ready_to_build": build
|
||||
})
|
||||
|
||||
out.append(row)
|
||||
|
||||
return out
|
||||
|
||||
def get_production_orders():
|
||||
|
||||
out = frappe.get_all("Production Order", filters={"docstatus": 1, "status": ( "!=","Completed")}, fields=["name","status"], order_by='name')
|
||||
out = frappe.get_all("Production Order", filters={"docstatus": 1, "status": ( "!=","Completed")},
|
||||
fields=["name","status", "bom_no", "qty", "produced_qty"], order_by='name')
|
||||
|
||||
return out
|
||||
|
||||
def get_columns():
|
||||
@@ -93,6 +97,18 @@ def get_columns():
|
||||
"options": "",
|
||||
"width": 230
|
||||
}, {
|
||||
"fieldname": "item_code",
|
||||
"label": "Item Code",
|
||||
"fieldtype": "Link",
|
||||
"options": "Item",
|
||||
"width": 110
|
||||
},{
|
||||
"fieldname": "source_warehouse",
|
||||
"label": "Source Warehouse",
|
||||
"fieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
"width": 110
|
||||
},{
|
||||
"fieldname": "qty",
|
||||
"label": "Qty to Build",
|
||||
"fieldtype": "Data",
|
||||
|
||||
@@ -460,3 +460,7 @@ erpnext.patches.v9_0.remove_non_existing_warehouse_from_stock_settings
|
||||
execute:frappe.delete_doc_if_exists("DocType", "Program Fee")
|
||||
erpnext.patches.v9_0.update_employee_loan_details
|
||||
erpnext.patches.v9_2.delete_healthcare_domain_default_items
|
||||
erpnext.patches.v9_2.rename_translated_domains_in_en
|
||||
erpnext.patches.v9_2.repost_reserved_qty_for_production
|
||||
erpnext.patches.v9_2.remove_company_from_patient
|
||||
erpnext.patches.v9_2.set_item_name_in_production_order
|
||||
@@ -18,4 +18,6 @@ def execute():
|
||||
and so.order_type = 'Sales'
|
||||
and (so_item.delivery_date is null or so_item.delivery_date = ''
|
||||
or so_item.delivery_date = '0000-00-00')
|
||||
""")
|
||||
and (so.delivery_date is not null and so.delivery_date != ''
|
||||
and so.delivery_date != '0000-00-00')
|
||||
""")
|
||||
|
||||
6
erpnext/patches/v9_2/remove_company_from_patient.py
Normal file
6
erpnext/patches/v9_2/remove_company_from_patient.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
if frappe.db.exists("DocType", "Patient"):
|
||||
if 'company' in frappe.db.get_table_columns("Patient"):
|
||||
frappe.db.sql("alter table `tabPatient` drop column company")
|
||||
31
erpnext/patches/v9_2/rename_translated_domains_in_en.py
Normal file
31
erpnext/patches/v9_2/rename_translated_domains_in_en.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import frappe
|
||||
from frappe import _
|
||||
|
||||
def execute():
|
||||
language = frappe.get_single("System Settings").language
|
||||
|
||||
if language and language.startswith('en'): return
|
||||
|
||||
frappe.local.lang = language
|
||||
|
||||
all_domains = frappe.get_hooks("domains")
|
||||
|
||||
for domain in all_domains:
|
||||
translated_domain = _(domain, lang=language)
|
||||
if frappe.db.exists("Domain", translated_domain):
|
||||
frappe.rename_doc("Domain", translated_domain, domain, ignore_permissions=True, merge=True)
|
||||
|
||||
domain_settings = frappe.get_single("Domain Settings")
|
||||
active_domains = [d.domain for d in domain_settings.active_domains]
|
||||
|
||||
try:
|
||||
for domain in active_domains:
|
||||
domain = frappe.get_doc("Domain", domain)
|
||||
domain.setup_domain()
|
||||
|
||||
if int(frappe.db.get_single_value('System Settings', 'setup_complete')):
|
||||
domain.setup_sidebar_items()
|
||||
domain.setup_desktop_icons()
|
||||
domain.set_default_portal_role()
|
||||
except frappe.LinkValidationError:
|
||||
pass
|
||||
@@ -0,0 +1,7 @@
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
bins = frappe.db.sql("select name from `tabBin` where reserved_qty_for_production > 0")
|
||||
for d in bins:
|
||||
bin_doc = frappe.get_doc("Bin", d[0])
|
||||
bin_doc.update_reserved_qty_for_production()
|
||||
11
erpnext/patches/v9_2/set_item_name_in_production_order.py
Normal file
11
erpnext/patches/v9_2/set_item_name_in_production_order.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
|
||||
frappe.db.sql("""
|
||||
update `tabBOM Item` bom, `tabProduction Order Item` po_item
|
||||
set po_item.item_name = bom.item_name,
|
||||
po_item.description = bom.description
|
||||
where po_item.item_code = bom.item_code
|
||||
and (po_item.item_name is null or po_item.description is null)
|
||||
""")
|
||||
@@ -34,7 +34,7 @@
|
||||
margin-left: 15px;
|
||||
}
|
||||
.cart-wrapper {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.cart-wrapper .list-item__content:not(:first-child) {
|
||||
justify-content: flex-end;
|
||||
@@ -121,7 +121,6 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
border-collapse: collapse;
|
||||
cursor: pointer;
|
||||
display: table;
|
||||
margin: auto;
|
||||
}
|
||||
.num-row {
|
||||
display: table-row;
|
||||
|
||||
@@ -521,9 +521,11 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
var actual_taxes_dict = {};
|
||||
|
||||
$.each(this.frm.doc["taxes"] || [], function(i, tax) {
|
||||
if (tax.charge_type == "Actual")
|
||||
actual_taxes_dict[tax.idx] = tax.tax_amount;
|
||||
else if (actual_taxes_dict[tax.row_id] !== null) {
|
||||
if (tax.charge_type == "Actual") {
|
||||
var tax_amount = (tax.category == "Valuation") ? 0.0 : tax.tax_amount;
|
||||
tax_amount *= (tax.add_deduct_tax == "Deduct") ? -1.0 : 1.0;
|
||||
actual_taxes_dict[tax.idx] = tax_amount;
|
||||
} else if (actual_taxes_dict[tax.row_id] !== null) {
|
||||
var actual_tax_amount = flt(actual_taxes_dict[tax.row_id]) * flt(tax.rate) / 100;
|
||||
actual_taxes_dict[tax.idx] = actual_tax_amount;
|
||||
}
|
||||
|
||||
@@ -550,7 +550,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
|
||||
}
|
||||
// Make read only if Accounts Settings doesn't allow stale rates
|
||||
this.frm.set_df_property("conversion_rate", "read_only", erpnext.stale_rate_allowed());
|
||||
this.frm.set_df_property("conversion_rate", "read_only", erpnext.stale_rate_allowed() ? 0 : 1);
|
||||
},
|
||||
|
||||
set_actual_charges_based_on_currency: function() {
|
||||
|
||||
@@ -171,7 +171,10 @@ erpnext.utils.validate_mandatory = function(frm, label, value, trigger_on) {
|
||||
erpnext.utils.get_shipping_address = function(frm, callback){
|
||||
frappe.call({
|
||||
method: "frappe.contacts.doctype.address.address.get_shipping_address",
|
||||
args: {company: frm.doc.company},
|
||||
args: {
|
||||
company: frm.doc.company,
|
||||
address: frm.doc.shipping_address
|
||||
},
|
||||
callback: function(r){
|
||||
if(r.message){
|
||||
frm.set_value("shipping_address", r.message[0]) //Address title or name
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
}
|
||||
|
||||
.cart-wrapper {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 12px;
|
||||
.list-item__content:not(:first-child) {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
@@ -155,7 +155,6 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
border-collapse: collapse;
|
||||
cursor: pointer;
|
||||
display: table;
|
||||
margin: auto;
|
||||
}
|
||||
.num-row {
|
||||
display: table-row;
|
||||
|
||||
@@ -14,15 +14,15 @@ def validate_gstin_for_india(doc, method):
|
||||
if not p.match(doc.gstin):
|
||||
frappe.throw(_("Invalid GSTIN or Enter NA for Unregistered"))
|
||||
|
||||
if not doc.gst_state:
|
||||
if doc.state in states:
|
||||
doc.gst_state = doc.state
|
||||
if not doc.gst_state:
|
||||
if doc.state in states:
|
||||
doc.gst_state = doc.state
|
||||
|
||||
if doc.gst_state:
|
||||
doc.gst_state_number = state_numbers[doc.gst_state]
|
||||
if doc.gstin != "NA" and 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))
|
||||
if doc.gst_state:
|
||||
doc.gst_state_number = state_numbers[doc.gst_state]
|
||||
if doc.gstin and doc.gstin != "NA" and 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))
|
||||
|
||||
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
|
||||
if frappe.get_meta(item_doctype).has_field('gst_hsn_code'):
|
||||
|
||||
@@ -103,7 +103,7 @@ class SalesOrder(SellingController):
|
||||
def validate_delivery_date(self):
|
||||
if self.order_type == 'Sales':
|
||||
if not self.delivery_date:
|
||||
self.delivery_date = max([d.delivery_date for d in self.get("items")])
|
||||
self.delivery_date = max([d.delivery_date for d in self.get("items") if d.delivery_date])
|
||||
|
||||
if self.delivery_date:
|
||||
for d in self.get("items"):
|
||||
@@ -762,10 +762,15 @@ def make_production_orders(items, sales_order, company, project=None):
|
||||
out = []
|
||||
|
||||
for i in items:
|
||||
if not i.get("bom"):
|
||||
frappe.throw(_("Please select BOM against item {0}").format(i.get("item_code")))
|
||||
if not i.get("pending_qty"):
|
||||
frappe.throw(_("Please select Qty against item {0}").format(i.get("item_code")))
|
||||
|
||||
production_order = frappe.get_doc(dict(
|
||||
doctype='Production Order',
|
||||
production_item=i['item_code'],
|
||||
bom_no=i['bom'],
|
||||
bom_no=i.get('bom'),
|
||||
qty=i['pending_qty'],
|
||||
company=company,
|
||||
sales_order=sales_order,
|
||||
|
||||
@@ -53,8 +53,6 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
() => this.setup_pos_profile(),
|
||||
() => this.make_new_invoice(),
|
||||
() => {
|
||||
frappe.timeout(1);
|
||||
this.make_items();
|
||||
this.bind_events();
|
||||
frappe.dom.unfreeze();
|
||||
},
|
||||
@@ -208,7 +206,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
|
||||
select_batch_and_serial_no(item) {
|
||||
erpnext.show_serial_batch_selector(this.frm, item, () => {
|
||||
this.update_item_in_frm(item)
|
||||
this.update_item_in_frm(item, 'qty', item.qty)
|
||||
.then(() => {
|
||||
// update cart
|
||||
if (item.qty === 0) {
|
||||
@@ -324,15 +322,17 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
make_new_invoice() {
|
||||
return frappe.run_serially([
|
||||
() => this.make_sales_invoice_frm(),
|
||||
() => this.set_pos_profile_data(),
|
||||
() => {
|
||||
if (this.cart) {
|
||||
this.cart.frm = this.frm;
|
||||
this.cart.reset();
|
||||
} else {
|
||||
this.make_items();
|
||||
this.make_cart();
|
||||
}
|
||||
this.toggle_editing(true);
|
||||
}
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -359,12 +359,32 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
if(!frm.doc.company) {
|
||||
frm.set_value('company', pos_profile.company);
|
||||
}
|
||||
frm.set_value('is_pos', 1);
|
||||
frm.meta.default_print_format = 'POS Invoice';
|
||||
frm.doc.is_pos = 1;
|
||||
return frm;
|
||||
}
|
||||
}
|
||||
|
||||
set_pos_profile_data() {
|
||||
return new Promise(resolve => {
|
||||
return this.frm.call({
|
||||
doc: this.frm.doc,
|
||||
method: "set_missing_values",
|
||||
}).then((r) => {
|
||||
if(!r.exc) {
|
||||
this.frm.script_manager.trigger("update_stock");
|
||||
frappe.model.set_default_values(this.frm.doc);
|
||||
this.frm.cscript.calculate_taxes_and_totals();
|
||||
|
||||
if (r.message) {
|
||||
this.frm.meta.default_print_format = r.message.print_format || 'POS Invoice';
|
||||
}
|
||||
}
|
||||
|
||||
resolve();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
prepare_menu() {
|
||||
var me = this;
|
||||
this.page.clear_menu();
|
||||
@@ -392,9 +412,6 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
if(this.frm.doc.docstatus !== 1) return;
|
||||
|
||||
this.page.set_secondary_action(__("Print"), () => {
|
||||
if (this.pos_profile && this.pos_profile.print_format_for_online) {
|
||||
this.frm.meta.default_print_format = this.pos_profile.print_format_for_online;
|
||||
}
|
||||
this.frm.print_preview.printit(true);
|
||||
});
|
||||
|
||||
@@ -899,7 +916,7 @@ class POSItems {
|
||||
this.search_field = frappe.ui.form.make_control({
|
||||
df: {
|
||||
fieldtype: 'Data',
|
||||
label: 'Search Item ( Ctrl + i )',
|
||||
label: 'Search Item (Ctrl + i)',
|
||||
placeholder: 'Search by item code, serial number, batch no or barcode'
|
||||
},
|
||||
parent: this.wrapper.find('.search-field'),
|
||||
@@ -963,7 +980,7 @@ class POSItems {
|
||||
}
|
||||
curr_row += all_items[i];
|
||||
|
||||
if(i == all_items.length - 1 && all_items.length % 4 !== 0) {
|
||||
if(i == all_items.length - 1) {
|
||||
row_items.push(curr_row);
|
||||
}
|
||||
}
|
||||
@@ -991,7 +1008,7 @@ class POSItems {
|
||||
|
||||
this.get_items({search_value: search_term, item_group })
|
||||
.then(({ items, serial_no, batch_no, barcode }) => {
|
||||
if (search_term) {
|
||||
if (search_term && !barcode) {
|
||||
this.search_index[search_term] = items;
|
||||
}
|
||||
|
||||
@@ -1264,6 +1281,16 @@ class Payment {
|
||||
$(this.dialog.body).find('.input-with-feedback').focusin(function() {
|
||||
me.numpad.reset_value();
|
||||
me.fieldname = $(this).prop('dataset').fieldname;
|
||||
if (me.frm.doc.outstanding_amount > 0 &&
|
||||
!in_list(['write_off_amount', 'change_amount'], me.fieldname)) {
|
||||
me.frm.doc.payments.forEach((data) => {
|
||||
if (data.mode_of_payment == me.fieldname && !data.amount) {
|
||||
me.dialog.set_value(me.fieldname,
|
||||
me.frm.doc.outstanding_amount / me.frm.doc.conversion_rate);
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1403,4 +1430,4 @@ class Payment {
|
||||
this.dialog.set_value("paid_amount", this.frm.doc.paid_amount);
|
||||
this.dialog.set_value("outstanding_amount", this.frm.doc.outstanding_amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,7 +232,7 @@ class EmailDigest(Document):
|
||||
"new_quotations","pending_quotations","sales_order","purchase_order","pending_sales_orders","pending_purchase_orders",
|
||||
"invoiced_amount", "payables", "bank_balance", "credit_balance"):
|
||||
if self.get(key):
|
||||
cache_key = "email_digest:card:{0}:{1}:{2}".format(self.company, self.frequency, key)
|
||||
cache_key = "email_digest:card:{0}:{1}:{2}:{3}".format(self.company, self.frequency, key, self.from_date)
|
||||
card = cache.get(cache_key)
|
||||
|
||||
if card:
|
||||
|
||||
@@ -81,7 +81,7 @@ class ItemGroup(NestedSet, WebsiteGenerator):
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def get_product_list_for_group(product_group=None, start=0, limit=10, search=None):
|
||||
child_groups = ", ".join(['"' + i[0] + '"' for i in get_child_groups(product_group)])
|
||||
child_groups = ", ".join(['"' + frappe.db.escape(i[0]) + '"' for i in get_child_groups(product_group)])
|
||||
|
||||
# base query
|
||||
query = """select name, item_name, item_code, route, image, website_image, thumbnail, item_group,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "field:party_type",
|
||||
@@ -13,6 +14,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -43,17 +45,17 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"in_create": 1,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-20 13:25:04.456818",
|
||||
"modified": "2017-11-23 17:46:27.075001",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Party Type",
|
||||
@@ -64,8 +66,8 @@
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
@@ -78,14 +80,14 @@
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
@@ -98,14 +100,14 @@
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
@@ -118,10 +120,10 @@
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
"write": 0
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 1,
|
||||
|
||||
23
erpnext/setup/doctype/party_type/test_party_type.js
Normal file
23
erpnext/setup/doctype/party_type/test_party_type.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Party Type", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Party Type
|
||||
() => frappe.tests.make('Party Type', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
frappe.ui.form.on('Sales Partner', {
|
||||
refresh: function(frm) {
|
||||
frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Sales Person'}
|
||||
frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Sales Partner'}
|
||||
|
||||
if(frm.doc.__islocal){
|
||||
hide_field(['address_html', 'contact_html', 'address_contacts']);
|
||||
|
||||
@@ -14,12 +14,12 @@ default_lead_sources = ["Existing Customer", "Reference", "Advertisement",
|
||||
def install(country=None):
|
||||
records = [
|
||||
# domains
|
||||
{ 'doctype': 'Domain', 'domain': _('Distribution')},
|
||||
{ 'doctype': 'Domain', 'domain': _('Manufacturing')},
|
||||
{ 'doctype': 'Domain', 'domain': _('Retail')},
|
||||
{ 'doctype': 'Domain', 'domain': _('Services')},
|
||||
{ 'doctype': 'Domain', 'domain': _('Education')},
|
||||
{ 'doctype': 'Domain', 'domain': _('Healthcare')},
|
||||
{ 'doctype': 'Domain', 'domain': 'Distribution'},
|
||||
{ 'doctype': 'Domain', 'domain': 'Manufacturing'},
|
||||
{ 'doctype': 'Domain', 'domain': 'Retail'},
|
||||
{ 'doctype': 'Domain', 'domain': 'Services'},
|
||||
{ 'doctype': 'Domain', 'domain': 'Education'},
|
||||
{ 'doctype': 'Domain', 'domain': 'Healthcare'},
|
||||
|
||||
# Setup Progress
|
||||
{'doctype': "Setup Progress", "actions": [
|
||||
|
||||
@@ -40,7 +40,7 @@ def setup_complete(args=None):
|
||||
|
||||
frappe.local.message_log = []
|
||||
domain_settings = frappe.get_single('Domain Settings')
|
||||
domain_settings.set_active_domains([_(args.get('domain'))])
|
||||
domain_settings.set_active_domains([args.get('domain')])
|
||||
|
||||
frappe.db.commit()
|
||||
login_as_first_user(args)
|
||||
@@ -186,10 +186,6 @@ def set_defaults(args):
|
||||
hr_settings.emp_created_by = "Naming Series"
|
||||
hr_settings.save()
|
||||
|
||||
domain_settings = frappe.get_doc("Domain Settings")
|
||||
domain_settings.append('active_domains', dict(domain=_(args.get('domain'))))
|
||||
domain_settings.save()
|
||||
|
||||
def create_feed_and_todo():
|
||||
"""update Activity feed and create todo for creation of item, customer, vendor"""
|
||||
add_info_comment(**{
|
||||
|
||||
@@ -65,31 +65,38 @@ frappe.ui.form.on('Batch', {
|
||||
// move - ask for target warehouse and make stock entry
|
||||
rows.find('.btn-move').on('click', function() {
|
||||
var $btn = $(this);
|
||||
frappe.prompt({
|
||||
fieldname: 'to_warehouse',
|
||||
label: __('To Warehouse'),
|
||||
fieldtype: 'Link',
|
||||
options: 'Warehouse'
|
||||
},
|
||||
(data) => {
|
||||
frappe.call({
|
||||
method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
|
||||
args: {
|
||||
item_code: frm.doc.item,
|
||||
batch_no: frm.doc.name,
|
||||
qty: $btn.attr('data-qty'),
|
||||
from_warehouse: $btn.attr('data-warehouse'),
|
||||
to_warehouse: data.to_warehouse
|
||||
},
|
||||
callback: (r) => {
|
||||
frappe.show_alert(__('Stock Entry {0} created',
|
||||
['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
|
||||
frm.refresh();
|
||||
},
|
||||
});
|
||||
},
|
||||
__('Select Target Warehouse'),
|
||||
__('Move')
|
||||
const fields = [
|
||||
{
|
||||
fieldname: 'to_warehouse',
|
||||
label: __('To Warehouse'),
|
||||
fieldtype: 'Link',
|
||||
options: 'Warehouse'
|
||||
}
|
||||
];
|
||||
|
||||
frappe.prompt(
|
||||
fields,
|
||||
(data) => {
|
||||
frappe.call({
|
||||
method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
|
||||
args: {
|
||||
item_code: frm.doc.item,
|
||||
batch_no: frm.doc.name,
|
||||
qty: $btn.attr('data-qty'),
|
||||
from_warehouse: $btn.attr('data-warehouse'),
|
||||
to_warehouse: data.to_warehouse,
|
||||
source_document: frm.doc.reference_name,
|
||||
reference_doctype: frm.doc.reference_doctype
|
||||
},
|
||||
callback: (r) => {
|
||||
frappe.show_alert(__('Stock Entry {0} created',
|
||||
['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
|
||||
frm.refresh();
|
||||
},
|
||||
});
|
||||
},
|
||||
__('Select Target Warehouse'),
|
||||
__('Move')
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ class Bin(Document):
|
||||
|
||||
self.set_projected_qty()
|
||||
|
||||
self.db_set('reserved_qty_for_production', self.reserved_qty_for_production)
|
||||
self.db_set('reserved_qty_for_production', flt(self.reserved_qty_for_production))
|
||||
self.db_set('projected_qty', self.projected_qty)
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ from erpnext import set_perpetual_inventory
|
||||
from erpnext.stock.doctype.serial_no.serial_no import SerialNoDuplicateError
|
||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
||||
|
||||
|
||||
class TestPurchaseReceipt(unittest.TestCase):
|
||||
def setUp(self):
|
||||
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
|
||||
@@ -259,7 +260,7 @@ class TestPurchaseReceipt(unittest.TestCase):
|
||||
|
||||
item_code = frappe.db.get_value('Item', {'has_serial_no': 1})
|
||||
if not item_code:
|
||||
item = make_item("Test Serial Item 1", dict(has_serial_no = 1))
|
||||
item = make_item("Test Serial Item 1", dict(has_serial_no=1))
|
||||
item_code = item.name
|
||||
|
||||
serial_no = random_string(5)
|
||||
@@ -273,11 +274,13 @@ class TestPurchaseReceipt(unittest.TestCase):
|
||||
serial_no=serial_no, basic_rate=100, do_not_submit=True)
|
||||
self.assertRaises(SerialNoDuplicateError, se.submit)
|
||||
|
||||
|
||||
def get_gl_entries(voucher_type, voucher_no):
|
||||
return frappe.db.sql("""select account, debit, credit
|
||||
from `tabGL Entry` where voucher_type=%s and voucher_no=%s
|
||||
order by account desc""", (voucher_type, voucher_no), as_dict=1)
|
||||
|
||||
|
||||
def make_purchase_receipt(**args):
|
||||
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
|
||||
pr = frappe.new_doc("Purchase Receipt")
|
||||
|
||||
@@ -14,8 +14,6 @@ frappe.ui.form.on('Stock Entry', {
|
||||
]
|
||||
}
|
||||
});
|
||||
// },
|
||||
// onload_post_render: function(frm) {
|
||||
|
||||
frm.set_query('batch_no', 'items', function(doc, cdt, cdn) {
|
||||
var item = locals[cdt][cdn];
|
||||
@@ -40,9 +38,8 @@ frappe.ui.form.on('Stock Entry', {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if(!frm.doc.docstatus) {
|
||||
frm.add_custom_button(__('Make Material Request'), function() {
|
||||
@@ -73,10 +70,12 @@ frappe.ui.form.on('Stock Entry', {
|
||||
frm.trigger("toggle_display_account_head");
|
||||
}
|
||||
},
|
||||
|
||||
purpose: function(frm) {
|
||||
frm.fields_dict.items.grid.refresh();
|
||||
frm.cscript.toggle_related_fields(frm.doc);
|
||||
},
|
||||
|
||||
company: function(frm) {
|
||||
if(frm.doc.company) {
|
||||
var company_doc = frappe.get_doc(":Company", frm.doc.company);
|
||||
@@ -86,6 +85,7 @@ frappe.ui.form.on('Stock Entry', {
|
||||
frm.trigger("toggle_display_account_head");
|
||||
}
|
||||
},
|
||||
|
||||
set_serial_no: function(frm, cdt, cdn) {
|
||||
var d = frappe.model.get_doc(cdt, cdn);
|
||||
if(!d.item_code && !d.s_warehouse && !d.qty) return;
|
||||
@@ -104,20 +104,142 @@ frappe.ui.form.on('Stock Entry', {
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
toggle_display_account_head: function(frm) {
|
||||
var enabled = erpnext.is_perpetual_inventory_enabled(frm.doc.company);
|
||||
frm.fields_dict["items"].grid.set_column_disp(["cost_center", "expense_account"], enabled);
|
||||
}
|
||||
},
|
||||
|
||||
set_basic_rate: function(frm, cdt, cdn, callback) {
|
||||
const item = locals[cdt][cdn];
|
||||
item.transfer_qty = flt(item.qty) * flt(item.conversion_factor);
|
||||
|
||||
const args = {
|
||||
'item_code' : item.item_code,
|
||||
'posting_date' : frm.doc.posting_date,
|
||||
'posting_time' : frm.doc.posting_time,
|
||||
'warehouse' : cstr(item.s_warehouse) || cstr(item.t_warehouse),
|
||||
'serial_no ' : item.serial_no,
|
||||
'company' : frm.doc.company,
|
||||
'qty' : item.s_warehouse ? -1*flt(item.transfer_qty) : flt(item.transfer_qty)
|
||||
};
|
||||
|
||||
frappe.call({
|
||||
method: "erpnext.stock.utils.get_incoming_rate",
|
||||
args: {
|
||||
args: args
|
||||
},
|
||||
callback: function(r) {
|
||||
frappe.model.set_value(cdt, cdn, 'basic_rate', r.message);
|
||||
frm.events.calculate_basic_amount(frm, item);
|
||||
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
get_warehouse_details: function(frm, cdt, cdn, callback) {
|
||||
var child = locals[cdt][cdn];
|
||||
if(!child.bom_no) {
|
||||
frappe.call({
|
||||
method: "erpnext.stock.doctype.stock_entry.stock_entry.get_warehouse_details",
|
||||
args: {
|
||||
"args": {
|
||||
'item_code': child.item_code,
|
||||
'warehouse': cstr(child.s_warehouse) || cstr(child.t_warehouse),
|
||||
'transfer_qty': child.transfer_qty,
|
||||
'serial_no': child.serial_no,
|
||||
'qty': child.s_warehouse ? -1* child.transfer_qty : child.transfer_qty,
|
||||
'posting_date': frm.doc.posting_date,
|
||||
'posting_time': frm.doc.posting_time
|
||||
}
|
||||
},
|
||||
callback: function(r) {
|
||||
if (!r.exc) {
|
||||
$.extend(child, r.message);
|
||||
frm.events.calculate_basic_amount(frm, child);
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
calculate_basic_amount: function(frm, item) {
|
||||
item.basic_amount = flt(flt(item.transfer_qty) * flt(item.basic_rate),
|
||||
precision("basic_amount", item));
|
||||
|
||||
frm.events.calculate_amount(frm);
|
||||
},
|
||||
|
||||
calculate_amount: function(frm) {
|
||||
frm.events.calculate_total_additional_costs(frm);
|
||||
|
||||
const total_basic_amount = frappe.utils.sum(
|
||||
(frm.doc.items || []).map(function(i) { return i.t_warehouse ? flt(i.basic_amount) : 0; })
|
||||
);
|
||||
|
||||
for (let i in frm.doc.items) {
|
||||
let item = frm.doc.items[i];
|
||||
|
||||
if (item.t_warehouse && total_basic_amount) {
|
||||
item.additional_cost = (flt(item.basic_amount) / total_basic_amount) * frm.doc.total_additional_costs;
|
||||
} else {
|
||||
item.additional_cost = 0;
|
||||
}
|
||||
|
||||
item.amount = flt(item.basic_amount + flt(item.additional_cost),
|
||||
precision("amount", item));
|
||||
|
||||
item.valuation_rate = flt(flt(item.basic_rate)
|
||||
+ (flt(item.additional_cost) / flt(item.transfer_qty)),
|
||||
precision("valuation_rate", item));
|
||||
}
|
||||
|
||||
refresh_field('items');
|
||||
},
|
||||
|
||||
calculate_total_additional_costs: function(frm) {
|
||||
const total_additional_costs = frappe.utils.sum(
|
||||
(frm.doc.additional_costs || []).map(function(c) { return flt(c.amount); })
|
||||
);
|
||||
|
||||
frm.set_value("total_additional_costs",
|
||||
flt(total_additional_costs, precision("total_additional_costs")));
|
||||
},
|
||||
})
|
||||
|
||||
frappe.ui.form.on('Stock Entry Detail', {
|
||||
qty: function(frm, cdt, cdn) {
|
||||
frm.events.set_serial_no(frm, cdt, cdn);
|
||||
frm.events.set_basic_rate(frm, cdt, cdn, () => {
|
||||
frm.events.set_serial_no(frm, cdt, cdn);
|
||||
});
|
||||
},
|
||||
|
||||
conversion_factor: function(frm, cdt, cdn) {
|
||||
frm.events.set_basic_rate(frm, cdt, cdn);
|
||||
},
|
||||
|
||||
s_warehouse: function(frm, cdt, cdn) {
|
||||
frm.events.set_serial_no(frm, cdt, cdn);
|
||||
frm.events.get_warehouse_details(frm, cdt, cdn, () => {
|
||||
frm.events.set_serial_no(frm, cdt, cdn);
|
||||
});
|
||||
},
|
||||
|
||||
t_warehouse: function(frm, cdt, cdn) {
|
||||
frm.events.get_warehouse_details(frm, cdt, cdn);
|
||||
},
|
||||
|
||||
basic_rate: function(frm, cdt, cdn) {
|
||||
var item = locals[cdt][cdn];
|
||||
frm.events.calculate_basic_amount(frm, item);
|
||||
},
|
||||
|
||||
barcode: function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.barcode) {
|
||||
@@ -132,6 +254,7 @@ frappe.ui.form.on('Stock Entry Detail', {
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
uom: function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if(d.uom && d.item_code){
|
||||
@@ -150,6 +273,7 @@ frappe.ui.form.on('Stock Entry Detail', {
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
item_code: function(frm, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if(d.item_code) {
|
||||
@@ -157,7 +281,7 @@ frappe.ui.form.on('Stock Entry Detail', {
|
||||
'item_code' : d.item_code,
|
||||
'warehouse' : cstr(d.s_warehouse) || cstr(d.t_warehouse),
|
||||
'transfer_qty' : d.transfer_qty,
|
||||
'serial_no ' : d.serial_no,
|
||||
'serial_no' : d.serial_no,
|
||||
'bom_no' : d.bom_no,
|
||||
'expense_account' : d.expense_account,
|
||||
'cost_center' : d.cost_center,
|
||||
@@ -191,7 +315,7 @@ frappe.ui.form.on('Stock Entry Detail', {
|
||||
|
||||
frappe.ui.form.on('Landed Cost Taxes and Charges', {
|
||||
amount: function(frm) {
|
||||
frm.events.calculate_amount();
|
||||
frm.events.calculate_amount(frm);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -330,12 +454,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
}
|
||||
},
|
||||
|
||||
qty: function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
d.transfer_qty = flt(d.qty) * flt(d.conversion_factor);
|
||||
this.calculate_basic_amount(d);
|
||||
},
|
||||
|
||||
production_order: function() {
|
||||
var me = this;
|
||||
this.toggle_enable_bom();
|
||||
@@ -434,88 +552,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
erpnext.setup_serial_no();
|
||||
},
|
||||
|
||||
basic_rate: function(doc, cdt, cdn) {
|
||||
var item = frappe.model.get_doc(cdt, cdn);
|
||||
this.calculate_basic_amount(item);
|
||||
},
|
||||
|
||||
s_warehouse: function(doc, cdt, cdn) {
|
||||
this.get_warehouse_details(doc, cdt, cdn)
|
||||
},
|
||||
|
||||
t_warehouse: function(doc, cdt, cdn) {
|
||||
this.get_warehouse_details(doc, cdt, cdn)
|
||||
},
|
||||
|
||||
get_warehouse_details: function(doc, cdt, cdn) {
|
||||
var me = this;
|
||||
var d = locals[cdt][cdn];
|
||||
if(!d.bom_no) {
|
||||
frappe.call({
|
||||
method: "erpnext.stock.doctype.stock_entry.stock_entry.get_warehouse_details",
|
||||
args: {
|
||||
"args": {
|
||||
'item_code': d.item_code,
|
||||
'warehouse': cstr(d.s_warehouse) || cstr(d.t_warehouse),
|
||||
'transfer_qty': d.transfer_qty,
|
||||
'serial_no': d.serial_no,
|
||||
'qty': d.s_warehouse ? -1* d.qty : d.qty,
|
||||
'posting_date': this.frm.doc.posting_date,
|
||||
'posting_time': this.frm.doc.posting_time
|
||||
}
|
||||
},
|
||||
callback: function(r) {
|
||||
if (!r.exc) {
|
||||
$.extend(d, r.message);
|
||||
me.calculate_basic_amount(d);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
calculate_basic_amount: function(item) {
|
||||
item.basic_amount = flt(flt(item.transfer_qty) * flt(item.basic_rate),
|
||||
precision("basic_amount", item));
|
||||
|
||||
this.calculate_amount();
|
||||
},
|
||||
|
||||
calculate_amount: function() {
|
||||
this.calculate_total_additional_costs();
|
||||
|
||||
var total_basic_amount = frappe.utils.sum(
|
||||
(this.frm.doc.items || []).map(function(i) { return i.t_warehouse ? flt(i.basic_amount) : 0; })
|
||||
);
|
||||
|
||||
for (var i in this.frm.doc.items) {
|
||||
var item = this.frm.doc.items[i];
|
||||
|
||||
if (item.t_warehouse && total_basic_amount) {
|
||||
item.additional_cost = (flt(item.basic_amount) / total_basic_amount) * this.frm.doc.total_additional_costs;
|
||||
} else {
|
||||
item.additional_cost = 0;
|
||||
}
|
||||
|
||||
item.amount = flt(item.basic_amount + flt(item.additional_cost),
|
||||
precision("amount", item));
|
||||
|
||||
item.valuation_rate = flt(flt(item.basic_rate)
|
||||
+ (flt(item.additional_cost) / flt(item.transfer_qty)),
|
||||
precision("valuation_rate", item));
|
||||
}
|
||||
|
||||
refresh_field('items');
|
||||
},
|
||||
|
||||
calculate_total_additional_costs: function() {
|
||||
var total_additional_costs = frappe.utils.sum(
|
||||
(this.frm.doc.additional_costs || []).map(function(c) { return flt(c.amount); })
|
||||
);
|
||||
|
||||
this.frm.set_value("total_additional_costs", flt(total_additional_costs, precision("total_additional_costs")));
|
||||
},
|
||||
|
||||
toggle_related_fields: function(doc) {
|
||||
this.frm.toggle_enable("from_warehouse", doc.purpose!='Material Receipt');
|
||||
this.frm.toggle_enable("to_warehouse", doc.purpose!='Material Issue');
|
||||
|
||||
@@ -49,6 +49,9 @@ class StockEntry(StockController):
|
||||
self.validate_with_material_request()
|
||||
self.validate_batch()
|
||||
|
||||
if not self.from_bom:
|
||||
self.fg_completed_qty = 0.0
|
||||
|
||||
if self._action == 'submit':
|
||||
self.make_batches('t_warehouse')
|
||||
else:
|
||||
@@ -351,6 +354,7 @@ class StockEntry(StockController):
|
||||
if self.purpose == "Subcontract" and self.purchase_order:
|
||||
purchase_order = frappe.get_doc("Purchase Order", self.purchase_order)
|
||||
for se_item in self.items:
|
||||
precision = cint(frappe.db.get_default("float_precision")) or 3
|
||||
total_allowed = sum([flt(d.required_qty) for d in purchase_order.supplied_items \
|
||||
if d.rm_item_code == se_item.item_code])
|
||||
if not total_allowed:
|
||||
@@ -364,8 +368,8 @@ class StockEntry(StockController):
|
||||
and `tabStock Entry Detail`.parent = `tabStock Entry`.name""",
|
||||
(self.purchase_order, se_item.item_code))[0][0]
|
||||
|
||||
if total_supplied > total_allowed:
|
||||
frappe.throw(_("Not allowed to tranfer more {0} than {1} against Purchase Order {2}").format(se_item.item_code,
|
||||
if flt(total_supplied, precision) > flt(total_allowed, precision):
|
||||
frappe.throw(_("Not allowed to transfer more {0} than {1} against Purchase Order {2}").format(se_item.item_code,
|
||||
total_allowed, self.purchase_order))
|
||||
|
||||
def validate_bom(self):
|
||||
@@ -517,7 +521,7 @@ class StockEntry(StockController):
|
||||
args['posting_date'] = self.posting_date
|
||||
args['posting_time'] = self.posting_time
|
||||
|
||||
stock_and_rate = args.get('warehouse') and get_warehouse_details(args) or {}
|
||||
stock_and_rate = get_warehouse_details(args) if args.get('warehouse') else {}
|
||||
ret.update(stock_and_rate)
|
||||
|
||||
# automatically select batch for outgoing item
|
||||
@@ -771,6 +775,9 @@ class StockEntry(StockController):
|
||||
se_child.expense_account = item_dict[d].get("expense_account") or expense_account
|
||||
se_child.cost_center = item_dict[d].get("cost_center") or cost_center
|
||||
|
||||
if item_dict[d].get("idx"):
|
||||
se_child.idx = item_dict[d].get("idx")
|
||||
|
||||
if se_child.s_warehouse==None:
|
||||
se_child.s_warehouse = self.from_warehouse
|
||||
if se_child.t_warehouse==None:
|
||||
|
||||
@@ -20,6 +20,16 @@ def make_stock_entry(**args):
|
||||
:do_not_save: Optional flag
|
||||
:do_not_submit: Optional flag
|
||||
'''
|
||||
|
||||
def process_serial_numbers(serial_nos_list):
|
||||
serial_nos_list = [
|
||||
'\n'.join(serial_num['serial_no'] for serial_num in serial_nos_list)
|
||||
]
|
||||
|
||||
uniques = list(set(serial_nos_list[0].split('\n')))
|
||||
|
||||
return '\n'.join(uniques)
|
||||
|
||||
s = frappe.new_doc("Stock Entry")
|
||||
args = frappe._dict(args)
|
||||
|
||||
@@ -77,6 +87,25 @@ def make_stock_entry(**args):
|
||||
if not args.cost_center:
|
||||
args.cost_center = frappe.get_value('Company', s.company, 'cost_center')
|
||||
|
||||
if not args.expense_account:
|
||||
args.expense_account = frappe.get_value('Company', s.company, 'stock_adjustment_account')
|
||||
|
||||
# We can find out the serial number using the batch source document
|
||||
serial_number = args.serial_no
|
||||
|
||||
if not args.serial_no and args.qty and args.batch_no:
|
||||
serial_number_list = frappe.get_list(
|
||||
doctype='Stock Ledger Entry',
|
||||
fields=['serial_no'],
|
||||
filters={
|
||||
'batch_no': args.batch_no,
|
||||
'warehouse': args.from_warehouse
|
||||
}
|
||||
)
|
||||
serial_number = process_serial_numbers(serial_number_list)
|
||||
|
||||
args.serial_no = serial_number
|
||||
|
||||
s.append("items", {
|
||||
"item_code": args.item,
|
||||
"s_warehouse": args.source,
|
||||
|
||||
@@ -96,16 +96,6 @@ def get_item_details(args):
|
||||
|
||||
return out
|
||||
|
||||
# print(frappe._dict({
|
||||
# 'has_serial_no' : out.has_serial_no,
|
||||
# 'has_batch_no' : out.has_batch_no
|
||||
# }))
|
||||
|
||||
# return frappe._dict({
|
||||
# 'has_serial_no' : out.has_serial_no,
|
||||
# 'has_batch_no' : out.has_batch_no
|
||||
# })
|
||||
|
||||
def process_args(args):
|
||||
if isinstance(args, basestring):
|
||||
args = json.loads(args)
|
||||
@@ -373,11 +363,11 @@ def get_pos_profile_item_details(company, args, pos_profile=None):
|
||||
@frappe.whitelist()
|
||||
def get_pos_profile(company):
|
||||
pos_profile = frappe.db.sql("""select * from `tabPOS Profile` where user = %s
|
||||
and company = %s""", (frappe.session['user'], company), as_dict=1)
|
||||
and company = %s and ifnull(disabled,0) != 1""", (frappe.session['user'], company), as_dict=1)
|
||||
|
||||
if not pos_profile:
|
||||
pos_profile = frappe.db.sql("""select * from `tabPOS Profile`
|
||||
where ifnull(user,'') = '' and company = %s""", company, as_dict=1)
|
||||
where ifnull(user,'') = '' and company = %s and ifnull(disabled,0) != 1""", company, as_dict=1)
|
||||
|
||||
return pos_profile and pos_profile[0] or None
|
||||
|
||||
@@ -532,8 +522,6 @@ def get_default_bom(item_code=None):
|
||||
bom = frappe.db.get_value("BOM", {"docstatus": 1, "is_default": 1, "is_active": 1, "item": item_code})
|
||||
if bom:
|
||||
return bom
|
||||
else:
|
||||
frappe.throw(_("No default BOM exists for Item {0}").format(item_code))
|
||||
|
||||
def get_valuation_rate(item_code, warehouse=None):
|
||||
item = frappe.get_doc("Item", item_code)
|
||||
|
||||
@@ -230,6 +230,13 @@ class update_entries_after(object):
|
||||
# else it remains the same as that of previous entry
|
||||
self.valuation_rate = new_stock_value / new_stock_qty
|
||||
|
||||
if not self.valuation_rate and sle.voucher_detail_no:
|
||||
allow_zero_rate = self.check_if_allow_zero_valuation_rate(sle.voucher_type, sle.voucher_detail_no)
|
||||
if not allow_zero_rate:
|
||||
self.valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse,
|
||||
sle.voucher_type, sle.voucher_no, self.allow_zero_rate,
|
||||
currency=erpnext.get_company_currency(sle.company))
|
||||
|
||||
def get_moving_average_values(self, sle):
|
||||
actual_qty = flt(sle.actual_qty)
|
||||
new_stock_qty = flt(self.qty_after_transaction) + actual_qty
|
||||
|
||||
@@ -126,7 +126,7 @@ def update_bin(args, allow_negative_stock=False, via_landed_cost_voucher=False):
|
||||
def get_incoming_rate(args):
|
||||
"""Get Incoming Rate based on valuation method"""
|
||||
from erpnext.stock.stock_ledger import get_previous_sle
|
||||
|
||||
|
||||
if isinstance(args, basestring):
|
||||
args = json.loads(args)
|
||||
|
||||
@@ -141,6 +141,8 @@ def get_incoming_rate(args):
|
||||
return 0.0
|
||||
previous_stock_queue = json.loads(previous_sle.get('stock_queue', '[]') or '[]')
|
||||
in_rate = get_fifo_rate(previous_stock_queue, args.get("qty") or 0) if previous_stock_queue else 0
|
||||
if not in_rate and not previous_stock_queue:
|
||||
in_rate = previous_sle.get('valuation_rate') or 0
|
||||
elif valuation_method == 'Moving Average':
|
||||
in_rate = previous_sle.get('valuation_rate') or 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user