Merge branch 'develop' into multi-barcode
This commit is contained in:
commit
76dddbf26e
@ -5,7 +5,7 @@ import frappe
|
|||||||
from erpnext.hooks import regional_overrides
|
from erpnext.hooks import regional_overrides
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
|
|
||||||
__version__ = '9.2.21'
|
__version__ = '10.0.7'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
@ -53,14 +53,12 @@ class Account(NestedSet):
|
|||||||
def set_root_and_report_type(self):
|
def set_root_and_report_type(self):
|
||||||
if self.parent_account:
|
if self.parent_account:
|
||||||
par = frappe.db.get_value("Account", self.parent_account,
|
par = frappe.db.get_value("Account", self.parent_account,
|
||||||
["report_type", "root_type", "account_type"], as_dict=1)
|
["report_type", "root_type"], as_dict=1)
|
||||||
|
|
||||||
if par.report_type:
|
if par.report_type:
|
||||||
self.report_type = par.report_type
|
self.report_type = par.report_type
|
||||||
if par.root_type:
|
if par.root_type:
|
||||||
self.root_type = par.root_type
|
self.root_type = par.root_type
|
||||||
if par.account_type and not self.account_type:
|
|
||||||
self.account_type = par.account_type
|
|
||||||
|
|
||||||
if self.is_group:
|
if self.is_group:
|
||||||
db_value = frappe.db.get_value("Account", self.name, ["report_type", "root_type"], as_dict=1)
|
db_value = frappe.db.get_value("Account", self.name, ["report_type", "root_type"], as_dict=1)
|
||||||
@ -165,16 +163,16 @@ class Account(NestedSet):
|
|||||||
if self.check_gle_exists():
|
if self.check_gle_exists():
|
||||||
throw(_("Account with existing transaction can not be deleted"))
|
throw(_("Account with existing transaction can not be deleted"))
|
||||||
|
|
||||||
super(Account, self).on_trash()
|
super(Account, self).on_trash(True)
|
||||||
|
|
||||||
def before_rename(self, old, new, merge=False):
|
def before_rename(self, old, new, merge=False):
|
||||||
# Add company abbr if not provided
|
# Add company abbr if not provided
|
||||||
from erpnext.setup.doctype.company.company import get_name_with_abbr
|
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_abbr(new, self.company)
|
||||||
new_account = get_name_with_number(new_account, self.account_number)
|
if not merge:
|
||||||
|
new_account = get_name_with_number(new_account, self.account_number)
|
||||||
# Validate properties before merging
|
else:
|
||||||
if merge:
|
# Validate properties before merging
|
||||||
if not frappe.db.exists("Account", new):
|
if not frappe.db.exists("Account", new):
|
||||||
throw(_("Account {0} does not exist").format(new))
|
throw(_("Account {0} does not exist").format(new))
|
||||||
|
|
||||||
|
@ -79,15 +79,17 @@ frappe.treeview_settings["Account"] = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
onrender: function(node) {
|
onrender: function(node) {
|
||||||
var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr";
|
if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){
|
||||||
if (node.data && node.data.balance!==undefined) {
|
var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr";
|
||||||
$('<span class="balance-area pull-right text-muted small">'
|
if (node.data && node.data.balance!==undefined) {
|
||||||
+ (node.data.balance_in_account_currency ?
|
$('<span class="balance-area pull-right text-muted small">'
|
||||||
(format_currency(Math.abs(node.data.balance_in_account_currency),
|
+ (node.data.balance_in_account_currency ?
|
||||||
node.data.account_currency) + " / ") : "")
|
(format_currency(Math.abs(node.data.balance_in_account_currency),
|
||||||
+ format_currency(Math.abs(node.data.balance), node.data.company_currency)
|
node.data.account_currency) + " / ") : "")
|
||||||
+ " " + dr_or_cr
|
+ format_currency(Math.abs(node.data.balance), node.data.company_currency)
|
||||||
+ '</span>').insertBefore(node.$ul);
|
+ " " + dr_or_cr
|
||||||
|
+ '</span>').insertBefore(node.$ul);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toolbar: [
|
toolbar: [
|
||||||
|
@ -52,6 +52,7 @@ def _make_test_records(verbose):
|
|||||||
["_Test Account Customs Duty", "_Test Account Stock Expenses", 0, "Tax", None],
|
["_Test Account Customs Duty", "_Test Account Stock Expenses", 0, "Tax", None],
|
||||||
["_Test Account Insurance Charges", "_Test Account Stock Expenses", 0, "Chargeable", None],
|
["_Test Account Insurance Charges", "_Test Account Stock Expenses", 0, "Chargeable", None],
|
||||||
["_Test Account Stock Adjustment", "_Test Account Stock Expenses", 0, "Stock Adjustment", None],
|
["_Test Account Stock Adjustment", "_Test Account Stock Expenses", 0, "Stock Adjustment", None],
|
||||||
|
["_Test Employee Advance", "Current Liabilities", 0, None, None],
|
||||||
|
|
||||||
["_Test Account Tax Assets", "Current Assets", 1, None, None],
|
["_Test Account Tax Assets", "Current Assets", 1, None, None],
|
||||||
["_Test Account VAT", "_Test Account Tax Assets", 0, "Tax", None],
|
["_Test Account VAT", "_Test Account Tax Assets", 0, "Tax", None],
|
||||||
|
@ -287,6 +287,125 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "print_settings",
|
||||||
|
"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": "Print Settings",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "show_inclusive_tax_in_print",
|
||||||
|
"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": "Show Inclusive Tax In Print",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "column_break_12",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "show_payment_schedule_in_print",
|
||||||
|
"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": "Show Payment Schedule in Print",
|
||||||
|
"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,
|
"allow_on_submit": 0,
|
||||||
@ -392,7 +511,7 @@
|
|||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-09-05 10:10:03.117505",
|
"modified": "2018-01-05 15:26:10.357085",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
@ -417,7 +536,7 @@
|
|||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
"submit": 0,
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
"apply_user_permissions": 0,
|
"apply_user_permissions": 0,
|
||||||
@ -437,7 +556,7 @@
|
|||||||
"share": 0,
|
"share": 0,
|
||||||
"submit": 0,
|
"submit": 0,
|
||||||
"write": 0
|
"write": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
"apply_user_permissions": 0,
|
"apply_user_permissions": 0,
|
||||||
@ -466,4 +585,4 @@
|
|||||||
"sort_order": "ASC",
|
"sort_order": "ASC",
|
||||||
"track_changes": 1,
|
"track_changes": 1,
|
||||||
"track_seen": 0
|
"track_seen": 0
|
||||||
}
|
}
|
@ -7,6 +7,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import cint
|
from frappe.utils import cint
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
|
||||||
|
|
||||||
|
|
||||||
class AccountsSettings(Document):
|
class AccountsSettings(Document):
|
||||||
@ -15,6 +16,7 @@ class AccountsSettings(Document):
|
|||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_stale_days()
|
self.validate_stale_days()
|
||||||
|
self.enable_payment_schedule_in_print()
|
||||||
|
|
||||||
def validate_stale_days(self):
|
def validate_stale_days(self):
|
||||||
if not self.allow_stale and cint(self.stale_days) <= 0:
|
if not self.allow_stale and cint(self.stale_days) <= 0:
|
||||||
@ -22,3 +24,8 @@ class AccountsSettings(Document):
|
|||||||
"Stale Days should start from 1.", title='Error', indicator='red',
|
"Stale Days should start from 1.", title='Error', indicator='red',
|
||||||
raise_exception=1)
|
raise_exception=1)
|
||||||
|
|
||||||
|
def enable_payment_schedule_in_print(self):
|
||||||
|
show_in_print = cint(self.show_payment_schedule_in_print)
|
||||||
|
for doctype in ("Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"):
|
||||||
|
make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check")
|
||||||
|
make_property_setter(doctype, "payment_schedule", "print_hide", 0 if show_in_print else 1, "Check")
|
@ -74,36 +74,6 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "due_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Due 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,
|
"allow_on_submit": 0,
|
||||||
@ -748,7 +718,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-08-10 18:06:44.904081",
|
"modified": "2017-12-20 12:40:09.611951",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "GL Entry",
|
"name": "GL Entry",
|
||||||
@ -824,4 +794,4 @@
|
|||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 0,
|
"track_changes": 0,
|
||||||
"track_seen": 0
|
"track_seen": 0
|
||||||
}
|
}
|
||||||
|
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
|
@ -124,6 +124,15 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(jvd.reference_type==="Employee Advance") {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
'status': ['=', 'Unpaid'],
|
||||||
|
'docstatus': 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// journal entry
|
// journal entry
|
||||||
if(jvd.reference_type==="Journal Entry") {
|
if(jvd.reference_type==="Journal Entry") {
|
||||||
frappe.model.validate_missing(jvd, "account");
|
frappe.model.validate_missing(jvd, "account");
|
||||||
@ -185,56 +194,21 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
due_date_options_cache: {},
|
|
||||||
|
|
||||||
reference_name: function(doc, cdt, cdn) {
|
reference_name: function(doc, cdt, cdn) {
|
||||||
var d = frappe.get_doc(cdt, cdn);
|
var d = frappe.get_doc(cdt, cdn);
|
||||||
var me = this;
|
|
||||||
|
|
||||||
const get_invoice_due_dates = invoice_name => {
|
|
||||||
const options = this.due_date_options_cache[invoice_name];
|
|
||||||
const input = $(cur_frm.fields_dict["accounts"].wrapper).find("select[data-fieldname=reference_due_date]");
|
|
||||||
|
|
||||||
if (options) {
|
|
||||||
input.empty();
|
|
||||||
input.add_options(options);
|
|
||||||
frappe.model.set_value(cdt, cdn, "reference_due_date", options[0]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
frappe.call({
|
|
||||||
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_invoice_due_dates",
|
|
||||||
args: {name: invoice_name},
|
|
||||||
callback: function(r) {
|
|
||||||
const options = [];
|
|
||||||
$.each(r.message, function(key, value) {
|
|
||||||
options.push(value.due_date);
|
|
||||||
});
|
|
||||||
input.empty();
|
|
||||||
input.add_options(options);
|
|
||||||
frappe.model.set_value(cdt, cdn, "reference_due_date", options[0]);
|
|
||||||
me.due_date_options_cache[d.reference_name] = options;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(d.reference_name) {
|
if(d.reference_name) {
|
||||||
if (d.reference_type==="Purchase Invoice" && !flt(d.debit)) {
|
if (d.reference_type==="Purchase Invoice" && !flt(d.debit)) {
|
||||||
this.get_outstanding('Purchase Invoice', d.reference_name, doc.company, d);
|
this.get_outstanding('Purchase Invoice', d.reference_name, doc.company, d);
|
||||||
}
|
} else if (d.reference_type==="Sales Invoice" && !flt(d.credit)) {
|
||||||
if (d.reference_type==="Sales Invoice" && !flt(d.credit)) {
|
|
||||||
this.get_outstanding('Sales Invoice', d.reference_name, doc.company, d);
|
this.get_outstanding('Sales Invoice', d.reference_name, doc.company, d);
|
||||||
}
|
} else if (d.reference_type==="Journal Entry" && !flt(d.credit) && !flt(d.debit)) {
|
||||||
if (d.reference_type==="Journal Entry" && !flt(d.credit) && !flt(d.debit)) {
|
|
||||||
this.get_outstanding('Journal Entry', d.reference_name, doc.company, d);
|
this.get_outstanding('Journal Entry', d.reference_name, doc.company, d);
|
||||||
}
|
}
|
||||||
if( in_list(["Sales Invoice", "Purchase Invoice"]), d.reference_type) {
|
|
||||||
get_invoice_due_dates(d.reference_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
get_outstanding: function(doctype, docname, company, child) {
|
get_outstanding: function(doctype, docname, company, child, due_date) {
|
||||||
var me = this;
|
var me = this;
|
||||||
var args = {
|
var args = {
|
||||||
"doctype": doctype,
|
"doctype": doctype,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, erpnext, json
|
import frappe, erpnext, json
|
||||||
from frappe.utils import cstr, flt, fmt_money, formatdate
|
from frappe.utils import cstr, flt, fmt_money, formatdate, getdate
|
||||||
from frappe import msgprint, _, scrub
|
from frappe import msgprint, _, scrub
|
||||||
from erpnext.controllers.accounts_controller import AccountsController
|
from erpnext.controllers.accounts_controller import AccountsController
|
||||||
from erpnext.accounts.utils import get_balance_on, get_account_currency
|
from erpnext.accounts.utils import get_balance_on, get_account_currency
|
||||||
@ -54,8 +54,8 @@ class JournalEntry(AccountsController):
|
|||||||
def update_advance_paid(self):
|
def update_advance_paid(self):
|
||||||
advance_paid = frappe._dict()
|
advance_paid = frappe._dict()
|
||||||
for d in self.get("accounts"):
|
for d in self.get("accounts"):
|
||||||
if d.is_advance == "Yes":
|
if d.is_advance:
|
||||||
if d.reference_type in ("Sales Order", "Purchase Order"):
|
if d.reference_type in ("Sales Order", "Purchase Order", "Employee Advance"):
|
||||||
advance_paid.setdefault(d.reference_type, []).append(d.reference_name)
|
advance_paid.setdefault(d.reference_type, []).append(d.reference_name)
|
||||||
|
|
||||||
for voucher_type, order_list in advance_paid.items():
|
for voucher_type, order_list in advance_paid.items():
|
||||||
@ -101,8 +101,6 @@ class JournalEntry(AccountsController):
|
|||||||
if account_type in ["Receivable", "Payable"]:
|
if account_type in ["Receivable", "Payable"]:
|
||||||
if not (d.party_type and d.party):
|
if not (d.party_type and d.party):
|
||||||
frappe.throw(_("Row {0}: Party Type and Party is required for Receivable / Payable account {1}").format(d.idx, d.account))
|
frappe.throw(_("Row {0}: Party Type and Party is required for Receivable / Payable account {1}").format(d.idx, d.account))
|
||||||
elif d.party_type and d.party:
|
|
||||||
frappe.throw(_("Row {0}: Party Type and Party is only applicable against Receivable / Payable account").format(d.idx))
|
|
||||||
|
|
||||||
def check_credit_limit(self):
|
def check_credit_limit(self):
|
||||||
customers = list(set([d.party for d in self.get("accounts")
|
customers = list(set([d.party for d in self.get("accounts")
|
||||||
@ -436,8 +434,7 @@ class JournalEntry(AccountsController):
|
|||||||
"against_voucher": d.reference_name,
|
"against_voucher": d.reference_name,
|
||||||
"remarks": self.remark,
|
"remarks": self.remark,
|
||||||
"cost_center": d.cost_center,
|
"cost_center": d.cost_center,
|
||||||
"project": d.project,
|
"project": d.project
|
||||||
"due_date": d.reference_due_date
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -649,9 +646,8 @@ def get_payment_entry_against_invoice(dt, dn, amount=None, debit_in_account_cur
|
|||||||
party_type = "Supplier"
|
party_type = "Supplier"
|
||||||
party_account = ref_doc.credit_to
|
party_account = ref_doc.credit_to
|
||||||
|
|
||||||
|
if (dt == "Sales Invoice" and ref_doc.outstanding_amount > 0) \
|
||||||
if (dt=="Sales Invoice" and ref_doc.outstanding_amount > 0) \
|
or (dt == "Purchase Invoice" and ref_doc.outstanding_amount < 0):
|
||||||
or (dt=="Purchase Invoice" and ref_doc.outstanding_amount < 0):
|
|
||||||
amount_field_party = "credit_in_account_currency"
|
amount_field_party = "credit_in_account_currency"
|
||||||
amount_field_bank = "debit_in_account_currency"
|
amount_field_bank = "debit_in_account_currency"
|
||||||
else:
|
else:
|
||||||
@ -672,6 +668,7 @@ def get_payment_entry_against_invoice(dt, dn, amount=None, debit_in_account_cur
|
|||||||
"journal_entry": journal_entry
|
"journal_entry": journal_entry
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def get_payment_entry(ref_doc, args):
|
def get_payment_entry(ref_doc, args):
|
||||||
cost_center = frappe.db.get_value("Company", ref_doc.company, "cost_center")
|
cost_center = frappe.db.get_value("Company", ref_doc.company, "cost_center")
|
||||||
exchange_rate = 1
|
exchange_rate = 1
|
||||||
@ -696,7 +693,7 @@ def get_payment_entry(ref_doc, args):
|
|||||||
"cost_center": cost_center,
|
"cost_center": cost_center,
|
||||||
"account_type": frappe.db.get_value("Account", args.get("party_account"), "account_type"),
|
"account_type": frappe.db.get_value("Account", args.get("party_account"), "account_type"),
|
||||||
"account_currency": args.get("party_account_currency") or \
|
"account_currency": args.get("party_account_currency") or \
|
||||||
get_account_currency(args.get("party_account")),
|
get_account_currency(args.get("party_account")),
|
||||||
"balance": get_balance_on(args.get("party_account")),
|
"balance": get_balance_on(args.get("party_account")),
|
||||||
"party_balance": get_balance_on(party=args.get("party"), party_type=args.get("party_type")),
|
"party_balance": get_balance_on(party=args.get("party"), party_type=args.get("party_type")),
|
||||||
"exchange_rate": exchange_rate,
|
"exchange_rate": exchange_rate,
|
||||||
@ -708,7 +705,7 @@ def get_payment_entry(ref_doc, args):
|
|||||||
|
|
||||||
bank_row = je.append("accounts")
|
bank_row = je.append("accounts")
|
||||||
|
|
||||||
#make it bank_details
|
# Make it bank_details
|
||||||
bank_account = get_default_bank_cash_account(ref_doc.company, "Bank", account=args.get("bank_account"))
|
bank_account = get_default_bank_cash_account(ref_doc.company, "Bank", account=args.get("bank_account"))
|
||||||
if bank_account:
|
if bank_account:
|
||||||
bank_row.update(bank_account)
|
bank_row.update(bank_account)
|
||||||
@ -727,7 +724,7 @@ def get_payment_entry(ref_doc, args):
|
|||||||
else:
|
else:
|
||||||
bank_row.set(args.get("amount_field_bank"), amount * exchange_rate)
|
bank_row.set(args.get("amount_field_bank"), amount * exchange_rate)
|
||||||
|
|
||||||
# set multi currency check
|
# Multi currency check again
|
||||||
if party_row.account_currency != ref_doc.company_currency \
|
if party_row.account_currency != ref_doc.company_currency \
|
||||||
or (bank_row.account_currency and bank_row.account_currency != ref_doc.company_currency):
|
or (bank_row.account_currency and bank_row.account_currency != ref_doc.company_currency):
|
||||||
je.multi_currency = 1
|
je.multi_currency = 1
|
||||||
@ -737,6 +734,7 @@ def get_payment_entry(ref_doc, args):
|
|||||||
|
|
||||||
return je if args.get("journal_entry") else je.as_dict()
|
return je if args.get("journal_entry") else je.as_dict()
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_opening_accounts(company):
|
def get_opening_accounts(company):
|
||||||
"""get all balance sheet accounts for opening entry"""
|
"""get all balance sheet accounts for opening entry"""
|
||||||
@ -759,6 +757,7 @@ def get_against_jv(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
and jv.docstatus = 1 and jv.`{0}` like %s order by jv.name desc limit %s, %s""".format(frappe.db.escape(searchfield)),
|
and jv.docstatus = 1 and jv.`{0}` like %s order by jv.name desc limit %s, %s""".format(frappe.db.escape(searchfield)),
|
||||||
(filters.get("account"), cstr(filters.get("party")), "%{0}%".format(txt), start, page_len))
|
(filters.get("account"), cstr(filters.get("party")), "%{0}%".format(txt), start, page_len))
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_outstanding(args):
|
def get_outstanding(args):
|
||||||
if not frappe.has_permission("Account"):
|
if not frappe.has_permission("Account"):
|
||||||
@ -820,6 +819,7 @@ def get_party_account_and_balance(company, party_type, party):
|
|||||||
"account_currency": frappe.db.get_value("Account", account, "account_currency")
|
"account_currency": frappe.db.get_value("Account", account, "account_currency")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None):
|
def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None):
|
||||||
"""Returns dict of account balance and party type to be set in Journal Entry on selection of account."""
|
"""Returns dict of account balance and party type to be set in Journal Entry on selection of account."""
|
||||||
@ -857,7 +857,7 @@ def get_account_balance_and_party_type(account, date, company, debit=None, credi
|
|||||||
|
|
||||||
return grid_values
|
return grid_values
|
||||||
|
|
||||||
# Added posting_date as one of the parameters of get_exchange_rate
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_exchange_rate(posting_date, account=None, account_currency=None, company=None,
|
def get_exchange_rate(posting_date, account=None, account_currency=None, company=None,
|
||||||
reference_type=None, reference_name=None, debit=None, credit=None, exchange_rate=None):
|
reference_type=None, reference_name=None, debit=None, credit=None, exchange_rate=None):
|
||||||
@ -890,6 +890,7 @@ def get_exchange_rate(posting_date, account=None, account_currency=None, company
|
|||||||
# don't return None or 0 as it is multipled with a value and that value could be lost
|
# don't return None or 0 as it is multipled with a value and that value could be lost
|
||||||
return exchange_rate or 1
|
return exchange_rate or 1
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_average_exchange_rate(account):
|
def get_average_exchange_rate(account):
|
||||||
exchange_rate = 0
|
exchange_rate = 0
|
||||||
@ -898,15 +899,4 @@ def get_average_exchange_rate(account):
|
|||||||
bank_balance_in_company_currency = get_balance_on(account, in_account_currency=False)
|
bank_balance_in_company_currency = get_balance_on(account, in_account_currency=False)
|
||||||
exchange_rate = bank_balance_in_company_currency / bank_balance_in_account_currency
|
exchange_rate = bank_balance_in_company_currency / bank_balance_in_account_currency
|
||||||
|
|
||||||
return exchange_rate
|
return exchange_rate
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def get_invoice_due_dates(name):
|
|
||||||
result = frappe.get_list(
|
|
||||||
doctype='GL Entry', group_by='name, due_date',
|
|
||||||
filters={'voucher_no': name, "ifnull(due_date, '')": ('!=', '')},
|
|
||||||
fields=['due_date'], distinct=True
|
|
||||||
)
|
|
||||||
|
|
||||||
return result
|
|
@ -618,7 +618,7 @@
|
|||||||
"label": "Reference Type",
|
"label": "Reference Type",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nEmployee Loan\nPayroll Entry",
|
"options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nEmployee Loan\nPayroll Entry\nEmployee Advance",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@ -661,39 +661,7 @@
|
|||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:doc.reference_type&&!in_list(doc.reference_type, ['Expense Claim', 'Asset', 'Employee Loan'])",
|
|
||||||
"fieldname": "reference_due_date",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Reference Due Date",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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,
|
"allow_on_submit": 0,
|
||||||
@ -827,7 +795,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-12-06 19:54:19.851534",
|
"modified": "2017-12-07 19:54:19.851534",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Journal Entry Account",
|
"name": "Journal Entry Account",
|
||||||
|
@ -4,10 +4,11 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _, scrub
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt, nowdate
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
|
||||||
class OpeningInvoiceCreationTool(Document):
|
class OpeningInvoiceCreationTool(Document):
|
||||||
def onload(self):
|
def onload(self):
|
||||||
"""Load the Opening Invoice summary"""
|
"""Load the Opening Invoice summary"""
|
||||||
@ -67,29 +68,25 @@ class OpeningInvoiceCreationTool(Document):
|
|||||||
for row in self.invoices:
|
for row in self.invoices:
|
||||||
if not row.qty:
|
if not row.qty:
|
||||||
row.qty = 1.0
|
row.qty = 1.0
|
||||||
if not row.party:
|
|
||||||
frappe.throw(mandatory_error_msg.format(
|
|
||||||
idx=row.idx,
|
|
||||||
field= _("Party"),
|
|
||||||
invoice_type=self.invoice_type
|
|
||||||
))
|
|
||||||
# set party type if not available
|
|
||||||
if not row.party_type:
|
|
||||||
row.party_type = "Customer" if self.invoice_type == "Sales" else "Supplier"
|
|
||||||
|
|
||||||
|
# always mandatory fields for the invoices
|
||||||
|
if not row.temporary_opening_account:
|
||||||
|
row.temporary_opening_account = get_temporary_opening_account(self.company)
|
||||||
|
row.party_type = "Customer" if self.invoice_type == "Sales" else "Supplier"
|
||||||
|
if not row.item_name:
|
||||||
|
row.item_name = _("Opening Invoice Item")
|
||||||
if not row.posting_date:
|
if not row.posting_date:
|
||||||
frappe.throw(mandatory_error_msg.format(
|
row.posting_date = nowdate()
|
||||||
idx=row.idx,
|
if not row.due_date:
|
||||||
field= _("Party"),
|
row.due_date = nowdate()
|
||||||
invoice_type=self.invoice_type
|
|
||||||
))
|
|
||||||
|
|
||||||
if not row.outstanding_amount:
|
for d in ("Party", "Outstanding Amount", "Temporary Opening Account"):
|
||||||
frappe.throw(mandatory_error_msg.format(
|
if not row.get(scrub(d)):
|
||||||
idx=row.idx,
|
frappe.throw(mandatory_error_msg.format(
|
||||||
field= _("Outstanding Amount"),
|
idx=row.idx,
|
||||||
invoice_type=self.invoice_type
|
field=_(d),
|
||||||
))
|
invoice_type=self.invoice_type
|
||||||
|
))
|
||||||
|
|
||||||
args = self.get_invoice_dict(row=row)
|
args = self.get_invoice_dict(row=row)
|
||||||
if not args:
|
if not args:
|
||||||
@ -99,10 +96,14 @@ class OpeningInvoiceCreationTool(Document):
|
|||||||
doc.submit()
|
doc.submit()
|
||||||
names.append(doc.name)
|
names.append(doc.name)
|
||||||
|
|
||||||
if(len(self.invoices) > 5):
|
if len(self.invoices) > 5:
|
||||||
frappe.publish_realtime("progress",
|
frappe.publish_realtime(
|
||||||
dict(progress=[row.idx, len(self.invoices)], title=_('Creating {0}').format(doc.doctype)),
|
"progress", dict(
|
||||||
user=frappe.session.user)
|
progress=[row.idx, len(self.invoices)],
|
||||||
|
title=_('Creating {0}').format(doc.doctype)
|
||||||
|
),
|
||||||
|
user=frappe.session.user
|
||||||
|
)
|
||||||
|
|
||||||
return names
|
return names
|
||||||
|
|
||||||
@ -111,8 +112,10 @@ class OpeningInvoiceCreationTool(Document):
|
|||||||
default_uom = frappe.db.get_single_value("Stock Settings", "stock_uom") or _("Nos")
|
default_uom = frappe.db.get_single_value("Stock Settings", "stock_uom") or _("Nos")
|
||||||
cost_center = frappe.db.get_value("Company", self.company, "cost_center")
|
cost_center = frappe.db.get_value("Company", self.company, "cost_center")
|
||||||
if not cost_center:
|
if not cost_center:
|
||||||
frappe.throw(_("Please set the Default Cost Center in {0} company").format(frappe.bold(self.company)))
|
frappe.throw(
|
||||||
rate = flt(row.outstanding_amount) / row.qty
|
_("Please set the Default Cost Center in {0} company").format(frappe.bold(self.company))
|
||||||
|
)
|
||||||
|
rate = flt(row.outstanding_amount) / flt(row.qty)
|
||||||
|
|
||||||
return frappe._dict({
|
return frappe._dict({
|
||||||
"uom": default_uom,
|
"uom": default_uom,
|
||||||
@ -143,8 +146,7 @@ class OpeningInvoiceCreationTool(Document):
|
|||||||
"due_date": row.due_date,
|
"due_date": row.due_date,
|
||||||
"posting_date": row.posting_date,
|
"posting_date": row.posting_date,
|
||||||
frappe.scrub(party_type): row.party,
|
frappe.scrub(party_type): row.party,
|
||||||
"doctype": "Sales Invoice" if self.invoice_type == "Sales" \
|
"doctype": "Sales Invoice" if self.invoice_type == "Sales" else "Purchase Invoice",
|
||||||
else "Purchase Invoice",
|
|
||||||
"currency": frappe.db.get_value("Company", self.company, "default_currency")
|
"currency": frappe.db.get_value("Company", self.company, "default_currency")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -160,4 +162,4 @@ def get_temporary_opening_account(company=None):
|
|||||||
if not accounts:
|
if not accounts:
|
||||||
frappe.throw(_("Please add a Temporary Opening account in Chart of Accounts"))
|
frappe.throw(_("Please add a Temporary Opening account in Chart of Accounts"))
|
||||||
|
|
||||||
return accounts[0].name
|
return accounts[0].name
|
||||||
|
@ -161,7 +161,7 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
@ -192,7 +192,7 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
@ -284,6 +284,66 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 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": "column_break_4",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "1",
|
||||||
|
"fieldname": "qty",
|
||||||
|
"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": "Quantity",
|
||||||
|
"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,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
@ -300,7 +360,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-11-15 14:19:00.433148",
|
"modified": "2017-12-19 05:07:01.549918",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Opening Invoice Creation Tool Item",
|
"name": "Opening Invoice Creation Tool Item",
|
||||||
|
@ -266,6 +266,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
() => frm.set_value("party_balance", r.message.party_balance),
|
() => frm.set_value("party_balance", r.message.party_balance),
|
||||||
|
() => frm.set_value("party_name", r.message.party_name),
|
||||||
() => frm.events.get_outstanding_documents(frm),
|
() => frm.events.get_outstanding_documents(frm),
|
||||||
() => frm.events.hide_unhide_fields(frm),
|
() => frm.events.hide_unhide_fields(frm),
|
||||||
() => frm.events.set_dynamic_labels(frm),
|
() => frm.events.set_dynamic_labels(frm),
|
||||||
@ -408,7 +409,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make read only if Accounts Settings doesn't allow stale rates
|
// Make read only if Accounts Settings doesn't allow stale rates
|
||||||
frm.set_df_property("source_exchange_rate", "read_only", erpnext.stale_rate_allowed());
|
frm.set_df_property("source_exchange_rate", "read_only", erpnext.stale_rate_allowed() ? 0 : 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
target_exchange_rate: function(frm) {
|
target_exchange_rate: function(frm) {
|
||||||
@ -429,7 +430,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
frm.set_paid_amount_based_on_received_amount = false;
|
frm.set_paid_amount_based_on_received_amount = false;
|
||||||
|
|
||||||
// Make read only if Accounts Settings doesn't allow stale rates
|
// Make read only if Accounts Settings doesn't allow stale rates
|
||||||
frm.set_df_property("target_exchange_rate", "read_only", erpnext.stale_rate_allowed());
|
frm.set_df_property("target_exchange_rate", "read_only", erpnext.stale_rate_allowed() ? 0 : 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
paid_amount: function(frm) {
|
paid_amount: function(frm) {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, json
|
import frappe, erpnext, json
|
||||||
from frappe import _, scrub, ValidationError
|
from frappe import _, scrub, ValidationError
|
||||||
from frappe.utils import flt, comma_or, nowdate
|
from frappe.utils import flt, comma_or, nowdate
|
||||||
from erpnext.accounts.utils import get_outstanding_invoices, get_account_currency, get_balance_on
|
from erpnext.accounts.utils import get_outstanding_invoices, get_account_currency, get_balance_on
|
||||||
@ -71,9 +71,10 @@ class PaymentEntry(AccountsController):
|
|||||||
def validate_duplicate_entry(self):
|
def validate_duplicate_entry(self):
|
||||||
reference_names = []
|
reference_names = []
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
if (d.reference_doctype, d.reference_name, d.due_date) in reference_names:
|
if (d.reference_doctype, d.reference_name) in reference_names:
|
||||||
frappe.throw(_("Row #{0}: Duplicate entry in References {1} {2}").format(d.idx, d.reference_doctype, d.reference_name))
|
frappe.throw(_("Row #{0}: Duplicate entry in References {1} {2}")
|
||||||
reference_names.append((d.reference_doctype, d.reference_name, d.due_date))
|
.format(d.idx, d.reference_doctype, d.reference_name))
|
||||||
|
reference_names.append((d.reference_doctype, d.reference_name))
|
||||||
|
|
||||||
def validate_allocated_amount(self):
|
def validate_allocated_amount(self):
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
@ -147,7 +148,7 @@ class PaymentEntry(AccountsController):
|
|||||||
if not frappe.db.exists(self.party_type, self.party):
|
if not frappe.db.exists(self.party_type, self.party):
|
||||||
frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party))
|
frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party))
|
||||||
|
|
||||||
if self.party_account:
|
if self.party_account and self.party_type != "Employee":
|
||||||
party_account_type = "Receivable" if self.party_type in ("Customer", "Student") else "Payable"
|
party_account_type = "Receivable" if self.party_type in ("Customer", "Student") else "Payable"
|
||||||
self.validate_account_type(self.party_account, [party_account_type])
|
self.validate_account_type(self.party_account, [party_account_type])
|
||||||
|
|
||||||
@ -188,7 +189,7 @@ class PaymentEntry(AccountsController):
|
|||||||
elif self.party_type == "Supplier":
|
elif self.party_type == "Supplier":
|
||||||
valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry")
|
valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry")
|
||||||
elif self.party_type == "Employee":
|
elif self.party_type == "Employee":
|
||||||
valid_reference_doctypes = ("Expense Claim", "Journal Entry")
|
valid_reference_doctypes = ("Expense Claim", "Journal Entry", "Employee Advance")
|
||||||
|
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
if not d.allocated_amount:
|
if not d.allocated_amount:
|
||||||
@ -205,7 +206,7 @@ class PaymentEntry(AccountsController):
|
|||||||
|
|
||||||
if d.reference_doctype != "Journal Entry":
|
if d.reference_doctype != "Journal Entry":
|
||||||
if self.party != ref_doc.get(scrub(self.party_type)):
|
if self.party != ref_doc.get(scrub(self.party_type)):
|
||||||
frappe.throw(_("{0} {1} does not associated with {2} {3}")
|
frappe.throw(_("{0} {1} is not associated with {2} {3}")
|
||||||
.format(d.reference_doctype, d.reference_name, self.party_type, self.party))
|
.format(d.reference_doctype, d.reference_name, self.party_type, self.party))
|
||||||
else:
|
else:
|
||||||
self.validate_journal_entry()
|
self.validate_journal_entry()
|
||||||
@ -413,8 +414,7 @@ class PaymentEntry(AccountsController):
|
|||||||
gle = party_gl_dict.copy()
|
gle = party_gl_dict.copy()
|
||||||
gle.update({
|
gle.update({
|
||||||
"against_voucher_type": d.reference_doctype,
|
"against_voucher_type": d.reference_doctype,
|
||||||
"against_voucher": d.reference_name,
|
"against_voucher": d.reference_name
|
||||||
"due_date": d.due_date
|
|
||||||
})
|
})
|
||||||
|
|
||||||
allocated_amount_in_company_currency = flt(flt(d.allocated_amount) * flt(d.exchange_rate),
|
allocated_amount_in_company_currency = flt(flt(d.allocated_amount) * flt(d.exchange_rate),
|
||||||
@ -483,8 +483,9 @@ class PaymentEntry(AccountsController):
|
|||||||
def update_advance_paid(self):
|
def update_advance_paid(self):
|
||||||
if self.payment_type in ("Receive", "Pay") and self.party:
|
if self.payment_type in ("Receive", "Pay") and self.party:
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
if d.allocated_amount and d.reference_doctype in ("Sales Order", "Purchase Order"):
|
if d.allocated_amount \
|
||||||
frappe.get_doc(d.reference_doctype, d.reference_name).set_total_advance_paid()
|
and d.reference_doctype in ("Sales Order", "Purchase Order", "Employee Advance"):
|
||||||
|
frappe.get_doc(d.reference_doctype, d.reference_name).set_total_advance_paid()
|
||||||
|
|
||||||
def update_expense_claim(self):
|
def update_expense_claim(self):
|
||||||
if self.payment_type in ("Pay") and self.party:
|
if self.payment_type in ("Pay") and self.party:
|
||||||
@ -507,13 +508,18 @@ def get_outstanding_reference_documents(args):
|
|||||||
|
|
||||||
# Get negative outstanding sales /purchase invoices
|
# Get negative outstanding sales /purchase invoices
|
||||||
negative_outstanding_invoices = []
|
negative_outstanding_invoices = []
|
||||||
if args.get("party_type") not in ["Student", "Employee"]:
|
if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"):
|
||||||
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
|
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
|
||||||
args.get("party"), args.get("party_account"), party_account_currency, company_currency)
|
args.get("party"), args.get("party_account"), party_account_currency, company_currency)
|
||||||
|
|
||||||
# Get positive outstanding sales /purchase invoices/ Fees
|
# Get positive outstanding sales /purchase invoices/ Fees
|
||||||
|
condition = ""
|
||||||
|
if args.get("voucher_type") and args.get("voucher_no"):
|
||||||
|
condition = " and voucher_type='{0}' and voucher_no='{1}'"\
|
||||||
|
.format(frappe.db.escape(args["voucher_type"]), frappe.db.escape(args["voucher_no"]))
|
||||||
|
|
||||||
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
||||||
args.get("party_account"))
|
args.get("party_account"), condition=condition)
|
||||||
|
|
||||||
for d in outstanding_invoices:
|
for d in outstanding_invoices:
|
||||||
d["exchange_rate"] = 1
|
d["exchange_rate"] = 1
|
||||||
@ -535,6 +541,7 @@ def get_outstanding_reference_documents(args):
|
|||||||
|
|
||||||
return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
|
return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
|
||||||
|
|
||||||
|
|
||||||
def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency):
|
def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency):
|
||||||
if party_type == "Customer":
|
if party_type == "Customer":
|
||||||
voucher_type = 'Sales Order'
|
voucher_type = 'Sales Order'
|
||||||
@ -563,18 +570,17 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
|
|||||||
and abs(100 - per_billed) > 0.01
|
and abs(100 - per_billed) > 0.01
|
||||||
order by
|
order by
|
||||||
transaction_date, name
|
transaction_date, name
|
||||||
""".format(**{
|
""".format(**{
|
||||||
"ref_field": ref_field,
|
"ref_field": ref_field,
|
||||||
"voucher_type": voucher_type,
|
"voucher_type": voucher_type,
|
||||||
"party_type": scrub(party_type)
|
"party_type": scrub(party_type)
|
||||||
}), party, as_dict = True)
|
}), party, as_dict=True)
|
||||||
|
|
||||||
order_list = []
|
order_list = []
|
||||||
for d in orders:
|
for d in orders:
|
||||||
d["voucher_type"] = voucher_type
|
d["voucher_type"] = voucher_type
|
||||||
# This assumes that the exchange rate required is the one in the SO
|
# This assumes that the exchange rate required is the one in the SO
|
||||||
d["exchange_rate"] = get_exchange_rate(party_account_currency,
|
d["exchange_rate"] = get_exchange_rate(party_account_currency, company_currency, posting_date)
|
||||||
company_currency, posting_date)
|
|
||||||
order_list.append(d)
|
order_list.append(d)
|
||||||
|
|
||||||
return order_list
|
return order_list
|
||||||
@ -608,6 +614,7 @@ def get_negative_outstanding_invoices(party_type, party, party_account, party_ac
|
|||||||
"party_account": "debit_to" if party_type == "Customer" else "credit_to"
|
"party_account": "debit_to" if party_type == "Customer" else "credit_to"
|
||||||
}), (party, party_account), as_dict=True)
|
}), (party, party_account), as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_party_details(company, party_type, party, date):
|
def get_party_details(company, party_type, party, date):
|
||||||
if not frappe.db.exists(party_type, party):
|
if not frappe.db.exists(party_type, party):
|
||||||
@ -617,15 +624,19 @@ def get_party_details(company, party_type, party, date):
|
|||||||
|
|
||||||
account_currency = get_account_currency(party_account)
|
account_currency = get_account_currency(party_account)
|
||||||
account_balance = get_balance_on(party_account, date)
|
account_balance = get_balance_on(party_account, date)
|
||||||
|
_party_name = "title" if party_type == "Student" else party_type.lower() + "_name"
|
||||||
|
party_name = frappe.db.get_value(party_type, party, _party_name)
|
||||||
party_balance = get_balance_on(party_type=party_type, party=party)
|
party_balance = get_balance_on(party_type=party_type, party=party)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"party_account": party_account,
|
"party_account": party_account,
|
||||||
|
"party_name": party_name,
|
||||||
"party_account_currency": account_currency,
|
"party_account_currency": account_currency,
|
||||||
"party_balance": party_balance,
|
"party_balance": party_balance,
|
||||||
"account_balance": account_balance
|
"account_balance": account_balance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_account_details(account, date):
|
def get_account_details(account, date):
|
||||||
frappe.has_permission('Payment Entry', throw=True)
|
frappe.has_permission('Payment Entry', throw=True)
|
||||||
@ -635,6 +646,7 @@ def get_account_details(account, date):
|
|||||||
"account_type": frappe.db.get_value("Account", account, "account_type")
|
"account_type": frappe.db.get_value("Account", account, "account_type")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_company_defaults(company):
|
def get_company_defaults(company):
|
||||||
fields = ["write_off_account", "exchange_gain_loss_account", "cost_center"]
|
fields = ["write_off_account", "exchange_gain_loss_account", "cost_center"]
|
||||||
@ -647,19 +659,23 @@ def get_company_defaults(company):
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_reference_details(reference_doctype, reference_name, party_account_currency):
|
def get_reference_details(reference_doctype, reference_name, party_account_currency):
|
||||||
total_amount = outstanding_amount = exchange_rate = None
|
total_amount = outstanding_amount = exchange_rate = None
|
||||||
ref_doc = frappe.get_doc(reference_doctype, reference_name)
|
ref_doc = frappe.get_doc(reference_doctype, reference_name)
|
||||||
|
company_currency = ref_doc.get("company_currency") or erpnext.get_company_currency(ref_doc.company)
|
||||||
|
|
||||||
if reference_doctype == "Fees":
|
if reference_doctype == "Fees":
|
||||||
total_amount = ref_doc.get("grand_total")
|
total_amount = ref_doc.get("grand_total")
|
||||||
exchange_rate = 1
|
exchange_rate = 1
|
||||||
outstanding_amount = ref_doc.get("outstanding_amount")
|
outstanding_amount = ref_doc.get("outstanding_amount")
|
||||||
elif reference_doctype != "Journal Entry":
|
elif reference_doctype != "Journal Entry":
|
||||||
if party_account_currency == ref_doc.company_currency:
|
if party_account_currency == company_currency:
|
||||||
if ref_doc.doctype == "Expense Claim":
|
if ref_doc.doctype == "Expense Claim":
|
||||||
total_amount = ref_doc.total_sanctioned_amount
|
total_amount = ref_doc.total_sanctioned_amount
|
||||||
|
elif ref_doc.doctype == "Employee Advance":
|
||||||
|
total_amount = ref_doc.advance_amount
|
||||||
else:
|
else:
|
||||||
total_amount = ref_doc.base_grand_total
|
total_amount = ref_doc.base_grand_total
|
||||||
exchange_rate = 1
|
exchange_rate = 1
|
||||||
@ -669,15 +685,18 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
|||||||
# Get the exchange rate from the original ref doc
|
# Get the exchange rate from the original ref doc
|
||||||
# or get it based on the posting date of the ref doc
|
# or get it based on the posting date of the ref doc
|
||||||
exchange_rate = ref_doc.get("conversion_rate") or \
|
exchange_rate = ref_doc.get("conversion_rate") or \
|
||||||
get_exchange_rate(party_account_currency, ref_doc.company_currency, ref_doc.posting_date)
|
get_exchange_rate(party_account_currency, company_currency, ref_doc.posting_date)
|
||||||
|
|
||||||
outstanding_amount = ref_doc.get("outstanding_amount") \
|
if reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim"):
|
||||||
if reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim") \
|
outstanding_amount = ref_doc.get("outstanding_amount")
|
||||||
else flt(total_amount) - flt(ref_doc.advance_paid)
|
elif reference_doctype == "Employee Advance":
|
||||||
|
outstanding_amount = ref_doc.advance_amount - flt(ref_doc.paid_amount)
|
||||||
|
else:
|
||||||
|
outstanding_amount = flt(total_amount) - flt(ref_doc.advance_paid)
|
||||||
else:
|
else:
|
||||||
# Get the exchange rate based on the posting date of the ref doc
|
# Get the exchange rate based on the posting date of the ref doc
|
||||||
exchange_rate = get_exchange_rate(party_account_currency,
|
exchange_rate = get_exchange_rate(party_account_currency,
|
||||||
ref_doc.company_currency, ref_doc.posting_date)
|
company_currency, ref_doc.posting_date)
|
||||||
|
|
||||||
return frappe._dict({
|
return frappe._dict({
|
||||||
"due_date": ref_doc.get("due_date"),
|
"due_date": ref_doc.get("due_date"),
|
||||||
@ -686,6 +705,7 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
|||||||
"exchange_rate": exchange_rate
|
"exchange_rate": exchange_rate
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None):
|
def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None):
|
||||||
doc = frappe.get_doc(dt, dn)
|
doc = frappe.get_doc(dt, dn)
|
||||||
@ -697,7 +717,7 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
party_type = "Customer"
|
party_type = "Customer"
|
||||||
elif dt in ("Purchase Invoice", "Purchase Order"):
|
elif dt in ("Purchase Invoice", "Purchase Order"):
|
||||||
party_type = "Supplier"
|
party_type = "Supplier"
|
||||||
elif dt in ("Expense Claim"):
|
elif dt in ("Expense Claim", "Employee Advance"):
|
||||||
party_type = "Employee"
|
party_type = "Employee"
|
||||||
elif dt in ("Fees"):
|
elif dt in ("Fees"):
|
||||||
party_type = "Student"
|
party_type = "Student"
|
||||||
@ -709,6 +729,8 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
party_account = doc.credit_to
|
party_account = doc.credit_to
|
||||||
elif dt == "Fees":
|
elif dt == "Fees":
|
||||||
party_account = doc.receivable_account
|
party_account = doc.receivable_account
|
||||||
|
elif dt == "Employee Advance":
|
||||||
|
party_account = doc.advance_account
|
||||||
else:
|
else:
|
||||||
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
||||||
|
|
||||||
@ -733,7 +755,11 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
outstanding_amount = doc.outstanding_amount
|
outstanding_amount = doc.outstanding_amount
|
||||||
elif dt in ("Expense Claim"):
|
elif dt in ("Expense Claim"):
|
||||||
grand_total = doc.total_sanctioned_amount
|
grand_total = doc.total_sanctioned_amount
|
||||||
outstanding_amount = doc.total_sanctioned_amount - doc.total_amount_reimbursed
|
outstanding_amount = doc.total_sanctioned_amount \
|
||||||
|
- doc.total_amount_reimbursed - flt(doc.total_advance_amount)
|
||||||
|
elif dt == "Employee Advance":
|
||||||
|
grand_total = doc.advance_amount
|
||||||
|
outstanding_amount = flt(doc.advance_amount) - flt(doc.paid_amount)
|
||||||
elif dt == "Fees":
|
elif dt == "Fees":
|
||||||
grand_total = doc.grand_total
|
grand_total = doc.grand_total
|
||||||
outstanding_amount = doc.outstanding_amount
|
outstanding_amount = doc.outstanding_amount
|
||||||
@ -776,26 +802,16 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
pe.received_amount = received_amount
|
pe.received_amount = received_amount
|
||||||
pe.allocate_payment_amount = 1
|
pe.allocate_payment_amount = 1
|
||||||
pe.letter_head = doc.get("letter_head")
|
pe.letter_head = doc.get("letter_head")
|
||||||
args = {
|
|
||||||
'party_account': party_account, 'company': pe.company, 'party_type': pe.party_type,
|
|
||||||
'party': pe.party, 'posting_date': pe.posting_date
|
|
||||||
}
|
|
||||||
references = get_outstanding_reference_documents(args=args)
|
|
||||||
|
|
||||||
for reference in references:
|
pe.append("references", {
|
||||||
if reference.voucher_no == dn:
|
'reference_doctype': dt,
|
||||||
allocated_amount = min(paid_amount, reference.outstanding_amount)
|
'reference_name': dn,
|
||||||
pe.append("references", {
|
"bill_no": doc.get("bill_no"),
|
||||||
'reference_doctype': reference.voucher_type,
|
"due_date": doc.get("due_date"),
|
||||||
'reference_name': reference.voucher_no,
|
'total_amount': grand_total,
|
||||||
'due_date': reference.due_date,
|
'outstanding_amount': outstanding_amount,
|
||||||
'total_amount': reference.invoice_amount,
|
'allocated_amount': outstanding_amount
|
||||||
'outstanding_amount': reference.outstanding_amount,
|
})
|
||||||
'allocated_amount': allocated_amount,
|
|
||||||
"bill_no": reference.get("bill_no")
|
|
||||||
})
|
|
||||||
if paid_amount:
|
|
||||||
paid_amount -= allocated_amount
|
|
||||||
|
|
||||||
pe.setup_party_account_field()
|
pe.setup_party_account_field()
|
||||||
pe.set_missing_values()
|
pe.set_missing_values()
|
||||||
|
@ -66,18 +66,6 @@ class TestPaymentEntry(unittest.TestCase):
|
|||||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||||
self.assertEqual(outstanding_amount, 100)
|
self.assertEqual(outstanding_amount, 100)
|
||||||
|
|
||||||
def test_payment_entry_against_si_multi_due_dates(self):
|
|
||||||
si = create_sales_invoice(do_not_save=1)
|
|
||||||
si.payment_terms_template = '_Test Payment Term Template'
|
|
||||||
si.insert()
|
|
||||||
si.submit()
|
|
||||||
|
|
||||||
pe = get_payment_entry(si.doctype, si.name)
|
|
||||||
pe.reference_no = "1"
|
|
||||||
pe.reference_date = "2016-01-01"
|
|
||||||
pe.insert()
|
|
||||||
pe.submit()
|
|
||||||
|
|
||||||
def test_payment_entry_against_pi(self):
|
def test_payment_entry_against_pi(self):
|
||||||
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
|
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
|
||||||
currency="USD", conversion_rate=50)
|
currency="USD", conversion_rate=50)
|
||||||
@ -106,6 +94,7 @@ class TestPaymentEntry(unittest.TestCase):
|
|||||||
pe.reference_no = "1"
|
pe.reference_no = "1"
|
||||||
pe.reference_date = "2016-01-01"
|
pe.reference_date = "2016-01-01"
|
||||||
pe.source_exchange_rate = 1
|
pe.source_exchange_rate = 1
|
||||||
|
pe.paid_to = payable
|
||||||
pe.insert()
|
pe.insert()
|
||||||
pe.submit()
|
pe.submit()
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
@ -98,7 +98,7 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
@ -160,7 +160,7 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
@ -179,8 +179,8 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-11-23 12:39:02.013040",
|
"modified": "2017-12-19 16:20:33.546984",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "nabinhait@gmail.com",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Schedule",
|
"name": "Payment Schedule",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
|
@ -106,11 +106,6 @@ cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn)
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
cur_frm.fields_dict.user.get_query = function(doc,cdt,cdn) {
|
|
||||||
return{ query:"frappe.core.doctype.user.user.user_query"};
|
|
||||||
};
|
|
||||||
|
|
||||||
cur_frm.fields_dict.write_off_account.get_query = function(doc) {
|
cur_frm.fields_dict.write_off_account.get_query = function(doc) {
|
||||||
return{
|
return{
|
||||||
filters:{
|
filters:{
|
||||||
|
@ -101,38 +101,6 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "user",
|
|
||||||
"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": "Applicable for User",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "user",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "User",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 1,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -162,7 +130,7 @@
|
|||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 1,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1508,7 +1476,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-11-24 14:08:09.184226",
|
"modified": "2018-01-03 17:30:45.198147",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "POS Profile",
|
"name": "POS Profile",
|
||||||
|
@ -31,8 +31,8 @@ class POSProfile(Document):
|
|||||||
msgprint(_("Already set default in pos profile {0} for user {1}, kindly disabled default")
|
msgprint(_("Already set default in pos profile {0} for user {1}, kindly disabled default")
|
||||||
.format(res[0][0], row.user), raise_exception=1)
|
.format(res[0][0], row.user), raise_exception=1)
|
||||||
elif not row.default and not res:
|
elif not row.default and not res:
|
||||||
msgprint(_("Row {0}: set atleast one default pos profile for user {1}")
|
msgprint(_("User {0} doesn't have any default POS Profile. Check Default at Row {1} for this User.")
|
||||||
.format(row.idx, row.user), raise_exception=1)
|
.format(row.user, row.idx), raise_exception=1)
|
||||||
|
|
||||||
def validate_all_link_fields(self):
|
def validate_all_link_fields(self):
|
||||||
accounts = {"Account": [self.income_account,
|
accounts = {"Account": [self.income_account,
|
||||||
@ -63,7 +63,11 @@ class POSProfile(Document):
|
|||||||
|
|
||||||
if len(default_mode_of_payment) > 1:
|
if len(default_mode_of_payment) > 1:
|
||||||
frappe.throw(_("Multiple default mode of payment is not allowed"))
|
frappe.throw(_("Multiple default mode of payment is not allowed"))
|
||||||
|
|
||||||
def validate_customer_territory_group(self):
|
def validate_customer_territory_group(self):
|
||||||
|
if not frappe.db.get_single_value('POS Settings', 'use_pos_in_offline_mode'):
|
||||||
|
return
|
||||||
|
|
||||||
if not self.territory:
|
if not self.territory:
|
||||||
frappe.throw(_("Territory is Required in POS Profile"), title="Mandatory Field")
|
frappe.throw(_("Territory is Required in POS Profile"), title="Mandatory Field")
|
||||||
|
|
||||||
@ -83,12 +87,12 @@ class POSProfile(Document):
|
|||||||
frappe.defaults.clear_default("is_pos")
|
frappe.defaults.clear_default("is_pos")
|
||||||
|
|
||||||
if not include_current_pos:
|
if not include_current_pos:
|
||||||
condition = " where name != '%s'" % self.name.replace("'", "\'")
|
condition = " where pfu.name != '%s' and pfu.default = 1 " % self.name.replace("'", "\'")
|
||||||
else:
|
else:
|
||||||
condition = ""
|
condition = " where pfu.default = 1 "
|
||||||
|
|
||||||
pos_view_users = frappe.db.sql_list("""select user
|
pos_view_users = frappe.db.sql_list("""select pfu.user
|
||||||
from `tabPOS Profile` {0}""".format(condition))
|
from `tabPOS Profile User` as pfu {0}""".format(condition))
|
||||||
|
|
||||||
for user in pos_view_users:
|
for user in pos_view_users:
|
||||||
if user:
|
if user:
|
||||||
@ -103,7 +107,7 @@ def get_item_groups(pos_profile):
|
|||||||
if pos_profile.get('item_groups'):
|
if pos_profile.get('item_groups'):
|
||||||
# Get items based on the item groups defined in the POS profile
|
# Get items based on the item groups defined in the POS profile
|
||||||
for data in pos_profile.get('item_groups'):
|
for data in pos_profile.get('item_groups'):
|
||||||
item_groups.extend(["'%s'"%d.name for d in get_child_nodes('Item Group', data.item_group)])
|
item_groups.extend(["'%s'" % frappe.db.escape(d.name) for d in get_child_nodes('Item Group', data.item_group)])
|
||||||
|
|
||||||
return list(set(item_groups))
|
return list(set(item_groups))
|
||||||
|
|
||||||
|
@ -140,6 +140,37 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "tax_id",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"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": "Tax Id",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "supplier.tax_id",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 1,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -161,7 +192,7 @@
|
|||||||
"oldfieldname": "due_date",
|
"oldfieldname": "due_date",
|
||||||
"oldfieldtype": "Date",
|
"oldfieldtype": "Date",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 1,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
@ -3086,7 +3117,7 @@
|
|||||||
"options": "Payment Schedule",
|
"options": "Payment Schedule",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 1,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
@ -3883,7 +3914,7 @@
|
|||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"menu_index": 0,
|
"menu_index": 0,
|
||||||
"modified": "2017-11-29 13:44:40.722157",
|
"modified": "2017-12-20 17:49:51.230092",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Invoice",
|
"name": "Purchase Invoice",
|
||||||
|
@ -277,6 +277,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
.format(item.purchase_receipt))
|
.format(item.purchase_receipt))
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
|
super(PurchaseInvoice, self).on_submit()
|
||||||
|
|
||||||
self.check_prev_docstatus()
|
self.check_prev_docstatus()
|
||||||
self.update_status_updater_args()
|
self.update_status_updater_args()
|
||||||
|
|
||||||
@ -348,7 +350,6 @@ class PurchaseInvoice(BuyingController):
|
|||||||
self.negative_expense_to_be_booked = 0.0
|
self.negative_expense_to_be_booked = 0.0
|
||||||
gl_entries = []
|
gl_entries = []
|
||||||
|
|
||||||
|
|
||||||
self.make_supplier_gl_entry(gl_entries)
|
self.make_supplier_gl_entry(gl_entries)
|
||||||
self.make_item_gl_entries(gl_entries)
|
self.make_item_gl_entries(gl_entries)
|
||||||
self.make_tax_gl_entries(gl_entries)
|
self.make_tax_gl_entries(gl_entries)
|
||||||
@ -363,27 +364,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
def make_supplier_gl_entry(self, gl_entries):
|
def make_supplier_gl_entry(self, gl_entries):
|
||||||
grand_total = self.rounded_total or self.grand_total
|
grand_total = self.rounded_total or self.grand_total
|
||||||
if self.get("payment_schedule"):
|
if grand_total:
|
||||||
for d in self.get("payment_schedule"):
|
|
||||||
payment_amount_in_company_currency = flt(d.payment_amount * self.conversion_rate,
|
|
||||||
d.precision("payment_amount"))
|
|
||||||
|
|
||||||
gl_entries.append(
|
|
||||||
self.get_gl_dict({
|
|
||||||
"account": self.credit_to,
|
|
||||||
"party_type": "Supplier",
|
|
||||||
"party": self.supplier,
|
|
||||||
"due_date": d.due_date,
|
|
||||||
"against": self.against_expense_account,
|
|
||||||
"credit": payment_amount_in_company_currency,
|
|
||||||
"credit_in_account_currency": payment_amount_in_company_currency \
|
|
||||||
if self.party_account_currency==self.company_currency else d.payment_amount,
|
|
||||||
"against_voucher": self.return_against if cint(self.is_return) else self.name,
|
|
||||||
"against_voucher_type": self.doctype
|
|
||||||
}, self.party_account_currency)
|
|
||||||
)
|
|
||||||
|
|
||||||
elif grand_total:
|
|
||||||
# Didnot use base_grand_total to book rounding loss gle
|
# Didnot use base_grand_total to book rounding loss gle
|
||||||
grand_total_in_company_currency = flt(grand_total * self.conversion_rate,
|
grand_total_in_company_currency = flt(grand_total * self.conversion_rate,
|
||||||
self.precision("grand_total"))
|
self.precision("grand_total"))
|
||||||
@ -442,7 +423,10 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
# sub-contracting warehouse
|
# sub-contracting warehouse
|
||||||
if flt(item.rm_supp_cost):
|
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({
|
gl_entries.append(self.get_gl_dict({
|
||||||
"account": supplier_warehouse_account,
|
"account": supplier_warehouse_account,
|
||||||
"against": item.expense_account,
|
"against": item.expense_account,
|
||||||
@ -626,6 +610,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
))
|
))
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
|
super(PurchaseInvoice, self).on_cancel()
|
||||||
|
|
||||||
self.check_for_closed_status()
|
self.check_for_closed_status()
|
||||||
|
|
||||||
self.update_status_updater_args()
|
self.update_status_updater_args()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
QUnit.module('Purchase Invoice');
|
QUnit.module('Purchase Invoice');
|
||||||
|
|
||||||
QUnit.test("test purchase invoice", function(assert) {
|
QUnit.test("test purchase invoice", function(assert) {
|
||||||
assert.expect(6);
|
assert.expect(9);
|
||||||
let done = assert.async();
|
let done = assert.async();
|
||||||
frappe.run_serially([
|
frappe.run_serially([
|
||||||
() => {
|
() => {
|
||||||
@ -18,7 +18,7 @@ QUnit.test("test purchase invoice", function(assert) {
|
|||||||
{update_stock:1},
|
{update_stock:1},
|
||||||
{supplier_address: 'Test1-Billing'},
|
{supplier_address: 'Test1-Billing'},
|
||||||
{contact_person: 'Contact 3-Test Supplier'},
|
{contact_person: 'Contact 3-Test Supplier'},
|
||||||
{taxes_and_charges: 'TEST In State GST'},
|
{taxes_and_charges: 'TEST In State GST - FT'},
|
||||||
{tc_name: 'Test Term 1'},
|
{tc_name: 'Test Term 1'},
|
||||||
{terms: 'This is Test'},
|
{terms: 'This is Test'},
|
||||||
{payment_terms_template: '_Test Payment Term Template UI'}
|
{payment_terms_template: '_Test Payment Term Template UI'}
|
||||||
@ -29,7 +29,7 @@ QUnit.test("test purchase invoice", function(assert) {
|
|||||||
// get_item_details
|
// get_item_details
|
||||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||||
// get tax details
|
// get tax details
|
||||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||||
// get tax account head details
|
// get tax account head details
|
||||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||||
// grand_total Calculated
|
// grand_total Calculated
|
||||||
@ -39,6 +39,33 @@ QUnit.test("test purchase invoice", function(assert) {
|
|||||||
assert.ok(cur_frm.doc.payment_schedule.length > 0, "Payment Term Schedule is not empty");
|
assert.ok(cur_frm.doc.payment_schedule.length > 0, "Payment Term Schedule is not empty");
|
||||||
|
|
||||||
},
|
},
|
||||||
|
() => {
|
||||||
|
let date = cur_frm.doc.due_date;
|
||||||
|
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||||
|
frappe.timeout(0.5);
|
||||||
|
assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user');
|
||||||
|
},
|
||||||
|
() => frappe.timeout(1),
|
||||||
|
() => frappe.tests.click_button('Close'),
|
||||||
|
() => frappe.timeout(0.5),
|
||||||
|
() => frappe.tests.set_form_values(cur_frm, [{'payment_terms_schedule': ''}]),
|
||||||
|
() => {
|
||||||
|
let date = cur_frm.doc.due_date;
|
||||||
|
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||||
|
frappe.timeout(0.5);
|
||||||
|
assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user');
|
||||||
|
},
|
||||||
|
() => frappe.timeout(1),
|
||||||
|
() => frappe.tests.click_button('Close'),
|
||||||
|
() => frappe.timeout(0.5),
|
||||||
|
() => frappe.tests.set_form_values(cur_frm, [{'payment_schedule': []}]),
|
||||||
|
() => {
|
||||||
|
let date = cur_frm.doc.due_date;
|
||||||
|
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||||
|
frappe.timeout(0.5);
|
||||||
|
assert.ok(!cur_dialog, 'Message is not shown');
|
||||||
|
},
|
||||||
|
() => cur_frm.save(),
|
||||||
() => frappe.tests.click_button('Submit'),
|
() => frappe.tests.click_button('Submit'),
|
||||||
() => frappe.tests.click_button('Yes'),
|
() => frappe.tests.click_button('Yes'),
|
||||||
() => frappe.timeout(1),
|
() => frappe.timeout(1),
|
||||||
|
@ -6,7 +6,7 @@ from __future__ import unicode_literals
|
|||||||
import unittest
|
import unittest
|
||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
import frappe.model
|
import frappe.model
|
||||||
from frappe.utils import cint, flt, today, nowdate, getdate, add_days
|
from frappe.utils import cint, flt, today, nowdate, add_days
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
|
||||||
test_records as pr_test_records
|
test_records as pr_test_records
|
||||||
@ -27,6 +27,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
unlink_payment_on_cancel_of_invoice(0)
|
unlink_payment_on_cancel_of_invoice(0)
|
||||||
|
|
||||||
def test_gl_entries_without_perpetual_inventory(self):
|
def test_gl_entries_without_perpetual_inventory(self):
|
||||||
|
frappe.db.set_value("Company", "_Test Company", "round_off_account", "Round Off - _TC")
|
||||||
wrapper = frappe.copy_doc(test_records[0])
|
wrapper = frappe.copy_doc(test_records[0])
|
||||||
set_perpetual_inventory(0, wrapper.company)
|
set_perpetual_inventory(0, wrapper.company)
|
||||||
self.assertTrue(not cint(erpnext.is_perpetual_inventory_enabled(wrapper.company)))
|
self.assertTrue(not cint(erpnext.is_perpetual_inventory_enabled(wrapper.company)))
|
||||||
@ -647,39 +648,6 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
self.assertEquals(pi.total_taxes_and_charges, 462.3)
|
self.assertEquals(pi.total_taxes_and_charges, 462.3)
|
||||||
self.assertEquals(pi.grand_total, 1712.3)
|
self.assertEquals(pi.grand_total, 1712.3)
|
||||||
|
|
||||||
def test_gl_entry_based_on_payment_schedule(self):
|
|
||||||
pi = make_purchase_invoice(do_not_save=True, supplier="_Test Supplier P")
|
|
||||||
pi.append("payment_schedule", {
|
|
||||||
"due_date": add_days(nowdate(), 15),
|
|
||||||
"payment_amount": 100,
|
|
||||||
"invoice_portion": 40.00
|
|
||||||
})
|
|
||||||
pi.append("payment_schedule", {
|
|
||||||
"due_date": add_days(nowdate(), 25),
|
|
||||||
"payment_amount": 150,
|
|
||||||
"invoice_portion": 60.00
|
|
||||||
})
|
|
||||||
|
|
||||||
pi.save()
|
|
||||||
pi.submit()
|
|
||||||
|
|
||||||
gl_entries = frappe.db.sql("""select account, debit, credit, due_date
|
|
||||||
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
|
|
||||||
order by account asc, debit asc""", pi.name, as_dict=1)
|
|
||||||
self.assertTrue(gl_entries)
|
|
||||||
|
|
||||||
expected_gl_entries = sorted([
|
|
||||||
[pi.credit_to, 0.0, 100.0, add_days(nowdate(), 15)],
|
|
||||||
[pi.credit_to, 0.0, 150.0, add_days(nowdate(), 25)],
|
|
||||||
["_Test Account Cost for Goods Sold - _TC", 250.0, 0.0, None]
|
|
||||||
])
|
|
||||||
|
|
||||||
for i, gle in enumerate(sorted(gl_entries, key=lambda gle: gle.account)):
|
|
||||||
self.assertEquals(expected_gl_entries[i][0], gle.account)
|
|
||||||
self.assertEquals(expected_gl_entries[i][1], gle.debit)
|
|
||||||
self.assertEquals(expected_gl_entries[i][2], gle.credit)
|
|
||||||
self.assertEquals(getdate(expected_gl_entries[i][3]), getdate(gle.due_date))
|
|
||||||
|
|
||||||
def test_make_pi_without_terms(self):
|
def test_make_pi_without_terms(self):
|
||||||
pi = make_purchase_invoice(do_not_save=1)
|
pi = make_purchase_invoice(do_not_save=1)
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.accounts.doctype.sales_taxes_and_charges_template.sales_taxes_and_charges_template \
|
from erpnext.accounts.doctype.sales_taxes_and_charges_template.sales_taxes_and_charges_template \
|
||||||
import valdiate_taxes_and_charges_template
|
import valdiate_taxes_and_charges_template
|
||||||
@ -10,3 +11,8 @@ from erpnext.accounts.doctype.sales_taxes_and_charges_template.sales_taxes_and_c
|
|||||||
class PurchaseTaxesandChargesTemplate(Document):
|
class PurchaseTaxesandChargesTemplate(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
valdiate_taxes_and_charges_template(self)
|
valdiate_taxes_and_charges_template(self)
|
||||||
|
|
||||||
|
def autoname(self):
|
||||||
|
if self.company and self.title:
|
||||||
|
abbr = frappe.db.get_value('Company', self.company, 'abbr')
|
||||||
|
self.name = '{0} - {1}'.format(self.title, abbr)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
QUnit.module('Sales Taxes and Charges Template');
|
QUnit.module('Sales Taxes and Charges Template');
|
||||||
|
|
||||||
QUnit.test("test sales taxes and charges template", function(assert) {
|
QUnit.test("test sales taxes and charges template", function(assert) {
|
||||||
assert.expect(1);
|
assert.expect(2);
|
||||||
let done = assert.async();
|
let done = assert.async();
|
||||||
frappe.run_serially([
|
frappe.run_serially([
|
||||||
() => {
|
() => {
|
||||||
@ -19,7 +19,10 @@ QUnit.test("test sales taxes and charges template", function(assert) {
|
|||||||
]}
|
]}
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
() => {assert.ok(cur_frm.doc.title=='TEST In State GST');},
|
() => {
|
||||||
|
assert.ok(cur_frm.doc.title=='TEST In State GST');
|
||||||
|
assert.ok(cur_frm.doc.name=='TEST In State GST - FT');
|
||||||
|
},
|
||||||
() => done()
|
() => done()
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
@ -503,7 +503,7 @@
|
|||||||
"oldfieldname": "due_date",
|
"oldfieldname": "due_date",
|
||||||
"oldfieldtype": "Date",
|
"oldfieldtype": "Date",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 1,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
@ -2864,7 +2864,7 @@
|
|||||||
"options": "Payment Schedule",
|
"options": "Payment Schedule",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 1,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
@ -4563,7 +4563,7 @@
|
|||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"menu_index": 0,
|
"menu_index": 0,
|
||||||
"modified": "2017-11-29 17:36:05.216046",
|
"modified": "2017-12-20 17:36:05.216046",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice",
|
"name": "Sales Invoice",
|
||||||
|
@ -143,6 +143,7 @@ class SalesInvoice(SellingController):
|
|||||||
self.update_time_sheet(self.name)
|
self.update_time_sheet(self.name)
|
||||||
|
|
||||||
self.update_current_month_sales()
|
self.update_current_month_sales()
|
||||||
|
self.update_project()
|
||||||
|
|
||||||
def validate_pos_paid_amount(self):
|
def validate_pos_paid_amount(self):
|
||||||
if len(self.payments) == 0 and self.is_pos:
|
if len(self.payments) == 0 and self.is_pos:
|
||||||
@ -181,6 +182,7 @@ class SalesInvoice(SellingController):
|
|||||||
frappe.db.set(self, 'status', 'Cancelled')
|
frappe.db.set(self, 'status', 'Cancelled')
|
||||||
|
|
||||||
self.update_current_month_sales()
|
self.update_current_month_sales()
|
||||||
|
self.update_project()
|
||||||
|
|
||||||
def update_current_month_sales(self):
|
def update_current_month_sales(self):
|
||||||
if frappe.flags.in_test:
|
if frappe.flags.in_test:
|
||||||
@ -635,27 +637,7 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
def make_customer_gl_entry(self, gl_entries):
|
def make_customer_gl_entry(self, gl_entries):
|
||||||
grand_total = self.rounded_total or self.grand_total
|
grand_total = self.rounded_total or self.grand_total
|
||||||
if self.get("payment_schedule"):
|
if grand_total:
|
||||||
for d in self.get("payment_schedule"):
|
|
||||||
payment_amount_in_company_currency = flt(d.payment_amount * self.conversion_rate,
|
|
||||||
d.precision("payment_amount"))
|
|
||||||
|
|
||||||
gl_entries.append(
|
|
||||||
self.get_gl_dict({
|
|
||||||
"account": self.debit_to,
|
|
||||||
"party_type": "Customer",
|
|
||||||
"party": self.customer,
|
|
||||||
"due_date": d.due_date,
|
|
||||||
"against": self.against_income_account,
|
|
||||||
"debit": payment_amount_in_company_currency,
|
|
||||||
"debit_in_account_currency": payment_amount_in_company_currency \
|
|
||||||
if self.party_account_currency==self.company_currency else d.payment_amount,
|
|
||||||
"against_voucher": self.return_against if cint(self.is_return) else self.name,
|
|
||||||
"against_voucher_type": self.doctype
|
|
||||||
}, self.party_account_currency)
|
|
||||||
)
|
|
||||||
|
|
||||||
elif grand_total:
|
|
||||||
# Didnot use base_grand_total to book rounding loss gle
|
# Didnot use base_grand_total to book rounding loss gle
|
||||||
grand_total_in_company_currency = flt(grand_total * self.conversion_rate,
|
grand_total_in_company_currency = flt(grand_total * self.conversion_rate,
|
||||||
self.precision("grand_total"))
|
self.precision("grand_total"))
|
||||||
@ -912,6 +894,13 @@ class SalesInvoice(SellingController):
|
|||||||
serial_no, sales_invoice
|
serial_no, sales_invoice
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
def update_project(self):
|
||||||
|
if self.project:
|
||||||
|
project = frappe.get_doc("Project", self.project)
|
||||||
|
project.flags.dont_sync_tasks = True
|
||||||
|
project.update_billed_amount()
|
||||||
|
project.save()
|
||||||
|
|
||||||
def get_list_context(context=None):
|
def get_list_context(context=None):
|
||||||
from erpnext.controllers.website_list_for_contact import get_list_context
|
from erpnext.controllers.website_list_for_contact import get_list_context
|
||||||
list_context = get_list_context(context)
|
list_context = get_list_context(context)
|
||||||
@ -991,4 +980,4 @@ def make_sales_return(source_name, target_doc=None):
|
|||||||
def set_account_for_mode_of_payment(self):
|
def set_account_for_mode_of_payment(self):
|
||||||
for data in self.payments:
|
for data in self.payments:
|
||||||
if not data.account:
|
if not data.account:
|
||||||
data.account = get_bank_cash_account(data.mode_of_payment, self.company).get("account")
|
data.account = get_bank_cash_account(data.mode_of_payment, self.company).get("account")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
QUnit.module('Sales Invoice');
|
QUnit.module('Sales Invoice');
|
||||||
|
|
||||||
QUnit.test("test sales Invoice", function(assert) {
|
QUnit.test("test sales Invoice", function(assert) {
|
||||||
assert.expect(6);
|
assert.expect(9);
|
||||||
let done = assert.async();
|
let done = assert.async();
|
||||||
frappe.run_serially([
|
frappe.run_serially([
|
||||||
() => {
|
() => {
|
||||||
@ -17,7 +17,7 @@ QUnit.test("test sales Invoice", function(assert) {
|
|||||||
{customer_address: 'Test1-Billing'},
|
{customer_address: 'Test1-Billing'},
|
||||||
{shipping_address_name: 'Test1-Shipping'},
|
{shipping_address_name: 'Test1-Shipping'},
|
||||||
{contact_person: 'Contact 1-Test Customer 1'},
|
{contact_person: 'Contact 1-Test Customer 1'},
|
||||||
{taxes_and_charges: 'TEST In State GST'},
|
{taxes_and_charges: 'TEST In State GST - FT'},
|
||||||
{tc_name: 'Test Term 1'},
|
{tc_name: 'Test Term 1'},
|
||||||
{terms: 'This is Test'},
|
{terms: 'This is Test'},
|
||||||
{payment_terms_template: '_Test Payment Term Template UI'}
|
{payment_terms_template: '_Test Payment Term Template UI'}
|
||||||
@ -28,7 +28,7 @@ QUnit.test("test sales Invoice", function(assert) {
|
|||||||
// get_item_details
|
// get_item_details
|
||||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||||
// get tax details
|
// get tax details
|
||||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||||
// get tax account head details
|
// get tax account head details
|
||||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||||
// grand_total Calculated
|
// grand_total Calculated
|
||||||
@ -38,6 +38,33 @@ QUnit.test("test sales Invoice", function(assert) {
|
|||||||
assert.ok(cur_frm.doc.payment_schedule.length > 0, "Payment Term Schedule is not empty");
|
assert.ok(cur_frm.doc.payment_schedule.length > 0, "Payment Term Schedule is not empty");
|
||||||
|
|
||||||
},
|
},
|
||||||
|
() => {
|
||||||
|
let date = cur_frm.doc.due_date;
|
||||||
|
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||||
|
frappe.timeout(0.5);
|
||||||
|
assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user');
|
||||||
|
},
|
||||||
|
() => frappe.timeout(1),
|
||||||
|
() => frappe.tests.click_button('Close'),
|
||||||
|
() => frappe.timeout(0.5),
|
||||||
|
() => frappe.tests.set_form_values(cur_frm, [{'payment_terms_schedule': ''}]),
|
||||||
|
() => {
|
||||||
|
let date = cur_frm.doc.due_date;
|
||||||
|
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||||
|
frappe.timeout(0.5);
|
||||||
|
assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user');
|
||||||
|
},
|
||||||
|
() => frappe.timeout(1),
|
||||||
|
() => frappe.tests.click_button('Close'),
|
||||||
|
() => frappe.timeout(0.5),
|
||||||
|
() => frappe.tests.set_form_values(cur_frm, [{'payment_schedule': []}]),
|
||||||
|
() => {
|
||||||
|
let date = cur_frm.doc.due_date;
|
||||||
|
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||||
|
frappe.timeout(0.5);
|
||||||
|
assert.ok(!cur_dialog, 'Message is not shown');
|
||||||
|
},
|
||||||
|
() => cur_frm.save(),
|
||||||
() => frappe.tests.click_button('Submit'),
|
() => frappe.tests.click_button('Submit'),
|
||||||
() => frappe.tests.click_button('Yes'),
|
() => frappe.tests.click_button('Yes'),
|
||||||
() => frappe.timeout(0.3),
|
() => frappe.timeout(0.3),
|
||||||
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
import unittest, copy, time
|
import unittest, copy, time
|
||||||
from frappe.utils import nowdate, add_days, flt, getdate, cint
|
from frappe.utils import nowdate, flt, getdate, cint
|
||||||
from frappe.model.dynamic_links import get_dynamic_link_map
|
from frappe.model.dynamic_links import get_dynamic_link_map
|
||||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
|
||||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice
|
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice
|
||||||
@ -1321,40 +1321,6 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
})
|
})
|
||||||
si.insert()
|
si.insert()
|
||||||
return si
|
return si
|
||||||
|
|
||||||
def test_gl_entry_based_on_payment_schedule(self):
|
|
||||||
si = create_sales_invoice(do_not_save=True, customer="_Test Customer P")
|
|
||||||
si.append("payment_schedule", {
|
|
||||||
"due_date": add_days(nowdate(), 15),
|
|
||||||
"payment_amount": 20,
|
|
||||||
"invoice_portion": 20.00
|
|
||||||
})
|
|
||||||
si.append("payment_schedule", {
|
|
||||||
"due_date": add_days(nowdate(), 45),
|
|
||||||
"payment_amount": 80,
|
|
||||||
"invoice_portion": 80.00
|
|
||||||
})
|
|
||||||
|
|
||||||
si.save()
|
|
||||||
si.submit()
|
|
||||||
|
|
||||||
gl_entries = frappe.db.sql("""select account, debit, credit, due_date
|
|
||||||
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
|
|
||||||
order by account asc, debit asc""", si.name, as_dict=1)
|
|
||||||
self.assertTrue(gl_entries)
|
|
||||||
|
|
||||||
expected_gl_entries = sorted([
|
|
||||||
[si.debit_to, 20.0, 0.0, add_days(nowdate(), 15)],
|
|
||||||
[si.debit_to, 80.0, 0.0, add_days(nowdate(), 45)],
|
|
||||||
["Sales - _TC", 0.0, 100.0, None]
|
|
||||||
])
|
|
||||||
|
|
||||||
for i, gle in enumerate(sorted(gl_entries, key=lambda gle: gle.account)):
|
|
||||||
self.assertEquals(expected_gl_entries[i][0], gle.account)
|
|
||||||
self.assertEquals(expected_gl_entries[i][1], gle.debit)
|
|
||||||
self.assertEquals(expected_gl_entries[i][2], gle.credit)
|
|
||||||
self.assertEquals(getdate(expected_gl_entries[i][3]), getdate(gle.due_date))
|
|
||||||
|
|
||||||
|
|
||||||
def test_company_monthly_sales(self):
|
def test_company_monthly_sales(self):
|
||||||
existing_current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
|
existing_current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
|
||||||
|
@ -17,7 +17,7 @@ QUnit.test("test sales Invoice", function(assert) {
|
|||||||
{customer_address: 'Test1-Billing'},
|
{customer_address: 'Test1-Billing'},
|
||||||
{shipping_address_name: 'Test1-Shipping'},
|
{shipping_address_name: 'Test1-Shipping'},
|
||||||
{contact_person: 'Contact 1-Test Customer 1'},
|
{contact_person: 'Contact 1-Test Customer 1'},
|
||||||
{taxes_and_charges: 'TEST In State GST'},
|
{taxes_and_charges: 'TEST In State GST - FT'},
|
||||||
{tc_name: 'Test Term 1'},
|
{tc_name: 'Test Term 1'},
|
||||||
{terms: 'This is Test'}
|
{terms: 'This is Test'}
|
||||||
]);
|
]);
|
||||||
@ -27,7 +27,7 @@ QUnit.test("test sales Invoice", function(assert) {
|
|||||||
// get_item_details
|
// get_item_details
|
||||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||||
// get tax details
|
// get tax details
|
||||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||||
// get tax account head details
|
// get tax account head details
|
||||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||||
// grand_total Calculated
|
// grand_total Calculated
|
||||||
|
@ -17,7 +17,7 @@ QUnit.test("test sales Invoice with payment", function(assert) {
|
|||||||
{customer_address: 'Test1-Billing'},
|
{customer_address: 'Test1-Billing'},
|
||||||
{shipping_address_name: 'Test1-Shipping'},
|
{shipping_address_name: 'Test1-Shipping'},
|
||||||
{contact_person: 'Contact 1-Test Customer 1'},
|
{contact_person: 'Contact 1-Test Customer 1'},
|
||||||
{taxes_and_charges: 'TEST In State GST'},
|
{taxes_and_charges: 'TEST In State GST - FT'},
|
||||||
{tc_name: 'Test Term 1'},
|
{tc_name: 'Test Term 1'},
|
||||||
{terms: 'This is Test'},
|
{terms: 'This is Test'},
|
||||||
{payment_terms_template: '_Test Payment Term Template UI'}
|
{payment_terms_template: '_Test Payment Term Template UI'}
|
||||||
@ -28,7 +28,7 @@ QUnit.test("test sales Invoice with payment", function(assert) {
|
|||||||
// get_item_details
|
// get_item_details
|
||||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||||
// get tax details
|
// get tax details
|
||||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||||
// grand_total Calculated
|
// grand_total Calculated
|
||||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ QUnit.test("test sales Invoice with payment request", function(assert) {
|
|||||||
{customer_address: 'Test1-Billing'},
|
{customer_address: 'Test1-Billing'},
|
||||||
{shipping_address_name: 'Test1-Shipping'},
|
{shipping_address_name: 'Test1-Shipping'},
|
||||||
{contact_person: 'Contact 1-Test Customer 1'},
|
{contact_person: 'Contact 1-Test Customer 1'},
|
||||||
{taxes_and_charges: 'TEST In State GST'},
|
{taxes_and_charges: 'TEST In State GST - FT'},
|
||||||
{tc_name: 'Test Term 1'},
|
{tc_name: 'Test Term 1'},
|
||||||
{terms: 'This is Test'}
|
{terms: 'This is Test'}
|
||||||
]);
|
]);
|
||||||
@ -27,7 +27,7 @@ QUnit.test("test sales Invoice with payment request", function(assert) {
|
|||||||
// get_item_details
|
// get_item_details
|
||||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||||
// get tax details
|
// get tax details
|
||||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||||
// grand_total Calculated
|
// grand_total Calculated
|
||||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ QUnit.test("test sales Invoice with serialize item", function(assert) {
|
|||||||
{customer_address: 'Test1-Billing'},
|
{customer_address: 'Test1-Billing'},
|
||||||
{shipping_address_name: 'Test1-Shipping'},
|
{shipping_address_name: 'Test1-Shipping'},
|
||||||
{contact_person: 'Contact 1-Test Customer 1'},
|
{contact_person: 'Contact 1-Test Customer 1'},
|
||||||
{taxes_and_charges: 'TEST In State GST'},
|
{taxes_and_charges: 'TEST In State GST - FT'},
|
||||||
{tc_name: 'Test Term 1'},
|
{tc_name: 'Test Term 1'},
|
||||||
{terms: 'This is Test'}
|
{terms: 'This is Test'}
|
||||||
]);
|
]);
|
||||||
@ -27,7 +27,7 @@ QUnit.test("test sales Invoice with serialize item", function(assert) {
|
|||||||
// get_item_details
|
// get_item_details
|
||||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
|
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
|
||||||
// get tax details
|
// get tax details
|
||||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||||
// get tax account head details
|
// get tax account head details
|
||||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||||
// get batch number
|
// get batch number
|
||||||
|
@ -11,7 +11,12 @@ from erpnext.controllers.accounts_controller import validate_taxes_and_charges,
|
|||||||
class SalesTaxesandChargesTemplate(Document):
|
class SalesTaxesandChargesTemplate(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
valdiate_taxes_and_charges_template(self)
|
valdiate_taxes_and_charges_template(self)
|
||||||
|
|
||||||
|
def autoname(self):
|
||||||
|
if self.company and self.title:
|
||||||
|
abbr = frappe.db.get_value('Company', self.company, 'abbr')
|
||||||
|
self.name = '{0} - {1}'.format(self.title, abbr)
|
||||||
|
|
||||||
def set_missing_values(self):
|
def set_missing_values(self):
|
||||||
for data in self.taxes:
|
for data in self.taxes:
|
||||||
if data.charge_type == 'On Net Total' and flt(data.rate) == 0.0:
|
if data.charge_type == 'On Net Total' and flt(data.rate) == 0.0:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
QUnit.module('Sales Taxes and Charges Template');
|
QUnit.module('Sales Taxes and Charges Template');
|
||||||
|
|
||||||
QUnit.test("test sales taxes and charges template", function(assert) {
|
QUnit.test("test sales taxes and charges template", function(assert) {
|
||||||
assert.expect(1);
|
assert.expect(2);
|
||||||
let done = assert.async();
|
let done = assert.async();
|
||||||
frappe.run_serially([
|
frappe.run_serially([
|
||||||
() => {
|
() => {
|
||||||
@ -19,7 +19,10 @@ QUnit.test("test sales taxes and charges template", function(assert) {
|
|||||||
]}
|
]}
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
() => {assert.ok(cur_frm.doc.title=='TEST In State GST');},
|
() => {
|
||||||
|
assert.ok(cur_frm.doc.title=='TEST In State GST');
|
||||||
|
assert.ok(cur_frm.doc.name=='TEST In State GST - FT');
|
||||||
|
},
|
||||||
() => done()
|
() => done()
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"doctype": "Tax Rule",
|
"doctype": "Tax Rule",
|
||||||
"tax_type" : "Sales",
|
"tax_type" : "Sales",
|
||||||
"sales_tax_template": "_Test Tax 1",
|
"sales_tax_template": "_Test Tax 1 - _TC",
|
||||||
"use_for_shopping_cart": 1,
|
"use_for_shopping_cart": 1,
|
||||||
"billing_city": "_Test City",
|
"billing_city": "_Test City",
|
||||||
"billing_state": "Test State",
|
"billing_state": "Test State",
|
||||||
@ -15,7 +15,7 @@
|
|||||||
{
|
{
|
||||||
"doctype": "Tax Rule",
|
"doctype": "Tax Rule",
|
||||||
"tax_type" : "Sales",
|
"tax_type" : "Sales",
|
||||||
"sales_tax_template": "_Test Tax 2",
|
"sales_tax_template": "_Test Tax 2 - _TC",
|
||||||
"use_for_shopping_cart": 0,
|
"use_for_shopping_cart": 0,
|
||||||
"billing_city": "_Test City",
|
"billing_city": "_Test City",
|
||||||
"billing_country": "India",
|
"billing_country": "India",
|
||||||
|
@ -18,40 +18,40 @@ class TestTaxRule(unittest.TestCase):
|
|||||||
|
|
||||||
def test_conflict(self):
|
def test_conflict(self):
|
||||||
tax_rule1 = make_tax_rule(customer= "_Test Customer",
|
tax_rule1 = make_tax_rule(customer= "_Test Customer",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1)
|
||||||
tax_rule1.save()
|
tax_rule1.save()
|
||||||
|
|
||||||
tax_rule2 = make_tax_rule(customer= "_Test Customer",
|
tax_rule2 = make_tax_rule(customer= "_Test Customer",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1)
|
||||||
|
|
||||||
self.assertRaises(ConflictingTaxRule, tax_rule2.save)
|
self.assertRaises(ConflictingTaxRule, tax_rule2.save)
|
||||||
|
|
||||||
def test_conflict_with_non_overlapping_dates(self):
|
def test_conflict_with_non_overlapping_dates(self):
|
||||||
tax_rule1 = make_tax_rule(customer= "_Test Customer",
|
tax_rule1 = make_tax_rule(customer= "_Test Customer",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01")
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, from_date = "2015-01-01")
|
||||||
tax_rule1.save()
|
tax_rule1.save()
|
||||||
|
|
||||||
tax_rule2 = make_tax_rule(customer= "_Test Customer",
|
tax_rule2 = make_tax_rule(customer= "_Test Customer",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, to_date = "2013-01-01")
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, to_date = "2013-01-01")
|
||||||
|
|
||||||
tax_rule2.save()
|
tax_rule2.save()
|
||||||
self.assertTrue(tax_rule2.name)
|
self.assertTrue(tax_rule2.name)
|
||||||
|
|
||||||
def test_for_parent_customer_group(self):
|
def test_for_parent_customer_group(self):
|
||||||
tax_rule1 = make_tax_rule(customer_group= "All Customer Groups",
|
tax_rule1 = make_tax_rule(customer_group= "All Customer Groups",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01")
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, from_date = "2015-01-01")
|
||||||
tax_rule1.save()
|
tax_rule1.save()
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial", "use_for_shopping_cart":0}),
|
self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial", "use_for_shopping_cart":0}),
|
||||||
"_Test Sales Taxes and Charges Template")
|
"_Test Sales Taxes and Charges Template - _TC")
|
||||||
|
|
||||||
def test_conflict_with_overlapping_dates(self):
|
def test_conflict_with_overlapping_dates(self):
|
||||||
tax_rule1 = make_tax_rule(customer= "_Test Customer",
|
tax_rule1 = make_tax_rule(customer= "_Test Customer",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01", to_date = "2015-01-05")
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, from_date = "2015-01-01", to_date = "2015-01-05")
|
||||||
tax_rule1.save()
|
tax_rule1.save()
|
||||||
|
|
||||||
tax_rule2 = make_tax_rule(customer= "_Test Customer",
|
tax_rule2 = make_tax_rule(customer= "_Test Customer",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-03", to_date = "2015-01-09")
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, from_date = "2015-01-03", to_date = "2015-01-09")
|
||||||
|
|
||||||
self.assertRaises(ConflictingTaxRule, tax_rule2.save)
|
self.assertRaises(ConflictingTaxRule, tax_rule2.save)
|
||||||
|
|
||||||
@ -62,66 +62,66 @@ class TestTaxRule(unittest.TestCase):
|
|||||||
|
|
||||||
def test_select_tax_rule_based_on_customer(self):
|
def test_select_tax_rule_based_on_customer(self):
|
||||||
make_tax_rule(customer= "_Test Customer",
|
make_tax_rule(customer= "_Test Customer",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", save=1)
|
||||||
|
|
||||||
make_tax_rule(customer= "_Test Customer 1",
|
make_tax_rule(customer= "_Test Customer 1",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
|
||||||
|
|
||||||
make_tax_rule(customer= "_Test Customer 2",
|
make_tax_rule(customer= "_Test Customer 2",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 2", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 2 - _TC", save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer 2"}),
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer 2"}),
|
||||||
"_Test Sales Taxes and Charges Template 2")
|
"_Test Sales Taxes and Charges Template 2 - _TC")
|
||||||
|
|
||||||
def test_select_tax_rule_based_on_better_match(self):
|
def test_select_tax_rule_based_on_better_match(self):
|
||||||
make_tax_rule(customer= "_Test Customer", billing_city = "Test City", billing_state = "Test State",
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City", billing_state = "Test State",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", save=1)
|
||||||
|
|
||||||
make_tax_rule(customer= "_Test Customer", billing_city = "Test City1", billing_state = "Test State",
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City1", billing_state = "Test State",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City", "billing_state": "Test State"}),
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City", "billing_state": "Test State"}),
|
||||||
"_Test Sales Taxes and Charges Template")
|
"_Test Sales Taxes and Charges Template - _TC")
|
||||||
|
|
||||||
def test_select_tax_rule_based_on_state_match(self):
|
def test_select_tax_rule_based_on_state_match(self):
|
||||||
make_tax_rule(customer= "_Test Customer", shipping_state = "Test State",
|
make_tax_rule(customer= "_Test Customer", shipping_state = "Test State",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", save=1)
|
||||||
|
|
||||||
make_tax_rule(customer= "_Test Customer", shipping_state = "Test State12",
|
make_tax_rule(customer= "_Test Customer", shipping_state = "Test State12",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 1", priority=2, save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", priority=2, save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "shipping_state": "Test State"}),
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "shipping_state": "Test State"}),
|
||||||
"_Test Sales Taxes and Charges Template")
|
"_Test Sales Taxes and Charges Template - _TC")
|
||||||
|
|
||||||
def test_select_tax_rule_based_on_better_priority(self):
|
def test_select_tax_rule_based_on_better_priority(self):
|
||||||
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", priority=1, save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority=1, save=1)
|
||||||
|
|
||||||
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 1", priority=2, save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", priority=2, save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City"}),
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City"}),
|
||||||
"_Test Sales Taxes and Charges Template 1")
|
"_Test Sales Taxes and Charges Template 1 - _TC")
|
||||||
|
|
||||||
def test_select_tax_rule_based_cross_matching_keys(self):
|
def test_select_tax_rule_based_cross_matching_keys(self):
|
||||||
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", save=1)
|
||||||
|
|
||||||
make_tax_rule(customer= "_Test Customer 1", billing_city = "Test City 1",
|
make_tax_rule(customer= "_Test Customer 1", billing_city = "Test City 1",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
|
||||||
None)
|
None)
|
||||||
|
|
||||||
def test_select_tax_rule_based_cross_partially_keys(self):
|
def test_select_tax_rule_based_cross_partially_keys(self):
|
||||||
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", save=1)
|
||||||
|
|
||||||
make_tax_rule(billing_city = "Test City 1",
|
make_tax_rule(billing_city = "Test City 1",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
|
||||||
"_Test Sales Taxes and Charges Template 1")
|
"_Test Sales Taxes and Charges Template 1 - _TC")
|
||||||
|
|
||||||
|
|
||||||
def make_tax_rule(**args):
|
def make_tax_rule(**args):
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
from frappe.utils import flt, cstr, cint, getdate
|
from frappe.utils import flt, cstr, cint
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.meta import get_field_precision
|
from frappe.model.meta import get_field_precision
|
||||||
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
|
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
|
||||||
@ -75,8 +75,7 @@ def check_if_in_list(gle, gl_map):
|
|||||||
and cstr(e.get('against_voucher'))==cstr(gle.get('against_voucher')) \
|
and cstr(e.get('against_voucher'))==cstr(gle.get('against_voucher')) \
|
||||||
and cstr(e.get('against_voucher_type')) == cstr(gle.get('against_voucher_type')) \
|
and cstr(e.get('against_voucher_type')) == cstr(gle.get('against_voucher_type')) \
|
||||||
and cstr(e.get('cost_center')) == cstr(gle.get('cost_center')) \
|
and cstr(e.get('cost_center')) == cstr(gle.get('cost_center')) \
|
||||||
and cstr(e.get('project')) == cstr(gle.get('project')) \
|
and cstr(e.get('project')) == cstr(gle.get('project')):
|
||||||
and getdate(e.get('due_date')) == getdate(gle.get('due_date')):
|
|
||||||
return e
|
return e
|
||||||
|
|
||||||
def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
|
def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
"align_labels_right": 0,
|
"align_labels_right": 0,
|
||||||
"creation": "2017-08-08 12:33:04.773099",
|
"creation": "2017-08-08 12:33:04.773099",
|
||||||
"custom_format": 1,
|
"custom_format": 1,
|
||||||
"disabled": 0,
|
"disabled": 1,
|
||||||
"doc_type": "Sales Invoice",
|
"doc_type": "Sales Invoice",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Print Format",
|
"doctype": "Print Format",
|
||||||
"font": "Default",
|
"font": "Default",
|
||||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ _(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"net_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t{%- if not row.included_in_print_rate -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
|
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"line_breaks": 0,
|
"line_breaks": 0,
|
||||||
"modified": "2017-09-14 15:54:19.467642",
|
"modified": "2018-01-05 17:25:59.181985",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "GST POS Invoice",
|
"name": "GST POS Invoice",
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
{
|
{
|
||||||
|
"align_labels_right": 0,
|
||||||
"creation": "2011-12-21 11:08:55",
|
"creation": "2011-12-21 11:08:55",
|
||||||
"custom_format": 1,
|
"custom_format": 1,
|
||||||
|
"disabled": 0,
|
||||||
"doc_type": "Sales Invoice",
|
"doc_type": "Sales Invoice",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Print Format",
|
"doctype": "Print Format",
|
||||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{{ doc.select_print_heading or _(\"Invoice\") }}<br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t<b>{{ _(\"Customer\") }}:</b> {{ doc.customer_name }}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.get_formatted(\"rate\") }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ _(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"net_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t{%- if not row.included_in_print_rate -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n{% if doc.get(\"taxes\", filters={\"included_in_print_rate\": 1}) %}\n<hr>\n<p><b>Taxes Included:</b></p>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t{%- for row in doc.taxes -%}\n\t\t{%- if row.included_in_print_rate -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ row.get_formatted(\"tax_amount_after_discount_amount\", doc) }}\n\t\t\t</td>\n\t\t<tr>\n\t\t{%- endif -%}\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n{%- endif -%}\n<hr>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
|
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{{ doc.select_print_heading or _(\"Invoice\") }}<br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t<b>{{ _(\"Customer\") }}:</b> {{ doc.customer_name }}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.get_formatted(\"rate\") }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n<hr>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"modified": "2015-04-21 05:06:29.380856",
|
"line_breaks": 0,
|
||||||
|
"modified": "2018-01-05 17:23:40.403289",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
"name": "POS Invoice",
|
"name": "POS Invoice",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
|
"print_format_builder": 0,
|
||||||
"print_format_type": "Server",
|
"print_format_type": "Server",
|
||||||
|
"show_section_headings": 0,
|
||||||
"standard": "Yes"
|
"standard": "Yes"
|
||||||
}
|
}
|
@ -113,7 +113,7 @@ class ReceivablePayableReport(object):
|
|||||||
row += [self.get_party_name(gle.party_type, gle.party)]
|
row += [self.get_party_name(gle.party_type, gle.party)]
|
||||||
|
|
||||||
# get due date
|
# get due date
|
||||||
due_date = gle.due_date or voucher_details.get(gle.voucher_no, {}).get("due_date", "")
|
due_date = voucher_details.get(gle.voucher_no, {}).get("due_date", "")
|
||||||
|
|
||||||
row += [gle.voucher_type, gle.voucher_no, due_date]
|
row += [gle.voucher_type, gle.voucher_no, due_date]
|
||||||
|
|
||||||
@ -188,8 +188,7 @@ class ReceivablePayableReport(object):
|
|||||||
reverse_dr_or_cr = "credit" if dr_or_cr=="debit" else "debit"
|
reverse_dr_or_cr = "credit" if dr_or_cr=="debit" else "debit"
|
||||||
|
|
||||||
for e in self.get_gl_entries_for(gle.party, gle.party_type, gle.voucher_type, gle.voucher_no):
|
for e in self.get_gl_entries_for(gle.party, gle.party_type, gle.voucher_type, gle.voucher_no):
|
||||||
if getdate(e.posting_date) <= report_date and e.name!=gle.name \
|
if getdate(e.posting_date) <= report_date and e.name!=gle.name:
|
||||||
and (not gle.due_date or getdate(e.due_date) == getdate(gle.due_date)):
|
|
||||||
amount = flt(e.get(reverse_dr_or_cr)) - flt(e.get(dr_or_cr))
|
amount = flt(e.get(reverse_dr_or_cr)) - flt(e.get(dr_or_cr))
|
||||||
if e.voucher_no not in return_entries:
|
if e.voucher_no not in return_entries:
|
||||||
payment_amount += amount
|
payment_amount += amount
|
||||||
@ -251,11 +250,11 @@ class ReceivablePayableReport(object):
|
|||||||
select_fields = "sum(debit) as debit, sum(credit) as credit"
|
select_fields = "sum(debit) as debit, sum(credit) as credit"
|
||||||
|
|
||||||
self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party,
|
self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party,
|
||||||
voucher_type, voucher_no, against_voucher_type, against_voucher, due_date,
|
voucher_type, voucher_no, against_voucher_type, against_voucher,
|
||||||
account_currency, remarks, {0}
|
account_currency, remarks, {0}
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where docstatus < 2 and party_type=%s and (party is not null and party != '') {1}
|
where docstatus < 2 and party_type=%s and (party is not null and party != '') {1}
|
||||||
group by voucher_type, voucher_no, against_voucher_type, against_voucher, party, due_date
|
group by voucher_type, voucher_no, against_voucher_type, against_voucher, party
|
||||||
order by posting_date, party"""
|
order by posting_date, party"""
|
||||||
.format(select_fields, conditions), values, as_dict=True)
|
.format(select_fields, conditions), values, as_dict=True)
|
||||||
|
|
||||||
|
@ -193,6 +193,24 @@ def get_data_with_opening_closing(filters, account_details, gl_entries):
|
|||||||
# closing
|
# closing
|
||||||
data.append(totals.closing)
|
data.append(totals.closing)
|
||||||
|
|
||||||
|
#total closing
|
||||||
|
total_closing = totals.total_closing
|
||||||
|
total_debit = totals.closing.get('debit', 0)
|
||||||
|
total_credit = totals.closing.get('credit', 0)
|
||||||
|
debit_in_account_currency = totals.closing.get('debit_in_account_currency', 0)
|
||||||
|
credit_in_account_currency = totals.closing.get('credit_in_account_currency', 0)
|
||||||
|
|
||||||
|
total_amount = total_debit - total_credit
|
||||||
|
|
||||||
|
if total_amount > 0:
|
||||||
|
total_closing['debit'] = total_amount
|
||||||
|
total_closing['debit_in_account_currency'] = debit_in_account_currency - credit_in_account_currency
|
||||||
|
else:
|
||||||
|
total_closing['credit'] = abs(total_amount)
|
||||||
|
total_closing['credit_in_account_currency'] = abs(debit_in_account_currency - credit_in_account_currency)
|
||||||
|
|
||||||
|
data.append(totals.total_closing)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def get_totals_dict():
|
def get_totals_dict():
|
||||||
@ -207,7 +225,8 @@ def get_totals_dict():
|
|||||||
return _dict(
|
return _dict(
|
||||||
opening = _get_debit_credit_dict(_('Opening')),
|
opening = _get_debit_credit_dict(_('Opening')),
|
||||||
total = _get_debit_credit_dict(_('Total')),
|
total = _get_debit_credit_dict(_('Total')),
|
||||||
closing = _get_debit_credit_dict(_('Closing (Opening + Total)'))
|
closing = _get_debit_credit_dict(_('Closing (Opening + Total)')),
|
||||||
|
total_closing = _get_debit_credit_dict(_('Closing Balance (Dr - Cr)'))
|
||||||
)
|
)
|
||||||
|
|
||||||
def initialize_gle_map(gl_entries):
|
def initialize_gle_map(gl_entries):
|
||||||
@ -233,6 +252,9 @@ def get_accountwise_gle(filters, gl_entries, gle_map):
|
|||||||
if gle.posting_date < from_date or cstr(gle.is_opening) == "Yes":
|
if gle.posting_date < from_date or cstr(gle.is_opening) == "Yes":
|
||||||
update_value_in_dict(gle_map[gle.account].totals, 'opening', gle)
|
update_value_in_dict(gle_map[gle.account].totals, 'opening', gle)
|
||||||
update_value_in_dict(totals, 'opening', gle)
|
update_value_in_dict(totals, 'opening', gle)
|
||||||
|
|
||||||
|
update_value_in_dict(gle_map[gle.account].totals, 'closing', gle)
|
||||||
|
update_value_in_dict(totals, 'closing', gle)
|
||||||
|
|
||||||
elif gle.posting_date <= to_date:
|
elif gle.posting_date <= to_date:
|
||||||
update_value_in_dict(gle_map[gle.account].totals, 'total', gle)
|
update_value_in_dict(gle_map[gle.account].totals, 'total', gle)
|
||||||
@ -242,8 +264,8 @@ def get_accountwise_gle(filters, gl_entries, gle_map):
|
|||||||
else:
|
else:
|
||||||
entries.append(gle)
|
entries.append(gle)
|
||||||
|
|
||||||
update_value_in_dict(gle_map[gle.account].totals, 'closing', gle)
|
update_value_in_dict(gle_map[gle.account].totals, 'closing', gle)
|
||||||
update_value_in_dict(totals, 'closing', gle)
|
update_value_in_dict(totals, 'closing', gle)
|
||||||
|
|
||||||
return totals, entries
|
return totals, entries
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
// License: GNU General Public License v3. See license.txt
|
// 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": [
|
"filters": [
|
||||||
{
|
{
|
||||||
"fieldname":"from_date",
|
"fieldname":"from_date",
|
||||||
|
@ -6,6 +6,7 @@ import frappe, erpnext
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from frappe.model.meta import get_field_precision
|
from frappe.model.meta import get_field_precision
|
||||||
|
from frappe.utils.xlsxutils import handle_html
|
||||||
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
|
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
@ -188,10 +189,10 @@ def get_tax_accounts(item_list, columns, company_currency,
|
|||||||
tuple([doctype] + invoice_item_row.keys()))
|
tuple([doctype] + invoice_item_row.keys()))
|
||||||
|
|
||||||
for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
||||||
|
description = handle_html(description)
|
||||||
if description not in tax_columns and tax_amount:
|
if description not in tax_columns and tax_amount:
|
||||||
# as description is text editor earlier and markup can break the column convention in reports
|
# as description is text editor earlier and markup can break the column convention in reports
|
||||||
from frappe.utils.xlsxutils import handle_html
|
tax_columns.append(description)
|
||||||
tax_columns.append(handle_html(description))
|
|
||||||
|
|
||||||
if item_wise_tax_detail:
|
if item_wise_tax_detail:
|
||||||
try:
|
try:
|
||||||
|
@ -15,12 +15,12 @@ def execute(filters=None):
|
|||||||
def get_column():
|
def get_column():
|
||||||
return [
|
return [
|
||||||
_("Purchase Receipt") + ":Link/Purchase Receipt:120", _("Date") + ":Date:100",
|
_("Purchase Receipt") + ":Link/Purchase Receipt:120", _("Date") + ":Date:100",
|
||||||
_("Suplier") + ":Link/Supplier:120", _("Suplier Name") + "::120",
|
_("Supplier") + ":Link/Supplier:120", _("Supplier Name") + "::120",
|
||||||
_("Project") + ":Link/Project:120", _("Item Code") + ":Link/Item:120",
|
_("Project") + ":Link/Project:120", _("Item Code") + ":Link/Item:120",
|
||||||
_("Amount") + ":Currency:100", _("Billed Amount") + ":Currency:100", _("Amount to Bill") + ":Currency:100",
|
_("Amount") + ":Currency:100", _("Billed Amount") + ":Currency:100", _("Amount to Bill") + ":Currency:100",
|
||||||
_("Item Name") + "::120", _("Description") + "::120", _("Company") + ":Link/Company:120",
|
_("Item Name") + "::120", _("Description") + "::120", _("Company") + ":Link/Company:120",
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_args():
|
def get_args():
|
||||||
return {'doctype': 'Purchase Receipt', 'party': 'supplier',
|
return {'doctype': 'Purchase Receipt', 'party': 'supplier',
|
||||||
'date': 'posting_date', 'order': 'name', 'order_by': 'desc'}
|
'date': 'posting_date', 'order': 'name', 'order_by': 'desc'}
|
@ -12,7 +12,7 @@
|
|||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Partners Commission",
|
"name": "Sales Partners Commission",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"query": "SELECT\n sales_partner as \"Sales Partner:Link/Sales Partner:150\",\n\tsum(base_net_total) as \"Invoiced Amount (Exculsive Tax):Currency:210\",\n\tsum(total_commission) as \"Total Commission:Currency:150\",\n\tsum(total_commission)*100/sum(base_net_total) as \"Average Commission Rate:Currency:170\"\nFROM\n\t`tabSales Invoice`\nWHERE\n\tdocstatus = 1 and ifnull(base_net_total, 0) > 0 and ifnull(total_commission, 0) > 0\nGROUP BY\n\tsales_partner\nORDER BY\n\t\"Total Commission:Currency:120\"",
|
"query": "SELECT\n sales_partner as \"Sales Partner:Link/Sales Partner:150\",\n\tsum(base_net_total) as \"Invoiced Amount (Exclusive Tax):Currency:210\",\n\tsum(total_commission) as \"Total Commission:Currency:150\",\n\tsum(total_commission)*100/sum(base_net_total) as \"Average Commission Rate:Currency:170\"\nFROM\n\t`tabSales Invoice`\nWHERE\n\tdocstatus = 1 and ifnull(base_net_total, 0) > 0 and ifnull(total_commission, 0) > 0\nGROUP BY\n\tsales_partner\nORDER BY\n\t\"Total Commission:Currency:120\"",
|
||||||
"ref_doctype": "Sales Invoice",
|
"ref_doctype": "Sales Invoice",
|
||||||
"report_name": "Sales Partners Commission",
|
"report_name": "Sales Partners Commission",
|
||||||
"report_type": "Query Report",
|
"report_type": "Query Report",
|
||||||
@ -24,4 +24,4 @@
|
|||||||
"role": "Accounts User"
|
"role": "Accounts User"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
frappe.query_reports["Sales Payment Summary"] = {
|
frappe.query_reports["Sales Payment Summary"] = {
|
||||||
"filters": [
|
"filters": [
|
||||||
{
|
{
|
||||||
@ -8,12 +7,14 @@ frappe.query_reports["Sales Payment Summary"] = {
|
|||||||
"label": __("From Date"),
|
"label": __("From Date"),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"default": frappe.datetime.get_today(),
|
"default": frappe.datetime.get_today(),
|
||||||
|
"reqd": 1,
|
||||||
"width": "80"
|
"width": "80"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"to_date",
|
"fieldname":"to_date",
|
||||||
"label": __("To Date"),
|
"label": __("To Date"),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
|
"reqd": 1,
|
||||||
"default": frappe.datetime.get_today()
|
"default": frappe.datetime.get_today()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -23,12 +24,6 @@ frappe.query_reports["Sales Payment Summary"] = {
|
|||||||
"options": "Company",
|
"options": "Company",
|
||||||
"default": frappe.defaults.get_user_default("Company")
|
"default": frappe.defaults.get_user_default("Company")
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname":"mode_of_payment",
|
|
||||||
"label": __("Mode of Payment"),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "Mode of Payment"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname":"owner",
|
"fieldname":"owner",
|
||||||
"label": __("Owner"),
|
"label": __("Owner"),
|
||||||
@ -36,22 +31,15 @@ frappe.query_reports["Sales Payment Summary"] = {
|
|||||||
"options": "User",
|
"options": "User",
|
||||||
"defaults": user
|
"defaults": user
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname":"cost_center",
|
|
||||||
"label": __("Cost Center"),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "Cost Center"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname":"warehouse",
|
|
||||||
"label": __("Warehouse"),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "Warehouse"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname":"is_pos",
|
"fieldname":"is_pos",
|
||||||
"label": __("POS?"),
|
"label": __("Show only POS"),
|
||||||
"fieldtype": "Check"
|
"fieldtype": "Check"
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"payment_detail",
|
||||||
|
"label": __("Show Payment Details"),
|
||||||
|
"fieldtype": "Check"
|
||||||
|
},
|
||||||
]
|
]
|
||||||
};
|
};
|
@ -1,9 +1,9 @@
|
|||||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
from frappe.utils import cstr
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
columns, data = [], []
|
columns, data = [], []
|
||||||
@ -14,53 +14,133 @@ def execute(filters=None):
|
|||||||
def get_columns():
|
def get_columns():
|
||||||
return [
|
return [
|
||||||
_("Date") + ":Date:80",
|
_("Date") + ":Date:80",
|
||||||
_("Owner") + "::150",
|
_("Owner") + ":Data:200",
|
||||||
_("Payment Mode") + "::120",
|
_("Payment Mode") + ":Data:240",
|
||||||
_("Warehouse") + ":Link/Cost Center:100",
|
|
||||||
_("Cost Center") + ":Link/Warehouse:100",
|
|
||||||
_("Sales and Returns") + ":Currency/currency:120",
|
_("Sales and Returns") + ":Currency/currency:120",
|
||||||
_("Taxes") + ":Currency/currency:120",
|
_("Taxes") + ":Currency/currency:120",
|
||||||
_("Payments") + ":Currency/currency:120",
|
_("Payments") + ":Currency/currency:120"
|
||||||
_("Reconciliation") + ":Currency/currency:120"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_sales_payment_data(filters, columns):
|
def get_sales_payment_data(filters, columns):
|
||||||
sales_invoice_data = get_sales_invoice_data(filters)
|
|
||||||
data = []
|
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:
|
for inv in sales_invoice_data:
|
||||||
row = [inv.posting_date, inv.owner, inv.mode_of_payment,inv.warehouse,
|
owner_posting_date = inv["owner"]+cstr(inv["posting_date"])
|
||||||
inv.cost_center,inv.net_total, inv.total_taxes, inv.paid_amount,
|
if show_payment_detail:
|
||||||
(inv.net_total + inv.total_taxes - inv.paid_amount)]
|
row = [inv.posting_date, inv.owner," ",inv.net_total,inv.total_taxes, 0]
|
||||||
data.append(row)
|
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
|
return data
|
||||||
|
|
||||||
def get_conditions(filters):
|
def get_conditions(filters):
|
||||||
conditions = ""
|
conditions = ""
|
||||||
if filters.get("company"): conditions += " a.company=%(company)s"
|
if filters.get("from_date"): conditions += "a.posting_date >= %(from_date)s"
|
||||||
|
if filters.get("to_date"): conditions += " and a.posting_date <= %(to_date)s"
|
||||||
|
if filters.get("company"): conditions += " and a.company=%(company)s"
|
||||||
if filters.get("customer"): conditions += " and a.customer = %(customer)s"
|
if filters.get("customer"): conditions += " and a.customer = %(customer)s"
|
||||||
if filters.get("owner"): conditions += " and a.owner = %(owner)s"
|
if filters.get("owner"): conditions += " and a.owner = %(owner)s"
|
||||||
if filters.get("from_date"): conditions += " and a.posting_date >= %(from_date)s"
|
|
||||||
if filters.get("to_date"): conditions += " and a.posting_date <= %(to_date)s"
|
|
||||||
if filters.get("mode_of_payment"): conditions += " and c.mode_of_payment >= %(mode_of_payment)s"
|
|
||||||
if filters.get("warehouse"): conditions += " and b.warehouse <= %(warehouse)s"
|
|
||||||
if filters.get("cost_center"): conditions += " and b.cost_center <= %(cost_center)s"
|
|
||||||
if filters.get("is_pos"): conditions += " and a.is_pos = %(is_pos)s"
|
if filters.get("is_pos"): conditions += " and a.is_pos = %(is_pos)s"
|
||||||
|
|
||||||
return conditions
|
return conditions
|
||||||
|
|
||||||
def get_sales_invoice_data(filters):
|
def get_sales_invoice_data(filters):
|
||||||
conditions = get_conditions(filters)
|
conditions = get_conditions(filters)
|
||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
select
|
select
|
||||||
a.owner, a.posting_date, c.mode_of_payment, b.warehouse, b.cost_center,
|
a.posting_date, a.owner,
|
||||||
sum(a.net_total) as "net_total",
|
sum(a.net_total) as "net_total",
|
||||||
sum(a.total_taxes_and_charges) as "total_taxes",
|
sum(a.total_taxes_and_charges) as "total_taxes",
|
||||||
sum(a.base_paid_amount) as "paid_amount"
|
sum(a.base_paid_amount) as "paid_amount",
|
||||||
from `tabSales Invoice` a, `tabSales Invoice Item` b, `tabSales Invoice Payment` c
|
sum(a.outstanding_amount) as "outstanding_amount"
|
||||||
where
|
from `tabSales Invoice` a
|
||||||
a.name = b.parent
|
where a.docstatus = 1
|
||||||
and a.name = c.parent
|
|
||||||
and {conditions}
|
and {conditions}
|
||||||
group by
|
group by
|
||||||
a.owner, a.posting_date, c.mode_of_payment, b.warehouse, b.cost_center
|
a.owner, a.posting_date
|
||||||
""".format(conditions=conditions), filters, as_dict=1)
|
""".format(conditions=conditions), filters, as_dict=1)
|
||||||
|
|
||||||
|
def get_mode_of_payments(filters):
|
||||||
|
mode_of_payments = {}
|
||||||
|
invoice_list = get_invoices(filters)
|
||||||
|
invoice_list_names = ",".join(['"' + invoice['name'] + '"' for invoice in invoice_list])
|
||||||
|
if invoice_list:
|
||||||
|
inv_mop = frappe.db.sql("""select a.owner,a.posting_date, ifnull(b.mode_of_payment, '') as mode_of_payment
|
||||||
|
from `tabSales Invoice` a, `tabSales Invoice Payment` b
|
||||||
|
where a.name = b.parent
|
||||||
|
and a.name in ({invoice_list_names})
|
||||||
|
union
|
||||||
|
select a.owner,a.posting_date, 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
|
||||||
|
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)
|
||||||
|
return mode_of_payments
|
||||||
|
|
||||||
|
def get_invoices(filters):
|
||||||
|
conditions = get_conditions(filters)
|
||||||
|
return frappe.db.sql("""select a.name
|
||||||
|
from `tabSales Invoice` a
|
||||||
|
where a.docstatus = 1 and {conditions}""".format(conditions=conditions),
|
||||||
|
filters, as_dict=1)
|
||||||
|
|
||||||
|
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
|
@ -252,6 +252,9 @@ def add_ac(args=None):
|
|||||||
if not ac.parent_account:
|
if not ac.parent_account:
|
||||||
ac.parent_account = args.get("parent")
|
ac.parent_account = args.get("parent")
|
||||||
|
|
||||||
|
if ac.is_root:
|
||||||
|
ac.parent_account=''
|
||||||
|
|
||||||
ac.old_parent = ""
|
ac.old_parent = ""
|
||||||
ac.freeze_account = "No"
|
ac.freeze_account = "No"
|
||||||
if cint(ac.get("is_root")):
|
if cint(ac.get("is_root")):
|
||||||
@ -576,16 +579,17 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
|
|||||||
outstanding_invoices = []
|
outstanding_invoices = []
|
||||||
precision = frappe.get_precision("Sales Invoice", "outstanding_amount")
|
precision = frappe.get_precision("Sales Invoice", "outstanding_amount")
|
||||||
|
|
||||||
if party_type == "Customer" or party_type == "Student":
|
if party_type in ("Customer", "Student"):
|
||||||
dr_or_cr = "debit_in_account_currency - credit_in_account_currency"
|
dr_or_cr = "debit_in_account_currency - credit_in_account_currency"
|
||||||
payment_dr_or_cr = "payment_gl_entry.credit_in_account_currency - payment_gl_entry.debit_in_account_currency"
|
payment_dr_or_cr = "payment_gl_entry.credit_in_account_currency - payment_gl_entry.debit_in_account_currency"
|
||||||
else:
|
else:
|
||||||
dr_or_cr = "credit_in_account_currency - debit_in_account_currency"
|
dr_or_cr = "credit_in_account_currency - debit_in_account_currency"
|
||||||
payment_dr_or_cr = "payment_gl_entry.debit_in_account_currency - payment_gl_entry.credit_in_account_currency"
|
payment_dr_or_cr = "payment_gl_entry.debit_in_account_currency - payment_gl_entry.credit_in_account_currency"
|
||||||
|
|
||||||
|
invoice = 'Sales Invoice' if party_type == 'Customer' else 'Purchase Invoice'
|
||||||
invoice_list = frappe.db.sql("""
|
invoice_list = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
voucher_no, voucher_type, posting_date, ifnull(sum({dr_or_cr}), 0) as invoice_amount, due_date,
|
voucher_no, voucher_type, posting_date, ifnull(sum({dr_or_cr}), 0) as invoice_amount,
|
||||||
(
|
(
|
||||||
select ifnull(sum({payment_dr_or_cr}), 0)
|
select ifnull(sum({payment_dr_or_cr}), 0)
|
||||||
from `tabGL Entry` payment_gl_entry
|
from `tabGL Entry` payment_gl_entry
|
||||||
@ -596,7 +600,6 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
|
|||||||
and payment_gl_entry.party_type = invoice_gl_entry.party_type
|
and payment_gl_entry.party_type = invoice_gl_entry.party_type
|
||||||
and payment_gl_entry.party = invoice_gl_entry.party
|
and payment_gl_entry.party = invoice_gl_entry.party
|
||||||
and payment_gl_entry.account = invoice_gl_entry.account
|
and payment_gl_entry.account = invoice_gl_entry.account
|
||||||
and payment_gl_entry.due_date = invoice_gl_entry.due_date
|
|
||||||
and {payment_dr_or_cr} > 0
|
and {payment_dr_or_cr} > 0
|
||||||
) as payment_amount
|
) as payment_amount
|
||||||
from
|
from
|
||||||
@ -608,10 +611,11 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
|
|||||||
and ((voucher_type = 'Journal Entry'
|
and ((voucher_type = 'Journal Entry'
|
||||||
and (against_voucher = '' or against_voucher is null))
|
and (against_voucher = '' or against_voucher is null))
|
||||||
or (voucher_type not in ('Journal Entry', 'Payment Entry')))
|
or (voucher_type not in ('Journal Entry', 'Payment Entry')))
|
||||||
group by voucher_type, voucher_no, due_date
|
group by voucher_type, voucher_no
|
||||||
having (invoice_amount - payment_amount) > 0.005
|
having (invoice_amount - payment_amount) > 0.005
|
||||||
order by posting_date, name, due_date""".format(
|
order by posting_date, name""".format(
|
||||||
dr_or_cr=dr_or_cr,
|
dr_or_cr=dr_or_cr,
|
||||||
|
invoice = invoice,
|
||||||
payment_dr_or_cr=payment_dr_or_cr,
|
payment_dr_or_cr=payment_dr_or_cr,
|
||||||
condition=condition or ""
|
condition=condition or ""
|
||||||
), {
|
), {
|
||||||
@ -621,12 +625,8 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
|
|||||||
}, as_dict=True)
|
}, as_dict=True)
|
||||||
|
|
||||||
for d in invoice_list:
|
for d in invoice_list:
|
||||||
due_date = d.due_date or (
|
due_date = frappe.db.get_value(d.voucher_type, d.voucher_no,
|
||||||
frappe.db.get_value(
|
"posting_date" if party_type == "Employee" else "due_date")
|
||||||
d.voucher_type, d.voucher_no,
|
|
||||||
"posting_date" if party_type == "Employee" else "due_date"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
outstanding_invoices.append(
|
outstanding_invoices.append(
|
||||||
frappe._dict({
|
frappe._dict({
|
||||||
@ -704,7 +704,7 @@ def get_children(doctype, parent, company, is_root=False):
|
|||||||
return acc
|
return acc
|
||||||
|
|
||||||
def create_payment_gateway_account(gateway):
|
def create_payment_gateway_account(gateway):
|
||||||
from erpnext.setup.setup_wizard.setup_wizard import create_bank_account
|
from erpnext.setup.setup_wizard.operations.company_setup import create_bank_account
|
||||||
|
|
||||||
company = frappe.db.get_value("Global Defaults", None, "default_company")
|
company = frappe.db.get_value("Global Defaults", None, "default_company")
|
||||||
if not company:
|
if not company:
|
||||||
|
@ -1,7 +1,55 @@
|
|||||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.provide("erpnext.crop");
|
||||||
|
|
||||||
frappe.ui.form.on('Crop', {
|
frappe.ui.form.on('Crop', {
|
||||||
validate: (frm) => {
|
refresh: (frm) => {
|
||||||
|
frm.fields_dict.materials_required.grid.set_column_disp('bom_no', false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on("BOM Item", {
|
||||||
|
item_code: (frm, cdt, cdn) => {
|
||||||
|
erpnext.crop.update_item_rate_uom(frm, cdt, cdn);
|
||||||
|
},
|
||||||
|
qty: (frm, cdt, cdn) => {
|
||||||
|
erpnext.crop.update_item_qty_amount(frm, cdt, cdn);
|
||||||
|
},
|
||||||
|
rate: (frm, cdt, cdn) => {
|
||||||
|
erpnext.crop.update_item_qty_amount(frm, cdt, cdn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
erpnext.crop.update_item_rate_uom = function(frm, cdt, cdn) {
|
||||||
|
let material_list = ['materials_required', 'produce', 'byproducts'];
|
||||||
|
material_list.forEach((material) => {
|
||||||
|
frm.doc[material].forEach((item, index) => {
|
||||||
|
if (item.name == cdn && item.item_code){
|
||||||
|
frappe.call({
|
||||||
|
method:'erpnext.agriculture.doctype.crop.crop.get_item_details',
|
||||||
|
args: {
|
||||||
|
item_code: item.item_code
|
||||||
|
},
|
||||||
|
callback: (r) => {
|
||||||
|
frappe.model.set_value('BOM Item', item.name, 'uom', r.message.uom);
|
||||||
|
frappe.model.set_value('BOM Item', item.name, 'rate', r.message.rate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
erpnext.crop.update_item_qty_amount = function(frm, cdt, cdn) {
|
||||||
|
let material_list = ['materials_required', 'produce', 'byproducts'];
|
||||||
|
material_list.forEach((material) => {
|
||||||
|
frm.doc[material].forEach((item, index) => {
|
||||||
|
if (item.name == cdn){
|
||||||
|
if (!frappe.model.get_value('BOM Item', item.name, 'qty'))
|
||||||
|
frappe.model.set_value('BOM Item', item.name, 'qty', 1);
|
||||||
|
frappe.model.set_value('BOM Item', item.name, 'amount', item.qty * item.rate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
@ -15,4 +15,9 @@ class Crop(Document):
|
|||||||
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.subject))
|
||||||
# to calculate the period of the Crop Cycle
|
# to calculate the period of the Crop Cycle
|
||||||
if task.end_day > max_period: max_period = task.end_day
|
if task.end_day > max_period: max_period = task.end_day
|
||||||
if max_period > self.period: self.period = max_period
|
if max_period > self.period: self.period = max_period
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_item_details(item_code):
|
||||||
|
item = frappe.get_doc('Item', item_code)
|
||||||
|
return { "uom": item.stock_uom, "rate": item.valuation_rate }
|
@ -15,7 +15,7 @@ frappe.ui.form.on('Crop Cycle', {
|
|||||||
output[doctype].forEach( (analysis_doc) => {
|
output[doctype].forEach( (analysis_doc) => {
|
||||||
let point_to_be_tested = JSON.parse(analysis_doc.location).features[0].geometry.coordinates;
|
let point_to_be_tested = JSON.parse(analysis_doc.location).features[0].geometry.coordinates;
|
||||||
let poly_of_land = JSON.parse(land_doc.location).features[0].geometry.coordinates[0];
|
let poly_of_land = JSON.parse(land_doc.location).features[0].geometry.coordinates[0];
|
||||||
if (test_analysis_position(point_to_be_tested, poly_of_land)){
|
if (is_in_land_unit(point_to_be_tested, poly_of_land)){
|
||||||
obj_to_append[analysis_doctypes_docs[analysis_doctypes.indexOf(doctype)]].push(analysis_doc.name);
|
obj_to_append[analysis_doctypes_docs[analysis_doctypes.indexOf(doctype)]].push(analysis_doc.name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -28,7 +28,7 @@ frappe.ui.form.on('Crop Cycle', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function test_analysis_position(point, vs) {
|
function is_in_land_unit(point, vs) {
|
||||||
// ray-casting algorithm based on
|
// ray-casting algorithm based on
|
||||||
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
||||||
|
|
||||||
|
@ -599,6 +599,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"depends_on": "eval:!doc.__islocal",
|
||||||
"description": "List of diseases detected on the field. When selected it'll automatically add a list of tasks to deal with the disease ",
|
"description": "List of diseases detected on the field. When selected it'll automatically add a list of tasks to deal with the disease ",
|
||||||
"fieldname": "section_break_14",
|
"fieldname": "section_break_14",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
@ -790,7 +791,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-12-06 01:47:26.656870",
|
"modified": "2017-12-18 12:54:29.071743",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Agriculture",
|
"module": "Agriculture",
|
||||||
"name": "Crop Cycle",
|
"name": "Crop Cycle",
|
||||||
|
@ -12,11 +12,37 @@ class CropCycle(Document):
|
|||||||
if self.is_new():
|
if self.is_new():
|
||||||
crop = frappe.get_doc('Crop', self.crop)
|
crop = frappe.get_doc('Crop', self.crop)
|
||||||
self.create_project(crop.period, crop.agriculture_task)
|
self.create_project(crop.period, crop.agriculture_task)
|
||||||
if not self.project:
|
if not self.crop_spacing_uom:
|
||||||
self.project = self.name
|
self.crop_spacing_uom = crop.crop_spacing_uom
|
||||||
for detected_disease in self.detected_disease:
|
if not self.row_spacing_uom:
|
||||||
disease = frappe.get_doc('Disease', detected_disease.disease)
|
self.row_spacing_uom = crop.row_spacing_uom
|
||||||
self.create_task(disease.treatment_task, self.name, detected_disease.start_date)
|
if not self.project:
|
||||||
|
self.project = self.name
|
||||||
|
disease = []
|
||||||
|
for detected_disease in self.detected_disease:
|
||||||
|
disease.append(detected_disease.name)
|
||||||
|
if disease != []:
|
||||||
|
self.update_disease(disease)
|
||||||
|
else:
|
||||||
|
old_disease, new_disease = [], []
|
||||||
|
for detected_disease in self.detected_disease:
|
||||||
|
new_disease.append(detected_disease.name)
|
||||||
|
for detected_disease in self.get_doc_before_save().get('detected_disease'):
|
||||||
|
old_disease.append(detected_disease.name)
|
||||||
|
if list(set(new_disease)-set(old_disease)) != []:
|
||||||
|
self.update_disease(list(set(new_disease)-set(old_disease)))
|
||||||
|
frappe.msgprint("All tasks for the detected diseases were imported")
|
||||||
|
|
||||||
|
def update_disease(self, disease_hashes):
|
||||||
|
new_disease = []
|
||||||
|
for disease in self.detected_disease:
|
||||||
|
for disease_hash in disease_hashes:
|
||||||
|
if disease.name == disease_hash:
|
||||||
|
self.import_disease_tasks(disease.disease, disease.start_date)
|
||||||
|
|
||||||
|
def import_disease_tasks(self, disease, start_date):
|
||||||
|
disease_doc = frappe.get_doc('Disease', disease)
|
||||||
|
self.create_task(disease_doc.treatment_task, self.name, start_date)
|
||||||
|
|
||||||
def create_project(self, period, crop_tasks):
|
def create_project(self, period, crop_tasks):
|
||||||
project = frappe.new_doc("Project")
|
project = frappe.new_doc("Project")
|
||||||
@ -59,4 +85,19 @@ class CropCycle(Document):
|
|||||||
return ast.literal_eval(doc.location).get('features')[0].get('geometry').get('coordinates')
|
return ast.literal_eval(doc.location).get('features')[0].get('geometry').get('coordinates')
|
||||||
|
|
||||||
def get_geometry_type(self, doc):
|
def get_geometry_type(self, doc):
|
||||||
return ast.literal_eval(doc.location).get('features')[0].get('geometry').get('type')
|
return ast.literal_eval(doc.location).get('features')[0].get('geometry').get('type')
|
||||||
|
|
||||||
|
def is_in_land_unit(self, point, vs):
|
||||||
|
x, y = point
|
||||||
|
inside = False
|
||||||
|
j = len(vs)-1
|
||||||
|
i = 0
|
||||||
|
while i < len(vs):
|
||||||
|
xi, yi = vs[i]
|
||||||
|
xj, yj = vs[j]
|
||||||
|
intersect = ((yi > y) != (yj > y)) and (x < (xj - xi) * (y - yi) / (yj - yi) + xi)
|
||||||
|
if intersect:
|
||||||
|
inside = not inside
|
||||||
|
i = j
|
||||||
|
j += 1
|
||||||
|
return inside
|
@ -102,66 +102,6 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "description",
|
|
||||||
"fieldtype": "Long Text",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Description",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 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": "section_break_2",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Treatment Task",
|
|
||||||
"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,
|
"allow_on_submit": 0,
|
||||||
@ -222,6 +162,66 @@
|
|||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "section_break_2",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Treatment Task",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "description",
|
||||||
|
"fieldtype": "Long Text",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Description",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"has_web_view": 0,
|
||||||
@ -234,7 +234,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-12-04 19:20:19.352479",
|
"modified": "2017-12-07 16:24:22.923154",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Agriculture",
|
"module": "Agriculture",
|
||||||
"name": "Disease",
|
"name": "Disease",
|
||||||
|
@ -9,6 +9,13 @@ frappe.ui.form.on('Land Unit', {
|
|||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
frm.add_fetch("parent_land_unit", "latitude", "latitude");
|
frm.add_fetch("parent_land_unit", "latitude", "latitude");
|
||||||
frm.add_fetch("parent_land_unit", "longitude", "longitude");
|
frm.add_fetch("parent_land_unit", "longitude", "longitude");
|
||||||
|
frm.set_query("parent_land_unit", function() {
|
||||||
|
return {
|
||||||
|
"filters": {
|
||||||
|
"is_group": 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onload_post_render(frm){
|
onload_post_render(frm){
|
||||||
@ -20,12 +27,4 @@ frappe.ui.form.on('Land Unit', {
|
|||||||
frm.doc.longitude = frm.fields_dict.location.map.getCenter()['lng'];
|
frm.doc.longitude = frm.fields_dict.location.map.getCenter()['lng'];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
refresh: function(frm) {
|
|
||||||
if(!frm.doc.parent_land_unit) {
|
|
||||||
frm.set_read_only();
|
|
||||||
frm.set_intro(__("This is a root land unit and cannot be edited."));
|
|
||||||
} else {
|
|
||||||
frm.set_intro(null);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
@ -431,7 +431,7 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 1,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
@ -502,7 +502,7 @@
|
|||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 1,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "section_break_17",
|
"fieldname": "section_break_17",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
@ -513,6 +513,7 @@
|
|||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
|
"label": "Linked Analysis",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
@ -631,7 +632,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-12-05 10:57:33.108504",
|
"modified": "2017-12-14 18:16:15.124188",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Agriculture",
|
"module": "Agriculture",
|
||||||
"name": "Land Unit",
|
"name": "Land Unit",
|
||||||
@ -679,7 +680,7 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
|
@ -10,6 +10,7 @@ import math
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
|
|
||||||
from frappe.utils.nestedset import NestedSet
|
from frappe.utils.nestedset import NestedSet
|
||||||
|
from frappe.utils import flt
|
||||||
# from frappe.model.document import Document
|
# from frappe.model.document import Document
|
||||||
|
|
||||||
RADIUS = 6378137
|
RADIUS = 6378137
|
||||||
@ -31,6 +32,7 @@ class LandUnit(NestedSet):
|
|||||||
ancestor_features[index] = json.loads(feature)
|
ancestor_features[index] = json.loads(feature)
|
||||||
ancestor_doc.set_location_value(features = ancestor_features)
|
ancestor_doc.set_location_value(features = ancestor_features)
|
||||||
ancestor_doc.db_set(fieldname='area', value=ancestor_doc.get('area')-self.get('area'),commit=True)
|
ancestor_doc.db_set(fieldname='area', value=ancestor_doc.get('area')-self.get('area'),commit=True)
|
||||||
|
super(LandUnit, self).on_update()
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if not self.is_new():
|
if not self.is_new():
|
||||||
@ -39,10 +41,10 @@ class LandUnit(NestedSet):
|
|||||||
else:
|
else:
|
||||||
features = json.loads(self.get('location')).get('features')
|
features = json.loads(self.get('location')).get('features')
|
||||||
new_area = compute_area(features)
|
new_area = compute_area(features)
|
||||||
self.area_difference = new_area - self.area
|
self.area_difference = new_area - flt(self.area)
|
||||||
self.area = new_area
|
self.area = new_area
|
||||||
|
|
||||||
if self.get('parent'):
|
if self.get('parent_land_unit'):
|
||||||
ancestors = self.get_ancestors()
|
ancestors = self.get_ancestors()
|
||||||
self_features = self.add_child_property()
|
self_features = self.add_child_property()
|
||||||
self_features = set(self_features)
|
self_features = set(self_features)
|
||||||
@ -78,7 +80,6 @@ class LandUnit(NestedSet):
|
|||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
super(LandUnit, self).on_update()
|
super(LandUnit, self).on_update()
|
||||||
self.validate_one_root()
|
|
||||||
|
|
||||||
def add_child_property(self):
|
def add_child_property(self):
|
||||||
location = self.get('location')
|
location = self.get('location')
|
||||||
@ -118,7 +119,7 @@ def compute_area(features):
|
|||||||
layer_area += polygon_area(coords = feature.get('geometry').get('coordinates'))
|
layer_area += polygon_area(coords = feature.get('geometry').get('coordinates'))
|
||||||
elif feature.get('geometry').get('type') == 'Point' and feature.get('properties').get('point_type') == 'circle':
|
elif feature.get('geometry').get('type') == 'Point' and feature.get('properties').get('point_type') == 'circle':
|
||||||
layer_area += math.pi * math.pow(feature.get('properties').get('radius'), 2)
|
layer_area += math.pi * math.pow(feature.get('properties').get('radius'), 2)
|
||||||
return layer_area
|
return flt(layer_area)
|
||||||
|
|
||||||
def rad(angle_in_degrees):
|
def rad(angle_in_degrees):
|
||||||
return angle_in_degrees*math.pi/180
|
return angle_in_degrees*math.pi/180
|
||||||
@ -162,4 +163,18 @@ def ring_area(coords):
|
|||||||
|
|
||||||
area = area * RADIUS * RADIUS / 2
|
area = area * RADIUS * RADIUS / 2
|
||||||
return area
|
return area
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_children(doctype, parent, is_root=False):
|
||||||
|
if is_root:
|
||||||
|
parent = ''
|
||||||
|
|
||||||
|
land_units = frappe.db.sql("""select name as value,
|
||||||
|
is_group as expandable
|
||||||
|
from `tabLand Unit`
|
||||||
|
where ifnull(`parent_land_unit`,'') = %s
|
||||||
|
order by name""", (parent), as_dict=1)
|
||||||
|
|
||||||
|
# return nodes
|
||||||
|
return land_units
|
||||||
|
|
@ -1,15 +1,30 @@
|
|||||||
frappe.treeview_settings["Land Unit"] = {
|
frappe.treeview_settings["Land Unit"] = {
|
||||||
|
get_tree_nodes: "erpnext.agriculture.doctype.land_unit.land_unit.get_children",
|
||||||
ignore_fields:["parent_land_unit"],
|
ignore_fields:["parent_land_unit"],
|
||||||
|
get_tree_root: false,
|
||||||
disable_add_node: true,
|
disable_add_node: true,
|
||||||
|
root_label: "All Land Units",
|
||||||
|
onload: function(me) {
|
||||||
|
me.make_tree();
|
||||||
|
},
|
||||||
toolbar: [
|
toolbar: [
|
||||||
{ toggle_btn: true },
|
{ toggle_btn: true },
|
||||||
{
|
{
|
||||||
label:__("Add Child"),
|
label:__("Edit"),
|
||||||
|
condition: function(node) { return (node.label!='All Land Units'); },
|
||||||
click: function(node) {
|
click: function(node) {
|
||||||
|
frappe.set_route('Form', 'Land Unit', node.data.value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label:__("Add Child"),
|
||||||
|
condition: function(node) { return node.expandable; },
|
||||||
|
click: function(node) {
|
||||||
|
if(node.label=='All Land Units') node.label='';
|
||||||
var lu = frappe.new_doc("Land Unit", {
|
var lu = frappe.new_doc("Land Unit", {
|
||||||
"parent_land_unit": node.label
|
"parent_land_unit": node.label
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
}
|
};
|
@ -12,7 +12,6 @@ QUnit.test("test: Land Unit", function (assert) {
|
|||||||
// insert a new Land Unit
|
// insert a new Land Unit
|
||||||
() => frappe.tests.make('Land Unit', [
|
() => frappe.tests.make('Land Unit', [
|
||||||
// values to be set
|
// values to be set
|
||||||
{parent_land_unit: 'All Land Units'},
|
|
||||||
{land_unit_name: 'Basil Farm'}
|
{land_unit_name: 'Basil Farm'}
|
||||||
]),
|
]),
|
||||||
() => {
|
() => {
|
||||||
|
@ -21,6 +21,6 @@ class TestLandUnit(unittest.TestCase):
|
|||||||
temp['features'][0]['properties']['feature_of'] = land_unit
|
temp['features'][0]['properties']['feature_of'] = land_unit
|
||||||
formatted_land_units.extend(temp['features'])
|
formatted_land_units.extend(temp['features'])
|
||||||
formatted_land_unit_string = str(formatted_land_units)
|
formatted_land_unit_string = str(formatted_land_units)
|
||||||
all_land_units = frappe.get_doc('Land Unit', 'All Land Units')
|
test_land = frappe.get_doc('Land Unit', 'Test Land')
|
||||||
self.assertEquals(formatted_land_unit_string, str(json.loads(all_land_units.get('location'))['features']))
|
self.assertEquals(formatted_land_unit_string, str(json.loads(test_land.get('location'))['features']))
|
||||||
self.assertEquals(area, all_land_units.get('area'))
|
self.assertEquals(area, test_land.get('area'))
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"doctype": "Land Unit",
|
||||||
|
"land_unit_name": "Test Land",
|
||||||
|
"is_group": 1,
|
||||||
|
"is_container": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Land Unit",
|
"doctype": "Land Unit",
|
||||||
"land_unit_name": "Basil Farm",
|
"land_unit_name": "Basil Farm",
|
||||||
"location": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{\"point_type\":\"circle\",\"radius\":884.5625420736483},\"geometry\":{\"type\":\"Point\",\"coordinates\":[72.875834,19.100566]}}]}",
|
"location": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{\"point_type\":\"circle\",\"radius\":884.5625420736483},\"geometry\":{\"type\":\"Point\",\"coordinates\":[72.875834,19.100566]}}]}",
|
||||||
"parent_land_unit": "All Land Units",
|
"parent_land_unit": "Test Land",
|
||||||
"parent": "All Land Units",
|
"parent": "Test Land",
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"is_container": 1
|
"is_container": 1
|
||||||
},
|
},
|
||||||
|
@ -4,12 +4,13 @@ from frappe import _
|
|||||||
from erpnext.setup.utils import insert_record
|
from erpnext.setup.utils import insert_record
|
||||||
|
|
||||||
def setup_agriculture():
|
def setup_agriculture():
|
||||||
|
if frappe.get_all('Agriculture Analysis Criteria'):
|
||||||
|
# already setup
|
||||||
|
return
|
||||||
|
create_agriculture_data()
|
||||||
|
|
||||||
|
def create_agriculture_data():
|
||||||
records = [
|
records = [
|
||||||
dict(
|
|
||||||
doctype="Land Unit",
|
|
||||||
land_unit_name="All Land Units",
|
|
||||||
is_group=1,
|
|
||||||
is_container=1),
|
|
||||||
dict(
|
dict(
|
||||||
doctype='Item Group',
|
doctype='Item Group',
|
||||||
item_group_name='Fertilizer',
|
item_group_name='Fertilizer',
|
||||||
@ -182,7 +183,7 @@ def setup_agriculture():
|
|||||||
linked_doctype='Soil Analysis'),
|
linked_doctype='Soil Analysis'),
|
||||||
dict(
|
dict(
|
||||||
doctype='Agriculture Analysis Criteria',
|
doctype='Agriculture Analysis Criteria',
|
||||||
title='pH',
|
title='Soil pH',
|
||||||
standard=1,
|
standard=1,
|
||||||
linked_doctype='Soil Analysis'),
|
linked_doctype='Soil Analysis'),
|
||||||
dict(
|
dict(
|
||||||
@ -272,7 +273,7 @@ def setup_agriculture():
|
|||||||
linked_doctype='Soil Analysis'),
|
linked_doctype='Soil Analysis'),
|
||||||
dict(
|
dict(
|
||||||
doctype='Agriculture Analysis Criteria',
|
doctype='Agriculture Analysis Criteria',
|
||||||
title='pH',
|
title='Water pH',
|
||||||
standard=1,
|
standard=1,
|
||||||
linked_doctype='Water Analysis'),
|
linked_doctype='Water Analysis'),
|
||||||
dict(
|
dict(
|
||||||
@ -424,11 +425,6 @@ def setup_agriculture():
|
|||||||
doctype='Agriculture Analysis Criteria',
|
doctype='Agriculture Analysis Criteria',
|
||||||
title='Degree Days',
|
title='Degree Days',
|
||||||
standard=1,
|
standard=1,
|
||||||
linked_doctype='Weather'),
|
linked_doctype='Weather')
|
||||||
dict(
|
|
||||||
doctype='Agriculture Analysis Criteria',
|
|
||||||
title='Degree Days',
|
|
||||||
standard=1,
|
|
||||||
linked_doctype='Water Analysis')
|
|
||||||
]
|
]
|
||||||
insert_record(records)
|
insert_record(records)
|
||||||
|
@ -175,7 +175,7 @@ frappe.ui.form.on('Asset', {
|
|||||||
"item_code": frm.doc.item_code,
|
"item_code": frm.doc.item_code,
|
||||||
"company": frm.doc.company
|
"company": frm.doc.company
|
||||||
},
|
},
|
||||||
method: "erpnext.accounts.doctype.asset.asset.make_sales_invoice",
|
method: "erpnext.assets.doctype.asset.asset.make_sales_invoice",
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
var doclist = frappe.model.sync(r.message);
|
var doclist = frappe.model.sync(r.message);
|
||||||
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
||||||
|
@ -154,7 +154,7 @@
|
|||||||
"label": "Status",
|
"label": "Status",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Draft\nSubmitted\nPartially Depreciated\nFully Depreciated\nSold\nScrapped\nIn Repair\nOut of Order",
|
"options": "Draft\nSubmitted\nPartially Depreciated\nFully Depreciated\nSold\nScrapped\nIn Maintenance\nOut of Order",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@ -193,7 +193,7 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
@ -1221,7 +1221,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-12-01 15:11:47.466859",
|
"modified": "2017-12-19 12:58:44.137460",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset",
|
"name": "Asset",
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt, add_months, cint, nowdate, getdate
|
from frappe.utils import flt, add_months, cint, nowdate, getdate, today
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import get_fixed_asset_account
|
from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import get_fixed_asset_account
|
||||||
from erpnext.assets.doctype.asset.depreciation \
|
from erpnext.assets.doctype.asset.depreciation \
|
||||||
@ -174,7 +174,7 @@ class Asset(Document):
|
|||||||
def set_status(self, status=None):
|
def set_status(self, status=None):
|
||||||
'''Get and update status'''
|
'''Get and update status'''
|
||||||
if not status:
|
if not status:
|
||||||
status = self.get_status()
|
status = self.get_status()
|
||||||
self.db_set("status", status)
|
self.db_set("status", status)
|
||||||
|
|
||||||
def get_status(self):
|
def get_status(self):
|
||||||
@ -193,6 +193,16 @@ class Asset(Document):
|
|||||||
status = "Cancelled"
|
status = "Cancelled"
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
def update_maintenance_status():
|
||||||
|
assets = frappe.get_all('Asset', filters = {'docstatus': 1, 'maintenance_required': 1})
|
||||||
|
|
||||||
|
for asset in assets:
|
||||||
|
asset = frappe.get_doc("Asset", asset.name)
|
||||||
|
if frappe.db.exists('Asset Maintenance Task', {'parent': asset.name, 'next_due_date': today()}):
|
||||||
|
asset.set_status('In Maintenance')
|
||||||
|
if frappe.db.exists('Asset Repair', {'asset_name': asset.name, 'repair_status': 'Pending'}):
|
||||||
|
asset.set_status('Out of Order')
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_purchase_invoice(asset, item_code, gross_purchase_amount, company, posting_date):
|
def make_purchase_invoice(asset, item_code, gross_purchase_amount, company, posting_date):
|
||||||
pi = frappe.new_doc("Purchase Invoice")
|
pi = frappe.new_doc("Purchase Invoice")
|
||||||
|
@ -225,7 +225,7 @@
|
|||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"modified": "2015-08-25 04:55:06.052342",
|
"modified": "2017-12-27 15:20:06.052342",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Buying Settings",
|
"name": "Buying Settings",
|
||||||
|
@ -12,6 +12,15 @@ frappe.ui.form.on("Purchase Order", {
|
|||||||
'Purchase Invoice': 'Invoice',
|
'Purchase Invoice': 'Invoice',
|
||||||
'Stock Entry': 'Material to Supplier'
|
'Stock Entry': 'Material to Supplier'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frm.set_query("reserve_warehouse", "supplied_items", function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
"company": frm.doc.company,
|
||||||
|
"is_group": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
@ -21,22 +30,17 @@ frappe.ui.form.on("Purchase Order", {
|
|||||||
return erpnext.queries.warehouse(frm.doc);
|
return erpnext.queries.warehouse(frm.doc);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.db.get_value('Buying Settings', {name: 'Buying Settings'}, 'disable_fetch_last_purchase_rate', (r) => {
|
||||||
|
value = r && cint(r.disable_fetch_last_purchase_rate);
|
||||||
|
frm.toggle_display('get_last_purchase_rate', !value);
|
||||||
|
});
|
||||||
|
|
||||||
frm.set_indicator_formatter('item_code',
|
frm.set_indicator_formatter('item_code',
|
||||||
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
|
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on("Purchase Order Item", {
|
frappe.ui.form.on("Purchase Order Item", {
|
||||||
item_code: function(frm) {
|
|
||||||
frappe.call({
|
|
||||||
method: "get_last_purchase_rate",
|
|
||||||
doc: frm.doc,
|
|
||||||
callback: function(r, rt) {
|
|
||||||
frm.trigger('calculate_taxes_and_totals');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
schedule_date: function(frm, cdt, cdn) {
|
schedule_date: function(frm, cdt, cdn) {
|
||||||
var row = locals[cdt][cdn];
|
var row = locals[cdt][cdn];
|
||||||
if (row.schedule_date) {
|
if (row.schedule_date) {
|
||||||
@ -289,7 +293,8 @@ cur_frm.fields_dict['items'].grid.get_field('bom').get_query = function(doc, cdt
|
|||||||
filters: [
|
filters: [
|
||||||
['BOM', 'item', '=', d.item_code],
|
['BOM', 'item', '=', d.item_code],
|
||||||
['BOM', 'is_active', '=', '1'],
|
['BOM', 'is_active', '=', '1'],
|
||||||
['BOM', 'docstatus', '=', '1']
|
['BOM', 'docstatus', '=', '1'],
|
||||||
|
['BOM', 'company', '=', doc.company]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,11 +41,11 @@
|
|||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "{supplier_name}",
|
"default": "{supplier_name}",
|
||||||
@ -292,40 +292,40 @@
|
|||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "",
|
"default": "",
|
||||||
"fieldname": "schedule_date",
|
"fieldname": "schedule_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Reqd By Date",
|
"label": "Reqd By Date",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@ -1238,6 +1238,37 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"depends_on": "eval:doc.docstatus===0 && (doc.items && doc.items.length)",
|
||||||
|
"fieldname": "get_last_purchase_rate",
|
||||||
|
"fieldtype": "Button",
|
||||||
|
"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": "Get last purchase rate",
|
||||||
|
"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,
|
"allow_on_submit": 0,
|
||||||
@ -2552,7 +2583,7 @@
|
|||||||
"options": "Payment Schedule",
|
"options": "Payment Schedule",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 1,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
@ -3071,6 +3102,38 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 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",
|
"fieldname": "supplied_items",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -3261,7 +3324,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-11-29 14:06:33.636401",
|
"modified": "2018-01-05 14:44:56.132189",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order",
|
"name": "Purchase Order",
|
||||||
|
@ -11,9 +11,8 @@ from erpnext.controllers.buying_controller import BuyingController
|
|||||||
from erpnext.stock.doctype.item.item import get_last_purchase_details
|
from erpnext.stock.doctype.item.item import get_last_purchase_details
|
||||||
from erpnext.stock.stock_balance import update_bin_qty, get_ordered_qty
|
from erpnext.stock.stock_balance import update_bin_qty, get_ordered_qty
|
||||||
from frappe.desk.notifications import clear_doctype_notifications
|
from frappe.desk.notifications import clear_doctype_notifications
|
||||||
from erpnext.buying.utils import (validate_for_items, check_for_closed_status,
|
from erpnext.buying.utils import validate_for_items, check_for_closed_status
|
||||||
update_last_purchase_rate)
|
from erpnext.stock.utils import get_bin
|
||||||
|
|
||||||
|
|
||||||
form_grid_templates = {
|
form_grid_templates = {
|
||||||
"items": "templates/form_grid/item_grid.html"
|
"items": "templates/form_grid/item_grid.html"
|
||||||
@ -72,8 +71,10 @@ class PurchaseOrder(BuyingController):
|
|||||||
def validate_supplier(self):
|
def validate_supplier(self):
|
||||||
prevent_po = frappe.db.get_value("Supplier", self.supplier, 'prevent_pos')
|
prevent_po = frappe.db.get_value("Supplier", self.supplier, 'prevent_pos')
|
||||||
if prevent_po:
|
if prevent_po:
|
||||||
standing = frappe.db.get_value("Supplier Scorecard",self.supplier, 'status')
|
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))
|
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')
|
warn_po = frappe.db.get_value("Supplier", self.supplier, 'warn_pos')
|
||||||
if warn_po:
|
if warn_po:
|
||||||
@ -112,27 +113,26 @@ class PurchaseOrder(BuyingController):
|
|||||||
|
|
||||||
def get_last_purchase_rate(self):
|
def get_last_purchase_rate(self):
|
||||||
"""get last purchase rates for all items"""
|
"""get last purchase rates for all items"""
|
||||||
|
if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
|
||||||
|
|
||||||
if not cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")):
|
conversion_rate = flt(self.get('conversion_rate')) or 1.0
|
||||||
conversion_rate = flt(self.get('conversion_rate')) or 1.0
|
for d in self.get("items"):
|
||||||
|
if d.item_code:
|
||||||
|
last_purchase_details = get_last_purchase_details(d.item_code, self.name)
|
||||||
|
if last_purchase_details:
|
||||||
|
d.base_price_list_rate = (last_purchase_details['base_price_list_rate'] *
|
||||||
|
(flt(d.conversion_factor) or 1.0))
|
||||||
|
d.discount_percentage = last_purchase_details['discount_percentage']
|
||||||
|
d.base_rate = last_purchase_details['base_rate'] * (flt(d.conversion_factor) or 1.0)
|
||||||
|
d.price_list_rate = d.base_price_list_rate / conversion_rate
|
||||||
|
d.rate = d.base_rate / conversion_rate
|
||||||
|
d.last_purchase_rate = d.rate
|
||||||
|
else:
|
||||||
|
|
||||||
for d in self.get("items"):
|
item_last_purchase_rate = frappe.db.get_value("Item", d.item_code, "last_purchase_rate")
|
||||||
if d.item_code:
|
if item_last_purchase_rate:
|
||||||
last_purchase_details = get_last_purchase_details(d.item_code, self.name)
|
d.base_price_list_rate = d.base_rate = d.price_list_rate \
|
||||||
|
= d.rate = d.last_purchase_rate = item_last_purchase_rate
|
||||||
if last_purchase_details:
|
|
||||||
d.base_price_list_rate = (last_purchase_details['base_price_list_rate'] *
|
|
||||||
(flt(d.conversion_factor) or 1.0))
|
|
||||||
d.discount_percentage = last_purchase_details['discount_percentage']
|
|
||||||
d.base_rate = last_purchase_details['base_rate'] * (flt(d.conversion_factor) or 1.0)
|
|
||||||
d.price_list_rate = d.base_price_list_rate / conversion_rate
|
|
||||||
d.last_purchase_rate = d.base_rate / conversion_rate
|
|
||||||
else:
|
|
||||||
|
|
||||||
item_last_purchase_rate = frappe.db.get_value("Item", d.item_code, "last_purchase_rate")
|
|
||||||
if item_last_purchase_rate:
|
|
||||||
d.base_price_list_rate = d.base_rate = d.price_list_rate \
|
|
||||||
= d.last_purchase_rate = item_last_purchase_rate
|
|
||||||
|
|
||||||
# Check for Closed status
|
# Check for Closed status
|
||||||
def check_for_closed_status(self):
|
def check_for_closed_status(self):
|
||||||
@ -185,29 +185,39 @@ class PurchaseOrder(BuyingController):
|
|||||||
self.set_status(update=True, status=status)
|
self.set_status(update=True, status=status)
|
||||||
self.update_requested_qty()
|
self.update_requested_qty()
|
||||||
self.update_ordered_qty()
|
self.update_ordered_qty()
|
||||||
|
if self.is_subcontracted == "Yes":
|
||||||
|
self.update_reserved_qty_for_subcontract()
|
||||||
|
|
||||||
self.notify_update()
|
self.notify_update()
|
||||||
clear_doctype_notifications(self)
|
clear_doctype_notifications(self)
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
|
super(PurchaseOrder, self).on_submit()
|
||||||
|
|
||||||
if self.is_against_so():
|
if self.is_against_so():
|
||||||
self.update_status_updater()
|
self.update_status_updater()
|
||||||
|
|
||||||
self.update_prevdoc_status()
|
self.update_prevdoc_status()
|
||||||
self.update_requested_qty()
|
self.update_requested_qty()
|
||||||
self.update_ordered_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,
|
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
|
||||||
self.company, self.base_grand_total)
|
self.company, self.base_grand_total)
|
||||||
|
|
||||||
update_last_purchase_rate(self, is_submit = 1)
|
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
|
super(PurchaseOrder, self).on_cancel()
|
||||||
|
|
||||||
if self.is_against_so():
|
if self.is_against_so():
|
||||||
self.update_status_updater()
|
self.update_status_updater()
|
||||||
|
|
||||||
if self.has_drop_ship_item():
|
if self.has_drop_ship_item():
|
||||||
self.update_delivered_qty_in_sales_order()
|
self.update_delivered_qty_in_sales_order()
|
||||||
|
|
||||||
|
if self.is_subcontracted == "Yes":
|
||||||
|
self.update_reserved_qty_for_subcontract()
|
||||||
|
|
||||||
self.check_for_closed_status()
|
self.check_for_closed_status()
|
||||||
|
|
||||||
frappe.db.set(self,'status','Cancelled')
|
frappe.db.set(self,'status','Cancelled')
|
||||||
@ -218,8 +228,6 @@ class PurchaseOrder(BuyingController):
|
|||||||
self.update_requested_qty()
|
self.update_requested_qty()
|
||||||
self.update_ordered_qty()
|
self.update_ordered_qty()
|
||||||
|
|
||||||
update_last_purchase_rate(self, is_submit = 0)
|
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -257,6 +265,27 @@ class PurchaseOrder(BuyingController):
|
|||||||
if item.delivered_by_supplier == 1:
|
if item.delivered_by_supplier == 1:
|
||||||
item.received_qty = item.qty
|
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
|
||||||
|
|
||||||
|
conversion_rate = flt(conversion_rate) or 1.0
|
||||||
|
|
||||||
|
last_purchase_details = get_last_purchase_details(item_code, name)
|
||||||
|
if last_purchase_details:
|
||||||
|
last_purchase_rate = (last_purchase_details['base_rate'] * (flt(conversion_factor) or 1.0)) / conversion_rate
|
||||||
|
return last_purchase_rate
|
||||||
|
else:
|
||||||
|
item_last_purchase_rate = frappe.db.get_value("Item", item_code, "last_purchase_rate")
|
||||||
|
if item_last_purchase_rate:
|
||||||
|
return item_last_purchase_rate
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def close_or_unclose_purchase_orders(names, status):
|
def close_or_unclose_purchase_orders(names, status):
|
||||||
if not frappe.has_permission("Purchase Order", "write"):
|
if not frappe.has_permission("Purchase Order", "write"):
|
||||||
|
@ -6,8 +6,8 @@ import unittest
|
|||||||
import frappe
|
import frappe
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from frappe.utils import flt, add_days, nowdate
|
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_stock_entry as make_subcontract_transfer_entry)
|
||||||
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||||
|
|
||||||
class TestPurchaseOrder(unittest.TestCase):
|
class TestPurchaseOrder(unittest.TestCase):
|
||||||
def test_make_purchase_receipt(self):
|
def test_make_purchase_receipt(self):
|
||||||
@ -182,24 +182,129 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
pi.insert()
|
pi.insert()
|
||||||
self.assertTrue(pi.get('payment_schedule'))
|
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
|
||||||
|
se = frappe.get_doc(make_subcontract_transfer_entry(po.name, "_Test FG Item"))
|
||||||
|
se.to_warehouse = "_Test Warehouse 1 - _TC"
|
||||||
|
for d in se.get("items"):
|
||||||
|
if d.item_code == "_Test Item":
|
||||||
|
d.qty = 6
|
||||||
|
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():
|
def get_same_items():
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"item_code": "_Test FG Item",
|
"item_code": "_Test FG Item",
|
||||||
"warehouse": "_Test Warehouse - _TC",
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
"qty": 1,
|
"qty": 1,
|
||||||
"rate": 500,
|
"rate": 500,
|
||||||
"schedule_date": add_days(nowdate(), 1)
|
"schedule_date": add_days(nowdate(), 1)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"item_code": "_Test FG Item",
|
"item_code": "_Test FG Item",
|
||||||
"warehouse": "_Test Warehouse - _TC",
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
"qty": 4,
|
"qty": 4,
|
||||||
"rate": 500,
|
"rate": 500,
|
||||||
"schedule_date": add_days(nowdate(), 1)
|
"schedule_date": add_days(nowdate(), 1)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
def create_purchase_order(**args):
|
def create_purchase_order(**args):
|
||||||
po = frappe.new_doc("Purchase Order")
|
po = frappe.new_doc("Purchase Order")
|
||||||
@ -224,6 +329,10 @@ def create_purchase_order(**args):
|
|||||||
if not args.do_not_save:
|
if not args.do_not_save:
|
||||||
po.insert()
|
po.insert()
|
||||||
if not args.do_not_submit:
|
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()
|
po.submit()
|
||||||
|
|
||||||
return po
|
return po
|
||||||
|
@ -24,7 +24,7 @@ QUnit.test("test: purchase order with taxes and charges", function(assert) {
|
|||||||
]
|
]
|
||||||
]},
|
]},
|
||||||
|
|
||||||
{taxes_and_charges: 'TEST In State GST'}
|
{taxes_and_charges: 'TEST In State GST - FT'}
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1169,7 +1169,7 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 1,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
@ -1259,7 +1259,7 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 1,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
@ -1897,7 +1897,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-11-30 14:17:15.817754",
|
"modified": "2017-12-14 09:36:40.837027",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order Item",
|
"name": "Purchase Order Item",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
@ -10,16 +11,20 @@
|
|||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 2,
|
||||||
"fieldname": "main_item_code",
|
"fieldname": "main_item_code",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "Item Code",
|
"label": "Item Code",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
@ -29,6 +34,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -36,16 +42,20 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 2,
|
||||||
"fieldname": "rm_item_code",
|
"fieldname": "rm_item_code",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "Raw Material Item Code",
|
"label": "Raw Material Item Code",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
@ -55,6 +65,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -62,16 +73,20 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 2,
|
||||||
"fieldname": "required_qty",
|
"fieldname": "required_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "Supplied Qty",
|
"label": "Supplied Qty",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
@ -81,6 +96,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -88,16 +104,20 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 2,
|
||||||
"fieldname": "rate",
|
"fieldname": "rate",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "Rate",
|
"label": "Rate",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
@ -108,6 +128,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -115,16 +136,20 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "amount",
|
"fieldname": "amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "Amount",
|
"label": "Amount",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
@ -135,6 +160,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -142,16 +168,49 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "bom_detail_no",
|
"fieldname": "bom_detail_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_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",
|
"label": "BOM Detail No",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
@ -161,6 +220,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -168,16 +228,20 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "reference_name",
|
"fieldname": "reference_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 1,
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "Reference Name",
|
"label": "Reference Name",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
@ -187,6 +251,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -194,16 +259,20 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "conversion_factor",
|
"fieldname": "conversion_factor",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "Conversion Factor",
|
"label": "Conversion Factor",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
@ -213,6 +282,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -220,16 +290,20 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "stock_uom",
|
"fieldname": "stock_uom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "Stock Uom",
|
"label": "Stock Uom",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
@ -240,6 +314,38 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 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,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -247,17 +353,17 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
"hide_toolbar": 1,
|
"hide_toolbar": 1,
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"image_view": 0,
|
"image_view": 0,
|
||||||
"in_create": 0,
|
"in_create": 0,
|
||||||
"in_dialog": 0,
|
|
||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-07-11 03:28:05.533063",
|
"modified": "2018-01-05 14:47:15.400785",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order Item Supplied",
|
"name": "Purchase Order Item Supplied",
|
||||||
@ -266,5 +372,7 @@
|
|||||||
"quick_entry": 0,
|
"quick_entry": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"track_changes": 0,
|
||||||
"track_seen": 0
|
"track_seen": 0
|
||||||
}
|
}
|
@ -941,8 +941,8 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-08-31 16:10:44.049915",
|
"modified": "2017-12-26 04:50:15.317590",
|
||||||
"modified_by": "tundebabzy@gmail.com",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Supplier",
|
"name": "Supplier",
|
||||||
"name_case": "Title Case",
|
"name_case": "Title Case",
|
||||||
|
@ -17,7 +17,7 @@ QUnit.test("test: supplier quotation with taxes and charges", function(assert) {
|
|||||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
|
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
|
||||||
]
|
]
|
||||||
]},
|
]},
|
||||||
{taxes_and_charges:'TEST In State GST'},
|
{taxes_and_charges:'TEST In State GST - FT'},
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
() => {supplier_quotation_name = cur_frm.doc.name;},
|
() => {supplier_quotation_name = cur_frm.doc.name;},
|
||||||
|
@ -1072,7 +1072,7 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 1,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
@ -1162,7 +1162,7 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 1,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
@ -1614,7 +1614,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-11-30 14:22:10.542868",
|
"modified": "2017-12-14 09:37:47.427897",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Supplier Quotation Item",
|
"name": "Supplier Quotation Item",
|
||||||
|
61
erpnext/change_log/v10/v10_0_0.md
Normal file
61
erpnext/change_log/v10/v10_0_0.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
- Account Numbers
|
||||||
|
- Default Chart of accounts with account number
|
||||||
|
- Set account number for your existing chart of accounts
|
||||||
|
|
||||||
|
- Payment Terms
|
||||||
|
- Create Sales Invoice with multiple due dates and payment slab
|
||||||
|
|
||||||
|
- Agriculture (New Domain)
|
||||||
|
- Manage Crop, Crop Cycle, Land Unit, Disease and Fertilizer records
|
||||||
|
- Maintain records of Plant / Soil / Water Analysis
|
||||||
|
|
||||||
|
- Non Profits (New Domain)
|
||||||
|
- Manage records of Members, Donors, Volunteers and Chapters
|
||||||
|
- Portal for Grant Application
|
||||||
|
|
||||||
|
- Delivery Trip
|
||||||
|
- Track each of your delivery trips with their associated stops and timing
|
||||||
|
|
||||||
|
- Item Variants Update
|
||||||
|
- Create variants from Quick Entry dialog
|
||||||
|
- Create multiple variants from a single screen
|
||||||
|
|
||||||
|
- Shipping Rule
|
||||||
|
- Now available in Buying cycle
|
||||||
|
- Apply based on Net Weight / Fixed Amount / Net Total
|
||||||
|
|
||||||
|
- Updated POS
|
||||||
|
- Single POS Profile for multiple Users
|
||||||
|
- Sales Payment Summary (X & Z) report
|
||||||
|
- Fixed multiple bugs
|
||||||
|
|
||||||
|
- Employee Advance
|
||||||
|
- Manage Advances given to your employee and adjust with Expense Claim
|
||||||
|
|
||||||
|
- Payroll Entry
|
||||||
|
- Maintain records of each payroll processing
|
||||||
|
- Deprecated Process Payroll tool
|
||||||
|
|
||||||
|
- Schools to Education
|
||||||
|
- School module is renamed to Education
|
||||||
|
|
||||||
|
- Opening Invoice Tool
|
||||||
|
- A new tool to create opening invoices
|
||||||
|
|
||||||
|
- Asset Maintenance
|
||||||
|
- Maintain records of Asset Maintenance and Asset Repair
|
||||||
|
|
||||||
|
- Employee Tree
|
||||||
|
- Employee document now has a tree view, so you can create your organisation chart based on it
|
||||||
|
|
||||||
|
- Task Tree
|
||||||
|
- Task also has a Tree view now
|
||||||
|
|
||||||
|
- Education module update
|
||||||
|
- Course Scheduling Tool
|
||||||
|
|
||||||
|
- Batch selection based on earlier expiry date of the batch
|
||||||
|
|
||||||
|
- Invoice GL Entry based on rounded total (instead of grand total)
|
||||||
|
|
||||||
|
- Multiple UOM in Material Request
|
@ -134,6 +134,14 @@ def get_data():
|
|||||||
"link": "pos",
|
"link": "pos",
|
||||||
"label": _("POS")
|
"label": _("POS")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"module_name": "Leaderboard",
|
||||||
|
"color": "#589494",
|
||||||
|
"icon": "octicon octicon-graph",
|
||||||
|
"type": "page",
|
||||||
|
"link": "leaderboard",
|
||||||
|
"label": _("Leaderboard")
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"module_name": "Projects",
|
"module_name": "Projects",
|
||||||
"color": "#8e44ad",
|
"color": "#8e44ad",
|
||||||
@ -292,18 +300,21 @@ def get_data():
|
|||||||
"label": _("Hub")
|
"label": _("Hub")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"module_name": "Data Import Tool",
|
"module_name": "Data Import",
|
||||||
"color": "#7f8c8d",
|
"color": "#FFF168",
|
||||||
"icon": "octicon octicon-circuit-board",
|
"reverse": 1,
|
||||||
"type": "page",
|
"doctype": "Data Import",
|
||||||
"link": "data-import-tool",
|
"icon": "octicon octicon-cloud-upload",
|
||||||
"label": _("Data Import Tool")
|
"label": _("Data Import"),
|
||||||
|
"link": "List/Data Import",
|
||||||
|
"type": "list"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"module_name": "Restaurant",
|
"module_name": "Restaurant",
|
||||||
"color": "#EA81E8",
|
"color": "#EA81E8",
|
||||||
"icon": "🍔",
|
"icon": "🍔",
|
||||||
"_doctype": "Restaurant",
|
"_doctype": "Restaurant",
|
||||||
|
"type": "list",
|
||||||
"link": "List/Restaurant",
|
"link": "List/Restaurant",
|
||||||
"label": _("Restaurant"),
|
"label": _("Restaurant"),
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
@ -322,7 +333,7 @@ def get_data():
|
|||||||
"label": _("Crop"),
|
"label": _("Crop"),
|
||||||
"color": "#8BC34A",
|
"color": "#8BC34A",
|
||||||
"icon": "fa fa-tree",
|
"icon": "fa fa-tree",
|
||||||
"type": "link",
|
"type": "list",
|
||||||
"link": "List/Crop",
|
"link": "List/Crop",
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
},
|
},
|
||||||
@ -332,7 +343,7 @@ def get_data():
|
|||||||
"label": _("Crop Cycle"),
|
"label": _("Crop Cycle"),
|
||||||
"color": "#8BC34A",
|
"color": "#8BC34A",
|
||||||
"icon": "fa fa-circle-o-notch",
|
"icon": "fa fa-circle-o-notch",
|
||||||
"type": "link",
|
"type": "list",
|
||||||
"link": "List/Crop Cycle",
|
"link": "List/Crop Cycle",
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
},
|
},
|
||||||
@ -342,7 +353,7 @@ def get_data():
|
|||||||
"label": _("Fertilizer"),
|
"label": _("Fertilizer"),
|
||||||
"color": "#8BC34A",
|
"color": "#8BC34A",
|
||||||
"icon": "fa fa-leaf",
|
"icon": "fa fa-leaf",
|
||||||
"type": "link",
|
"type": "list",
|
||||||
"link": "List/Fertilizer",
|
"link": "List/Fertilizer",
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
},
|
},
|
||||||
@ -352,7 +363,7 @@ def get_data():
|
|||||||
"label": _("Land Unit"),
|
"label": _("Land Unit"),
|
||||||
"color": "#8BC34A",
|
"color": "#8BC34A",
|
||||||
"icon": "fa fa-map",
|
"icon": "fa fa-map",
|
||||||
"type": "link",
|
"type": "list",
|
||||||
"link": "List/Land Unit",
|
"link": "List/Land Unit",
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
},
|
},
|
||||||
@ -362,7 +373,7 @@ def get_data():
|
|||||||
"label": _("Disease"),
|
"label": _("Disease"),
|
||||||
"color": "#8BC34A",
|
"color": "#8BC34A",
|
||||||
"icon": "octicon octicon-bug",
|
"icon": "octicon octicon-bug",
|
||||||
"type": "link",
|
"type": "list",
|
||||||
"link": "List/Disease",
|
"link": "List/Disease",
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
},
|
},
|
||||||
@ -372,7 +383,7 @@ def get_data():
|
|||||||
"label": _("Plant Analysis"),
|
"label": _("Plant Analysis"),
|
||||||
"color": "#8BC34A",
|
"color": "#8BC34A",
|
||||||
"icon": "fa fa-pagelines",
|
"icon": "fa fa-pagelines",
|
||||||
"type": "link",
|
"type": "list",
|
||||||
"link": "List/Plant Analysis",
|
"link": "List/Plant Analysis",
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
},
|
},
|
||||||
@ -382,7 +393,7 @@ def get_data():
|
|||||||
"label": _("Soil Analysis"),
|
"label": _("Soil Analysis"),
|
||||||
"color": "#8BC34A",
|
"color": "#8BC34A",
|
||||||
"icon": "fa fa-flask",
|
"icon": "fa fa-flask",
|
||||||
"type": "link",
|
"type": "list",
|
||||||
"link": "List/Soil Analysis",
|
"link": "List/Soil Analysis",
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
},
|
},
|
||||||
@ -392,7 +403,7 @@ def get_data():
|
|||||||
"label": _("Soil Texture"),
|
"label": _("Soil Texture"),
|
||||||
"color": "#8BC34A",
|
"color": "#8BC34A",
|
||||||
"icon": "octicon octicon-beaker",
|
"icon": "octicon octicon-beaker",
|
||||||
"type": "link",
|
"type": "list",
|
||||||
"link": "List/Soil Texture",
|
"link": "List/Soil Texture",
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
},
|
},
|
||||||
@ -402,7 +413,7 @@ def get_data():
|
|||||||
"label": _("Water Analysis"),
|
"label": _("Water Analysis"),
|
||||||
"color": "#8BC34A",
|
"color": "#8BC34A",
|
||||||
"icon": "fa fa-tint",
|
"icon": "fa fa-tint",
|
||||||
"type": "link",
|
"type": "list",
|
||||||
"link": "List/Water Analysis",
|
"link": "List/Water Analysis",
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
},
|
},
|
||||||
@ -412,7 +423,7 @@ def get_data():
|
|||||||
"label": _("Weather"),
|
"label": _("Weather"),
|
||||||
"color": "#8BC34A",
|
"color": "#8BC34A",
|
||||||
"icon": "fa fa-sun-o",
|
"icon": "fa fa-sun-o",
|
||||||
"type": "link",
|
"type": "list",
|
||||||
"link": "List/Weather",
|
"link": "List/Weather",
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
},
|
},
|
||||||
@ -429,6 +440,7 @@ def get_data():
|
|||||||
"color": "#E9AB17",
|
"color": "#E9AB17",
|
||||||
"icon": "fa fa-gift",
|
"icon": "fa fa-gift",
|
||||||
"_doctype": "Grant Application",
|
"_doctype": "Grant Application",
|
||||||
|
"type": "list",
|
||||||
"link": "List/Grant Application",
|
"link": "List/Grant Application",
|
||||||
"label": _("Grant Application"),
|
"label": _("Grant Application"),
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
@ -439,6 +451,7 @@ def get_data():
|
|||||||
"color": "#7F5A58",
|
"color": "#7F5A58",
|
||||||
"icon": "fa fa-tint",
|
"icon": "fa fa-tint",
|
||||||
"_doctype": "Donor",
|
"_doctype": "Donor",
|
||||||
|
"type": "list",
|
||||||
"link": "List/Donor",
|
"link": "List/Donor",
|
||||||
"label": _("Donor"),
|
"label": _("Donor"),
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
@ -448,6 +461,7 @@ def get_data():
|
|||||||
"color": "#7E587E",
|
"color": "#7E587E",
|
||||||
"icon": "fa fa-angellist",
|
"icon": "fa fa-angellist",
|
||||||
"_doctype": "Volunteer",
|
"_doctype": "Volunteer",
|
||||||
|
"type": "list",
|
||||||
"link": "List/Volunteer",
|
"link": "List/Volunteer",
|
||||||
"label": _("Volunteer"),
|
"label": _("Volunteer"),
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
@ -457,6 +471,7 @@ def get_data():
|
|||||||
"color": "#79BAEC",
|
"color": "#79BAEC",
|
||||||
"icon": "fa fa-users",
|
"icon": "fa fa-users",
|
||||||
"_doctype": "Member",
|
"_doctype": "Member",
|
||||||
|
"type": "list",
|
||||||
"link": "List/Member",
|
"link": "List/Member",
|
||||||
"label": _("Member"),
|
"label": _("Member"),
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
@ -466,6 +481,7 @@ def get_data():
|
|||||||
"color": "#3B9C9C",
|
"color": "#3B9C9C",
|
||||||
"icon": "fa fa-handshake-o",
|
"icon": "fa fa-handshake-o",
|
||||||
"_doctype": "Chapter",
|
"_doctype": "Chapter",
|
||||||
|
"type": "list",
|
||||||
"link": "List/Chapter",
|
"link": "List/Chapter",
|
||||||
"label": _("Chapter"),
|
"label": _("Chapter"),
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
|
@ -11,7 +11,7 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Patient Appointment",
|
"name": "Patient Appointment",
|
||||||
"description": _("Patient Appointment"),
|
"label": _("Patient Appointment"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
@ -43,7 +43,7 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Lab Test",
|
"name": "Lab Test",
|
||||||
"description": _("Results"),
|
"label": _("Lab Test"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
@ -53,7 +53,8 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "report",
|
"type": "report",
|
||||||
"name": "Lab Test Report",
|
"name": "Lab Test Report",
|
||||||
"is_query_report": True
|
"is_query_report": True,
|
||||||
|
"label": _("Lab Test Report"),
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -69,7 +70,7 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Physician",
|
"name": "Physician",
|
||||||
"label": "Physician",
|
"label": _("Physician"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
@ -100,57 +101,57 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Medical Department",
|
"name": "Medical Department",
|
||||||
"label": "Medical Department"
|
"label": _("Medical Department"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Appointment Type",
|
"name": "Appointment Type",
|
||||||
"description": _("Appointment Type Master"),
|
"label": _("Appointment Type"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Prescription Dosage",
|
"name": "Prescription Dosage",
|
||||||
"description": _("Prescription Dosage")
|
"label": _("Prescription Dosage")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Prescription Duration",
|
"name": "Prescription Duration",
|
||||||
"description": _("Prescription Period")
|
"label": _("Prescription Duration")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Complaint",
|
"name": "Complaint",
|
||||||
"description": _("Complaint")
|
"label": _("Complaint")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Diagnosis",
|
"name": "Diagnosis",
|
||||||
"description": _("Diagnosis")
|
"label": _("Diagnosis")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Lab Test Sample",
|
"name": "Lab Test Sample",
|
||||||
"description": _("Test Sample Master."),
|
"label": _("Test Sample."),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Lab Test UOM",
|
"name": "Lab Test UOM",
|
||||||
"description": _("Lab Test UOM.")
|
"label": _("Lab Test UOM.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Antibiotic",
|
"name": "Antibiotic",
|
||||||
"description": _("Antibiotic.")
|
"label": _("Antibiotic.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Sensitivity",
|
"name": "Sensitivity",
|
||||||
"description": _("Sensitivity Naming.")
|
"label": _("Sensitivity Naming.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Lab Test Template",
|
"name": "Lab Test Template",
|
||||||
"description": _("Lab Test Configurations.")
|
"label": _("Lab Test Template.")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,11 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"label": _("Expense Claims"),
|
"label": _("Expense Claims"),
|
||||||
"items": [
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Employee Advance",
|
||||||
|
"description": _("Manage advance amount given to the Employee"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Expense Claim",
|
"name": "Expense Claim",
|
||||||
|
@ -24,7 +24,7 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "help",
|
"type": "help",
|
||||||
"label": _("Report Builder"),
|
"label": _("Report Builder"),
|
||||||
"youtube_id": "y0o5iYZOioU"
|
"youtube_id": "TxJGUNarcQs"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "help",
|
"type": "help",
|
||||||
"label": _("Opening Stock Balance"),
|
"label": _("Opening Stock Balance"),
|
||||||
"youtube_id": "0yPgrtfeCTs"
|
"youtube_id": "nlHX0ZZ84Lw"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "help",
|
"type": "help",
|
||||||
@ -55,7 +55,7 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "help",
|
"type": "help",
|
||||||
"label": _("Users and Permissions"),
|
"label": _("Users and Permissions"),
|
||||||
"youtube_id": "fnBoRhBrwR4"
|
"youtube_id": "8Slw1hsTmUI"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "help",
|
"type": "help",
|
||||||
@ -120,7 +120,7 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "help",
|
"type": "help",
|
||||||
"label": _("Sales Order to Payment"),
|
"label": _("Sales Order to Payment"),
|
||||||
"youtube_id": "7AMq4lqkN4A"
|
"youtube_id": "1eP90MWoDQM"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "help",
|
"type": "help",
|
||||||
@ -195,12 +195,12 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "help",
|
"type": "help",
|
||||||
"label": _("Material Request to Purchase Order"),
|
"label": _("Material Request to Purchase Order"),
|
||||||
"youtube_id": "4TN9kPyfIqM"
|
"youtube_id": "55Gk2j7Q8Zw"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "help",
|
"type": "help",
|
||||||
"label": _("Purchase Order to Payment"),
|
"label": _("Purchase Order to Payment"),
|
||||||
"youtube_id": "EK65tLdVUDk"
|
"youtube_id": "efFajTTQBa8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "help",
|
"type": "help",
|
||||||
@ -261,7 +261,7 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "help",
|
"type": "help",
|
||||||
"label": _("Managing Projects"),
|
"label": _("Managing Projects"),
|
||||||
"youtube_id": "egxIGwtoKI4"
|
"youtube_id": "gCzShu9Niu4"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -56,7 +56,12 @@ def get_data():
|
|||||||
"name": "Stock Ageing",
|
"name": "Stock Ageing",
|
||||||
"doctype": "Item",
|
"doctype": "Item",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "report",
|
||||||
|
"is_query_report": True,
|
||||||
|
"name": "Item Price Stock",
|
||||||
|
"doctype": "Item",
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -64,15 +64,14 @@ class AccountsController(TransactionBase):
|
|||||||
def validate_invoice_documents_schedule(self):
|
def validate_invoice_documents_schedule(self):
|
||||||
self.validate_payment_schedule_dates()
|
self.validate_payment_schedule_dates()
|
||||||
self.set_due_date()
|
self.set_due_date()
|
||||||
self.validate_invoice_portion()
|
|
||||||
self.set_payment_schedule()
|
self.set_payment_schedule()
|
||||||
self.validate_payment_schedule_amount()
|
self.validate_payment_schedule_amount()
|
||||||
self.validate_due_date()
|
self.validate_due_date()
|
||||||
self.validate_advance_entries()
|
self.validate_advance_entries()
|
||||||
|
|
||||||
def validate_non_invoice_documents_schedule(self):
|
def validate_non_invoice_documents_schedule(self):
|
||||||
self.validate_invoice_portion()
|
|
||||||
self.set_payment_schedule()
|
self.set_payment_schedule()
|
||||||
|
self.validate_payment_schedule_dates()
|
||||||
self.validate_payment_schedule_amount()
|
self.validate_payment_schedule_amount()
|
||||||
|
|
||||||
def validate_all_documents_schedule(self):
|
def validate_all_documents_schedule(self):
|
||||||
@ -233,9 +232,10 @@ class AccountsController(TransactionBase):
|
|||||||
tax_master_doctype = self.meta.get_field("taxes_and_charges").options
|
tax_master_doctype = self.meta.get_field("taxes_and_charges").options
|
||||||
|
|
||||||
if self.is_new() and not self.get("taxes"):
|
if self.is_new() and not self.get("taxes"):
|
||||||
if not self.get("taxes_and_charges"):
|
if self.company and not self.get("taxes_and_charges"):
|
||||||
# get the default tax master
|
# get the default tax master
|
||||||
self.taxes_and_charges = frappe.db.get_value(tax_master_doctype, {"is_default": 1})
|
self.taxes_and_charges = frappe.db.get_value(tax_master_doctype,
|
||||||
|
{"is_default": 1, 'company': self.company})
|
||||||
|
|
||||||
self.append_taxes_from_master(tax_master_doctype)
|
self.append_taxes_from_master(tax_master_doctype)
|
||||||
|
|
||||||
@ -375,6 +375,17 @@ class AccountsController(TransactionBase):
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def is_inclusive_tax(self):
|
||||||
|
is_inclusive = cint(frappe.db.get_single_value("Accounts Settings",
|
||||||
|
"show_inclusive_tax_in_print"))
|
||||||
|
|
||||||
|
if is_inclusive:
|
||||||
|
is_inclusive = 0
|
||||||
|
if self.get("taxes", filters={"included_in_print_rate": 1}):
|
||||||
|
is_inclusive = 1
|
||||||
|
|
||||||
|
return is_inclusive
|
||||||
|
|
||||||
def validate_advance_entries(self):
|
def validate_advance_entries(self):
|
||||||
order_field = "sales_order" if self.doctype == "Sales Invoice" else "purchase_order"
|
order_field = "sales_order" if self.doctype == "Sales Invoice" else "purchase_order"
|
||||||
order_list = list(set([d.get(order_field)
|
order_list = list(set([d.get(order_field)
|
||||||
@ -650,6 +661,8 @@ class AccountsController(TransactionBase):
|
|||||||
date = self.get("due_date")
|
date = self.get("due_date")
|
||||||
due_date = date or posting_date
|
due_date = date or posting_date
|
||||||
grand_total = self.get("rounded_total") or self.grand_total
|
grand_total = self.get("rounded_total") or self.grand_total
|
||||||
|
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||||
|
grand_total = grand_total - flt(self.write_off_amount)
|
||||||
|
|
||||||
if not self.get("payment_schedule"):
|
if not self.get("payment_schedule"):
|
||||||
if self.get("payment_terms_template"):
|
if self.get("payment_terms_template"):
|
||||||
@ -661,7 +674,8 @@ class AccountsController(TransactionBase):
|
|||||||
self.append("payment_schedule", data)
|
self.append("payment_schedule", data)
|
||||||
else:
|
else:
|
||||||
for d in self.get("payment_schedule"):
|
for d in self.get("payment_schedule"):
|
||||||
d.payment_amount = grand_total * flt(d.invoice_portion) / 100
|
if d.invoice_portion:
|
||||||
|
d.payment_amount = grand_total * flt(d.invoice_portion) / 100
|
||||||
|
|
||||||
def set_due_date(self):
|
def set_due_date(self):
|
||||||
due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date]
|
due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date]
|
||||||
@ -671,15 +685,12 @@ class AccountsController(TransactionBase):
|
|||||||
def validate_payment_schedule_dates(self):
|
def validate_payment_schedule_dates(self):
|
||||||
dates = []
|
dates = []
|
||||||
li = []
|
li = []
|
||||||
if self.due_date and getdate(self.due_date) < getdate(self.posting_date):
|
|
||||||
frappe.throw(_("Due Date cannot be before posting date"))
|
|
||||||
|
|
||||||
for d in self.get("payment_schedule"):
|
for d in self.get("payment_schedule"):
|
||||||
if getdate(d.due_date) < getdate(self.posting_date):
|
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))
|
frappe.throw(_("Row {0}: Due Date cannot be before posting date").format(d.idx))
|
||||||
elif d.due_date in dates:
|
elif d.due_date in dates:
|
||||||
li.append('{0} in row {1}'.format(d.due_date, d.idx))
|
li.append('{0} in row {1}'.format(d.due_date, d.idx))
|
||||||
# frappe.throw(_("Row {0}: Duplicate due date found").format(d.idx))
|
|
||||||
dates.append(d.due_date)
|
dates.append(d.due_date)
|
||||||
|
|
||||||
if li:
|
if li:
|
||||||
@ -692,20 +703,14 @@ class AccountsController(TransactionBase):
|
|||||||
total = 0
|
total = 0
|
||||||
for d in self.get("payment_schedule"):
|
for d in self.get("payment_schedule"):
|
||||||
total += flt(d.payment_amount)
|
total += flt(d.payment_amount)
|
||||||
|
total = flt(total, self.precision("grand_total"))
|
||||||
|
|
||||||
grand_total = self.get("rounded_total") or self.grand_total
|
grand_total = flt(self.get("rounded_total") or self.grand_total, self.precision('grand_total'))
|
||||||
|
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||||
|
grand_total = grand_total - flt(self.write_off_amount)
|
||||||
if total != grand_total:
|
if total != grand_total:
|
||||||
frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total"))
|
frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total"))
|
||||||
|
|
||||||
def validate_invoice_portion(self):
|
|
||||||
if self.get("payment_schedule"):
|
|
||||||
total_portion = 0
|
|
||||||
for term in self.payment_schedule:
|
|
||||||
total_portion += flt(term.get('invoice_portion', 0))
|
|
||||||
|
|
||||||
if flt(total_portion, 2) != 100.00:
|
|
||||||
frappe.throw(_('Combined invoice portion must equal 100%'), indicator='red')
|
|
||||||
|
|
||||||
def is_rounded_total_disabled(self):
|
def is_rounded_total_disabled(self):
|
||||||
if self.meta.get_field("disable_rounded_total"):
|
if self.meta.get_field("disable_rounded_total"):
|
||||||
return self.disable_rounded_total
|
return self.disable_rounded_total
|
||||||
@ -717,8 +722,12 @@ def get_tax_rate(account_head):
|
|||||||
return frappe.db.get_value("Account", account_head, ["tax_rate", "account_name"], as_dict=True)
|
return frappe.db.get_value("Account", account_head, ["tax_rate", "account_name"], as_dict=True)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_default_taxes_and_charges(master_doctype):
|
def get_default_taxes_and_charges(master_doctype, company=None):
|
||||||
default_tax = frappe.db.get_value(master_doctype, {"is_default": 1})
|
if not company: return {}
|
||||||
|
|
||||||
|
default_tax = frappe.db.get_value(master_doctype,
|
||||||
|
{"is_default": 1, "company": company})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'taxes_and_charges': default_tax,
|
'taxes_and_charges': default_tax,
|
||||||
'taxes': get_taxes_and_charges(master_doctype, default_tax)
|
'taxes': get_taxes_and_charges(master_doctype, default_tax)
|
||||||
|
@ -8,7 +8,7 @@ from frappe.utils import flt,cint, cstr, getdate
|
|||||||
|
|
||||||
from erpnext.accounts.party import get_party_details
|
from erpnext.accounts.party import get_party_details
|
||||||
from erpnext.stock.get_item_details import get_conversion_factor
|
from erpnext.stock.get_item_details import get_conversion_factor
|
||||||
from erpnext.buying.utils import validate_for_items
|
from erpnext.buying.utils import validate_for_items, update_last_purchase_rate
|
||||||
from erpnext.stock.stock_ledger import get_valuation_rate
|
from erpnext.stock.stock_ledger import get_valuation_rate
|
||||||
|
|
||||||
from erpnext.controllers.stock_controller import StockController
|
from erpnext.controllers.stock_controller import StockController
|
||||||
@ -18,7 +18,10 @@ class BuyingController(StockController):
|
|||||||
if hasattr(self, "taxes"):
|
if hasattr(self, "taxes"):
|
||||||
self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings",
|
self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings",
|
||||||
"print_taxes_with_zero_amount"))
|
"print_taxes_with_zero_amount"))
|
||||||
|
self.flags.show_inclusive_tax_in_print = self.is_inclusive_tax()
|
||||||
|
|
||||||
self.print_templates = {
|
self.print_templates = {
|
||||||
|
"total": "templates/print_formats/includes/total.html",
|
||||||
"taxes": "templates/print_formats/includes/taxes.html"
|
"taxes": "templates/print_formats/includes/taxes.html"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +163,11 @@ class BuyingController(StockController):
|
|||||||
if item in self.sub_contracted_items and not item.bom:
|
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))
|
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:
|
else:
|
||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
if item.bom:
|
if item.bom:
|
||||||
@ -189,8 +197,16 @@ class BuyingController(StockController):
|
|||||||
def update_raw_materials_supplied(self, item, raw_material_table):
|
def update_raw_materials_supplied(self, item, raw_material_table):
|
||||||
bom_items = self.get_items_from_bom(item.item_code, item.bom)
|
bom_items = self.get_items_from_bom(item.item_code, item.bom)
|
||||||
raw_materials_cost = 0
|
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:
|
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
|
# check if exists
|
||||||
exists = 0
|
exists = 0
|
||||||
for d in self.get(raw_material_table):
|
for d in self.get(raw_material_table):
|
||||||
@ -210,6 +226,8 @@ class BuyingController(StockController):
|
|||||||
rm.rm_item_code = bom_item.item_code
|
rm.rm_item_code = bom_item.item_code
|
||||||
rm.stock_uom = bom_item.stock_uom
|
rm.stock_uom = bom_item.stock_uom
|
||||||
rm.required_qty = required_qty
|
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
|
rm.conversion_factor = item.conversion_factor
|
||||||
|
|
||||||
@ -261,7 +279,7 @@ class BuyingController(StockController):
|
|||||||
def get_items_from_bom(self, item_code, bom):
|
def get_items_from_bom(self, item_code, bom):
|
||||||
bom_items = frappe.db.sql("""select t2.item_code,
|
bom_items = frappe.db.sql("""select t2.item_code,
|
||||||
t2.stock_qty / ifnull(t1.quantity, 1) as qty_consumed_per_unit,
|
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
|
from `tabBOM` t1, `tabBOM Item` t2, tabItem t3
|
||||||
where t2.parent = t1.name and t1.item = %s
|
where t2.parent = t1.name and t1.item = %s
|
||||||
and t1.docstatus = 1 and t1.is_active = 1 and t1.name = %s
|
and t1.docstatus = 1 and t1.is_active = 1 and t1.name = %s
|
||||||
@ -336,7 +354,7 @@ class BuyingController(StockController):
|
|||||||
frappe.get_meta(item_row.doctype).get_label(fieldname), item_row['item_code'])))
|
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):
|
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 = []
|
sl_entries = []
|
||||||
stock_items = self.get_stock_items()
|
stock_items = self.get_stock_items()
|
||||||
@ -378,7 +396,7 @@ class BuyingController(StockController):
|
|||||||
self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock,
|
self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock,
|
||||||
via_landed_cost_voucher=via_landed_cost_voucher)
|
via_landed_cost_voucher=via_landed_cost_voucher)
|
||||||
|
|
||||||
def update_ordered_qty(self):
|
def update_ordered_and_reserved_qty(self):
|
||||||
po_map = {}
|
po_map = {}
|
||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
if self.doctype=="Purchase Receipt" \
|
if self.doctype=="Purchase Receipt" \
|
||||||
@ -397,6 +415,8 @@ class BuyingController(StockController):
|
|||||||
frappe.InvalidStatusError)
|
frappe.InvalidStatusError)
|
||||||
|
|
||||||
po_obj.update_ordered_qty(po_item_rows)
|
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):
|
def make_sl_entries_for_supplier_warehouse(self, sl_entries):
|
||||||
if hasattr(self, 'supplied_items'):
|
if hasattr(self, 'supplied_items'):
|
||||||
@ -409,6 +429,18 @@ class BuyingController(StockController):
|
|||||||
"actual_qty": -1*flt(d.consumed_qty),
|
"actual_qty": -1*flt(d.consumed_qty),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
def on_submit(self):
|
||||||
|
if self.get('is_return'):
|
||||||
|
return
|
||||||
|
|
||||||
|
update_last_purchase_rate(self, is_submit = 1)
|
||||||
|
|
||||||
|
def on_cancel(self):
|
||||||
|
if self.get('is_return'):
|
||||||
|
return
|
||||||
|
|
||||||
|
update_last_purchase_rate(self, is_submit = 0)
|
||||||
|
|
||||||
def validate_schedule_date(self):
|
def validate_schedule_date(self):
|
||||||
if not self.schedule_date:
|
if not self.schedule_date:
|
||||||
self.schedule_date = min([d.schedule_date for d in self.get("items")])
|
self.schedule_date = min([d.schedule_date for d in self.get("items")])
|
||||||
@ -418,8 +450,9 @@ class BuyingController(StockController):
|
|||||||
if not d.schedule_date:
|
if not d.schedule_date:
|
||||||
d.schedule_date = self.schedule_date
|
d.schedule_date = self.schedule_date
|
||||||
|
|
||||||
if d.schedule_date and getdate(d.schedule_date) < getdate(self.transaction_date):
|
if (d.schedule_date and self.transaction_date and
|
||||||
frappe.throw(_("Expected Date cannot be before Transaction Date"))
|
getdate(d.schedule_date) < getdate(self.transaction_date)):
|
||||||
|
frappe.throw(_("Row #{0}: Reqd by Date cannot be before Transaction Date").format(d.idx))
|
||||||
else:
|
else:
|
||||||
frappe.throw(_("Please enter Schedule Date"))
|
frappe.throw(_("Please enter Reqd by Date"))
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ def validate_item_variant_attributes(item, args=None):
|
|||||||
if not args:
|
if not args:
|
||||||
args = {d.attribute.lower():d.attribute_value for d in item.attributes}
|
args = {d.attribute.lower():d.attribute_value for d in item.attributes}
|
||||||
|
|
||||||
attribute_values, numeric_values = get_attribute_values()
|
attribute_values, numeric_values = get_attribute_values(item)
|
||||||
|
|
||||||
for attribute, value in args.items():
|
for attribute, value in args.items():
|
||||||
if not value:
|
if not value:
|
||||||
@ -96,16 +96,17 @@ def validate_item_attribute_value(attributes_list, attribute, attribute_value, i
|
|||||||
frappe.throw(_("Value {0} for Attribute {1} does not exist in the list of valid Item Attribute Values for Item {2}").format(
|
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'))
|
attribute_value, attribute, item), InvalidItemAttributeValueError, title=_('Invalid Attribute'))
|
||||||
|
|
||||||
def get_attribute_values():
|
def get_attribute_values(item):
|
||||||
if not frappe.flags.attribute_values:
|
if not frappe.flags.attribute_values:
|
||||||
attribute_values = {}
|
attribute_values = {}
|
||||||
numeric_values = {}
|
numeric_values = {}
|
||||||
for t in frappe.get_all("Item Attribute Value", fields=["parent", "attribute_value"]):
|
for t in frappe.get_all("Item Attribute Value", fields=["parent", "attribute_value"]):
|
||||||
attribute_values.setdefault(t.parent.lower(), []).append(t.attribute_value)
|
attribute_values.setdefault(t.parent.lower(), []).append(t.attribute_value)
|
||||||
|
|
||||||
for t in frappe.get_all('Item Attribute',
|
for t in frappe.get_all('Item Variant Attribute',
|
||||||
fields=["name", "from_range", "to_range", "increment"], filters={'numeric_values': 1}):
|
fields=["attribute", "from_range", "to_range", "increment"],
|
||||||
numeric_values[t.name.lower()] = t
|
filters={'numeric_values': 1, 'parent': item.variant_of}):
|
||||||
|
numeric_values[t.attribute.lower()] = t
|
||||||
|
|
||||||
frappe.flags.attribute_values = attribute_values
|
frappe.flags.attribute_values = attribute_values
|
||||||
frappe.flags.numeric_values = numeric_values
|
frappe.flags.numeric_values = numeric_values
|
||||||
|
@ -418,6 +418,6 @@ def get_batch_numbers(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
'where (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL)'
|
'where (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL)'
|
||||||
|
|
||||||
if filters and filters.get('item_code'):
|
if filters and filters.get('item_code'):
|
||||||
query += 'where item = %(item_code)s' % filters
|
query += 'and item = %(item_code)s'
|
||||||
|
|
||||||
return frappe.db.sql(query)
|
return frappe.db.sql(query, filters)
|
||||||
|
@ -16,7 +16,10 @@ class SellingController(StockController):
|
|||||||
if hasattr(self, "taxes"):
|
if hasattr(self, "taxes"):
|
||||||
self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings",
|
self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings",
|
||||||
"print_taxes_with_zero_amount"))
|
"print_taxes_with_zero_amount"))
|
||||||
|
self.flags.show_inclusive_tax_in_print = self.is_inclusive_tax()
|
||||||
|
|
||||||
self.print_templates = {
|
self.print_templates = {
|
||||||
|
"total": "templates/print_formats/includes/total.html",
|
||||||
"taxes": "templates/print_formats/includes/taxes.html"
|
"taxes": "templates/print_formats/includes/taxes.html"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +188,10 @@ class SellingController(StockController):
|
|||||||
'batch_no': cstr(p.batch_no).strip(),
|
'batch_no': cstr(p.batch_no).strip(),
|
||||||
'serial_no': cstr(p.serial_no).strip(),
|
'serial_no': cstr(p.serial_no).strip(),
|
||||||
'name': d.name,
|
'name': d.name,
|
||||||
'target_warehouse': p.target_warehouse
|
'target_warehouse': p.target_warehouse,
|
||||||
|
'company': self.company,
|
||||||
|
'voucher_type': self.doctype,
|
||||||
|
'allow_zero_valuation': d.allow_zero_valuation_rate
|
||||||
}))
|
}))
|
||||||
else:
|
else:
|
||||||
il.append(frappe._dict({
|
il.append(frappe._dict({
|
||||||
@ -198,7 +204,10 @@ class SellingController(StockController):
|
|||||||
'batch_no': cstr(d.get("batch_no")).strip(),
|
'batch_no': cstr(d.get("batch_no")).strip(),
|
||||||
'serial_no': cstr(d.get("serial_no")).strip(),
|
'serial_no': cstr(d.get("serial_no")).strip(),
|
||||||
'name': d.name,
|
'name': d.name,
|
||||||
'target_warehouse': d.target_warehouse
|
'target_warehouse': d.target_warehouse,
|
||||||
|
'company': self.company,
|
||||||
|
'voucher_type': self.doctype,
|
||||||
|
'allow_zero_valuation': d.allow_zero_valuation_rate
|
||||||
}))
|
}))
|
||||||
return il
|
return il
|
||||||
|
|
||||||
@ -293,7 +302,11 @@ class SellingController(StockController):
|
|||||||
"posting_date": self.posting_date,
|
"posting_date": self.posting_date,
|
||||||
"posting_time": self.posting_time,
|
"posting_time": self.posting_time,
|
||||||
"qty": -1*flt(d.qty),
|
"qty": -1*flt(d.qty),
|
||||||
"serial_no": d.serial_no
|
"serial_no": d.serial_no,
|
||||||
|
"company": d.company,
|
||||||
|
"voucher_type": d.voucher_type,
|
||||||
|
"voucher_no": d.name,
|
||||||
|
"allow_zero_valuation": d.allow_zero_valuation
|
||||||
})
|
})
|
||||||
target_warehouse_sle.update({
|
target_warehouse_sle.update({
|
||||||
"incoming_rate": get_incoming_rate(args)
|
"incoming_rate": get_incoming_rate(args)
|
||||||
|
@ -70,7 +70,6 @@ class calculate_taxes_and_totals(object):
|
|||||||
item.net_rate = item.rate
|
item.net_rate = item.rate
|
||||||
item.amount = flt(item.rate * item.qty, item.precision("amount"))
|
item.amount = flt(item.rate * item.qty, item.precision("amount"))
|
||||||
item.net_amount = item.amount
|
item.net_amount = item.amount
|
||||||
item.total_weight = flt(item.weight_per_unit * item.qty)
|
|
||||||
|
|
||||||
self._set_in_company_currency(item, ["price_list_rate", "rate", "net_rate", "amount", "net_amount"])
|
self._set_in_company_currency(item, ["price_list_rate", "rate", "net_rate", "amount", "net_amount"])
|
||||||
|
|
||||||
@ -164,13 +163,12 @@ class calculate_taxes_and_totals(object):
|
|||||||
return tax.rate
|
return tax.rate
|
||||||
|
|
||||||
def calculate_net_total(self):
|
def calculate_net_total(self):
|
||||||
self.doc.total = self.doc.base_total = self.doc.net_total = self.doc.base_net_total = self.doc.total_net_weight= 0.0
|
self.doc.total = self.doc.base_total = self.doc.net_total = self.doc.base_net_total = 0.0
|
||||||
for item in self.doc.get("items"):
|
for item in self.doc.get("items"):
|
||||||
self.doc.total += item.amount
|
self.doc.total += item.amount
|
||||||
self.doc.base_total += item.base_amount
|
self.doc.base_total += item.base_amount
|
||||||
self.doc.net_total += item.net_amount
|
self.doc.net_total += item.net_amount
|
||||||
self.doc.base_net_total += item.base_net_amount
|
self.doc.base_net_total += item.base_net_amount
|
||||||
self.doc.total_net_weight += item.total_weight
|
|
||||||
|
|
||||||
self.doc.round_floats_in(self.doc, ["total", "base_total", "net_total", "base_net_total"])
|
self.doc.round_floats_in(self.doc, ["total", "base_total", "net_total", "base_net_total"])
|
||||||
|
|
||||||
@ -400,7 +398,8 @@ class calculate_taxes_and_totals(object):
|
|||||||
|
|
||||||
for tax in self.doc.get("taxes"):
|
for tax in self.doc.get("taxes"):
|
||||||
if tax.charge_type == "Actual":
|
if tax.charge_type == "Actual":
|
||||||
actual_taxes_dict.setdefault(tax.idx, tax.tax_amount)
|
tax_amount = self.get_tax_amount_if_for_valuation_or_deduction(tax.tax_amount, tax)
|
||||||
|
actual_taxes_dict.setdefault(tax.idx, tax_amount)
|
||||||
elif tax.row_id in actual_taxes_dict:
|
elif tax.row_id in actual_taxes_dict:
|
||||||
actual_tax_amount = flt(actual_taxes_dict.get(tax.row_id, 0)) * flt(tax.rate) / 100
|
actual_tax_amount = flt(actual_taxes_dict.get(tax.row_id, 0)) * flt(tax.rate) / 100
|
||||||
actual_taxes_dict.setdefault(tax.idx, actual_tax_amount)
|
actual_taxes_dict.setdefault(tax.idx, actual_tax_amount)
|
||||||
@ -535,7 +534,7 @@ def get_itemised_tax_breakup_html(doc):
|
|||||||
for tax in doc.taxes:
|
for tax in doc.taxes:
|
||||||
if getattr(tax, "category", None) and tax.category=="Valuation":
|
if getattr(tax, "category", None) and tax.category=="Valuation":
|
||||||
continue
|
continue
|
||||||
if tax.description not in tax_accounts and tax.tax_amount_after_discount_amount:
|
if tax.description not in tax_accounts:
|
||||||
tax_accounts.append(tax.description)
|
tax_accounts.append(tax.description)
|
||||||
|
|
||||||
headers = get_itemised_tax_breakup_header(doc.doctype + " Item", tax_accounts)
|
headers = get_itemised_tax_breakup_header(doc.doctype + " Item", tax_accounts)
|
||||||
@ -545,6 +544,7 @@ def get_itemised_tax_breakup_html(doc):
|
|||||||
|
|
||||||
get_rounded_tax_amount(itemised_tax, doc.precision("tax_amount", "taxes"))
|
get_rounded_tax_amount(itemised_tax, doc.precision("tax_amount", "taxes"))
|
||||||
|
|
||||||
|
update_itemised_tax_data(doc)
|
||||||
frappe.flags.company = None
|
frappe.flags.company = None
|
||||||
|
|
||||||
return frappe.render_template(
|
return frappe.render_template(
|
||||||
@ -557,6 +557,12 @@ def get_itemised_tax_breakup_html(doc):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@erpnext.allow_regional
|
||||||
|
def update_itemised_tax_data(doc):
|
||||||
|
#Don't delete this method, used for localization
|
||||||
|
pass
|
||||||
|
|
||||||
@erpnext.allow_regional
|
@erpnext.allow_regional
|
||||||
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
|
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
|
||||||
return [_("Item"), _("Taxable Amount")] + tax_accounts
|
return [_("Item"), _("Taxable Amount")] + tax_accounts
|
||||||
|
@ -101,7 +101,7 @@ class Lead(SellingController):
|
|||||||
|
|
||||||
def set_lead_name(self):
|
def set_lead_name(self):
|
||||||
if not self.lead_name:
|
if not self.lead_name:
|
||||||
frappe.db.set_value("Lead", self.name, "lead_name", self.organization_name)
|
frappe.db.set_value("Lead", self.name, "lead_name", self.company_name)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_customer(source_name, target_doc=None):
|
def make_customer(source_name, target_doc=None):
|
||||||
@ -129,7 +129,6 @@ def _make_customer(source_name, target_doc=None, ignore_permissions=False):
|
|||||||
}
|
}
|
||||||
}}, target_doc, set_missing_values, ignore_permissions=ignore_permissions)
|
}}, target_doc, set_missing_values, ignore_permissions=ignore_permissions)
|
||||||
|
|
||||||
print(doclist)
|
|
||||||
return doclist
|
return doclist
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
"email_id": "test_lead4@example.com",
|
"email_id": "test_lead4@example.com",
|
||||||
"organization_lead": 1,
|
"organization_lead": 1,
|
||||||
"lead_name": "_Test Lead 4",
|
"lead_name": "_Test Lead 4",
|
||||||
"organization_name": "_Test Lead 4",
|
"company_name": "_Test Lead 4",
|
||||||
"status": "Open"
|
"status": "Open"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -232,7 +232,7 @@ def make_quotation(source_name, target_doc=None):
|
|||||||
quotation.conversion_rate = exchange_rate
|
quotation.conversion_rate = exchange_rate
|
||||||
|
|
||||||
# get default taxes
|
# get default taxes
|
||||||
taxes = get_default_taxes_and_charges("Sales Taxes and Charges Template")
|
taxes = get_default_taxes_and_charges("Sales Taxes and Charges Template", quotation.company)
|
||||||
if taxes.get('taxes'):
|
if taxes.get('taxes'):
|
||||||
quotation.update(taxes)
|
quotation.update(taxes)
|
||||||
|
|
||||||
|
@ -2,36 +2,43 @@
|
|||||||
{
|
{
|
||||||
"asset_name": "Macbook Pro - 1",
|
"asset_name": "Macbook Pro - 1",
|
||||||
"item_code": "Computer",
|
"item_code": "Computer",
|
||||||
"gross_purchase_amount": 100000
|
"gross_purchase_amount": 100000,
|
||||||
|
"asset_owner": "Company"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"asset_name": "Macbook Air - 1",
|
"asset_name": "Macbook Air - 1",
|
||||||
"item_code": "Computer",
|
"item_code": "Computer",
|
||||||
"gross_purchase_amount": 60000
|
"gross_purchase_amount": 60000,
|
||||||
|
"asset_owner": "Company"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"asset_name": "Conferrence Table",
|
"asset_name": "Conferrence Table",
|
||||||
"item_code": "Table",
|
"item_code": "Table",
|
||||||
"gross_purchase_amount": 30000
|
"gross_purchase_amount": 30000,
|
||||||
|
"asset_owner": "Company"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"asset_name": "Lunch Table",
|
"asset_name": "Lunch Table",
|
||||||
"item_code": "Table",
|
"item_code": "Table",
|
||||||
"gross_purchase_amount": 20000
|
"gross_purchase_amount": 20000,
|
||||||
|
"asset_owner": "Company"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"asset_name": "ERPNext",
|
"asset_name": "ERPNext",
|
||||||
"item_code": "ERP",
|
"item_code": "ERP",
|
||||||
"gross_purchase_amount": 100000
|
"gross_purchase_amount": 100000,
|
||||||
|
"asset_owner": "Company"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"asset_name": "Chair 1",
|
"asset_name": "Chair 1",
|
||||||
"item_code": "Chair",
|
"item_code": "Chair",
|
||||||
"gross_purchase_amount": 10000
|
"gross_purchase_amount": 10000,
|
||||||
|
"asset_owner": "Company"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"asset_name": "Chair 2",
|
"asset_name": "Chair 2",
|
||||||
"item_code": "Chair",
|
"item_code": "Chair",
|
||||||
"gross_purchase_amount": 10000
|
"gross_purchase_amount": 10000,
|
||||||
|
"asset_owner": "Company"
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -55,7 +55,7 @@ def complete_setup(domain='Manufacturing'):
|
|||||||
"fy_start_date": "2015-01-01",
|
"fy_start_date": "2015-01-01",
|
||||||
"fy_end_date": "2015-12-31",
|
"fy_end_date": "2015-12-31",
|
||||||
"bank_account": "National Bank",
|
"bank_account": "National Bank",
|
||||||
"domain": domain,
|
"domains": [domain],
|
||||||
"company_name": data.get(domain).get('company_name'),
|
"company_name": data.get(domain).get('company_name'),
|
||||||
"chart_of_accounts": "Standard",
|
"chart_of_accounts": "Standard",
|
||||||
"company_abbr": ''.join([d[0] for d in data.get(domain).get('company_name').split()]).upper(),
|
"company_abbr": ''.join([d[0] for d in data.get(domain).get('company_name').split()]).upper(),
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 377 KiB |
BIN
erpnext/docs/assets/img/human-resources/employee_advance.png
Normal file
BIN
erpnext/docs/assets/img/human-resources/employee_advance.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 172 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user