mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-24 15:39:20 +00:00
Merge branch 'hotfix' into limit-cond-fix
This commit is contained in:
@@ -15,7 +15,7 @@ install:
|
|||||||
- sudo rm /etc/apt/sources.list.d/docker.list
|
- sudo rm /etc/apt/sources.list.d/docker.list
|
||||||
- sudo apt-get install hhvm && rm -rf /home/travis/.kiex/
|
- sudo apt-get install hhvm && rm -rf /home/travis/.kiex/
|
||||||
- sudo apt-get purge -y mysql-common mysql-server mysql-client
|
- sudo apt-get purge -y mysql-common mysql-server mysql-client
|
||||||
- nvm install v7.10.0
|
- nvm install 10
|
||||||
- pip install python-coveralls
|
- pip install python-coveralls
|
||||||
- wget https://raw.githubusercontent.com/frappe/bench/master/playbooks/install.py
|
- wget https://raw.githubusercontent.com/frappe/bench/master/playbooks/install.py
|
||||||
- sudo python install.py --develop --user travis --without-bench-setup
|
- sudo python install.py --develop --user travis --without-bench-setup
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
[](https://travis-ci.com/frappe/erpnext)
|
[](https://travis-ci.com/frappe/erpnext)
|
||||||
[](https://gitter.im/frappe/erpnext?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
||||||
[](https://www.codetriage.com/frappe/erpnext)
|
[](https://www.codetriage.com/frappe/erpnext)
|
||||||
[](https://coveralls.io/github/frappe/erpnext?branch=develop)
|
[](https://coveralls.io/github/frappe/erpnext?branch=develop)
|
||||||
|
|
||||||
|
|||||||
@@ -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__ = '11.1.8'
|
__version__ = '11.1.20'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import date_diff, add_months, today, getdate, add_days, flt
|
from frappe.utils import date_diff, add_months, today, getdate, add_days, flt, get_last_day
|
||||||
from erpnext.accounts.utils import get_account_currency
|
from erpnext.accounts.utils import get_account_currency
|
||||||
from erpnext.accounts.general_ledger import make_gl_entries
|
from frappe.email import sendmail_to_system_managers
|
||||||
|
|
||||||
def validate_service_stop_date(doc):
|
def validate_service_stop_date(doc):
|
||||||
''' Validates service_stop_date for Purchase Invoice and Sales Invoice '''
|
''' Validates service_stop_date for Purchase Invoice and Sales Invoice '''
|
||||||
@@ -33,47 +33,49 @@ def validate_service_stop_date(doc):
|
|||||||
frappe.throw(_("Cannot change Service Stop Date for item in row {0}".format(item.idx)))
|
frappe.throw(_("Cannot change Service Stop Date for item in row {0}".format(item.idx)))
|
||||||
|
|
||||||
def convert_deferred_expense_to_expense(start_date=None, end_date=None):
|
def convert_deferred_expense_to_expense(start_date=None, end_date=None):
|
||||||
|
# book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
|
||||||
|
if not start_date:
|
||||||
|
start_date = add_months(today(), -1)
|
||||||
|
if not end_date:
|
||||||
|
end_date = add_days(today(), -1)
|
||||||
|
|
||||||
# check for the purchase invoice for which GL entries has to be done
|
# check for the purchase invoice for which GL entries has to be done
|
||||||
invoices = frappe.db.sql_list('''
|
invoices = frappe.db.sql_list('''
|
||||||
select distinct parent from `tabPurchase Invoice Item` where service_start_date<=%s and service_end_date>=%s
|
select distinct parent from `tabPurchase Invoice Item`
|
||||||
|
where service_start_date<=%s and service_end_date>=%s
|
||||||
and enable_deferred_expense = 1 and docstatus = 1 and ifnull(amount, 0) > 0
|
and enable_deferred_expense = 1 and docstatus = 1 and ifnull(amount, 0) > 0
|
||||||
''', (end_date or today(), start_date or add_months(today(), -1)))
|
''', (end_date, start_date))
|
||||||
|
|
||||||
# For each invoice, book deferred expense
|
# For each invoice, book deferred expense
|
||||||
for invoice in invoices:
|
for invoice in invoices:
|
||||||
doc = frappe.get_doc("Purchase Invoice", invoice)
|
doc = frappe.get_doc("Purchase Invoice", invoice)
|
||||||
book_deferred_income_or_expense(doc, start_date, end_date)
|
book_deferred_income_or_expense(doc, end_date)
|
||||||
|
|
||||||
def convert_deferred_revenue_to_income(start_date=None, end_date=None):
|
def convert_deferred_revenue_to_income(start_date=None, end_date=None):
|
||||||
|
# book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
|
||||||
|
if not start_date:
|
||||||
|
start_date = add_months(today(), -1)
|
||||||
|
if not end_date:
|
||||||
|
end_date = add_days(today(), -1)
|
||||||
|
|
||||||
# check for the sales invoice for which GL entries has to be done
|
# check for the sales invoice for which GL entries has to be done
|
||||||
invoices = frappe.db.sql_list('''
|
invoices = frappe.db.sql_list('''
|
||||||
select distinct parent from `tabSales Invoice Item` where service_start_date<=%s and service_end_date>=%s
|
select distinct parent from `tabSales Invoice Item`
|
||||||
|
where service_start_date<=%s and service_end_date>=%s
|
||||||
and enable_deferred_revenue = 1 and docstatus = 1 and ifnull(amount, 0) > 0
|
and enable_deferred_revenue = 1 and docstatus = 1 and ifnull(amount, 0) > 0
|
||||||
''', (end_date or today(), start_date or add_months(today(), -1)))
|
''', (end_date, start_date))
|
||||||
|
|
||||||
# For each invoice, book deferred revenue
|
|
||||||
for invoice in invoices:
|
for invoice in invoices:
|
||||||
doc = frappe.get_doc("Sales Invoice", invoice)
|
doc = frappe.get_doc("Sales Invoice", invoice)
|
||||||
book_deferred_income_or_expense(doc, start_date, end_date)
|
book_deferred_income_or_expense(doc, end_date)
|
||||||
|
|
||||||
|
def get_booking_dates(doc, item, posting_date=None):
|
||||||
|
if not posting_date:
|
||||||
|
posting_date = add_days(today(), -1)
|
||||||
|
|
||||||
|
last_gl_entry = False
|
||||||
|
|
||||||
def get_booking_dates(doc, item, start_date=None, end_date=None):
|
|
||||||
deferred_account = "deferred_revenue_account" if doc.doctype=="Sales Invoice" else "deferred_expense_account"
|
deferred_account = "deferred_revenue_account" if doc.doctype=="Sales Invoice" else "deferred_expense_account"
|
||||||
last_gl_entry, skip = False, False
|
|
||||||
|
|
||||||
booking_end_date = getdate(add_days(today(), -1) if not end_date else end_date)
|
|
||||||
if booking_end_date < item.service_start_date or \
|
|
||||||
(item.service_stop_date and booking_end_date.month > item.service_stop_date.month):
|
|
||||||
return None, None, None, True
|
|
||||||
elif booking_end_date >= item.service_end_date:
|
|
||||||
last_gl_entry = True
|
|
||||||
booking_end_date = item.service_end_date
|
|
||||||
elif item.service_stop_date and item.service_stop_date <= booking_end_date:
|
|
||||||
last_gl_entry = True
|
|
||||||
booking_end_date = item.service_stop_date
|
|
||||||
|
|
||||||
booking_start_date = getdate(add_months(today(), -1) if not start_date else start_date)
|
|
||||||
booking_start_date = booking_start_date \
|
|
||||||
if booking_start_date > item.service_start_date else item.service_start_date
|
|
||||||
|
|
||||||
prev_gl_entry = frappe.db.sql('''
|
prev_gl_entry = frappe.db.sql('''
|
||||||
select name, posting_date from `tabGL Entry` where company=%s and account=%s and
|
select name, posting_date from `tabGL Entry` where company=%s and account=%s and
|
||||||
@@ -81,17 +83,28 @@ def get_booking_dates(doc, item, start_date=None, end_date=None):
|
|||||||
order by posting_date desc limit 1
|
order by posting_date desc limit 1
|
||||||
''', (doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
|
''', (doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
|
||||||
|
|
||||||
if not prev_gl_entry and item.service_start_date < booking_start_date:
|
if prev_gl_entry:
|
||||||
booking_start_date = item.service_start_date
|
start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1))
|
||||||
elif prev_gl_entry:
|
else:
|
||||||
booking_start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1))
|
start_date = item.service_start_date
|
||||||
skip = True if booking_start_date > booking_end_date else False
|
|
||||||
|
|
||||||
return last_gl_entry, booking_start_date, booking_end_date, skip
|
end_date = get_last_day(start_date)
|
||||||
|
if end_date >= item.service_end_date:
|
||||||
|
end_date = item.service_end_date
|
||||||
|
last_gl_entry = True
|
||||||
|
elif item.service_stop_date and end_date >= item.service_stop_date:
|
||||||
|
end_date = item.service_stop_date
|
||||||
|
last_gl_entry = True
|
||||||
|
|
||||||
def calculate_amount_and_base_amount(doc, item, last_gl_entry, total_days, total_booking_days):
|
if end_date > getdate(posting_date):
|
||||||
account_currency = get_account_currency(item.expense_account)
|
end_date = posting_date
|
||||||
|
|
||||||
|
if getdate(start_date) <= getdate(end_date):
|
||||||
|
return start_date, end_date, last_gl_entry
|
||||||
|
else:
|
||||||
|
return None, None, None
|
||||||
|
|
||||||
|
def calculate_amount(doc, item, last_gl_entry, total_days, total_booking_days, account_currency):
|
||||||
if doc.doctype == "Sales Invoice":
|
if doc.doctype == "Sales Invoice":
|
||||||
total_credit_debit, total_credit_debit_currency = "debit", "debit_in_account_currency"
|
total_credit_debit, total_credit_debit_currency = "debit", "debit_in_account_currency"
|
||||||
deferred_account = "deferred_revenue_account"
|
deferred_account = "deferred_revenue_account"
|
||||||
@@ -123,28 +136,15 @@ def calculate_amount_and_base_amount(doc, item, last_gl_entry, total_days, total
|
|||||||
|
|
||||||
return amount, base_amount
|
return amount, base_amount
|
||||||
|
|
||||||
def book_deferred_income_or_expense(doc, start_date=None, end_date=None):
|
def book_deferred_income_or_expense(doc, posting_date=None):
|
||||||
# book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
|
|
||||||
# start_date: 1st of the last month or the start date
|
|
||||||
# end_date: end_date or today-1
|
|
||||||
enable_check = "enable_deferred_revenue" \
|
enable_check = "enable_deferred_revenue" \
|
||||||
if doc.doctype=="Sales Invoice" else "enable_deferred_expense"
|
if doc.doctype=="Sales Invoice" else "enable_deferred_expense"
|
||||||
|
|
||||||
gl_entries = []
|
def _book_deferred_revenue_or_expense(item):
|
||||||
for item in doc.get('items'):
|
start_date, end_date, last_gl_entry = get_booking_dates(doc, item, posting_date=posting_date)
|
||||||
if not item.get(enable_check): continue
|
if not (start_date and end_date): return
|
||||||
|
|
||||||
skip = False
|
|
||||||
last_gl_entry, booking_start_date, booking_end_date, skip = \
|
|
||||||
get_booking_dates(doc, item, start_date, end_date)
|
|
||||||
|
|
||||||
if skip: continue
|
|
||||||
total_days = date_diff(item.service_end_date, item.service_start_date) + 1
|
|
||||||
total_booking_days = date_diff(booking_end_date, booking_start_date) + 1
|
|
||||||
|
|
||||||
account_currency = get_account_currency(item.expense_account)
|
account_currency = get_account_currency(item.expense_account)
|
||||||
amount, base_amount = calculate_amount_and_base_amount(doc, item, last_gl_entry, total_days, total_booking_days)
|
|
||||||
|
|
||||||
if doc.doctype == "Sales Invoice":
|
if doc.doctype == "Sales Invoice":
|
||||||
against, project = doc.customer, doc.project
|
against, project = doc.customer, doc.project
|
||||||
credit_account, debit_account = item.income_account, item.deferred_revenue_account
|
credit_account, debit_account = item.income_account, item.deferred_revenue_account
|
||||||
@@ -152,36 +152,62 @@ def book_deferred_income_or_expense(doc, start_date=None, end_date=None):
|
|||||||
against, project = doc.supplier, item.project
|
against, project = doc.supplier, item.project
|
||||||
credit_account, debit_account = item.deferred_expense_account, item.expense_account
|
credit_account, debit_account = item.deferred_expense_account, item.expense_account
|
||||||
|
|
||||||
# GL Entry for crediting the amount in the deferred expense
|
total_days = date_diff(item.service_end_date, item.service_start_date) + 1
|
||||||
gl_entries.append(
|
total_booking_days = date_diff(end_date, start_date) + 1
|
||||||
doc.get_gl_dict({
|
|
||||||
"account": credit_account,
|
amount, base_amount = calculate_amount(doc, item, last_gl_entry,
|
||||||
"against": against,
|
total_days, total_booking_days, account_currency)
|
||||||
"credit": base_amount,
|
|
||||||
"credit_in_account_currency": amount,
|
make_gl_entries(doc, credit_account, debit_account, against,
|
||||||
"cost_center": item.cost_center,
|
amount, base_amount, end_date, project, account_currency, item.cost_center, item.name)
|
||||||
"voucher_detail_no": item.name,
|
|
||||||
'posting_date': booking_end_date,
|
if getdate(end_date) < getdate(posting_date) and not last_gl_entry:
|
||||||
'project': project
|
_book_deferred_revenue_or_expense(item)
|
||||||
}, account_currency)
|
|
||||||
)
|
|
||||||
# GL Entry to debit the amount from the expense
|
for item in doc.get('items'):
|
||||||
gl_entries.append(
|
if item.get(enable_check):
|
||||||
doc.get_gl_dict({
|
_book_deferred_revenue_or_expense(item)
|
||||||
"account": debit_account,
|
|
||||||
"against": against,
|
def make_gl_entries(doc, credit_account, debit_account, against,
|
||||||
"debit": base_amount,
|
amount, base_amount, posting_date, project, account_currency, cost_center, voucher_detail_no):
|
||||||
"debit_in_account_currency": amount,
|
# GL Entry for crediting the amount in the deferred expense
|
||||||
"cost_center": item.cost_center,
|
from erpnext.accounts.general_ledger import make_gl_entries
|
||||||
"voucher_detail_no": item.name,
|
|
||||||
'posting_date': booking_end_date,
|
gl_entries = []
|
||||||
'project': project
|
gl_entries.append(
|
||||||
}, account_currency)
|
doc.get_gl_dict({
|
||||||
)
|
"account": credit_account,
|
||||||
|
"against": against,
|
||||||
|
"credit": base_amount,
|
||||||
|
"credit_in_account_currency": amount,
|
||||||
|
"cost_center": cost_center,
|
||||||
|
"voucher_detail_no": voucher_detail_no,
|
||||||
|
'posting_date': posting_date,
|
||||||
|
'project': project
|
||||||
|
}, account_currency)
|
||||||
|
)
|
||||||
|
# GL Entry to debit the amount from the expense
|
||||||
|
gl_entries.append(
|
||||||
|
doc.get_gl_dict({
|
||||||
|
"account": debit_account,
|
||||||
|
"against": against,
|
||||||
|
"debit": base_amount,
|
||||||
|
"debit_in_account_currency": amount,
|
||||||
|
"cost_center": cost_center,
|
||||||
|
"voucher_detail_no": voucher_detail_no,
|
||||||
|
'posting_date': posting_date,
|
||||||
|
'project': project
|
||||||
|
}, account_currency)
|
||||||
|
)
|
||||||
|
|
||||||
if gl_entries:
|
if gl_entries:
|
||||||
try:
|
try:
|
||||||
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
|
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
except:
|
except:
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
frappe.log_error(message = frappe.get_traceback(), title = _("Error while processing deferred accounting for {0}").format(doc.name))
|
title = _("Error while processing deferred accounting for {0}").format(doc.name)
|
||||||
|
traceback = frappe.get_traceback()
|
||||||
|
frappe.log_error(message=traceback , title=title)
|
||||||
|
sendmail_to_system_managers(title, traceback)
|
||||||
@@ -632,6 +632,39 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"depends_on": "eval:(doc.report_type == 'Profit and Loss' && !doc.is_group)",
|
||||||
|
"fieldname": "include_in_gross",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Include in gross",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"has_web_view": 0,
|
||||||
@@ -645,7 +678,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2019-01-07 16:52:02.557837",
|
"modified": "2019-03-04 14:42:07.208893",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Account",
|
"name": "Account",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import cint, cstr
|
from frappe.utils import cint, cstr
|
||||||
from frappe import throw, _
|
from frappe import throw, _
|
||||||
from frappe.utils.nestedset import NestedSet
|
from frappe.utils.nestedset import NestedSet, get_ancestors_of, get_descendants_of
|
||||||
|
|
||||||
class RootNotEditable(frappe.ValidationError): pass
|
class RootNotEditable(frappe.ValidationError): pass
|
||||||
class BalanceMismatchError(frappe.ValidationError): pass
|
class BalanceMismatchError(frappe.ValidationError): pass
|
||||||
@@ -41,6 +41,7 @@ class Account(NestedSet):
|
|||||||
self.validate_frozen_accounts_modifier()
|
self.validate_frozen_accounts_modifier()
|
||||||
self.validate_balance_must_be_debit_or_credit()
|
self.validate_balance_must_be_debit_or_credit()
|
||||||
self.validate_account_currency()
|
self.validate_account_currency()
|
||||||
|
self.validate_root_company_and_sync_account_to_children()
|
||||||
|
|
||||||
def validate_parent(self):
|
def validate_parent(self):
|
||||||
"""Fetch Parent Details and validate parent account"""
|
"""Fetch Parent Details and validate parent account"""
|
||||||
@@ -90,6 +91,38 @@ class Account(NestedSet):
|
|||||||
if not self.parent_account and not self.is_group:
|
if not self.parent_account and not self.is_group:
|
||||||
frappe.throw(_("Root Account must be a group"))
|
frappe.throw(_("Root Account must be a group"))
|
||||||
|
|
||||||
|
def validate_root_company_and_sync_account_to_children(self):
|
||||||
|
# ignore validation while creating new compnay or while syncing to child companies
|
||||||
|
if frappe.local.flags.ignore_root_company_validation or self.flags.ignore_root_company_validation:
|
||||||
|
return
|
||||||
|
|
||||||
|
ancestors = get_root_company(self.company)
|
||||||
|
if ancestors:
|
||||||
|
if frappe.get_value("Company", self.company, "allow_account_creation_against_child_company"):
|
||||||
|
return
|
||||||
|
frappe.throw(_("Please add the account to root level Company - %s" % ancestors[0]))
|
||||||
|
else:
|
||||||
|
descendants = get_descendants_of('Company', self.company)
|
||||||
|
if not descendants: return
|
||||||
|
|
||||||
|
acc_name_map = {}
|
||||||
|
acc_name = frappe.db.get_value('Account', self.parent_account, "account_name")
|
||||||
|
for d in frappe.db.get_values('Account',
|
||||||
|
{"company": ["in", descendants], "account_name": acc_name},
|
||||||
|
["company", "name"], as_dict=True):
|
||||||
|
acc_name_map[d["company"]] = d["name"]
|
||||||
|
|
||||||
|
if not acc_name_map: return
|
||||||
|
|
||||||
|
for company in descendants:
|
||||||
|
doc = frappe.copy_doc(self)
|
||||||
|
doc.flags.ignore_root_company_validation = True
|
||||||
|
doc.update({"company": company, "account_currency": None,
|
||||||
|
"parent": acc_name_map[company], "parent_account": acc_name_map[company]})
|
||||||
|
doc.save()
|
||||||
|
frappe.msgprint(_("Account {0} is added in the child company {1}")
|
||||||
|
.format(doc.name, company))
|
||||||
|
|
||||||
def validate_group_or_ledger(self):
|
def validate_group_or_ledger(self):
|
||||||
if self.get("__islocal"):
|
if self.get("__islocal"):
|
||||||
return
|
return
|
||||||
@@ -250,3 +283,9 @@ def merge_account(old, new, is_group, root_type, company):
|
|||||||
frappe.rename_doc("Account", old, new, merge=1, ignore_permissions=1)
|
frappe.rename_doc("Account", old, new, merge=1, ignore_permissions=1)
|
||||||
|
|
||||||
return new
|
return new
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_root_company(company):
|
||||||
|
# return the topmost company in the hierarchy
|
||||||
|
ancestors = get_ancestors_of('Company', company, "lft asc")
|
||||||
|
return [ancestors[0]] if ancestors else []
|
||||||
|
|||||||
@@ -4,13 +4,42 @@ frappe.treeview_settings["Account"] = {
|
|||||||
breadcrumbs: "Accounts",
|
breadcrumbs: "Accounts",
|
||||||
title: __("Chart Of Accounts"),
|
title: __("Chart Of Accounts"),
|
||||||
get_tree_root: false,
|
get_tree_root: false,
|
||||||
filters: [{
|
filters: [
|
||||||
fieldname: "company",
|
{
|
||||||
fieldtype:"Select",
|
fieldname: "company",
|
||||||
options: erpnext.utils.get_tree_options("company"),
|
fieldtype:"Select",
|
||||||
label: __("Company"),
|
options: erpnext.utils.get_tree_options("company"),
|
||||||
default: erpnext.utils.get_tree_default("company")
|
label: __("Company"),
|
||||||
}],
|
default: erpnext.utils.get_tree_default("company"),
|
||||||
|
on_change: function() {
|
||||||
|
var me = frappe.treeview_settings['Account'].treeview;
|
||||||
|
var company = me.page.fields_dict.company.get_value();
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.accounts.doctype.account.account.get_root_company",
|
||||||
|
args: {
|
||||||
|
company: company,
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
if(r.message) {
|
||||||
|
let root_company = r.message.length ? r.message[0] : "";
|
||||||
|
me.page.fields_dict.root_company.set_value(root_company);
|
||||||
|
|
||||||
|
frappe.db.get_value("Company", {"name": company}, "allow_account_creation_against_child_company", (r) => {
|
||||||
|
frappe.flags.ignore_root_company_validation = r.allow_account_creation_against_child_company;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "root_company",
|
||||||
|
fieldtype:"Data",
|
||||||
|
label: __("Root Company"),
|
||||||
|
hidden: true,
|
||||||
|
disable_onchange: true
|
||||||
|
}
|
||||||
|
],
|
||||||
root_label: "Accounts",
|
root_label: "Accounts",
|
||||||
get_tree_nodes: 'erpnext.accounts.utils.get_children',
|
get_tree_nodes: 'erpnext.accounts.utils.get_children',
|
||||||
add_tree_node: 'erpnext.accounts.utils.add_ac',
|
add_tree_node: 'erpnext.accounts.utils.add_ac',
|
||||||
@@ -42,8 +71,8 @@ frappe.treeview_settings["Account"] = {
|
|||||||
],
|
],
|
||||||
ignore_fields:["parent_account"],
|
ignore_fields:["parent_account"],
|
||||||
onload: function(treeview) {
|
onload: function(treeview) {
|
||||||
frappe.treeview_settings['Account'].page = {};
|
frappe.treeview_settings['Account'].treeview = {};
|
||||||
$.extend(frappe.treeview_settings['Account'].page, treeview.page);
|
$.extend(frappe.treeview_settings['Account'].treeview, treeview);
|
||||||
function get_company() {
|
function get_company() {
|
||||||
return treeview.page.fields_dict.company.get_value();
|
return treeview.page.fields_dict.company.get_value();
|
||||||
}
|
}
|
||||||
@@ -78,6 +107,18 @@ frappe.treeview_settings["Account"] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
post_render: function(treeview) {
|
||||||
|
frappe.treeview_settings['Account'].treeview["tree"] = treeview.tree;
|
||||||
|
treeview.page.set_primary_action(__("New"), function() {
|
||||||
|
let root_company = treeview.page.fields_dict.root_company.get_value();
|
||||||
|
|
||||||
|
if(root_company) {
|
||||||
|
frappe.throw(__("Please add the account to root level Company - ") + root_company);
|
||||||
|
} else {
|
||||||
|
treeview.new_node();
|
||||||
|
}
|
||||||
|
}, "octicon octicon-plus");
|
||||||
|
},
|
||||||
onrender: function(node) {
|
onrender: function(node) {
|
||||||
if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){
|
if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){
|
||||||
var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr";
|
var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr";
|
||||||
@@ -93,6 +134,20 @@ frappe.treeview_settings["Account"] = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
toolbar: [
|
toolbar: [
|
||||||
|
{
|
||||||
|
label:__("Add Child"),
|
||||||
|
condition: function(node) {
|
||||||
|
return frappe.boot.user.can_create.indexOf("Account") !== -1
|
||||||
|
&& (!frappe.treeview_settings['Account'].treeview.page.fields_dict.root_company.get_value()
|
||||||
|
|| frappe.flags.ignore_root_company_validation)
|
||||||
|
&& node.expandable && !node.hide_add;
|
||||||
|
},
|
||||||
|
click: function() {
|
||||||
|
var me = frappe.treeview_settings['Account'].treeview;
|
||||||
|
me.new_node();
|
||||||
|
},
|
||||||
|
btnClass: "hidden-xs"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
condition: function(node) {
|
condition: function(node) {
|
||||||
return !node.root && frappe.boot.user.can_read.indexOf("GL Entry") !== -1
|
return !node.root && frappe.boot.user.can_read.indexOf("GL Entry") !== -1
|
||||||
@@ -103,7 +158,7 @@ frappe.treeview_settings["Account"] = {
|
|||||||
"account": node.label,
|
"account": node.label,
|
||||||
"from_date": frappe.sys_defaults.year_start_date,
|
"from_date": frappe.sys_defaults.year_start_date,
|
||||||
"to_date": frappe.sys_defaults.year_end_date,
|
"to_date": frappe.sys_defaults.year_end_date,
|
||||||
"company": frappe.treeview_settings['Account'].page.fields_dict.company.get_value()
|
"company": frappe.treeview_settings['Account'].treeview.page.fields_dict.company.get_value()
|
||||||
};
|
};
|
||||||
frappe.set_route("query-report", "General Ledger");
|
frappe.set_route("query-report", "General Ledger");
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -97,6 +97,19 @@ class TestAccount(unittest.TestCase):
|
|||||||
self.assertRaises(frappe.ValidationError, merge_account, "Capital Stock - _TC",\
|
self.assertRaises(frappe.ValidationError, merge_account, "Capital Stock - _TC",\
|
||||||
"Softwares - _TC", doc.is_group, doc.root_type, doc.company)
|
"Softwares - _TC", doc.is_group, doc.root_type, doc.company)
|
||||||
|
|
||||||
|
def test_account_sync(self):
|
||||||
|
del frappe.local.flags["ignore_root_company_validation"]
|
||||||
|
acc = frappe.new_doc("Account")
|
||||||
|
acc.account_name = "Test Sync Account"
|
||||||
|
acc.parent_account = "Temporary Accounts - _TC3"
|
||||||
|
acc.company = "_Test Company 3"
|
||||||
|
acc.insert()
|
||||||
|
|
||||||
|
acc_tc_4 = frappe.db.get_value('Account', {'account_name': "Test Sync Account", "company": "_Test Company 4"})
|
||||||
|
acc_tc_5 = frappe.db.get_value('Account', {'account_name': "Test Sync Account", "company": "_Test Company 5"})
|
||||||
|
self.assertEqual(acc_tc_4, "Test Sync Account - _TC4")
|
||||||
|
self.assertEqual(acc_tc_5, "Test Sync Account - _TC5")
|
||||||
|
|
||||||
def _make_test_records(verbose):
|
def _make_test_records(verbose):
|
||||||
from frappe.test_runner import make_test_objects
|
from frappe.test_runner import make_test_objects
|
||||||
|
|
||||||
@@ -168,13 +181,17 @@ def get_inventory_account(company, warehouse=None):
|
|||||||
return account
|
return account
|
||||||
|
|
||||||
def create_account(**kwargs):
|
def create_account(**kwargs):
|
||||||
account = frappe.get_doc(dict(
|
account = frappe.db.get_value("Account", filters={"account_name": kwargs.get("account_name"), "company": kwargs.get("company")})
|
||||||
doctype = "Account",
|
if account:
|
||||||
account_name = kwargs.get('account_name'),
|
return account
|
||||||
account_type = kwargs.get('account_type'),
|
else:
|
||||||
parent_account = kwargs.get('parent_account'),
|
account = frappe.get_doc(dict(
|
||||||
company = kwargs.get('company')
|
doctype = "Account",
|
||||||
))
|
account_name = kwargs.get('account_name'),
|
||||||
|
account_type = kwargs.get('account_type'),
|
||||||
|
parent_account = kwargs.get('parent_account'),
|
||||||
|
company = kwargs.get('company')
|
||||||
|
))
|
||||||
|
|
||||||
account.save()
|
account.save()
|
||||||
return account.name
|
return account.name
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
@@ -290,7 +291,7 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "IBAN",
|
"label": "IBAN",
|
||||||
"length": 25,
|
"length": 30,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
@@ -669,7 +670,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-07-20 13:55:36.996465",
|
"modified": "2019-03-05 17:56:05.103238",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Account",
|
"name": "Bank Account",
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ class BankReconciliation(Document):
|
|||||||
select
|
select
|
||||||
"Payment Entry" as payment_document, name as payment_entry,
|
"Payment Entry" as payment_document, name as payment_entry,
|
||||||
reference_no as cheque_number, reference_date as cheque_date,
|
reference_no as cheque_number, reference_date as cheque_date,
|
||||||
if(paid_from=%(account)s, paid_amount, "") as credit,
|
if(paid_from=%(account)s, paid_amount, 0) as credit,
|
||||||
if(paid_from=%(account)s, "", received_amount) as debit,
|
if(paid_from=%(account)s, 0, received_amount) as debit,
|
||||||
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
||||||
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
||||||
from `tabPayment Entry`
|
from `tabPayment Entry`
|
||||||
@@ -79,8 +79,12 @@ class BankReconciliation(Document):
|
|||||||
|
|
||||||
for d in entries:
|
for d in entries:
|
||||||
row = self.append('payment_entries', {})
|
row = self.append('payment_entries', {})
|
||||||
amount = d.debit if d.debit else d.credit
|
|
||||||
d.amount = fmt_money(amount, 2, d.account_currency) + " " + (_("Dr") if d.debit else _("Cr"))
|
amount = flt(d.get('debit', 0)) - flt(d.get('credit', 0))
|
||||||
|
|
||||||
|
formatted_amount = fmt_money(abs(amount), 2, d.account_currency)
|
||||||
|
d.amount = formatted_amount + " " + (_("Dr") if amount > 0 else _("Cr"))
|
||||||
|
|
||||||
d.pop("credit")
|
d.pop("credit")
|
||||||
d.pop("debit")
|
d.pop("debit")
|
||||||
d.pop("account_currency")
|
d.pop("account_currency")
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "Cost Center",
|
"default": "Cost Center",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "budget_against",
|
"fieldname": "budget_against",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -52,6 +54,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -86,6 +89,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:doc.budget_against == 'Cost Center'",
|
"depends_on": "eval:doc.budget_against == 'Cost Center'",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "cost_center",
|
"fieldname": "cost_center",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -120,6 +124,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:doc.budget_against == 'Project'",
|
"depends_on": "eval:doc.budget_against == 'Project'",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "project",
|
"fieldname": "project",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -153,6 +158,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "fiscal_year",
|
"fieldname": "fiscal_year",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -186,6 +192,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_3",
|
"fieldname": "column_break_3",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -218,6 +225,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:in_list([\"Stop\", \"Warn\"], doc.action_if_accumulated_monthly_budget_exceeded_on_po || doc.action_if_accumulated_monthly_budget_exceeded_on_mr || doc.action_if_accumulated_monthly_budget_exceeded_on_actual)",
|
"depends_on": "eval:in_list([\"Stop\", \"Warn\"], doc.action_if_accumulated_monthly_budget_exceeded_on_po || doc.action_if_accumulated_monthly_budget_exceeded_on_mr || doc.action_if_accumulated_monthly_budget_exceeded_on_actual)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "monthly_distribution",
|
"fieldname": "monthly_distribution",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -251,6 +259,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -283,6 +292,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "section_break_6",
|
"fieldname": "section_break_6",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -315,6 +325,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "applicable_on_material_request",
|
"fieldname": "applicable_on_material_request",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -343,12 +354,13 @@
|
|||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "Stop",
|
"default": "Stop",
|
||||||
"depends_on": "eval:doc.applicable_on_material_request == 1",
|
"depends_on": "eval:doc.applicable_on_material_request == 1",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "action_if_annual_budget_exceeded_on_mr",
|
"fieldname": "action_if_annual_budget_exceeded_on_mr",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -378,12 +390,13 @@
|
|||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "Warn",
|
"default": "Warn",
|
||||||
"depends_on": "eval:doc.applicable_on_material_request == 1",
|
"depends_on": "eval:doc.applicable_on_material_request == 1",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "action_if_accumulated_monthly_budget_exceeded_on_mr",
|
"fieldname": "action_if_accumulated_monthly_budget_exceeded_on_mr",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -417,6 +430,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_13",
|
"fieldname": "column_break_13",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -448,6 +462,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "applicable_on_purchase_order",
|
"fieldname": "applicable_on_purchase_order",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -476,12 +491,13 @@
|
|||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "Stop",
|
"default": "Stop",
|
||||||
"depends_on": "eval:doc.applicable_on_purchase_order == 1",
|
"depends_on": "eval:doc.applicable_on_purchase_order == 1",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "action_if_annual_budget_exceeded_on_po",
|
"fieldname": "action_if_annual_budget_exceeded_on_po",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -511,12 +527,13 @@
|
|||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "Warn",
|
"default": "Warn",
|
||||||
"depends_on": "eval:doc.applicable_on_purchase_order == 1",
|
"depends_on": "eval:doc.applicable_on_purchase_order == 1",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "action_if_accumulated_monthly_budget_exceeded_on_po",
|
"fieldname": "action_if_accumulated_monthly_budget_exceeded_on_po",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -550,6 +567,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "section_break_16",
|
"fieldname": "section_break_16",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -581,6 +599,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "applicable_on_booking_actual_expenses",
|
"fieldname": "applicable_on_booking_actual_expenses",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -609,12 +628,13 @@
|
|||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "Stop",
|
"default": "Stop",
|
||||||
"depends_on": "eval:doc.applicable_on_booking_actual_expenses == 1",
|
"depends_on": "eval:doc.applicable_on_booking_actual_expenses == 1",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "action_if_annual_budget_exceeded",
|
"fieldname": "action_if_annual_budget_exceeded",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -644,12 +664,13 @@
|
|||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "Warn",
|
"default": "Warn",
|
||||||
"depends_on": "eval:doc.applicable_on_booking_actual_expenses == 1",
|
"depends_on": "eval:doc.applicable_on_booking_actual_expenses == 1",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "action_if_accumulated_monthly_budget_exceeded",
|
"fieldname": "action_if_accumulated_monthly_budget_exceeded",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -683,6 +704,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "section_break_21",
|
"fieldname": "section_break_21",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -715,6 +737,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "accounts",
|
"fieldname": "accounts",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -752,7 +775,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-09-12 11:02:41.825923",
|
"modified": "2019-03-22 12:06:02.323099",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Budget",
|
"name": "Budget",
|
||||||
|
|||||||
@@ -1,426 +1,434 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
"allow_events_in_timeline": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_import": 0,
|
||||||
"allow_import": 0,
|
"allow_rename": 0,
|
||||||
"allow_rename": 0,
|
"autoname": "naming_series:",
|
||||||
"autoname": "naming_series:",
|
"beta": 0,
|
||||||
"beta": 0,
|
"creation": "2018-06-18 16:51:49.994750",
|
||||||
"creation": "2018-06-18 16:51:49.994750",
|
"custom": 0,
|
||||||
"custom": 0,
|
"docstatus": 0,
|
||||||
"docstatus": 0,
|
"doctype": "DocType",
|
||||||
"doctype": "DocType",
|
"document_type": "",
|
||||||
"document_type": "",
|
"editable_grid": 1,
|
||||||
"editable_grid": 1,
|
"engine": "InnoDB",
|
||||||
"engine": "InnoDB",
|
"fields": [
|
||||||
"fields": [
|
{
|
||||||
{
|
"allow_bulk_edit": 0,
|
||||||
"allow_bulk_edit": 0,
|
"allow_on_submit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"bold": 0,
|
||||||
"allow_on_submit": 0,
|
"collapsible": 0,
|
||||||
"bold": 0,
|
"columns": 0,
|
||||||
"collapsible": 0,
|
"default": "POS-CLO-",
|
||||||
"columns": 0,
|
"fieldname": "naming_series",
|
||||||
"default": "Cashier-closing-",
|
"fieldtype": "Select",
|
||||||
"fieldname": "naming_series",
|
"hidden": 0,
|
||||||
"fieldtype": "Select",
|
"ignore_user_permissions": 0,
|
||||||
"hidden": 0,
|
"ignore_xss_filter": 0,
|
||||||
"ignore_user_permissions": 0,
|
"in_filter": 1,
|
||||||
"ignore_xss_filter": 0,
|
"in_global_search": 1,
|
||||||
"in_filter": 1,
|
"in_list_view": 0,
|
||||||
"in_global_search": 1,
|
"in_standard_filter": 1,
|
||||||
"in_list_view": 0,
|
"label": "Series",
|
||||||
"in_standard_filter": 1,
|
"length": 0,
|
||||||
"label": "Series",
|
"no_copy": 0,
|
||||||
"length": 0,
|
"options": "POS-CLO-",
|
||||||
"no_copy": 0,
|
"permlevel": 0,
|
||||||
"options": "Cashier-closing-",
|
"precision": "",
|
||||||
"permlevel": 0,
|
"print_hide": 0,
|
||||||
"precision": "",
|
"print_hide_if_no_value": 0,
|
||||||
"print_hide": 0,
|
"read_only": 1,
|
||||||
"print_hide_if_no_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"read_only": 1,
|
"report_hide": 0,
|
||||||
"remember_last_selected_value": 0,
|
"reqd": 0,
|
||||||
"report_hide": 0,
|
"search_index": 0,
|
||||||
"reqd": 0,
|
"set_only_once": 0,
|
||||||
"search_index": 0,
|
"unique": 0
|
||||||
"set_only_once": 0,
|
},
|
||||||
"translatable": 0,
|
{
|
||||||
"unique": 0
|
"allow_bulk_edit": 0,
|
||||||
},
|
"allow_on_submit": 0,
|
||||||
{
|
"bold": 0,
|
||||||
"allow_bulk_edit": 0,
|
"collapsible": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"columns": 0,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "user",
|
||||||
"bold": 0,
|
"fieldtype": "Link",
|
||||||
"collapsible": 0,
|
"hidden": 0,
|
||||||
"columns": 0,
|
"ignore_user_permissions": 0,
|
||||||
"fieldname": "user",
|
"ignore_xss_filter": 0,
|
||||||
"fieldtype": "Link",
|
"in_filter": 1,
|
||||||
"hidden": 0,
|
"in_global_search": 0,
|
||||||
"ignore_user_permissions": 0,
|
"in_list_view": 1,
|
||||||
"ignore_xss_filter": 0,
|
"in_standard_filter": 1,
|
||||||
"in_filter": 1,
|
"label": "User",
|
||||||
"in_global_search": 0,
|
"length": 0,
|
||||||
"in_list_view": 1,
|
"no_copy": 0,
|
||||||
"in_standard_filter": 1,
|
"options": "User",
|
||||||
"label": "User",
|
"permlevel": 0,
|
||||||
"length": 0,
|
"precision": "",
|
||||||
"no_copy": 0,
|
"print_hide": 0,
|
||||||
"options": "User",
|
"print_hide_if_no_value": 0,
|
||||||
"permlevel": 0,
|
"read_only": 1,
|
||||||
"precision": "",
|
"remember_last_selected_value": 0,
|
||||||
"print_hide": 0,
|
"report_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"reqd": 1,
|
||||||
"read_only": 1,
|
"search_index": 0,
|
||||||
"remember_last_selected_value": 0,
|
"set_only_once": 0,
|
||||||
"report_hide": 0,
|
"unique": 0
|
||||||
"reqd": 1,
|
},
|
||||||
"search_index": 0,
|
{
|
||||||
"set_only_once": 0,
|
"allow_bulk_edit": 0,
|
||||||
"translatable": 0,
|
"allow_on_submit": 0,
|
||||||
"unique": 0
|
"bold": 0,
|
||||||
},
|
"collapsible": 0,
|
||||||
{
|
"columns": 0,
|
||||||
"allow_bulk_edit": 0,
|
"default": "Today",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "date",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Date",
|
||||||
"bold": 0,
|
"hidden": 0,
|
||||||
"collapsible": 0,
|
"ignore_user_permissions": 0,
|
||||||
"columns": 0,
|
"ignore_xss_filter": 0,
|
||||||
"default": "Today",
|
"in_filter": 1,
|
||||||
"fieldname": "date",
|
"in_global_search": 0,
|
||||||
"fieldtype": "Date",
|
"in_list_view": 0,
|
||||||
"hidden": 0,
|
"in_standard_filter": 1,
|
||||||
"ignore_user_permissions": 0,
|
"label": "Date",
|
||||||
"ignore_xss_filter": 0,
|
"length": 0,
|
||||||
"in_filter": 1,
|
"no_copy": 0,
|
||||||
"in_global_search": 0,
|
"permlevel": 0,
|
||||||
"in_list_view": 0,
|
"precision": "",
|
||||||
"in_standard_filter": 1,
|
"print_hide": 0,
|
||||||
"label": "Date",
|
"print_hide_if_no_value": 0,
|
||||||
"length": 0,
|
"read_only": 1,
|
||||||
"no_copy": 0,
|
"remember_last_selected_value": 0,
|
||||||
"permlevel": 0,
|
"report_hide": 0,
|
||||||
"precision": "",
|
"reqd": 0,
|
||||||
"print_hide": 0,
|
"search_index": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"set_only_once": 0,
|
||||||
"read_only": 1,
|
"unique": 0
|
||||||
"remember_last_selected_value": 0,
|
},
|
||||||
"report_hide": 0,
|
{
|
||||||
"reqd": 0,
|
"allow_bulk_edit": 0,
|
||||||
"search_index": 0,
|
"allow_on_submit": 0,
|
||||||
"set_only_once": 0,
|
"bold": 0,
|
||||||
"translatable": 0,
|
"collapsible": 0,
|
||||||
"unique": 0
|
"columns": 0,
|
||||||
},
|
"fieldname": "from_time",
|
||||||
{
|
"fieldtype": "Time",
|
||||||
"allow_bulk_edit": 0,
|
"hidden": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"ignore_user_permissions": 0,
|
||||||
"allow_on_submit": 0,
|
"ignore_xss_filter": 0,
|
||||||
"bold": 0,
|
"in_filter": 1,
|
||||||
"collapsible": 0,
|
"in_global_search": 0,
|
||||||
"columns": 0,
|
"in_list_view": 0,
|
||||||
"fieldname": "from_time",
|
"in_standard_filter": 1,
|
||||||
"fieldtype": "Time",
|
"label": "From Time",
|
||||||
"hidden": 0,
|
"length": 0,
|
||||||
"ignore_user_permissions": 0,
|
"no_copy": 0,
|
||||||
"ignore_xss_filter": 0,
|
"permlevel": 0,
|
||||||
"in_filter": 1,
|
"precision": "",
|
||||||
"in_global_search": 0,
|
"print_hide": 0,
|
||||||
"in_list_view": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"in_standard_filter": 1,
|
"read_only": 0,
|
||||||
"label": "From Time",
|
"remember_last_selected_value": 0,
|
||||||
"length": 0,
|
"report_hide": 0,
|
||||||
"no_copy": 0,
|
"reqd": 1,
|
||||||
"permlevel": 0,
|
"search_index": 0,
|
||||||
"precision": "",
|
"set_only_once": 0,
|
||||||
"print_hide": 0,
|
"unique": 0
|
||||||
"print_hide_if_no_value": 0,
|
},
|
||||||
"read_only": 0,
|
{
|
||||||
"remember_last_selected_value": 0,
|
"allow_bulk_edit": 0,
|
||||||
"report_hide": 0,
|
"allow_on_submit": 0,
|
||||||
"reqd": 1,
|
"bold": 0,
|
||||||
"search_index": 0,
|
"collapsible": 0,
|
||||||
"set_only_once": 0,
|
"columns": 0,
|
||||||
"translatable": 0,
|
"default": "",
|
||||||
"unique": 0
|
"fieldname": "time",
|
||||||
},
|
"fieldtype": "Time",
|
||||||
{
|
"hidden": 0,
|
||||||
"allow_bulk_edit": 0,
|
"ignore_user_permissions": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"ignore_xss_filter": 0,
|
||||||
"allow_on_submit": 0,
|
"in_filter": 1,
|
||||||
"bold": 0,
|
"in_global_search": 0,
|
||||||
"collapsible": 0,
|
"in_list_view": 0,
|
||||||
"columns": 0,
|
"in_standard_filter": 1,
|
||||||
"default": "",
|
"label": "To Time",
|
||||||
"fieldname": "time",
|
"length": 0,
|
||||||
"fieldtype": "Time",
|
"no_copy": 0,
|
||||||
"hidden": 0,
|
"permlevel": 0,
|
||||||
"ignore_user_permissions": 0,
|
"precision": "",
|
||||||
"ignore_xss_filter": 0,
|
"print_hide": 0,
|
||||||
"in_filter": 1,
|
"print_hide_if_no_value": 0,
|
||||||
"in_global_search": 0,
|
"read_only": 0,
|
||||||
"in_list_view": 0,
|
"remember_last_selected_value": 0,
|
||||||
"in_standard_filter": 1,
|
"report_hide": 0,
|
||||||
"label": "To Time",
|
"reqd": 1,
|
||||||
"length": 0,
|
"search_index": 0,
|
||||||
"no_copy": 0,
|
"set_only_once": 0,
|
||||||
"permlevel": 0,
|
"unique": 0
|
||||||
"precision": "",
|
},
|
||||||
"print_hide": 0,
|
{
|
||||||
"print_hide_if_no_value": 0,
|
"allow_bulk_edit": 0,
|
||||||
"read_only": 0,
|
"allow_on_submit": 0,
|
||||||
"remember_last_selected_value": 0,
|
"bold": 0,
|
||||||
"report_hide": 0,
|
"collapsible": 0,
|
||||||
"reqd": 1,
|
"columns": 0,
|
||||||
"search_index": 0,
|
"default": "0.00",
|
||||||
"set_only_once": 0,
|
"fieldname": "expense",
|
||||||
"translatable": 0,
|
"fieldtype": "Float",
|
||||||
"unique": 0
|
"hidden": 0,
|
||||||
},
|
"ignore_user_permissions": 0,
|
||||||
{
|
"ignore_xss_filter": 0,
|
||||||
"allow_bulk_edit": 0,
|
"in_filter": 1,
|
||||||
"allow_in_quick_entry": 0,
|
"in_global_search": 0,
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 0,
|
||||||
"bold": 0,
|
"in_standard_filter": 0,
|
||||||
"collapsible": 0,
|
"label": "Expense",
|
||||||
"columns": 0,
|
"length": 0,
|
||||||
"default": "0.00",
|
"no_copy": 0,
|
||||||
"fieldname": "expense",
|
"permlevel": 0,
|
||||||
"fieldtype": "Float",
|
"precision": "2",
|
||||||
"hidden": 0,
|
"print_hide": 0,
|
||||||
"ignore_user_permissions": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"ignore_xss_filter": 0,
|
"read_only": 0,
|
||||||
"in_filter": 1,
|
"remember_last_selected_value": 0,
|
||||||
"in_global_search": 0,
|
"report_hide": 0,
|
||||||
"in_list_view": 0,
|
"reqd": 0,
|
||||||
"in_standard_filter": 0,
|
"search_index": 0,
|
||||||
"label": "Expense",
|
"set_only_once": 0,
|
||||||
"length": 0,
|
"unique": 0
|
||||||
"no_copy": 0,
|
},
|
||||||
"permlevel": 0,
|
{
|
||||||
"precision": "",
|
"allow_bulk_edit": 0,
|
||||||
"print_hide": 0,
|
"allow_on_submit": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"bold": 0,
|
||||||
"read_only": 0,
|
"collapsible": 0,
|
||||||
"remember_last_selected_value": 0,
|
"columns": 0,
|
||||||
"report_hide": 0,
|
"default": "0.00",
|
||||||
"reqd": 0,
|
"fieldname": "custody",
|
||||||
"search_index": 0,
|
"fieldtype": "Float",
|
||||||
"set_only_once": 0,
|
"hidden": 0,
|
||||||
"translatable": 0,
|
"ignore_user_permissions": 0,
|
||||||
"unique": 0
|
"ignore_xss_filter": 0,
|
||||||
},
|
"in_filter": 1,
|
||||||
{
|
"in_global_search": 0,
|
||||||
"allow_bulk_edit": 0,
|
"in_list_view": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"in_standard_filter": 0,
|
||||||
"allow_on_submit": 0,
|
"label": "Custody",
|
||||||
"bold": 0,
|
"length": 0,
|
||||||
"collapsible": 0,
|
"no_copy": 0,
|
||||||
"columns": 0,
|
"permlevel": 0,
|
||||||
"default": "0.00",
|
"precision": "2",
|
||||||
"fieldname": "custody",
|
"print_hide": 0,
|
||||||
"fieldtype": "Float",
|
"print_hide_if_no_value": 0,
|
||||||
"hidden": 0,
|
"read_only": 0,
|
||||||
"ignore_user_permissions": 0,
|
"remember_last_selected_value": 0,
|
||||||
"ignore_xss_filter": 0,
|
"report_hide": 0,
|
||||||
"in_filter": 1,
|
"reqd": 0,
|
||||||
"in_global_search": 0,
|
"search_index": 0,
|
||||||
"in_list_view": 0,
|
"set_only_once": 0,
|
||||||
"in_standard_filter": 0,
|
"unique": 0
|
||||||
"label": "Custody",
|
},
|
||||||
"length": 0,
|
{
|
||||||
"no_copy": 0,
|
"allow_bulk_edit": 0,
|
||||||
"permlevel": 0,
|
"allow_on_submit": 0,
|
||||||
"precision": "",
|
"bold": 0,
|
||||||
"print_hide": 0,
|
"collapsible": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"columns": 0,
|
||||||
"read_only": 0,
|
"default": "0.00",
|
||||||
"remember_last_selected_value": 0,
|
"fieldname": "returns",
|
||||||
"report_hide": 0,
|
"fieldtype": "Float",
|
||||||
"reqd": 0,
|
"hidden": 0,
|
||||||
"search_index": 0,
|
"ignore_user_permissions": 0,
|
||||||
"set_only_once": 0,
|
"ignore_xss_filter": 0,
|
||||||
"translatable": 0,
|
"in_filter": 1,
|
||||||
"unique": 0
|
"in_global_search": 0,
|
||||||
},
|
"in_list_view": 0,
|
||||||
{
|
"in_standard_filter": 0,
|
||||||
"allow_bulk_edit": 0,
|
"label": "Returns",
|
||||||
"allow_in_quick_entry": 0,
|
"length": 0,
|
||||||
"allow_on_submit": 0,
|
"no_copy": 0,
|
||||||
"bold": 0,
|
"permlevel": 0,
|
||||||
"collapsible": 0,
|
"precision": "2",
|
||||||
"columns": 0,
|
"print_hide": 0,
|
||||||
"default": "0.00",
|
"print_hide_if_no_value": 0,
|
||||||
"fieldname": "outstanding_amount",
|
"read_only": 0,
|
||||||
"fieldtype": "Float",
|
"remember_last_selected_value": 0,
|
||||||
"hidden": 0,
|
"report_hide": 0,
|
||||||
"ignore_user_permissions": 0,
|
"reqd": 0,
|
||||||
"ignore_xss_filter": 0,
|
"search_index": 0,
|
||||||
"in_filter": 0,
|
"set_only_once": 0,
|
||||||
"in_global_search": 0,
|
"unique": 0
|
||||||
"in_list_view": 0,
|
},
|
||||||
"in_standard_filter": 0,
|
{
|
||||||
"label": "Outstanding Amount",
|
"allow_bulk_edit": 0,
|
||||||
"length": 0,
|
"allow_on_submit": 0,
|
||||||
"no_copy": 0,
|
"bold": 0,
|
||||||
"permlevel": 0,
|
"collapsible": 0,
|
||||||
"precision": "",
|
"columns": 0,
|
||||||
"print_hide": 0,
|
"default": "0.00",
|
||||||
"print_hide_if_no_value": 0,
|
"fieldname": "outstanding_amount",
|
||||||
"read_only": 1,
|
"fieldtype": "Float",
|
||||||
"remember_last_selected_value": 0,
|
"hidden": 0,
|
||||||
"report_hide": 0,
|
"ignore_user_permissions": 0,
|
||||||
"reqd": 0,
|
"ignore_xss_filter": 0,
|
||||||
"search_index": 0,
|
"in_filter": 0,
|
||||||
"set_only_once": 0,
|
"in_global_search": 0,
|
||||||
"translatable": 0,
|
"in_list_view": 0,
|
||||||
"unique": 0
|
"in_standard_filter": 0,
|
||||||
},
|
"label": "Outstanding Amount",
|
||||||
{
|
"length": 0,
|
||||||
"allow_bulk_edit": 0,
|
"no_copy": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"permlevel": 0,
|
||||||
"allow_on_submit": 0,
|
"precision": "2",
|
||||||
"bold": 0,
|
"print_hide": 0,
|
||||||
"collapsible": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"columns": 0,
|
"read_only": 1,
|
||||||
"default": "0.0",
|
"remember_last_selected_value": 0,
|
||||||
"fieldname": "payments",
|
"report_hide": 0,
|
||||||
"fieldtype": "Table",
|
"reqd": 0,
|
||||||
"hidden": 0,
|
"search_index": 0,
|
||||||
"ignore_user_permissions": 0,
|
"set_only_once": 0,
|
||||||
"ignore_xss_filter": 0,
|
"unique": 0
|
||||||
"in_filter": 1,
|
},
|
||||||
"in_global_search": 0,
|
{
|
||||||
"in_list_view": 0,
|
"allow_bulk_edit": 0,
|
||||||
"in_standard_filter": 0,
|
"allow_on_submit": 0,
|
||||||
"label": "Payments",
|
"bold": 0,
|
||||||
"length": 0,
|
"collapsible": 0,
|
||||||
"no_copy": 0,
|
"columns": 0,
|
||||||
"options": "Cashier Closing Payments",
|
"default": "0.0",
|
||||||
"permlevel": 0,
|
"fieldname": "payments",
|
||||||
"precision": "",
|
"fieldtype": "Table",
|
||||||
"print_hide": 0,
|
"hidden": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"ignore_user_permissions": 0,
|
||||||
"read_only": 0,
|
"ignore_xss_filter": 0,
|
||||||
"remember_last_selected_value": 0,
|
"in_filter": 1,
|
||||||
"report_hide": 0,
|
"in_global_search": 0,
|
||||||
"reqd": 0,
|
"in_list_view": 0,
|
||||||
"search_index": 0,
|
"in_standard_filter": 0,
|
||||||
"set_only_once": 0,
|
"label": "Payments",
|
||||||
"translatable": 0,
|
"length": 0,
|
||||||
"unique": 0
|
"no_copy": 0,
|
||||||
},
|
"options": "Cashier Closing Payments",
|
||||||
{
|
"permlevel": 0,
|
||||||
"allow_bulk_edit": 0,
|
"precision": "",
|
||||||
"allow_in_quick_entry": 0,
|
"print_hide": 0,
|
||||||
"allow_on_submit": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"bold": 0,
|
"read_only": 0,
|
||||||
"collapsible": 0,
|
"remember_last_selected_value": 0,
|
||||||
"columns": 0,
|
"report_hide": 0,
|
||||||
"fieldname": "net_amount",
|
"reqd": 0,
|
||||||
"fieldtype": "Float",
|
"search_index": 0,
|
||||||
"hidden": 0,
|
"set_only_once": 0,
|
||||||
"ignore_user_permissions": 0,
|
"unique": 0
|
||||||
"ignore_xss_filter": 0,
|
},
|
||||||
"in_filter": 1,
|
{
|
||||||
"in_global_search": 0,
|
"allow_bulk_edit": 0,
|
||||||
"in_list_view": 1,
|
"allow_on_submit": 0,
|
||||||
"in_standard_filter": 1,
|
"bold": 0,
|
||||||
"label": "Net Amount",
|
"collapsible": 0,
|
||||||
"length": 0,
|
"columns": 0,
|
||||||
"no_copy": 0,
|
"fieldname": "net_amount",
|
||||||
"permlevel": 0,
|
"fieldtype": "Float",
|
||||||
"precision": "",
|
"hidden": 0,
|
||||||
"print_hide": 0,
|
"ignore_user_permissions": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"ignore_xss_filter": 0,
|
||||||
"read_only": 1,
|
"in_filter": 1,
|
||||||
"remember_last_selected_value": 0,
|
"in_global_search": 0,
|
||||||
"report_hide": 0,
|
"in_list_view": 1,
|
||||||
"reqd": 0,
|
"in_standard_filter": 1,
|
||||||
"search_index": 0,
|
"label": "Net Amount",
|
||||||
"set_only_once": 0,
|
"length": 0,
|
||||||
"translatable": 0,
|
"no_copy": 0,
|
||||||
"unique": 0
|
"permlevel": 0,
|
||||||
},
|
"precision": "",
|
||||||
{
|
"print_hide": 0,
|
||||||
"allow_bulk_edit": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"read_only": 1,
|
||||||
"allow_on_submit": 0,
|
"remember_last_selected_value": 0,
|
||||||
"bold": 0,
|
"report_hide": 0,
|
||||||
"collapsible": 0,
|
"reqd": 0,
|
||||||
"columns": 0,
|
"search_index": 0,
|
||||||
"fieldname": "amended_from",
|
"set_only_once": 0,
|
||||||
"fieldtype": "Link",
|
"unique": 0
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
{
|
||||||
"ignore_xss_filter": 0,
|
"allow_bulk_edit": 0,
|
||||||
"in_filter": 0,
|
"allow_on_submit": 0,
|
||||||
"in_global_search": 0,
|
"bold": 0,
|
||||||
"in_list_view": 0,
|
"collapsible": 0,
|
||||||
"in_standard_filter": 0,
|
"columns": 0,
|
||||||
"label": "Amended From",
|
"fieldname": "amended_from",
|
||||||
"length": 0,
|
"fieldtype": "Link",
|
||||||
"no_copy": 1,
|
"hidden": 0,
|
||||||
"options": "Cashier Closing",
|
"ignore_user_permissions": 0,
|
||||||
"permlevel": 0,
|
"ignore_xss_filter": 0,
|
||||||
"print_hide": 1,
|
"in_filter": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"in_global_search": 0,
|
||||||
"read_only": 1,
|
"in_list_view": 0,
|
||||||
"remember_last_selected_value": 0,
|
"in_standard_filter": 0,
|
||||||
"report_hide": 0,
|
"label": "Amended From",
|
||||||
"reqd": 0,
|
"length": 0,
|
||||||
"search_index": 0,
|
"no_copy": 1,
|
||||||
"set_only_once": 0,
|
"options": "Cashier Closing",
|
||||||
"translatable": 0,
|
"permlevel": 0,
|
||||||
"unique": 0
|
"print_hide": 1,
|
||||||
}
|
"print_hide_if_no_value": 0,
|
||||||
],
|
"read_only": 1,
|
||||||
"has_web_view": 0,
|
"remember_last_selected_value": 0,
|
||||||
"hide_heading": 0,
|
"report_hide": 0,
|
||||||
"hide_toolbar": 0,
|
"reqd": 0,
|
||||||
"idx": 0,
|
"search_index": 0,
|
||||||
"image_view": 0,
|
"set_only_once": 0,
|
||||||
"in_create": 0,
|
"unique": 0
|
||||||
"is_submittable": 1,
|
}
|
||||||
"issingle": 0,
|
],
|
||||||
"istable": 0,
|
"has_web_view": 0,
|
||||||
"max_attachments": 0,
|
"hide_heading": 0,
|
||||||
"modified": "2019-02-19 08:35:23.157327",
|
"hide_toolbar": 0,
|
||||||
"modified_by": "Administrator",
|
"idx": 0,
|
||||||
"module": "Accounts",
|
"image_view": 0,
|
||||||
"name": "Cashier Closing",
|
"in_create": 0,
|
||||||
"name_case": "",
|
"is_submittable": 1,
|
||||||
"owner": "Administrator",
|
"issingle": 0,
|
||||||
"permissions": [
|
"istable": 0,
|
||||||
{
|
"max_attachments": 0,
|
||||||
"amend": 0,
|
"modified": "2019-03-14 09:14:26.727129",
|
||||||
"cancel": 0,
|
"modified_by": "Administrator",
|
||||||
"create": 1,
|
"module": "Accounts",
|
||||||
"delete": 1,
|
"name": "Cashier Closing",
|
||||||
"email": 1,
|
"name_case": "",
|
||||||
"export": 1,
|
"owner": "Administrator",
|
||||||
"if_owner": 0,
|
"permissions": [
|
||||||
"import": 0,
|
{
|
||||||
"permlevel": 0,
|
"amend": 0,
|
||||||
"print": 1,
|
"apply_user_permissions": 0,
|
||||||
"read": 1,
|
"cancel": 0,
|
||||||
"report": 1,
|
"create": 1,
|
||||||
"role": "System Manager",
|
"delete": 1,
|
||||||
"set_user_permissions": 0,
|
"email": 1,
|
||||||
"share": 1,
|
"export": 1,
|
||||||
"submit": 1,
|
"if_owner": 0,
|
||||||
"write": 1
|
"import": 0,
|
||||||
}
|
"permlevel": 0,
|
||||||
],
|
"print": 1,
|
||||||
"quick_entry": 0,
|
"read": 1,
|
||||||
"read_only": 0,
|
"report": 1,
|
||||||
"read_only_onload": 0,
|
"role": "System Manager",
|
||||||
"show_name_in_global_search": 0,
|
"set_user_permissions": 0,
|
||||||
"sort_field": "modified",
|
"share": 1,
|
||||||
"sort_order": "DESC",
|
"submit": 1,
|
||||||
"track_changes": 1,
|
"write": 1
|
||||||
"track_seen": 0,
|
}
|
||||||
"track_views": 0
|
],
|
||||||
}
|
"quick_entry": 0,
|
||||||
|
"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
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ class CashierClosing(Document):
|
|||||||
for i in self.payments:
|
for i in self.payments:
|
||||||
total += flt(i.amount)
|
total += flt(i.amount)
|
||||||
|
|
||||||
self.net_amount = total + self.outstanding_amount + self.expense - self.custody
|
self.net_amount = total + self.outstanding_amount + self.expense - self.custody + self.returns
|
||||||
|
|
||||||
def validate_time(self):
|
def validate_time(self):
|
||||||
if self.from_time >= self.time:
|
if self.from_time >= self.time:
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import frappe, erpnext
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt, fmt_money, getdate, formatdate
|
from frappe.utils import flt, fmt_money, getdate, formatdate
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe.model.meta import get_field_precision
|
||||||
from erpnext.accounts.party import validate_party_gle_currency, validate_party_frozen_disabled
|
from erpnext.accounts.party import validate_party_gle_currency, validate_party_frozen_disabled
|
||||||
from erpnext.accounts.utils import get_account_currency
|
from erpnext.accounts.utils import get_account_currency
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
@@ -56,7 +57,7 @@ class GLEntry(Document):
|
|||||||
.format(self.voucher_type, self.voucher_no, self.account))
|
.format(self.voucher_type, self.voucher_no, self.account))
|
||||||
|
|
||||||
# Zero value transaction is not allowed
|
# Zero value transaction is not allowed
|
||||||
if not (flt(self.debit) or flt(self.credit)):
|
if not (flt(self.debit, self.precision("debit")) or flt(self.credit, self.precision("credit"))):
|
||||||
frappe.throw(_("{0} {1}: Either debit or credit amount is required for {2}")
|
frappe.throw(_("{0} {1}: Either debit or credit amount is required for {2}")
|
||||||
.format(self.voucher_type, self.voucher_no, self.account))
|
.format(self.voucher_type, self.voucher_no, self.account))
|
||||||
|
|
||||||
@@ -74,7 +75,8 @@ class GLEntry(Document):
|
|||||||
|
|
||||||
def check_pl_account(self):
|
def check_pl_account(self):
|
||||||
if self.is_opening=='Yes' and \
|
if self.is_opening=='Yes' and \
|
||||||
frappe.db.get_value("Account", self.account, "report_type")=="Profit and Loss":
|
frappe.db.get_value("Account", self.account, "report_type")=="Profit and Loss" and \
|
||||||
|
self.voucher_type not in ['Purchase Invoice', 'Sales Invoice']:
|
||||||
frappe.throw(_("{0} {1}: 'Profit and Loss' type account {2} not allowed in Opening Entry")
|
frappe.throw(_("{0} {1}: 'Profit and Loss' type account {2} not allowed in Opening Entry")
|
||||||
.format(self.voucher_type, self.voucher_no, self.account))
|
.format(self.voucher_type, self.voucher_no, self.account))
|
||||||
|
|
||||||
@@ -215,17 +217,23 @@ def validate_frozen_account(account, adv_adj=None):
|
|||||||
def update_against_account(voucher_type, voucher_no):
|
def update_against_account(voucher_type, voucher_no):
|
||||||
entries = frappe.db.get_all("GL Entry",
|
entries = frappe.db.get_all("GL Entry",
|
||||||
filters={"voucher_type": voucher_type, "voucher_no": voucher_no},
|
filters={"voucher_type": voucher_type, "voucher_no": voucher_no},
|
||||||
fields=["name", "party", "against", "debit", "credit", "account"])
|
fields=["name", "party", "against", "debit", "credit", "account", "company"])
|
||||||
|
|
||||||
|
if not entries:
|
||||||
|
return
|
||||||
|
company_currency = erpnext.get_company_currency(entries[0].company)
|
||||||
|
precision = get_field_precision(frappe.get_meta("GL Entry")
|
||||||
|
.get_field("debit"), company_currency)
|
||||||
|
|
||||||
accounts_debited, accounts_credited = [], []
|
accounts_debited, accounts_credited = [], []
|
||||||
for d in entries:
|
for d in entries:
|
||||||
if flt(d.debit > 0): accounts_debited.append(d.party or d.account)
|
if flt(d.debit, precision) > 0: accounts_debited.append(d.party or d.account)
|
||||||
if flt(d.credit) > 0: accounts_credited.append(d.party or d.account)
|
if flt(d.credit, precision) > 0: accounts_credited.append(d.party or d.account)
|
||||||
|
|
||||||
for d in entries:
|
for d in entries:
|
||||||
if flt(d.debit > 0):
|
if flt(d.debit, precision) > 0:
|
||||||
new_against = ", ".join(list(set(accounts_credited)))
|
new_against = ", ".join(list(set(accounts_credited)))
|
||||||
if flt(d.credit > 0):
|
if flt(d.credit, precision) > 0:
|
||||||
new_against = ", ".join(list(set(accounts_debited)))
|
new_against = ", ".join(list(set(accounts_debited)))
|
||||||
|
|
||||||
if d.against != new_against:
|
if d.against != new_against:
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ class JournalEntry(AccountsController):
|
|||||||
self.update_loan()
|
self.update_loan()
|
||||||
self.update_inter_company_jv()
|
self.update_inter_company_jv()
|
||||||
|
|
||||||
|
|
||||||
def get_title(self):
|
def get_title(self):
|
||||||
return self.pay_to_recd_from or self.accounts[0].account
|
return self.pay_to_recd_from or self.accounts[0].account
|
||||||
|
|
||||||
|
|||||||
@@ -232,6 +232,13 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
party_type: function(frm) {
|
party_type: function(frm) {
|
||||||
|
|
||||||
|
let party_types = Object.keys(frappe.boot.party_account_types);
|
||||||
|
if(frm.doc.party_type && !party_types.includes(frm.doc.party_type)){
|
||||||
|
frm.set_value("party_type", "");
|
||||||
|
frappe.throw(__("Party can only be one of "+ party_types.join(", ")));
|
||||||
|
}
|
||||||
|
|
||||||
if(frm.doc.party) {
|
if(frm.doc.party) {
|
||||||
$.each(["party", "party_balance", "paid_from", "paid_to",
|
$.each(["party", "party_balance", "paid_from", "paid_to",
|
||||||
"paid_from_account_currency", "paid_from_account_balance",
|
"paid_from_account_currency", "paid_from_account_balance",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "type_of_payment",
|
"fieldname": "type_of_payment",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -53,6 +54,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "",
|
"default": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "naming_series",
|
"fieldname": "naming_series",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -86,6 +88,7 @@
|
|||||||
"bold": 1,
|
"bold": 1,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "payment_type",
|
"fieldname": "payment_type",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -119,6 +122,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_5",
|
"fieldname": "column_break_5",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -151,6 +155,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "Today",
|
"default": "Today",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "posting_date",
|
"fieldname": "posting_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -183,6 +188,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -216,6 +222,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "cost_center",
|
"fieldname": "cost_center",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -249,6 +256,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "mode_of_payment",
|
"fieldname": "mode_of_payment",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -283,6 +291,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)",
|
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "party_section",
|
"fieldname": "party_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -317,6 +326,7 @@
|
|||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "",
|
"default": "",
|
||||||
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.docstatus==0",
|
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.docstatus==0",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "party_type",
|
"fieldname": "party_type",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -351,6 +361,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.party_type",
|
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.party_type",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "party",
|
"fieldname": "party",
|
||||||
"fieldtype": "Dynamic Link",
|
"fieldtype": "Dynamic Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -386,6 +397,7 @@
|
|||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.party_type",
|
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.party_type",
|
||||||
"description": "",
|
"description": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "party_name",
|
"fieldname": "party_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -418,6 +430,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_11",
|
"fieldname": "column_break_11",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -450,6 +463,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "party",
|
"depends_on": "party",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "bank_account",
|
"fieldname": "bank_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -476,40 +490,6 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "contact_person",
|
|
||||||
"fieldname": "contact_email",
|
|
||||||
"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": "Email",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Email",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
@@ -518,6 +498,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "party",
|
"depends_on": "party",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "contact_person",
|
"fieldname": "contact_person",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -544,6 +525,41 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"depends_on": "contact_person",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "contact_email",
|
||||||
|
"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": "Email",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Email",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
@@ -551,6 +567,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "payment_accounts_section",
|
"fieldname": "payment_accounts_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -584,6 +601,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "party",
|
"depends_on": "party",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "party_balance",
|
"fieldname": "party_balance",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -617,6 +635,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:(in_list([\"Internal Transfer\", \"Pay\"], doc.payment_type) || doc.party)",
|
"depends_on": "eval:(in_list([\"Internal Transfer\", \"Pay\"], doc.payment_type) || doc.party)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "paid_from",
|
"fieldname": "paid_from",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -651,6 +670,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "paid_from",
|
"depends_on": "paid_from",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "paid_from_account_currency",
|
"fieldname": "paid_from_account_currency",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -685,6 +705,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "paid_from",
|
"depends_on": "paid_from",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "paid_from_account_balance",
|
"fieldname": "paid_from_account_balance",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -718,6 +739,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_18",
|
"fieldname": "column_break_18",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -750,6 +772,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:(in_list([\"Internal Transfer\", \"Receive\"], doc.payment_type) || doc.party)",
|
"depends_on": "eval:(in_list([\"Internal Transfer\", \"Receive\"], doc.payment_type) || doc.party)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "paid_to",
|
"fieldname": "paid_to",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -784,6 +807,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "paid_to",
|
"depends_on": "paid_to",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "paid_to_account_currency",
|
"fieldname": "paid_to_account_currency",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -818,6 +842,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "paid_to",
|
"depends_on": "paid_to",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "paid_to_account_balance",
|
"fieldname": "paid_to_account_balance",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -853,6 +878,7 @@
|
|||||||
"collapsible_depends_on": "",
|
"collapsible_depends_on": "",
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:(doc.paid_to && doc.paid_from)",
|
"depends_on": "eval:(doc.paid_to && doc.paid_from)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "payment_amounts_section",
|
"fieldname": "payment_amounts_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -886,6 +912,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "paid_amount",
|
"fieldname": "paid_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -920,6 +947,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "source_exchange_rate",
|
"fieldname": "source_exchange_rate",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -953,6 +981,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "base_paid_amount",
|
"fieldname": "base_paid_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -986,6 +1015,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_21",
|
"fieldname": "column_break_21",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1018,6 +1048,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "received_amount",
|
"fieldname": "received_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1052,6 +1083,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "target_exchange_rate",
|
"fieldname": "target_exchange_rate",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1085,6 +1117,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "base_received_amount",
|
"fieldname": "base_received_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1120,6 +1153,7 @@
|
|||||||
"collapsible_depends_on": "references",
|
"collapsible_depends_on": "references",
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:(doc.party && doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)",
|
"depends_on": "eval:(doc.party && doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "section_break_14",
|
"fieldname": "section_break_14",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1154,6 +1188,7 @@
|
|||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"depends_on": "eval:in_list(['Pay', 'Receive'], doc.payment_type)",
|
"depends_on": "eval:in_list(['Pay', 'Receive'], doc.payment_type)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "allocate_payment_amount",
|
"fieldname": "allocate_payment_amount",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1187,6 +1222,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "references",
|
"fieldname": "references",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1221,6 +1257,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "section_break_34",
|
"fieldname": "section_break_34",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1254,6 +1291,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:(doc.paid_amount && doc.received_amount && doc.references)",
|
"depends_on": "eval:(doc.paid_amount && doc.received_amount && doc.references)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "total_allocated_amount",
|
"fieldname": "total_allocated_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1287,6 +1325,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "base_total_allocated_amount",
|
"fieldname": "base_total_allocated_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1320,6 +1359,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "set_exchange_gain_loss",
|
"fieldname": "set_exchange_gain_loss",
|
||||||
"fieldtype": "Button",
|
"fieldtype": "Button",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1352,6 +1392,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_36",
|
"fieldname": "column_break_36",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1384,6 +1425,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:(doc.paid_amount && doc.received_amount && doc.references)",
|
"depends_on": "eval:(doc.paid_amount && doc.received_amount && doc.references)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "unallocated_amount",
|
"fieldname": "unallocated_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1417,6 +1459,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:(doc.paid_amount && doc.received_amount)",
|
"depends_on": "eval:(doc.paid_amount && doc.received_amount)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "difference_amount",
|
"fieldname": "difference_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1451,6 +1494,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "difference_amount",
|
"depends_on": "difference_amount",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "write_off_difference_amount",
|
"fieldname": "write_off_difference_amount",
|
||||||
"fieldtype": "Button",
|
"fieldtype": "Button",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1485,6 +1529,7 @@
|
|||||||
"collapsible_depends_on": "deductions",
|
"collapsible_depends_on": "deductions",
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:(doc.paid_amount && doc.received_amount)",
|
"depends_on": "eval:(doc.paid_amount && doc.received_amount)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "deductions_or_loss_section",
|
"fieldname": "deductions_or_loss_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1517,6 +1562,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "deductions",
|
"fieldname": "deductions",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1550,6 +1596,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "transaction_references",
|
"fieldname": "transaction_references",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1583,6 +1630,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:(doc.paid_from && doc.paid_to)",
|
"depends_on": "eval:(doc.paid_from && doc.paid_to)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "reference_no",
|
"fieldname": "reference_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1615,6 +1663,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_23",
|
"fieldname": "column_break_23",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1647,6 +1696,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:(doc.paid_from && doc.paid_to)",
|
"depends_on": "eval:(doc.paid_from && doc.paid_to)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "reference_date",
|
"fieldname": "reference_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1680,6 +1730,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:doc.docstatus==1",
|
"depends_on": "eval:doc.docstatus==1",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "clearance_date",
|
"fieldname": "clearance_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1714,6 +1765,7 @@
|
|||||||
"collapsible_depends_on": "",
|
"collapsible_depends_on": "",
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:(doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)",
|
"depends_on": "eval:(doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "section_break_12",
|
"fieldname": "section_break_12",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1747,6 +1799,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "project",
|
"fieldname": "project",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1780,6 +1833,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "remarks",
|
"fieldname": "remarks",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1812,6 +1866,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_16",
|
"fieldname": "column_break_16",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1843,6 +1898,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "letter_head",
|
"fieldname": "letter_head",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1876,6 +1932,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "print_heading",
|
"fieldname": "print_heading",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1910,6 +1967,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fetch_from": "bank_account.bank",
|
"fetch_from": "bank_account.bank",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "bank",
|
"fieldname": "bank",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1943,6 +2001,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fetch_from": "bank_account.bank_account_no",
|
"fetch_from": "bank_account.bank_account_no",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "bank_account_no",
|
"fieldname": "bank_account_no",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1975,6 +2034,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "payment_order",
|
"fieldname": "payment_order",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -2008,6 +2068,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "subscription_section",
|
"fieldname": "subscription_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -2040,6 +2101,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "auto_repeat",
|
"fieldname": "auto_repeat",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -2073,6 +2135,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -2105,6 +2168,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "title",
|
"fieldname": "title",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
@@ -2141,7 +2205,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2019-01-15 15:58:40.742601",
|
"modified": "2019-03-27 17:39:54.163016",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe, erpnext, json
|
import frappe, erpnext, json
|
||||||
from frappe import _, scrub, ValidationError
|
from frappe import _, scrub, ValidationError
|
||||||
from frappe.utils import flt, comma_or, nowdate, getdate
|
from frappe.utils import flt, comma_or, nowdate, getdate
|
||||||
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, get_allow_cost_center_in_entry_of_bs_account
|
||||||
from erpnext.accounts.party import get_party_account
|
from erpnext.accounts.party import get_party_account
|
||||||
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
|
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
|
||||||
from erpnext.setup.utils import get_exchange_rate
|
from erpnext.setup.utils import get_exchange_rate
|
||||||
@@ -70,6 +70,7 @@ class PaymentEntry(AccountsController):
|
|||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
self.update_expense_claim()
|
self.update_expense_claim()
|
||||||
|
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.setup_party_account_field()
|
self.setup_party_account_field()
|
||||||
self.make_gl_entries(cancel=1)
|
self.make_gl_entries(cancel=1)
|
||||||
@@ -564,8 +565,8 @@ def get_outstanding_reference_documents(args):
|
|||||||
.format(frappe.db.escape(args["voucher_type"]), frappe.db.escape(args["voucher_no"]))
|
.format(frappe.db.escape(args["voucher_type"]), frappe.db.escape(args["voucher_no"]))
|
||||||
|
|
||||||
# Add cost center condition
|
# Add cost center condition
|
||||||
if args.get("cost_center"):
|
if args.get("cost_center") and get_allow_cost_center_in_entry_of_bs_account():
|
||||||
condition += " and cost_center='%s'" % args.get("cost_center")
|
condition += " and cost_center='%s'" % args.get("cost_center")
|
||||||
|
|
||||||
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"), condition=condition)
|
args.get("party_account"), condition=condition)
|
||||||
@@ -748,7 +749,7 @@ def get_outstanding_on_journal_entry(name):
|
|||||||
|
|
||||||
@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 = bill_no = 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)
|
company_currency = ref_doc.get("company_currency") or erpnext.get_company_currency(ref_doc.company)
|
||||||
|
|
||||||
@@ -782,6 +783,7 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
|||||||
|
|
||||||
if reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
if reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||||
outstanding_amount = ref_doc.get("outstanding_amount")
|
outstanding_amount = ref_doc.get("outstanding_amount")
|
||||||
|
bill_no = ref_doc.get("bill_no")
|
||||||
elif reference_doctype == "Expense Claim":
|
elif reference_doctype == "Expense Claim":
|
||||||
outstanding_amount = flt(ref_doc.get("total_sanctioned_amount")) \
|
outstanding_amount = flt(ref_doc.get("total_sanctioned_amount")) \
|
||||||
- flt(ref_doc.get("total_amount+reimbursed")) - flt(ref_doc.get("total_advance_amount"))
|
- flt(ref_doc.get("total_amount+reimbursed")) - flt(ref_doc.get("total_advance_amount"))
|
||||||
@@ -798,7 +800,8 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
|||||||
"due_date": ref_doc.get("due_date"),
|
"due_date": ref_doc.get("due_date"),
|
||||||
"total_amount": total_amount,
|
"total_amount": total_amount,
|
||||||
"outstanding_amount": outstanding_amount,
|
"outstanding_amount": outstanding_amount,
|
||||||
"exchange_rate": exchange_rate
|
"exchange_rate": exchange_rate,
|
||||||
|
"bill_no": bill_no
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -214,9 +214,10 @@ class PaymentRequest(Document):
|
|||||||
|
|
||||||
def check_if_payment_entry_exists(self):
|
def check_if_payment_entry_exists(self):
|
||||||
if self.status == "Paid":
|
if self.status == "Paid":
|
||||||
payment_entry = frappe.db.sql_list("""select parent from `tabPayment Entry Reference`
|
if frappe.get_all("Payment Entry Reference",
|
||||||
where reference_name=%s""", self.reference_name)
|
filters={"reference_name": self.reference_name, "docstatus": ["<", 2]},
|
||||||
if payment_entry:
|
fields=["parent"],
|
||||||
|
limit=1):
|
||||||
frappe.throw(_("Payment Entry already exists"), title=_('Error'))
|
frappe.throw(_("Payment Entry already exists"), title=_('Error'))
|
||||||
|
|
||||||
def make_communication_entry(self):
|
def make_communication_entry(self):
|
||||||
|
|||||||
@@ -8,5 +8,6 @@ frappe.ui.form.on('Payment Terms Template', {
|
|||||||
frm.add_fetch("payment_term", "due_date_based_on", "due_date_based_on");
|
frm.add_fetch("payment_term", "due_date_based_on", "due_date_based_on");
|
||||||
frm.add_fetch("payment_term", "credit_days", "credit_days");
|
frm.add_fetch("payment_term", "credit_days", "credit_days");
|
||||||
frm.add_fetch("payment_term", "credit_months", "credit_months");
|
frm.add_fetch("payment_term", "credit_months", "credit_months");
|
||||||
|
frm.add_fetch("payment_term", "mode_of_payment", "mode_of_payment");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -33,6 +33,14 @@ frappe.ui.form.on('POS Profile', {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frm.set_query("account_for_change_amount", function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
account_type: ['in', ["Cash", "Bank"]]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
frm.set_query("print_format", function() {
|
frm.set_query("print_format", function() {
|
||||||
return { filters: { doc_type: "Sales Invoice", print_format_type: "Js"} };
|
return { filters: { doc_type: "Sales Invoice", print_format_type: "Js"} };
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -468,7 +468,7 @@ cur_frm.fields_dict["items"].grid.get_field("cost_center").get_query = function(
|
|||||||
|
|
||||||
cur_frm.cscript.cost_center = function(doc, cdt, cdn){
|
cur_frm.cscript.cost_center = function(doc, cdt, cdn){
|
||||||
var d = locals[cdt][cdn];
|
var d = locals[cdt][cdn];
|
||||||
if(d.idx == 1 && d.cost_center){
|
if(d.cost_center){
|
||||||
var cl = doc.items || [];
|
var cl = doc.items || [];
|
||||||
for(var i = 0; i < cl.length; i++){
|
for(var i = 0; i < cl.length; i++){
|
||||||
if(!cl[i].cost_center) cl[i].cost_center = d.cost_center;
|
if(!cl[i].cost_center) cl[i].cost_center = d.cost_center;
|
||||||
@@ -510,6 +510,15 @@ frappe.ui.form.on("Purchase Invoice", {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frm.set_query("cost_center", function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
company: frm.doc.company,
|
||||||
|
is_group: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ from frappe.utils import cint, cstr, formatdate, flt, getdate, nowdate
|
|||||||
from frappe import _, throw
|
from frappe import _, throw
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
|
|
||||||
|
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
|
||||||
from erpnext.controllers.buying_controller import BuyingController
|
from erpnext.controllers.buying_controller import BuyingController
|
||||||
from erpnext.accounts.party import get_party_account, get_due_date
|
from erpnext.accounts.party import get_party_account, get_due_date
|
||||||
from erpnext.accounts.utils import get_account_currency, get_fiscal_year
|
from erpnext.accounts.utils import get_account_currency, get_fiscal_year
|
||||||
@@ -17,7 +18,7 @@ from erpnext.accounts.general_ledger import make_gl_entries, merge_similar_entri
|
|||||||
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
|
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
|
||||||
from erpnext.buying.utils import check_for_closed_status
|
from erpnext.buying.utils import check_for_closed_status
|
||||||
from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center
|
from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center
|
||||||
from erpnext.assets.doctype.asset.asset import get_asset_account
|
from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_disabled
|
||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_invoice,\
|
from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_invoice,\
|
||||||
@@ -46,6 +47,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
}]
|
}]
|
||||||
|
|
||||||
def onload(self):
|
def onload(self):
|
||||||
|
super(PurchaseInvoice, self).onload()
|
||||||
supplier_tds = frappe.db.get_value("Supplier", self.supplier, "tax_withholding_category")
|
supplier_tds = frappe.db.get_value("Supplier", self.supplier, "tax_withholding_category")
|
||||||
self.set_onload("supplier_tds", supplier_tds)
|
self.set_onload("supplier_tds", supplier_tds)
|
||||||
|
|
||||||
@@ -53,6 +55,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
if not self.on_hold:
|
if not self.on_hold:
|
||||||
self.release_date = ''
|
self.release_date = ''
|
||||||
|
|
||||||
|
|
||||||
def invoice_is_blocked(self):
|
def invoice_is_blocked(self):
|
||||||
return self.on_hold and (not self.release_date or self.release_date > getdate(nowdate()))
|
return self.on_hold and (not self.release_date or self.release_date > getdate(nowdate()))
|
||||||
|
|
||||||
@@ -215,7 +218,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
self.validate_item_code()
|
self.validate_item_code()
|
||||||
self.validate_warehouse()
|
self.validate_warehouse()
|
||||||
if auto_accounting_for_stock:
|
if auto_accounting_for_stock:
|
||||||
warehouse_account = get_warehouse_account_map()
|
warehouse_account = get_warehouse_account_map(self.company)
|
||||||
|
|
||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
# in case of auto inventory accounting,
|
# in case of auto inventory accounting,
|
||||||
@@ -231,6 +234,13 @@ class PurchaseInvoice(BuyingController):
|
|||||||
item.expense_account = warehouse_account[item.warehouse]["account"]
|
item.expense_account = warehouse_account[item.warehouse]["account"]
|
||||||
else:
|
else:
|
||||||
item.expense_account = stock_not_billed_account
|
item.expense_account = stock_not_billed_account
|
||||||
|
elif item.is_fixed_asset and is_cwip_accounting_disabled():
|
||||||
|
if not item.asset:
|
||||||
|
frappe.throw(_("Row {0}: asset is required for item {1}")
|
||||||
|
.format(item.idx, item.item_code))
|
||||||
|
|
||||||
|
item.expense_account = get_asset_category_account(item.asset, 'fixed_asset_account',
|
||||||
|
company = self.company)
|
||||||
elif item.is_fixed_asset and item.pr_detail:
|
elif item.is_fixed_asset and item.pr_detail:
|
||||||
item.expense_account = asset_received_but_not_billed
|
item.expense_account = asset_received_but_not_billed
|
||||||
elif not item.expense_account and for_validate:
|
elif not item.expense_account and for_validate:
|
||||||
@@ -359,7 +369,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
if repost_future_gle and cint(self.update_stock) and self.auto_accounting_for_stock:
|
if repost_future_gle and cint(self.update_stock) and self.auto_accounting_for_stock:
|
||||||
from erpnext.controllers.stock_controller import update_gl_entries_after
|
from erpnext.controllers.stock_controller import update_gl_entries_after
|
||||||
items, warehouses = self.get_items_and_warehouses()
|
items, warehouses = self.get_items_and_warehouses()
|
||||||
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items)
|
update_gl_entries_after(self.posting_date, self.posting_time,
|
||||||
|
warehouses, items, company = self.company)
|
||||||
|
|
||||||
elif self.docstatus == 2 and cint(self.update_stock) and self.auto_accounting_for_stock:
|
elif self.docstatus == 2 and cint(self.update_stock) and self.auto_accounting_for_stock:
|
||||||
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
||||||
@@ -376,7 +387,9 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
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.get_asset_gl_entry(gl_entries)
|
if not is_cwip_accounting_disabled():
|
||||||
|
self.get_asset_gl_entry(gl_entries)
|
||||||
|
|
||||||
self.make_tax_gl_entries(gl_entries)
|
self.make_tax_gl_entries(gl_entries)
|
||||||
|
|
||||||
gl_entries = merge_similar_entries(gl_entries)
|
gl_entries = merge_similar_entries(gl_entries)
|
||||||
@@ -416,7 +429,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
stock_items = self.get_stock_items()
|
stock_items = self.get_stock_items()
|
||||||
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
|
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
|
||||||
if self.update_stock and self.auto_accounting_for_stock:
|
if self.update_stock and self.auto_accounting_for_stock:
|
||||||
warehouse_account = get_warehouse_account_map()
|
warehouse_account = get_warehouse_account_map(self.company)
|
||||||
|
|
||||||
voucher_wise_stock_value = {}
|
voucher_wise_stock_value = {}
|
||||||
if self.update_stock:
|
if self.update_stock:
|
||||||
@@ -468,7 +481,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
|
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
|
||||||
"credit": flt(item.rm_supp_cost)
|
"credit": flt(item.rm_supp_cost)
|
||||||
}, warehouse_account[self.supplier_warehouse]["account_currency"]))
|
}, warehouse_account[self.supplier_warehouse]["account_currency"]))
|
||||||
elif not item.is_fixed_asset:
|
elif not item.is_fixed_asset or (item.is_fixed_asset and is_cwip_accounting_disabled()):
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": item.expense_account if not item.enable_deferred_expense else item.deferred_expense_account,
|
"account": item.expense_account if not item.enable_deferred_expense else item.deferred_expense_account,
|
||||||
@@ -513,7 +526,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
base_asset_amount = flt(item.base_net_amount + item.item_tax_amount)
|
base_asset_amount = flt(item.base_net_amount + item.item_tax_amount)
|
||||||
|
|
||||||
if (not item.expense_account or frappe.db.get_value('Account',
|
if (not item.expense_account or frappe.db.get_value('Account',
|
||||||
item.expense_account, 'account_type') != 'Asset Received But Not Billed'):
|
item.expense_account, 'account_type') not in ['Asset Received But Not Billed', 'Fixed Asset']):
|
||||||
arbnb_account = self.get_company_default("asset_received_but_not_billed")
|
arbnb_account = self.get_company_default("asset_received_but_not_billed")
|
||||||
item.expense_account = arbnb_account
|
item.expense_account = arbnb_account
|
||||||
|
|
||||||
|
|||||||
@@ -344,6 +344,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
pi = frappe.copy_doc(test_records[0])
|
pi = frappe.copy_doc(test_records[0])
|
||||||
pi.disable_rounded_total = 1
|
pi.disable_rounded_total = 1
|
||||||
|
pi.allocate_advances_automatically = 0
|
||||||
pi.append("advances", {
|
pi.append("advances", {
|
||||||
"reference_type": "Journal Entry",
|
"reference_type": "Journal Entry",
|
||||||
"reference_name": jv.name,
|
"reference_name": jv.name,
|
||||||
@@ -383,6 +384,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
pi = frappe.copy_doc(test_records[0])
|
pi = frappe.copy_doc(test_records[0])
|
||||||
pi.disable_rounded_total = 1
|
pi.disable_rounded_total = 1
|
||||||
|
pi.allocate_advances_automatically = 0
|
||||||
pi.append("advances", {
|
pi.append("advances", {
|
||||||
"reference_type": "Journal Entry",
|
"reference_type": "Journal Entry",
|
||||||
"reference_name": jv.name,
|
"reference_name": jv.name,
|
||||||
|
|||||||
3
erpnext/accounts/doctype/sales_invoice/regional/italy.js
Normal file
3
erpnext/accounts/doctype/sales_invoice/regional/italy.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{% include "erpnext/regional/italy/sales_invoice.js" %}
|
||||||
|
|
||||||
|
erpnext.setup_e_invoice_button('Sales Invoice')
|
||||||
@@ -201,7 +201,8 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
get_query: function() {
|
get_query: function() {
|
||||||
var filters = {
|
var filters = {
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
company: me.frm.doc.company
|
company: me.frm.doc.company,
|
||||||
|
is_return: 0
|
||||||
};
|
};
|
||||||
if(me.frm.doc.customer) filters["customer"] = me.frm.doc.customer;
|
if(me.frm.doc.customer) filters["customer"] = me.frm.doc.customer;
|
||||||
return {
|
return {
|
||||||
@@ -555,6 +556,23 @@ frappe.ui.form.on('Sales Invoice', {
|
|||||||
frm.add_fetch('payment_term', 'invoice_portion', 'invoice_portion');
|
frm.add_fetch('payment_term', 'invoice_portion', 'invoice_portion');
|
||||||
frm.add_fetch('payment_term', 'description', 'description');
|
frm.add_fetch('payment_term', 'description', 'description');
|
||||||
|
|
||||||
|
frm.set_query("account_for_change_amount", function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
account_type: ['in', ["Cash", "Bank"]]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
frm.set_query("cost_center", function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
company: frm.doc.company,
|
||||||
|
is_group: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
frm.custom_make_buttons = {
|
frm.custom_make_buttons = {
|
||||||
'Delivery Note': 'Delivery',
|
'Delivery Note': 'Delivery',
|
||||||
'Sales Invoice': 'Sales Return',
|
'Sales Invoice': 'Sales Return',
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -205,6 +205,7 @@ class SalesInvoice(SellingController):
|
|||||||
def before_cancel(self):
|
def before_cancel(self):
|
||||||
self.update_time_sheet(None)
|
self.update_time_sheet(None)
|
||||||
|
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.check_close_sales_order("sales_order")
|
self.check_close_sales_order("sales_order")
|
||||||
|
|
||||||
@@ -399,7 +400,7 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
for fieldname in ('territory', 'naming_series', 'currency', 'taxes_and_charges', 'letter_head', 'tc_name',
|
for fieldname in ('territory', 'naming_series', 'currency', 'taxes_and_charges', 'letter_head', 'tc_name',
|
||||||
'company', 'select_print_heading', 'cash_bank_account', 'company_address',
|
'company', 'select_print_heading', 'cash_bank_account', 'company_address',
|
||||||
'write_off_account', 'write_off_cost_center', 'apply_discount_on'):
|
'write_off_account', 'write_off_cost_center', 'apply_discount_on', 'cost_center'):
|
||||||
if (not for_validate) or (for_validate and not self.get(fieldname)):
|
if (not for_validate) or (for_validate and not self.get(fieldname)):
|
||||||
self.set(fieldname, pos.get(fieldname))
|
self.set(fieldname, pos.get(fieldname))
|
||||||
|
|
||||||
@@ -523,8 +524,8 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
def validate_pos(self):
|
def validate_pos(self):
|
||||||
if self.is_return:
|
if self.is_return:
|
||||||
if flt(self.paid_amount) + flt(self.write_off_amount) - flt(self.grand_total) < \
|
if flt(self.paid_amount) + flt(self.write_off_amount) - flt(self.grand_total) > \
|
||||||
1/(10**(self.precision("grand_total") + 1)):
|
1.0/(10.0**(self.precision("grand_total") + 1.0)):
|
||||||
frappe.throw(_("Paid amount + Write Off Amount can not be greater than Grand Total"))
|
frappe.throw(_("Paid amount + Write Off Amount can not be greater than Grand Total"))
|
||||||
|
|
||||||
def validate_item_code(self):
|
def validate_item_code(self):
|
||||||
@@ -689,7 +690,8 @@ class SalesInvoice(SellingController):
|
|||||||
if repost_future_gle and cint(self.update_stock) \
|
if repost_future_gle and cint(self.update_stock) \
|
||||||
and cint(auto_accounting_for_stock):
|
and cint(auto_accounting_for_stock):
|
||||||
items, warehouses = self.get_items_and_warehouses()
|
items, warehouses = self.get_items_and_warehouses()
|
||||||
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items)
|
update_gl_entries_after(self.posting_date, self.posting_time,
|
||||||
|
warehouses, items, company = self.company)
|
||||||
elif self.docstatus == 2 and cint(self.update_stock) \
|
elif self.docstatus == 2 and cint(self.update_stock) \
|
||||||
and cint(auto_accounting_for_stock):
|
and cint(auto_accounting_for_stock):
|
||||||
from erpnext.accounts.general_ledger import delete_gl_entries
|
from erpnext.accounts.general_ledger import delete_gl_entries
|
||||||
@@ -1012,9 +1014,10 @@ class SalesInvoice(SellingController):
|
|||||||
for serial_no in item.serial_no.split("\n"):
|
for serial_no in item.serial_no.split("\n"):
|
||||||
sales_invoice = frappe.db.get_value("Serial No", serial_no, "sales_invoice")
|
sales_invoice = frappe.db.get_value("Serial No", serial_no, "sales_invoice")
|
||||||
if sales_invoice and self.name != sales_invoice:
|
if sales_invoice and self.name != sales_invoice:
|
||||||
frappe.throw(_("Serial Number: {0} is already referenced in Sales Invoice: {1}".format(
|
sales_invoice_company = frappe.db.get_value("Sales Invoice", sales_invoice, "company")
|
||||||
serial_no, sales_invoice
|
if sales_invoice_company == self.company:
|
||||||
)))
|
frappe.throw(_("Serial Number: {0} is already referenced in Sales Invoice: {1}"
|
||||||
|
.format(serial_no, sales_invoice)))
|
||||||
|
|
||||||
def update_project(self):
|
def update_project(self):
|
||||||
if self.project:
|
if self.project:
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_per
|
|||||||
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
|
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
|
||||||
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
|
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
|
||||||
from frappe.model.naming import make_autoname
|
from frappe.model.naming import make_autoname
|
||||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
from erpnext.accounts.doctype.account.test_account import get_inventory_account, create_account
|
||||||
from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
|
from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
|
||||||
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
class TestSalesInvoice(unittest.TestCase):
|
class TestSalesInvoice(unittest.TestCase):
|
||||||
def make(self):
|
def make(self):
|
||||||
@@ -854,6 +855,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
jv.submit()
|
jv.submit()
|
||||||
|
|
||||||
si = frappe.copy_doc(test_records[0])
|
si = frappe.copy_doc(test_records[0])
|
||||||
|
si.allocate_advances_automatically = 0
|
||||||
si.append("advances", {
|
si.append("advances", {
|
||||||
"doctype": "Sales Invoice Advance",
|
"doctype": "Sales Invoice Advance",
|
||||||
"reference_type": "Journal Entry",
|
"reference_type": "Journal Entry",
|
||||||
@@ -1514,6 +1516,56 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
|
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
|
||||||
accounts_settings.save()
|
accounts_settings.save()
|
||||||
|
|
||||||
|
def test_deferred_revenue(self):
|
||||||
|
deferred_account = create_account(account_name="Deferred Revenue",
|
||||||
|
parent_account="Current Liabilities - _TC", company="_Test Company")
|
||||||
|
|
||||||
|
item = create_item("_Test Item for Deferred Accounting")
|
||||||
|
item.enable_deferred_revenue = 1
|
||||||
|
item.deferred_revenue_account = deferred_account
|
||||||
|
item.no_of_months = 12
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
si = create_sales_invoice(item=item.name, posting_date="2019-01-10", do_not_submit=True)
|
||||||
|
si.items[0].enable_deferred_revenue = 1
|
||||||
|
si.items[0].service_start_date = "2019-01-10"
|
||||||
|
si.items[0].service_end_date = "2019-03-15"
|
||||||
|
si.items[0].deferred_revenue_account = deferred_account
|
||||||
|
si.save()
|
||||||
|
si.submit()
|
||||||
|
|
||||||
|
from erpnext.accounts.deferred_revenue import convert_deferred_revenue_to_income
|
||||||
|
convert_deferred_revenue_to_income(start_date="2019-01-01", end_date="2019-01-31")
|
||||||
|
|
||||||
|
expected_gle = [
|
||||||
|
[deferred_account, 33.85, 0.0, "2019-01-31"],
|
||||||
|
["Sales - _TC", 0.0, 33.85, "2019-01-31"]
|
||||||
|
]
|
||||||
|
|
||||||
|
self.check_gl_entries(si.name, expected_gle, "2019-01-10")
|
||||||
|
|
||||||
|
convert_deferred_revenue_to_income(start_date="2019-01-01", end_date="2019-03-31")
|
||||||
|
|
||||||
|
expected_gle = [
|
||||||
|
[deferred_account, 43.08, 0.0, "2019-02-28"],
|
||||||
|
["Sales - _TC", 0.0, 43.08, "2019-02-28"],
|
||||||
|
[deferred_account, 23.07, 0.0, "2019-03-15"],
|
||||||
|
["Sales - _TC", 0.0, 23.07, "2019-03-15"]
|
||||||
|
]
|
||||||
|
|
||||||
|
self.check_gl_entries(si.name, expected_gle, "2019-01-31")
|
||||||
|
|
||||||
|
def check_gl_entries(self, voucher_no, expected_gle, posting_date):
|
||||||
|
gl_entries = frappe.db.sql("""select account, debit, credit, posting_date
|
||||||
|
from `tabGL Entry`
|
||||||
|
where voucher_type='Sales Invoice' and voucher_no=%s and posting_date > %s
|
||||||
|
order by posting_date asc, account asc""", (voucher_no, posting_date), as_dict=1)
|
||||||
|
|
||||||
|
for i, gle in enumerate(gl_entries):
|
||||||
|
self.assertEqual(expected_gle[i][0], gle.account)
|
||||||
|
self.assertEqual(expected_gle[i][1], gle.debit)
|
||||||
|
self.assertEqual(expected_gle[i][2], gle.credit)
|
||||||
|
self.assertEqual(getdate(expected_gle[i][3]), gle.posting_date)
|
||||||
|
|
||||||
def create_sales_invoice(**args):
|
def create_sales_invoice(**args):
|
||||||
si = frappe.new_doc("Sales Invoice")
|
si = frappe.new_doc("Sales Invoice")
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:parent.doctype == 'POS Profile'",
|
"depends_on": "eval:parent.doctype == 'POS Profile'",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "default",
|
"fieldname": "default",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -52,6 +53,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "mode_of_payment",
|
"fieldname": "mode_of_payment",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -85,8 +87,9 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "",
|
"default": "0",
|
||||||
"depends_on": "eval:parent.doctype == 'Sales Invoice'",
|
"depends_on": "eval:parent.doctype == 'Sales Invoice'",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "amount",
|
"fieldname": "amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -120,6 +123,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_3",
|
"fieldname": "column_break_3",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -151,6 +155,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "account",
|
"fieldname": "account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -185,6 +190,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fetch_from": "mode_of_payment.type",
|
"fetch_from": "mode_of_payment.type",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "type",
|
"fieldname": "type",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -218,6 +224,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "base_amount",
|
"fieldname": "base_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -251,6 +258,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "clearance_date",
|
"fieldname": "clearance_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -287,7 +295,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2019-02-18 15:03:59.720469",
|
"modified": "2019-03-06 15:58:37.839241",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice Payment",
|
"name": "Sales Invoice Payment",
|
||||||
|
|||||||
@@ -333,6 +333,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
var me = this;
|
var me = this;
|
||||||
this.frm = {}
|
this.frm = {}
|
||||||
this.load_data(true);
|
this.load_data(true);
|
||||||
|
this.frm.doc.offline_pos_name = '';
|
||||||
this.setup();
|
this.setup();
|
||||||
this.set_default_customer()
|
this.set_default_customer()
|
||||||
},
|
},
|
||||||
@@ -345,7 +346,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
if (load_doc) {
|
if (load_doc) {
|
||||||
this.frm.doc = JSON.parse(localStorage.getItem('doc'));
|
this.frm.doc = JSON.parse(localStorage.getItem('doc'));
|
||||||
this.frm.doc.offline_pos_name = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$.each(this.meta, function (i, data) {
|
$.each(this.meta, function (i, data) {
|
||||||
@@ -641,7 +641,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
me.list_customers_btn.toggleClass("view_customer");
|
me.list_customers_btn.toggleClass("view_customer");
|
||||||
me.pos_bill.show();
|
me.pos_bill.show();
|
||||||
me.list_customers_btn.show();
|
me.list_customers_btn.show();
|
||||||
me.frm.doc.offline_pos_name = $(this).parents().attr('invoice-name')
|
me.frm.doc.offline_pos_name = $(this).parents().attr('invoice-name');
|
||||||
me.edit_record();
|
me.edit_record();
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -984,7 +984,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!this.customer_doc.fields_dict.customer_pos_id.value) {
|
if(!this.customer_doc.fields_dict.customer_pos_id.value) {
|
||||||
this.customer_doc.set_value("customer_pos_id", $.now())
|
this.customer_doc.set_value("customer_pos_id", frappe.datetime.now_datetime())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1686,10 +1686,18 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
create_invoice: function () {
|
create_invoice: function () {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
var existing_pos_list = [];
|
||||||
var invoice_data = {};
|
var invoice_data = {};
|
||||||
this.si_docs = this.get_doc_from_localstorage();
|
this.si_docs = this.get_doc_from_localstorage();
|
||||||
|
|
||||||
if (this.frm.doc.offline_pos_name) {
|
if(this.si_docs) {
|
||||||
|
this.si_docs.forEach((row) => {
|
||||||
|
existing_pos_list.push(Object.keys(row));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.frm.doc.offline_pos_name
|
||||||
|
&& in_list(existing_pos_list, this.frm.doc.offline_pos_name)) {
|
||||||
this.update_invoice()
|
this.update_invoice()
|
||||||
//to retrieve and set the default payment
|
//to retrieve and set the default payment
|
||||||
invoice_data[this.frm.doc.offline_pos_name] = this.frm.doc;
|
invoice_data[this.frm.doc.offline_pos_name] = this.frm.doc;
|
||||||
@@ -1698,8 +1706,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
this.frm.doc.paid_amount = this.frm.doc.net_total
|
this.frm.doc.paid_amount = this.frm.doc.net_total
|
||||||
this.frm.doc.outstanding_amount = 0
|
this.frm.doc.outstanding_amount = 0
|
||||||
} else {
|
} else if(!this.frm.doc.offline_pos_name) {
|
||||||
this.frm.doc.offline_pos_name = $.now();
|
this.frm.doc.offline_pos_name = frappe.datetime.now_datetime();
|
||||||
this.frm.doc.posting_date = frappe.datetime.get_today();
|
this.frm.doc.posting_date = frappe.datetime.get_today();
|
||||||
this.frm.doc.posting_time = frappe.datetime.now_time();
|
this.frm.doc.posting_time = frappe.datetime.now_time();
|
||||||
this.frm.doc.pos_total_qty = this.frm.doc.qty_total;
|
this.frm.doc.pos_total_qty = this.frm.doc.qty_total;
|
||||||
|
|||||||
@@ -573,11 +573,17 @@ def get_party_shipping_address(doctype, name):
|
|||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_partywise_advanced_payment_amount(party_type="Customer"):
|
def get_partywise_advanced_payment_amount(party_type, posting_date = None):
|
||||||
|
cond = "1=1"
|
||||||
|
if posting_date:
|
||||||
|
cond = "posting_date <= '{0}'".format(posting_date)
|
||||||
|
|
||||||
data = frappe.db.sql(""" SELECT party, sum({0}) as amount
|
data = frappe.db.sql(""" SELECT party, sum({0}) as amount
|
||||||
FROM `tabGL Entry`
|
FROM `tabGL Entry`
|
||||||
WHERE party_type = %s and against_voucher is null GROUP BY party"""
|
WHERE
|
||||||
.format(("credit - debit") if party_type == "Customer" else "debit") , party_type)
|
party_type = %s and against_voucher is null
|
||||||
|
and {1} GROUP BY party"""
|
||||||
|
.format(("credit") if party_type == "Customer" else "debit", cond) , party_type)
|
||||||
|
|
||||||
if data:
|
if data:
|
||||||
return frappe._dict(data)
|
return frappe._dict(data)
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
{%- from "templates/print_formats/standard_macros.html" import add_header -%}
|
||||||
|
<style>
|
||||||
|
.table-bordered td.top-bottom {border-top: none !important;border-bottom: none !important;}
|
||||||
|
.table-bordered td.right{border-right: none !important;}
|
||||||
|
.table-bordered td.left{border-left: none !important;}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<div class="page-break">
|
||||||
|
{%- if not doc.get("print_heading") and not doc.get("select_print_heading")
|
||||||
|
and doc.set("select_print_heading", _("Payment Entry")) -%}{%- endif -%}
|
||||||
|
{{ add_header(0, 1, doc, letter_head, no_letterhead, print_settings) }}
|
||||||
|
<div class="row margin-bottom">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Voucher No: </strong></td><td>{{ doc.name }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Date: </strong></td><td>{{ frappe.utils.formatdate(doc.creation) }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="margin-top">
|
||||||
|
<table class="table table-bordered table-condensed">
|
||||||
|
<tr>
|
||||||
|
<th>Account</th>
|
||||||
|
<th>Party Type</th>
|
||||||
|
<th>Party</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="top-bottom" colspan="5"><strong>Credit</strong></td>
|
||||||
|
</tr>
|
||||||
|
{% set total_credit = 0 -%}
|
||||||
|
{% for entries in doc.gl_entries %}
|
||||||
|
{% if entries.debit == 0.0 %}
|
||||||
|
<tr>
|
||||||
|
<td class="right top-bottom">{{ entries.account }}</td>
|
||||||
|
<td class="right left top-bottom">{{ entries.party_type }}</td>
|
||||||
|
<td class="right left top-bottom">{{ entries.party }}</td>
|
||||||
|
<td class="left top-bottom">{{ entries.credit }}</td>
|
||||||
|
{% set total_credit = total_credit + entries.credit -%}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="top-bottom" colspan="4"><strong> Narration </strong><br>{{ entries.remarks }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="right" colspan="3"><strong>Total (credit) </strong></td>
|
||||||
|
<td class="left" >{{total_credit}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<tr>
|
||||||
|
<td class="top-bottom" colspan="4"> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="top-bottom" colspan="5"><strong>Debit</strong></td>
|
||||||
|
</tr>
|
||||||
|
{% set total_debit = 0 -%}
|
||||||
|
{% for entries in doc.gl_entries %}
|
||||||
|
{% if entries.credit == 0.0 %}
|
||||||
|
<tr>
|
||||||
|
<td class="right top-bottom">{{ entries.account }}</td>
|
||||||
|
<td class="right left top-bottom">{{ entries.party_type }}</td>
|
||||||
|
<td class="right left top-bottom">{{ entries.party }}</td>
|
||||||
|
{% set total_debit = total_debit + entries.debit -%}
|
||||||
|
<td class="left top-bottom">{{ entries.debit }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="top-bottom"colspan="4"><strong> Narration </strong><br>{{ entries.remarks }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="right" colspan="3" ><strong>Total (debit) </strong></td>
|
||||||
|
<td class="left" >{{total_debit}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"align_labels_right": 0,
|
||||||
|
"creation": "2019-02-15 11:49:08.608619",
|
||||||
|
"custom_format": 0,
|
||||||
|
"default_print_language": "en",
|
||||||
|
"disabled": 0,
|
||||||
|
"doc_type": "Payment Entry",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Print Format",
|
||||||
|
"font": "Default",
|
||||||
|
"idx": 0,
|
||||||
|
"line_breaks": 0,
|
||||||
|
"modified": "2019-02-15 11:49:08.608619",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Bank and Cash Payment Voucher",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"print_format_builder": 0,
|
||||||
|
"print_format_type": "Server",
|
||||||
|
"show_section_headings": 0,
|
||||||
|
"standard": "Yes"
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,76 @@
|
|||||||
|
{%- from "templates/print_formats/standard_macros.html" import add_header -%}
|
||||||
|
<style>
|
||||||
|
.table-bordered td.top-bottom {border-top: none !important;border-bottom: none !important;}
|
||||||
|
.table-bordered td.right{border-right: none !important;}
|
||||||
|
.table-bordered td.left{border-left: none !important;}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<div class="page-break">
|
||||||
|
{%- if not doc.get("print_heading") and not doc.get("select_print_heading")
|
||||||
|
and doc.set("select_print_heading", _("Journal Entry")) -%}{%- endif -%}
|
||||||
|
{{ add_header(0, 1, doc, letter_head, no_letterhead, print_settings) }}
|
||||||
|
<div class="row margin-bottom">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Voucher No: </strong></td><td>{{ doc.name }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Date: </strong></td><td>{{ frappe.utils.formatdate(doc.creation) }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="margin-top">
|
||||||
|
<table class="table table-bordered table-condensed">
|
||||||
|
<tr>
|
||||||
|
<th>Account</th>
|
||||||
|
<th>Party Type</th>
|
||||||
|
<th>Party</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="top-bottom" colspan="5"><strong>Credit</strong></td>
|
||||||
|
</tr>
|
||||||
|
{% set total_credit = 0 -%}
|
||||||
|
{% for entries in doc.gl_entries %}
|
||||||
|
{% if entries.debit == 0.0 %}
|
||||||
|
<tr>
|
||||||
|
<td class="right top-bottom">{{ entries.account }}</td>
|
||||||
|
<td class="right left top-bottom">{{ entries.party_type }}</td>
|
||||||
|
<td class="right left top-bottom">{{ entries.party }}</td>
|
||||||
|
<td class="left top-bottom">{{ entries.credit }}</td>
|
||||||
|
{% set total_credit = total_credit + entries.credit -%}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="right" colspan="3"><strong>Total (credit) </strong></td>
|
||||||
|
<td class="left" >{{total_credit}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<tr>
|
||||||
|
<td class="top-bottom" colspan="4"> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="top-bottom" colspan="5"><strong>Debit</strong></td>
|
||||||
|
</tr>
|
||||||
|
{% set total_debit = 0 -%}
|
||||||
|
{% for entries in doc.gl_entries %}
|
||||||
|
{% if entries.credit == 0.0 %}
|
||||||
|
<tr>
|
||||||
|
<td class="right top-bottom">{{ entries.account }}</td>
|
||||||
|
<td class="right left top-bottom">{{ entries.party_type }}</td>
|
||||||
|
<td class="right left top-bottom">{{ entries.party }}</td>
|
||||||
|
{% set total_debit = total_debit + entries.debit -%}
|
||||||
|
<td class="left top-bottom">{{ entries.debit }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="right" colspan="3" ><strong>Total (debit) </strong></td>
|
||||||
|
<td class="left" >{{total_debit}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"align_labels_right": 0,
|
||||||
|
"creation": "2019-02-15 14:13:05.721784",
|
||||||
|
"custom_format": 0,
|
||||||
|
"default_print_language": "en",
|
||||||
|
"disabled": 0,
|
||||||
|
"doc_type": "Journal Entry",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Print Format",
|
||||||
|
"font": "Default",
|
||||||
|
"idx": 0,
|
||||||
|
"line_breaks": 0,
|
||||||
|
"modified": "2019-02-15 14:13:05.721784",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Journal Auditing Voucher",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"print_format_builder": 0,
|
||||||
|
"print_format_type": "Server",
|
||||||
|
"show_section_headings": 0,
|
||||||
|
"standard": "Yes"
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
{%- from "templates/print_formats/standard_macros.html" import add_header -%}
|
||||||
|
<div class="page-break">
|
||||||
|
{%- if not doc.get("print_heading") and not doc.get("select_print_heading")
|
||||||
|
and doc.set("select_print_heading", _("Purchase Invoice")) -%}{%- endif -%}
|
||||||
|
{{ add_header(0, 1, doc, letter_head, no_letterhead, print_settings) }}
|
||||||
|
<div class="row margin-bottom">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Supplier Name: </strong></td><td>{{ doc.supplier }}</td></tr>
|
||||||
|
<tr><td><strong>Due Date: </strong></td><td>{{ frappe.utils.formatdate(doc.due_date) }}</td></tr>
|
||||||
|
<tr><td><strong>Address: </strong></td><td>{{doc.address_display}}</td></tr>
|
||||||
|
<tr><td><strong>Contact: </strong></td><td>{{doc.contact_display}}</td></tr>
|
||||||
|
<tr><td><strong>Mobile no: </strong> </td><td>{{doc.contact_mobile}}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Voucher No: </strong></td><td>{{ doc.name }}</td></tr>
|
||||||
|
<tr><td><strong>Date: </strong></td><td>{{ frappe.utils.formatdate(doc.creation) }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="margin-top margin-bottom">
|
||||||
|
<table class="table table-bordered table-condensed">
|
||||||
|
<tr>
|
||||||
|
<th>SL</th>
|
||||||
|
<th>Item Code</th>
|
||||||
|
<th>Item Name</th>
|
||||||
|
<th>UOM</th>
|
||||||
|
<th>Received Qty.</th>
|
||||||
|
<th>Rejected Qty</th>
|
||||||
|
<th>Qty</th>
|
||||||
|
<th>Basic Rate</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
</tr>
|
||||||
|
{% for item in doc.items %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ loop.index }}</td>
|
||||||
|
<td>{{ item.item_code }}</td>
|
||||||
|
<td>{{ item.item_name }}</td>
|
||||||
|
<td>{{ item.uom }}</td>
|
||||||
|
<td>{{ item.received_qty }}</td>
|
||||||
|
<td>{{ item.rejected_qty }}</td>
|
||||||
|
<td>{{ item.qty}}</td>
|
||||||
|
<td>{{ item.rate }}</td>
|
||||||
|
<td>{{ item.amount }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="row margin-bottom">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Total Quantity: </strong></td><td>{{ doc.total_qty }}</td></tr>
|
||||||
|
<tr><td><strong>Total: </strong></td><td>{{doc.total}}</td></tr>
|
||||||
|
<tr><td><strong>Net Weight: </strong></td><td>{{ doc.total_net_weight }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Tax and Charges: </strong></td><td>{{doc.taxes_and_charges}}</td></tr>
|
||||||
|
{% for tax in doc.taxes %}
|
||||||
|
<tr><td><strong>{{ tax.account_head }}: </strong></td><td>{{ tax.tax_amount_after_discount_amount }}</td></tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr><td><strong> Taxes and Charges Added: </strong></td><td>{{ doc.taxes_and_charges_added }}</td></tr>
|
||||||
|
<tr><td><strong> Taxes and Charges Deducted: </strong></td><td>{{ doc.taxes_and_charges_deducted }}</td></tr>
|
||||||
|
<tr><td><strong> Total Taxes and Charges: </strong></td><td>{{ doc.total_taxes_and_charges }}</td></tr>
|
||||||
|
<tr><td><strong> Net Payable: </strong></td><td>{{ doc.grand_total }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="margin-top">
|
||||||
|
<table class='table table-bordered table-condensed'>
|
||||||
|
<tr>
|
||||||
|
<th>SL</th>
|
||||||
|
<th>Account</th>
|
||||||
|
<th>Party Type</th>
|
||||||
|
<th>Party</th>
|
||||||
|
<th>Credit Amount</th>
|
||||||
|
<th>Debit Amount</th>
|
||||||
|
</tr>
|
||||||
|
{% for entries in doc.gl_entries %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ loop.index }}</td>
|
||||||
|
<td>{{ entries.account }}</td>
|
||||||
|
<td>{{ entries.party_type }}</td>
|
||||||
|
<td>{{ entries.party }}</td>
|
||||||
|
<td>{{ entries.credit }}</td>
|
||||||
|
<td>{{ entries.debit }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="4"><strong>Total</strong></td>
|
||||||
|
<td>{{ doc.grand_total|flt }}</td>
|
||||||
|
<td>{{ doc.grand_total|flt }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"align_labels_right": 0,
|
||||||
|
"creation": "2019-02-14 14:42:35.151611",
|
||||||
|
"custom_format": 0,
|
||||||
|
"default_print_language": "en",
|
||||||
|
"disabled": 0,
|
||||||
|
"doc_type": "Purchase Invoice",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Print Format",
|
||||||
|
"font": "Default",
|
||||||
|
"idx": 0,
|
||||||
|
"line_breaks": 0,
|
||||||
|
"modified": "2019-02-14 14:42:35.151611",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Purchase Auditing Voucher",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"print_format_builder": 0,
|
||||||
|
"print_format_type": "Server",
|
||||||
|
"show_section_headings": 0,
|
||||||
|
"standard": "Yes"
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
{%- from "templates/print_formats/standard_macros.html" import add_header -%}
|
||||||
|
<div class="page-break">
|
||||||
|
{%- if not doc.get("print_heading") and not doc.get("select_print_heading")
|
||||||
|
and doc.set("select_print_heading", _("Sales Invoice")) -%}{%- endif -%}
|
||||||
|
{{ add_header(0, 1, doc, letter_head, no_letterhead, print_settings) }}
|
||||||
|
<div class="row margin-bottom">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Customer Name: </strong></td><td>{{ doc.customer }}</td></tr>
|
||||||
|
<tr><td><strong>Due Date: </strong></td><td>{{ frappe.utils.formatdate(doc.due_date) }}</td></tr>
|
||||||
|
<tr><td><strong>Address: </strong></td><td>{{doc.address_display}}</td></tr>
|
||||||
|
<tr><td><strong>Contact: </strong></td><td>{{doc.contact_display}}</td></tr>
|
||||||
|
<tr><td><strong>Mobile no: </strong> </td><td>{{doc.contact_mobile}}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Voucher No: </strong></td><td>{{ doc.name }}</td></tr>
|
||||||
|
<tr><td><strong>Date: </strong></td><td>{{ frappe.utils.formatdate(doc.creation) }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="margin-top margin-bottom">
|
||||||
|
<table class="table table-bordered table-condensed">
|
||||||
|
<tr>
|
||||||
|
<th>SL</th>
|
||||||
|
<th>Item Code</th>
|
||||||
|
<th>Item Name</th>
|
||||||
|
<th>UOM</th>
|
||||||
|
<th>Quantity</th>
|
||||||
|
<th>Basic Rate</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
</tr>
|
||||||
|
{% for item in doc.items %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ loop.index }}</td>
|
||||||
|
<td>{{ item.item_code }}</td>
|
||||||
|
<td>{{ item.item_name }}</td>
|
||||||
|
<td>{{ item.uom }}</td>
|
||||||
|
<td>{{ item.qty}}</td>
|
||||||
|
<td>{{ item.rate }}</td>
|
||||||
|
<td>{{ item.amount }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="row margin-bottom">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Total Quantity: </strong></td><td>{{ doc.total_qty }}</td></tr>
|
||||||
|
<tr><td><strong>Total: </strong></td><td>{{doc.total}}</td></tr>
|
||||||
|
<tr><td><strong>Net Weight: </strong></td><td>{{ doc.total_net_weight }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<tr><td><strong>Tax and Charges: </strong></td><td>{{doc.taxes_and_charges}}</td></tr>
|
||||||
|
{% for tax in doc.taxes %}
|
||||||
|
<tr><td><strong>{{ tax.account_head }}: </strong></td><td>{{ tax.tax_amount_after_discount_amount }}</td></tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr><td><strong> Total Taxes and Charges: </strong></td><td>{{ doc.total_taxes_and_charges }}</td></tr>
|
||||||
|
<tr><td><strong> Net Payable: </strong></td><td>{{ doc.grand_total }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="margin-top">
|
||||||
|
<table class='table table-bordered table-condensed'>
|
||||||
|
<tr>
|
||||||
|
<th>SL</th>
|
||||||
|
<th>Account</th>
|
||||||
|
<th>Party Type</th>
|
||||||
|
<th>Party</th>
|
||||||
|
<th>Credit Amount</th>
|
||||||
|
<th>Debit Amount</th>
|
||||||
|
</tr>
|
||||||
|
{% for entries in doc.gl_entries %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ loop.index }}</td>
|
||||||
|
<td>{{ entries.account }}</td>
|
||||||
|
<td>{{ entries.party_type }}</td>
|
||||||
|
<td>{{ entries.party }}</td>
|
||||||
|
<td>{{ entries.credit }}</td>
|
||||||
|
<td>{{ entries.debit }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="4"><strong>Total</strong></td>
|
||||||
|
<td>{{ doc.grand_total|flt }}</td>
|
||||||
|
<td>{{ doc.grand_total|flt }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"align_labels_right": 0,
|
||||||
|
"creation": "2019-02-15 15:02:51.454754",
|
||||||
|
"custom_format": 0,
|
||||||
|
"default_print_language": "en",
|
||||||
|
"disabled": 0,
|
||||||
|
"doc_type": "Sales Invoice",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Print Format",
|
||||||
|
"font": "Default",
|
||||||
|
"idx": 0,
|
||||||
|
"line_breaks": 0,
|
||||||
|
"modified": "2019-02-15 15:02:51.454754",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Sales Auditing Voucher",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"print_format_builder": 0,
|
||||||
|
"print_format_type": "Server",
|
||||||
|
"show_section_headings": 0,
|
||||||
|
"standard": "Yes"
|
||||||
|
}
|
||||||
@@ -107,26 +107,28 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||||
<th style="width: 7%">{%= __("Date") %}</th>
|
<th style="width: 9%">{%= __("Date") %}</th>
|
||||||
<th style="width: 7%">{%= __("Age (Days)") %}</th>
|
<th style="width: 5%">{%= __("Age (Days)") %}</th>
|
||||||
<th style="width: 13%">{%= __("Reference") %}</th>
|
|
||||||
{% if(report.report_name === "Accounts Receivable") { %}
|
{% if(report.report_name === "Accounts Receivable" && filters.show_sales_person_in_print) { %}
|
||||||
<th style="width: 10%">{%= __("Sales Person") %}</th>
|
<th style="width: 16%">{%= __("Reference") %}</th>
|
||||||
|
<th style="width: 10%">{%= __("Sales Person") %}</th>
|
||||||
|
{% } else { %}
|
||||||
|
<th style="width: 26%">{%= __("Reference") %}</th>
|
||||||
{% } %}
|
{% } %}
|
||||||
{% if(!filters.show_pdc_in_print) { %}
|
{% if(!filters.show_pdc_in_print) { %}
|
||||||
<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||||
{% } %}
|
{% } %}
|
||||||
<th style="width: 10%; text-align: right">{%= __("Invoiced Amount") %}</th>
|
<th style="width: 10%; text-align: right">{%= __("Invoiced Amount") %}</th>
|
||||||
{% if(!filters.show_pdc_in_print) { %}
|
{% if(!filters.show_pdc_in_print) { %}
|
||||||
<th style="width: 10%; text-align: right">{%= __("Paid Amount") %}</th>
|
<th style="width: 10%; text-align: right">{%= __("Paid Amount") %}</th>
|
||||||
<th style="width: 10%; text-align: right">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
<th style="width: 10%; text-align: right">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
||||||
{% } %}
|
{% } %}
|
||||||
<th style="width: 15%; text-align: right">{%= __("Outstanding Amount") %}</th>
|
<th style="width: 10%; text-align: right">{%= __("Outstanding Amount") %}</th>
|
||||||
{% if(filters.show_pdc_in_print) { %}
|
{% if(filters.show_pdc_in_print) { %}
|
||||||
{% if(report.report_name === "Accounts Receivable") { %}
|
{% if(report.report_name === "Accounts Receivable") { %}
|
||||||
<th style="width: 10%">{%= __("Customer LPO No.") %}</th>
|
<th style="width: 10%">{%= __("Customer LPO No.") %}</th>
|
||||||
{% } %}
|
{% } %}
|
||||||
<th style="width: 10%">{%= __("PDC/LC Date") %}</th>
|
|
||||||
<th style="width: 10%">{%= __("PDC/LC Ref") %}</th>
|
<th style="width: 10%">{%= __("PDC/LC Ref") %}</th>
|
||||||
<th style="width: 10%">{%= __("PDC/LC Amount") %}</th>
|
<th style="width: 10%">{%= __("PDC/LC Amount") %}</th>
|
||||||
<th style="width: 10%">{%= __("Remaining Balance") %}</th>
|
<th style="width: 10%">{%= __("Remaining Balance") %}</th>
|
||||||
@@ -155,7 +157,7 @@
|
|||||||
{%= data[i]["voucher_no"] %}
|
{%= data[i]["voucher_no"] %}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
{% if(report.report_name === "Accounts Receivable") { %}
|
{% if(report.report_name === "Accounts Receivable" && filters.show_sales_person_in_print) { %}
|
||||||
<td>{%= data[i]["sales_person"] %}</td>
|
<td>{%= data[i]["sales_person"] %}</td>
|
||||||
{% } %}
|
{% } %}
|
||||||
|
|
||||||
@@ -195,7 +197,6 @@
|
|||||||
<td style="text-align: right">
|
<td style="text-align: right">
|
||||||
{%= data[i]["po_no"] %}</td>
|
{%= data[i]["po_no"] %}</td>
|
||||||
{% } %}
|
{% } %}
|
||||||
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][("pdc/lc_date")]) %}</td>
|
|
||||||
<td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
|
<td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
|
||||||
<td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
|
<td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
|
||||||
<td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
|
<td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
|
||||||
@@ -226,7 +227,6 @@
|
|||||||
<td style="text-align: right">
|
<td style="text-align: right">
|
||||||
{%= data[i][__("Customer LPO")] %}</td>
|
{%= data[i][__("Customer LPO")] %}</td>
|
||||||
{% } %}
|
{% } %}
|
||||||
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
|
|
||||||
<td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
|
<td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
|
||||||
<td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
|
<td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
|
||||||
<td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
|
<td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
|
||||||
|
|||||||
@@ -102,14 +102,19 @@ frappe.query_reports["Accounts Receivable"] = {
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Sales Person"
|
"options": "Sales Person"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"based_on_payment_terms",
|
||||||
|
"label": __("Based On Payment Terms"),
|
||||||
|
"fieldtype": "Check",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"show_pdc_in_print",
|
"fieldname":"show_pdc_in_print",
|
||||||
"label": __("Show PDC in Print"),
|
"label": __("Show PDC in Print"),
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"based_on_payment_terms",
|
"fieldname":"show_sales_person_in_print",
|
||||||
"label": __("Based On Payment Terms"),
|
"label": __("Show Sales Person in Print"),
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,7 +136,8 @@ class AccountsReceivableSummary(ReceivablePayableReport):
|
|||||||
|
|
||||||
partywise_total = self.get_partywise_total(party_naming_by, args)
|
partywise_total = self.get_partywise_total(party_naming_by, args)
|
||||||
|
|
||||||
partywise_advance_amount = get_partywise_advanced_payment_amount(args.get("party_type")) or {}
|
partywise_advance_amount = get_partywise_advanced_payment_amount(args.get("party_type"),
|
||||||
|
self.filters.get("report_date")) or {}
|
||||||
for party, party_dict in iteritems(partywise_total):
|
for party, party_dict in iteritems(partywise_total):
|
||||||
row = [party]
|
row = [party]
|
||||||
|
|
||||||
@@ -145,8 +146,12 @@ class AccountsReceivableSummary(ReceivablePayableReport):
|
|||||||
|
|
||||||
row += [partywise_advance_amount.get(party, 0)]
|
row += [partywise_advance_amount.get(party, 0)]
|
||||||
|
|
||||||
|
paid_amt = 0
|
||||||
|
if party_dict.paid_amt > 0:
|
||||||
|
paid_amt = flt(party_dict.paid_amt - partywise_advance_amount.get(party, 0))
|
||||||
|
|
||||||
row += [
|
row += [
|
||||||
party_dict.invoiced_amt, party_dict.paid_amt, party_dict.credit_amt, party_dict.outstanding_amt,
|
party_dict.invoiced_amt, paid_amt, party_dict.credit_amt, party_dict.outstanding_amt,
|
||||||
party_dict.range1, party_dict.range2, party_dict.range3, party_dict.range4,
|
party_dict.range1, party_dict.range2, party_dict.range3, party_dict.range4,
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -205,7 +210,7 @@ class AccountsReceivableSummary(ReceivablePayableReport):
|
|||||||
|
|
||||||
cols += ["invoiced_amt", "paid_amt", "credit_amt",
|
cols += ["invoiced_amt", "paid_amt", "credit_amt",
|
||||||
"outstanding_amt", "age", "range1", "range2", "range3", "range4", "currency", "pdc/lc_date", "pdc/lc_ref",
|
"outstanding_amt", "age", "range1", "range2", "range3", "range4", "currency", "pdc/lc_date", "pdc/lc_ref",
|
||||||
"pdc/lc_amount", "remaining_balance"]
|
"pdc/lc_amount"]
|
||||||
|
|
||||||
if args.get("party_type") == "Supplier":
|
if args.get("party_type") == "Supplier":
|
||||||
cols += ["supplier_group", "remarks"]
|
cols += ["supplier_group", "remarks"]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
import erpnext
|
import erpnext
|
||||||
from frappe import _
|
from frappe import _, scrub
|
||||||
from frappe.utils import getdate, nowdate
|
from frappe.utils import getdate, nowdate
|
||||||
from six import iteritems, itervalues
|
from six import iteritems, itervalues
|
||||||
|
|
||||||
@@ -14,6 +14,9 @@ class PartyLedgerSummaryReport(object):
|
|||||||
self.filters.from_date = getdate(self.filters.from_date or nowdate())
|
self.filters.from_date = getdate(self.filters.from_date or nowdate())
|
||||||
self.filters.to_date = getdate(self.filters.to_date or nowdate())
|
self.filters.to_date = getdate(self.filters.to_date or nowdate())
|
||||||
|
|
||||||
|
if not self.filters.get("company"):
|
||||||
|
self.filters["company"] = frappe.db.get_single_value('Global Defaults', 'default_company')
|
||||||
|
|
||||||
def run(self, args):
|
def run(self, args):
|
||||||
if self.filters.from_date > self.filters.to_date:
|
if self.filters.from_date > self.filters.to_date:
|
||||||
frappe.throw(_("From Date must be before To Date"))
|
frappe.throw(_("From Date must be before To Date"))
|
||||||
@@ -21,10 +24,9 @@ class PartyLedgerSummaryReport(object):
|
|||||||
self.filters.party_type = args.get("party_type")
|
self.filters.party_type = args.get("party_type")
|
||||||
self.party_naming_by = frappe.db.get_value(args.get("naming_by")[0], None, args.get("naming_by")[1])
|
self.party_naming_by = frappe.db.get_value(args.get("naming_by")[0], None, args.get("naming_by")[1])
|
||||||
|
|
||||||
discount_account_field = "discount_allowed_account" if self.filters.party_type == "Customer" \
|
self.get_gl_entries()
|
||||||
else "discount_received_account"
|
self.get_return_invoices()
|
||||||
self.round_off_account, self.write_off_account, self.discount_account = frappe.get_cached_value('Company',
|
self.get_party_adjustment_amounts()
|
||||||
self.filters.company, ["round_off_account", "write_off_account", discount_account_field])
|
|
||||||
|
|
||||||
columns = self.get_columns()
|
columns = self.get_columns()
|
||||||
data = self.get_data()
|
data = self.get_data()
|
||||||
@@ -48,7 +50,6 @@ class PartyLedgerSummaryReport(object):
|
|||||||
})
|
})
|
||||||
|
|
||||||
credit_or_debit_note = "Credit Note" if self.filters.party_type == "Customer" else "Debit Note"
|
credit_or_debit_note = "Credit Note" if self.filters.party_type == "Customer" else "Debit Note"
|
||||||
discount_allowed_or_received = "Discount Allowed" if self.filters.party_type == "Customer" else "Discount Received"
|
|
||||||
|
|
||||||
columns += [
|
columns += [
|
||||||
{
|
{
|
||||||
@@ -79,27 +80,19 @@ class PartyLedgerSummaryReport(object):
|
|||||||
"options": "currency",
|
"options": "currency",
|
||||||
"width": 120
|
"width": 120
|
||||||
},
|
},
|
||||||
{
|
]
|
||||||
"label": _(discount_allowed_or_received),
|
|
||||||
"fieldname": "discount_amount",
|
for account in self.party_adjustment_accounts:
|
||||||
|
columns.append({
|
||||||
|
"label": account,
|
||||||
|
"fieldname": "adj_" + scrub(account),
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"options": "currency",
|
"options": "currency",
|
||||||
"width": 120
|
"width": 120,
|
||||||
},
|
"is_adjustment": 1
|
||||||
{
|
})
|
||||||
"label": _("Write Off Amount"),
|
|
||||||
"fieldname": "write_off_amount",
|
columns += [
|
||||||
"fieldtype": "Currency",
|
|
||||||
"options": "currency",
|
|
||||||
"width": 120
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Other Adjustments"),
|
|
||||||
"fieldname": "adjustment_amount",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"options": "currency",
|
|
||||||
"width": 120
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"label": _("Closing Balance"),
|
"label": _("Closing Balance"),
|
||||||
"fieldname": "closing_balance",
|
"fieldname": "closing_balance",
|
||||||
@@ -119,17 +112,10 @@ class PartyLedgerSummaryReport(object):
|
|||||||
return columns
|
return columns
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
if not self.filters.get("company"):
|
|
||||||
self.filters["company"] = frappe.db.get_single_value('Global Defaults', 'default_company')
|
|
||||||
|
|
||||||
company_currency = frappe.get_cached_value('Company', self.filters.get("company"), "default_currency")
|
company_currency = frappe.get_cached_value('Company', self.filters.get("company"), "default_currency")
|
||||||
invoice_dr_or_cr = "debit" if self.filters.party_type == "Customer" else "credit"
|
invoice_dr_or_cr = "debit" if self.filters.party_type == "Customer" else "credit"
|
||||||
reverse_dr_or_cr = "credit" if self.filters.party_type == "Customer" else "debit"
|
reverse_dr_or_cr = "credit" if self.filters.party_type == "Customer" else "debit"
|
||||||
|
|
||||||
self.get_gl_entries()
|
|
||||||
self.get_return_invoices()
|
|
||||||
self.get_party_adjustment_amounts()
|
|
||||||
|
|
||||||
self.party_data = frappe._dict({})
|
self.party_data = frappe._dict({})
|
||||||
for gle in self.gl_entries:
|
for gle in self.gl_entries:
|
||||||
self.party_data.setdefault(gle.party, frappe._dict({
|
self.party_data.setdefault(gle.party, frappe._dict({
|
||||||
@@ -146,7 +132,7 @@ class PartyLedgerSummaryReport(object):
|
|||||||
amount = gle.get(invoice_dr_or_cr) - gle.get(reverse_dr_or_cr)
|
amount = gle.get(invoice_dr_or_cr) - gle.get(reverse_dr_or_cr)
|
||||||
self.party_data[gle.party].closing_balance += amount
|
self.party_data[gle.party].closing_balance += amount
|
||||||
|
|
||||||
if gle.posting_date < self.filters.from_date:
|
if gle.posting_date < self.filters.from_date or gle.is_opening == "Yes":
|
||||||
self.party_data[gle.party].opening_balance += amount
|
self.party_data[gle.party].opening_balance += amount
|
||||||
else:
|
else:
|
||||||
if amount > 0:
|
if amount > 0:
|
||||||
@@ -161,9 +147,10 @@ class PartyLedgerSummaryReport(object):
|
|||||||
if row.opening_balance or row.invoiced_amount or row.paid_amount or row.return_amount or row.closing_amount:
|
if row.opening_balance or row.invoiced_amount or row.paid_amount or row.return_amount or row.closing_amount:
|
||||||
total_party_adjustment = sum([amount for amount in itervalues(self.party_adjustment_details.get(party, {}))])
|
total_party_adjustment = sum([amount for amount in itervalues(self.party_adjustment_details.get(party, {}))])
|
||||||
row.paid_amount -= total_party_adjustment
|
row.paid_amount -= total_party_adjustment
|
||||||
row.discount_amount = self.party_adjustment_details.get(party, {}).get(self.discount_account, 0)
|
|
||||||
row.write_off_amount = self.party_adjustment_details.get(party, {}).get(self.write_off_account, 0)
|
adjustments = self.party_adjustment_details.get(party, {})
|
||||||
row.adjustment_amount = total_party_adjustment - row.discount_amount - row.write_off_amount
|
for account in self.party_adjustment_accounts:
|
||||||
|
row["adj_" + scrub(account)] = adjustments.get(account, 0)
|
||||||
|
|
||||||
out.append(row)
|
out.append(row)
|
||||||
|
|
||||||
@@ -182,7 +169,7 @@ class PartyLedgerSummaryReport(object):
|
|||||||
self.gl_entries = frappe.db.sql("""
|
self.gl_entries = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
gle.posting_date, gle.party, gle.voucher_type, gle.voucher_no, gle.against_voucher_type,
|
gle.posting_date, gle.party, gle.voucher_type, gle.voucher_no, gle.against_voucher_type,
|
||||||
gle.against_voucher, gle.debit, gle.credit {join_field}
|
gle.against_voucher, gle.debit, gle.credit, gle.is_opening {join_field}
|
||||||
from `tabGL Entry` gle
|
from `tabGL Entry` gle
|
||||||
{join}
|
{join}
|
||||||
where
|
where
|
||||||
@@ -195,7 +182,7 @@ class PartyLedgerSummaryReport(object):
|
|||||||
conditions = [""]
|
conditions = [""]
|
||||||
|
|
||||||
if self.filters.company:
|
if self.filters.company:
|
||||||
conditions.append("company=%(company)s")
|
conditions.append("gle.company=%(company)s")
|
||||||
|
|
||||||
self.filters.company_finance_book = erpnext.get_default_finance_book(self.filters.company)
|
self.filters.company_finance_book = erpnext.get_default_finance_book(self.filters.company)
|
||||||
|
|
||||||
@@ -254,9 +241,10 @@ class PartyLedgerSummaryReport(object):
|
|||||||
|
|
||||||
def get_party_adjustment_amounts(self):
|
def get_party_adjustment_amounts(self):
|
||||||
conditions = self.prepare_conditions()
|
conditions = self.prepare_conditions()
|
||||||
income_or_expense = "Expense" if self.filters.party_type == "Customer" else "Income"
|
income_or_expense = "Expense Account" if self.filters.party_type == "Customer" else "Income Account"
|
||||||
invoice_dr_or_cr = "debit" if self.filters.party_type == "Customer" else "credit"
|
invoice_dr_or_cr = "debit" if self.filters.party_type == "Customer" else "credit"
|
||||||
reverse_dr_or_cr = "credit" if self.filters.party_type == "Customer" else "debit"
|
reverse_dr_or_cr = "credit" if self.filters.party_type == "Customer" else "debit"
|
||||||
|
round_off_account = frappe.get_cached_value('Company', self.filters.company, "round_off_account")
|
||||||
|
|
||||||
gl_entries = frappe.db.sql("""
|
gl_entries = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
@@ -267,7 +255,7 @@ class PartyLedgerSummaryReport(object):
|
|||||||
docstatus < 2
|
docstatus < 2
|
||||||
and (voucher_type, voucher_no) in (
|
and (voucher_type, voucher_no) in (
|
||||||
select voucher_type, voucher_no from `tabGL Entry` gle, `tabAccount` acc
|
select voucher_type, voucher_no from `tabGL Entry` gle, `tabAccount` acc
|
||||||
where acc.name = gle.account and acc.root_type = '{income_or_expense}'
|
where acc.name = gle.account and acc.account_type = '{income_or_expense}'
|
||||||
and gle.posting_date between %(from_date)s and %(to_date)s and gle.docstatus < 2
|
and gle.posting_date between %(from_date)s and %(to_date)s and gle.docstatus < 2
|
||||||
) and (voucher_type, voucher_no) in (
|
) and (voucher_type, voucher_no) in (
|
||||||
select voucher_type, voucher_no from `tabGL Entry` gle
|
select voucher_type, voucher_no from `tabGL Entry` gle
|
||||||
@@ -277,6 +265,7 @@ class PartyLedgerSummaryReport(object):
|
|||||||
""".format(conditions=conditions, income_or_expense=income_or_expense), self.filters, as_dict=True)
|
""".format(conditions=conditions, income_or_expense=income_or_expense), self.filters, as_dict=True)
|
||||||
|
|
||||||
self.party_adjustment_details = {}
|
self.party_adjustment_details = {}
|
||||||
|
self.party_adjustment_accounts = set()
|
||||||
adjustment_voucher_entries = {}
|
adjustment_voucher_entries = {}
|
||||||
for gle in gl_entries:
|
for gle in gl_entries:
|
||||||
adjustment_voucher_entries.setdefault((gle.voucher_type, gle.voucher_no), [])
|
adjustment_voucher_entries.setdefault((gle.voucher_type, gle.voucher_no), [])
|
||||||
@@ -288,12 +277,12 @@ class PartyLedgerSummaryReport(object):
|
|||||||
has_irrelevant_entry = False
|
has_irrelevant_entry = False
|
||||||
|
|
||||||
for gle in voucher_gl_entries:
|
for gle in voucher_gl_entries:
|
||||||
if gle.account == self.round_off_account:
|
if gle.account == round_off_account:
|
||||||
continue
|
continue
|
||||||
elif gle.party:
|
elif gle.party:
|
||||||
parties.setdefault(gle.party, 0)
|
parties.setdefault(gle.party, 0)
|
||||||
parties[gle.party] += gle.get(reverse_dr_or_cr) - gle.get(invoice_dr_or_cr)
|
parties[gle.party] += gle.get(reverse_dr_or_cr) - gle.get(invoice_dr_or_cr)
|
||||||
elif frappe.get_cached_value("Account", gle.account, "root_type") == income_or_expense:
|
elif frappe.get_cached_value("Account", gle.account, "account_type") == income_or_expense:
|
||||||
accounts.setdefault(gle.account, 0)
|
accounts.setdefault(gle.account, 0)
|
||||||
accounts[gle.account] += gle.get(invoice_dr_or_cr) - gle.get(reverse_dr_or_cr)
|
accounts[gle.account] += gle.get(invoice_dr_or_cr) - gle.get(reverse_dr_or_cr)
|
||||||
else:
|
else:
|
||||||
@@ -303,11 +292,13 @@ class PartyLedgerSummaryReport(object):
|
|||||||
if len(parties) == 1:
|
if len(parties) == 1:
|
||||||
party = parties.keys()[0]
|
party = parties.keys()[0]
|
||||||
for account, amount in iteritems(accounts):
|
for account, amount in iteritems(accounts):
|
||||||
|
self.party_adjustment_accounts.add(account)
|
||||||
self.party_adjustment_details.setdefault(party, {})
|
self.party_adjustment_details.setdefault(party, {})
|
||||||
self.party_adjustment_details[party].setdefault(account, 0)
|
self.party_adjustment_details[party].setdefault(account, 0)
|
||||||
self.party_adjustment_details[party][account] += amount
|
self.party_adjustment_details[party][account] += amount
|
||||||
elif len(accounts) == 1 and not has_irrelevant_entry:
|
elif len(accounts) == 1 and not has_irrelevant_entry:
|
||||||
account = accounts.keys()[0]
|
account = accounts.keys()[0]
|
||||||
|
self.party_adjustment_accounts.add(account)
|
||||||
for party, amount in iteritems(parties):
|
for party, amount in iteritems(parties):
|
||||||
self.party_adjustment_details.setdefault(party, {})
|
self.party_adjustment_details.setdefault(party, {})
|
||||||
self.party_adjustment_details[party].setdefault(account, 0)
|
self.party_adjustment_details[party].setdefault(account, 0)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
height: 37px;
|
height: 37px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% var letterhead= filters.letter_head || (frappe.get_doc(":Company", filters.company) && frappe.get_doc(":Company", filters.company).default_letter_head) || frappe.defaults.get_default("letter_head"); %}
|
{% var letterhead= filters.letter_head || (frappe.get_doc(":Company", filters.company) && frappe.get_doc(":Company", filters.company).default_letter_head) %}
|
||||||
{% if(letterhead) { %}
|
{% if(letterhead) { %}
|
||||||
<div style="margin-bottom: 7px;" class="text-center">
|
<div style="margin-bottom: 7px;" class="text-center">
|
||||||
{%= frappe.boot.letter_heads[letterhead].header %}
|
{%= frappe.boot.letter_heads[letterhead].header %}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ def get_label(periodicity, from_date, to_date):
|
|||||||
def get_data(
|
def get_data(
|
||||||
company, root_type, balance_must_be, period_list, filters=None,
|
company, root_type, balance_must_be, period_list, filters=None,
|
||||||
accumulated_values=1, only_current_fiscal_year=True, ignore_closing_entries=False,
|
accumulated_values=1, only_current_fiscal_year=True, ignore_closing_entries=False,
|
||||||
ignore_accumulated_values_for_fy=False):
|
ignore_accumulated_values_for_fy=False , total = True):
|
||||||
|
|
||||||
accounts = get_accounts(company, root_type)
|
accounts = get_accounts(company, root_type)
|
||||||
if not accounts:
|
if not accounts:
|
||||||
@@ -154,7 +154,7 @@ def get_data(
|
|||||||
out = prepare_data(accounts, balance_must_be, period_list, company_currency)
|
out = prepare_data(accounts, balance_must_be, period_list, company_currency)
|
||||||
out = filter_out_zero_value_rows(out, parent_children_map)
|
out = filter_out_zero_value_rows(out, parent_children_map)
|
||||||
|
|
||||||
if out:
|
if out and total:
|
||||||
add_total_row(out, root_type, balance_must_be, period_list, company_currency)
|
add_total_row(out, root_type, balance_must_be, period_list, company_currency)
|
||||||
|
|
||||||
return out
|
return out
|
||||||
@@ -218,6 +218,9 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
|
|||||||
"year_start_date": year_start_date,
|
"year_start_date": year_start_date,
|
||||||
"year_end_date": year_end_date,
|
"year_end_date": year_end_date,
|
||||||
"currency": company_currency,
|
"currency": company_currency,
|
||||||
|
"include_in_gross": d.include_in_gross,
|
||||||
|
"account_type": d.account_type,
|
||||||
|
"is_group": d.is_group,
|
||||||
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1),
|
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1),
|
||||||
"account_name": ('%s - %s' %(_(d.account_number), _(d.account_name))
|
"account_name": ('%s - %s' %(_(d.account_number), _(d.account_name))
|
||||||
if d.account_number else _(d.account_name))
|
if d.account_number else _(d.account_name))
|
||||||
@@ -270,7 +273,7 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency
|
|||||||
for period in period_list:
|
for period in period_list:
|
||||||
total_row.setdefault(period.key, 0.0)
|
total_row.setdefault(period.key, 0.0)
|
||||||
total_row[period.key] += row.get(period.key, 0.0)
|
total_row[period.key] += row.get(period.key, 0.0)
|
||||||
row[period.key] = 0.0
|
row[period.key] = row.get(period.key, 0.0)
|
||||||
|
|
||||||
total_row.setdefault("total", 0.0)
|
total_row.setdefault("total", 0.0)
|
||||||
total_row["total"] += flt(row["total"])
|
total_row["total"] += flt(row["total"])
|
||||||
@@ -285,7 +288,7 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency
|
|||||||
|
|
||||||
def get_accounts(company, root_type):
|
def get_accounts(company, root_type):
|
||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
select name, account_number, parent_account, lft, rgt, root_type, report_type, account_name
|
select name, account_number, parent_account, lft, rgt, root_type, report_type, account_name, include_in_gross, account_type, is_group, lft, rgt
|
||||||
from `tabAccount`
|
from `tabAccount`
|
||||||
where company=%s and root_type=%s order by lft""", (company, root_type), as_dict=True)
|
where company=%s and root_type=%s order by lft""", (company, root_type), as_dict=True)
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ def validate_filters(filters, account_details):
|
|||||||
frappe.throw(_("Can not filter based on Account, if grouped by Account"))
|
frappe.throw(_("Can not filter based on Account, if grouped by Account"))
|
||||||
|
|
||||||
if (filters.get("voucher_no")
|
if (filters.get("voucher_no")
|
||||||
and filters.get("group_by") in [_('Group by Voucher'), _('Group by Voucher (Consolidated)')]):
|
and filters.get("group_by") in [_('Group by Voucher')]):
|
||||||
frappe.throw(_("Can not filter based on Voucher No, if grouped by Voucher"))
|
frappe.throw(_("Can not filter based on Voucher No, if grouped by Voucher"))
|
||||||
|
|
||||||
if filters.from_date > filters.to_date:
|
if filters.from_date > filters.to_date:
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{% include "accounts/report/financial_statements.html" %}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
frappe.query_reports["Gross and Net Profit Report"] = {
|
||||||
|
"filters": [
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
||||||
|
frappe.query_reports["Gross and Net Profit Report"] = $.extend({},
|
||||||
|
erpnext.financial_statements);
|
||||||
|
|
||||||
|
frappe.query_reports["Gross and Net Profit Report"]["filters"].push(
|
||||||
|
{
|
||||||
|
"fieldname":"project",
|
||||||
|
"label": __("Project"),
|
||||||
|
"fieldtype": "MultiSelect",
|
||||||
|
get_data: function() {
|
||||||
|
var projects = frappe.query_report.get_filter_value("project") || "";
|
||||||
|
|
||||||
|
const values = projects.split(/\s*,\s*/).filter(d => d);
|
||||||
|
const txt = projects.match(/[^,\s*]*$/)[0] || '';
|
||||||
|
let data = [];
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
type: "GET",
|
||||||
|
method:'frappe.desk.search.search_link',
|
||||||
|
async: false,
|
||||||
|
no_spinner: true,
|
||||||
|
args: {
|
||||||
|
doctype: "Project",
|
||||||
|
txt: txt,
|
||||||
|
filters: {
|
||||||
|
"name": ["not in", values]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
data = r.results;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "accumulated_values",
|
||||||
|
"label": __("Accumulated Values"),
|
||||||
|
"fieldtype": "Check"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"add_total_row": 0,
|
||||||
|
"creation": "2019-02-08 10:58:55.763090",
|
||||||
|
"disable_prepared_report": 0,
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"modified": "2019-02-08 10:58:55.763090",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Gross and Net Profit Report",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"prepared_report": 0,
|
||||||
|
"ref_doctype": "GL Entry",
|
||||||
|
"report_name": "Gross and Net Profit Report",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Accounts User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Accounts Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Auditor"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import flt
|
||||||
|
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
|
||||||
|
import copy
|
||||||
|
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
||||||
|
filters.periodicity, filters.accumulated_values, filters.company)
|
||||||
|
|
||||||
|
columns, data = [], []
|
||||||
|
|
||||||
|
income = get_data(filters.company, "Income", "Credit", period_list, filters = filters,
|
||||||
|
accumulated_values=filters.accumulated_values,
|
||||||
|
ignore_closing_entries=True, ignore_accumulated_values_for_fy= True, total= False)
|
||||||
|
|
||||||
|
expense = get_data(filters.company, "Expense", "Debit", period_list, filters=filters,
|
||||||
|
accumulated_values=filters.accumulated_values,
|
||||||
|
ignore_closing_entries=True, ignore_accumulated_values_for_fy= True, total= False)
|
||||||
|
|
||||||
|
columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company)
|
||||||
|
|
||||||
|
|
||||||
|
gross_income = get_revenue(income, period_list)
|
||||||
|
|
||||||
|
gross_expense = get_revenue(expense, period_list)
|
||||||
|
|
||||||
|
if(len(gross_income)==0 and len(gross_expense)== 0):
|
||||||
|
data.append({"account_name": "'" + _("Nothing is included in gross") + "'",
|
||||||
|
"account": "'" + _("Nothing is included in gross") + "'"})
|
||||||
|
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
data.append({"account_name": "'" + _("Included in Gross Profit") + "'",
|
||||||
|
"account": "'" + _("Included in Gross Profit") + "'"})
|
||||||
|
|
||||||
|
data.append({})
|
||||||
|
data.extend(gross_income or [])
|
||||||
|
|
||||||
|
data.append({})
|
||||||
|
data.extend(gross_expense or [])
|
||||||
|
|
||||||
|
data.append({})
|
||||||
|
gross_profit = get_profit(gross_income, gross_expense, period_list, filters.company, 'Gross Profit',filters.presentation_currency)
|
||||||
|
data.append(gross_profit)
|
||||||
|
|
||||||
|
non_gross_income = get_revenue(income, period_list, 0)
|
||||||
|
data.append({})
|
||||||
|
data.extend(non_gross_income or [])
|
||||||
|
|
||||||
|
non_gross_expense = get_revenue(expense, period_list, 0)
|
||||||
|
data.append({})
|
||||||
|
data.extend(non_gross_expense or [])
|
||||||
|
|
||||||
|
net_profit = get_net_profit(non_gross_income, gross_income, gross_expense, non_gross_expense, period_list, filters.company,filters.presentation_currency)
|
||||||
|
data.append({})
|
||||||
|
data.append(net_profit)
|
||||||
|
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
def get_revenue(data, period_list, include_in_gross=1):
|
||||||
|
revenue = [item for item in data if item['include_in_gross']==include_in_gross or item['is_group']==1]
|
||||||
|
|
||||||
|
data_to_be_removed =True
|
||||||
|
while data_to_be_removed:
|
||||||
|
revenue, data_to_be_removed = remove_parent_with_no_child(revenue, period_list)
|
||||||
|
revenue = adjust_account(revenue, period_list)
|
||||||
|
return copy.deepcopy(revenue)
|
||||||
|
|
||||||
|
def remove_parent_with_no_child(data, period_list):
|
||||||
|
data_to_be_removed = False
|
||||||
|
for parent in data:
|
||||||
|
if 'is_group' in parent and parent.get("is_group") == 1:
|
||||||
|
have_child = False
|
||||||
|
for child in data:
|
||||||
|
if 'parent_account' in child and child.get("parent_account") == parent.get("account"):
|
||||||
|
have_child = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not have_child:
|
||||||
|
data_to_be_removed = True
|
||||||
|
data.remove(parent)
|
||||||
|
|
||||||
|
return data, data_to_be_removed
|
||||||
|
|
||||||
|
def adjust_account(data, period_list, consolidated= False):
|
||||||
|
leaf_nodes = [item for item in data if item['is_group'] == 0]
|
||||||
|
totals = {}
|
||||||
|
for node in leaf_nodes:
|
||||||
|
set_total(node, node["total"], data, totals)
|
||||||
|
for d in data:
|
||||||
|
for period in period_list:
|
||||||
|
key = period if consolidated else period.key
|
||||||
|
d[key] = totals[d["account"]]
|
||||||
|
d['total'] = totals[d["account"]]
|
||||||
|
return data
|
||||||
|
|
||||||
|
def set_total(node, value, complete_list, totals):
|
||||||
|
if not totals.get(node['account']):
|
||||||
|
totals[node["account"]] = 0
|
||||||
|
totals[node["account"]] += value
|
||||||
|
|
||||||
|
parent = node['parent_account']
|
||||||
|
if not parent == '':
|
||||||
|
return set_total(next(item for item in complete_list if item['account'] == parent), value, complete_list, totals)
|
||||||
|
|
||||||
|
|
||||||
|
def get_profit(gross_income, gross_expense, period_list, company, profit_type, currency=None, consolidated=False):
|
||||||
|
|
||||||
|
profit_loss = {
|
||||||
|
"account_name": "'" + _(profit_type) + "'",
|
||||||
|
"account": "'" + _(profit_type) + "'",
|
||||||
|
"warn_if_negative": True,
|
||||||
|
"currency": currency or frappe.get_cached_value('Company', company, "default_currency")
|
||||||
|
}
|
||||||
|
|
||||||
|
has_value = False
|
||||||
|
|
||||||
|
for period in period_list:
|
||||||
|
key = period if consolidated else period.key
|
||||||
|
profit_loss[key] = flt(gross_income[0].get(key, 0)) - flt(gross_expense[0].get(key, 0))
|
||||||
|
|
||||||
|
if profit_loss[key]:
|
||||||
|
has_value=True
|
||||||
|
|
||||||
|
if has_value:
|
||||||
|
return profit_loss
|
||||||
|
|
||||||
|
def get_net_profit(non_gross_income, gross_income, gross_expense, non_gross_expense, period_list, company, currency=None, consolidated=False):
|
||||||
|
profit_loss = {
|
||||||
|
"account_name": "'" + _("Net Profit") + "'",
|
||||||
|
"account": "'" + _("Net Profit") + "'",
|
||||||
|
"warn_if_negative": True,
|
||||||
|
"currency": currency or frappe.get_cached_value('Company', company, "default_currency")
|
||||||
|
}
|
||||||
|
|
||||||
|
has_value = False
|
||||||
|
|
||||||
|
for period in period_list:
|
||||||
|
key = period if consolidated else period.key
|
||||||
|
total_income = flt(gross_income[0].get(key, 0)) + flt(non_gross_income[0].get(key, 0))
|
||||||
|
total_expense = flt(gross_expense[0].get(key, 0)) + flt(non_gross_expense[0].get(key, 0))
|
||||||
|
profit_loss[key] = flt(total_income) - flt(total_expense)
|
||||||
|
|
||||||
|
if profit_loss[key]:
|
||||||
|
has_value=True
|
||||||
|
|
||||||
|
if has_value:
|
||||||
|
return profit_loss
|
||||||
@@ -6,7 +6,7 @@ import frappe
|
|||||||
from frappe import _, scrub
|
from frappe import _, scrub
|
||||||
from erpnext.stock.utils import get_incoming_rate
|
from erpnext.stock.utils import get_incoming_rate
|
||||||
from erpnext.controllers.queries import get_match_cond
|
from erpnext.controllers.queries import get_match_cond
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt, cint
|
||||||
|
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
@@ -106,11 +106,14 @@ class GrossProfitGenerator(object):
|
|||||||
self.grouped = {}
|
self.grouped = {}
|
||||||
self.grouped_data = []
|
self.grouped_data = []
|
||||||
|
|
||||||
|
self.currency_precision = cint(frappe.db.get_default("currency_precision")) or 3
|
||||||
|
self.float_precision = cint(frappe.db.get_default("float_precision")) or 2
|
||||||
|
|
||||||
for row in self.si_list:
|
for row in self.si_list:
|
||||||
if self.skip_row(row, self.product_bundles):
|
if self.skip_row(row, self.product_bundles):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
row.base_amount = flt(row.base_net_amount)
|
row.base_amount = flt(row.base_net_amount, self.currency_precision)
|
||||||
|
|
||||||
product_bundles = []
|
product_bundles = []
|
||||||
if row.update_stock:
|
if row.update_stock:
|
||||||
@@ -122,22 +125,23 @@ class GrossProfitGenerator(object):
|
|||||||
|
|
||||||
# get buying amount
|
# get buying amount
|
||||||
if row.item_code in product_bundles:
|
if row.item_code in product_bundles:
|
||||||
row.buying_amount = self.get_buying_amount_from_product_bundle(row,
|
row.buying_amount = flt(self.get_buying_amount_from_product_bundle(row,
|
||||||
product_bundles[row.item_code])
|
product_bundles[row.item_code]), self.currency_precision)
|
||||||
else:
|
else:
|
||||||
row.buying_amount = self.get_buying_amount(row, row.item_code)
|
row.buying_amount = flt(self.get_buying_amount(row, row.item_code),
|
||||||
|
self.currency_precision)
|
||||||
|
|
||||||
# get buying rate
|
# get buying rate
|
||||||
if row.qty:
|
if row.qty:
|
||||||
row.buying_rate = row.buying_amount / row.qty
|
row.buying_rate = flt(row.buying_amount / row.qty, self.float_precision)
|
||||||
row.base_rate = row.base_amount / row.qty
|
row.base_rate = flt(row.base_amount / row.qty, self.float_precision)
|
||||||
else:
|
else:
|
||||||
row.buying_rate, row.base_rate = 0.0, 0.0
|
row.buying_rate, row.base_rate = 0.0, 0.0
|
||||||
|
|
||||||
# calculate gross profit
|
# calculate gross profit
|
||||||
row.gross_profit = row.base_amount - row.buying_amount
|
row.gross_profit = flt(row.base_amount - row.buying_amount, self.currency_precision)
|
||||||
if row.base_amount:
|
if row.base_amount:
|
||||||
row.gross_profit_percent = (row.gross_profit / row.base_amount) * 100.0
|
row.gross_profit_percent = flt((row.gross_profit / row.base_amount) * 100.0, self.currency_precision)
|
||||||
else:
|
else:
|
||||||
row.gross_profit_percent = 0.0
|
row.gross_profit_percent = 0.0
|
||||||
|
|
||||||
@@ -156,8 +160,8 @@ class GrossProfitGenerator(object):
|
|||||||
new_row = row
|
new_row = row
|
||||||
else:
|
else:
|
||||||
new_row.qty += row.qty
|
new_row.qty += row.qty
|
||||||
new_row.buying_amount += row.buying_amount
|
new_row.buying_amount += flt(row.buying_amount, self.currency_precision)
|
||||||
new_row.base_amount += row.base_amount
|
new_row.base_amount += flt(row.base_amount, self.currency_precision)
|
||||||
new_row = self.set_average_rate(new_row)
|
new_row = self.set_average_rate(new_row)
|
||||||
self.grouped_data.append(new_row)
|
self.grouped_data.append(new_row)
|
||||||
else:
|
else:
|
||||||
@@ -167,18 +171,19 @@ class GrossProfitGenerator(object):
|
|||||||
returned_item_rows = self.returned_invoices[row.parent][row.item_code]
|
returned_item_rows = self.returned_invoices[row.parent][row.item_code]
|
||||||
for returned_item_row in returned_item_rows:
|
for returned_item_row in returned_item_rows:
|
||||||
row.qty += returned_item_row.qty
|
row.qty += returned_item_row.qty
|
||||||
row.base_amount += returned_item_row.base_amount
|
row.base_amount += flt(returned_item_row.base_amount, self.currency_precision)
|
||||||
row.buying_amount = row.qty * row.buying_rate
|
row.buying_amount = flt(row.qty * row.buying_rate, self.currency_precision)
|
||||||
if row.qty or row.base_amount:
|
if row.qty or row.base_amount:
|
||||||
row = self.set_average_rate(row)
|
row = self.set_average_rate(row)
|
||||||
self.grouped_data.append(row)
|
self.grouped_data.append(row)
|
||||||
|
|
||||||
def set_average_rate(self, new_row):
|
def set_average_rate(self, new_row):
|
||||||
new_row.gross_profit = new_row.base_amount - new_row.buying_amount
|
new_row.gross_profit = flt(new_row.base_amount - new_row.buying_amount, self.currency_precision)
|
||||||
new_row.gross_profit_percent = ((new_row.gross_profit / new_row.base_amount) * 100.0) \
|
new_row.gross_profit_percent = flt(((new_row.gross_profit / new_row.base_amount) * 100.0), self.currency_precision) \
|
||||||
if new_row.base_amount else 0
|
if new_row.base_amount else 0
|
||||||
new_row.buying_rate = (new_row.buying_amount / new_row.qty) if new_row.qty else 0
|
new_row.buying_rate = flt(new_row.buying_amount / new_row.qty, self.float_precision) if new_row.qty else 0
|
||||||
new_row.base_rate = (new_row.base_amount / new_row.qty) if new_row.qty else 0
|
new_row.base_rate = flt(new_row.base_amount / new_row.qty, self.float_precision) if new_row.qty else 0
|
||||||
|
|
||||||
return new_row
|
return new_row
|
||||||
|
|
||||||
def get_returned_invoice_items(self):
|
def get_returned_invoice_items(self):
|
||||||
@@ -211,7 +216,7 @@ class GrossProfitGenerator(object):
|
|||||||
if packed_item.get("parent_detail_docname")==row.item_row:
|
if packed_item.get("parent_detail_docname")==row.item_row:
|
||||||
buying_amount += self.get_buying_amount(row, packed_item.item_code)
|
buying_amount += self.get_buying_amount(row, packed_item.item_code)
|
||||||
|
|
||||||
return buying_amount
|
return flt(buying_amount, self.currency_precision)
|
||||||
|
|
||||||
def get_buying_amount(self, row, item_code):
|
def get_buying_amount(self, row, item_code):
|
||||||
# IMP NOTE
|
# IMP NOTE
|
||||||
|
|||||||
@@ -54,8 +54,10 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom
|
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom
|
||||||
]
|
]
|
||||||
|
|
||||||
row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount] \
|
if d.stock_uom != d.uom and d.stock_qty:
|
||||||
if d.stock_uom != d.uom and d.stock_qty != 0 else [d.base_net_rate, d.base_net_amount]
|
row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount]
|
||||||
|
else:
|
||||||
|
row += [d.base_net_rate, d.base_net_amount]
|
||||||
|
|
||||||
total_tax = 0
|
total_tax = 0
|
||||||
for tax in tax_columns:
|
for tax in tax_columns:
|
||||||
|
|||||||
@@ -133,6 +133,13 @@ def get_columns(filters):
|
|||||||
"options": filters.get("based_on"),
|
"options": filters.get("based_on"),
|
||||||
"width": 300
|
"width": 300
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "currency",
|
||||||
|
"label": _("Currency"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Currency",
|
||||||
|
"hidden": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "income",
|
"fieldname": "income",
|
||||||
"label": _("Income"),
|
"label": _("Income"),
|
||||||
@@ -153,13 +160,6 @@ def get_columns(filters):
|
|||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"options": "currency",
|
"options": "currency",
|
||||||
"width": 120
|
"width": 120
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "currency",
|
|
||||||
"label": _("Currency"),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "Currency",
|
|
||||||
"hidden": 1
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
total_tax += tax_amount
|
total_tax += tax_amount
|
||||||
row.append(tax_amount)
|
row.append(tax_amount)
|
||||||
|
|
||||||
# total tax, grand total, outstanding amount & rounded total
|
# total tax, grand total, rounded total & outstanding amount
|
||||||
row += [total_tax, inv.base_grand_total, flt(inv.base_grand_total, 2), inv.outstanding_amount]
|
row += [total_tax, inv.base_grand_total, flt(inv.base_grand_total, 0), inv.outstanding_amount]
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ frappe.query_reports["Supplier Ledger Summary"] = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"party",
|
"fieldname":"party",
|
||||||
"label": __("Customer"),
|
"label": __("Supplier"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Customer",
|
"options": "Supplier",
|
||||||
on_change: () => {
|
on_change: () => {
|
||||||
var party = frappe.query_report.get_filter_value('party');
|
var party = frappe.query_report.get_filter_value('party');
|
||||||
if (party) {
|
if (party) {
|
||||||
|
|||||||
@@ -55,12 +55,15 @@ def get_result(filters):
|
|||||||
supplier = supplier_map[d]
|
supplier = supplier_map[d]
|
||||||
|
|
||||||
tds_doc = tds_docs[supplier.tax_withholding_category]
|
tds_doc = tds_docs[supplier.tax_withholding_category]
|
||||||
account = [i.account for i in tds_doc.accounts if i.company == filters.company][0]
|
account_list = [i.account for i in tds_doc.accounts if i.company == filters.company]
|
||||||
|
|
||||||
|
if account_list:
|
||||||
|
account = account_list[0]
|
||||||
|
|
||||||
for k in gle_map[d]:
|
for k in gle_map[d]:
|
||||||
if k.party == supplier_map[d] and k.credit > 0:
|
if k.party == supplier_map[d] and k.credit > 0:
|
||||||
total_amount_credited += k.credit
|
total_amount_credited += k.credit
|
||||||
elif k.account == account and k.credit > 0:
|
elif account_list and k.account == account and k.credit > 0:
|
||||||
tds_deducted = k.credit
|
tds_deducted = k.credit
|
||||||
total_amount_credited += k.credit
|
total_amount_credited += k.credit
|
||||||
|
|
||||||
|
|||||||
@@ -544,14 +544,14 @@ def fix_total_debit_credit():
|
|||||||
(dr_or_cr, dr_or_cr, '%s', '%s', '%s', dr_or_cr),
|
(dr_or_cr, dr_or_cr, '%s', '%s', '%s', dr_or_cr),
|
||||||
(d.diff, d.voucher_type, d.voucher_no))
|
(d.diff, d.voucher_type, d.voucher_no))
|
||||||
|
|
||||||
def get_stock_and_account_difference(account_list=None, posting_date=None):
|
def get_stock_and_account_difference(account_list=None, posting_date=None, company=None):
|
||||||
from erpnext.stock.utils import get_stock_value_on
|
from erpnext.stock.utils import get_stock_value_on
|
||||||
from erpnext.stock import get_warehouse_account_map
|
from erpnext.stock import get_warehouse_account_map
|
||||||
|
|
||||||
if not posting_date: posting_date = nowdate()
|
if not posting_date: posting_date = nowdate()
|
||||||
|
|
||||||
difference = {}
|
difference = {}
|
||||||
warehouse_account = get_warehouse_account_map()
|
warehouse_account = get_warehouse_account_map(company)
|
||||||
|
|
||||||
for warehouse, account_data in iteritems(warehouse_account):
|
for warehouse, account_data in iteritems(warehouse_account):
|
||||||
if account_data.get('account') in account_list:
|
if account_data.get('account') in account_list:
|
||||||
|
|||||||
@@ -206,12 +206,10 @@ frappe.ui.form.on('Asset', {
|
|||||||
erpnext.asset.set_accululated_depreciation(frm);
|
erpnext.asset.set_accululated_depreciation(frm);
|
||||||
},
|
},
|
||||||
|
|
||||||
depreciation_method: function(frm) {
|
|
||||||
frm.events.make_schedules_editable(frm);
|
|
||||||
},
|
|
||||||
|
|
||||||
make_schedules_editable: function(frm) {
|
make_schedules_editable: function(frm) {
|
||||||
var is_editable = frm.doc.depreciation_method==="Manual" ? true : false;
|
var is_editable = frm.doc.finance_books.filter(d => d.depreciation_method == "Manual").length > 0
|
||||||
|
? true : false;
|
||||||
|
|
||||||
frm.toggle_enable("schedules", is_editable);
|
frm.toggle_enable("schedules", is_editable);
|
||||||
frm.fields_dict["schedules"].grid.toggle_enable("schedule_date", is_editable);
|
frm.fields_dict["schedules"].grid.toggle_enable("schedule_date", is_editable);
|
||||||
frm.fields_dict["schedules"].grid.toggle_enable("depreciation_amount", is_editable);
|
frm.fields_dict["schedules"].grid.toggle_enable("depreciation_amount", is_editable);
|
||||||
@@ -296,6 +294,44 @@ frappe.ui.form.on('Asset', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation);
|
frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation);
|
||||||
|
},
|
||||||
|
|
||||||
|
set_depreciation_rate: function(frm, row) {
|
||||||
|
if (row.total_number_of_depreciations && row.frequency_of_depreciation) {
|
||||||
|
frappe.call({
|
||||||
|
method: "get_depreciation_rate",
|
||||||
|
doc: frm.doc,
|
||||||
|
args: row,
|
||||||
|
callback: function(r) {
|
||||||
|
if (r.message) {
|
||||||
|
frappe.model.set_value(row.doctype, row.name, "rate_of_depreciation", r.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on('Asset Finance Book', {
|
||||||
|
depreciation_method: function(frm, cdt, cdn) {
|
||||||
|
const row = locals[cdt][cdn];
|
||||||
|
frm.events.set_depreciation_rate(frm, row);
|
||||||
|
frm.events.make_schedules_editable(frm);
|
||||||
|
},
|
||||||
|
|
||||||
|
expected_value_after_useful_life: function(frm, cdt, cdn) {
|
||||||
|
const row = locals[cdt][cdn];
|
||||||
|
frm.events.set_depreciation_rate(frm, row);
|
||||||
|
},
|
||||||
|
|
||||||
|
frequency_of_depreciation: function(frm, cdt, cdn) {
|
||||||
|
const row = locals[cdt][cdn];
|
||||||
|
frm.events.set_depreciation_rate(frm, row);
|
||||||
|
},
|
||||||
|
|
||||||
|
total_number_of_depreciations: function(frm, cdt, cdn) {
|
||||||
|
const row = locals[cdt][cdn];
|
||||||
|
frm.events.set_depreciation_rate(frm, row);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
# 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, erpnext
|
import frappe, erpnext, math, json
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
from six import string_types
|
||||||
from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff
|
from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
|
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
|
||||||
@@ -20,6 +21,7 @@ class Asset(AccountsController):
|
|||||||
self.validate_item()
|
self.validate_item()
|
||||||
self.set_missing_values()
|
self.set_missing_values()
|
||||||
if self.calculate_depreciation:
|
if self.calculate_depreciation:
|
||||||
|
self.set_depreciation_rate()
|
||||||
self.make_depreciation_schedule()
|
self.make_depreciation_schedule()
|
||||||
self.set_accumulated_depreciation()
|
self.set_accumulated_depreciation()
|
||||||
else:
|
else:
|
||||||
@@ -33,7 +35,7 @@ class Asset(AccountsController):
|
|||||||
self.validate_in_use_date()
|
self.validate_in_use_date()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
self.update_stock_movement()
|
self.update_stock_movement()
|
||||||
if not self.booked_fixed_asset:
|
if not self.booked_fixed_asset and not is_cwip_accounting_disabled():
|
||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
@@ -71,14 +73,15 @@ class Asset(AccountsController):
|
|||||||
if not flt(self.gross_purchase_amount):
|
if not flt(self.gross_purchase_amount):
|
||||||
frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
|
frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
|
||||||
|
|
||||||
if not self.is_existing_asset and not (self.purchase_receipt or self.purchase_invoice):
|
if not is_cwip_accounting_disabled():
|
||||||
frappe.throw(_("Please create purchase receipt or purchase invoice for the item {0}").
|
if not self.is_existing_asset and not (self.purchase_receipt or self.purchase_invoice):
|
||||||
format(self.item_code))
|
frappe.throw(_("Please create purchase receipt or purchase invoice for the item {0}").
|
||||||
|
format(self.item_code))
|
||||||
|
|
||||||
if (not self.purchase_receipt and self.purchase_invoice
|
if (not self.purchase_receipt and self.purchase_invoice
|
||||||
and not frappe.db.get_value('Purchase Invoice', self.purchase_invoice, 'update_stock')):
|
and not frappe.db.get_value('Purchase Invoice', self.purchase_invoice, 'update_stock')):
|
||||||
frappe.throw(_("Update stock must be enable for the purchase invoice {0}").
|
frappe.throw(_("Update stock must be enable for the purchase invoice {0}").
|
||||||
format(self.purchase_invoice))
|
format(self.purchase_invoice))
|
||||||
|
|
||||||
if not self.calculate_depreciation:
|
if not self.calculate_depreciation:
|
||||||
return
|
return
|
||||||
@@ -88,17 +91,22 @@ class Asset(AccountsController):
|
|||||||
if self.is_existing_asset:
|
if self.is_existing_asset:
|
||||||
return
|
return
|
||||||
|
|
||||||
date = nowdate()
|
|
||||||
docname = self.purchase_receipt or self.purchase_invoice
|
docname = self.purchase_receipt or self.purchase_invoice
|
||||||
if docname:
|
if docname:
|
||||||
doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
|
doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
|
||||||
date = frappe.db.get_value(doctype, docname, 'posting_date')
|
date = frappe.db.get_value(doctype, docname, 'posting_date')
|
||||||
|
|
||||||
if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(date):
|
if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(self.purchase_date):
|
||||||
frappe.throw(_("Available-for-use Date should be after purchase date"))
|
frappe.throw(_("Available-for-use Date should be after purchase date"))
|
||||||
|
|
||||||
|
def set_depreciation_rate(self):
|
||||||
|
for d in self.get("finance_books"):
|
||||||
|
d.rate_of_depreciation = self.get_depreciation_rate(d)
|
||||||
|
|
||||||
def make_depreciation_schedule(self):
|
def make_depreciation_schedule(self):
|
||||||
if self.depreciation_method != 'Manual':
|
depreciation_method = [d.depreciation_method for d in self.finance_books]
|
||||||
|
|
||||||
|
if 'Manual' not in depreciation_method:
|
||||||
self.schedules = []
|
self.schedules = []
|
||||||
|
|
||||||
if not self.get("schedules") and self.available_for_use_date:
|
if not self.get("schedules") and self.available_for_use_date:
|
||||||
@@ -253,14 +261,16 @@ class Asset(AccountsController):
|
|||||||
return flt(self.get('finance_books')[cint(idx)-1].value_after_depreciation)
|
return flt(self.get('finance_books')[cint(idx)-1].value_after_depreciation)
|
||||||
|
|
||||||
def get_depreciation_amount(self, depreciable_value, total_number_of_depreciations, row):
|
def get_depreciation_amount(self, depreciable_value, total_number_of_depreciations, row):
|
||||||
percentage_value = 100.0 if row.depreciation_method == 'Written Down Value' else 200.0
|
if row.depreciation_method in ["Straight Line", "Manual"]:
|
||||||
|
amt = (flt(self.gross_purchase_amount) - flt(row.expected_value_after_useful_life) -
|
||||||
|
flt(self.opening_accumulated_depreciation))
|
||||||
|
|
||||||
factor = percentage_value / total_number_of_depreciations
|
depreciation_amount = amt * row.rate_of_depreciation
|
||||||
depreciation_amount = flt(depreciable_value * factor / 100, 0)
|
else:
|
||||||
|
depreciation_amount = flt(depreciable_value) * (flt(row.rate_of_depreciation) / 100)
|
||||||
value_after_depreciation = flt(depreciable_value) - depreciation_amount
|
value_after_depreciation = flt(depreciable_value) - depreciation_amount
|
||||||
if value_after_depreciation < flt(row.expected_value_after_useful_life):
|
if value_after_depreciation < flt(row.expected_value_after_useful_life):
|
||||||
depreciation_amount = flt(depreciable_value) - flt(row.expected_value_after_useful_life)
|
depreciation_amount = flt(depreciable_value) - flt(row.expected_value_after_useful_life)
|
||||||
|
|
||||||
return depreciation_amount
|
return depreciation_amount
|
||||||
|
|
||||||
@@ -275,7 +285,7 @@ class Asset(AccountsController):
|
|||||||
flt(row.expected_value_after_useful_life)) / (cint(row.total_number_of_depreciations) -
|
flt(row.expected_value_after_useful_life)) / (cint(row.total_number_of_depreciations) -
|
||||||
cint(self.number_of_depreciations_booked)) * prorata_temporis
|
cint(self.number_of_depreciations_booked)) * prorata_temporis
|
||||||
else:
|
else:
|
||||||
depreciation_amount = self.get_depreciation_amount(depreciable_value, row)
|
depreciation_amount = self.get_depreciation_amount(depreciable_value, row.total_number_of_depreciations, row)
|
||||||
|
|
||||||
return depreciation_amount
|
return depreciation_amount
|
||||||
|
|
||||||
@@ -393,6 +403,32 @@ class Asset(AccountsController):
|
|||||||
make_gl_entries(gl_entries)
|
make_gl_entries(gl_entries)
|
||||||
self.db_set('booked_fixed_asset', 1)
|
self.db_set('booked_fixed_asset', 1)
|
||||||
|
|
||||||
|
def get_depreciation_rate(self, args):
|
||||||
|
if isinstance(args, string_types):
|
||||||
|
args = json.loads(args)
|
||||||
|
|
||||||
|
number_of_depreciations_booked = 0
|
||||||
|
if self.is_existing_asset:
|
||||||
|
number_of_depreciations_booked = self.number_of_depreciations_booked
|
||||||
|
|
||||||
|
float_precision = cint(frappe.db.get_default("float_precision")) or 2
|
||||||
|
tot_no_of_depreciation = flt(args.get("total_number_of_depreciations")) - flt(number_of_depreciations_booked)
|
||||||
|
|
||||||
|
if args.get("depreciation_method") in ["Straight Line", "Manual"]:
|
||||||
|
return 1.0 / tot_no_of_depreciation
|
||||||
|
|
||||||
|
if args.get("depreciation_method") == 'Double Declining Balance':
|
||||||
|
return 200.0 / args.get("total_number_of_depreciations")
|
||||||
|
|
||||||
|
if args.get("depreciation_method") == "Written Down Value" and not args.get("rate_of_depreciation"):
|
||||||
|
no_of_years = flt(args.get("total_number_of_depreciations") * flt(args.get("frequency_of_depreciation"))) / 12
|
||||||
|
value = flt(args.get("expected_value_after_useful_life")) / flt(self.gross_purchase_amount)
|
||||||
|
|
||||||
|
# square root of flt(salvage_value) / flt(asset_cost)
|
||||||
|
depreciation_rate = math.pow(value, 1.0/flt(no_of_years, 2))
|
||||||
|
|
||||||
|
return 100 * (1 - flt(depreciation_rate, float_precision))
|
||||||
|
|
||||||
def update_maintenance_status():
|
def update_maintenance_status():
|
||||||
assets = frappe.get_all('Asset', filters = {'docstatus': 1, 'maintenance_required': 1})
|
assets = frappe.get_all('Asset', filters = {'docstatus': 1, 'maintenance_required': 1})
|
||||||
|
|
||||||
@@ -404,6 +440,9 @@ def update_maintenance_status():
|
|||||||
asset.set_status('Out of Order')
|
asset.set_status('Out of Order')
|
||||||
|
|
||||||
def make_post_gl_entry():
|
def make_post_gl_entry():
|
||||||
|
if is_cwip_accounting_disabled():
|
||||||
|
return
|
||||||
|
|
||||||
assets = frappe.db.sql_list(""" select name from `tabAsset`
|
assets = frappe.db.sql_list(""" select name from `tabAsset`
|
||||||
where ifnull(booked_fixed_asset, 0) = 0 and available_for_use_date = %s""", nowdate())
|
where ifnull(booked_fixed_asset, 0) = 0 and available_for_use_date = %s""", nowdate())
|
||||||
|
|
||||||
@@ -476,7 +515,6 @@ def create_asset_adjustment(asset, asset_category, company):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def transfer_asset(args):
|
def transfer_asset(args):
|
||||||
import json
|
|
||||||
args = json.loads(args)
|
args = json.loads(args)
|
||||||
|
|
||||||
if args.get('serial_no'):
|
if args.get('serial_no'):
|
||||||
@@ -551,3 +589,6 @@ def make_journal_entry(asset_name):
|
|||||||
})
|
})
|
||||||
|
|
||||||
return je
|
return je
|
||||||
|
|
||||||
|
def is_cwip_accounting_disabled():
|
||||||
|
return cint(frappe.db.get_single_value("Asset Settings", "disable_cwip_accounting"))
|
||||||
|
|||||||
@@ -160,9 +160,9 @@ class TestAsset(unittest.TestCase):
|
|||||||
asset.save()
|
asset.save()
|
||||||
|
|
||||||
expected_schedules = [
|
expected_schedules = [
|
||||||
["2020-06-06", 66667.0, 66667.0],
|
["2020-06-06", 66666.67, 66666.67],
|
||||||
["2021-04-06", 22222.0, 88889.0],
|
["2021-04-06", 22222.22, 88888.89],
|
||||||
["2022-02-06", 1111.0, 90000.0]
|
["2022-02-06", 1111.11, 90000.0]
|
||||||
]
|
]
|
||||||
|
|
||||||
schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
|
schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
|
||||||
@@ -192,8 +192,8 @@ class TestAsset(unittest.TestCase):
|
|||||||
asset.save()
|
asset.save()
|
||||||
|
|
||||||
expected_schedules = [
|
expected_schedules = [
|
||||||
["2020-06-06", 33333.0, 83333.0],
|
["2020-06-06", 33333.33, 83333.33],
|
||||||
["2021-04-06", 6667.0, 90000.0]
|
["2021-04-06", 6666.67, 90000.0]
|
||||||
]
|
]
|
||||||
|
|
||||||
schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
|
schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
|
||||||
@@ -209,7 +209,7 @@ class TestAsset(unittest.TestCase):
|
|||||||
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
|
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
|
||||||
asset = frappe.get_doc('Asset', asset_name)
|
asset = frappe.get_doc('Asset', asset_name)
|
||||||
asset.calculate_depreciation = 1
|
asset.calculate_depreciation = 1
|
||||||
asset.purchase_date = '2020-06-06'
|
asset.purchase_date = '2020-01-30'
|
||||||
asset.is_existing_asset = 0
|
asset.is_existing_asset = 0
|
||||||
asset.available_for_use_date = "2020-01-30"
|
asset.available_for_use_date = "2020-01-30"
|
||||||
asset.append("finance_books", {
|
asset.append("finance_books", {
|
||||||
@@ -244,7 +244,7 @@ class TestAsset(unittest.TestCase):
|
|||||||
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
|
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
|
||||||
asset = frappe.get_doc('Asset', asset_name)
|
asset = frappe.get_doc('Asset', asset_name)
|
||||||
asset.calculate_depreciation = 1
|
asset.calculate_depreciation = 1
|
||||||
asset.purchase_date = '2020-06-06'
|
asset.purchase_date = '2020-01-30'
|
||||||
asset.available_for_use_date = "2020-01-30"
|
asset.available_for_use_date = "2020-01-30"
|
||||||
asset.append("finance_books", {
|
asset.append("finance_books", {
|
||||||
"expected_value_after_useful_life": 10000,
|
"expected_value_after_useful_life": 10000,
|
||||||
@@ -277,6 +277,37 @@ class TestAsset(unittest.TestCase):
|
|||||||
self.assertEqual(gle, expected_gle)
|
self.assertEqual(gle, expected_gle)
|
||||||
self.assertEqual(asset.get("value_after_depreciation"), 0)
|
self.assertEqual(asset.get("value_after_depreciation"), 0)
|
||||||
|
|
||||||
|
def test_depreciation_entry_for_wdv(self):
|
||||||
|
pr = make_purchase_receipt(item_code="Macbook Pro",
|
||||||
|
qty=1, rate=8000.0, location="Test Location")
|
||||||
|
|
||||||
|
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
|
||||||
|
asset = frappe.get_doc('Asset', asset_name)
|
||||||
|
asset.calculate_depreciation = 1
|
||||||
|
asset.available_for_use_date = '2030-06-06'
|
||||||
|
asset.purchase_date = '2030-06-06'
|
||||||
|
asset.append("finance_books", {
|
||||||
|
"expected_value_after_useful_life": 1000,
|
||||||
|
"depreciation_method": "Written Down Value",
|
||||||
|
"total_number_of_depreciations": 3,
|
||||||
|
"frequency_of_depreciation": 12,
|
||||||
|
"depreciation_start_date": "2030-12-31"
|
||||||
|
})
|
||||||
|
asset.save(ignore_permissions=True)
|
||||||
|
|
||||||
|
self.assertEqual(asset.finance_books[0].rate_of_depreciation, 50.0)
|
||||||
|
|
||||||
|
expected_schedules = [
|
||||||
|
["2030-12-31", 4000.0, 4000.0],
|
||||||
|
["2031-12-31", 2000.0, 6000.0],
|
||||||
|
["2032-12-31", 1000.0, 7000.0],
|
||||||
|
]
|
||||||
|
|
||||||
|
schedules = [[cstr(d.schedule_date), flt(d.depreciation_amount, 2), flt(d.accumulated_depreciation_amount, 2)]
|
||||||
|
for d in asset.get("schedules")]
|
||||||
|
|
||||||
|
self.assertEqual(schedules, expected_schedules)
|
||||||
|
|
||||||
def test_depreciation_entry_cancellation(self):
|
def test_depreciation_entry_cancellation(self):
|
||||||
pr = make_purchase_receipt(item_code="Macbook Pro",
|
pr = make_purchase_receipt(item_code="Macbook Pro",
|
||||||
qty=1, rate=100000.0, location="Test Location")
|
qty=1, rate=100000.0, location="Test Location")
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
@@ -14,11 +15,13 @@
|
|||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "",
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "finance_book",
|
"fieldname": "finance_book",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -42,14 +45,17 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "depreciation_method",
|
"fieldname": "depreciation_method",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -73,14 +79,17 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "total_number_of_depreciations",
|
"fieldname": "total_number_of_depreciations",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -103,14 +112,17 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_5",
|
"fieldname": "column_break_5",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -133,14 +145,17 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "frequency_of_depreciation",
|
"fieldname": "frequency_of_depreciation",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -163,15 +178,18 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval:parent.doctype == 'Asset'",
|
"depends_on": "eval:parent.doctype == 'Asset'",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "depreciation_start_date",
|
"fieldname": "depreciation_start_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -194,16 +212,19 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"depends_on": "eval:parent.doctype == 'Asset'",
|
"depends_on": "eval:parent.doctype == 'Asset'",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "expected_value_after_useful_life",
|
"fieldname": "expected_value_after_useful_life",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -227,14 +248,17 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "value_after_depreciation",
|
"fieldname": "value_after_depreciation",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
@@ -258,20 +282,54 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"depends_on": "eval:doc.depreciation_method == 'Written Down Value'",
|
||||||
|
"description": "In Percentage",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "rate_of_depreciation",
|
||||||
|
"fieldtype": "Percent",
|
||||||
|
"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": "Rate of Depreciation",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"has_web_view": 0,
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
"hide_toolbar": 0,
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
"in_create": 0,
|
||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-05-12 14:56:44.800046",
|
"modified": "2019-04-09 19:45:14.523488",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset Finance Book",
|
"name": "Asset Finance Book",
|
||||||
@@ -280,10 +338,10 @@
|
|||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
"show_name_in_global_search": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1,
|
"track_changes": 1,
|
||||||
"track_seen": 0
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
@@ -14,10 +15,12 @@
|
|||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "depreciation_options",
|
"fieldname": "depreciation_options",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -40,14 +43,17 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "schedule_based_on_fiscal_year",
|
"fieldname": "schedule_based_on_fiscal_year",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -70,10 +76,12 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -81,6 +89,7 @@
|
|||||||
"default": "360",
|
"default": "360",
|
||||||
"depends_on": "eval:doc.schedule_based_on_fiscal_year",
|
"depends_on": "eval:doc.schedule_based_on_fiscal_year",
|
||||||
"description": "This value is used for pro-rata temporis calculation",
|
"description": "This value is used for pro-rata temporis calculation",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "number_of_days_in_fiscal_year",
|
"fieldname": "number_of_days_in_fiscal_year",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -103,6 +112,40 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "disable_cwip_accounting",
|
||||||
|
"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": "Disable CWIP Accounting",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -116,7 +159,7 @@
|
|||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-01-05 10:10:39.803255",
|
"modified": "2019-03-08 10:44:41.924547",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset Settings",
|
"name": "Asset Settings",
|
||||||
@@ -125,7 +168,6 @@
|
|||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
"cancel": 0,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
@@ -145,7 +187,6 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
"cancel": 0,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
@@ -171,5 +212,6 @@
|
|||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1,
|
"track_changes": 1,
|
||||||
"track_seen": 0
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
}
|
}
|
||||||
@@ -379,7 +379,9 @@ def make_purchase_invoice(source_name, target_doc=None):
|
|||||||
def postprocess(source, target):
|
def postprocess(source, target):
|
||||||
set_missing_values(source, target)
|
set_missing_values(source, target)
|
||||||
#Get the advance paid Journal Entries in Purchase Invoice Advance
|
#Get the advance paid Journal Entries in Purchase Invoice Advance
|
||||||
target.set_advances()
|
|
||||||
|
if target.get("allocate_advances_automatically"):
|
||||||
|
target.set_advances()
|
||||||
|
|
||||||
def update_item(obj, target, source_parent):
|
def update_item(obj, target, source_parent):
|
||||||
target.amount = flt(obj.amount) - flt(obj.billed_amt)
|
target.amount = flt(obj.amount) - flt(obj.billed_amt)
|
||||||
@@ -388,9 +390,10 @@ def make_purchase_invoice(source_name, target_doc=None):
|
|||||||
|
|
||||||
item = get_item_defaults(target.item_code, source_parent.company)
|
item = get_item_defaults(target.item_code, source_parent.company)
|
||||||
item_group = get_item_group_defaults(target.item_code, source_parent.company)
|
item_group = get_item_group_defaults(target.item_code, source_parent.company)
|
||||||
target.cost_center = frappe.db.get_value("Project", obj.project, "cost_center") \
|
target.cost_center = (obj.cost_center
|
||||||
or item.get("buying_cost_center") \
|
or frappe.db.get_value("Project", obj.project, "cost_center")
|
||||||
or item_group.get("buying_cost_center")
|
or item.get("buying_cost_center")
|
||||||
|
or item_group.get("buying_cost_center"))
|
||||||
|
|
||||||
doc = get_mapped_doc("Purchase Order", source_name, {
|
doc = get_mapped_doc("Purchase Order", source_name, {
|
||||||
"Purchase Order": {
|
"Purchase Order": {
|
||||||
|
|||||||
@@ -325,7 +325,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",
|
||||||
|
|||||||
@@ -116,6 +116,12 @@ class AccountsController(TransactionBase):
|
|||||||
self.validate_non_invoice_documents_schedule()
|
self.validate_non_invoice_documents_schedule()
|
||||||
|
|
||||||
def before_print(self):
|
def before_print(self):
|
||||||
|
if self.doctype in ['Journal Entry', 'Payment Entry', 'Sales Invoice', 'Purchase Invoice']:
|
||||||
|
self.gl_entries = frappe.get_list("GL Entry", filters={
|
||||||
|
"voucher_type": self.doctype,
|
||||||
|
"voucher_no": self.name
|
||||||
|
}, fields=["account", "party_type", "party", "debit", "credit", "remarks"])
|
||||||
|
|
||||||
if self.doctype in ['Purchase Order', 'Sales Order', 'Sales Invoice', 'Purchase Invoice',
|
if self.doctype in ['Purchase Order', 'Sales Order', 'Sales Invoice', 'Purchase Invoice',
|
||||||
'Supplier Quotation', 'Purchase Receipt', 'Delivery Note', 'Quotation']:
|
'Supplier Quotation', 'Purchase Receipt', 'Delivery Note', 'Quotation']:
|
||||||
if self.get("group_same_items"):
|
if self.get("group_same_items"):
|
||||||
|
|||||||
@@ -172,8 +172,8 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
|
|||||||
or tabItem.item_code LIKE %(txt)s
|
or tabItem.item_code LIKE %(txt)s
|
||||||
or tabItem.item_group LIKE %(txt)s
|
or tabItem.item_group LIKE %(txt)s
|
||||||
or tabItem.item_name LIKE %(txt)s
|
or tabItem.item_name LIKE %(txt)s
|
||||||
or tabItem.item_code IN (select parent from `tabItem Barcode` where barcode LIKE %(txt)s
|
or tabItem.item_code IN (select parent from `tabItem Barcode` where barcode LIKE %(txt)s)
|
||||||
{description_cond}))
|
{description_cond})
|
||||||
{fcond} {mcond}
|
{fcond} {mcond}
|
||||||
order by
|
order by
|
||||||
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
|
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
# 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
|
import frappe, erpnext
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
from frappe.model.meta import get_field_precision
|
||||||
from frappe.utils import flt, get_datetime, format_datetime
|
from frappe.utils import flt, get_datetime, format_datetime
|
||||||
|
|
||||||
class StockOverReturnError(frappe.ValidationError): pass
|
class StockOverReturnError(frappe.ValidationError): pass
|
||||||
@@ -116,6 +117,10 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items):
|
|||||||
|
|
||||||
already_returned_data = already_returned_items.get(args.item_code) or {}
|
already_returned_data = already_returned_items.get(args.item_code) or {}
|
||||||
|
|
||||||
|
company_currency = erpnext.get_company_currency(doc.company)
|
||||||
|
stock_qty_precision = get_field_precision(frappe.get_meta(doc.doctype + " Item")
|
||||||
|
.get_field("stock_qty"), company_currency)
|
||||||
|
|
||||||
for column in fields:
|
for column in fields:
|
||||||
returned_qty = flt(already_returned_data.get(column, 0)) if len(already_returned_data) > 0 else 0
|
returned_qty = flt(already_returned_data.get(column, 0)) if len(already_returned_data) > 0 else 0
|
||||||
|
|
||||||
@@ -126,7 +131,7 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items):
|
|||||||
reference_qty = ref.get(column) * ref.get("conversion_factor", 1.0)
|
reference_qty = ref.get(column) * ref.get("conversion_factor", 1.0)
|
||||||
current_stock_qty = args.get(column) * args.get("conversion_factor", 1.0)
|
current_stock_qty = args.get(column) * args.get("conversion_factor", 1.0)
|
||||||
|
|
||||||
max_returnable_qty = flt(reference_qty) - returned_qty
|
max_returnable_qty = flt(reference_qty, stock_qty_precision) - returned_qty
|
||||||
label = column.replace('_', ' ').title()
|
label = column.replace('_', ' ').title()
|
||||||
|
|
||||||
if reference_qty:
|
if reference_qty:
|
||||||
@@ -135,7 +140,7 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items):
|
|||||||
elif returned_qty >= reference_qty and args.get(column):
|
elif returned_qty >= reference_qty and args.get(column):
|
||||||
frappe.throw(_("Item {0} has already been returned")
|
frappe.throw(_("Item {0} has already been returned")
|
||||||
.format(args.item_code), StockOverReturnError)
|
.format(args.item_code), StockOverReturnError)
|
||||||
elif abs(current_stock_qty) > max_returnable_qty:
|
elif abs(flt(current_stock_qty, stock_qty_precision)) > max_returnable_qty:
|
||||||
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
|
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
|
||||||
.format(args.idx, max_returnable_qty, args.item_code), StockOverReturnError)
|
.format(args.idx, max_returnable_qty, args.item_code), StockOverReturnError)
|
||||||
|
|
||||||
@@ -239,6 +244,10 @@ def make_return_doc(doctype, source_name, target_doc=None):
|
|||||||
doc.paid_amount = -1 * source.paid_amount
|
doc.paid_amount = -1 * source.paid_amount
|
||||||
doc.base_paid_amount = -1 * source.base_paid_amount
|
doc.base_paid_amount = -1 * source.base_paid_amount
|
||||||
|
|
||||||
|
if doc.get("is_return") and hasattr(doc, "packed_items"):
|
||||||
|
for d in doc.get("packed_items"):
|
||||||
|
d.qty = d.qty * -1
|
||||||
|
|
||||||
doc.discount_amount = -1 * source.discount_amount
|
doc.discount_amount = -1 * source.discount_amount
|
||||||
doc.run_method("calculate_taxes_and_totals")
|
doc.run_method("calculate_taxes_and_totals")
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class StockController(AccountsController):
|
|||||||
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
||||||
|
|
||||||
if cint(erpnext.is_perpetual_inventory_enabled(self.company)):
|
if cint(erpnext.is_perpetual_inventory_enabled(self.company)):
|
||||||
warehouse_account = get_warehouse_account_map()
|
warehouse_account = get_warehouse_account_map(self.company)
|
||||||
|
|
||||||
if self.docstatus==1:
|
if self.docstatus==1:
|
||||||
if not gl_entries:
|
if not gl_entries:
|
||||||
@@ -36,7 +36,7 @@ class StockController(AccountsController):
|
|||||||
if repost_future_gle:
|
if repost_future_gle:
|
||||||
items, warehouses = self.get_items_and_warehouses()
|
items, warehouses = self.get_items_and_warehouses()
|
||||||
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items,
|
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items,
|
||||||
warehouse_account)
|
warehouse_account, company=self.company)
|
||||||
elif self.doctype in ['Purchase Receipt', 'Purchase Invoice'] and self.docstatus == 1:
|
elif self.doctype in ['Purchase Receipt', 'Purchase Invoice'] and self.docstatus == 1:
|
||||||
gl_entries = []
|
gl_entries = []
|
||||||
gl_entries = self.get_asset_gl_entry(gl_entries)
|
gl_entries = self.get_asset_gl_entry(gl_entries)
|
||||||
@@ -46,7 +46,7 @@ class StockController(AccountsController):
|
|||||||
default_cost_center=None):
|
default_cost_center=None):
|
||||||
|
|
||||||
if not warehouse_account:
|
if not warehouse_account:
|
||||||
warehouse_account = get_warehouse_account_map()
|
warehouse_account = get_warehouse_account_map(self.company)
|
||||||
|
|
||||||
sle_map = self.get_stock_ledger_details()
|
sle_map = self.get_stock_ledger_details()
|
||||||
voucher_details = self.get_voucher_details(default_expense_account, default_cost_center, sle_map)
|
voucher_details = self.get_voucher_details(default_expense_account, default_cost_center, sle_map)
|
||||||
@@ -199,7 +199,8 @@ class StockController(AccountsController):
|
|||||||
def make_adjustment_entry(self, expected_gle, voucher_obj):
|
def make_adjustment_entry(self, expected_gle, voucher_obj):
|
||||||
from erpnext.accounts.utils import get_stock_and_account_difference
|
from erpnext.accounts.utils import get_stock_and_account_difference
|
||||||
account_list = [d.account for d in expected_gle]
|
account_list = [d.account for d in expected_gle]
|
||||||
acc_diff = get_stock_and_account_difference(account_list, expected_gle[0].posting_date)
|
acc_diff = get_stock_and_account_difference(account_list,
|
||||||
|
expected_gle[0].posting_date, self.company)
|
||||||
|
|
||||||
cost_center = self.get_company_default("cost_center")
|
cost_center = self.get_company_default("cost_center")
|
||||||
stock_adjustment_account = self.get_company_default("stock_adjustment_account")
|
stock_adjustment_account = self.get_company_default("stock_adjustment_account")
|
||||||
@@ -361,13 +362,13 @@ class StockController(AccountsController):
|
|||||||
frappe.get_doc("Blanket Order", blanket_order).update_ordered_qty()
|
frappe.get_doc("Blanket Order", blanket_order).update_ordered_qty()
|
||||||
|
|
||||||
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
|
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
|
||||||
warehouse_account=None):
|
warehouse_account=None, company=None):
|
||||||
def _delete_gl_entries(voucher_type, voucher_no):
|
def _delete_gl_entries(voucher_type, voucher_no):
|
||||||
frappe.db.sql("""delete from `tabGL Entry`
|
frappe.db.sql("""delete from `tabGL Entry`
|
||||||
where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
|
where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
|
||||||
|
|
||||||
if not warehouse_account:
|
if not warehouse_account:
|
||||||
warehouse_account = get_warehouse_account_map()
|
warehouse_account = get_warehouse_account_map(company)
|
||||||
|
|
||||||
future_stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, for_warehouses, for_items)
|
future_stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, for_warehouses, for_items)
|
||||||
gle = get_voucherwise_gl_entries(future_stock_vouchers, posting_date)
|
gle = get_voucherwise_gl_entries(future_stock_vouchers, posting_date)
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ def create_variant_with_tables(item, args):
|
|||||||
return variant
|
return variant
|
||||||
|
|
||||||
def make_item_variant():
|
def make_item_variant():
|
||||||
frappe.delete_doc_if_exists("Item", "_Test Variant Item-S", force=1)
|
frappe.delete_doc_if_exists("Item", "_Test Variant Item-XSL", force=1)
|
||||||
variant = create_variant_with_tables("_Test Variant Item", '{"Test Size": "Small"}')
|
variant = create_variant_with_tables("_Test Variant Item", '{"Test Size": "Extra Small"}')
|
||||||
variant.item_code = "_Test Variant Item-S"
|
variant.item_code = "_Test Variant Item-XSL"
|
||||||
variant.item_name = "_Test Variant Item-S"
|
variant.item_name = "_Test Variant Item-XSL"
|
||||||
variant.save()
|
variant.save()
|
||||||
return variant
|
return variant
|
||||||
|
|
||||||
|
|||||||
@@ -162,6 +162,8 @@ def create_item_code(amazon_item_json, sku):
|
|||||||
igroup.parent_item_group = mws_settings.item_group
|
igroup.parent_item_group = mws_settings.item_group
|
||||||
igroup.insert()
|
igroup.insert()
|
||||||
|
|
||||||
|
item.append("item_defaults", {'company':mws_settings.company})
|
||||||
|
|
||||||
item.insert(ignore_permissions=True)
|
item.insert(ignore_permissions=True)
|
||||||
create_item_price(amazon_item_json, item.item_code)
|
create_item_price(amazon_item_json, item.item_code)
|
||||||
|
|
||||||
@@ -213,7 +215,7 @@ def get_orders(after_date):
|
|||||||
fulfillment_channels=["MFN", "AFN"],
|
fulfillment_channels=["MFN", "AFN"],
|
||||||
lastupdatedafter=after_date,
|
lastupdatedafter=after_date,
|
||||||
orderstatus=statuses,
|
orderstatus=statuses,
|
||||||
max_results='20')
|
max_results='50')
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
orders_list = []
|
orders_list = []
|
||||||
@@ -432,8 +434,8 @@ def get_order_items(market_place_order_id):
|
|||||||
return final_order_items
|
return final_order_items
|
||||||
|
|
||||||
def get_item_code(order_item):
|
def get_item_code(order_item):
|
||||||
asin = order_item.ASIN
|
sku = order_item.SellerSKU
|
||||||
item_code = frappe.db.get_value("Item", {"amazon_item_code": asin}, "item_code")
|
item_code = frappe.db.get_value("Item", {"item_code": sku}, "item_code")
|
||||||
if item_code:
|
if item_code:
|
||||||
return item_code
|
return item_code
|
||||||
|
|
||||||
@@ -451,11 +453,16 @@ def get_charges_and_fees(market_place_order_id):
|
|||||||
shipment_item_list = return_as_list(shipment_event.ShipmentEvent.ShipmentItemList.ShipmentItem)
|
shipment_item_list = return_as_list(shipment_event.ShipmentEvent.ShipmentItemList.ShipmentItem)
|
||||||
|
|
||||||
for shipment_item in shipment_item_list:
|
for shipment_item in shipment_item_list:
|
||||||
charges = return_as_list(shipment_item.ItemChargeList.ChargeComponent)
|
charges, fees = []
|
||||||
fees = return_as_list(shipment_item.ItemFeeList.FeeComponent)
|
|
||||||
|
if 'ItemChargeList' in shipment_item.keys():
|
||||||
|
charges = return_as_list(shipment_item.ItemChargeList.ChargeComponent)
|
||||||
|
|
||||||
|
if 'ItemFeeList' in shipment_item.keys():
|
||||||
|
fees = return_as_list(shipment_item.ItemFeeList.FeeComponent)
|
||||||
|
|
||||||
for charge in charges:
|
for charge in charges:
|
||||||
if(charge.ChargeType != "Principal"):
|
if(charge.ChargeType != "Principal") and float(charge.ChargeAmount.CurrencyAmount) != 0:
|
||||||
charge_account = get_account(charge.ChargeType)
|
charge_account = get_account(charge.ChargeType)
|
||||||
charges_fees.get("charges").append({
|
charges_fees.get("charges").append({
|
||||||
"charge_type":"Actual",
|
"charge_type":"Actual",
|
||||||
@@ -465,13 +472,14 @@ def get_charges_and_fees(market_place_order_id):
|
|||||||
})
|
})
|
||||||
|
|
||||||
for fee in fees:
|
for fee in fees:
|
||||||
fee_account = get_account(fee.FeeType)
|
if float(fee.FeeAmount.CurrencyAmount) != 0:
|
||||||
charges_fees.get("fees").append({
|
fee_account = get_account(fee.FeeType)
|
||||||
"charge_type":"Actual",
|
charges_fees.get("fees").append({
|
||||||
"account_head": fee_account,
|
"charge_type":"Actual",
|
||||||
"tax_amount": fee.FeeAmount.CurrencyAmount,
|
"account_head": fee_account,
|
||||||
"description": fee.FeeType + " for " + shipment_item.SellerSKU
|
"tax_amount": fee.FeeAmount.CurrencyAmount,
|
||||||
})
|
"description": fee.FeeType + " for " + shipment_item.SellerSKU
|
||||||
|
})
|
||||||
|
|
||||||
return charges_fees
|
return charges_fees
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class WoocommerceSettings(Document):
|
|||||||
if not frappe.get_value("Item Group",{"name": "WooCommerce Products"}):
|
if not frappe.get_value("Item Group",{"name": "WooCommerce Products"}):
|
||||||
item_group = frappe.new_doc("Item Group")
|
item_group = frappe.new_doc("Item Group")
|
||||||
item_group.item_group_name = "WooCommerce Products"
|
item_group.item_group_name = "WooCommerce Products"
|
||||||
item_group.parent_item_group = "All Item Groups"
|
item_group.parent_item_group = _("All Item Groups")
|
||||||
item_group.save()
|
item_group.save()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ frappe.ui.form.on('Healthcare Service Unit Type', {
|
|||||||
var disable = function(frm){
|
var disable = function(frm){
|
||||||
var doc = frm.doc;
|
var doc = frm.doc;
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
|
method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
|
||||||
args: {status: 1, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
|
args: {status: 1, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
|
||||||
callback: function(){
|
callback: function(){
|
||||||
cur_frm.reload_doc();
|
cur_frm.reload_doc();
|
||||||
@@ -60,7 +60,7 @@ var disable = function(frm){
|
|||||||
var enable = function(frm){
|
var enable = function(frm){
|
||||||
var doc = frm.doc;
|
var doc = frm.doc;
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
|
method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
|
||||||
args: {status: 0, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
|
args: {status: 0, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
|
||||||
callback: function(){
|
callback: function(){
|
||||||
cur_frm.reload_doc();
|
cur_frm.reload_doc();
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ def change_item_code(item, item_code, doc_name):
|
|||||||
frappe.db.set_value("Healthcare Service Unit Type", doc_name, "item_code", item_code)
|
frappe.db.set_value("Healthcare Service Unit Type", doc_name, "item_code", item_code)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def disable_enable(status, doc_name, item, is_billable):
|
def disable_enable(status, doc_name, item=None, is_billable=None):
|
||||||
frappe.db.set_value("Healthcare Service Unit Type", doc_name, "disabled", status)
|
frappe.db.set_value("Healthcare Service Unit Type", doc_name, "disabled", status)
|
||||||
if(is_billable == 1):
|
if(is_billable == 1):
|
||||||
frappe.db.set_value("Item", item, "disabled", status)
|
frappe.db.set_value("Item", item, "disabled", status)
|
||||||
|
|||||||
@@ -11,16 +11,14 @@ from frappe.utils import getdate, date_diff
|
|||||||
class AdditionalSalary(Document):
|
class AdditionalSalary(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_dates()
|
self.validate_dates()
|
||||||
if self.amount <= 0:
|
if self.amount < 0:
|
||||||
frappe.throw(_("Amount should be greater than zero."))
|
frappe.throw(_("Amount should not be less than zero."))
|
||||||
|
|
||||||
def validate_dates(self):
|
def validate_dates(self):
|
||||||
date_of_joining, relieving_date = frappe.db.get_value("Employee", self.employee,
|
date_of_joining, relieving_date = frappe.db.get_value("Employee", self.employee,
|
||||||
["date_of_joining", "relieving_date"])
|
["date_of_joining", "relieving_date"])
|
||||||
if date_of_joining and getdate(self.payroll_date) < getdate(date_of_joining):
|
if date_of_joining and getdate(self.payroll_date) < getdate(date_of_joining):
|
||||||
frappe.throw(_("Payroll date can not be less than employee's joining date"))
|
frappe.throw(_("Payroll date can not be less than employee's joining date"))
|
||||||
elif relieving_date and getdate(self.payroll_date) > getdate(relieving_date):
|
|
||||||
frappe.throw(_("To date can not greater than employee's relieving date"))
|
|
||||||
|
|
||||||
def get_amount(self, sal_start_date, sal_end_date):
|
def get_amount(self, sal_start_date, sal_end_date):
|
||||||
start_date = getdate(sal_start_date)
|
start_date = getdate(sal_start_date)
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ $.extend(cur_frm.cscript, new erpnext.hr.ExpenseClaimController({frm: cur_frm}))
|
|||||||
|
|
||||||
cur_frm.add_fetch('employee', 'company', 'company');
|
cur_frm.add_fetch('employee', 'company', 'company');
|
||||||
cur_frm.add_fetch('employee','employee_name','employee_name');
|
cur_frm.add_fetch('employee','employee_name','employee_name');
|
||||||
|
cur_frm.add_fetch('expense_type','description','description');
|
||||||
|
|
||||||
cur_frm.cscript.onload = function(doc) {
|
cur_frm.cscript.onload = function(doc) {
|
||||||
if (doc.__islocal) {
|
if (doc.__islocal) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -46,6 +48,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -76,6 +79,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -144,6 +149,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -174,11 +180,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fetch_from": "expense_type.description",
|
"fetch_from": "",
|
||||||
"fieldname": "description",
|
"fieldname": "description",
|
||||||
"fieldtype": "Text Editor",
|
"fieldtype": "Text Editor",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -210,6 +217,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -240,6 +248,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -275,6 +284,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -305,6 +315,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -349,7 +360,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-05-16 22:42:56.727863",
|
"modified": "2019-02-24 08:41:36.122565",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Expense Claim Detail",
|
"name": "Expense Claim Detail",
|
||||||
@@ -362,5 +373,6 @@
|
|||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 0,
|
"track_changes": 0,
|
||||||
"track_seen": 0
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
}
|
}
|
||||||
@@ -399,6 +399,19 @@ def get_leave_balance_on(employee, leave_type, date, allocation_records=None, do
|
|||||||
|
|
||||||
return flt(allocation.total_leaves_allocated) - (flt(leaves_taken) + flt(leaves_encashed))
|
return flt(allocation.total_leaves_allocated) - (flt(leaves_taken) + flt(leaves_encashed))
|
||||||
|
|
||||||
|
def get_total_allocated_leaves(employee, leave_type, date):
|
||||||
|
filters= {
|
||||||
|
'from_date': ['<=', date],
|
||||||
|
'to_date': ['>=', date],
|
||||||
|
'docstatus': 1,
|
||||||
|
'leave_type': leave_type,
|
||||||
|
'employee': employee
|
||||||
|
}
|
||||||
|
|
||||||
|
leave_allocation_records = frappe.db.get_all('Leave Allocation', filters=filters, fields=['total_leaves_allocated'])
|
||||||
|
|
||||||
|
return flt(leave_allocation_records[0]['total_leaves_allocated']) if leave_allocation_records else flt(0)
|
||||||
|
|
||||||
def get_leaves_for_period(employee, leave_type, from_date, to_date, status, docname=None):
|
def get_leaves_for_period(employee, leave_type, from_date, to_date, status, docname=None):
|
||||||
leave_applications = frappe.db.sql("""
|
leave_applications = frappe.db.sql("""
|
||||||
select name, employee, leave_type, from_date, to_date, total_leave_days
|
select name, employee, leave_type, from_date, to_date, total_leave_days
|
||||||
@@ -487,7 +500,6 @@ def get_events(start, end, filters=None):
|
|||||||
|
|
||||||
add_block_dates(events, start, end, employee, company)
|
add_block_dates(events, start, end, employee, company)
|
||||||
add_holidays(events, start, end, employee, company)
|
add_holidays(events, start, end, employee, company)
|
||||||
|
|
||||||
return events
|
return events
|
||||||
|
|
||||||
def add_department_leaves(events, start, end, employee, company):
|
def add_department_leaves(events, start, end, employee, company):
|
||||||
@@ -500,19 +512,32 @@ def add_department_leaves(events, start, end, employee, company):
|
|||||||
department_employees = frappe.db.sql_list("""select name from tabEmployee where department=%s
|
department_employees = frappe.db.sql_list("""select name from tabEmployee where department=%s
|
||||||
and company=%s""", (department, company))
|
and company=%s""", (department, company))
|
||||||
|
|
||||||
match_conditions = "and employee in (\"%s\")" % '", "'.join(department_employees)
|
filter_conditions = " and employee in (\"%s\")" % '", "'.join(department_employees)
|
||||||
add_leaves(events, start, end, match_conditions=match_conditions)
|
add_leaves(events, start, end, filter_conditions=filter_conditions)
|
||||||
|
|
||||||
|
def add_leaves(events, start, end, filter_conditions=None):
|
||||||
|
conditions = []
|
||||||
|
|
||||||
|
|
||||||
|
if not cint(frappe.db.get_value("HR Settings", None, "show_leaves_of_all_department_members_in_calendar")):
|
||||||
|
from frappe.desk.reportview import build_match_conditions
|
||||||
|
match_conditions = build_match_conditions("Leave Application")
|
||||||
|
|
||||||
|
if match_conditions:
|
||||||
|
conditions.append(match_conditions)
|
||||||
|
|
||||||
def add_leaves(events, start, end, match_conditions=None):
|
|
||||||
query = """select name, from_date, to_date, employee_name, half_day,
|
query = """select name, from_date, to_date, employee_name, half_day,
|
||||||
status, employee, docstatus
|
status, employee, docstatus
|
||||||
from `tabLeave Application` where
|
from `tabLeave Application` where
|
||||||
from_date <= %(end)s and to_date >= %(start)s <= to_date
|
from_date <= %(end)s and to_date >= %(start)s <= to_date
|
||||||
and docstatus < 2
|
and docstatus < 2
|
||||||
and status!="Rejected" """
|
and status!='Rejected' """
|
||||||
|
|
||||||
if match_conditions:
|
if conditions:
|
||||||
query += match_conditions
|
query += ' and ' + ' and '.join(conditions)
|
||||||
|
|
||||||
|
if filter_conditions:
|
||||||
|
query += filter_conditions
|
||||||
|
|
||||||
for d in frappe.db.sql(query, {"start":start, "end": end}, as_dict=True):
|
for d in frappe.db.sql(query, {"start":start, "end": end}, as_dict=True):
|
||||||
e = {
|
e = {
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ class SalarySlip(TransactionBase):
|
|||||||
|
|
||||||
self.set_loan_repayment()
|
self.set_loan_repayment()
|
||||||
|
|
||||||
self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
|
self.net_pay = (flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))) * flt(self.payment_days / self.total_working_days)
|
||||||
self.rounded_total = rounded(self.net_pay,
|
self.rounded_total = rounded(self.net_pay,
|
||||||
self.precision("net_pay") if disable_rounded_total else 0)
|
self.precision("net_pay") if disable_rounded_total else 0)
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class StaffingPlan(Document):
|
|||||||
self.total_estimated_budget = 0
|
self.total_estimated_budget = 0
|
||||||
|
|
||||||
for detail in self.get("staffing_details"):
|
for detail in self.get("staffing_details"):
|
||||||
|
self.set_vacancies(detail)
|
||||||
self.validate_overlap(detail)
|
self.validate_overlap(detail)
|
||||||
self.validate_with_subsidiary_plans(detail)
|
self.validate_with_subsidiary_plans(detail)
|
||||||
self.validate_with_parent_plan(detail)
|
self.validate_with_parent_plan(detail)
|
||||||
@@ -39,6 +40,15 @@ class StaffingPlan(Document):
|
|||||||
else: detail.vacancies = detail.number_of_positions = detail.total_estimated_cost = 0
|
else: detail.vacancies = detail.number_of_positions = detail.total_estimated_cost = 0
|
||||||
self.total_estimated_budget += detail.total_estimated_cost
|
self.total_estimated_budget += detail.total_estimated_cost
|
||||||
|
|
||||||
|
def set_vacancies(self, row):
|
||||||
|
if not row.vacancies:
|
||||||
|
current_openings = 0
|
||||||
|
for field in ['current_count', 'current_openings']:
|
||||||
|
if row.get(field):
|
||||||
|
current_openings += row.get(field)
|
||||||
|
|
||||||
|
row.vacancies = row.number_of_positions - current_openings
|
||||||
|
|
||||||
def validate_overlap(self, staffing_plan_detail):
|
def validate_overlap(self, staffing_plan_detail):
|
||||||
# Validate if any submitted Staffing Plan exist for any Designations in this plan
|
# Validate if any submitted Staffing Plan exist for any Designations in this plan
|
||||||
# and spd.vacancies>0 ?
|
# and spd.vacancies>0 ?
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class TestStaffingPlan(unittest.TestCase):
|
|||||||
if frappe.db.exists("Staffing Plan", "Test"):
|
if frappe.db.exists("Staffing Plan", "Test"):
|
||||||
return
|
return
|
||||||
staffing_plan = frappe.new_doc("Staffing Plan")
|
staffing_plan = frappe.new_doc("Staffing Plan")
|
||||||
staffing_plan.company = "_Test Company 3"
|
staffing_plan.company = "_Test Company 10"
|
||||||
staffing_plan.name = "Test"
|
staffing_plan.name = "Test"
|
||||||
staffing_plan.from_date = nowdate()
|
staffing_plan.from_date = nowdate()
|
||||||
staffing_plan.to_date = add_days(nowdate(), 10)
|
staffing_plan.to_date = add_days(nowdate(), 10)
|
||||||
@@ -67,7 +67,7 @@ class TestStaffingPlan(unittest.TestCase):
|
|||||||
if frappe.db.exists("Staffing Plan", "Test 1"):
|
if frappe.db.exists("Staffing Plan", "Test 1"):
|
||||||
return
|
return
|
||||||
staffing_plan = frappe.new_doc("Staffing Plan")
|
staffing_plan = frappe.new_doc("Staffing Plan")
|
||||||
staffing_plan.company = "_Test Company 3"
|
staffing_plan.company = "_Test Company 10"
|
||||||
staffing_plan.name = "Test 1"
|
staffing_plan.name = "Test 1"
|
||||||
staffing_plan.from_date = nowdate()
|
staffing_plan.from_date = nowdate()
|
||||||
staffing_plan.to_date = add_days(nowdate(), 10)
|
staffing_plan.to_date = add_days(nowdate(), 10)
|
||||||
@@ -85,11 +85,11 @@ def _set_up():
|
|||||||
make_company()
|
make_company()
|
||||||
|
|
||||||
def make_company():
|
def make_company():
|
||||||
if frappe.db.exists("Company", "_Test Company 3"):
|
if frappe.db.exists("Company", "_Test Company 10"):
|
||||||
return
|
return
|
||||||
company = frappe.new_doc("Company")
|
company = frappe.new_doc("Company")
|
||||||
company.company_name = "_Test Company 3"
|
company.company_name = "_Test Company 10"
|
||||||
company.abbr = "_TC3"
|
company.abbr = "_TC10"
|
||||||
company.parent_company = "_Test Company"
|
company.parent_company = "_Test Company"
|
||||||
company.default_currency = "INR"
|
company.default_currency = "INR"
|
||||||
company.country = "India"
|
company.country = "India"
|
||||||
|
|||||||
@@ -15,9 +15,11 @@ class TrainingFeedback(Document):
|
|||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
training_event = frappe.get_doc("Training Event", self.training_event)
|
training_event = frappe.get_doc("Training Event", self.training_event)
|
||||||
|
status = None
|
||||||
for e in training_event.employees:
|
for e in training_event.employees:
|
||||||
if e.employee == self.employee:
|
if e.employee == self.employee:
|
||||||
training_event.status = 'Feedback Submitted'
|
status = 'Feedback Submitted'
|
||||||
break
|
break
|
||||||
|
|
||||||
training_event.save()
|
if status:
|
||||||
|
frappe.db.set_value("Training Event", self.training_event, "status", status)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from erpnext.hr.doctype.leave_application.leave_application \
|
from erpnext.hr.doctype.leave_application.leave_application \
|
||||||
import get_leave_allocation_records, get_leave_balance_on, get_approved_leaves_for_period
|
import get_leave_allocation_records, get_leave_balance_on, get_approved_leaves_for_period, get_total_allocated_leaves
|
||||||
|
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
@@ -51,8 +51,7 @@ def get_data(filters, leave_types):
|
|||||||
filters.from_date, filters.to_date)
|
filters.from_date, filters.to_date)
|
||||||
|
|
||||||
# opening balance
|
# opening balance
|
||||||
opening = get_leave_balance_on(employee.name, leave_type, filters.from_date,
|
opening = get_total_allocated_leaves(employee.name, leave_type, filters.to_date)
|
||||||
allocation_records_based_on_from_date.get(employee.name, frappe._dict()))
|
|
||||||
|
|
||||||
# closing balance
|
# closing balance
|
||||||
closing = get_leave_balance_on(employee.name, leave_type, filters.to_date,
|
closing = get_leave_balance_on(employee.name, leave_type, filters.to_date,
|
||||||
|
|||||||
@@ -41,12 +41,19 @@ class MaintenanceVisit(TransactionBase):
|
|||||||
work_done = nm and nm[0][3] or ''
|
work_done = nm and nm[0][3] or ''
|
||||||
else:
|
else:
|
||||||
status = 'Open'
|
status = 'Open'
|
||||||
mntc_date = ''
|
mntc_date = None
|
||||||
service_person = ''
|
service_person = None
|
||||||
work_done = ''
|
work_done = None
|
||||||
|
|
||||||
frappe.db.sql("update `tabWarranty Claim` set resolution_date=%s, resolved_by=%s, resolution_details=%s, status=%s where name =%s",(mntc_date,service_person,work_done,status,d.prevdoc_docname))
|
wc_doc = frappe.get_doc('Warranty Claim', d.prevdoc_docname)
|
||||||
|
wc_doc.update({
|
||||||
|
'resolution_date': mntc_date,
|
||||||
|
'resolved_by': service_person,
|
||||||
|
'resolution_details': work_done,
|
||||||
|
'status': status
|
||||||
|
})
|
||||||
|
|
||||||
|
wc_doc.db_update()
|
||||||
|
|
||||||
def check_if_last_visit(self):
|
def check_if_last_visit(self):
|
||||||
"""check if last maintenance visit against same sales order/ Warranty Claim"""
|
"""check if last maintenance visit against same sales order/ Warranty Claim"""
|
||||||
|
|||||||
@@ -580,7 +580,7 @@ def get_list_context(context):
|
|||||||
context.title = _("Bill of Materials")
|
context.title = _("Bill of Materials")
|
||||||
# context.introduction = _('Boms')
|
# context.introduction = _('Boms')
|
||||||
|
|
||||||
def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_items=0, include_non_stock_items=False):
|
def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_items=0, include_non_stock_items=False, fetch_qty_in_stock_uom=True):
|
||||||
item_dict = {}
|
item_dict = {}
|
||||||
|
|
||||||
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
|
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
|
||||||
@@ -588,7 +588,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
|
|||||||
bom_item.item_code,
|
bom_item.item_code,
|
||||||
bom_item.idx,
|
bom_item.idx,
|
||||||
item.item_name,
|
item.item_name,
|
||||||
sum(bom_item.stock_qty/ifnull(bom.quantity, 1)) * %(qty)s as qty,
|
sum(bom_item.{qty_field}/ifnull(bom.quantity, 1)) * %(qty)s as qty,
|
||||||
item.description,
|
item.description,
|
||||||
item.image,
|
item.image,
|
||||||
item.stock_uom,
|
item.stock_uom,
|
||||||
@@ -616,16 +616,18 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
|
|||||||
query = query.format(table="BOM Explosion Item",
|
query = query.format(table="BOM Explosion Item",
|
||||||
where_conditions="",
|
where_conditions="",
|
||||||
is_stock_item=is_stock_item,
|
is_stock_item=is_stock_item,
|
||||||
|
qty_field="stock_qty",
|
||||||
select_columns = """, bom_item.source_warehouse, bom_item.operation, bom_item.include_item_in_manufacturing,
|
select_columns = """, bom_item.source_warehouse, bom_item.operation, bom_item.include_item_in_manufacturing,
|
||||||
(Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s ) as idx""")
|
(Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s limit 1) as idx""")
|
||||||
|
|
||||||
items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True)
|
items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True)
|
||||||
elif fetch_scrap_items:
|
elif fetch_scrap_items:
|
||||||
query = query.format(table="BOM Scrap Item", where_conditions="", select_columns=", bom_item.idx", is_stock_item=is_stock_item)
|
query = query.format(table="BOM Scrap Item", where_conditions="", select_columns=", bom_item.idx", is_stock_item=is_stock_item, qty_field="stock_qty")
|
||||||
items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
|
items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
|
||||||
else:
|
else:
|
||||||
query = query.format(table="BOM Item", where_conditions="", is_stock_item=is_stock_item,
|
query = query.format(table="BOM Item", where_conditions="", is_stock_item=is_stock_item,
|
||||||
select_columns = ", bom_item.source_warehouse, bom_item.idx, bom_item.operation, bom_item.include_item_in_manufacturing")
|
qty_field="stock_qty" if fetch_qty_in_stock_uom else "qty",
|
||||||
|
select_columns = ", bom_item.uom, bom_item.conversion_factor, bom_item.source_warehouse, bom_item.idx, bom_item.operation, bom_item.include_item_in_manufacturing")
|
||||||
items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
|
items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
@@ -706,8 +708,11 @@ def get_children(doctype, parent=None, is_root=False, **filters):
|
|||||||
|
|
||||||
def get_boms_in_bottom_up_order(bom_no=None):
|
def get_boms_in_bottom_up_order(bom_no=None):
|
||||||
def _get_parent(bom_no):
|
def _get_parent(bom_no):
|
||||||
return frappe.db.sql_list("""select distinct parent from `tabBOM Item`
|
return frappe.db.sql_list("""
|
||||||
where bom_no = %s and docstatus=1 and parenttype='BOM'""", bom_no)
|
select distinct bom_item.parent from `tabBOM Item` bom_item
|
||||||
|
where bom_item.bom_no = %s and bom_item.docstatus=1 and bom_item.parenttype='BOM'
|
||||||
|
and exists(select bom.name from `tabBOM` bom where bom.name=bom_item.parent and bom.is_active=1)
|
||||||
|
""", bom_no)
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
bom_list = []
|
bom_list = []
|
||||||
@@ -715,9 +720,10 @@ def get_boms_in_bottom_up_order(bom_no=None):
|
|||||||
bom_list.append(bom_no)
|
bom_list.append(bom_no)
|
||||||
else:
|
else:
|
||||||
# get all leaf BOMs
|
# get all leaf BOMs
|
||||||
bom_list = frappe.db.sql_list("""select name from `tabBOM` bom where docstatus=1
|
bom_list = frappe.db.sql_list("""select name from `tabBOM` bom
|
||||||
and not exists(select bom_no from `tabBOM Item`
|
where docstatus=1 and is_active=1
|
||||||
where parent=bom.name and ifnull(bom_no, '')!='')""")
|
and not exists(select bom_no from `tabBOM Item`
|
||||||
|
where parent=bom.name and ifnull(bom_no, '')!='')""")
|
||||||
|
|
||||||
while(count < len(bom_list)):
|
while(count < len(bom_list)):
|
||||||
for child_bom in _get_parent(bom_list[count]):
|
for child_bom in _get_parent(bom_list[count]):
|
||||||
|
|||||||
@@ -78,6 +78,39 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "operation",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Item operation",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Operation",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
@@ -893,6 +926,38 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "allow_alternative_item",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 1,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Allow Alternative Item",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
@@ -958,71 +1023,6 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "operation",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item operation",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Operation",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "allow_alternative_item",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"hidden": 1,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Allow Alternative Item",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"has_web_view": 0,
|
||||||
@@ -1035,7 +1035,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-11-23 15:05:55.187136",
|
"modified": "2019-02-21 19:19:54.872459",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "BOM Item",
|
"name": "BOM Item",
|
||||||
|
|||||||
@@ -18,20 +18,27 @@ frappe.ui.form.on('Job Card', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.docstatus == 0) {
|
if (frm.doc.docstatus == 0) {
|
||||||
if (!frm.doc.actual_start_date || !frm.doc.actual_end_date) {
|
frm.trigger("make_dashboard");
|
||||||
frm.trigger("make_dashboard");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!frm.doc.actual_start_date) {
|
if (!frm.doc.job_started) {
|
||||||
frm.add_custom_button(__("Start Job"), () => {
|
frm.add_custom_button(__("Start Job"), () => {
|
||||||
frm.set_value('actual_start_date', frappe.datetime.now_datetime());
|
let row = frappe.model.add_child(frm.doc, 'Job Card Time Log', 'time_logs');
|
||||||
|
row.from_time = frappe.datetime.now_datetime();
|
||||||
|
frm.set_value('job_started', 1);
|
||||||
|
frm.set_value('started_time' , row.from_time);
|
||||||
frm.save();
|
frm.save();
|
||||||
});
|
});
|
||||||
} else if (!frm.doc.actual_end_date) {
|
} else {
|
||||||
frm.add_custom_button(__("Complete Job"), () => {
|
frm.add_custom_button(__("Complete Job"), () => {
|
||||||
frm.set_value('actual_end_date', frappe.datetime.now_datetime());
|
let completed_time = frappe.datetime.now_datetime();
|
||||||
frm.save();
|
frm.doc.time_logs.forEach(d => {
|
||||||
frm.savesubmit();
|
if (d.from_time && !d.to_time) {
|
||||||
|
d.to_time = completed_time;
|
||||||
|
frm.set_value('started_time' , '');
|
||||||
|
frm.set_value('job_started', 0);
|
||||||
|
frm.save();
|
||||||
|
}
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,8 +60,8 @@ frappe.ui.form.on('Job Card', {
|
|||||||
|
|
||||||
var section = frm.dashboard.add_section(timer);
|
var section = frm.dashboard.add_section(timer);
|
||||||
|
|
||||||
if (frm.doc.actual_start_date) {
|
if (frm.doc.started_time) {
|
||||||
let currentIncrement = moment(frappe.datetime.now_datetime()).diff(moment(frm.doc.actual_start_date),"seconds");
|
let currentIncrement = moment(frappe.datetime.now_datetime()).diff(moment(frm.doc.started_time),"seconds");
|
||||||
initialiseTimer();
|
initialiseTimer();
|
||||||
|
|
||||||
function initialiseTimer() {
|
function initialiseTimer() {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "work_order",
|
"fieldname": "work_order",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -54,6 +55,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "bom_no",
|
"fieldname": "bom_no",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -87,6 +89,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "workstation",
|
"fieldname": "workstation",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -120,6 +123,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "operation",
|
"fieldname": "operation",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -153,6 +157,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_4",
|
"fieldname": "column_break_4",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -185,6 +190,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "Today",
|
"default": "Today",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "posting_date",
|
"fieldname": "posting_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -217,6 +223,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -250,6 +257,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "for_quantity",
|
"fieldname": "for_quantity",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -282,6 +290,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "wip_warehouse",
|
"fieldname": "wip_warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -315,6 +324,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "timing_detail",
|
"fieldname": "timing_detail",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -347,6 +357,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "employee",
|
"fieldname": "employee",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -380,7 +391,74 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "time_in_mins",
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "time_logs",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Time Logs",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Job Card Time Log",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "section_break_13",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "total_completed_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
@@ -389,7 +467,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": "Time In Mins",
|
"label": "Total Completed Qty",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
@@ -412,7 +490,8 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "column_break_13",
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "column_break_15",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
@@ -443,8 +522,9 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "actual_start_date",
|
"fetch_if_empty": 0,
|
||||||
"fieldtype": "Datetime",
|
"fieldname": "total_time_in_mins",
|
||||||
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
@@ -452,46 +532,14 @@
|
|||||||
"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": "Actual Start Date",
|
"label": "Total Time in Mins",
|
||||||
"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": 1,
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "actual_end_date",
|
|
||||||
"fieldtype": "Datetime",
|
|
||||||
"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": "Actual End 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,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
@@ -507,6 +555,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "section_break_8",
|
"fieldname": "section_break_8",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -539,6 +588,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "items",
|
"fieldname": "items",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -572,6 +622,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "more_information",
|
"fieldname": "more_information",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -604,6 +655,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "operation_id",
|
"fieldname": "operation_id",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
@@ -637,6 +689,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "0",
|
"default": "0",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "transferred_qty",
|
"fieldname": "transferred_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -670,6 +723,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "0",
|
"default": "0",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "requested_qty",
|
"fieldname": "requested_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -702,6 +756,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "project",
|
"fieldname": "project",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -735,6 +790,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "remarks",
|
"fieldname": "remarks",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -767,6 +823,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "column_break_20",
|
"fieldname": "column_break_20",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -799,6 +856,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "Open",
|
"default": "Open",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "status",
|
"fieldname": "status",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -832,6 +890,73 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "job_started",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 1,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Job Started",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 1,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "started_time",
|
||||||
|
"fieldtype": "Datetime",
|
||||||
|
"hidden": 1,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Started Time",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 1,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -868,7 +993,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-12-13 17:23:57.986381",
|
"modified": "2019-03-10 17:38:37.499871",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Job Card",
|
"name": "Job Card",
|
||||||
|
|||||||
@@ -11,44 +11,56 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
class JobCard(Document):
|
class JobCard(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_actual_dates()
|
self.validate_time_logs()
|
||||||
self.set_time_in_mins()
|
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
def validate_actual_dates(self):
|
def validate_time_logs(self):
|
||||||
if get_datetime(self.actual_start_date) > get_datetime(self.actual_end_date):
|
self.total_completed_qty = 0.0
|
||||||
frappe.throw(_("Actual start date must be less than actual end date"))
|
self.total_time_in_mins = 0.0
|
||||||
|
|
||||||
if not (self.employee and self.actual_start_date and self.actual_end_date):
|
for d in self.get('time_logs'):
|
||||||
return
|
if get_datetime(d.from_time) > get_datetime(d.to_time):
|
||||||
|
frappe.throw(_("Row {0}: From time must be less than to time").format(d.idx))
|
||||||
|
|
||||||
data = frappe.db.sql(""" select name from `tabJob Card`
|
data = self.get_overlap_for(d)
|
||||||
where
|
if data:
|
||||||
((%(actual_start_date)s > actual_start_date and %(actual_start_date)s < actual_end_date) or
|
frappe.throw(_("Row {0}: From Time and To Time of {1} is overlapping with {2}")
|
||||||
(%(actual_end_date)s > actual_start_date and %(actual_end_date)s < actual_end_date) or
|
.format(d.idx, self.name, data.name))
|
||||||
(%(actual_start_date)s <= actual_start_date and %(actual_end_date)s >= actual_end_date)) and
|
|
||||||
name != %(name)s and employee = %(employee)s and docstatus =1
|
|
||||||
""", {
|
|
||||||
'actual_start_date': self.actual_start_date,
|
|
||||||
'actual_end_date': self.actual_end_date,
|
|
||||||
'employee': self.employee,
|
|
||||||
'name': self.name
|
|
||||||
}, as_dict=1)
|
|
||||||
|
|
||||||
if data:
|
if d.from_time and d.to_time:
|
||||||
frappe.throw(_("Start date and end date is overlapping with the job card <a href='#Form/Job Card/{0}'>{1}</a>")
|
d.time_in_mins = time_diff_in_hours(d.to_time, d.from_time) * 60
|
||||||
.format(data[0].name, data[0].name))
|
self.total_time_in_mins += d.time_in_mins
|
||||||
|
|
||||||
def set_time_in_mins(self):
|
if d.completed_qty:
|
||||||
if self.actual_start_date and self.actual_end_date:
|
self.total_completed_qty += d.completed_qty
|
||||||
self.time_in_mins = time_diff_in_hours(self.actual_end_date, self.actual_start_date) * 60
|
|
||||||
|
def get_overlap_for(self, args):
|
||||||
|
existing = frappe.db.sql("""select jc.name as name from
|
||||||
|
`tabJob Card Time Log` jctl, `tabJob Card` jc where jctl.parent = jc.name and
|
||||||
|
(
|
||||||
|
(%(from_time)s > jctl.from_time and %(from_time)s < jctl.to_time) or
|
||||||
|
(%(to_time)s > jctl.from_time and %(to_time)s < jctl.to_time) or
|
||||||
|
(%(from_time)s <= jctl.from_time and %(to_time)s >= jctl.to_time))
|
||||||
|
and jctl.name!=%(name)s
|
||||||
|
and jc.name!=%(parent)s
|
||||||
|
and jc.docstatus < 2
|
||||||
|
and jc.employee = %(employee)s """,
|
||||||
|
{
|
||||||
|
"from_time": args.from_time,
|
||||||
|
"to_time": args.to_time,
|
||||||
|
"name": args.name or "No Name",
|
||||||
|
"parent": args.parent or "No Name",
|
||||||
|
"employee": self.employee
|
||||||
|
}, as_dict=True)
|
||||||
|
|
||||||
|
return existing[0] if existing else None
|
||||||
|
|
||||||
def get_required_items(self):
|
def get_required_items(self):
|
||||||
if not self.get('work_order'):
|
if not self.get('work_order'):
|
||||||
return
|
return
|
||||||
|
|
||||||
doc = frappe.get_doc('Work Order', self.get('work_order'))
|
doc = frappe.get_doc('Work Order', self.get('work_order'))
|
||||||
if doc.transfer_material_against == 'Work Order' and doc.skip_transfer:
|
if doc.transfer_material_against == 'Work Order' or doc.skip_transfer:
|
||||||
return
|
return
|
||||||
|
|
||||||
for d in doc.required_items:
|
for d in doc.required_items:
|
||||||
@@ -67,36 +79,51 @@ class JobCard(Document):
|
|||||||
})
|
})
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.validate_dates()
|
self.validate_job_card()
|
||||||
self.update_work_order()
|
self.update_work_order()
|
||||||
self.set_transferred_qty()
|
self.set_transferred_qty()
|
||||||
|
|
||||||
def validate_dates(self):
|
|
||||||
if not self.actual_start_date and not self.actual_end_date:
|
|
||||||
frappe.throw(_("Actual start date and actual end date is mandatory"))
|
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.update_work_order()
|
self.update_work_order()
|
||||||
self.set_transferred_qty()
|
self.set_transferred_qty()
|
||||||
|
|
||||||
|
def validate_job_card(self):
|
||||||
|
if not self.time_logs:
|
||||||
|
frappe.throw(_("Time logs are required for job card {0}").format(self.name))
|
||||||
|
|
||||||
|
if self.total_completed_qty <= 0.0:
|
||||||
|
frappe.throw(_("Total completed qty must be greater than zero"))
|
||||||
|
|
||||||
|
if self.total_completed_qty > self.for_quantity:
|
||||||
|
frappe.throw(_("Total completed qty can not be greater than for quantity"))
|
||||||
|
|
||||||
def update_work_order(self):
|
def update_work_order(self):
|
||||||
if not self.work_order:
|
if not self.work_order:
|
||||||
return
|
return
|
||||||
|
|
||||||
data = frappe.db.get_value("Job Card", {'docstatus': 1, 'operation_id': self.operation_id},
|
for_quantity, time_in_mins = 0, 0
|
||||||
['sum(time_in_mins)', 'min(actual_start_date)', 'max(actual_end_date)', 'sum(for_quantity)'])
|
from_time_list, to_time_list = [], []
|
||||||
|
|
||||||
if data:
|
|
||||||
time_in_mins, actual_start_date, actual_end_date, for_quantity = data
|
|
||||||
|
|
||||||
|
for d in frappe.get_all('Job Card',
|
||||||
|
filters = {'docstatus': 1, 'operation_id': self.operation_id}):
|
||||||
|
doc = frappe.get_doc('Job Card', d.name)
|
||||||
|
|
||||||
|
for_quantity += doc.total_completed_qty
|
||||||
|
time_in_mins += doc.total_time_in_mins
|
||||||
|
for time_log in doc.time_logs:
|
||||||
|
from_time_list.append(time_log.from_time)
|
||||||
|
to_time_list.append(time_log.to_time)
|
||||||
|
|
||||||
|
if for_quantity:
|
||||||
wo = frappe.get_doc('Work Order', self.work_order)
|
wo = frappe.get_doc('Work Order', self.work_order)
|
||||||
|
|
||||||
for data in wo.operations:
|
for data in wo.operations:
|
||||||
if data.name == self.operation_id:
|
if data.name == self.operation_id:
|
||||||
data.completed_qty = for_quantity
|
data.completed_qty = for_quantity
|
||||||
data.actual_operation_time = time_in_mins
|
data.actual_operation_time = time_in_mins
|
||||||
data.actual_start_time = actual_start_date
|
data.actual_start_time = min(from_time_list)
|
||||||
data.actual_end_time = actual_end_date
|
data.actual_end_time = max(to_time_list)
|
||||||
|
|
||||||
wo.flags.ignore_validate_update_after_submit = True
|
wo.flags.ignore_validate_update_after_submit = True
|
||||||
wo.update_operation_status()
|
wo.update_operation_status()
|
||||||
@@ -134,7 +161,9 @@ class JobCard(Document):
|
|||||||
if completed:
|
if completed:
|
||||||
job_cards = frappe.get_all('Job Card', filters = {'work_order': self.work_order,
|
job_cards = frappe.get_all('Job Card', filters = {'work_order': self.work_order,
|
||||||
'docstatus': ('!=', 2)}, fields = 'sum(transferred_qty) as qty', group_by='operation_id')
|
'docstatus': ('!=', 2)}, fields = 'sum(transferred_qty) as qty', group_by='operation_id')
|
||||||
qty = min([d.qty for d in job_cards])
|
|
||||||
|
if job_cards:
|
||||||
|
qty = min([d.qty for d in job_cards])
|
||||||
|
|
||||||
doc.db_set('material_transferred_for_manufacturing', qty)
|
doc.db_set('material_transferred_for_manufacturing', qty)
|
||||||
|
|
||||||
@@ -147,7 +176,7 @@ class JobCard(Document):
|
|||||||
2: "Cancelled"
|
2: "Cancelled"
|
||||||
}[self.docstatus or 0]
|
}[self.docstatus or 0]
|
||||||
|
|
||||||
if self.actual_start_date:
|
if self.time_logs:
|
||||||
self.status = 'Work In Progress'
|
self.status = 'Work In Progress'
|
||||||
|
|
||||||
if (self.docstatus == 1 and
|
if (self.docstatus == 1 and
|
||||||
|
|||||||
@@ -0,0 +1,208 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2019-03-08 23:56:43.187569",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "from_time",
|
||||||
|
"fieldtype": "Datetime",
|
||||||
|
"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": "From Time",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "to_time",
|
||||||
|
"fieldtype": "Datetime",
|
||||||
|
"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": "To Time",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "column_break_2",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "time_in_mins",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Time In Mins",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "0",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "completed_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Completed Qty",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 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": "2019-03-10 17:08:46.504910",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Manufacturing",
|
||||||
|
"name": "Job Card Time Log",
|
||||||
|
"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": "ASC",
|
||||||
|
"track_changes": 1,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class JobCardTimeLog(Document):
|
||||||
|
pass
|
||||||
@@ -302,6 +302,19 @@ class TestWorkOrder(unittest.TestCase):
|
|||||||
self.assertEqual(len(ste.additional_costs), 1)
|
self.assertEqual(len(ste.additional_costs), 1)
|
||||||
self.assertEqual(ste.total_additional_costs, 1000)
|
self.assertEqual(ste.total_additional_costs, 1000)
|
||||||
|
|
||||||
|
def test_job_card(self):
|
||||||
|
data = frappe.get_cached_value('BOM',
|
||||||
|
{'docstatus': 1, 'with_operations': 1, 'company': '_Test Company'}, ['name', 'item'])
|
||||||
|
|
||||||
|
if data:
|
||||||
|
bom, bom_item = data
|
||||||
|
|
||||||
|
bom_doc = frappe.get_doc('BOM', bom)
|
||||||
|
work_order = make_wo_order_test_record(item=bom_item, qty=1, bom_no=bom)
|
||||||
|
|
||||||
|
job_cards = frappe.get_all('Job Card', filters = {'work_order': work_order})
|
||||||
|
self.assertEqual(len(job_cards), len(bom_doc.operations))
|
||||||
|
|
||||||
def test_work_order_with_non_transfer_item(self):
|
def test_work_order_with_non_transfer_item(self):
|
||||||
items = {'Finished Good Transfer Item': 1, '_Test FG Item': 1, '_Test FG Item 1': 0}
|
items = {'Finished Good Transfer Item': 1, '_Test FG Item': 1, '_Test FG Item 1': 0}
|
||||||
for item, allow_transfer in items.items():
|
for item, allow_transfer in items.items():
|
||||||
@@ -346,7 +359,7 @@ def make_wo_order_test_record(**args):
|
|||||||
|
|
||||||
wo_order = frappe.new_doc("Work Order")
|
wo_order = frappe.new_doc("Work Order")
|
||||||
wo_order.production_item = args.production_item or args.item or args.item_code or "_Test FG Item"
|
wo_order.production_item = args.production_item or args.item or args.item_code or "_Test FG Item"
|
||||||
wo_order.bom_no = frappe.db.get_value("BOM", {"item": wo_order.production_item,
|
wo_order.bom_no = args.bom_no or frappe.db.get_value("BOM", {"item": wo_order.production_item,
|
||||||
"is_active": 1, "is_default": 1})
|
"is_active": 1, "is_default": 1})
|
||||||
wo_order.qty = args.qty or 10
|
wo_order.qty = args.qty or 10
|
||||||
wo_order.wip_warehouse = args.wip_warehouse or "_Test Warehouse - _TC"
|
wo_order.wip_warehouse = args.wip_warehouse or "_Test Warehouse - _TC"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user