Compare commits
152 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a398b4742 | ||
|
|
56882033bf | ||
|
|
74c817e7f9 | ||
|
|
d98a6d81eb | ||
|
|
baac05955b | ||
|
|
89346967da | ||
|
|
97e890d0b3 | ||
|
|
95763bc233 | ||
|
|
96f4b22589 | ||
|
|
13460f023d | ||
|
|
3907eae83f | ||
|
|
04f50be306 | ||
|
|
b34ab7549a | ||
|
|
aa54d934b8 | ||
|
|
2c7a6e6b43 | ||
|
|
58797481f0 | ||
|
|
12aa4265ff | ||
|
|
69d9f51dbb | ||
|
|
3dea6589d7 | ||
|
|
096d136460 | ||
|
|
c3889d85a1 | ||
|
|
052333ea63 | ||
|
|
aadd30d194 | ||
|
|
22e6f8d4c2 | ||
|
|
acd3479269 | ||
|
|
a32e57ae82 | ||
|
|
a3a63177a1 | ||
|
|
1643cce479 | ||
|
|
bb42e3b411 | ||
|
|
586e9400b1 | ||
|
|
668ec25d19 | ||
|
|
f0543a9765 | ||
|
|
36b4faab48 | ||
|
|
2b59a851c4 | ||
|
|
857d4f7a0b | ||
|
|
12d7bfb658 | ||
|
|
ca6e223694 | ||
|
|
343ba85e3a | ||
|
|
16c324f699 | ||
|
|
1fa992564a | ||
|
|
a65b28772f | ||
|
|
ba6003ece7 | ||
|
|
491ce05b8d | ||
|
|
2cfcbf933d | ||
|
|
2550180a05 | ||
|
|
5fd7b3bb80 | ||
|
|
35b665cb26 | ||
|
|
a6a4e86dc8 | ||
|
|
0eb8bb2511 | ||
|
|
67cfa81de2 | ||
|
|
a942722619 | ||
|
|
c10bbd6aa7 | ||
|
|
4badb45ee5 | ||
|
|
855d843e55 | ||
|
|
0df95fa781 | ||
|
|
6578bc11b6 | ||
|
|
f68dc69078 | ||
|
|
502af4dd67 | ||
|
|
db9fa78ee8 | ||
|
|
a645f36b2b | ||
|
|
332a17ee86 | ||
|
|
a310cc7156 | ||
|
|
3b43c0d160 | ||
|
|
96002c28bd | ||
|
|
91fc1a8fbe | ||
|
|
f1755fb5b1 | ||
|
|
be841ccc53 | ||
|
|
51dfba749b | ||
|
|
3799f8bec9 | ||
|
|
3edc101957 | ||
|
|
127c61e930 | ||
|
|
e55831a89c | ||
|
|
4ff4d185f7 | ||
|
|
d54953e419 | ||
|
|
339426c926 | ||
|
|
489ff6e21c | ||
|
|
d12fb58c12 | ||
|
|
82048cf3ce | ||
|
|
4d76269eeb | ||
|
|
d5b2e39f45 | ||
|
|
dd0fc1084e | ||
|
|
d283ee73f3 | ||
|
|
93f138eece | ||
|
|
2b2cf13408 | ||
|
|
7f49b57aaa | ||
|
|
00330f52bd | ||
|
|
6b69fc7e5d | ||
|
|
d8cd54dfd0 | ||
|
|
2949e9c5dc | ||
|
|
15bd3167a8 | ||
|
|
9b530fb2cb | ||
|
|
06bace9089 | ||
|
|
c15978fca0 | ||
|
|
cb2264e0b4 | ||
|
|
7d862276af | ||
|
|
e4fe2d9603 | ||
|
|
23a2b65576 | ||
|
|
0bde9e11c7 | ||
|
|
09d56754ea | ||
|
|
e9166d7c19 | ||
|
|
9a64d4371e | ||
|
|
d4491d361f | ||
|
|
09acb779d7 | ||
|
|
67f74414c4 | ||
|
|
8a77a0e1e4 | ||
|
|
bc5515651b | ||
|
|
f65afac353 | ||
|
|
2fbb4923a7 | ||
|
|
554f2de23d | ||
|
|
a5003f8f5b | ||
|
|
6c5d7986ab | ||
|
|
5448318146 | ||
|
|
174a18399c | ||
|
|
ec23a6f0eb | ||
|
|
33b2614377 | ||
|
|
b95ecd7fcd | ||
|
|
cc98d40ff7 | ||
|
|
103c4e9b92 | ||
|
|
5a947f38ab | ||
|
|
0acb63a938 | ||
|
|
db6f0848e3 | ||
|
|
ca166eaae5 | ||
|
|
a13b177908 | ||
|
|
0500ce445f | ||
|
|
351dc08576 | ||
|
|
8e675ebbe2 | ||
|
|
d53b149828 | ||
|
|
5a91989665 | ||
|
|
62d6593fe7 | ||
|
|
ed35a296ab | ||
|
|
6a7495dbc8 | ||
|
|
6e90f49a35 | ||
|
|
6e7e70c977 | ||
|
|
0aeeb7e02c | ||
|
|
caccd2289d | ||
|
|
45ac31ab93 | ||
|
|
7477899d2e | ||
|
|
13afef2f72 | ||
|
|
cab73b8a02 | ||
|
|
c7a9e3424b | ||
|
|
a884bd9c6a | ||
|
|
37b2aa2b11 | ||
|
|
f4211c4a52 | ||
|
|
c1f982a9bb | ||
|
|
4d250585a6 | ||
|
|
6041f5cb8c | ||
|
|
144c9977a2 | ||
|
|
f1fa338999 | ||
|
|
f7717b9ec2 | ||
|
|
1a4d77a962 | ||
|
|
056c1709c6 | ||
|
|
b553b7a69d |
@@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '10.0.20'
|
||||
__version__ = '10.1.10'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -169,10 +169,10 @@ class Account(NestedSet):
|
||||
# Add company abbr if not provided
|
||||
from erpnext.setup.doctype.company.company import get_name_with_abbr
|
||||
new_account = get_name_with_abbr(new, self.company)
|
||||
new_account = get_name_with_number(new_account, self.account_number)
|
||||
|
||||
# Validate properties before merging
|
||||
if merge:
|
||||
if not merge:
|
||||
new_account = get_name_with_number(new_account, self.account_number)
|
||||
else:
|
||||
# Validate properties before merging
|
||||
if not frappe.db.exists("Account", new):
|
||||
throw(_("Account {0} does not exist").format(new))
|
||||
|
||||
|
||||
@@ -159,6 +159,36 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "include_pos_transactions",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Include POS Transactions",
|
||||
"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,
|
||||
@@ -292,7 +322,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-04-21 16:58:26.902732",
|
||||
"modified": "2018-03-07 18:58:48.658687",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Reconciliation",
|
||||
|
||||
@@ -53,10 +53,26 @@ class BankReconciliation(Document):
|
||||
posting_date ASC, name DESC
|
||||
""".format(condition),
|
||||
{"account":self.bank_account, "from":self.from_date, "to":self.to_date}, as_dict=1)
|
||||
|
||||
entries = sorted(list(payment_entries)+list(journal_entries),
|
||||
|
||||
pos_entries = []
|
||||
if self.include_pos_transactions:
|
||||
pos_entries = frappe.db.sql("""
|
||||
select
|
||||
"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit,
|
||||
si.posting_date, si.debit_to as against_account, sip.clearance_date,
|
||||
account.account_currency, 0 as credit
|
||||
from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account
|
||||
where
|
||||
sip.account=%(account)s and si.docstatus=1 and sip.parent = si.name
|
||||
and account.name = sip.account and si.posting_date >= %(from)s and si.posting_date <= %(to)s {0}
|
||||
order by
|
||||
si.posting_date ASC, si.name DESC
|
||||
""".format(condition),
|
||||
{"account":self.bank_account, "from":self.from_date, "to":self.to_date}, as_dict=1)
|
||||
|
||||
entries = sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
|
||||
key=lambda k: k['posting_date'] or getdate(nowdate()))
|
||||
|
||||
|
||||
self.set('payment_entries', [])
|
||||
self.total_amount = 0.0
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
|
||||
class TestBankReconciliation(unittest.TestCase):
|
||||
pass
|
||||
0
erpnext/accounts/doctype/gst_account/__init__.py
Normal file
0
erpnext/accounts/doctype/gst_account/__init__.py
Normal file
196
erpnext/accounts/doctype/gst_account/gst_account.json
Normal file
196
erpnext/accounts/doctype/gst_account/gst_account.json
Normal file
@@ -0,0 +1,196 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2018-01-02 15:48:58.768352",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Company",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "cgst_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "CGST Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "sgst_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "SGST Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "igst_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "IGST Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "cess_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "CESS Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-01-02 15:52:22.335988",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "GST Account",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
10
erpnext/accounts/doctype/gst_account/gst_account.py
Normal file
10
erpnext/accounts/doctype/gst_account/gst_account.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class GSTAccount(Document):
|
||||
pass
|
||||
@@ -145,13 +145,13 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.doc.paid_amount : frm.doc.received_amount;
|
||||
|
||||
frm.toggle_display("write_off_difference_amount", (frm.doc.difference_amount && frm.doc.party &&
|
||||
(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) &&
|
||||
(frm.doc.total_allocated_amount > party_amount)));
|
||||
|
||||
frm.toggle_display("set_exchange_gain_loss",
|
||||
(frm.doc.paid_amount && frm.doc.received_amount && frm.doc.difference_amount &&
|
||||
(frm.doc.paid_from_account_currency != company_currency ||
|
||||
frm.doc.paid_to_account_currency != company_currency)));
|
||||
((frm.doc.paid_from_account_currency != company_currency ||
|
||||
frm.doc.paid_to_account_currency != company_currency) &&
|
||||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency)));
|
||||
|
||||
frm.refresh_fields();
|
||||
},
|
||||
@@ -300,7 +300,15 @@ frappe.ui.form.on('Payment Entry', {
|
||||
if(frm.doc.payment_type == "Pay") {
|
||||
frm.events.get_outstanding_documents(frm);
|
||||
} else if (frm.doc.payment_type == "Receive") {
|
||||
frm.events.received_amount(frm);
|
||||
if(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
|
||||
if(frm.doc.source_exchange_rate) {
|
||||
frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
|
||||
}
|
||||
frm.set_value("received_amount", frm.doc.paid_amount);
|
||||
|
||||
} else {
|
||||
frm.events.received_amount(frm);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -317,26 +325,31 @@ frappe.ui.form.on('Payment Entry', {
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
if(r.message) {
|
||||
frm.set_value(currency_field, r.message['account_currency']);
|
||||
frm.set_value(balance_field, r.message['account_balance']);
|
||||
frappe.run_serially([
|
||||
() => frm.set_value(currency_field, r.message['account_currency']),
|
||||
() => {
|
||||
frm.set_value(balance_field, r.message['account_balance']);
|
||||
|
||||
if(frm.doc.payment_type=="Receive" && currency_field=="paid_to_account_currency") {
|
||||
frm.toggle_reqd(["reference_no", "reference_date"],
|
||||
(r.message['account_type'] == "Bank" ? 1 : 0));
|
||||
if(!frm.doc.received_amount && frm.doc.paid_amount)
|
||||
frm.events.paid_amount(frm);
|
||||
} else if(frm.doc.payment_type=="Pay" && currency_field=="paid_from_account_currency") {
|
||||
frm.toggle_reqd(["reference_no", "reference_date"],
|
||||
(r.message['account_type'] == "Bank" ? 1 : 0));
|
||||
if(frm.doc.payment_type=="Receive" && currency_field=="paid_to_account_currency") {
|
||||
frm.toggle_reqd(["reference_no", "reference_date"],
|
||||
(r.message['account_type'] == "Bank" ? 1 : 0));
|
||||
if(!frm.doc.received_amount && frm.doc.paid_amount)
|
||||
frm.events.paid_amount(frm);
|
||||
} else if(frm.doc.payment_type=="Pay" && currency_field=="paid_from_account_currency") {
|
||||
frm.toggle_reqd(["reference_no", "reference_date"],
|
||||
(r.message['account_type'] == "Bank" ? 1 : 0));
|
||||
|
||||
if(!frm.doc.paid_amount && frm.doc.received_amount)
|
||||
frm.events.received_amount(frm);
|
||||
}
|
||||
if(!frm.doc.paid_amount && frm.doc.received_amount)
|
||||
frm.events.received_amount(frm);
|
||||
}
|
||||
},
|
||||
() => {
|
||||
if(callback_function) callback_function(frm);
|
||||
|
||||
if(callback_function) callback_function(frm);
|
||||
|
||||
frm.events.hide_unhide_fields(frm);
|
||||
frm.events.set_dynamic_labels(frm);
|
||||
frm.events.hide_unhide_fields(frm);
|
||||
frm.events.set_dynamic_labels(frm);
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -405,7 +418,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_value("base_received_amount", frm.doc.base_paid_amount);
|
||||
}
|
||||
|
||||
frm.events.set_difference_amount(frm);
|
||||
frm.events.set_unallocated_amount(frm);
|
||||
}
|
||||
|
||||
// Make read only if Accounts Settings doesn't allow stale rates
|
||||
@@ -425,7 +438,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_value("base_paid_amount", frm.doc.base_received_amount);
|
||||
}
|
||||
|
||||
frm.events.set_difference_amount(frm);
|
||||
frm.events.set_unallocated_amount(frm);
|
||||
}
|
||||
frm.set_paid_amount_based_on_received_amount = false;
|
||||
|
||||
@@ -456,7 +469,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
if(frm.doc.payment_type == "Pay")
|
||||
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
|
||||
else
|
||||
frm.events.set_difference_amount(frm);
|
||||
frm.events.set_unallocated_amount(frm);
|
||||
|
||||
frm.set_paid_amount_based_on_received_amount = false;
|
||||
},
|
||||
@@ -476,7 +489,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
if(frm.doc.payment_type == "Receive")
|
||||
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
|
||||
else
|
||||
frm.events.set_difference_amount(frm);
|
||||
frm.events.set_unallocated_amount(frm);
|
||||
},
|
||||
|
||||
get_outstanding_documents: function(frm) {
|
||||
@@ -565,8 +578,11 @@ frappe.ui.form.on('Payment Entry', {
|
||||
if(frm.doc.references.length == 0){
|
||||
frm.events.get_outstanding_documents(frm);
|
||||
}
|
||||
|
||||
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
|
||||
if(frm.doc.payment_type == 'Internal Transfer') {
|
||||
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
|
||||
} else {
|
||||
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
|
||||
}
|
||||
},
|
||||
|
||||
allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
|
||||
@@ -651,28 +667,32 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_value("total_allocated_amount", Math.abs(total_allocated_amount));
|
||||
frm.set_value("base_total_allocated_amount", Math.abs(base_total_allocated_amount));
|
||||
|
||||
frm.events.set_difference_amount(frm);
|
||||
frm.events.set_unallocated_amount(frm);
|
||||
},
|
||||
|
||||
set_difference_amount: function(frm) {
|
||||
set_unallocated_amount: function(frm) {
|
||||
var unallocated_amount = 0;
|
||||
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
|
||||
function(d) { return flt(d.amount) }));
|
||||
|
||||
if(frm.doc.party) {
|
||||
var party_amount = frm.doc.payment_type=="Receive" ?
|
||||
frm.doc.paid_amount : frm.doc.received_amount;
|
||||
|
||||
if(frm.doc.total_allocated_amount < party_amount) {
|
||||
if(frm.doc.payment_type == "Receive") {
|
||||
unallocated_amount = party_amount - (frm.doc.total_allocated_amount - total_deductions);
|
||||
} else {
|
||||
unallocated_amount = party_amount - (frm.doc.total_allocated_amount + total_deductions);
|
||||
}
|
||||
if(frm.doc.payment_type == "Receive"
|
||||
&& frm.doc.base_total_allocated_amount < frm.doc.base_received_amount + total_deductions
|
||||
&& frm.doc.total_allocated_amount < frm.doc.paid_amount + (total_deductions / frm.doc.source_exchange_rate)) {
|
||||
unallocated_amount = (frm.doc.base_received_amount + total_deductions
|
||||
- frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
|
||||
} else if (frm.doc.payment_type == "Pay"
|
||||
&& frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions
|
||||
&& frm.doc.total_allocated_amount < frm.doc.received_amount + (total_deductions / frm.doc.target_exchange_rate)) {
|
||||
unallocated_amount = (frm.doc.base_paid_amount - (total_deductions
|
||||
+ frm.doc.base_total_allocated_amount)) / frm.doc.target_exchange_rate;
|
||||
}
|
||||
}
|
||||
frm.set_value("unallocated_amount", unallocated_amount);
|
||||
|
||||
frm.trigger("set_difference_amount");
|
||||
},
|
||||
|
||||
set_difference_amount: function(frm) {
|
||||
var difference_amount = 0;
|
||||
var base_unallocated_amount = flt(frm.doc.unallocated_amount) *
|
||||
(frm.doc.payment_type=="Receive" ? frm.doc.source_exchange_rate : frm.doc.target_exchange_rate);
|
||||
@@ -687,11 +707,18 @@ frappe.ui.form.on('Payment Entry', {
|
||||
difference_amount = flt(frm.doc.base_paid_amount) - flt(frm.doc.base_received_amount);
|
||||
}
|
||||
|
||||
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
|
||||
function(d) { return flt(d.amount) }));
|
||||
|
||||
frm.set_value("difference_amount", difference_amount - total_deductions);
|
||||
|
||||
frm.events.hide_unhide_fields(frm);
|
||||
},
|
||||
|
||||
unallocated_amount: function(frm) {
|
||||
frm.trigger("set_difference_amount");
|
||||
},
|
||||
|
||||
check_mandatory_to_fetch: function(frm) {
|
||||
$.each(["Company", "Party Type", "Party", "payment_type"], function(i, field) {
|
||||
if(!frm.doc[frappe.model.scrub(field)]) {
|
||||
@@ -771,7 +798,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
row.amount = flt(row.amount) + flt(frm.doc.difference_amount);
|
||||
refresh_field("deductions");
|
||||
|
||||
frm.events.set_difference_amount(frm);
|
||||
frm.events.set_unallocated_amount(frm);
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -818,10 +845,10 @@ frappe.ui.form.on('Payment Entry Reference', {
|
||||
|
||||
frappe.ui.form.on('Payment Entry Deduction', {
|
||||
amount: function(frm) {
|
||||
frm.events.set_difference_amount(frm);
|
||||
frm.events.set_unallocated_amount(frm);
|
||||
},
|
||||
|
||||
deductions_remove: function(frm) {
|
||||
frm.events.set_difference_amount(frm);
|
||||
frm.events.set_unallocated_amount(frm);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -71,6 +72,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 1,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -102,6 +104,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -131,6 +134,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -162,6 +166,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -193,6 +198,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -224,6 +230,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -255,6 +262,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -288,6 +296,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -320,6 +329,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -349,6 +359,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -381,6 +392,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -411,6 +423,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -442,6 +455,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -474,6 +488,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -506,6 +521,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -538,6 +554,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -567,6 +584,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -599,6 +617,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -631,6 +650,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -663,6 +683,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -695,6 +716,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -727,6 +749,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -758,6 +781,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -790,6 +814,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -819,6 +844,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -851,6 +877,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -882,6 +909,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -914,6 +942,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -946,6 +975,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -978,6 +1008,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1010,6 +1041,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1041,6 +1073,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1072,6 +1105,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1104,6 +1138,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1134,6 +1169,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1163,6 +1199,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1188,12 +1225,13 @@
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1226,6 +1264,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1257,6 +1296,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1289,6 +1329,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1320,6 +1361,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1350,6 +1392,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1381,6 +1424,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1410,6 +1454,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1441,6 +1486,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1472,6 +1518,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1504,6 +1551,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1536,6 +1584,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1566,6 +1615,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1595,6 +1645,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1626,6 +1677,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1657,6 +1709,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1687,6 +1740,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1718,6 +1772,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1748,6 +1803,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1778,6 +1834,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@@ -1791,7 +1848,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-08-31 11:20:37.578469",
|
||||
"modified": "2018-02-19 16:58:23.899015",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry",
|
||||
|
||||
@@ -20,6 +20,11 @@ class InvalidPaymentEntry(ValidationError):
|
||||
|
||||
|
||||
class PaymentEntry(AccountsController):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PaymentEntry, self).__init__(*args, **kwargs)
|
||||
if not self.is_new():
|
||||
self.setup_party_account_field()
|
||||
|
||||
def setup_party_account_field(self):
|
||||
self.party_account_field = None
|
||||
self.party_account = None
|
||||
@@ -58,16 +63,21 @@ class PaymentEntry(AccountsController):
|
||||
if self.difference_amount:
|
||||
frappe.throw(_("Difference Amount must be zero"))
|
||||
self.make_gl_entries()
|
||||
self.update_outstanding_amounts()
|
||||
self.update_advance_paid()
|
||||
self.update_expense_claim()
|
||||
|
||||
def on_cancel(self):
|
||||
self.setup_party_account_field()
|
||||
self.make_gl_entries(cancel=1)
|
||||
self.update_outstanding_amounts()
|
||||
self.update_advance_paid()
|
||||
self.update_expense_claim()
|
||||
self.delink_advance_entry_references()
|
||||
|
||||
def update_outstanding_amounts(self):
|
||||
self.set_missing_ref_details(force=True)
|
||||
|
||||
def validate_duplicate_entry(self):
|
||||
reference_names = []
|
||||
for d in self.get("references"):
|
||||
@@ -129,14 +139,14 @@ class PaymentEntry(AccountsController):
|
||||
|
||||
self.set_missing_ref_details()
|
||||
|
||||
def set_missing_ref_details(self):
|
||||
def set_missing_ref_details(self, force=False):
|
||||
for d in self.get("references"):
|
||||
if d.allocated_amount:
|
||||
ref_details = get_reference_details(d.reference_doctype,
|
||||
d.reference_name, self.party_account_currency)
|
||||
|
||||
for field, value in ref_details.items():
|
||||
if not d.get(field):
|
||||
if not d.get(field) or force:
|
||||
d.set(field, value)
|
||||
|
||||
def validate_payment_type(self):
|
||||
@@ -281,17 +291,19 @@ class PaymentEntry(AccountsController):
|
||||
self.base_total_allocated_amount = abs(base_total_allocated_amount)
|
||||
|
||||
def set_unallocated_amount(self):
|
||||
self.unallocated_amount = 0;
|
||||
self.unallocated_amount = 0
|
||||
if self.party:
|
||||
party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
|
||||
|
||||
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
|
||||
|
||||
if self.total_allocated_amount < party_amount:
|
||||
if self.payment_type == "Receive":
|
||||
self.unallocated_amount = party_amount - (self.total_allocated_amount - total_deductions)
|
||||
else:
|
||||
self.unallocated_amount = party_amount - (self.total_allocated_amount + total_deductions)
|
||||
if self.payment_type == "Receive" \
|
||||
and self.base_total_allocated_amount < self.base_received_amount + total_deductions \
|
||||
and self.total_allocated_amount < self.paid_amount + (total_deductions / self.source_exchange_rate):
|
||||
self.unallocated_amount = (self.base_received_amount + total_deductions -
|
||||
self.base_total_allocated_amount) / self.source_exchange_rate
|
||||
elif self.payment_type == "Pay" \
|
||||
and self.base_total_allocated_amount < (self.base_paid_amount - total_deductions) \
|
||||
and self.total_allocated_amount < self.received_amount + (total_deductions / self.target_exchange_rate):
|
||||
self.unallocated_amount = (self.base_paid_amount - (total_deductions +
|
||||
self.base_total_allocated_amount)) / self.target_exchange_rate
|
||||
|
||||
def set_difference_amount(self):
|
||||
base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate)
|
||||
@@ -660,6 +672,24 @@ def get_company_defaults(company):
|
||||
return ret
|
||||
|
||||
|
||||
def get_outstanding_on_journal_entry(name):
|
||||
res = frappe.db.sql(
|
||||
'SELECT '
|
||||
'CASE WHEN party_type IN ("Customer", "Student") '
|
||||
'THEN ifnull(sum(debit_in_account_currency - credit_in_account_currency), 0) '
|
||||
'ELSE ifnull(sum(credit_in_account_currency - debit_in_account_currency), 0) '
|
||||
'END as outstanding_amount '
|
||||
'FROM `tabGL Entry` WHERE (voucher_no=%s OR against_voucher=%s) '
|
||||
'AND party_type IS NOT NULL '
|
||||
'AND party_type != ""',
|
||||
(name, name), as_dict=1
|
||||
)
|
||||
|
||||
outstanding_amount = res[0].get('outstanding_amount', 0) if res else 0
|
||||
|
||||
return outstanding_amount
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_reference_details(reference_doctype, reference_name, party_account_currency):
|
||||
total_amount = outstanding_amount = exchange_rate = None
|
||||
@@ -670,6 +700,13 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
||||
total_amount = ref_doc.get("grand_total")
|
||||
exchange_rate = 1
|
||||
outstanding_amount = ref_doc.get("outstanding_amount")
|
||||
elif reference_doctype == "Journal Entry" and ref_doc.docstatus == 1:
|
||||
total_amount = ref_doc.get("total_amount")
|
||||
if ref_doc.multi_currency:
|
||||
exchange_rate = get_exchange_rate(party_account_currency, company_currency, ref_doc.posting_date)
|
||||
else:
|
||||
exchange_rate = 1
|
||||
outstanding_amount = get_outstanding_on_journal_entry(reference_name)
|
||||
elif reference_doctype != "Journal Entry":
|
||||
if party_account_currency == company_currency:
|
||||
if ref_doc.doctype == "Expense Claim":
|
||||
|
||||
@@ -141,7 +141,6 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
def test_payment_entry_retrieves_last_exchange_rate(self):
|
||||
from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records, save_new_records
|
||||
|
||||
test_records = test_records
|
||||
save_new_records(test_records)
|
||||
|
||||
pe = frappe.new_doc("Payment Entry")
|
||||
@@ -151,6 +150,7 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
pe.paid_from = "_Test Bank USD - _TC"
|
||||
pe.paid_to = "_Test Bank - _TC"
|
||||
pe.paid_amount = 100
|
||||
pe.received_amount = 100
|
||||
pe.reference_no = "3"
|
||||
pe.reference_date = "2016-01-10"
|
||||
pe.party_type = "Supplier"
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-07-11 03:28:03.420683",
|
||||
"modified": "2018-02-21 03:28:03.420683",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry Deduction",
|
||||
|
||||
@@ -3,9 +3,26 @@
|
||||
|
||||
frappe.provide("erpnext.accounts");
|
||||
|
||||
frappe.ui.form.on("Payment Reconciliation Payment", {
|
||||
invoice_number: function(frm, cdt, cdn) {
|
||||
var row = locals[cdt][cdn];
|
||||
if(row.invoice_number) {
|
||||
var parts = row.invoice_number.split(' | ');
|
||||
var invoice_type = parts[0];
|
||||
var invoice_number = parts[1];
|
||||
|
||||
var invoice_amount = frm.doc.invoices.filter(function(d) {
|
||||
return d.invoice_type === invoice_type && d.invoice_number === invoice_number;
|
||||
})[0].outstanding_amount;
|
||||
|
||||
frappe.model.set_value(cdt, cdn, "allocated_amount", Math.min(invoice_amount, row.amount));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.extend({
|
||||
onload: function() {
|
||||
var me = this
|
||||
var me = this;
|
||||
this.frm.set_query("party_type", function() {
|
||||
return{
|
||||
query: "erpnext.setup.doctype.party_type.party_type.get_party_type"
|
||||
|
||||
@@ -55,6 +55,7 @@ class PaymentReconciliation(Document):
|
||||
THEN 1=1
|
||||
ELSE {bank_account_condition}
|
||||
END)
|
||||
order by t1.posting_date
|
||||
""".format(**{
|
||||
"dr_or_cr": dr_or_cr,
|
||||
"bank_account_condition": bank_account_condition,
|
||||
|
||||
@@ -61,13 +61,11 @@ class TestPaymentRequest(unittest.TestCase):
|
||||
self.assertEquals(pr.currency, "USD")
|
||||
|
||||
def test_payment_entry(self):
|
||||
frappe.db.set_value("Company", "_Test Company",
|
||||
frappe.db.set_value("Company", "_Test Company",
|
||||
"exchange_gain_loss_account", "_Test Exchange Gain/Loss - _TC")
|
||||
frappe.db.set_value("Company", "_Test Company",
|
||||
"write_off_account", "_Test Write Off - _TC")
|
||||
frappe.db.set_value("Company", "_Test Company",
|
||||
"cost_center", "_Test Cost Center - _TC")
|
||||
|
||||
frappe.db.set_value("Company", "_Test Company", "write_off_account", "_Test Write Off - _TC")
|
||||
frappe.db.set_value("Company", "_Test Company", "cost_center", "_Test Cost Center - _TC")
|
||||
|
||||
so_inr = make_sales_order(currency="INR")
|
||||
pr = make_payment_request(dt="Sales Order", dn=so_inr.name, recipient_id="saurabh@erpnext.com",
|
||||
mute_email=1, submit_doc=1, return_doc=1)
|
||||
@@ -82,15 +80,15 @@ class TestPaymentRequest(unittest.TestCase):
|
||||
|
||||
pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com",
|
||||
mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1, return_doc=1)
|
||||
|
||||
|
||||
pe = pr.set_as_paid()
|
||||
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["_Test Receivable USD - _TC", 0, 5000, si_usd.name],
|
||||
[pr.payment_account, 6290.0, 0, None],
|
||||
["_Test Exchange Gain/Loss - _TC", 0, 1290, None]
|
||||
])
|
||||
|
||||
|
||||
gl_entries = frappe.db.sql("""select account, debit, credit, against_voucher
|
||||
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
|
||||
order by account asc""", pe.name, as_dict=1)
|
||||
|
||||
@@ -32,7 +32,7 @@ class POSProfile(Document):
|
||||
.format(res[0][0], row.user), raise_exception=1)
|
||||
elif not row.default and not res:
|
||||
msgprint(_("User {0} doesn't have any default POS Profile. Check Default at Row {1} for this User.")
|
||||
.format(row.user, row.idx), raise_exception=1)
|
||||
.format(row.user, row.idx))
|
||||
|
||||
def validate_all_link_fields(self):
|
||||
accounts = {"Account": [self.income_account,
|
||||
|
||||
@@ -8,6 +8,10 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
setup: function(doc) {
|
||||
this.setup_posting_date_time_check();
|
||||
this._super(doc);
|
||||
|
||||
// formatter for material request item
|
||||
this.frm.set_indicator_formatter('item_code',
|
||||
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
|
||||
},
|
||||
onload: function() {
|
||||
this._super();
|
||||
@@ -20,10 +24,6 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
} else {
|
||||
this.frm.set_value("disable_rounded_total", cint(frappe.sys_defaults.disable_rounded_total));
|
||||
}
|
||||
|
||||
// formatter for material request item
|
||||
this.frm.set_indicator_formatter('item_code',
|
||||
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
|
||||
},
|
||||
|
||||
refresh: function(doc) {
|
||||
|
||||
@@ -350,7 +350,6 @@ class PurchaseInvoice(BuyingController):
|
||||
self.negative_expense_to_be_booked = 0.0
|
||||
gl_entries = []
|
||||
|
||||
|
||||
self.make_supplier_gl_entry(gl_entries)
|
||||
self.make_item_gl_entries(gl_entries)
|
||||
self.make_tax_gl_entries(gl_entries)
|
||||
@@ -424,7 +423,10 @@ class PurchaseInvoice(BuyingController):
|
||||
|
||||
# sub-contracting warehouse
|
||||
if flt(item.rm_supp_cost):
|
||||
supplier_warehouse_account = warehouse_account[self.supplier_warehouse]["name"]
|
||||
supplier_warehouse_account = warehouse_account[self.supplier_warehouse]["account"]
|
||||
if not supplier_warehouse_account:
|
||||
frappe.throw(_("Please set account in Warehouse {0}")
|
||||
.format(self.supplier_warehouse))
|
||||
gl_entries.append(self.get_gl_dict({
|
||||
"account": supplier_warehouse_account,
|
||||
"against": item.expense_account,
|
||||
|
||||
@@ -106,6 +106,10 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
on_submit: function(doc, dt, dn) {
|
||||
var me = this;
|
||||
|
||||
if (frappe.get_route()[0] != 'Form') {
|
||||
return
|
||||
}
|
||||
|
||||
$.each(doc["items"], function(i, row) {
|
||||
if(row.delivery_note) frappe.model.clear_doc("Delivery Note", row.delivery_note)
|
||||
})
|
||||
|
||||
@@ -639,6 +639,126 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "po_no",
|
||||
"columns": 0,
|
||||
"fieldname": "customer_po_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": "Customer PO 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": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "po_no",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Customer's Purchase Order",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_23",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "po_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Customer's Purchase Order Date",
|
||||
"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,
|
||||
@@ -4563,7 +4683,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-12-20 17:36:05.216046",
|
||||
"modified": "2018-03-13 15:19:54.711885",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
|
||||
@@ -101,6 +101,8 @@ class SalesInvoice(SellingController):
|
||||
self.set_billing_hours_and_amount()
|
||||
self.update_timesheet_billing_for_project()
|
||||
self.set_status()
|
||||
if self.is_pos and not self.is_return:
|
||||
self.verify_payment_amount_is_positive()
|
||||
|
||||
def before_save(self):
|
||||
set_account_for_mode_of_payment(self)
|
||||
@@ -903,6 +905,11 @@ class SalesInvoice(SellingController):
|
||||
project.update_billed_amount()
|
||||
project.save()
|
||||
|
||||
def verify_payment_amount_is_positive(self):
|
||||
for entry in self.payments:
|
||||
if entry.amount < 0:
|
||||
frappe.throw(_("Row #{0} (Payment Table): Amount must be positive").format(entry.idx))
|
||||
|
||||
def get_list_context(context=None):
|
||||
from erpnext.controllers.website_list_for_contact import get_list_context
|
||||
list_context = get_list_context(context)
|
||||
|
||||
@@ -227,6 +227,36 @@
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "clearance_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Clearance Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
@@ -239,7 +269,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-24 17:25:03.765856",
|
||||
"modified": "2018-03-07 18:34:39.552769",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Payment",
|
||||
|
||||
@@ -393,7 +393,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
this.frm = {}
|
||||
this.frm.doc = this.doc
|
||||
this.set_transaction_defaults("Customer");
|
||||
this.frm.doc["allow_user_to_edit_rate"] = this.pos_profile_data["allow_user_to_edit_rate"] ? true : false,
|
||||
this.frm.doc["allow_user_to_edit_rate"] = this.pos_profile_data["allow_user_to_edit_rate"] ? true : false;
|
||||
this.frm.doc["allow_user_to_edit_discount"] = this.pos_profile_data["allow_user_to_edit_discount"] ? true : false;
|
||||
this.wrapper.html(frappe.render_template("pos", this.frm.doc));
|
||||
this.make_search();
|
||||
this.make_customer();
|
||||
@@ -1177,8 +1178,17 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
$(this.wrapper).on("change", ".pos-item-disc", function () {
|
||||
var item_code = $(this).parents(".pos-selected-item-action").attr("data-item-code");
|
||||
var discount = $(this).val();
|
||||
me.update_discount(item_code, discount)
|
||||
me.update_value()
|
||||
if(discount > 100){
|
||||
discount = $(this).val('');
|
||||
frappe.show_alert({
|
||||
indicator: 'red',
|
||||
message: __('Discount amount cannot be greater than 100%')
|
||||
});
|
||||
me.update_discount(item_code, discount);
|
||||
}else{
|
||||
me.update_discount(item_code, discount);
|
||||
me.update_value();
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@@ -1247,6 +1257,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
$(this.wrapper).find('.selected-item').empty();
|
||||
if(this.child_doc.length) {
|
||||
this.child_doc[0]["allow_user_to_edit_rate"] = this.pos_profile_data["allow_user_to_edit_rate"] ? true : false,
|
||||
this.child_doc[0]["allow_user_to_edit_discount"] = this.pos_profile_data["allow_user_to_edit_discount"] ? true : false;
|
||||
this.selected_row = $(frappe.render_template("pos_selected_item", this.child_doc[0]))
|
||||
$(this.wrapper).find('.selected-item').html(this.selected_row)
|
||||
}
|
||||
@@ -1674,7 +1685,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
setInterval(function () {
|
||||
me.freeze_screen = false;
|
||||
me.sync_sales_invoice()
|
||||
}, 60000)
|
||||
}, 180000)
|
||||
},
|
||||
|
||||
sync_sales_invoice: function () {
|
||||
@@ -2006,4 +2017,4 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
frappe.throw(__("LocalStorage is full , did not save"))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -4,12 +4,11 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import datetime
|
||||
from frappe import _, msgprint, scrub
|
||||
from frappe.defaults import get_user_permissions
|
||||
from frappe.model.utils import get_fetch_values
|
||||
from frappe.utils import (add_days, getdate, formatdate, get_first_day, date_diff,
|
||||
add_years, get_timestamp, nowdate, flt, add_months, get_last_day)
|
||||
from frappe.utils import (add_days, getdate, formatdate, date_diff,
|
||||
add_years, get_timestamp, nowdate, flt, add_months, get_last_day)
|
||||
from frappe.contacts.doctype.address.address import (get_address_display,
|
||||
get_default_address, get_company_address)
|
||||
from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
{% if(filters.show_pdc_in_print) { %}
|
||||
<style>
|
||||
@media screen {
|
||||
.print-format {
|
||||
padding: 8mm;
|
||||
margin:4mm;
|
||||
font-size:10px;
|
||||
font-family: Tahoma, sans-serif;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% } %}
|
||||
|
||||
<h2 class="text-center">{%= __(report.report_name) %}</h2>
|
||||
<h4 class="text-center">{%= filters.customer || filters.supplier %} </h4>
|
||||
<h5 class="text-center">
|
||||
@@ -6,17 +19,93 @@
|
||||
{%= dateutil.str_to_user(filters.report_date) %}
|
||||
</h5>
|
||||
<hr>
|
||||
{% if(filters.show_pdc_in_print) { %}
|
||||
{% var balance_row = data.slice(-1).pop();
|
||||
var range1 = report.columns[11].label;
|
||||
var range2 = report.columns[12].label;
|
||||
var range3 = report.columns[13].label;
|
||||
var range4 = report.columns[14].label;
|
||||
%}
|
||||
{% if(balance_row) { %}
|
||||
<table class="table table-bordered table-condensed table-sm small">
|
||||
<caption class="text-right">(Amount in {%= data[0][__("currency")] || "" %})</caption>
|
||||
<colgroup>
|
||||
<col style="width: 30mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
</colgroup>
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{%= __(" ") %}</th>
|
||||
<th>{%= __(range1) %}</th>
|
||||
<th>{%= __(range2) %}</th>
|
||||
<th>{%= __(range3) %}</th>
|
||||
<th>{%= __(range4) %}</th>
|
||||
<th>{%= __("Total") %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{%= __("Total Outstanding") %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row[range1]) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row[range2]) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row[range3]) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row[range4]) %}</td>
|
||||
<td class="text-right">
|
||||
{%= format_currency(flt(balance_row[__("Outstanding Amount")]), data[data.length-1]["currency"]) %}
|
||||
</td>
|
||||
</tr>
|
||||
<td>{%= __("PDC/LC") %}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="text-right">
|
||||
{%= format_currency(flt(balance_row[__("PDC/LC Amount")]), data[data.length-1]["currency"]) %}
|
||||
</td>
|
||||
<tr class="cvs-footer">
|
||||
<th class="text-left">{%= __("Cheques Required") %}</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th class="text-right">
|
||||
{%= format_currency(flt(balance_row[__("Outstanding Amount")]-balance_row[__("PDC/LC Amount")]), data[data.length-1]["currency"]) %}</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
{% } %}
|
||||
{% } %}
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
<th style="width: 14%">{%= __("Date") %}</th>
|
||||
<th style="width: 16%">{%= __("Ref") %}</th>
|
||||
<th style="width: 30%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
<th style="width: 10%">{%= __("Date") %}</th>
|
||||
<th style="width: 15%">{%= __("Ref") %}</th>
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
{% } %}
|
||||
<th style="width: 10%">{%= __("Invoiced Amount") %}</th>
|
||||
<th style="width: 10%">{%= __("Paid Amount") %}</th>
|
||||
<th style="width: 10%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
||||
<th style="width: 10%">{%= __("Outstanding Amount") %}</th>
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<th style="width: 10%">{%= __("Paid Amount") %}</th>
|
||||
<th style="width: 10%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
||||
{% } %}
|
||||
<th style="width: 15%">{%= __("Outstanding Amount") %}</th>
|
||||
{% if(filters.show_pdc_in_print) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
<th style="width: 10%">{%= __("Customer LPO No.") %}</th>
|
||||
{% } %}
|
||||
<th style="width: 10%">{%= __("PDC/LC Date") %}</th>
|
||||
<th style="width: 10%">{%= __("PDC/LC Ref") %}</th>
|
||||
<th style="width: 10%">{%= __("PDC/LC Amount") %}</th>
|
||||
<th style="width: 10%">{%= __("Remaining Balance") %}</th>
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
<th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
<th style="width: 15%">{%= __("Total Invoiced Amount") %}</th>
|
||||
@@ -34,6 +123,7 @@
|
||||
<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
|
||||
<td>{%= data[i][__("Voucher Type")] %}
|
||||
<br>{%= data[i][__("Voucher No")] %}</td>
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
||||
@@ -46,25 +136,56 @@
|
||||
<br>{%= __("Remarks") %}:
|
||||
{%= data[i][__("Remarks")] %}
|
||||
</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Outstanding Amount"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(filters.show_pdc_in_print) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
<td style="text-align: right">
|
||||
{%= data[i][__("Customer LPO")] %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
|
||||
<td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("Remaining Balance")], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
<td></td>
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<td></td>
|
||||
{% } %}
|
||||
<td><b>{%= __("Total") %}</b></td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"] ) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} </td>
|
||||
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} </td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Outstanding Amount"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(filters.show_pdc_in_print) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
<td style="text-align: right">
|
||||
{%= data[i][__("Customer LPO")] %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
|
||||
<td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("Remaining Balance")], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
{% if(data[i][__("Customer")] || data[i][__("Supplier")]|| " ") { %}
|
||||
|
||||
@@ -64,6 +64,11 @@ frappe.query_reports["Accounts Receivable"] = {
|
||||
"fieldtype": "Int",
|
||||
"default": "90",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname":"show_pdc_in_print",
|
||||
"label": __("Show PDC in Print"),
|
||||
"fieldtype": "Check",
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
@@ -72,6 +72,18 @@ class ReceivablePayableReport(object):
|
||||
"options": "Currency",
|
||||
"width": 100
|
||||
})
|
||||
|
||||
columns += [
|
||||
_("PDC/LC Date") + ":Date:110",
|
||||
_("PDC/LC Ref") + ":Data:110",
|
||||
_("PDC/LC Amount") + ":Currency/currency:130",
|
||||
_("Remaining Balance") + ":Currency/currency:130"
|
||||
]
|
||||
|
||||
if args.get('party_type') == 'Customer':
|
||||
columns += [_("Customer LPO") + ":Data:100"]
|
||||
columns += [_("Delivery Note") + ":Data:100"]
|
||||
|
||||
if args.get("party_type") == "Customer":
|
||||
columns += [
|
||||
_("Territory") + ":Link/Territory:80",
|
||||
@@ -89,7 +101,8 @@ class ReceivablePayableReport(object):
|
||||
currency_precision = get_currency_precision() or 2
|
||||
dr_or_cr = "debit" if args.get("party_type") == "Customer" else "credit"
|
||||
|
||||
voucher_details = self.get_voucher_details(args.get("party_type"))
|
||||
dn_details = get_dn_details(args.get("party_type"))
|
||||
voucher_details = self.get_voucher_details(args.get("party_type"), dn_details)
|
||||
|
||||
future_vouchers = self.get_entries_after(self.filters.report_date, args.get("party_type"))
|
||||
|
||||
@@ -101,6 +114,8 @@ class ReceivablePayableReport(object):
|
||||
return_entries = self.get_return_entries(args.get("party_type"))
|
||||
|
||||
data = []
|
||||
pdc_details = get_pdc_details(args.get("party_type"))
|
||||
|
||||
for gle in self.get_entries_till(self.filters.report_date, args.get("party_type")):
|
||||
if self.is_receivable_or_payable(gle, dr_or_cr, future_vouchers):
|
||||
outstanding_amount, credit_note_amount = self.get_outstanding_amount(gle,
|
||||
@@ -144,6 +159,18 @@ class ReceivablePayableReport(object):
|
||||
else:
|
||||
row.append(company_currency)
|
||||
|
||||
pdc = pdc_details.get((gle.voucher_no, gle.party), {})
|
||||
remaining_balance = outstanding_amount - flt(pdc.get("pdc_amount"))
|
||||
row += [pdc.get("pdc_date"), pdc.get("pdc_ref"),
|
||||
flt(pdc.get("pdc_amount")), remaining_balance]
|
||||
|
||||
if args.get('party_type') == 'Customer':
|
||||
# customer LPO
|
||||
row += [voucher_details.get(gle.voucher_no, {}).get("po_no")]
|
||||
|
||||
# Delivery Note
|
||||
row += [voucher_details.get(gle.voucher_no, {}).get("delivery_note")]
|
||||
|
||||
# customer territory / supplier type
|
||||
if args.get("party_type") == "Customer":
|
||||
row += [self.get_territory(gle.party), self.get_customer_group(gle.party)]
|
||||
@@ -225,12 +252,13 @@ class ReceivablePayableReport(object):
|
||||
|
||||
return self.party_map
|
||||
|
||||
def get_voucher_details(self, party_type):
|
||||
def get_voucher_details(self, party_type, dn_details):
|
||||
voucher_details = frappe._dict()
|
||||
|
||||
if party_type == "Customer":
|
||||
for si in frappe.db.sql("""select name, due_date
|
||||
for si in frappe.db.sql("""select name, due_date, po_no
|
||||
from `tabSales Invoice` where docstatus=1""", as_dict=1):
|
||||
si['delivery_note'] = dn_details.get(si.name)
|
||||
voucher_details.setdefault(si.name, si)
|
||||
|
||||
if party_type == "Supplier":
|
||||
@@ -347,3 +375,62 @@ def get_ageing_data(first_range, second_range, third_range, age_as_on, entry_dat
|
||||
outstanding_range[index] = outstanding_amount
|
||||
|
||||
return [age] + outstanding_range
|
||||
|
||||
def get_pdc_details(party_type):
|
||||
pdc_details = frappe._dict()
|
||||
|
||||
for pdc in frappe.db.sql("""
|
||||
select
|
||||
pref.reference_name as invoice_no, pent.party, pent.party_type,
|
||||
max(pent.reference_date) as pdc_date, sum(ifnull(pref.allocated_amount,0)) as pdc_amount,
|
||||
GROUP_CONCAT(pent.reference_no SEPARATOR ', ') as pdc_ref
|
||||
from
|
||||
`tabPayment Entry` as pent inner join `tabPayment Entry Reference` as pref
|
||||
on
|
||||
(pref.parent = pent.name)
|
||||
where
|
||||
pent.docstatus < 2 and pent.reference_date >= pent.posting_date
|
||||
and pent.party_type = %s
|
||||
group by pent.party, pref.reference_name""", party_type, as_dict=1):
|
||||
pdc_details.setdefault((pdc.invoice_no, pdc.party), pdc)
|
||||
|
||||
if scrub(party_type):
|
||||
amount_field = "jea.debit_in_account_currency + jea.credit_in_account_currency"
|
||||
else:
|
||||
amount_field = "jea.debit + jea.credit"
|
||||
|
||||
for pdc in frappe.db.sql("""
|
||||
select
|
||||
jea.reference_name as invoice_no, jea.party, jea.party_type,
|
||||
max(je.cheque_date) as pdc_date, sum(ifnull({0},0)) as pdc_amount,
|
||||
GROUP_CONCAT(je.cheque_no SEPARATOR ', ') as pdc_ref
|
||||
from
|
||||
`tabJournal Entry` as je inner join `tabJournal Entry Account` as jea
|
||||
on
|
||||
(jea.parent = je.name)
|
||||
where
|
||||
je.docstatus < 2 and je.cheque_date >= je.posting_date
|
||||
and jea.party_type = %s
|
||||
group by jea.party, jea.reference_name""".format(amount_field), party_type, as_dict=1):
|
||||
if (pdc.invoice_no, pdc.party) in pdc_details:
|
||||
pdc_details[(pdc.invoice_no, pdc.party)]["pdc_amount"] += pdc.pdc_amount
|
||||
else:
|
||||
pdc_details.setdefault((pdc.invoice_no, pdc.party), pdc)
|
||||
|
||||
return pdc_details
|
||||
|
||||
def get_dn_details(party_type):
|
||||
dn_details = frappe._dict()
|
||||
|
||||
if party_type == "Customer":
|
||||
for si in frappe.db.sql("""select parent, GROUP_CONCAT(delivery_note SEPARATOR ', ') as dn
|
||||
from `tabSales Invoice Item`
|
||||
where docstatus=1 and delivery_note is not null and delivery_note != '' group by parent
|
||||
Union
|
||||
select against_sales_invoice as parent, GROUP_CONCAT(parent SEPARATOR ', ') as dn
|
||||
from `tabDelivery Note Item`
|
||||
where docstatus=1 and against_sales_invoice is not null
|
||||
and against_sales_invoice != '' group by against_sales_invoice""", as_dict=1):
|
||||
dn_details.setdefault(si.parent, si.dn)
|
||||
|
||||
return dn_details
|
||||
|
||||
@@ -28,5 +28,10 @@ frappe.query_reports["Bank Reconciliation Statement"] = {
|
||||
"default": frappe.datetime.get_today(),
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname":"include_pos_transactions",
|
||||
"label": __("Include POS Transactions"),
|
||||
"fieldtype": "Check"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -138,7 +138,23 @@ def get_entries(filters):
|
||||
and ifnull(clearance_date, '4000-01-01') > %(report_date)s
|
||||
""", filters, as_dict=1)
|
||||
|
||||
return sorted(list(payment_entries)+list(journal_entries),
|
||||
pos_entries = []
|
||||
if filters.include_pos_transactions:
|
||||
pos_entries = frappe.db.sql("""
|
||||
select
|
||||
"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit,
|
||||
si.posting_date, si.debit_to as against_account, sip.clearance_date,
|
||||
account.account_currency, 0 as credit
|
||||
from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account
|
||||
where
|
||||
sip.account=%(account)s and si.docstatus=1 and sip.parent = si.name
|
||||
and account.name = sip.account and si.posting_date <= %(report_date)s and
|
||||
ifnull(sip.clearance_date, '4000-01-01') > %(report_date)s
|
||||
order by
|
||||
si.posting_date ASC, si.name DESC
|
||||
""", filters, as_dict=1)
|
||||
|
||||
return sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
|
||||
key=lambda k: k['posting_date'] or getdate(nowdate()))
|
||||
|
||||
def get_amounts_not_reflected_in_system(filters):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.query_reports["Item-wise Sales Register"] = frappe.query_reports["Sales Register"] = {
|
||||
frappe.query_reports["Item-wise Sales Register"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname":"from_date",
|
||||
|
||||
@@ -50,10 +50,12 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
row += [
|
||||
d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])),
|
||||
d.territory, d.project, d.company, d.sales_order,
|
||||
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom,
|
||||
d.base_net_rate, d.base_net_amount
|
||||
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom
|
||||
]
|
||||
|
||||
row += [d.base_net_rate/d.stock_qty, d.base_net_amount] \
|
||||
if d.stock_uom != d.uom else [d.base_net_rate, d.base_net_amount]
|
||||
|
||||
total_tax = 0
|
||||
for tax in tax_columns:
|
||||
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
|
||||
@@ -103,7 +105,7 @@ def get_conditions(filters):
|
||||
|
||||
if filters.get("mode_of_payment"):
|
||||
conditions += """ and exists(select name from `tabSales Invoice Payment`
|
||||
where parent=si.name
|
||||
where parent=`tabSales Invoice`.name
|
||||
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
|
||||
|
||||
return conditions
|
||||
@@ -131,7 +133,7 @@ def get_items(filters, additional_query_columns):
|
||||
`tabSales Invoice Item`.stock_uom, `tabSales Invoice Item`.base_net_rate,
|
||||
`tabSales Invoice Item`.base_net_amount, `tabSales Invoice`.customer_name,
|
||||
`tabSales Invoice`.customer_group, `tabSales Invoice Item`.so_detail,
|
||||
`tabSales Invoice`.update_stock {0}
|
||||
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom {0}
|
||||
from `tabSales Invoice`, `tabSales Invoice Item`
|
||||
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
|
||||
and `tabSales Invoice`.docstatus = 1 %s %s
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"add_total_row": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2013-06-13 18:46:55",
|
||||
"disabled": 0,
|
||||
@@ -7,7 +7,7 @@
|
||||
"doctype": "Report",
|
||||
"idx": 3,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-02-24 20:16:25.027061",
|
||||
"modified": "2018-02-21 01:28:31.261299",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice Trends",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"add_total_row": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2013-06-13 18:44:21",
|
||||
"disabled": 0,
|
||||
@@ -7,7 +7,7 @@
|
||||
"doctype": "Report",
|
||||
"idx": 3,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-02-24 20:15:12.885723",
|
||||
"modified": "2018-02-21 01:28:03.622485",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Trends",
|
||||
|
||||
@@ -33,8 +33,13 @@ frappe.query_reports["Sales Payment Summary"] = {
|
||||
},
|
||||
{
|
||||
"fieldname":"is_pos",
|
||||
"label": __("POS?"),
|
||||
"label": __("Show only POS"),
|
||||
"fieldtype": "Check"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldname":"payment_detail",
|
||||
"label": __("Show Payment Details"),
|
||||
"fieldtype": "Check"
|
||||
},
|
||||
]
|
||||
};
|
||||
@@ -14,25 +14,41 @@ def execute(filters=None):
|
||||
def get_columns():
|
||||
return [
|
||||
_("Date") + ":Date:80",
|
||||
_("Owner") + "::150",
|
||||
_("Payment Mode") + "::140",
|
||||
_("Owner") + ":Data:200",
|
||||
_("Payment Mode") + ":Data:240",
|
||||
_("Sales and Returns") + ":Currency/currency:120",
|
||||
_("Taxes") + ":Currency/currency:120",
|
||||
_("Payments") + ":Currency/currency:120",
|
||||
_("Outstanding Amount") + ":Currency/currency:150",
|
||||
_("Payments") + ":Currency/currency:120"
|
||||
]
|
||||
|
||||
def get_sales_payment_data(filters, columns):
|
||||
sales_invoice_data = get_sales_invoice_data(filters)
|
||||
data = []
|
||||
show_payment_detail = False
|
||||
|
||||
sales_invoice_data = get_sales_invoice_data(filters)
|
||||
mode_of_payments = get_mode_of_payments(filters)
|
||||
mode_of_payment_details = get_mode_of_payment_details(filters)
|
||||
|
||||
if filters.get("payment_detail"):
|
||||
show_payment_detail = True
|
||||
else:
|
||||
show_payment_detail = False
|
||||
|
||||
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)
|
||||
owner_posting_date = inv["owner"]+cstr(inv["posting_date"])
|
||||
if show_payment_detail:
|
||||
row = [inv.posting_date, inv.owner," ",inv.net_total,inv.total_taxes, 0]
|
||||
data.append(row)
|
||||
for mop_detail in mode_of_payment_details.get(owner_posting_date,[]):
|
||||
row = [inv.posting_date, inv.owner,mop_detail[0],0,0,mop_detail[1],0]
|
||||
data.append(row)
|
||||
else:
|
||||
total_payment = 0
|
||||
for mop_detail in mode_of_payment_details.get(owner_posting_date,[]):
|
||||
total_payment = total_payment + mop_detail[1]
|
||||
row = [inv.posting_date, inv.owner,", ".join(mode_of_payments.get(owner_posting_date, [])),
|
||||
inv.net_total,inv.total_taxes,total_payment]
|
||||
data.append(row)
|
||||
return data
|
||||
|
||||
def get_conditions(filters):
|
||||
@@ -73,9 +89,17 @@ def get_mode_of_payments(filters):
|
||||
union
|
||||
select a.owner,a.posting_date, ifnull(b.mode_of_payment, '') as mode_of_payment
|
||||
from `tabSales Invoice` a, `tabPayment Entry` b,`tabPayment Entry Reference` c
|
||||
where a.name = c.reference_name
|
||||
where a.name = c.reference_name
|
||||
and b.name = c.parent
|
||||
and a.name in ({invoice_list_names})
|
||||
union
|
||||
select a.owner, a.posting_date,
|
||||
ifnull(a.voucher_type,'') as mode_of_payment
|
||||
from `tabJournal Entry` a, `tabJournal Entry Account` b
|
||||
where a.name = b.parent
|
||||
and a.docstatus = 1
|
||||
and b.reference_type = "Sales Invoice"
|
||||
and b.reference_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)
|
||||
@@ -86,4 +110,37 @@ def get_invoices(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)
|
||||
filters, as_dict=1)
|
||||
|
||||
def get_mode_of_payment_details(filters):
|
||||
mode_of_payment_details = {}
|
||||
invoice_list = get_invoices(filters)
|
||||
invoice_list_names = ",".join(['"' + invoice['name'] + '"' for invoice in invoice_list])
|
||||
if invoice_list:
|
||||
inv_mop_detail = frappe.db.sql("""select a.owner, a.posting_date,
|
||||
ifnull(b.mode_of_payment, '') as mode_of_payment, sum(b.base_amount) as paid_amount
|
||||
from `tabSales Invoice` a, `tabSales Invoice Payment` b
|
||||
where a.name = b.parent
|
||||
and a.name in ({invoice_list_names})
|
||||
group by a.owner, a.posting_date, mode_of_payment
|
||||
union
|
||||
select a.owner,a.posting_date,
|
||||
ifnull(b.mode_of_payment, '') as mode_of_payment, sum(b.base_paid_amount) as paid_amount
|
||||
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})
|
||||
group by a.owner, a.posting_date, mode_of_payment
|
||||
union
|
||||
select a.owner, a.posting_date,
|
||||
ifnull(a.voucher_type,'') as mode_of_payment, sum(b.credit)
|
||||
from `tabJournal Entry` a, `tabJournal Entry Account` b
|
||||
where a.name = b.parent
|
||||
and a.docstatus = 1
|
||||
and b.reference_type = "Sales Invoice"
|
||||
and b.reference_name in ({invoice_list_names})
|
||||
group by a.owner, a.posting_date, mode_of_payment
|
||||
""".format(invoice_list_names=invoice_list_names), as_dict=1)
|
||||
for d in inv_mop_detail:
|
||||
mode_of_payment_details.setdefault(d["owner"]+cstr(d["posting_date"]), []).append((d.mode_of_payment,d.paid_amount))
|
||||
return mode_of_payment_details
|
||||
@@ -5,6 +5,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe import _
|
||||
|
||||
class Crop(Document):
|
||||
def validate(self):
|
||||
@@ -12,7 +13,7 @@ class Crop(Document):
|
||||
for task in self.agriculture_task:
|
||||
# validate start_day is not > end_day
|
||||
if task.start_day > task.end_day:
|
||||
frappe.throw("Start day is greater than end day in task '{0}'".format(task.subject))
|
||||
frappe.throw(_("Start day is greater than end day in task '{0}'").format(task.task_name))
|
||||
# to calculate the period of the Crop Cycle
|
||||
if task.end_day > max_period: max_period = task.end_day
|
||||
if max_period > self.period: self.period = max_period
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe import _
|
||||
|
||||
class Disease(Document):
|
||||
def validate(self):
|
||||
@@ -12,7 +13,7 @@ class Disease(Document):
|
||||
for task in self.treatment_task:
|
||||
# validate start_day is not > end_day
|
||||
if task.start_day > task.end_day:
|
||||
frappe.throw("Start day is greater than end day in task '{0}'".format(task.task_name))
|
||||
frappe.throw(_("Start day is greater than end day in task '{0}'").format(task.task_name))
|
||||
# to calculate the period of the Crop Cycle
|
||||
if task.end_day > max_period: max_period = task.end_day
|
||||
self.treatment_period = max_period
|
||||
@@ -6,6 +6,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import flt, cint
|
||||
from frappe import _
|
||||
|
||||
class SoilTexture(Document):
|
||||
soil_edit_order = [2, 1, 0]
|
||||
@@ -20,9 +21,9 @@ class SoilTexture(Document):
|
||||
self.update_soil_edit('sand_composition')
|
||||
for soil_type in self.soil_types:
|
||||
if self.get(soil_type) > 100 or self.get(soil_type) < 0:
|
||||
frappe.throw("{0} should be a value between 0 and 100".format(soil_type))
|
||||
frappe.throw(_("{0} should be a value between 0 and 100").format(soil_type))
|
||||
if sum(self.get(soil_type) for soil_type in self.soil_types) != 100:
|
||||
frappe.throw('Soil compositions do not add up to 100')
|
||||
frappe.throw(_('Soil compositions do not add up to 100'))
|
||||
|
||||
def update_soil_edit(self, soil_type):
|
||||
self.soil_edit_order[self.soil_types.index(soil_type)] = max(self.soil_edit_order)+1
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe import _
|
||||
|
||||
class WaterAnalysis(Document):
|
||||
def load_contents(self):
|
||||
@@ -18,6 +19,6 @@ class WaterAnalysis(Document):
|
||||
|
||||
def validate(self):
|
||||
if self.collection_datetime > self.laboratory_testing_datetime:
|
||||
frappe.throw('Lab testing datetime cannot be before collection datetime')
|
||||
frappe.throw(_('Lab testing datetime cannot be before collection datetime'))
|
||||
if self.laboratory_testing_datetime > self.result_datetime:
|
||||
frappe.throw('Lab result datetime cannot be before testing datetime')
|
||||
frappe.throw(_('Lab result datetime cannot be before testing datetime'))
|
||||
@@ -12,6 +12,18 @@ frappe.ui.form.on("Purchase Order", {
|
||||
'Purchase Invoice': 'Invoice',
|
||||
'Stock Entry': 'Material to Supplier'
|
||||
}
|
||||
|
||||
frm.set_indicator_formatter('item_code',
|
||||
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
|
||||
|
||||
frm.set_query("reserve_warehouse", "supplied_items", function() {
|
||||
return {
|
||||
filters: {
|
||||
"company": frm.doc.company,
|
||||
"is_group": 0
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
@@ -25,9 +37,6 @@ frappe.ui.form.on("Purchase Order", {
|
||||
frm.toggle_display('get_last_purchase_rate',
|
||||
frm.doc.__onload.disable_fetch_last_purchase_rate);
|
||||
}
|
||||
|
||||
frm.set_indicator_formatter('item_code',
|
||||
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
|
||||
},
|
||||
});
|
||||
|
||||
@@ -134,23 +143,124 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
||||
var items = $.map(cur_frm.doc.items, function(d) { return d.bom ? d.item_code : false; });
|
||||
var me = this;
|
||||
|
||||
if(items.length===1) {
|
||||
me._make_stock_entry(items[0]);
|
||||
return;
|
||||
if(items.length >= 1){
|
||||
me.raw_material_data = [];
|
||||
me.show_dialog = 1;
|
||||
let title = "";
|
||||
let fields = [
|
||||
{fieldtype:'Section Break', label: __('Raw Materials')},
|
||||
{fieldname: 'sub_con_rm_items', fieldtype: 'Table',
|
||||
fields: [
|
||||
{
|
||||
fieldtype:'Data',
|
||||
fieldname:'item_code',
|
||||
label: __('Item'),
|
||||
read_only:1,
|
||||
in_list_view:1
|
||||
},
|
||||
{
|
||||
fieldtype:'Data',
|
||||
fieldname:'rm_item_code',
|
||||
label: __('Raw Material'),
|
||||
read_only:1,
|
||||
in_list_view:1
|
||||
},
|
||||
{
|
||||
fieldtype:'Float',
|
||||
read_only:1,
|
||||
fieldname:'qty',
|
||||
label: __('Quantity'),
|
||||
read_only:1,
|
||||
in_list_view:1
|
||||
},
|
||||
{
|
||||
fieldtype:'Data',
|
||||
read_only:1,
|
||||
fieldname:'warehouse',
|
||||
label: __('Reserve Warehouse'),
|
||||
in_list_view:1
|
||||
},
|
||||
{
|
||||
fieldtype:'Float',
|
||||
read_only:1,
|
||||
fieldname:'rate',
|
||||
label: __('Rate'),
|
||||
hidden:1
|
||||
},
|
||||
{
|
||||
fieldtype:'Float',
|
||||
read_only:1,
|
||||
fieldname:'amount',
|
||||
label: __('Amount'),
|
||||
hidden:1
|
||||
},
|
||||
{
|
||||
fieldtype:'Link',
|
||||
read_only:1,
|
||||
fieldname:'uom',
|
||||
label: __('UOM'),
|
||||
hidden:1
|
||||
}
|
||||
],
|
||||
data: me.raw_material_data,
|
||||
get_data: function() {
|
||||
return me.raw_material_data;
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
me.dialog = new frappe.ui.Dialog({
|
||||
title: title, fields: fields
|
||||
});
|
||||
|
||||
if (me.frm.doc['supplied_items']) {
|
||||
me.frm.doc['supplied_items'].forEach((item, index) => {
|
||||
if (item.rm_item_code && item.main_item_code) {
|
||||
me.raw_material_data.push ({
|
||||
'name':index,
|
||||
'item_code': item.main_item_code,
|
||||
'rm_item_code': item.rm_item_code,
|
||||
'item_name': item.rm_item_code,
|
||||
'qty': item.required_qty,
|
||||
'warehouse':item.reserve_warehouse,
|
||||
'rate':item.rate,
|
||||
'amount':item.amount,
|
||||
'stock_uom':item.stock_uom
|
||||
});
|
||||
me.dialog.fields_dict.sub_con_rm_items.grid.refresh();
|
||||
}
|
||||
})
|
||||
}
|
||||
frappe.prompt({fieldname:"item", options: items, fieldtype:"Select",
|
||||
label: __("Select Item for Transfer"), reqd: 1}, function(data) {
|
||||
me._make_stock_entry(data.item);
|
||||
}, __("Select Item"), __("Make"));
|
||||
|
||||
me.dialog.show()
|
||||
this.dialog.set_primary_action(__('Transfer'), function() {
|
||||
me.values = me.dialog.get_values();
|
||||
if(me.values) {
|
||||
me.values.sub_con_rm_items.map((row,i) => {
|
||||
if (!row.item_code || !row.rm_item_code || !row.warehouse || !row.qty || row.qty === 0) {
|
||||
frappe.throw(__("Item Code, warehouse, quantity are required on row" + (i+1)));
|
||||
}
|
||||
})
|
||||
me._make_rm_stock_entry(me.dialog.fields_dict.sub_con_rm_items.grid.get_selected_children())
|
||||
me.dialog.hide()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
me.dialog.get_close_btn().on('click', () => {
|
||||
me.dialog.hide();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
_make_stock_entry: function(item) {
|
||||
_make_rm_stock_entry: function(rm_items) {
|
||||
frappe.call({
|
||||
method:"erpnext.buying.doctype.purchase_order.purchase_order.make_stock_entry",
|
||||
method:"erpnext.buying.doctype.purchase_order.purchase_order.make_rm_stock_entry",
|
||||
args: {
|
||||
purchase_order: cur_frm.doc.name,
|
||||
item_code: item
|
||||
},
|
||||
rm_items: rm_items
|
||||
}
|
||||
,
|
||||
callback: function(r) {
|
||||
var doclist = frappe.model.sync(r.message);
|
||||
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
||||
@@ -284,7 +394,8 @@ cur_frm.fields_dict['items'].grid.get_field('bom').get_query = function(doc, cdt
|
||||
filters: [
|
||||
['BOM', 'item', '=', d.item_code],
|
||||
['BOM', 'is_active', '=', '1'],
|
||||
['BOM', 'docstatus', '=', '1']
|
||||
['BOM', 'docstatus', '=', '1'],
|
||||
['BOM', 'company', '=', doc.company]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "{supplier_name}",
|
||||
@@ -292,40 +292,40 @@
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "",
|
||||
"fieldname": "schedule_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reqd By Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "",
|
||||
"fieldname": "schedule_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reqd By Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -3101,7 +3101,70 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": "supplied_items",
|
||||
"columns": 0,
|
||||
"fieldname": "raw_material_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": "Raw Materials Supplied",
|
||||
"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": "eval:doc.is_subcontracted",
|
||||
"fieldname": "supplied_items_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Supplied Items",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "supplied_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@@ -3291,9 +3354,9 @@
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-21 14:45:34.140128",
|
||||
"modified_by": "Administrator",
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-17 11:00:05.037716",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
"owner": "Administrator",
|
||||
|
||||
@@ -12,7 +12,7 @@ from erpnext.stock.doctype.item.item import get_last_purchase_details
|
||||
from erpnext.stock.stock_balance import update_bin_qty, get_ordered_qty
|
||||
from frappe.desk.notifications import clear_doctype_notifications
|
||||
from erpnext.buying.utils import validate_for_items, check_for_closed_status
|
||||
|
||||
from erpnext.stock.utils import get_bin
|
||||
|
||||
form_grid_templates = {
|
||||
"items": "templates/form_grid/item_grid.html"
|
||||
@@ -30,8 +30,7 @@ class PurchaseOrder(BuyingController):
|
||||
'target_parent_field': 'per_ordered',
|
||||
'target_ref_field': 'stock_qty',
|
||||
'source_field': 'stock_qty',
|
||||
'percent_join_field': 'material_request',
|
||||
'overflow_type': 'order'
|
||||
'percent_join_field': 'material_request'
|
||||
}]
|
||||
|
||||
def onload(self):
|
||||
@@ -81,8 +80,10 @@ class PurchaseOrder(BuyingController):
|
||||
def validate_supplier(self):
|
||||
prevent_po = frappe.db.get_value("Supplier", self.supplier, 'prevent_pos')
|
||||
if prevent_po:
|
||||
standing = frappe.db.get_value("Supplier Scorecard",self.supplier, 'status')
|
||||
frappe.throw(_("Purchase Orders are not allowed for {0} due to a scorecard standing of {1}.").format(self.supplier, standing))
|
||||
standing = frappe.db.get_value("Supplier Scorecard", self.supplier, 'status')
|
||||
if standing:
|
||||
frappe.throw(_("Purchase Orders are not allowed for {0} due to a scorecard standing of {1}.")
|
||||
.format(self.supplier, standing))
|
||||
|
||||
warn_po = frappe.db.get_value("Supplier", self.supplier, 'warn_pos')
|
||||
if warn_po:
|
||||
@@ -193,6 +194,9 @@ class PurchaseOrder(BuyingController):
|
||||
self.set_status(update=True, status=status)
|
||||
self.update_requested_qty()
|
||||
self.update_ordered_qty()
|
||||
if self.is_subcontracted == "Yes":
|
||||
self.update_reserved_qty_for_subcontract()
|
||||
|
||||
self.notify_update()
|
||||
clear_doctype_notifications(self)
|
||||
|
||||
@@ -205,6 +209,8 @@ class PurchaseOrder(BuyingController):
|
||||
self.update_prevdoc_status()
|
||||
self.update_requested_qty()
|
||||
self.update_ordered_qty()
|
||||
if self.is_subcontracted == "Yes":
|
||||
self.update_reserved_qty_for_subcontract()
|
||||
|
||||
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
|
||||
self.company, self.base_grand_total)
|
||||
@@ -218,6 +224,9 @@ class PurchaseOrder(BuyingController):
|
||||
if self.has_drop_ship_item():
|
||||
self.update_delivered_qty_in_sales_order()
|
||||
|
||||
if self.is_subcontracted == "Yes":
|
||||
self.update_reserved_qty_for_subcontract()
|
||||
|
||||
self.check_for_closed_status()
|
||||
|
||||
frappe.db.set(self,'status','Cancelled')
|
||||
@@ -232,12 +241,16 @@ class PurchaseOrder(BuyingController):
|
||||
pass
|
||||
|
||||
def update_status_updater(self):
|
||||
self.status_updater[0].update({
|
||||
"target_parent_dt": "Sales Order",
|
||||
"target_dt": "Sales Order Item",
|
||||
self.status_updater.append({
|
||||
'source_dt': 'Purchase Order Item',
|
||||
'target_dt': 'Sales Order Item',
|
||||
'target_field': 'ordered_qty',
|
||||
"join_field": "sales_order_item",
|
||||
"target_parent_field": ''
|
||||
'target_parent_dt': 'Sales Order',
|
||||
'target_parent_field': '',
|
||||
'join_field': 'sales_order_item',
|
||||
'source_dt': 'Purchase Order Item',
|
||||
'target_ref_field': 'stock_qty',
|
||||
'source_field': 'stock_qty'
|
||||
})
|
||||
|
||||
def update_delivered_qty_in_sales_order(self):
|
||||
@@ -265,6 +278,12 @@ class PurchaseOrder(BuyingController):
|
||||
if item.delivered_by_supplier == 1:
|
||||
item.received_qty = item.qty
|
||||
|
||||
def update_reserved_qty_for_subcontract(self):
|
||||
for d in self.supplied_items:
|
||||
if d.rm_item_code:
|
||||
stock_bin = get_bin(d.rm_item_code, d.reserve_warehouse)
|
||||
stock_bin.update_reserved_qty_for_sub_contracting()
|
||||
|
||||
def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor= 1.0):
|
||||
"""get last purchase rate for an item"""
|
||||
if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
|
||||
@@ -385,23 +404,52 @@ def make_purchase_invoice(source_name, target_doc=None):
|
||||
return doc
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_stock_entry(purchase_order, item_code):
|
||||
purchase_order = frappe.get_doc("Purchase Order", purchase_order)
|
||||
def make_rm_stock_entry(purchase_order, rm_items):
|
||||
if isinstance(rm_items, basestring):
|
||||
rm_items_list = json.loads(rm_items)
|
||||
else:
|
||||
frappe.throw(_("No Items available for transfer"))
|
||||
|
||||
stock_entry = frappe.new_doc("Stock Entry")
|
||||
stock_entry.purpose = "Subcontract"
|
||||
stock_entry.purchase_order = purchase_order.name
|
||||
stock_entry.supplier = purchase_order.supplier
|
||||
stock_entry.supplier_name = purchase_order.supplier_name
|
||||
stock_entry.supplier_address = purchase_order.supplier_address
|
||||
stock_entry.address_display = purchase_order.address_display
|
||||
stock_entry.company = purchase_order.company
|
||||
stock_entry.from_bom = 1
|
||||
po_item = [d for d in purchase_order.items if d.item_code == item_code][0]
|
||||
stock_entry.fg_completed_qty = po_item.qty
|
||||
stock_entry.bom_no = po_item.bom
|
||||
stock_entry.get_items()
|
||||
return stock_entry.as_dict()
|
||||
if rm_items_list:
|
||||
fg_items = list(set(d["item_code"] for d in rm_items_list))
|
||||
else:
|
||||
frappe.throw(_("No Items selected for transfer"))
|
||||
|
||||
if purchase_order:
|
||||
purchase_order = frappe.get_doc("Purchase Order", purchase_order)
|
||||
|
||||
if fg_items:
|
||||
items = tuple(set(d["rm_item_code"] for d in rm_items_list))
|
||||
item_wh = frappe._dict(frappe.db.sql("""
|
||||
select item_code, description
|
||||
from `tabItem` where name in ({0})
|
||||
""".format(", ".join(["%s"] * len(items))), items))
|
||||
|
||||
stock_entry = frappe.new_doc("Stock Entry")
|
||||
stock_entry.purpose = "Subcontract"
|
||||
stock_entry.purchase_order = purchase_order.name
|
||||
stock_entry.supplier = purchase_order.supplier
|
||||
stock_entry.supplier_name = purchase_order.supplier_name
|
||||
stock_entry.supplier_address = purchase_order.supplier_address
|
||||
stock_entry.address_display = purchase_order.address_display
|
||||
stock_entry.company = purchase_order.company
|
||||
for item_code in fg_items:
|
||||
for rm_item_data in rm_items_list:
|
||||
if rm_item_data["item_code"] == item_code:
|
||||
items_dict = {
|
||||
rm_item_data["rm_item_code"]: {
|
||||
"item_name":rm_item_data["item_name"],
|
||||
"description":item_wh.get(rm_item_data["rm_item_code"]),
|
||||
'qty':rm_item_data["qty"],
|
||||
'from_warehouse':rm_item_data["warehouse"],
|
||||
'stock_uom':rm_item_data["stock_uom"]
|
||||
}
|
||||
}
|
||||
stock_entry.add_to_stock_entry_detail(items_dict)
|
||||
return stock_entry.as_dict()
|
||||
else:
|
||||
frappe.throw(_("No Items selected for transfer"))
|
||||
return purchase_order.name
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_status(status, name):
|
||||
|
||||
@@ -6,8 +6,9 @@ import unittest
|
||||
import frappe
|
||||
import frappe.defaults
|
||||
from frappe.utils import flt, add_days, nowdate
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt, make_purchase_invoice
|
||||
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import (make_purchase_receipt, make_purchase_invoice, make_rm_stock_entry as make_subcontract_transfer_entry)
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
import json
|
||||
|
||||
class TestPurchaseOrder(unittest.TestCase):
|
||||
def test_make_purchase_receipt(self):
|
||||
@@ -182,24 +183,129 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
pi.insert()
|
||||
self.assertTrue(pi.get('payment_schedule'))
|
||||
|
||||
|
||||
def test_reserved_qty_subcontract_po(self):
|
||||
# Make stock available for raw materials
|
||||
make_stock_entry(target="_Test Warehouse - _TC", qty=10, basic_rate=100)
|
||||
make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item Home Desktop 100",
|
||||
qty=20, basic_rate=100)
|
||||
|
||||
bin1 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
fieldname=["reserved_qty_for_sub_contract", "projected_qty"], as_dict=1)
|
||||
|
||||
# Submit PO
|
||||
po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
|
||||
|
||||
bin2 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
fieldname=["reserved_qty_for_sub_contract", "projected_qty"], as_dict=1)
|
||||
self.assertEquals(bin2.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10)
|
||||
self.assertEquals(bin2.projected_qty, bin1.projected_qty - 10)
|
||||
|
||||
# Create stock transfer
|
||||
rm_item = [{"item_code":"_Test FG Item","rm_item_code":"_Test Item","item_name":"_Test Item",
|
||||
"qty":6,"warehouse":"_Test Warehouse - _TC","rate":100,"amount":600,"stock_uom":"Nos"}]
|
||||
rm_item_string = json.dumps(rm_item)
|
||||
se = frappe.get_doc(make_subcontract_transfer_entry(po.name, rm_item_string))
|
||||
se.to_warehouse = "_Test Warehouse 1 - _TC"
|
||||
se.save()
|
||||
se.submit()
|
||||
|
||||
bin3 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||
|
||||
self.assertEquals(bin3.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
||||
|
||||
# close PO
|
||||
po.update_status("Closed")
|
||||
bin4 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||
|
||||
self.assertEquals(bin4.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
||||
|
||||
# Re-open PO
|
||||
po.update_status("Submitted")
|
||||
bin5 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||
|
||||
self.assertEquals(bin5.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
||||
|
||||
# make Purchase Receipt against PO
|
||||
pr = make_purchase_receipt(po.name)
|
||||
pr.supplier_warehouse = "_Test Warehouse 1 - _TC"
|
||||
pr.save()
|
||||
pr.submit()
|
||||
|
||||
bin6 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||
|
||||
self.assertEquals(bin6.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
||||
|
||||
# Cancel PR
|
||||
pr.cancel()
|
||||
bin7 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||
|
||||
self.assertEquals(bin7.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
||||
|
||||
# Make Purchase Invoice
|
||||
pi = make_purchase_invoice(po.name)
|
||||
pi.update_stock = 1
|
||||
pi.supplier_warehouse = "_Test Warehouse 1 - _TC"
|
||||
pi.insert()
|
||||
pi.submit()
|
||||
bin8 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||
|
||||
self.assertEquals(bin8.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
||||
|
||||
# Cancel PR
|
||||
pi.cancel()
|
||||
bin9 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||
|
||||
self.assertEquals(bin9.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
||||
|
||||
# Cancel Stock Entry
|
||||
se.cancel()
|
||||
bin10 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||
self.assertEquals(bin10.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10)
|
||||
|
||||
# Cancel PO
|
||||
po.reload()
|
||||
po.cancel()
|
||||
bin11 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||
|
||||
self.assertEquals(bin11.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
||||
|
||||
def get_same_items():
|
||||
return [
|
||||
{
|
||||
"item_code": "_Test FG Item",
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"qty": 1,
|
||||
"rate": 500,
|
||||
"schedule_date": add_days(nowdate(), 1)
|
||||
},
|
||||
{
|
||||
"item_code": "_Test FG Item",
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"qty": 4,
|
||||
"rate": 500,
|
||||
"schedule_date": add_days(nowdate(), 1)
|
||||
}
|
||||
]
|
||||
{
|
||||
"item_code": "_Test FG Item",
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"qty": 1,
|
||||
"rate": 500,
|
||||
"schedule_date": add_days(nowdate(), 1)
|
||||
},
|
||||
{
|
||||
"item_code": "_Test FG Item",
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"qty": 4,
|
||||
"rate": 500,
|
||||
"schedule_date": add_days(nowdate(), 1)
|
||||
}
|
||||
]
|
||||
|
||||
def create_purchase_order(**args):
|
||||
po = frappe.new_doc("Purchase Order")
|
||||
@@ -224,6 +330,10 @@ def create_purchase_order(**args):
|
||||
if not args.do_not_save:
|
||||
po.insert()
|
||||
if not args.do_not_submit:
|
||||
if po.is_subcontracted == "Yes":
|
||||
supp_items = po.get("supplied_items")
|
||||
for d in supp_items:
|
||||
d.reserve_warehouse = args.warehouse or "_Test Warehouse - _TC"
|
||||
po.submit()
|
||||
|
||||
return po
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
@@ -10,68 +11,86 @@
|
||||
"editable_grid": 1,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "main_item_code",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Item Code",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "main_item_code",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "rm_item_code",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Raw Material Item Code",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "rm_item_code",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "required_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Supplied Qty",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -81,23 +100,29 @@
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "rate",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rate",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -108,23 +133,29 @@
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -135,23 +166,59 @@
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_6",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "bom_detail_no",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "BOM Detail No",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -161,23 +228,29 @@
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reference_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reference Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -187,23 +260,29 @@
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "conversion_factor",
|
||||
"fieldtype": "Float",
|
||||
"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": "Conversion Factor",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -213,23 +292,29 @@
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Stock Uom",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -240,24 +325,58 @@
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "reserve_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reserve Warehouse",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 1,
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-07-11 03:28:05.533063",
|
||||
"modified": "2018-03-13 12:37:57.150914",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Item Supplied",
|
||||
@@ -266,5 +385,7 @@
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
@@ -11,12 +12,13 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "main_item_code",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@@ -29,6 +31,7 @@
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "main_item_code",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
@@ -38,15 +41,17 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rm_item_code",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@@ -59,6 +64,7 @@
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "rm_item_code",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
@@ -68,9 +74,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -99,10 +107,12 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "300px"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -129,9 +139,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -157,9 +169,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -184,9 +198,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -214,9 +230,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -244,9 +262,11 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -275,9 +295,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -306,9 +328,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -337,9 +361,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -367,9 +393,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -397,9 +425,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -427,9 +457,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -457,20 +489,21 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"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": "2017-02-17 16:43:21.668443",
|
||||
"modified": "2018-03-13 12:38:40.807453",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Receipt Item Supplied",
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
/* global frappe, refresh_field */
|
||||
|
||||
frappe.ui.form.on("Supplier Scorecard", {
|
||||
|
||||
onload: function(frm) {
|
||||
|
||||
setup: function(frm) {
|
||||
if (frm.doc.indicator_color !== "") {
|
||||
frm.set_indicator_formatter("status", function(doc) {
|
||||
return doc.indicator_color.toLowerCase();
|
||||
});
|
||||
}
|
||||
},
|
||||
onload: function(frm) {
|
||||
if (frm.doc.__unsaved == 1) {
|
||||
loadAllCriteria(frm);
|
||||
loadAllStandings(frm);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"add_total_row": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2013-06-13 18:45:01",
|
||||
"disabled": 0,
|
||||
@@ -7,7 +7,7 @@
|
||||
"doctype": "Report",
|
||||
"idx": 3,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-02-24 20:16:13.121638",
|
||||
"modified": "2018-02-21 01:28:37.416562",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Trends",
|
||||
|
||||
@@ -126,6 +126,11 @@ def get_data():
|
||||
"link": "Tree/Sales Person",
|
||||
"description": _("Manage Sales Person Tree."),
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Lead Source",
|
||||
"description": _("Track Leads by Lead Source.")
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -200,7 +200,7 @@ def get_data():
|
||||
"color": "#fd784f",
|
||||
"icon": "octicon octicon-calendar",
|
||||
"label": _("Course Schedule"),
|
||||
"link": "Calendar/Course Schedule",
|
||||
"link": "List/Course Schedule/Calendar",
|
||||
"_doctype": "Course Schedule",
|
||||
"type": "list",
|
||||
"hidden": 1
|
||||
|
||||
@@ -21,18 +21,7 @@ def get_data():
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Student Group"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Student Group Creation Tool"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Student and Guardian Contact Details",
|
||||
"doctype": "Program Enrollment"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -50,10 +39,6 @@ def get_data():
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Program Enrollment"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Program Enrollment Tool"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -68,10 +53,6 @@ def get_data():
|
||||
"type": "doctype",
|
||||
"name": "Student Leave Application"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Student Attendance Tool"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
@@ -84,21 +65,26 @@ def get_data():
|
||||
"name": "Student Batch-Wise Attendance",
|
||||
"doctype": "Student Attendance"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Student Monthly Attendance Sheet",
|
||||
"doctype": "Student Attendance"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Schedule"),
|
||||
"label": _("Tools"),
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Course Schedule",
|
||||
"route": "List/Course Schedule/Calendar"
|
||||
"name": "Student Attendance Tool"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Assessment Result Tool"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Student Group Creation Tool"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Program Enrollment Tool"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
@@ -125,28 +111,30 @@ def get_data():
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Assessment Criteria"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Assessment Criteria Group"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Assessment Result Tool"
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Assessment Reports"),
|
||||
"items": [
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Course wise Assessment Report",
|
||||
"doctype": "Assessment Result"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Final Assessment Grades",
|
||||
"doctype": "Assessment Result"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Assessment Plan Status",
|
||||
"doctype": "Assessment Plan"
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -167,17 +155,25 @@ def get_data():
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Fee Category"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"name": "Student Fee Collection",
|
||||
"doctype": "Fees",
|
||||
"is_query_report": True
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Setup"),
|
||||
"label": _("Schedule"),
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Course Schedule",
|
||||
"route": "List/Course Schedule/Calendar"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Course Scheduling Tool"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Masters"),
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
@@ -194,7 +190,12 @@ def get_data():
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Room"
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Setup"),
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Student Category"
|
||||
@@ -221,4 +222,27 @@ def get_data():
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Other Reports"),
|
||||
"items": [
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Student and Guardian Contact Details",
|
||||
"doctype": "Program Enrollment"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Student Monthly Attendance Sheet",
|
||||
"doctype": "Student Attendance"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"name": "Student Fee Collection",
|
||||
"doctype": "Fees",
|
||||
"is_query_report": True
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -173,6 +173,11 @@ def get_data():
|
||||
"name": "Industry Type",
|
||||
"description": _("Track Leads by Industry Type.")
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Lead Source",
|
||||
"description": _("Track Leads by Lead Source.")
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -666,6 +666,8 @@ class AccountsController(TransactionBase):
|
||||
self.remove(item)
|
||||
|
||||
def set_payment_schedule(self):
|
||||
if self.doctype == 'Sales Invoice' and self.is_pos: return
|
||||
|
||||
posting_date = self.get("bill_date") or self.get("posting_date") or self.get("transaction_date")
|
||||
date = self.get("due_date")
|
||||
due_date = date or posting_date
|
||||
@@ -695,6 +697,8 @@ class AccountsController(TransactionBase):
|
||||
dates = []
|
||||
li = []
|
||||
|
||||
if self.doctype == 'Sales Invoice' and self.is_pos: return
|
||||
|
||||
for d in self.get("payment_schedule"):
|
||||
if self.doctype == "Sales Order" and getdate(d.due_date) < getdate(self.transaction_date):
|
||||
frappe.throw(_("Row {0}: Due Date cannot be before posting date").format(d.idx))
|
||||
@@ -708,6 +712,8 @@ class AccountsController(TransactionBase):
|
||||
.format(list=duplicates))
|
||||
|
||||
def validate_payment_schedule_amount(self):
|
||||
if self.doctype == 'Sales Invoice' and self.is_pos: return
|
||||
|
||||
if self.get("payment_schedule"):
|
||||
total = 0
|
||||
for d in self.get("payment_schedule"):
|
||||
@@ -883,6 +889,7 @@ def get_advance_payment_entries(party_type, party, party_account,
|
||||
t1.name = t2.parent and t1.{0} = %s and t1.payment_type = %s
|
||||
and t1.party_type = %s and t1.party = %s and t1.docstatus = 1
|
||||
and t2.reference_doctype = %s {1}
|
||||
order by t1.posting_date
|
||||
""".format(party_account_field, reference_condition),
|
||||
[party_account, payment_type, party_type, party, order_doctype] + order_list, as_dict=1)
|
||||
|
||||
@@ -894,6 +901,7 @@ def get_advance_payment_entries(party_type, party, party_account,
|
||||
where
|
||||
{0} = %s and party_type = %s and party = %s and payment_type = %s
|
||||
and docstatus = 1 and unallocated_amount > 0
|
||||
order by posting_date
|
||||
""".format(party_account_field), (party_account, party_type, party, payment_type), as_dict=1)
|
||||
|
||||
return list(payment_entries_against_order) + list(unallocated_payment_entries)
|
||||
|
||||
@@ -163,6 +163,11 @@ class BuyingController(StockController):
|
||||
if item in self.sub_contracted_items and not item.bom:
|
||||
frappe.throw(_("Please select BOM in BOM field for Item {0}").format(item.item_code))
|
||||
|
||||
if self.doctype == "Purchase Order":
|
||||
for supplied_item in self.get("supplied_items"):
|
||||
if not supplied_item.reserve_warehouse:
|
||||
frappe.throw(_("Reserved Warehouse is mandatory for Item {0} in Raw Materials supplied").format(frappe.bold(supplied_item.rm_item_code)))
|
||||
|
||||
else:
|
||||
for item in self.get("items"):
|
||||
if item.bom:
|
||||
@@ -192,8 +197,16 @@ class BuyingController(StockController):
|
||||
def update_raw_materials_supplied(self, item, raw_material_table):
|
||||
bom_items = self.get_items_from_bom(item.item_code, item.bom)
|
||||
raw_materials_cost = 0
|
||||
items = list(set([d.item_code for d in bom_items]))
|
||||
item_wh = frappe._dict(frappe.db.sql("""select item_code, default_warehouse
|
||||
from `tabItem` where name in ({0})""".format(", ".join(["%s"] * len(items))), items))
|
||||
|
||||
for bom_item in bom_items:
|
||||
if self.doctype == "Purchase Order":
|
||||
reserve_warehouse = bom_item.source_warehouse or item_wh.get(bom_item.item_code)
|
||||
if frappe.db.get_value("Warehouse", reserve_warehouse, "company") != self.company:
|
||||
reserve_warehouse = None
|
||||
|
||||
# check if exists
|
||||
exists = 0
|
||||
for d in self.get(raw_material_table):
|
||||
@@ -213,6 +226,8 @@ class BuyingController(StockController):
|
||||
rm.rm_item_code = bom_item.item_code
|
||||
rm.stock_uom = bom_item.stock_uom
|
||||
rm.required_qty = required_qty
|
||||
if self.doctype == "Purchase Order" and not rm.reserve_warehouse:
|
||||
rm.reserve_warehouse = reserve_warehouse
|
||||
|
||||
rm.conversion_factor = item.conversion_factor
|
||||
|
||||
@@ -264,7 +279,7 @@ class BuyingController(StockController):
|
||||
def get_items_from_bom(self, item_code, bom):
|
||||
bom_items = frappe.db.sql("""select t2.item_code,
|
||||
t2.stock_qty / ifnull(t1.quantity, 1) as qty_consumed_per_unit,
|
||||
t2.rate, t2.stock_uom, t2.name, t2.description
|
||||
t2.rate, t2.stock_uom, t2.name, t2.description, t2.source_warehouse
|
||||
from `tabBOM` t1, `tabBOM Item` t2, tabItem t3
|
||||
where t2.parent = t1.name and t1.item = %s
|
||||
and t1.docstatus = 1 and t1.is_active = 1 and t1.name = %s
|
||||
@@ -339,7 +354,7 @@ class BuyingController(StockController):
|
||||
frappe.get_meta(item_row.doctype).get_label(fieldname), item_row['item_code'])))
|
||||
|
||||
def update_stock_ledger(self, allow_negative_stock=False, via_landed_cost_voucher=False):
|
||||
self.update_ordered_qty()
|
||||
self.update_ordered_and_reserved_qty()
|
||||
|
||||
sl_entries = []
|
||||
stock_items = self.get_stock_items()
|
||||
@@ -381,7 +396,7 @@ class BuyingController(StockController):
|
||||
self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock,
|
||||
via_landed_cost_voucher=via_landed_cost_voucher)
|
||||
|
||||
def update_ordered_qty(self):
|
||||
def update_ordered_and_reserved_qty(self):
|
||||
po_map = {}
|
||||
for d in self.get("items"):
|
||||
if self.doctype=="Purchase Receipt" \
|
||||
@@ -400,6 +415,8 @@ class BuyingController(StockController):
|
||||
frappe.InvalidStatusError)
|
||||
|
||||
po_obj.update_ordered_qty(po_item_rows)
|
||||
if self.is_subcontracted:
|
||||
po_obj.update_reserved_qty_for_subcontract()
|
||||
|
||||
def make_sl_entries_for_supplier_warehouse(self, sl_entries):
|
||||
if hasattr(self, 'supplied_items'):
|
||||
|
||||
@@ -92,7 +92,10 @@ def validate_is_incremental(numeric_attribute, attribute, value, item):
|
||||
InvalidItemAttributeValueError, title=_('Invalid Attribute'))
|
||||
|
||||
def validate_item_attribute_value(attributes_list, attribute, attribute_value, item):
|
||||
if attribute_value not in attributes_list:
|
||||
allow_rename_attribute_value = frappe.db.get_single_value('Item Variant Settings', 'allow_rename_attribute_value')
|
||||
if allow_rename_attribute_value:
|
||||
pass
|
||||
elif attribute_value not in attributes_list:
|
||||
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'))
|
||||
|
||||
|
||||
@@ -53,8 +53,9 @@ def validate_returned_items(doc):
|
||||
|
||||
valid_items = frappe._dict()
|
||||
|
||||
select_fields = "item_code, qty, rate, parenttype" if doc.doctype=="Purchase Invoice" \
|
||||
else "item_code, qty, rate, serial_no, batch_no, parenttype"
|
||||
select_fields = "item_code, qty, stock_qty, rate, parenttype, conversion_factor"
|
||||
if doc.doctype != 'Purchase Invoice':
|
||||
select_fields += ",serial_no, batch_no"
|
||||
|
||||
if doc.doctype in ['Purchase Invoice', 'Purchase Receipt']:
|
||||
select_fields += ",rejected_qty, received_qty"
|
||||
@@ -111,7 +112,7 @@ def validate_returned_items(doc):
|
||||
frappe.throw(_("Atleast one item should be entered with negative quantity in return document"))
|
||||
|
||||
def validate_quantity(doc, args, ref, valid_items, already_returned_items):
|
||||
fields = ['qty']
|
||||
fields = ['stock_qty']
|
||||
if doc.doctype in ['Purchase Receipt', 'Purchase Invoice']:
|
||||
fields.extend(['received_qty', 'rejected_qty'])
|
||||
|
||||
@@ -119,16 +120,19 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items):
|
||||
|
||||
for column in fields:
|
||||
returned_qty = flt(already_returned_data.get(column, 0)) if len(already_returned_data) > 0 else 0
|
||||
reference_qty = ref.get(column)
|
||||
reference_qty = (ref.get(column) if column == 'stock_qty'
|
||||
else ref.get(column) * ref.get("conversion_factor", 1.0))
|
||||
|
||||
max_returnable_qty = flt(reference_qty) - returned_qty
|
||||
label = column.replace('_', ' ').title()
|
||||
|
||||
if reference_qty:
|
||||
if flt(args.get(column)) > 0:
|
||||
frappe.throw(_("{0} must be negative in return document").format(label))
|
||||
elif returned_qty >= reference_qty and args.get(column):
|
||||
frappe.throw(_("Item {0} has already been returned")
|
||||
.format(args.item_code), StockOverReturnError)
|
||||
elif abs(args.get(column)) > max_returnable_qty:
|
||||
elif (abs(args.get(column)) * args.get("conversion_factor", 1.0)) > max_returnable_qty:
|
||||
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
|
||||
.format(args.idx, reference_qty, args.item_code), StockOverReturnError)
|
||||
|
||||
@@ -138,6 +142,7 @@ def get_ref_item_dict(valid_items, ref_item_row):
|
||||
valid_items.setdefault(ref_item_row.item_code, frappe._dict({
|
||||
"qty": 0,
|
||||
"rate": 0,
|
||||
"stock_qty": 0,
|
||||
"rejected_qty": 0,
|
||||
"received_qty": 0,
|
||||
"serial_no": [],
|
||||
@@ -145,6 +150,7 @@ def get_ref_item_dict(valid_items, ref_item_row):
|
||||
}))
|
||||
item_dict = valid_items[ref_item_row.item_code]
|
||||
item_dict["qty"] += ref_item_row.qty
|
||||
item_dict["stock_qty"] += ref_item_row.get('stock_qty', 0)
|
||||
if ref_item_row.get("rate", 0) > item_dict["rate"]:
|
||||
item_dict["rate"] = ref_item_row.get("rate", 0)
|
||||
|
||||
@@ -161,9 +167,10 @@ def get_ref_item_dict(valid_items, ref_item_row):
|
||||
return valid_items
|
||||
|
||||
def get_already_returned_items(doc):
|
||||
column = 'child.item_code, sum(abs(child.qty)) as qty'
|
||||
column = 'child.item_code, sum(abs(child.qty)) as qty, sum(abs(child.stock_qty)) as stock_qty'
|
||||
if doc.doctype in ['Purchase Invoice', 'Purchase Receipt']:
|
||||
column += ', sum(abs(child.rejected_qty)) as rejected_qty, sum(abs(child.received_qty)) as received_qty'
|
||||
column += """, sum(abs(child.rejected_qty) * child.conversion_factor) as rejected_qty,
|
||||
sum(abs(child.received_qty) * child.conversion_factor) as received_qty"""
|
||||
|
||||
data = frappe.db.sql("""
|
||||
select {0}
|
||||
@@ -180,6 +187,7 @@ def get_already_returned_items(doc):
|
||||
for d in data:
|
||||
items.setdefault(d.item_code, frappe._dict({
|
||||
"qty": d.get("qty"),
|
||||
"stock_qty": d.get("stock_qty"),
|
||||
"received_qty": d.get("received_qty"),
|
||||
"rejected_qty": d.get("rejected_qty")
|
||||
}))
|
||||
@@ -231,6 +239,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
|
||||
target_doc.received_qty = -1* source_doc.received_qty
|
||||
target_doc.rejected_qty = -1* source_doc.rejected_qty
|
||||
target_doc.qty = -1* source_doc.qty
|
||||
target_doc.stock_qty = -1 * source_doc.stock_qty
|
||||
target_doc.purchase_order = source_doc.purchase_order
|
||||
target_doc.purchase_order_item = source_doc.purchase_order_item
|
||||
target_doc.rejected_warehouse = source_doc.rejected_warehouse
|
||||
@@ -238,6 +247,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
|
||||
target_doc.received_qty = -1* source_doc.received_qty
|
||||
target_doc.rejected_qty = -1* source_doc.rejected_qty
|
||||
target_doc.qty = -1* source_doc.qty
|
||||
target_doc.stock_qty = -1 * source_doc.stock_qty
|
||||
target_doc.purchase_order = source_doc.purchase_order
|
||||
target_doc.purchase_receipt = source_doc.purchase_receipt
|
||||
target_doc.rejected_warehouse = source_doc.rejected_warehouse
|
||||
|
||||
@@ -38,6 +38,7 @@ class SellingController(StockController):
|
||||
self.validate_max_discount()
|
||||
self.validate_selling_price()
|
||||
self.set_qty_as_per_stock_uom()
|
||||
self.set_po_nos()
|
||||
check_active_sales_items(self)
|
||||
|
||||
def set_missing_values(self, for_validate=False):
|
||||
@@ -150,13 +151,16 @@ class SellingController(StockController):
|
||||
if not frappe.db.get_single_value("Selling Settings", "validate_selling_price"):
|
||||
return
|
||||
|
||||
if hasattr(self, "is_return") and self.is_return:
|
||||
return
|
||||
|
||||
for it in self.get("items"):
|
||||
if not it.item_code:
|
||||
continue
|
||||
|
||||
last_purchase_rate, is_stock_item = frappe.db.get_value("Item", it.item_code, ["last_purchase_rate", "is_stock_item"])
|
||||
last_purchase_rate_in_sales_uom = last_purchase_rate / (it.conversion_factor or 1)
|
||||
if flt(it.base_rate) < flt(last_purchase_rate_in_sales_uom) and not self.is_return:
|
||||
if flt(it.base_rate) < flt(last_purchase_rate_in_sales_uom):
|
||||
throw_message(it.item_name, last_purchase_rate_in_sales_uom, "last purchase rate")
|
||||
|
||||
last_valuation_rate = frappe.db.sql("""
|
||||
@@ -166,7 +170,7 @@ class SellingController(StockController):
|
||||
""", (it.item_code, it.warehouse))
|
||||
if last_valuation_rate:
|
||||
last_valuation_rate_in_sales_uom = last_valuation_rate[0][0] / (it.conversion_factor or 1)
|
||||
if is_stock_item and flt(it.base_rate) < flt(last_valuation_rate_in_sales_uom) and not self.is_return:
|
||||
if is_stock_item and flt(it.base_rate) < flt(last_valuation_rate_in_sales_uom):
|
||||
throw_message(it.name, last_valuation_rate_in_sales_uom, "valuation rate")
|
||||
|
||||
|
||||
@@ -323,9 +327,16 @@ class SellingController(StockController):
|
||||
"actual_qty": -1*flt(d.qty),
|
||||
"incoming_rate": return_rate
|
||||
}))
|
||||
|
||||
self.make_sl_entries(sl_entries)
|
||||
|
||||
def set_po_nos(self):
|
||||
if self.doctype in ("Delivery Note", "Sales Invoice"):
|
||||
ref_fieldname = "against_sales_order" if self.doctype == "Delivery Note" else "sales_order"
|
||||
sales_orders = list(set([d.get(ref_fieldname) for d in self.items]))
|
||||
if sales_orders:
|
||||
po_nos = frappe.get_all('Sales Order', 'po_no', filters = {'name': ('in', sales_orders)})
|
||||
self.po_no = ', '.join(list(set([d.po_no for d in po_nos if d.po_no])))
|
||||
|
||||
def check_active_sales_items(obj):
|
||||
for d in obj.get("items"):
|
||||
if d.item_code:
|
||||
|
||||
@@ -156,6 +156,9 @@ class StatusUpdater(Document):
|
||||
|
||||
# get unique transactions to update
|
||||
for d in self.get_all_children():
|
||||
if hasattr(d, 'qty') and d.qty < 0 and not self.get('is_return'):
|
||||
frappe.throw(_("For an item {0}, quantity must be positive number").format(d.item_code))
|
||||
|
||||
if d.doctype == args['source_dt'] and d.get(args["join_field"]):
|
||||
args['name'] = d.get(args['join_field'])
|
||||
|
||||
@@ -250,7 +253,7 @@ class StatusUpdater(Document):
|
||||
|
||||
if args['detail_id']:
|
||||
if not args.get("extra_cond"): args["extra_cond"] = ""
|
||||
|
||||
|
||||
frappe.db.sql("""update `tab%(target_dt)s`
|
||||
set %(target_field)s = (
|
||||
(select ifnull(sum(%(source_field)s), 0)
|
||||
@@ -275,7 +278,7 @@ class StatusUpdater(Document):
|
||||
"""Update percent field in parent transaction"""
|
||||
|
||||
self._update_modified(args, update_modified)
|
||||
|
||||
|
||||
if args.get('target_parent_field'):
|
||||
frappe.db.sql("""update `tab%(target_parent_dt)s`
|
||||
set %(target_parent_field)s = round(
|
||||
|
||||
@@ -415,13 +415,15 @@ class calculate_taxes_and_totals(object):
|
||||
|
||||
self.doc.total_advance = flt(total_allocated_amount, self.doc.precision("total_advance"))
|
||||
|
||||
grand_total = self.doc.rounded_total or self.doc.grand_total
|
||||
|
||||
if self.doc.party_account_currency == self.doc.currency:
|
||||
invoice_total = flt(self.doc.grand_total - flt(self.doc.write_off_amount),
|
||||
invoice_total = flt(grand_total - flt(self.doc.write_off_amount),
|
||||
self.doc.precision("grand_total"))
|
||||
else:
|
||||
base_write_off_amount = flt(flt(self.doc.write_off_amount) * self.doc.conversion_rate,
|
||||
self.doc.precision("base_write_off_amount"))
|
||||
invoice_total = flt(self.doc.grand_total * self.doc.conversion_rate,
|
||||
invoice_total = flt(grand_total * self.doc.conversion_rate,
|
||||
self.doc.precision("grand_total")) - base_write_off_amount
|
||||
|
||||
if invoice_total > 0 and self.doc.total_advance > invoice_total:
|
||||
|
||||
@@ -65,7 +65,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -151,7 +150,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -237,7 +235,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -323,7 +320,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -409,7 +405,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -495,7 +490,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -581,7 +575,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -667,7 +660,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -753,7 +745,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -839,7 +830,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -925,7 +915,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1011,7 +1000,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1097,7 +1085,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1183,7 +1170,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1269,7 +1255,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1355,7 +1340,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1441,7 +1425,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1527,7 +1510,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1613,7 +1595,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1699,7 +1680,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1785,7 +1765,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1871,7 +1850,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -1957,7 +1935,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2043,7 +2020,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2129,7 +2105,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2215,7 +2190,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2301,7 +2275,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2387,7 +2360,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2473,7 +2445,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2559,7 +2530,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2645,7 +2615,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2731,7 +2700,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2817,7 +2785,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2903,7 +2870,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -2989,7 +2955,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -3075,7 +3040,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -3161,7 +3125,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -3247,7 +3210,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -3333,7 +3295,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -3419,7 +3380,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -3505,7 +3465,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -3591,7 +3550,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -3677,7 +3635,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -3763,7 +3720,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -3849,7 +3805,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -3935,7 +3890,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4021,7 +3975,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4107,7 +4060,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4193,7 +4145,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4279,7 +4230,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4365,7 +4315,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4451,7 +4400,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4537,7 +4485,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4623,7 +4570,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4709,7 +4655,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4795,7 +4740,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4881,7 +4825,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -4967,7 +4910,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -5053,7 +4995,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -5139,7 +5080,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -5225,7 +5165,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -5311,7 +5250,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
@@ -5397,7 +5335,6 @@
|
||||
"taxes": [],
|
||||
"thumbnail": null,
|
||||
"tolerance": 0.0,
|
||||
"total_projected_qty": 0.0,
|
||||
"uoms": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
|
||||
@@ -38,9 +38,6 @@ frappe.ui.form.on('Fee Schedule', {
|
||||
if (data.reload && data.reload === 1) {
|
||||
frm.reload_doc();
|
||||
}
|
||||
if (data.progress && data.progress === "0") {
|
||||
frappe.msgprint(__("Fee records will be created in the background. In case of any error the error message will be updated in the Schedule."));
|
||||
}
|
||||
if (data.progress) {
|
||||
let progress_bar = $(cur_frm.dashboard.progress_area).find(".progress-bar");
|
||||
if (progress_bar) {
|
||||
@@ -74,6 +71,15 @@ frappe.ui.form.on('Fee Schedule', {
|
||||
});
|
||||
}, "fa fa-play", "btn-success");
|
||||
}
|
||||
if (frm.doc.fee_creation_status == "Successful") {
|
||||
frm.add_custom_button(__("View Fees Records"), function() {
|
||||
frappe.route_options = {
|
||||
fee_schedule: frm.doc.name
|
||||
};
|
||||
frappe.set_route("List", "Fees");
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
fee_structure: function(frm) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "naming_series:",
|
||||
"beta": 1,
|
||||
"beta": 0,
|
||||
"creation": "2017-07-18 15:21:21.527136",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
@@ -1029,7 +1029,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-04 13:08:27.727709",
|
||||
"modified": "2018-02-26 13:59:36.560780",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Fee Schedule",
|
||||
|
||||
@@ -56,8 +56,15 @@ class FeeSchedule(Document):
|
||||
self.db_set("fee_creation_status", "In Process")
|
||||
frappe.publish_realtime("fee_schedule_progress",
|
||||
{"progress": "0", "reload": 1}, user=frappe.session.user)
|
||||
enqueue(generate_fee, queue='default', timeout=6000, event='generate_fee',
|
||||
fee_schedule=self.name)
|
||||
|
||||
total_records = sum([int(d.total_students) for d in self.student_groups])
|
||||
if total_records > 10:
|
||||
frappe.msgprint(_('''Fee records will be created in the background.
|
||||
In case of any error the error message will be updated in the Schedule.'''))
|
||||
enqueue(generate_fee, queue='default', timeout=6000, event='generate_fee',
|
||||
fee_schedule=self.name)
|
||||
else:
|
||||
generate_fee(self.name)
|
||||
|
||||
def generate_fee(fee_schedule):
|
||||
doc = frappe.get_doc("Fee Schedule", fee_schedule)
|
||||
@@ -69,10 +76,7 @@ def generate_fee(fee_schedule):
|
||||
frappe.throw(_("Please setup Students under Student Groups"))
|
||||
|
||||
for d in doc.student_groups:
|
||||
students = frappe.db.sql(""" select sg.program, sg.batch, sgs.student, sgs.student_name
|
||||
from `tabStudent Group` sg, `tabStudent Group Student` sgs
|
||||
where sg.name=%s and sg.name=sgs.parent and sgs.active=1""", d.student_group, as_dict=1)
|
||||
|
||||
students = get_students(d.student_group, doc.academic_year, doc.academic_term, doc.student_category)
|
||||
for student in students:
|
||||
try:
|
||||
fees_doc = get_mapped_doc("Fee Schedule", fee_schedule, {
|
||||
@@ -86,7 +90,7 @@ def generate_fee(fee_schedule):
|
||||
fees_doc.student = student.student
|
||||
fees_doc.student_name = student.student_name
|
||||
fees_doc.program = student.program
|
||||
fees_doc.student_batch = student.batch
|
||||
fees_doc.student_batch = student.student_batch_name
|
||||
fees_doc.send_payment_request = doc.send_email
|
||||
fees_doc.save()
|
||||
fees_doc.submit()
|
||||
@@ -110,6 +114,30 @@ def generate_fee(fee_schedule):
|
||||
{"progress": "100", "reload": 1}, user=frappe.session.user)
|
||||
|
||||
|
||||
def get_students(student_group, academic_year, academic_term=None, student_category=None):
|
||||
conditions = ""
|
||||
if student_category:
|
||||
conditions = " and pe.student_category='{}'".format(frappe.db.escape(student_category))
|
||||
if academic_term:
|
||||
conditions = " and pe.academic_term='{}'".format(frappe.db.escape(academic_term))
|
||||
|
||||
students = frappe.db.sql("""
|
||||
select pe.student, pe.student_name, pe.program, pe.student_batch_name
|
||||
from `tabStudent Group Student` sgs, `tabProgram Enrollment` pe
|
||||
where
|
||||
pe.student = sgs.student and pe.academic_year = %s
|
||||
and sgs.parent = %s and sgs.active = 1
|
||||
{conditions}
|
||||
""".format(conditions=conditions), (academic_year, student_group), as_dict=1)
|
||||
return students
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_total_students(student_group, academic_year, academic_term=None, student_category=None):
|
||||
total_students = get_students(student_group, academic_year, academic_term, student_category)
|
||||
return len(total_students)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_fee_structure(source_name,target_doc=None):
|
||||
fee_request = get_mapped_doc("Fee Structure", source_name,
|
||||
@@ -117,23 +145,3 @@ def get_fee_structure(source_name,target_doc=None):
|
||||
"doctype": "Fee Schedule"
|
||||
}}, ignore_permissions=True)
|
||||
return fee_request
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_total_students(student_group, academic_year, academic_term=None, student_category=None):
|
||||
conditions = ""
|
||||
if student_category:
|
||||
conditions = " and pe.student_category='{}'".format(frappe.db.escape(student_category))
|
||||
if academic_term:
|
||||
conditions = " and pe.academic_term='{}'".format(frappe.db.escape(academic_term))
|
||||
|
||||
|
||||
return frappe.db.sql("""
|
||||
select count(pe.name)
|
||||
from `tabStudent Group Student` sgs, `tabProgram Enrollment` pe
|
||||
where
|
||||
pe.student = sgs.student
|
||||
and pe.academic_year = %s
|
||||
and sgs.parent = %s
|
||||
and sgs.active = 1
|
||||
{conditions}
|
||||
""".format(conditions=conditions), (academic_year, student_group))[0][0]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "naming_series:",
|
||||
"beta": 1,
|
||||
"beta": 0,
|
||||
"creation": "2015-09-22 16:57:22.143710",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
@@ -1276,7 +1276,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-12-06 05:55:10.502567",
|
||||
"modified": "2018-02-08 02:12:34.185245",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Fees",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"allow_rename": 1,
|
||||
"autoname": "GARD.####",
|
||||
"beta": 0,
|
||||
"creation": "2016-07-21 15:32:51.163292",
|
||||
@@ -507,7 +507,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-06 18:17:38.090252",
|
||||
"modified": "2018-03-07 12:51:06.941609",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Guardian",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-11-10 19:41:46.641227",
|
||||
"modified": "2018-02-08 15:11:24.904628",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Course wise Assessment Report",
|
||||
@@ -17,7 +17,10 @@
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Academics User"
|
||||
"role": "Instructor"
|
||||
},
|
||||
{
|
||||
"role": "Education Manager"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"letter_head": "Shishuvan Secondary School",
|
||||
"modified": "2018-01-22 17:04:43.412054",
|
||||
"modified": "2018-02-08 15:11:35.339434",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Final Assessment Grades",
|
||||
@@ -16,5 +16,12 @@
|
||||
"ref_doctype": "Assessment Result",
|
||||
"report_name": "Final Assessment Grades",
|
||||
"report_type": "Script Report",
|
||||
"roles": []
|
||||
"roles": [
|
||||
{
|
||||
"role": "Instructor"
|
||||
},
|
||||
{
|
||||
"role": "Education Manager"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -27,26 +27,27 @@ def execute(filters=None):
|
||||
course_dict = values.get("course_dict")
|
||||
|
||||
for student in args.students:
|
||||
student_row = {}
|
||||
student_row["student"] = student
|
||||
student_row["student_name"] = student_details[student]
|
||||
for course in course_dict:
|
||||
scrub_course = frappe.scrub(course)
|
||||
if assessment_group in assessment_result[student][course]:
|
||||
student_row["grade_" + scrub_course] = assessment_result[student][course][assessment_group]["Total Score"]["grade"]
|
||||
student_row["score_" + scrub_course] = assessment_result[student][course][assessment_group]["Total Score"]["score"]
|
||||
if student_details.get(student):
|
||||
student_row = {}
|
||||
student_row["student"] = student
|
||||
student_row["student_name"] = student_details[student]
|
||||
for course in course_dict:
|
||||
scrub_course = frappe.scrub(course)
|
||||
if assessment_group in assessment_result[student][course]:
|
||||
student_row["grade_" + scrub_course] = assessment_result[student][course][assessment_group]["Total Score"]["grade"]
|
||||
student_row["score_" + scrub_course] = assessment_result[student][course][assessment_group]["Total Score"]["score"]
|
||||
|
||||
# create the list of possible grades
|
||||
if student_row["grade_" + scrub_course] not in grades:
|
||||
grades.append(student_row["grade_" + scrub_course])
|
||||
# create the list of possible grades
|
||||
if student_row["grade_" + scrub_course] not in grades:
|
||||
grades.append(student_row["grade_" + scrub_course])
|
||||
|
||||
# create the dict of for gradewise analysis
|
||||
if student_row["grade_" + scrub_course] not in course_wise_analysis[course]:
|
||||
course_wise_analysis[course][student_row["grade_" + scrub_course]] = 1
|
||||
else:
|
||||
course_wise_analysis[course][student_row["grade_" + scrub_course]] += 1
|
||||
# create the dict of for gradewise analysis
|
||||
if student_row["grade_" + scrub_course] not in course_wise_analysis[course]:
|
||||
course_wise_analysis[course][student_row["grade_" + scrub_course]] = 1
|
||||
else:
|
||||
course_wise_analysis[course][student_row["grade_" + scrub_course]] += 1
|
||||
|
||||
data.append(student_row)
|
||||
data.append(student_row)
|
||||
|
||||
course_list = [d for d in course_dict]
|
||||
columns = get_column(course_dict)
|
||||
|
||||
@@ -23,11 +23,6 @@ frappe.ui.form.on('Consultation', {
|
||||
patient: frm.doc.patient
|
||||
},
|
||||
callback: function (data) {
|
||||
var age = null;
|
||||
if(data.message.dob){
|
||||
age = calculate_age(data.message.dob);
|
||||
}
|
||||
frappe.model.set_value(frm.doctype,frm.docname, "patient_age", age);
|
||||
show_details(data.message);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -70,6 +71,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -100,6 +102,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -126,10 +129,11 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -161,6 +165,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -192,6 +197,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -223,6 +229,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -254,6 +261,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -283,6 +291,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -313,6 +322,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -343,6 +353,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -373,6 +384,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -403,6 +415,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -433,6 +446,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -464,6 +478,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -493,6 +508,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -524,6 +540,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -554,6 +571,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -585,6 +603,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -615,6 +634,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -645,6 +665,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -674,6 +695,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -704,6 +726,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -734,6 +757,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -765,6 +789,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -796,6 +821,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@@ -810,7 +836,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-10-05 16:08:24.624644",
|
||||
"modified": "2018-03-09 07:05:24.984224",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Physician",
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
margin-bottom: -4px;
|
||||
}
|
||||
|
||||
.medical_record-row > * {
|
||||
z-index: -999;
|
||||
}
|
||||
|
||||
.date-indicator {
|
||||
background:none;
|
||||
font-size:12px;
|
||||
@@ -48,7 +52,6 @@
|
||||
.medical_record-date {
|
||||
padding: 15px;
|
||||
padding-right: 0px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#page-medical_record .plot-wrapper {
|
||||
|
||||
@@ -11,7 +11,7 @@ app_email = "info@erpnext.com"
|
||||
app_license = "GNU General Public License (v3)"
|
||||
source_link = "https://github.com/frappe/erpnext"
|
||||
|
||||
develop_version = '9.x.x-develop'
|
||||
develop_version = '10.x.x-develop'
|
||||
|
||||
error_report_email = "support@erpnext.com"
|
||||
|
||||
@@ -203,6 +203,9 @@ doc_events = {
|
||||
},
|
||||
'Address': {
|
||||
'validate': 'erpnext.regional.india.utils.validate_gstin_for_india'
|
||||
},
|
||||
('Sales Invoice', 'Purchase Invoice'): {
|
||||
'validate': 'erpnext.regional.india.utils.set_place_of_supply'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ frappe.ui.form.on('Employee',{
|
||||
}
|
||||
frappe.call({
|
||||
method: "erpnext.hr.doctype.employee.employee.create_user",
|
||||
args: { employee: cur_frm.doc.name },
|
||||
args: { employee: frm.doc.name, email: frm.doc.prefered_email },
|
||||
callback: function(r)
|
||||
{
|
||||
frm.set_value("user_id", r.message)
|
||||
|
||||
@@ -263,7 +263,7 @@ def deactivate_sales_person(status = None, employee = None):
|
||||
frappe.db.set_value("Sales Person", sales_person, "enabled", 0)
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_user(employee, user = None):
|
||||
def create_user(employee, user = None, email=None):
|
||||
emp = frappe.get_doc("Employee", employee)
|
||||
|
||||
employee_name = emp.employee_name.split(" ")
|
||||
@@ -277,6 +277,9 @@ def create_user(employee, user = None):
|
||||
|
||||
first_name = employee_name[0]
|
||||
|
||||
if email:
|
||||
emp.prefered_email = email
|
||||
|
||||
user = frappe.new_doc("User")
|
||||
user.update({
|
||||
"name": emp.employee_name,
|
||||
|
||||
@@ -135,7 +135,7 @@ def get_employee_loan_application(employee_loan_application):
|
||||
return employee_loan.as_dict()
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_jv_entry(employee_loan, company, employee_loan_account, employee, loan_amount, payment_account):
|
||||
def make_jv_entry(employee_loan, company, employee_loan_account, employee, loan_amount, payment_account=None):
|
||||
journal_entry = frappe.new_doc('Journal Entry')
|
||||
journal_entry.voucher_type = 'Bank Entry'
|
||||
journal_entry.user_remark = _('Against Employee Loan: {0}').format(employee_loan)
|
||||
|
||||
@@ -45,10 +45,11 @@ class ExpenseClaim(AccountsController):
|
||||
}[cstr(self.docstatus or 0)]
|
||||
|
||||
paid_amount = flt(self.total_amount_reimbursed) + flt(self.total_advance_amount)
|
||||
if self.total_sanctioned_amount > 0 and self.total_sanctioned_amount == paid_amount\
|
||||
if (self.is_paid or (flt(self.total_sanctioned_amount) > 0
|
||||
and flt(self.total_sanctioned_amount) == paid_amount)) \
|
||||
and self.docstatus == 1 and self.approval_status == 'Approved':
|
||||
self.status = "Paid"
|
||||
elif self.total_sanctioned_amount > 0 and self.docstatus == 1 and self.approval_status == 'Approved':
|
||||
self.status = "Paid"
|
||||
elif flt(self.total_sanctioned_amount) > 0 and self.docstatus == 1 and self.approval_status == 'Approved':
|
||||
self.status = "Unpaid"
|
||||
elif self.docstatus == 1 and self.approval_status == 'Rejected':
|
||||
self.status = 'Rejected'
|
||||
|
||||
@@ -235,52 +235,6 @@ class TestLeaveApplication(unittest.TestCase):
|
||||
application.half_day_date = "2013-01-05"
|
||||
application.insert()
|
||||
|
||||
def test_global_block_list(self):
|
||||
self._clear_roles()
|
||||
|
||||
from frappe.utils.user import add_role
|
||||
add_role("test1@example.com", "Employee")
|
||||
add_role("test@example.com", "Leave Approver")
|
||||
self._add_employee_leave_approver("_T-Employee-0002", "test@example.com")
|
||||
|
||||
make_allocation_record(employee="_T-Employee-0002")
|
||||
|
||||
application = self.get_application(_test_records[1])
|
||||
application.leave_approver = "test@example.com"
|
||||
|
||||
frappe.db.set_value("Leave Block List", "_Test Leave Block List",
|
||||
"applies_to_all_departments", 1)
|
||||
frappe.db.set_value("Employee", "_T-Employee-0002", "department",
|
||||
"_Test Department")
|
||||
|
||||
frappe.set_user("test1@example.com")
|
||||
application.insert()
|
||||
|
||||
frappe.set_user("test@example.com")
|
||||
application.status = "Approved"
|
||||
|
||||
# clear permlevel access cache on change user
|
||||
del application._has_access_to
|
||||
|
||||
self.assertRaises(LeaveDayBlockedError, application.submit)
|
||||
|
||||
frappe.db.set_value("Leave Block List", "_Test Leave Block List",
|
||||
"applies_to_all_departments", 0)
|
||||
|
||||
def test_leave_approval(self):
|
||||
self._clear_roles()
|
||||
|
||||
from frappe.utils.user import add_role
|
||||
add_role("test@example.com", "Employee")
|
||||
add_role("test1@example.com", "HR User")
|
||||
add_role("test1@example.com", "Leave Approver")
|
||||
add_role("test2@example.com", "Leave Approver")
|
||||
|
||||
self._test_leave_approval_basic_case()
|
||||
self._test_leave_approval_invalid_leave_approver_insert()
|
||||
self._test_leave_approval_invalid_leave_approver_submit()
|
||||
self._test_leave_approval_valid_leave_approver_insert()
|
||||
|
||||
def _test_leave_approval_basic_case(self):
|
||||
self._clear_applications()
|
||||
|
||||
|
||||
@@ -5,7 +5,10 @@ var in_progress = false;
|
||||
|
||||
frappe.ui.form.on('Payroll Entry', {
|
||||
onload: function (frm) {
|
||||
frm.doc.posting_date = frappe.datetime.nowdate();
|
||||
if (!frm.doc.posting_date) {
|
||||
frm.doc.posting_date = frappe.datetime.nowdate();
|
||||
}
|
||||
|
||||
frm.toggle_reqd(['payroll_frequency'], !frm.doc.salary_slip_based_on_timesheet);
|
||||
},
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ class PayrollEntry(Document):
|
||||
Get loan details from submitted salary slip based on selected criteria
|
||||
"""
|
||||
cond = self.get_filter_condition()
|
||||
return frappe.db.sql(""" select eld.employee_loan_account,
|
||||
return frappe.db.sql(""" select eld.employee_loan_account, eld.employee_loan,
|
||||
eld.interest_income_account, eld.principal_amount, eld.interest_amount, eld.total_payment
|
||||
from
|
||||
`tabSalary Slip` t1, `tabSalary Slip Loan` eld
|
||||
@@ -252,7 +252,7 @@ class PayrollEntry(Document):
|
||||
journal_entry.user_remark = _('Accural Journal Entry for salaries from {0} to {1}')\
|
||||
.format(self.start_date, self.end_date)
|
||||
journal_entry.company = self.company
|
||||
journal_entry.posting_date = nowdate()
|
||||
journal_entry.posting_date = self.posting_date
|
||||
|
||||
accounts = []
|
||||
payable_amount = 0
|
||||
@@ -283,7 +283,12 @@ class PayrollEntry(Document):
|
||||
"account": data.employee_loan_account,
|
||||
"credit_in_account_currency": data.principal_amount
|
||||
})
|
||||
accounts.append({
|
||||
|
||||
if data.interest_amount and not data.interest_income_account:
|
||||
frappe.throw(_("Select interest income account in employee loan {0}").format(data.employee_loan))
|
||||
|
||||
if data.interest_income_account and data.interest_amount:
|
||||
accounts.append({
|
||||
"account": data.interest_income_account,
|
||||
"credit_in_account_currency": data.interest_amount,
|
||||
"cost_center": self.cost_center,
|
||||
|
||||
@@ -156,9 +156,10 @@ class SalarySlip(TransactionBase):
|
||||
})
|
||||
|
||||
def get_date_details(self):
|
||||
date_details = get_start_end_dates(self.payroll_frequency, self.start_date or self.posting_date)
|
||||
self.start_date = date_details.start_date
|
||||
self.end_date = date_details.end_date
|
||||
if not self.end_date:
|
||||
date_details = get_start_end_dates(self.payroll_frequency, self.start_date or self.posting_date)
|
||||
self.start_date = date_details.start_date
|
||||
self.end_date = date_details.end_date
|
||||
|
||||
def check_sal_struct(self, joining_date, relieving_date):
|
||||
cond = ''
|
||||
|
||||
@@ -10,9 +10,7 @@ from frappe import _
|
||||
from erpnext.utilities.product import get_price, get_qty_in_stock
|
||||
from six import string_types
|
||||
|
||||
# hub_url = "http://erpnext.hub:8000"
|
||||
hub_url = "https://hub.erpnext.org"
|
||||
# hub_url = "http://192.168.29.145:3000"
|
||||
hub_url = "https://hubmarket.org"
|
||||
|
||||
class HubSetupError(frappe.ValidationError): pass
|
||||
|
||||
@@ -102,4 +100,4 @@ def reset_hub_settings(last_sync_datetime = ""):
|
||||
@frappe.whitelist()
|
||||
def sync():
|
||||
hub_settings = frappe.get_doc('Hub Settings')
|
||||
hub_settings.sync()
|
||||
hub_settings.sync()
|
||||
|
||||
@@ -47,7 +47,6 @@ class BOM(WebsiteGenerator):
|
||||
self.validate_currency()
|
||||
self.set_conversion_rate()
|
||||
self.validate_uom_is_interger()
|
||||
self.update_stock_qty()
|
||||
self.set_bom_material_details()
|
||||
self.validate_materials()
|
||||
self.validate_operations()
|
||||
@@ -200,6 +199,14 @@ class BOM(WebsiteGenerator):
|
||||
if not from_child_bom:
|
||||
frappe.msgprint(_("Cost Updated"))
|
||||
|
||||
def update_parent_cost(self):
|
||||
if self.total_cost:
|
||||
cost = self.total_cost / self.quantity
|
||||
|
||||
frappe.db.sql("""update `tabBOM Item` set rate=%s, amount=stock_qty*%s
|
||||
where bom_no = %s and docstatus < 2 and parenttype='BOM'""",
|
||||
(cost, cost, self.name))
|
||||
|
||||
def get_bom_unitcost(self, bom_no):
|
||||
bom = frappe.db.sql("""select name, base_total_cost/quantity as unit_cost from `tabBOM`
|
||||
where is_active = 1 and name = %s""", bom_no, as_dict=1)
|
||||
@@ -239,14 +246,12 @@ class BOM(WebsiteGenerator):
|
||||
set_default(self, "item")
|
||||
item = frappe.get_doc("Item", self.item)
|
||||
if item.default_bom != self.name:
|
||||
item.default_bom = self.name
|
||||
item.save(ignore_permissions = True)
|
||||
frappe.db.set_value('Item', self.item, 'default_bom', self.name)
|
||||
else:
|
||||
frappe.db.set(self, "is_default", 0)
|
||||
item = frappe.get_doc("Item", self.item)
|
||||
if item.default_bom == self.name:
|
||||
item.default_bom = None
|
||||
item.save(ignore_permissions = True)
|
||||
frappe.db.set_value('Item', self.item, 'default_bom', None)
|
||||
|
||||
def clear_operations(self):
|
||||
if not self.with_operations:
|
||||
@@ -283,6 +288,8 @@ class BOM(WebsiteGenerator):
|
||||
m.uom = m.stock_uom
|
||||
m.qty = m.stock_qty
|
||||
|
||||
m.db_update()
|
||||
|
||||
def validate_uom_is_interger(self):
|
||||
from erpnext.utilities.transaction_base import validate_uom_is_integer
|
||||
validate_uom_is_integer(self, "uom", "qty", "BOM Item")
|
||||
@@ -325,19 +332,23 @@ class BOM(WebsiteGenerator):
|
||||
|
||||
def check_recursion(self):
|
||||
""" Check whether recursion occurs in any bom"""
|
||||
bom_list = self.traverse_tree()
|
||||
bom_nos = frappe.get_all('BOM Item', fields=["bom_no"],
|
||||
filters={'parent': ('in', bom_list), 'parenttype': 'BOM'})
|
||||
|
||||
check_list = [['parent', 'bom_no', 'parent'], ['bom_no', 'parent', 'child']]
|
||||
for d in check_list:
|
||||
bom_list, count = [self.name], 0
|
||||
while (len(bom_list) > count ):
|
||||
boms = frappe.db.sql(" select %s from `tabBOM Item` where %s = %s and parenttype='BOM'" %
|
||||
(d[0], d[1], '%s'), cstr(bom_list[count]))
|
||||
count = count + 1
|
||||
for b in boms:
|
||||
if b[0] == self.name:
|
||||
frappe.throw(_("BOM recursion: {0} cannot be parent or child of {2}").format(b[0], self.name))
|
||||
if b[0]:
|
||||
bom_list.append(b[0])
|
||||
raise_exception = False
|
||||
if bom_nos and self.name in [d.bom_no for d in bom_nos]:
|
||||
raise_exception = True
|
||||
|
||||
if not raise_exception:
|
||||
bom_nos = frappe.get_all('BOM Item', fields=["parent"],
|
||||
filters={'bom_no': self.name, 'parenttype': 'BOM'})
|
||||
|
||||
if self.name in [d.parent for d in bom_nos]:
|
||||
raise_exception = True
|
||||
|
||||
if raise_exception:
|
||||
frappe.throw(_("BOM recursion: {0} cannot be parent or child of {2}").format(self.name, self.name))
|
||||
|
||||
def update_cost_and_exploded_items(self, bom_list=[]):
|
||||
bom_list = self.traverse_tree(bom_list)
|
||||
@@ -586,9 +597,16 @@ def validate_bom_no(item, bom_no):
|
||||
if bom.docstatus != 1:
|
||||
if not getattr(frappe.flags, "in_test", False):
|
||||
frappe.throw(_("BOM {0} must be submitted").format(bom_no))
|
||||
if item and not (bom.item.lower() == item.lower() or \
|
||||
bom.item.lower() == cstr(frappe.db.get_value("Item", item, "variant_of")).lower()):
|
||||
frappe.throw(_("BOM {0} does not belong to Item {1}").format(bom_no, item))
|
||||
if item:
|
||||
rm_item_exists = False
|
||||
for d in bom.items:
|
||||
if (d.item_code.lower() == item.lower()):
|
||||
rm_item_exists = True
|
||||
if bom.item.lower() == item.lower() or \
|
||||
bom.item.lower() == cstr(frappe.db.get_value("Item", item, "variant_of")).lower():
|
||||
rm_item_exists = True
|
||||
if not rm_item_exists:
|
||||
frappe.throw(_("BOM {0} does not belong to Item {1}").format(bom_no, item))
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_children(doctype, parent=None, is_root=False, **filters):
|
||||
|
||||
@@ -13,6 +13,7 @@ frappe.treeview_settings["BOM"] = {
|
||||
disable_add_node: true,
|
||||
root_label: "BOM", //fieldname from filters
|
||||
get_tree_root: false,
|
||||
show_expand_all: false,
|
||||
get_label: function(node) {
|
||||
if(node.data.qty) {
|
||||
return node.data.qty + " x " + node.data.item_code;
|
||||
@@ -59,5 +60,14 @@ frappe.treeview_settings["BOM"] = {
|
||||
condition: 'frappe.boot.user.can_create.indexOf("BOM") !== -1'
|
||||
}
|
||||
],
|
||||
onrender: function(node) {
|
||||
if(node.is_root && node.data.value!="BOM") {
|
||||
frappe.model.with_doc("BOM", node.data.value, function() {
|
||||
var bom = frappe.model.get_doc("BOM", node.data.value);
|
||||
node.data.image = bom.image || "";
|
||||
node.data.description = bom.description || "";
|
||||
});
|
||||
}
|
||||
},
|
||||
view_template: 'bom_item_preview'
|
||||
}
|
||||
@@ -13,11 +13,14 @@ class BOMUpdateTool(Document):
|
||||
def replace_bom(self):
|
||||
self.validate_bom()
|
||||
self.update_new_bom()
|
||||
bom_list = self.get_parent_boms()
|
||||
bom_list = self.get_parent_boms(self.new_bom)
|
||||
updated_bom = []
|
||||
for bom in bom_list:
|
||||
bom_obj = frappe.get_doc("BOM", bom)
|
||||
updated_bom = bom_obj.update_cost_and_exploded_items(updated_bom)
|
||||
bom_obj.calculate_cost()
|
||||
bom_obj.update_parent_cost()
|
||||
bom_obj.db_update()
|
||||
|
||||
frappe.msgprint(_("BOM replaced"))
|
||||
|
||||
@@ -38,10 +41,18 @@ class BOMUpdateTool(Document):
|
||||
rate=%s, amount=stock_qty*%s where bom_no = %s and docstatus < 2 and parenttype='BOM'""",
|
||||
(self.new_bom, new_bom_unitcost, new_bom_unitcost, self.current_bom))
|
||||
|
||||
def get_parent_boms(self):
|
||||
return [d[0] for d in frappe.db.sql("""select distinct parent
|
||||
from `tabBOM Item` where ifnull(bom_no, '') = %s and docstatus < 2 and parenttype='BOM'""",
|
||||
self.new_bom)]
|
||||
def get_parent_boms(self, bom, bom_list=None):
|
||||
if not bom_list:
|
||||
bom_list = []
|
||||
|
||||
data = frappe.db.sql(""" select distinct parent from `tabBOM Item`
|
||||
where ifnull(bom_no, '') = %s and docstatus < 2 and parenttype='BOM'""", bom)
|
||||
|
||||
for d in data:
|
||||
bom_list.append(d[0])
|
||||
self.get_parent_boms(d[0], bom_list)
|
||||
|
||||
return bom_list
|
||||
|
||||
@frappe.whitelist()
|
||||
def enqueue_update_cost():
|
||||
|
||||
@@ -79,6 +79,10 @@ frappe.ui.form.on("Production Order", {
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
// formatter for production order operation
|
||||
frm.set_indicator_formatter('operation',
|
||||
function(doc) { return (frm.doc.qty==doc.completed_qty) ? "green" : "orange" });
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
@@ -94,10 +98,6 @@ frappe.ui.form.on("Production Order", {
|
||||
});
|
||||
erpnext.production_order.set_default_warehouse(frm);
|
||||
}
|
||||
|
||||
// formatter for production order operation
|
||||
frm.set_indicator_formatter('operation',
|
||||
function(doc) { return (frm.doc.qty==doc.completed_qty) ? "green" : "orange" });
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
|
||||
@@ -10,7 +10,6 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_per
|
||||
from erpnext.manufacturing.doctype.production_order.production_order \
|
||||
import make_stock_entry, ItemHasVariantError, stop_unstop
|
||||
from erpnext.stock.doctype.stock_entry import test_stock_entry
|
||||
from erpnext.stock.doctype.item.test_item import get_total_projected_qty
|
||||
from erpnext.stock.utils import get_bin
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||
|
||||
@@ -81,7 +80,7 @@ class TestProductionOrder(unittest.TestCase):
|
||||
prod_order.set_production_order_operations()
|
||||
prod_order.insert()
|
||||
prod_order.submit()
|
||||
|
||||
|
||||
d = prod_order.operations[0]
|
||||
d.completed_qty = flt(d.completed_qty)
|
||||
|
||||
@@ -89,7 +88,7 @@ class TestProductionOrder(unittest.TestCase):
|
||||
time_sheet_doc = frappe.get_doc('Timesheet', name)
|
||||
self.assertEqual(prod_order.company, time_sheet_doc.company)
|
||||
time_sheet_doc.submit()
|
||||
|
||||
|
||||
|
||||
self.assertEqual(prod_order.name, time_sheet_doc.production_order)
|
||||
self.assertEqual((prod_order.qty - d.completed_qty),
|
||||
@@ -108,7 +107,7 @@ class TestProductionOrder(unittest.TestCase):
|
||||
|
||||
self.assertEqual(prod_order.operations[0].actual_operation_time, 60)
|
||||
self.assertEqual(prod_order.operations[0].actual_operating_cost, 6000)
|
||||
|
||||
|
||||
time_sheet_doc1 = make_timesheet(prod_order.name, prod_order.company)
|
||||
self.assertEqual(len(time_sheet_doc1.get('time_logs')), 0)
|
||||
|
||||
@@ -176,28 +175,6 @@ class TestProductionOrder(unittest.TestCase):
|
||||
self.assertEqual(self.bin1_at_start.projected_qty,
|
||||
cint(bin1_on_cancel.projected_qty))
|
||||
|
||||
def test_projected_qty_for_production_and_sales_order(self):
|
||||
before_production_order = get_bin(self.item, self.warehouse)
|
||||
before_production_order.update_reserved_qty_for_production()
|
||||
|
||||
self.pro_order = make_prod_order_test_record(item="_Test FG Item", qty=2,
|
||||
source_warehouse=self.warehouse)
|
||||
|
||||
after_production_order = get_bin(self.item, self.warehouse)
|
||||
|
||||
sales_order = make_sales_order(item = self.item, qty = 2)
|
||||
after_sales_order = get_bin(self.item, self.warehouse)
|
||||
|
||||
self.assertEqual(cint(before_production_order.reserved_qty_for_production) + 2,
|
||||
cint(after_sales_order.reserved_qty_for_production))
|
||||
self.assertEqual(cint(before_production_order.projected_qty),
|
||||
cint(after_sales_order.projected_qty) + 2)
|
||||
|
||||
total_projected_qty = get_total_projected_qty(self.item)
|
||||
|
||||
item_doc = frappe.get_doc('Item', self.item)
|
||||
self.assertEqual(total_projected_qty, item_doc.total_projected_qty)
|
||||
|
||||
def test_reserved_qty_for_production_on_stock_entry(self):
|
||||
test_stock_entry.make_stock_entry(item_code="_Test Item",
|
||||
target= self.warehouse, qty=100, basic_rate=100)
|
||||
@@ -230,7 +207,7 @@ class TestProductionOrder(unittest.TestCase):
|
||||
cint(bin1_on_start_production.reserved_qty_for_production))
|
||||
self.assertEqual(cint(bin1_on_end_production.projected_qty),
|
||||
cint(bin1_on_end_production.projected_qty))
|
||||
|
||||
|
||||
def test_reserved_qty_for_stopped_production(self):
|
||||
test_stock_entry.make_stock_entry(item_code="_Test Item",
|
||||
target= self.warehouse, qty=100, basic_rate=100)
|
||||
@@ -238,18 +215,18 @@ class TestProductionOrder(unittest.TestCase):
|
||||
target= self.warehouse, qty=100, basic_rate=100)
|
||||
|
||||
# 0 0 0
|
||||
|
||||
|
||||
self.test_reserved_qty_for_production_submit()
|
||||
|
||||
|
||||
#2 0 -2
|
||||
|
||||
s = frappe.get_doc(make_stock_entry(self.pro_order.name,
|
||||
"Material Transfer for Manufacture", 1))
|
||||
|
||||
s.submit()
|
||||
|
||||
|
||||
#1 -1 0
|
||||
|
||||
|
||||
bin1_on_start_production = get_bin(self.item, self.warehouse)
|
||||
|
||||
# reserved_qty_for_producion updated
|
||||
@@ -259,10 +236,10 @@ class TestProductionOrder(unittest.TestCase):
|
||||
# projected qty will now be 2 less (becuase of item movement)
|
||||
self.assertEqual(cint(self.bin1_at_start.projected_qty),
|
||||
cint(bin1_on_start_production.projected_qty) + 2)
|
||||
|
||||
|
||||
# STOP
|
||||
stop_unstop(self.pro_order.name, "Stopped")
|
||||
|
||||
|
||||
bin1_on_stop_production = get_bin(self.item, self.warehouse)
|
||||
|
||||
# no change in reserved / projected
|
||||
|
||||
@@ -487,4 +487,11 @@ erpnext.patches.v10_0.set_numeric_ranges_in_template_if_blank
|
||||
erpnext.patches.v10_0.update_assessment_plan
|
||||
erpnext.patches.v10_0.update_assessment_result
|
||||
erpnext.patches.v10_0.set_default_payment_terms_based_on_company
|
||||
erpnext.patches.v10_0.update_sales_order_link_to_purchase_order
|
||||
erpnext.patches.v10_0.update_sales_order_link_to_purchase_order
|
||||
erpnext.patches.v10_0.added_extra_gst_custom_field_in_gstr2 #2018-02-13
|
||||
erpnext.patches.v10_0.set_b2c_limit
|
||||
erpnext.patches.v10_0.update_status_for_multiple_source_in_po
|
||||
erpnext.patches.v10_0.set_auto_created_serial_no_in_stock_entry
|
||||
erpnext.patches.v10_0.update_territory_and_customer_group
|
||||
erpnext.patches.v10_0.update_warehouse_address_details
|
||||
erpnext.patches.v10_0.update_reserved_qty_for_purchase_order
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import frappe
|
||||
from erpnext.regional.india.setup import make_custom_fields
|
||||
|
||||
def execute():
|
||||
company = frappe.get_all('Company', filters = {'country': 'India'})
|
||||
if not company:
|
||||
return
|
||||
|
||||
for doctype in ["Sales Invoice", "Delivery Note", "Purchase Invoice"]:
|
||||
frappe.db.sql("""delete from `tabCustom Field` where dt = %s
|
||||
and fieldname in ('port_code', 'shipping_bill_number', 'shipping_bill_date')""", doctype)
|
||||
|
||||
make_custom_fields()
|
||||
|
||||
frappe.db.sql("""
|
||||
update `tabCustom Field`
|
||||
set reqd = 0, `default` = ''
|
||||
where fieldname = 'reason_for_issuing_document'
|
||||
""")
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
# Copyright (c) 2017, Frappe and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
serialised_items = [d.name for d in frappe.get_all("Item", filters={"has_serial_no": 1})]
|
||||
|
||||
if not serialised_items:
|
||||
return
|
||||
|
||||
for dt in ["Stock Entry Detail", "Purchase Receipt Item", "Purchase Invoice Item"]:
|
||||
cond = ""
|
||||
if dt=="Purchase Invoice Item":
|
||||
cond = """ and parent in (select name from `tabPurchase Invoice`
|
||||
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.parent and update_stock=1)"""
|
||||
|
||||
item_rows = frappe.db.sql("""
|
||||
select name
|
||||
from `tab{0}`
|
||||
where conversion_factor != 1
|
||||
and docstatus = 1
|
||||
and ifnull(serial_no, '') = ''
|
||||
and item_code in ({1})
|
||||
{2}
|
||||
""".format(dt, ', '.join(['%s']*len(serialised_items)), cond), tuple(serialised_items))
|
||||
|
||||
if item_rows:
|
||||
sle_serial_nos = dict(frappe.db.sql("""
|
||||
select voucher_detail_no, serial_no
|
||||
from `tabStock Ledger Entry`
|
||||
where ifnull(serial_no, '') != ''
|
||||
and voucher_detail_no in (%s)
|
||||
""".format(', '.join(['%s']*len(item_rows))),
|
||||
tuple([d[0] for d in item_rows])))
|
||||
|
||||
batch_size = 100
|
||||
for i in range(0, len(item_rows), batch_size):
|
||||
batch_item_rows = item_rows[i:i + batch_size]
|
||||
when_then = []
|
||||
for item_row in batch_item_rows:
|
||||
|
||||
when_then.append('WHEN `name` = "{row_name}" THEN "{value}"'.format(
|
||||
row_name=item_row[0],
|
||||
value=sle_serial_nos.get(item_row[0])))
|
||||
|
||||
frappe.db.sql("""
|
||||
update
|
||||
`tab{doctype}`
|
||||
set
|
||||
serial_no = CASE {when_then_cond} ELSE `serial_no` END
|
||||
""".format(
|
||||
doctype = dt,
|
||||
when_then_cond=" ".join(when_then)
|
||||
))
|
||||
12
erpnext/patches/v10_0/set_b2c_limit.py
Normal file
12
erpnext/patches/v10_0/set_b2c_limit.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("regional", "doctype", "gst_settings")
|
||||
frappe.reload_doc("accounts", "doctype", "gst_account")
|
||||
gst_settings = frappe.get_doc("GST Settings")
|
||||
gst_settings.b2c_limit = 250000
|
||||
gst_settings.save()
|
||||
@@ -0,0 +1,52 @@
|
||||
import frappe
|
||||
from erpnext.stock.utils import get_bin
|
||||
|
||||
def execute():
|
||||
po_item = list(frappe.db.sql(("""
|
||||
select distinct po.name as poname, poitem.rm_item_code as rm_item_code, po.company
|
||||
from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitem
|
||||
where po.name = poitem.parent
|
||||
and po.is_subcontracted = "Yes"
|
||||
and po.docstatus = 1"""), as_dict=1))
|
||||
if not po_item:
|
||||
return
|
||||
|
||||
frappe.reload_doc("stock", "doctype", "bin")
|
||||
frappe.reload_doc("buying", "doctype", "purchase_order_item_supplied")
|
||||
company_warehouse = frappe._dict(frappe.db.sql("""select company, min(name) from `tabWarehouse`
|
||||
where is_group = 0 group by company"""))
|
||||
|
||||
items = list(set([d.rm_item_code for d in po_item]))
|
||||
item_wh = frappe._dict(frappe.db.sql("""select item_code, default_warehouse
|
||||
from `tabItem` where name in ({0})""".format(", ".join(["%s"] * len(items))), items))
|
||||
|
||||
# Update reserved warehouse
|
||||
for item in po_item:
|
||||
reserve_warehouse = get_warehouse(item.rm_item_code, item.company, company_warehouse, item_wh)
|
||||
frappe.db.sql("""update `tabPurchase Order Item Supplied`
|
||||
set reserve_warehouse = %s
|
||||
where parent = %s and rm_item_code = %s
|
||||
""", (reserve_warehouse, item["poname"], item["rm_item_code"]))
|
||||
|
||||
# Update bin
|
||||
item_wh_bin = frappe.db.sql(("""
|
||||
select distinct poitemsup.rm_item_code as rm_item_code,
|
||||
poitemsup.reserve_warehouse as reserve_warehouse
|
||||
from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitemsup
|
||||
where po.name = poitemsup.parent
|
||||
and po.is_subcontracted = "Yes"
|
||||
and po.docstatus = 1"""), as_dict=1)
|
||||
for d in item_wh_bin:
|
||||
try:
|
||||
stock_bin = get_bin(d["rm_item_code"], d["reserve_warehouse"])
|
||||
stock_bin.update_reserved_qty_for_sub_contracting()
|
||||
except:
|
||||
pass
|
||||
|
||||
def get_warehouse(item_code, company, company_warehouse, item_wh):
|
||||
reserve_warehouse = item_wh.get(item_code)
|
||||
if frappe.db.get_value("Warehouse", reserve_warehouse, "company") != company:
|
||||
reserve_warehouse = None
|
||||
if not reserve_warehouse:
|
||||
reserve_warehouse = company_warehouse.get(company)
|
||||
return reserve_warehouse
|
||||
@@ -0,0 +1,40 @@
|
||||
# Copyright (c) 2017, Frappe and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
|
||||
|
||||
# update the sales order item in the material request
|
||||
frappe.reload_doc('stock', 'doctype', 'material_request_item')
|
||||
frappe.db.sql('''update `tabMaterial Request Item` mri, `tabSales Order Item` soi
|
||||
set mri.sales_order_item = soi.name
|
||||
where ifnull(mri.sales_order, "")!="" and soi.parent=mri.sales_order
|
||||
and soi.item_code=mri.item_code and mri.docstatus=1
|
||||
''')
|
||||
|
||||
# update the sales order item in the purchase order
|
||||
frappe.db.sql('''update `tabPurchase Order Item` poi, `tabSales Order Item` soi
|
||||
set poi.sales_order_item = soi.name
|
||||
where ifnull(poi.sales_order, "")!="" and soi.parent=poi.sales_order
|
||||
and soi.item_code=poi.item_code and poi.docstatus = 1
|
||||
''')
|
||||
|
||||
# Update the status in material request and sales order
|
||||
po_list = frappe.db.sql('''
|
||||
select parent from `tabPurchase Order Item` where ifnull(material_request, "")!="" and
|
||||
ifnull(sales_order, "")!="" and docstatus=1
|
||||
''',as_dict=1)
|
||||
|
||||
for po in list(set([d.get("parent") for d in po_list if d.get("parent")])):
|
||||
try:
|
||||
po_doc = frappe.get_doc("Purchase Order", po)
|
||||
|
||||
# update the so in the status updater
|
||||
po_doc.update_status_updater()
|
||||
po_doc.update_qty(update_modified=False)
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
29
erpnext/patches/v10_0/update_territory_and_customer_group.py
Normal file
29
erpnext/patches/v10_0/update_territory_and_customer_group.py
Normal file
@@ -0,0 +1,29 @@
|
||||
import frappe
|
||||
from frappe.model.rename_doc import get_fetch_fields
|
||||
|
||||
def execute():
|
||||
ignore_doctypes = ["Lead", "Opportunity", "POS Profile", "Tax Rule", "Pricing Rule"]
|
||||
customers = frappe.get_all('Customer', fields=["name", "customer_group"])
|
||||
|
||||
customer_group_fetch = get_fetch_fields('Customer', 'Customer Group', ignore_doctypes)
|
||||
|
||||
batch_size = 1000
|
||||
for i in range(0, len(customers), batch_size):
|
||||
batch_customers = customers[i:i + batch_size]
|
||||
for d in customer_group_fetch:
|
||||
when_then = []
|
||||
for customer in batch_customers:
|
||||
value = frappe.db.escape(frappe.as_unicode(customer.get("customer_group")))
|
||||
|
||||
when_then.append('''
|
||||
WHEN `%s` = "%s" and %s != "%s"
|
||||
THEN "%s"
|
||||
'''%(d["master_fieldname"], frappe.db.escape(frappe.as_unicode(customer.name)),
|
||||
d["linked_to_fieldname"], value, value))
|
||||
|
||||
frappe.db.sql("""
|
||||
update
|
||||
`tab%s`
|
||||
set
|
||||
%s = CASE %s ELSE `%s` END
|
||||
"""%(d['doctype'], d.linked_to_fieldname, " ".join(when_then), d.linked_to_fieldname))
|
||||
37
erpnext/patches/v10_0/update_warehouse_address_details.py
Normal file
37
erpnext/patches/v10_0/update_warehouse_address_details.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# Copyright (c) 2017, Frappe and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
warehouse = frappe.db.sql("""select name, email_id, phone_no, mobile_no, address_line_1,
|
||||
address_line_2, city, state, pin from `tabWarehouse` where ifnull(address_line_1, '') != ''
|
||||
or ifnull(mobile_no, '') != ''
|
||||
or ifnull(email_id, '') != '' """, as_dict=1)
|
||||
|
||||
for d in warehouse:
|
||||
try:
|
||||
address = frappe.new_doc('Address')
|
||||
address.name = d.name
|
||||
address.address_title = d.name
|
||||
address.address_line1 = d.address_line_1
|
||||
address.city = d.city
|
||||
address.state = d.state
|
||||
address.pincode = d.pin
|
||||
address.db_insert()
|
||||
address.append('links',{'link_doctype':'Warehouse','link_name':d.name})
|
||||
address.links[0].db_insert()
|
||||
if d.name and (d.email_id or d.mobile_no or d.phone_no):
|
||||
contact = frappe.new_doc('Contact')
|
||||
contact.name = d.name
|
||||
contact.first_name = d.name
|
||||
contact.mobile_no = d.mobile_no
|
||||
contact.email_id = d.email_id
|
||||
contact.phone = d.phone_no
|
||||
contact.db_insert()
|
||||
contact.append('links',{'link_doctype':'Warehouse','link_name':d.name})
|
||||
contact.links[0].db_insert()
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
@@ -10,6 +10,7 @@ def execute():
|
||||
frappe.reload_doctype("Purchase Receipt")
|
||||
frappe.reload_doctype("Sales Order Item")
|
||||
frappe.reload_doctype("Purchase Order Item")
|
||||
frappe.reload_doctype("Purchase Order Item Supplied")
|
||||
|
||||
# sales return
|
||||
return_entries = list(frappe.db.sql("""
|
||||
@@ -86,6 +87,6 @@ def execute():
|
||||
""", (order_details[0].purchase_order, order_details[0].po_detail, d.row_id))
|
||||
|
||||
pr = frappe.get_doc("Purchase Receipt", d.name)
|
||||
pr.update_ordered_qty()
|
||||
pr.update_ordered_and_reserved_qty()
|
||||
pr.update_prevdoc_status()
|
||||
|
||||
|
||||
@@ -3,26 +3,13 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from erpnext.stock.doctype.bin.bin import update_item_projected_qty
|
||||
|
||||
def execute():
|
||||
repost_bin_qty()
|
||||
repost_item_projected_qty()
|
||||
|
||||
def repost_bin_qty():
|
||||
for bin in frappe.db.sql(""" select name from `tabBin`
|
||||
for bin in frappe.db.sql(""" select name from `tabBin`
|
||||
where (actual_qty + ordered_qty + indented_qty + planned_qty- reserved_qty - reserved_qty_for_production) != projected_qty """, as_dict=1):
|
||||
bin_doc = frappe.get_doc('Bin', bin.name)
|
||||
bin_doc.set_projected_qty()
|
||||
bin_doc.db_set("projected_qty", bin_doc.projected_qty, update_modified = False)
|
||||
|
||||
def repost_item_projected_qty():
|
||||
for data in frappe.db.sql(""" select
|
||||
`tabBin`.item_code as item_code,
|
||||
sum(`tabBin`.projected_qty) as projected_qty,
|
||||
`tabItem`.total_projected_qty as total_projected_qty
|
||||
from
|
||||
`tabBin`, `tabItem`
|
||||
where `tabBin`.item_code = `tabItem`.name
|
||||
group by `tabBin`.item_code having projected_qty <> total_projected_qty """, as_dict=1):
|
||||
update_item_projected_qty(data.item_code)
|
||||
|
||||
@@ -156,14 +156,18 @@ class Timesheet(Document):
|
||||
(self.production_order, operation_id), as_dict=1)[0]
|
||||
|
||||
def update_task_and_project(self):
|
||||
tasks, projects = [], []
|
||||
|
||||
for data in self.time_logs:
|
||||
if data.task:
|
||||
if data.task and data.task not in tasks:
|
||||
task = frappe.get_doc("Task", data.task)
|
||||
task.update_time_and_costing()
|
||||
task.save()
|
||||
tasks.append(data.task)
|
||||
|
||||
elif data.project:
|
||||
elif data.project and data.project not in projects:
|
||||
frappe.get_doc("Project", data.project).update_project()
|
||||
projects.append(data.project)
|
||||
|
||||
def validate_dates(self):
|
||||
for data in self.time_logs:
|
||||
@@ -286,7 +290,7 @@ def get_projectwise_timesheet_data(project, parent=None):
|
||||
cond = "and parent = %(parent)s"
|
||||
|
||||
return frappe.db.sql("""select name, parent, billing_hours, billing_amount as billing_amt
|
||||
from `tabTimesheet Detail` where docstatus=1 and project = %(project)s {0} and billable = 1
|
||||
from `tabTimesheet Detail` where parenttype = 'Timesheet' and docstatus=1 and project = %(project)s {0} and billable = 1
|
||||
and sales_invoice is null""".format(cond), {'project': project, 'parent': parent}, as_dict=1)
|
||||
|
||||
@frappe.whitelist()
|
||||
|
||||
@@ -92,7 +92,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
item.amount = flt(item.rate * item.qty, precision("amount", item));
|
||||
item.net_amount = item.amount;
|
||||
item.item_tax_amount = 0.0;
|
||||
item.total_weight = flt(item.weight_per_unit * item.qty);
|
||||
item.total_weight = flt(item.weight_per_unit * item.stock_qty);
|
||||
|
||||
me.set_in_company_currency(item, ["price_list_rate", "rate", "amount", "net_rate", "net_amount"]);
|
||||
});
|
||||
|
||||
@@ -458,7 +458,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
}
|
||||
|
||||
var party = me.frm.doc[frappe.model.scrub(party_type)];
|
||||
if(party) {
|
||||
if(party && me.frm.doc.company) {
|
||||
return frappe.call({
|
||||
method: "erpnext.accounts.party.get_party_account",
|
||||
args: {
|
||||
@@ -704,7 +704,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
}
|
||||
|
||||
if(!this.in_apply_price_list) {
|
||||
this.apply_price_list();
|
||||
this.apply_price_list(null, true);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -776,7 +776,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
this.frm.toggle_reqd("plc_conversion_rate",
|
||||
!!(this.frm.doc.price_list_name && this.frm.doc.price_list_currency));
|
||||
|
||||
if(this.frm.doc_currency!==this.frm.doc.currency) {
|
||||
if(this.frm.doc_currency!==this.frm.doc.currency
|
||||
|| this.frm.doc_currency!==this.frm.doc.price_list_currency) {
|
||||
// reset names only when the currency is different
|
||||
|
||||
var company_currency = this.get_company_currency();
|
||||
@@ -1056,7 +1057,13 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
if(!price_list_rate_changed) me.calculate_taxes_and_totals();
|
||||
},
|
||||
|
||||
apply_price_list: function(item) {
|
||||
apply_price_list: function(item, reset_plc_conversion) {
|
||||
// We need to reset plc_conversion_rate sometimes because the call to
|
||||
// `erpnext.stock.get_item_details.apply_price_list` is sensitive to its value
|
||||
if (!reset_plc_conversion) {
|
||||
this.frm.set_value("plc_conversion_rate", "");
|
||||
}
|
||||
|
||||
var me = this;
|
||||
var args = this._get_args(item);
|
||||
if (!((args.items && args.items.length) || args.price_list)) {
|
||||
|
||||
@@ -37,20 +37,22 @@
|
||||
<div class="cell price-cell text-right tax-table">
|
||||
</div>
|
||||
</div>
|
||||
<div class="pos-list-row discount-amount-area">
|
||||
<div class="cell"></div>
|
||||
<div class="cell text-right">{%= __("Discount") %}</div>
|
||||
<div class="cell price-cell discount-field-col">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">%</span>
|
||||
<input type="text" class="form-control discount-percentage text-right">
|
||||
</div>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">{%= get_currency_symbol(currency) %}</span>
|
||||
<input type="text" class="form-control discount-amount text-right" placeholder="{%= 0.00 %}">
|
||||
{% if(allow_user_to_edit_discount) { %}
|
||||
<div class="pos-list-row discount-amount-area">
|
||||
<div class="cell"></div>
|
||||
<div class="cell text-right">{%= __("Discount") %}</div>
|
||||
<div class="cell price-cell discount-field-col">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">%</span>
|
||||
<input type="text" class="form-control discount-percentage text-right">
|
||||
</div>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">{%= get_currency_symbol(currency) %}</span>
|
||||
<input type="text" class="form-control discount-amount text-right" placeholder="{%= 0.00 %}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% } %}
|
||||
<div class="pos-list-row grand-total-area collapse-btn" style="border-bottom:1px solid #d1d8dd;">
|
||||
<div class="cell">
|
||||
<a class="">
|
||||
@@ -71,7 +73,7 @@
|
||||
{% for(var j=i*3; j
|
||||
<(i+1)*3; j++) { %} <button type="button" class="btn btn-default numeric-keypad" val="{{j+1}}">{{j+1}}</button>
|
||||
{% } %}
|
||||
<button type="button" {% if(!allow_user_to_edit_rate && chartData[i] == __("Price")) { %} disabled {% } %} id="pos-item-{{ chartData[i].toLowerCase() }}" class="btn text-center btn-default numeric-keypad pos-operation">{{ __(chartData[i]) }}</button>
|
||||
<button type="button" {% if((!allow_user_to_edit_rate && chartData[i] == __("Price")) || (!allow_user_to_edit_discount && chartData[i] == __("Disc"))) { %} disabled {% } %} id="pos-item-{{ chartData[i].toLowerCase() }}" class="btn text-center btn-default numeric-keypad pos-operation">{{ __(chartData[i]) }}</button>
|
||||
</div>
|
||||
{% } %}
|
||||
<div class="row text-right">
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user