Resolve merge conflicts
This commit is contained in:
commit
be9a8e1a14
14
.github/workflows/docker-release.yml
vendored
Normal file
14
.github/workflows/docker-release.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
name: Trigger Docker build on release
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [released]
|
||||||
|
jobs:
|
||||||
|
curl:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: alpine:latest
|
||||||
|
steps:
|
||||||
|
- name: curl
|
||||||
|
run: |
|
||||||
|
apk add curl bash
|
||||||
|
curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Travis-API-Version: 3" -H "Authorization: token ${{ secrets.TRAVIS_CI_TOKEN }}" -d '{"request":{"branch":"master"}}' https://api.travis-ci.com/repo/frappe%2Ffrappe_docker/requests
|
21
CODEOWNERS
21
CODEOWNERS
@ -3,17 +3,16 @@
|
|||||||
# These owners will be the default owners for everything in
|
# These owners will be the default owners for everything in
|
||||||
# the repo. Unless a later match takes precedence,
|
# the repo. Unless a later match takes precedence,
|
||||||
|
|
||||||
* @nabinhait
|
manufacturing/ @rohitwaghchaure @marination
|
||||||
manufacturing/ @rohitwaghchaure
|
|
||||||
accounts/ @deepeshgarg007 @nextchamp-saqib
|
accounts/ @deepeshgarg007 @nextchamp-saqib
|
||||||
loan_management/ @deepeshgarg007
|
loan_management/ @deepeshgarg007 @rohitwaghchaure
|
||||||
pos* @nextchamp-saqib
|
pos* @nextchamp-saqib @rohitwaghchaure
|
||||||
assets/ @nextchamp-saqib
|
assets/ @nextchamp-saqib @deepeshgarg007
|
||||||
stock/ @marination @rohitwaghchaure
|
stock/ @marination @rohitwaghchaure
|
||||||
buying/ @marination @rohitwaghchaure
|
buying/ @marination @deepeshgarg007
|
||||||
hr/ @Anurag810
|
hr/ @Anurag810 @rohitwaghchaure
|
||||||
projects/ @hrwX
|
projects/ @hrwX @nextchamp-saqib
|
||||||
support/ @hrwX
|
support/ @hrwX @marination
|
||||||
healthcare/ @ruchamahabal
|
healthcare/ @ruchamahabal @marination
|
||||||
erpnext_integrations/ @Mangesh-Khairnar
|
erpnext_integrations/ @Mangesh-Khairnar @nextchamp-saqib
|
||||||
requirements.txt @gavindsouza
|
requirements.txt @gavindsouza
|
||||||
|
@ -5,7 +5,22 @@ import frappe
|
|||||||
import json
|
import json
|
||||||
from frappe.utils import nowdate, add_months, get_date_str
|
from frappe.utils import nowdate, add_months, get_date_str
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from erpnext.accounts.utils import get_fiscal_year, get_account_name
|
from erpnext.accounts.utils import get_fiscal_year, get_account_name, FiscalYearError
|
||||||
|
|
||||||
|
def _get_fiscal_year(date=None):
|
||||||
|
try:
|
||||||
|
fiscal_year = get_fiscal_year(date=nowdate(), as_dict=True)
|
||||||
|
return fiscal_year
|
||||||
|
|
||||||
|
except FiscalYearError:
|
||||||
|
#if no fiscal year for current date then get default fiscal year
|
||||||
|
try:
|
||||||
|
fiscal_year = get_fiscal_year(as_dict=True)
|
||||||
|
return fiscal_year
|
||||||
|
|
||||||
|
except FiscalYearError:
|
||||||
|
#if still no fiscal year found then no accounting data created, return
|
||||||
|
return None
|
||||||
|
|
||||||
def get_company_for_dashboards():
|
def get_company_for_dashboards():
|
||||||
company = frappe.defaults.get_defaults().company
|
company = frappe.defaults.get_defaults().company
|
||||||
@ -18,10 +33,16 @@ def get_company_for_dashboards():
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
|
|
||||||
|
fiscal_year = _get_fiscal_year(nowdate())
|
||||||
|
|
||||||
|
if not fiscal_year:
|
||||||
|
return frappe._dict()
|
||||||
|
|
||||||
return frappe._dict({
|
return frappe._dict({
|
||||||
"dashboards": get_dashboards(),
|
"dashboards": get_dashboards(),
|
||||||
"charts": get_charts(),
|
"charts": get_charts(fiscal_year),
|
||||||
"number_cards": get_number_cards()
|
"number_cards": get_number_cards(fiscal_year)
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_dashboards():
|
def get_dashboards():
|
||||||
@ -46,10 +67,9 @@ def get_dashboards():
|
|||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def get_charts():
|
def get_charts(fiscal_year):
|
||||||
company = frappe.get_doc("Company", get_company_for_dashboards())
|
company = frappe.get_doc("Company", get_company_for_dashboards())
|
||||||
bank_account = company.default_bank_account or get_account_name("Bank", company=company.name)
|
bank_account = company.default_bank_account or get_account_name("Bank", company=company.name)
|
||||||
fiscal_year = get_fiscal_year(date=nowdate())
|
|
||||||
default_cost_center = company.cost_center
|
default_cost_center = company.cost_center
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@ -61,8 +81,8 @@ def get_charts():
|
|||||||
"filters_json": json.dumps({
|
"filters_json": json.dumps({
|
||||||
"company": company.name,
|
"company": company.name,
|
||||||
"filter_based_on": "Fiscal Year",
|
"filter_based_on": "Fiscal Year",
|
||||||
"from_fiscal_year": fiscal_year[0],
|
"from_fiscal_year": fiscal_year.get('name'),
|
||||||
"to_fiscal_year": fiscal_year[0],
|
"to_fiscal_year": fiscal_year.get('name'),
|
||||||
"periodicity": "Monthly",
|
"periodicity": "Monthly",
|
||||||
"include_default_book_entries": 1
|
"include_default_book_entries": 1
|
||||||
}),
|
}),
|
||||||
@ -158,8 +178,8 @@ def get_charts():
|
|||||||
"report_name": "Budget Variance Report",
|
"report_name": "Budget Variance Report",
|
||||||
"filters_json": json.dumps({
|
"filters_json": json.dumps({
|
||||||
"company": company.name,
|
"company": company.name,
|
||||||
"from_fiscal_year": fiscal_year[0],
|
"from_fiscal_year": fiscal_year.get('name'),
|
||||||
"to_fiscal_year": fiscal_year[0],
|
"to_fiscal_year": fiscal_year.get('name'),
|
||||||
"period": "Monthly",
|
"period": "Monthly",
|
||||||
"budget_against": "Cost Center"
|
"budget_against": "Cost Center"
|
||||||
}),
|
}),
|
||||||
@ -190,10 +210,10 @@ def get_charts():
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_number_cards():
|
def get_number_cards(fiscal_year):
|
||||||
fiscal_year = get_fiscal_year(date=nowdate())
|
|
||||||
year_start_date = get_date_str(fiscal_year[1])
|
year_start_date = get_date_str(fiscal_year.get("year_start_date"))
|
||||||
year_end_date = get_date_str(fiscal_year[2])
|
year_end_date = get_date_str(fiscal_year.get("year_end_date"))
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"doctype": "Number Card",
|
"doctype": "Number Card",
|
||||||
|
@ -2,10 +2,11 @@ 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, get_last_day, cint, get_link_to_form
|
from frappe.utils import date_diff, add_months, today, getdate, add_days, flt, get_last_day, get_first_day, cint, get_link_to_form, rounded
|
||||||
from erpnext.accounts.utils import get_account_currency
|
from erpnext.accounts.utils import get_account_currency
|
||||||
from frappe.email import sendmail_to_system_managers
|
from frappe.email import sendmail_to_system_managers
|
||||||
from frappe.utils.background_jobs import enqueue
|
from frappe.utils.background_jobs import enqueue
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||||
|
|
||||||
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 '''
|
||||||
@ -109,6 +110,18 @@ def get_booking_dates(doc, item, posting_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)
|
||||||
|
|
||||||
|
prev_gl_via_je = frappe.db.sql('''
|
||||||
|
SELECT p.name, p.posting_date FROM `tabJournal Entry` p, `tabJournal Entry Account` c
|
||||||
|
WHERE p.name = c.parent and p.company=%s and c.account=%s
|
||||||
|
and c.reference_type=%s and c.reference_name=%s
|
||||||
|
and c.reference_detail_no=%s and c.docstatus < 2 order by posting_date desc limit 1
|
||||||
|
''', (doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
|
||||||
|
|
||||||
|
if prev_gl_via_je:
|
||||||
|
if (not prev_gl_entry) or (prev_gl_entry and
|
||||||
|
prev_gl_entry[0].posting_date < prev_gl_via_je[0].posting_date):
|
||||||
|
prev_gl_entry = prev_gl_via_je
|
||||||
|
|
||||||
if prev_gl_entry:
|
if prev_gl_entry:
|
||||||
start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1))
|
start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1))
|
||||||
else:
|
else:
|
||||||
@ -130,14 +143,48 @@ def get_booking_dates(doc, item, posting_date=None):
|
|||||||
else:
|
else:
|
||||||
return None, None, None
|
return None, None, None
|
||||||
|
|
||||||
def calculate_amount(doc, item, last_gl_entry, total_days, total_booking_days, account_currency):
|
def calculate_monthly_amount(doc, item, last_gl_entry, start_date, end_date, total_days, total_booking_days, account_currency):
|
||||||
if doc.doctype == "Sales Invoice":
|
amount, base_amount = 0, 0
|
||||||
total_credit_debit, total_credit_debit_currency = "debit", "debit_in_account_currency"
|
|
||||||
deferred_account = "deferred_revenue_account"
|
|
||||||
else:
|
|
||||||
total_credit_debit, total_credit_debit_currency = "credit", "credit_in_account_currency"
|
|
||||||
deferred_account = "deferred_expense_account"
|
|
||||||
|
|
||||||
|
if not last_gl_entry:
|
||||||
|
total_months = (item.service_end_date.year - item.service_start_date.year) * 12 + \
|
||||||
|
(item.service_end_date.month - item.service_start_date.month) + 1
|
||||||
|
|
||||||
|
prorate_factor = flt(date_diff(item.service_end_date, item.service_start_date)) \
|
||||||
|
/ flt(date_diff(get_last_day(item.service_end_date), get_first_day(item.service_start_date)))
|
||||||
|
|
||||||
|
actual_months = rounded(total_months * prorate_factor, 1)
|
||||||
|
|
||||||
|
already_booked_amount, already_booked_amount_in_account_currency = get_already_booked_amount(doc, item)
|
||||||
|
base_amount = flt(item.base_net_amount / actual_months, item.precision("base_net_amount"))
|
||||||
|
|
||||||
|
if base_amount + already_booked_amount > item.base_net_amount:
|
||||||
|
base_amount = item.base_net_amount - already_booked_amount
|
||||||
|
|
||||||
|
if account_currency==doc.company_currency:
|
||||||
|
amount = base_amount
|
||||||
|
else:
|
||||||
|
amount = flt(item.net_amount/actual_months, item.precision("net_amount"))
|
||||||
|
if amount + already_booked_amount_in_account_currency > item.net_amount:
|
||||||
|
amount = item.net_amount - already_booked_amount_in_account_currency
|
||||||
|
|
||||||
|
if not (get_first_day(start_date) == start_date and get_last_day(end_date) == end_date):
|
||||||
|
partial_month = flt(date_diff(end_date, start_date)) \
|
||||||
|
/ flt(date_diff(get_last_day(end_date), get_first_day(start_date)))
|
||||||
|
|
||||||
|
base_amount = rounded(partial_month, 1) * base_amount
|
||||||
|
amount = rounded(partial_month, 1) * amount
|
||||||
|
else:
|
||||||
|
already_booked_amount, already_booked_amount_in_account_currency = get_already_booked_amount(doc, item)
|
||||||
|
base_amount = flt(item.base_net_amount - already_booked_amount, item.precision("base_net_amount"))
|
||||||
|
if account_currency==doc.company_currency:
|
||||||
|
amount = base_amount
|
||||||
|
else:
|
||||||
|
amount = flt(item.net_amount - already_booked_amount_in_account_currency, item.precision("net_amount"))
|
||||||
|
|
||||||
|
return amount, base_amount
|
||||||
|
|
||||||
|
def calculate_amount(doc, item, last_gl_entry, total_days, total_booking_days, account_currency):
|
||||||
amount, base_amount = 0, 0
|
amount, base_amount = 0, 0
|
||||||
if not last_gl_entry:
|
if not last_gl_entry:
|
||||||
base_amount = flt(item.base_net_amount*total_booking_days/flt(total_days), item.precision("base_net_amount"))
|
base_amount = flt(item.base_net_amount*total_booking_days/flt(total_days), item.precision("base_net_amount"))
|
||||||
@ -146,27 +193,55 @@ def calculate_amount(doc, item, last_gl_entry, total_days, total_booking_days, a
|
|||||||
else:
|
else:
|
||||||
amount = flt(item.net_amount*total_booking_days/flt(total_days), item.precision("net_amount"))
|
amount = flt(item.net_amount*total_booking_days/flt(total_days), item.precision("net_amount"))
|
||||||
else:
|
else:
|
||||||
gl_entries_details = frappe.db.sql('''
|
already_booked_amount, already_booked_amount_in_account_currency = get_already_booked_amount(doc, item)
|
||||||
select sum({0}) as total_credit, sum({1}) as total_credit_in_account_currency, voucher_detail_no
|
|
||||||
from `tabGL Entry` where company=%s and account=%s and voucher_type=%s and voucher_no=%s and voucher_detail_no=%s
|
|
||||||
group by voucher_detail_no
|
|
||||||
'''.format(total_credit_debit, total_credit_debit_currency),
|
|
||||||
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
|
|
||||||
already_booked_amount = gl_entries_details[0].total_credit if gl_entries_details else 0
|
|
||||||
base_amount = flt(item.base_net_amount - already_booked_amount, item.precision("base_net_amount"))
|
base_amount = flt(item.base_net_amount - already_booked_amount, item.precision("base_net_amount"))
|
||||||
if account_currency==doc.company_currency:
|
if account_currency==doc.company_currency:
|
||||||
amount = base_amount
|
amount = base_amount
|
||||||
else:
|
else:
|
||||||
already_booked_amount_in_account_currency = gl_entries_details[0].total_credit_in_account_currency if gl_entries_details else 0
|
|
||||||
amount = flt(item.net_amount - already_booked_amount_in_account_currency, item.precision("net_amount"))
|
amount = flt(item.net_amount - already_booked_amount_in_account_currency, item.precision("net_amount"))
|
||||||
|
|
||||||
return amount, base_amount
|
return amount, base_amount
|
||||||
|
|
||||||
|
def get_already_booked_amount(doc, item):
|
||||||
|
if doc.doctype == "Sales Invoice":
|
||||||
|
total_credit_debit, total_credit_debit_currency = "debit", "debit_in_account_currency"
|
||||||
|
deferred_account = "deferred_revenue_account"
|
||||||
|
else:
|
||||||
|
total_credit_debit, total_credit_debit_currency = "credit", "credit_in_account_currency"
|
||||||
|
deferred_account = "deferred_expense_account"
|
||||||
|
|
||||||
|
gl_entries_details = frappe.db.sql('''
|
||||||
|
select sum({0}) as total_credit, sum({1}) as total_credit_in_account_currency, voucher_detail_no
|
||||||
|
from `tabGL Entry` where company=%s and account=%s and voucher_type=%s and voucher_no=%s and voucher_detail_no=%s
|
||||||
|
group by voucher_detail_no
|
||||||
|
'''.format(total_credit_debit, total_credit_debit_currency),
|
||||||
|
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
|
||||||
|
|
||||||
|
journal_entry_details = frappe.db.sql('''
|
||||||
|
SELECT sum(c.{0}) as total_credit, sum(c.{1}) as total_credit_in_account_currency, reference_detail_no
|
||||||
|
FROM `tabJournal Entry` p , `tabJournal Entry Account` c WHERE p.name = c.parent and
|
||||||
|
p.company = %s and c.account=%s and c.reference_type=%s and c.reference_name=%s and c.reference_detail_no=%s
|
||||||
|
and p.docstatus < 2 group by reference_detail_no
|
||||||
|
'''.format(total_credit_debit, total_credit_debit_currency),
|
||||||
|
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
|
||||||
|
|
||||||
|
already_booked_amount = gl_entries_details[0].total_credit if gl_entries_details else 0
|
||||||
|
already_booked_amount += journal_entry_details[0].total_credit if journal_entry_details else 0
|
||||||
|
|
||||||
|
if doc.currency == doc.company_currency:
|
||||||
|
already_booked_amount_in_account_currency = already_booked_amount
|
||||||
|
else:
|
||||||
|
already_booked_amount_in_account_currency = gl_entries_details[0].total_credit_in_account_currency if gl_entries_details else 0
|
||||||
|
already_booked_amount_in_account_currency += journal_entry_details[0].total_credit_in_account_currency if journal_entry_details else 0
|
||||||
|
|
||||||
|
return already_booked_amount, already_booked_amount_in_account_currency
|
||||||
|
|
||||||
def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
||||||
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"
|
||||||
|
|
||||||
def _book_deferred_revenue_or_expense(item):
|
def _book_deferred_revenue_or_expense(item, via_journal_entry, submit_journal_entry, book_deferred_entries_based_on):
|
||||||
start_date, end_date, last_gl_entry = get_booking_dates(doc, item, posting_date=posting_date)
|
start_date, end_date, last_gl_entry = get_booking_dates(doc, item, posting_date=posting_date)
|
||||||
if not (start_date and end_date): return
|
if not (start_date and end_date): return
|
||||||
|
|
||||||
@ -181,23 +256,34 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
|||||||
total_days = date_diff(item.service_end_date, item.service_start_date) + 1
|
total_days = date_diff(item.service_end_date, item.service_start_date) + 1
|
||||||
total_booking_days = date_diff(end_date, start_date) + 1
|
total_booking_days = date_diff(end_date, start_date) + 1
|
||||||
|
|
||||||
amount, base_amount = calculate_amount(doc, item, last_gl_entry,
|
if book_deferred_entries_based_on == 'Months':
|
||||||
total_days, total_booking_days, account_currency)
|
amount, base_amount = calculate_monthly_amount(doc, item, last_gl_entry,
|
||||||
|
start_date, end_date, total_days, total_booking_days, account_currency)
|
||||||
|
else:
|
||||||
|
amount, base_amount = calculate_amount(doc, item, last_gl_entry,
|
||||||
|
total_days, total_booking_days, account_currency)
|
||||||
|
|
||||||
make_gl_entries(doc, credit_account, debit_account, against,
|
if via_journal_entry:
|
||||||
amount, base_amount, end_date, project, account_currency, item.cost_center, item, deferred_process)
|
book_revenue_via_journal_entry(doc, credit_account, debit_account, against, amount,
|
||||||
|
base_amount, end_date, project, account_currency, item.cost_center, item, deferred_process, submit_journal_entry)
|
||||||
|
else:
|
||||||
|
make_gl_entries(doc, credit_account, debit_account, against,
|
||||||
|
amount, base_amount, end_date, project, account_currency, item.cost_center, item, deferred_process)
|
||||||
|
|
||||||
# Returned in case of any errors because it tries to submit the same record again and again in case of errors
|
# Returned in case of any errors because it tries to submit the same record again and again in case of errors
|
||||||
if frappe.flags.deferred_accounting_error:
|
if frappe.flags.deferred_accounting_error:
|
||||||
return
|
return
|
||||||
|
|
||||||
if getdate(end_date) < getdate(posting_date) and not last_gl_entry:
|
if getdate(end_date) < getdate(posting_date) and not last_gl_entry:
|
||||||
_book_deferred_revenue_or_expense(item)
|
_book_deferred_revenue_or_expense(item, via_journal_entry, submit_journal_entry, book_deferred_entries_based_on)
|
||||||
|
|
||||||
|
via_journal_entry = cint(frappe.db.get_singles_value('Accounts Settings', 'book_deferred_entries_via_journal_entry'))
|
||||||
|
submit_journal_entry = cint(frappe.db.get_singles_value('Accounts Settings', 'submit_journal_entries'))
|
||||||
|
book_deferred_entries_based_on = frappe.db.get_singles_value('Accounts Settings', 'book_deferred_entries_based_on')
|
||||||
|
|
||||||
for item in doc.get('items'):
|
for item in doc.get('items'):
|
||||||
if item.get(enable_check):
|
if item.get(enable_check):
|
||||||
_book_deferred_revenue_or_expense(item)
|
_book_deferred_revenue_or_expense(item, via_journal_entry, submit_journal_entry, book_deferred_entries_based_on)
|
||||||
|
|
||||||
def process_deferred_accounting(posting_date=None):
|
def process_deferred_accounting(posting_date=None):
|
||||||
''' Converts deferred income/expense into income/expense
|
''' Converts deferred income/expense into income/expense
|
||||||
@ -281,3 +367,83 @@ def send_mail(deferred_process):
|
|||||||
and submit manually after resolving errors
|
and submit manually after resolving errors
|
||||||
""").format(get_link_to_form('Process Deferred Accounting', deferred_process))
|
""").format(get_link_to_form('Process Deferred Accounting', deferred_process))
|
||||||
sendmail_to_system_managers(title, content)
|
sendmail_to_system_managers(title, content)
|
||||||
|
|
||||||
|
def book_revenue_via_journal_entry(doc, credit_account, debit_account, against,
|
||||||
|
amount, base_amount, posting_date, project, account_currency, cost_center, item,
|
||||||
|
deferred_process=None, submit='No'):
|
||||||
|
|
||||||
|
if amount == 0: return
|
||||||
|
|
||||||
|
journal_entry = frappe.new_doc('Journal Entry')
|
||||||
|
journal_entry.posting_date = posting_date
|
||||||
|
journal_entry.company = doc.company
|
||||||
|
journal_entry.voucher_type = 'Deferred Revenue' if doc.doctype == 'Sales Invoice' \
|
||||||
|
else 'Deferred Expense'
|
||||||
|
|
||||||
|
debit_entry = {
|
||||||
|
'account': credit_account,
|
||||||
|
'credit': base_amount,
|
||||||
|
'credit_in_account_currency': amount,
|
||||||
|
'party_type': 'Customer' if doc.doctype == 'Sales Invoice' else 'Supplier',
|
||||||
|
'party': against,
|
||||||
|
'account_currency': account_currency,
|
||||||
|
'reference_name': doc.name,
|
||||||
|
'reference_type': doc.doctype,
|
||||||
|
'reference_detail_no': item.name,
|
||||||
|
'cost_center': cost_center,
|
||||||
|
'project': project,
|
||||||
|
}
|
||||||
|
|
||||||
|
credit_entry = {
|
||||||
|
'account': debit_account,
|
||||||
|
'debit': base_amount,
|
||||||
|
'debit_in_account_currency': amount,
|
||||||
|
'party_type': 'Customer' if doc.doctype == 'Sales Invoice' else 'Supplier',
|
||||||
|
'party': against,
|
||||||
|
'account_currency': account_currency,
|
||||||
|
'reference_name': doc.name,
|
||||||
|
'reference_type': doc.doctype,
|
||||||
|
'reference_detail_no': item.name,
|
||||||
|
'cost_center': cost_center,
|
||||||
|
'project': project,
|
||||||
|
}
|
||||||
|
|
||||||
|
for dimension in get_accounting_dimensions():
|
||||||
|
debit_entry.update({
|
||||||
|
dimension: item.get(dimension)
|
||||||
|
})
|
||||||
|
|
||||||
|
credit_entry.update({
|
||||||
|
dimension: item.get(dimension)
|
||||||
|
})
|
||||||
|
|
||||||
|
journal_entry.append('accounts', debit_entry)
|
||||||
|
journal_entry.append('accounts', credit_entry)
|
||||||
|
|
||||||
|
try:
|
||||||
|
journal_entry.save()
|
||||||
|
|
||||||
|
if submit:
|
||||||
|
journal_entry.submit()
|
||||||
|
except:
|
||||||
|
frappe.db.rollback()
|
||||||
|
traceback = frappe.get_traceback()
|
||||||
|
frappe.log_error(message=traceback)
|
||||||
|
|
||||||
|
frappe.flags.deferred_accounting_error = True
|
||||||
|
|
||||||
|
def get_deferred_booking_accounts(doctype, voucher_detail_no, dr_or_cr):
|
||||||
|
|
||||||
|
if doctype == 'Sales Invoice':
|
||||||
|
credit_account, debit_account = frappe.db.get_value('Sales Invoice Item', {'name': voucher_detail_no},
|
||||||
|
['income_account', 'deferred_revenue_account'])
|
||||||
|
else:
|
||||||
|
credit_account, debit_account = frappe.db.get_value('Purchase Invoice Item', {'name': voucher_detail_no},
|
||||||
|
['deferred_expense_account', 'expense_account'])
|
||||||
|
|
||||||
|
if dr_or_cr == 'Debit':
|
||||||
|
return debit_account
|
||||||
|
else:
|
||||||
|
return credit_account
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Accounts Receivable",
|
"label": "Accounts Receivable",
|
||||||
"links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Billed\",\n \"name\": \"Ordered Items To Be Billed\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]"
|
"links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -98,7 +98,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Accounting",
|
"label": "Accounting",
|
||||||
"modified": "2020-05-27 20:34:50.949772",
|
"modified": "2020-06-19 12:42:44.054598",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounting",
|
"name": "Accounting",
|
||||||
@ -122,11 +122,6 @@
|
|||||||
"link_to": "Purchase Invoice",
|
"link_to": "Purchase Invoice",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"label": "Dashboard",
|
|
||||||
"link_to": "Accounts",
|
|
||||||
"type": "Dashboard"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"label": "Journal Entry",
|
"label": "Journal Entry",
|
||||||
"link_to": "Journal Entry",
|
"link_to": "Journal Entry",
|
||||||
@ -151,6 +146,11 @@
|
|||||||
"label": "Trial Balance",
|
"label": "Trial Balance",
|
||||||
"link_to": "Trial Balance",
|
"link_to": "Trial Balance",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Dashboard",
|
||||||
|
"link_to": "Accounts",
|
||||||
|
"type": "Dashboard"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -14,6 +14,9 @@ frappe.treeview_settings["Account"] = {
|
|||||||
on_change: function() {
|
on_change: function() {
|
||||||
var me = frappe.treeview_settings['Account'].treeview;
|
var me = frappe.treeview_settings['Account'].treeview;
|
||||||
var company = me.page.fields_dict.company.get_value();
|
var company = me.page.fields_dict.company.get_value();
|
||||||
|
if (!company) {
|
||||||
|
frappe.throw(__("Please set a Company"));
|
||||||
|
}
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.account.account.get_root_company",
|
method: "erpnext.accounts.doctype.account.account.get_root_company",
|
||||||
args: {
|
args: {
|
||||||
|
@ -72,7 +72,11 @@ def make_dimension_in_accounting_doctypes(doc):
|
|||||||
if doctype == "Budget":
|
if doctype == "Budget":
|
||||||
add_dimension_to_budget_doctype(df, doc)
|
add_dimension_to_budget_doctype(df, doc)
|
||||||
else:
|
else:
|
||||||
create_custom_field(doctype, df)
|
meta = frappe.get_meta(doctype, cached=False)
|
||||||
|
fieldnames = [d.fieldname for d in meta.get("fields")]
|
||||||
|
|
||||||
|
if df['fieldname'] not in fieldnames:
|
||||||
|
create_custom_field(doctype, df)
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
|
@ -22,7 +22,12 @@
|
|||||||
"allow_cost_center_in_entry_of_bs_account",
|
"allow_cost_center_in_entry_of_bs_account",
|
||||||
"add_taxes_from_item_tax_template",
|
"add_taxes_from_item_tax_template",
|
||||||
"automatically_fetch_payment_terms",
|
"automatically_fetch_payment_terms",
|
||||||
|
"deferred_accounting_settings_section",
|
||||||
"automatically_process_deferred_accounting_entry",
|
"automatically_process_deferred_accounting_entry",
|
||||||
|
"book_deferred_entries_based_on",
|
||||||
|
"column_break_18",
|
||||||
|
"book_deferred_entries_via_journal_entry",
|
||||||
|
"submit_journal_entries",
|
||||||
"print_settings",
|
"print_settings",
|
||||||
"show_inclusive_tax_in_print",
|
"show_inclusive_tax_in_print",
|
||||||
"column_break_12",
|
"column_break_12",
|
||||||
@ -189,13 +194,45 @@
|
|||||||
"fieldname": "automatically_process_deferred_accounting_entry",
|
"fieldname": "automatically_process_deferred_accounting_entry",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Automatically Process Deferred Accounting Entry"
|
"label": "Automatically Process Deferred Accounting Entry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "deferred_accounting_settings_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Deferred Accounting Settings"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_18",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"description": "If this is unchecked direct GL Entries will be created to book Deferred Revenue/Expense",
|
||||||
|
"fieldname": "book_deferred_entries_via_journal_entry",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Book Deferred Entries Via Journal Entry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"depends_on": "eval:doc.book_deferred_entries_via_journal_entry",
|
||||||
|
"description": "If this is unchecked Journal Entries will be saved in a Draft state and will have to be submitted manually",
|
||||||
|
"fieldname": "submit_journal_entries",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Submit Journal Entries"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "Days",
|
||||||
|
"description": "If \"Months\" is selected then fixed amount will be booked as deferred revenue or expense for each month irrespective of number of days in a month. Will be prorated if deferred revenue or expense is not booked for an entire month.",
|
||||||
|
"fieldname": "book_deferred_entries_based_on",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Book Deferred Entries Based On",
|
||||||
|
"options": "Days\nMonths"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "icon-cog",
|
"icon": "icon-cog",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2019-12-19 16:58:17.395595",
|
"modified": "2020-06-22 20:13:26.043092",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
|
@ -14,7 +14,18 @@ frappe.ui.form.on('Cost Center', {
|
|||||||
is_group: 1
|
is_group: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
frm.set_query("cost_center", "distributed_cost_center", function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
company: frm.doc.company,
|
||||||
|
is_group: 0,
|
||||||
|
enable_distributed_cost_center: 0,
|
||||||
|
name: ['!=', frm.doc.name]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
},
|
},
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
if (!frm.is_new()) {
|
if (!frm.is_new()) {
|
||||||
@ -60,8 +71,13 @@ frappe.ui.form.on('Cost Center', {
|
|||||||
"label": "Cost Center Number",
|
"label": "Cost Center Number",
|
||||||
"fieldname": "cost_center_number",
|
"fieldname": "cost_center_number",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"reqd": 1,
|
|
||||||
"default": frm.doc.cost_center_number
|
"default": frm.doc.cost_center_number
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": __("Merge with existing"),
|
||||||
|
"fieldname": "merge",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"default": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
@ -76,8 +92,9 @@ frappe.ui.form.on('Cost Center', {
|
|||||||
args: {
|
args: {
|
||||||
docname: frm.doc.name,
|
docname: frm.doc.name,
|
||||||
cost_center_name: data.cost_center_name,
|
cost_center_name: data.cost_center_name,
|
||||||
cost_center_number: data.cost_center_number,
|
cost_center_number: cstr(data.cost_center_number),
|
||||||
company: frm.doc.company
|
company: frm.doc.company,
|
||||||
|
merge: data.merge
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
frappe.dom.unfreeze();
|
frappe.dom.unfreeze();
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
"cb0",
|
"cb0",
|
||||||
"is_group",
|
"is_group",
|
||||||
"disabled",
|
"disabled",
|
||||||
|
"section_break_9",
|
||||||
|
"enable_distributed_cost_center",
|
||||||
|
"distributed_cost_center",
|
||||||
"lft",
|
"lft",
|
||||||
"rgt",
|
"rgt",
|
||||||
"old_parent"
|
"old_parent"
|
||||||
@ -119,13 +122,31 @@
|
|||||||
"fieldname": "disabled",
|
"fieldname": "disabled",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Disabled"
|
"label": "Disabled"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "enable_distributed_cost_center",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Enable Distributed Cost Center"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.is_group==0",
|
||||||
|
"fieldname": "section_break_9",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "enable_distributed_cost_center",
|
||||||
|
"fieldname": "distributed_cost_center",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"label": "Distributed Cost Center",
|
||||||
|
"options": "Distributed Cost Center"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-money",
|
"icon": "fa fa-money",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_tree": 1,
|
"is_tree": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-29 16:09:30.025214",
|
"modified": "2020-06-17 16:09:30.025214",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Cost Center",
|
"name": "Cost Center",
|
||||||
|
@ -19,6 +19,24 @@ class CostCenter(NestedSet):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_mandatory()
|
self.validate_mandatory()
|
||||||
self.validate_parent_cost_center()
|
self.validate_parent_cost_center()
|
||||||
|
self.validate_distributed_cost_center()
|
||||||
|
|
||||||
|
def validate_distributed_cost_center(self):
|
||||||
|
if cint(self.enable_distributed_cost_center):
|
||||||
|
if not self.distributed_cost_center:
|
||||||
|
frappe.throw(_("Please enter distributed cost center"))
|
||||||
|
if sum(x.percentage_allocation for x in self.distributed_cost_center) != 100:
|
||||||
|
frappe.throw(_("Total percentage allocation for distributed cost center should be equal to 100"))
|
||||||
|
if not self.get('__islocal'):
|
||||||
|
if not cint(frappe.get_cached_value("Cost Center", {"name": self.name}, "enable_distributed_cost_center")) \
|
||||||
|
and self.check_if_part_of_distributed_cost_center():
|
||||||
|
frappe.throw(_("Cannot enable Distributed Cost Center for a Cost Center already allocated in another Distributed Cost Center"))
|
||||||
|
if next((True for x in self.distributed_cost_center if x.cost_center == x.parent), False):
|
||||||
|
frappe.throw(_("Parent Cost Center cannot be added in Distributed Cost Center"))
|
||||||
|
if check_if_distributed_cost_center_enabled(list(x.cost_center for x in self.distributed_cost_center)):
|
||||||
|
frappe.throw(_("A Distributed Cost Center cannot be added in the Distributed Cost Center allocation table."))
|
||||||
|
else:
|
||||||
|
self.distributed_cost_center = []
|
||||||
|
|
||||||
def validate_mandatory(self):
|
def validate_mandatory(self):
|
||||||
if self.cost_center_name != self.company and not self.parent_cost_center:
|
if self.cost_center_name != self.company and not self.parent_cost_center:
|
||||||
@ -43,12 +61,15 @@ class CostCenter(NestedSet):
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
def convert_ledger_to_group(self):
|
def convert_ledger_to_group(self):
|
||||||
|
if cint(self.enable_distributed_cost_center):
|
||||||
|
frappe.throw(_("Cost Center with enabled distributed cost center can not be converted to group"))
|
||||||
|
if self.check_if_part_of_distributed_cost_center():
|
||||||
|
frappe.throw(_("Cost Center Already Allocated in a Distributed Cost Center cannot be converted to group"))
|
||||||
if self.check_gle_exists():
|
if self.check_gle_exists():
|
||||||
frappe.throw(_("Cost Center with existing transactions can not be converted to group"))
|
frappe.throw(_("Cost Center with existing transactions can not be converted to group"))
|
||||||
else:
|
self.is_group = 1
|
||||||
self.is_group = 1
|
self.save()
|
||||||
self.save()
|
return 1
|
||||||
return 1
|
|
||||||
|
|
||||||
def check_gle_exists(self):
|
def check_gle_exists(self):
|
||||||
return frappe.db.get_value("GL Entry", {"cost_center": self.name})
|
return frappe.db.get_value("GL Entry", {"cost_center": self.name})
|
||||||
@ -57,6 +78,9 @@ class CostCenter(NestedSet):
|
|||||||
return frappe.db.sql("select name from `tabCost Center` where \
|
return frappe.db.sql("select name from `tabCost Center` where \
|
||||||
parent_cost_center = %s and docstatus != 2", self.name)
|
parent_cost_center = %s and docstatus != 2", self.name)
|
||||||
|
|
||||||
|
def check_if_part_of_distributed_cost_center(self):
|
||||||
|
return frappe.db.get_value("Distributed Cost Center", {"cost_center": self.name})
|
||||||
|
|
||||||
def before_rename(self, olddn, newdn, merge=False):
|
def before_rename(self, olddn, newdn, merge=False):
|
||||||
# Add company abbr if not provided
|
# Add company abbr if not provided
|
||||||
from erpnext.setup.doctype.company.company import get_name_with_abbr
|
from erpnext.setup.doctype.company.company import get_name_with_abbr
|
||||||
@ -100,3 +124,7 @@ def get_name_with_number(new_account, account_number):
|
|||||||
if account_number and not new_account[0].isdigit():
|
if account_number and not new_account[0].isdigit():
|
||||||
new_account = account_number + " - " + new_account
|
new_account = account_number + " - " + new_account
|
||||||
return new_account
|
return new_account
|
||||||
|
|
||||||
|
def check_if_distributed_cost_center_enabled(cost_center_list):
|
||||||
|
value_list = frappe.get_list("Cost Center", {"name": ["in", cost_center_list]}, "enable_distributed_cost_center", as_list=1)
|
||||||
|
return next((True for x in value_list if x[0]), False)
|
@ -22,6 +22,33 @@ class TestCostCenter(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertRaises(frappe.ValidationError, cost_center.save)
|
self.assertRaises(frappe.ValidationError, cost_center.save)
|
||||||
|
|
||||||
|
def test_validate_distributed_cost_center(self):
|
||||||
|
|
||||||
|
if not frappe.db.get_value('Cost Center', {'name': '_Test Cost Center - _TC'}):
|
||||||
|
frappe.get_doc(test_records[0]).insert()
|
||||||
|
|
||||||
|
if not frappe.db.get_value('Cost Center', {'name': '_Test Cost Center 2 - _TC'}):
|
||||||
|
frappe.get_doc(test_records[1]).insert()
|
||||||
|
|
||||||
|
invalid_distributed_cost_center = frappe.get_doc({
|
||||||
|
"company": "_Test Company",
|
||||||
|
"cost_center_name": "_Test Distributed Cost Center",
|
||||||
|
"doctype": "Cost Center",
|
||||||
|
"is_group": 0,
|
||||||
|
"parent_cost_center": "_Test Company - _TC",
|
||||||
|
"enable_distributed_cost_center": 1,
|
||||||
|
"distributed_cost_center": [{
|
||||||
|
"cost_center": "_Test Cost Center - _TC",
|
||||||
|
"percentage_allocation": 40
|
||||||
|
}, {
|
||||||
|
"cost_center": "_Test Cost Center 2 - _TC",
|
||||||
|
"percentage_allocation": 50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
self.assertRaises(frappe.ValidationError, invalid_distributed_cost_center.save)
|
||||||
|
|
||||||
def create_cost_center(**args):
|
def create_cost_center(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
if args.cost_center_name:
|
if args.cost_center_name:
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"creation": "2020-03-19 12:34:01.500390",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"cost_center",
|
||||||
|
"percentage_allocation"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "cost_center",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Cost Center",
|
||||||
|
"options": "Cost Center",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "percentage_allocation",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Percentage Allocation",
|
||||||
|
"reqd": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2020-03-19 12:54:43.674655",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Distributed Cost Center",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class DistributedCostCenter(Document):
|
||||||
|
pass
|
@ -4,7 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, erpnext
|
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, cint
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.model.naming import set_name_from_naming_options
|
from frappe.model.naming import set_name_from_naming_options
|
||||||
from frappe.model.meta import get_field_precision
|
from frappe.model.meta import get_field_precision
|
||||||
@ -134,10 +134,17 @@ class GLEntry(Document):
|
|||||||
|
|
||||||
return self.cost_center_company[self.cost_center]
|
return self.cost_center_company[self.cost_center]
|
||||||
|
|
||||||
|
def _check_is_group():
|
||||||
|
return cint(frappe.get_cached_value('Cost Center', self.cost_center, 'is_group'))
|
||||||
|
|
||||||
if self.cost_center and _get_cost_center_company() != self.company:
|
if self.cost_center and _get_cost_center_company() != self.company:
|
||||||
frappe.throw(_("{0} {1}: Cost Center {2} does not belong to Company {3}")
|
frappe.throw(_("{0} {1}: Cost Center {2} does not belong to Company {3}")
|
||||||
.format(self.voucher_type, self.voucher_no, self.cost_center, self.company))
|
.format(self.voucher_type, self.voucher_no, self.cost_center, self.company))
|
||||||
|
|
||||||
|
if self.cost_center and _check_is_group():
|
||||||
|
frappe.throw(_("""{0} {1}: Cost Center {2} is a group cost center and group cost centers cannot
|
||||||
|
be used in transactions""").format(self.voucher_type, self.voucher_no, frappe.bold(self.cost_center)))
|
||||||
|
|
||||||
def validate_party(self):
|
def validate_party(self):
|
||||||
validate_party_frozen_disabled(self.party_type, self.party)
|
validate_party_frozen_disabled(self.party_type, self.party)
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
|
|||||||
// payroll entry
|
// payroll entry
|
||||||
if(jvd.reference_type==="Payroll Entry") {
|
if(jvd.reference_type==="Payroll Entry") {
|
||||||
return {
|
return {
|
||||||
query: "erpnext.hr.doctype.payroll_entry.payroll_entry.get_payroll_entries_for_jv",
|
query: "erpnext.payroll.doctype.payroll_entry.payroll_entry.get_payroll_entries_for_jv",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
"label": "Entry Type",
|
"label": "Entry Type",
|
||||||
"oldfieldname": "voucher_type",
|
"oldfieldname": "voucher_type",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "Journal Entry\nInter Company Journal Entry\nBank Entry\nCash Entry\nCredit Card Entry\nDebit Note\nCredit Note\nContra Entry\nExcise Entry\nWrite Off Entry\nOpening Entry\nDepreciation Entry\nExchange Rate Revaluation",
|
"options": "Journal Entry\nInter Company Journal Entry\nBank Entry\nCash Entry\nCredit Card Entry\nDebit Note\nCredit Note\nContra Entry\nExcise Entry\nWrite Off Entry\nOpening Entry\nDepreciation Entry\nExchange Rate Revaluation\nDeferred Revenue\nDeferred Expense",
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
@ -191,6 +191,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "total_debit",
|
"fieldname": "total_debit",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "Total Debit",
|
"label": "Total Debit",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "total_debit",
|
"oldfieldname": "total_debit",
|
||||||
@ -252,7 +253,6 @@
|
|||||||
"fieldname": "total_amount",
|
"fieldname": "total_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Total Amount",
|
"label": "Total Amount",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "total_amount_currency",
|
"options": "total_amount_currency",
|
||||||
@ -503,7 +503,7 @@
|
|||||||
"idx": 176,
|
"idx": 176,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-29 10:55:28.240916",
|
"modified": "2020-06-02 18:15:46.955697",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Journal Entry",
|
"name": "Journal Entry",
|
||||||
|
@ -10,6 +10,7 @@ from erpnext.accounts.utils import get_balance_on, get_account_currency
|
|||||||
from erpnext.accounts.party import get_party_account
|
from erpnext.accounts.party import get_party_account
|
||||||
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
|
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
|
||||||
from erpnext.accounts.doctype.invoice_discounting.invoice_discounting import get_party_account_based_on_invoice_discounting
|
from erpnext.accounts.doctype.invoice_discounting.invoice_discounting import get_party_account_based_on_invoice_discounting
|
||||||
|
from erpnext.accounts.deferred_revenue import get_deferred_booking_accounts
|
||||||
|
|
||||||
from six import string_types, iteritems
|
from six import string_types, iteritems
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ class JournalEntry(AccountsController):
|
|||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
||||||
from erpnext.hr.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip
|
from erpnext.payroll.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip
|
||||||
unlink_ref_doc_from_payment_entries(self)
|
unlink_ref_doc_from_payment_entries(self)
|
||||||
unlink_ref_doc_from_salary_slip(self.name)
|
unlink_ref_doc_from_salary_slip(self.name)
|
||||||
self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry')
|
self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry')
|
||||||
@ -265,7 +266,10 @@ class JournalEntry(AccountsController):
|
|||||||
# set totals
|
# set totals
|
||||||
if not d.reference_name in self.reference_totals:
|
if not d.reference_name in self.reference_totals:
|
||||||
self.reference_totals[d.reference_name] = 0.0
|
self.reference_totals[d.reference_name] = 0.0
|
||||||
self.reference_totals[d.reference_name] += flt(d.get(dr_or_cr))
|
|
||||||
|
if self.voucher_type not in ('Deferred Revenue', 'Deferred Expense'):
|
||||||
|
self.reference_totals[d.reference_name] += flt(d.get(dr_or_cr))
|
||||||
|
|
||||||
self.reference_types[d.reference_name] = d.reference_type
|
self.reference_types[d.reference_name] = d.reference_type
|
||||||
self.reference_accounts[d.reference_name] = d.account
|
self.reference_accounts[d.reference_name] = d.account
|
||||||
|
|
||||||
@ -277,10 +281,16 @@ class JournalEntry(AccountsController):
|
|||||||
|
|
||||||
# check if party and account match
|
# check if party and account match
|
||||||
if d.reference_type in ("Sales Invoice", "Purchase Invoice"):
|
if d.reference_type in ("Sales Invoice", "Purchase Invoice"):
|
||||||
if d.reference_type == "Sales Invoice":
|
if self.voucher_type in ('Deferred Revenue', 'Deferred Expense') and d.reference_detail_no:
|
||||||
party_account = get_party_account_based_on_invoice_discounting(d.reference_name) or against_voucher[1]
|
debit_or_credit = 'Debit' if d.debit else 'Credit'
|
||||||
|
party_account = get_deferred_booking_accounts(d.reference_type, d.reference_detail_no,
|
||||||
|
debit_or_credit)
|
||||||
else:
|
else:
|
||||||
party_account = against_voucher[1]
|
if d.reference_type == "Sales Invoice":
|
||||||
|
party_account = get_party_account_based_on_invoice_discounting(d.reference_name) or against_voucher[1]
|
||||||
|
else:
|
||||||
|
party_account = against_voucher[1]
|
||||||
|
|
||||||
if (against_voucher[0] != d.party or party_account != d.account):
|
if (against_voucher[0] != d.party or party_account != d.account):
|
||||||
frappe.throw(_("Row {0}: Party / Account does not match with {1} / {2} in {3} {4}")
|
frappe.throw(_("Row {0}: Party / Account does not match with {1} / {2} in {3} {4}")
|
||||||
.format(d.idx, field_dict.get(d.reference_type)[0], field_dict.get(d.reference_type)[1],
|
.format(d.idx, field_dict.get(d.reference_type)[0], field_dict.get(d.reference_type)[1],
|
||||||
@ -513,14 +523,20 @@ class JournalEntry(AccountsController):
|
|||||||
"against_voucher_type": d.reference_type,
|
"against_voucher_type": d.reference_type,
|
||||||
"against_voucher": d.reference_name,
|
"against_voucher": d.reference_name,
|
||||||
"remarks": remarks,
|
"remarks": remarks,
|
||||||
|
"voucher_detail_no": d.reference_detail_no,
|
||||||
"cost_center": d.cost_center,
|
"cost_center": d.cost_center,
|
||||||
"project": d.project,
|
"project": d.project,
|
||||||
"finance_book": self.finance_book
|
"finance_book": self.finance_book
|
||||||
}, item=d)
|
}, item=d)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self.voucher_type in ('Deferred Revenue', 'Deferred Expense'):
|
||||||
|
update_outstanding = 'No'
|
||||||
|
else:
|
||||||
|
update_outstanding = 'Yes'
|
||||||
|
|
||||||
if gl_map:
|
if gl_map:
|
||||||
make_gl_entries(gl_map, cancel=cancel, adv_adj=adv_adj)
|
make_gl_entries(gl_map, cancel=cancel, adv_adj=adv_adj, update_outstanding=update_outstanding)
|
||||||
|
|
||||||
def get_balance(self):
|
def get_balance(self):
|
||||||
if not self.get('accounts'):
|
if not self.get('accounts'):
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
|
"project",
|
||||||
"currency_section",
|
"currency_section",
|
||||||
"account_currency",
|
"account_currency",
|
||||||
"column_break_10",
|
"column_break_10",
|
||||||
@ -32,7 +33,7 @@
|
|||||||
"reference_type",
|
"reference_type",
|
||||||
"reference_name",
|
"reference_name",
|
||||||
"reference_due_date",
|
"reference_due_date",
|
||||||
"project",
|
"reference_detail_no",
|
||||||
"col_break3",
|
"col_break3",
|
||||||
"is_advance",
|
"is_advance",
|
||||||
"user_remark",
|
"user_remark",
|
||||||
@ -268,6 +269,12 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Bank Account",
|
"label": "Bank Account",
|
||||||
"options": "Bank Account"
|
"options": "Bank Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "reference_detail_no",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Reference Detail No"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
|
@ -319,7 +319,7 @@ class PaymentEntry(AccountsController):
|
|||||||
invoice_payment_amount_map.setdefault(key, 0.0)
|
invoice_payment_amount_map.setdefault(key, 0.0)
|
||||||
invoice_payment_amount_map[key] += reference.allocated_amount
|
invoice_payment_amount_map[key] += reference.allocated_amount
|
||||||
|
|
||||||
if not invoice_paid_amount_map.get(reference.reference_name):
|
if not invoice_paid_amount_map.get(key):
|
||||||
payment_schedule = frappe.get_all('Payment Schedule', filters={'parent': reference.reference_name},
|
payment_schedule = frappe.get_all('Payment Schedule', filters={'parent': reference.reference_name},
|
||||||
fields=['paid_amount', 'payment_amount', 'payment_term'])
|
fields=['paid_amount', 'payment_amount', 'payment_term'])
|
||||||
for term in payment_schedule:
|
for term in payment_schedule:
|
||||||
@ -332,12 +332,14 @@ class PaymentEntry(AccountsController):
|
|||||||
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` - %s
|
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` - %s
|
||||||
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
||||||
else:
|
else:
|
||||||
outstanding = invoice_paid_amount_map.get(key)['outstanding']
|
outstanding = flt(invoice_paid_amount_map.get(key, {}).get('outstanding'))
|
||||||
|
|
||||||
if amount > outstanding:
|
if amount > outstanding:
|
||||||
frappe.throw(_('Cannot allocate more than {0} against payment term {1}').format(outstanding, key[0]))
|
frappe.throw(_('Cannot allocate more than {0} against payment term {1}').format(outstanding, key[0]))
|
||||||
|
|
||||||
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` + %s
|
if amount and outstanding:
|
||||||
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` + %s
|
||||||
|
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
||||||
|
|
||||||
def set_status(self):
|
def set_status(self):
|
||||||
if self.docstatus == 2:
|
if self.docstatus == 2:
|
||||||
@ -451,6 +453,8 @@ class PaymentEntry(AccountsController):
|
|||||||
frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction"))
|
frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction"))
|
||||||
|
|
||||||
def set_remarks(self):
|
def set_remarks(self):
|
||||||
|
if self.remarks: return
|
||||||
|
|
||||||
if self.payment_type=="Internal Transfer":
|
if self.payment_type=="Internal Transfer":
|
||||||
remarks = [_("Amount {0} {1} transferred from {2} to {3}")
|
remarks = [_("Amount {0} {1} transferred from {2} to {3}")
|
||||||
.format(self.paid_from_account_currency, self.paid_amount, self.paid_from, self.paid_to)]
|
.format(self.paid_from_account_currency, self.paid_amount, self.paid_from, self.paid_to)]
|
||||||
@ -1091,17 +1095,20 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
|
def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
|
||||||
references = []
|
references = []
|
||||||
for payment_term in payment_schedule:
|
for payment_term in payment_schedule:
|
||||||
references.append({
|
payment_term_outstanding = flt(payment_term.payment_amount - payment_term.paid_amount,
|
||||||
'reference_doctype': dt,
|
|
||||||
'reference_name': dn,
|
|
||||||
'bill_no': doc.get('bill_no'),
|
|
||||||
'due_date': doc.get('due_date'),
|
|
||||||
'total_amount': grand_total,
|
|
||||||
'outstanding_amount': outstanding_amount,
|
|
||||||
'payment_term': payment_term.payment_term,
|
|
||||||
'allocated_amount': flt(payment_term.payment_amount - payment_term.paid_amount,
|
|
||||||
payment_term.precision('payment_amount'))
|
payment_term.precision('payment_amount'))
|
||||||
})
|
|
||||||
|
if payment_term_outstanding:
|
||||||
|
references.append({
|
||||||
|
'reference_doctype': dt,
|
||||||
|
'reference_name': dn,
|
||||||
|
'bill_no': doc.get('bill_no'),
|
||||||
|
'due_date': doc.get('due_date'),
|
||||||
|
'total_amount': grand_total,
|
||||||
|
'outstanding_amount': outstanding_amount,
|
||||||
|
'payment_term': payment_term.payment_term,
|
||||||
|
'allocated_amount': payment_term_outstanding
|
||||||
|
})
|
||||||
|
|
||||||
return references
|
return references
|
||||||
|
|
||||||
|
@ -349,9 +349,10 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"in_create": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-05-08 10:23:02.815237",
|
"modified": "2020-05-29 17:38:49.392713",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Request",
|
"name": "Payment Request",
|
||||||
|
@ -17,6 +17,8 @@ from six import string_types
|
|||||||
apply_on_dict = {"Item Code": "items",
|
apply_on_dict = {"Item Code": "items",
|
||||||
"Item Group": "item_groups", "Brand": "brands"}
|
"Item Group": "item_groups", "Brand": "brands"}
|
||||||
|
|
||||||
|
other_fields = ["other_item_code", "other_item_group", "other_brand"]
|
||||||
|
|
||||||
class PricingRule(Document):
|
class PricingRule(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_mandatory()
|
self.validate_mandatory()
|
||||||
@ -47,6 +49,13 @@ class PricingRule(Document):
|
|||||||
if tocheck and not self.get(tocheck):
|
if tocheck and not self.get(tocheck):
|
||||||
throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError)
|
throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError)
|
||||||
|
|
||||||
|
if self.apply_rule_on_other:
|
||||||
|
o_field = 'other_' + frappe.scrub(self.apply_rule_on_other)
|
||||||
|
if not self.get(o_field) and o_field in other_fields:
|
||||||
|
frappe.throw(_("For the 'Apply Rule On Other' condition the field {0} is mandatory")
|
||||||
|
.format(frappe.bold(self.apply_rule_on_other)))
|
||||||
|
|
||||||
|
|
||||||
if self.price_or_product_discount == 'Price' and not self.rate_or_discount:
|
if self.price_or_product_discount == 'Price' and not self.rate_or_discount:
|
||||||
throw(_("Rate or Discount is required for the price discount."), frappe.MandatoryError)
|
throw(_("Rate or Discount is required for the price discount."), frappe.MandatoryError)
|
||||||
|
|
||||||
@ -80,13 +89,27 @@ class PricingRule(Document):
|
|||||||
for f in options:
|
for f in options:
|
||||||
if not f: continue
|
if not f: continue
|
||||||
|
|
||||||
f = frappe.scrub(f)
|
scrubbed_f = frappe.scrub(f)
|
||||||
if f!=fieldname:
|
|
||||||
self.set(f, None)
|
if logic_field == 'apply_on':
|
||||||
|
apply_on_f = apply_on_dict.get(f, f)
|
||||||
|
else:
|
||||||
|
apply_on_f = scrubbed_f
|
||||||
|
|
||||||
|
if scrubbed_f != fieldname:
|
||||||
|
self.set(apply_on_f, None)
|
||||||
|
|
||||||
if self.mixed_conditions and self.get("same_item"):
|
if self.mixed_conditions and self.get("same_item"):
|
||||||
self.same_item = 0
|
self.same_item = 0
|
||||||
|
|
||||||
|
apply_rule_on_other = frappe.scrub(self.apply_rule_on_other or "")
|
||||||
|
|
||||||
|
cleanup_other_fields = (other_fields if not apply_rule_on_other
|
||||||
|
else [o_field for o_field in other_fields if o_field != 'other_' + apply_rule_on_other])
|
||||||
|
|
||||||
|
for other_field in cleanup_other_fields:
|
||||||
|
self.set(other_field, None)
|
||||||
|
|
||||||
def validate_rate_or_discount(self):
|
def validate_rate_or_discount(self):
|
||||||
for field in ["Rate"]:
|
for field in ["Rate"]:
|
||||||
if flt(self.get(frappe.scrub(field))) < 0:
|
if flt(self.get(frappe.scrub(field))) < 0:
|
||||||
|
@ -385,6 +385,50 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
so.load_from_db()
|
so.load_from_db()
|
||||||
self.assertEqual(so.items[1].is_free_item, 1)
|
self.assertEqual(so.items[1].is_free_item, 1)
|
||||||
self.assertEqual(so.items[1].item_code, "_Test Item 2")
|
self.assertEqual(so.items[1].item_code, "_Test Item 2")
|
||||||
|
|
||||||
|
def test_cumulative_pricing_rule(self):
|
||||||
|
frappe.delete_doc_if_exists('Pricing Rule', '_Test Cumulative Pricing Rule')
|
||||||
|
test_record = {
|
||||||
|
"doctype": "Pricing Rule",
|
||||||
|
"title": "_Test Cumulative Pricing Rule",
|
||||||
|
"apply_on": "Item Code",
|
||||||
|
"currency": "USD",
|
||||||
|
"items": [{
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
}],
|
||||||
|
"is_cumulative": 1,
|
||||||
|
"selling": 1,
|
||||||
|
"applicable_for": "Customer",
|
||||||
|
"customer": "_Test Customer",
|
||||||
|
"rate_or_discount": "Discount Percentage",
|
||||||
|
"rate": 0,
|
||||||
|
"min_amt": 0,
|
||||||
|
"max_amt": 10000,
|
||||||
|
"discount_percentage": 17.5,
|
||||||
|
"price_or_product_discount": "Price",
|
||||||
|
"company": "_Test Company",
|
||||||
|
"valid_from": frappe.utils.nowdate(),
|
||||||
|
"valid_upto": frappe.utils.nowdate()
|
||||||
|
}
|
||||||
|
frappe.get_doc(test_record.copy()).insert()
|
||||||
|
|
||||||
|
args = frappe._dict({
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
"company": "_Test Company",
|
||||||
|
"price_list": "_Test Price List",
|
||||||
|
"currency": "_Test Currency",
|
||||||
|
"doctype": "Sales Invoice",
|
||||||
|
"conversion_rate": 1,
|
||||||
|
"price_list_currency": "_Test Currency",
|
||||||
|
"plc_conversion_rate": 1,
|
||||||
|
"order_type": "Sales",
|
||||||
|
"customer": "_Test Customer",
|
||||||
|
"name": None,
|
||||||
|
"transaction_date": frappe.utils.nowdate()
|
||||||
|
})
|
||||||
|
details = get_item_details(args)
|
||||||
|
|
||||||
|
self.assertTrue(details)
|
||||||
|
|
||||||
def make_pricing_rule(**args):
|
def make_pricing_rule(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
@ -366,8 +366,7 @@ def get_qty_amount_data_for_cumulative(pr_doc, doc, items=[]):
|
|||||||
sum_qty, sum_amt = [0, 0]
|
sum_qty, sum_amt = [0, 0]
|
||||||
doctype = doc.get('parenttype') or doc.doctype
|
doctype = doc.get('parenttype') or doc.doctype
|
||||||
|
|
||||||
date_field = ('transaction_date'
|
date_field = 'transaction_date' if frappe.get_meta(doctype).has_field('transaction_date') else 'posting_date'
|
||||||
if doc.get('transaction_date') else 'posting_date')
|
|
||||||
|
|
||||||
child_doctype = '{0} Item'.format(doctype)
|
child_doctype = '{0} Item'.format(doctype)
|
||||||
apply_on = frappe.scrub(pr_doc.get('apply_on'))
|
apply_on = frappe.scrub(pr_doc.get('apply_on'))
|
||||||
|
@ -10,6 +10,18 @@ frappe.ui.form.on('Process Deferred Accounting', {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (frm.doc.company) {
|
||||||
|
frm.set_query("account", function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
'company': frm.doc.company,
|
||||||
|
'root_type': 'Liability',
|
||||||
|
'is_group': 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
validate: function() {
|
validate: function() {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -238,6 +238,12 @@ class PurchaseInvoice(BuyingController):
|
|||||||
not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")):
|
not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")):
|
||||||
|
|
||||||
if self.update_stock and (not item.from_warehouse):
|
if self.update_stock and (not item.from_warehouse):
|
||||||
|
if for_validate and item.expense_account and item.expense_account != warehouse_account[item.warehouse]["account"]:
|
||||||
|
frappe.msgprint(_('''Row {0}: Expense Head changed to {1} because account {2}
|
||||||
|
is not linked to warehouse {3} or it is not the default inventory account'''.format(
|
||||||
|
item.idx, frappe.bold(warehouse_account[item.warehouse]["account"]),
|
||||||
|
frappe.bold(item.expense_account), frappe.bold(item.warehouse))))
|
||||||
|
|
||||||
item.expense_account = warehouse_account[item.warehouse]["account"]
|
item.expense_account = warehouse_account[item.warehouse]["account"]
|
||||||
else:
|
else:
|
||||||
# check if 'Stock Received But Not Billed' account is credited in Purchase receipt or not
|
# check if 'Stock Received But Not Billed' account is credited in Purchase receipt or not
|
||||||
@ -247,10 +253,21 @@ class PurchaseInvoice(BuyingController):
|
|||||||
(item.purchase_receipt, stock_not_billed_account))
|
(item.purchase_receipt, stock_not_billed_account))
|
||||||
|
|
||||||
if negative_expense_booked_in_pr:
|
if negative_expense_booked_in_pr:
|
||||||
|
if for_validate and item.expense_account and item.expense_account != stock_not_billed_account:
|
||||||
|
frappe.msgprint(_('''Row {0}: Expense Head changed to {1} because
|
||||||
|
expense is booked against this account in Purchase Receipt {2}'''.format(
|
||||||
|
item.idx, frappe.bold(stock_not_billed_account), frappe.bold(item.purchase_receipt))))
|
||||||
|
|
||||||
item.expense_account = stock_not_billed_account
|
item.expense_account = stock_not_billed_account
|
||||||
else:
|
else:
|
||||||
# If no purchase receipt present then book expense in 'Stock Received But Not Billed'
|
# If no purchase receipt present then book expense in 'Stock Received But Not Billed'
|
||||||
# This is done in cases when Purchase Invoice is created before Purchase Receipt
|
# This is done in cases when Purchase Invoice is created before Purchase Receipt
|
||||||
|
if for_validate and item.expense_account and item.expense_account != stock_not_billed_account:
|
||||||
|
frappe.msgprint(_('''Row {0}: Expense Head changed to {1} as no Purchase
|
||||||
|
Receipt is created against Item {2}. This is done to handle accounting for cases
|
||||||
|
when Purchase Receipt is created after Purchase Invoice'''.format(
|
||||||
|
item.idx, frappe.bold(stock_not_billed_account), frappe.bold(item.item_code))))
|
||||||
|
|
||||||
item.expense_account = stock_not_billed_account
|
item.expense_account = stock_not_billed_account
|
||||||
|
|
||||||
elif item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category):
|
elif item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category):
|
||||||
@ -1020,7 +1037,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
# calculate totals again after applying TDS
|
# calculate totals again after applying TDS
|
||||||
self.calculate_taxes_and_totals()
|
self.calculate_taxes_and_totals()
|
||||||
|
|
||||||
def set_status(self, update=False, status=None, update_modified=True):
|
def set_status(self, update=False, status=None, update_modified=True):
|
||||||
if self.is_new():
|
if self.is_new():
|
||||||
if self.get('amended_from'):
|
if self.get('amended_from'):
|
||||||
|
@ -16,7 +16,7 @@ frappe.listview_settings['Purchase Invoice'] = {
|
|||||||
} else if(frappe.datetime.get_diff(doc.due_date) < 0) {
|
} else if(frappe.datetime.get_diff(doc.due_date) < 0) {
|
||||||
return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<,Today"];
|
return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<,Today"];
|
||||||
} else {
|
} else {
|
||||||
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due,>=,Today"];
|
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>=,Today"];
|
||||||
}
|
}
|
||||||
} else if(cint(doc.is_return)) {
|
} else if(cint(doc.is_return)) {
|
||||||
return [__("Return"), "darkgrey", "is_return,=,Yes"];
|
return [__("Return"), "darkgrey", "is_return,=,Yes"];
|
||||||
@ -24,4 +24,4 @@ frappe.listview_settings['Purchase Invoice'] = {
|
|||||||
return [__("Paid"), "green", "outstanding_amount,=,0"];
|
return [__("Paid"), "green", "outstanding_amount,=,0"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -7,14 +7,15 @@ import unittest
|
|||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
import frappe.model
|
import frappe.model
|
||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||||
from frappe.utils import cint, flt, today, nowdate, add_days
|
from frappe.utils import cint, flt, today, nowdate, add_days, getdate
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
|
||||||
test_records as pr_test_records, make_purchase_receipt, get_taxes
|
test_records as pr_test_records, make_purchase_receipt, get_taxes
|
||||||
from erpnext.controllers.accounts_controller import get_payment_terms
|
from erpnext.controllers.accounts_controller import get_payment_terms
|
||||||
from erpnext.exceptions import InvalidCurrency
|
from erpnext.exceptions import InvalidCurrency
|
||||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import get_qty_after_transaction
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import get_qty_after_transaction
|
||||||
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.stock.doctype.item.test_item import create_item
|
||||||
|
|
||||||
test_dependencies = ["Item", "Cost Center", "Payment Term", "Payment Terms Template"]
|
test_dependencies = ["Item", "Cost Center", "Payment Term", "Payment Terms Template"]
|
||||||
test_ignore = ["Serial No"]
|
test_ignore = ["Serial No"]
|
||||||
@ -866,6 +867,67 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
for gle in gl_entries:
|
for gle in gl_entries:
|
||||||
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
|
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
|
||||||
|
|
||||||
|
def test_deferred_expense_via_journal_entry(self):
|
||||||
|
deferred_account = create_account(account_name="Deferred Expense",
|
||||||
|
parent_account="Current Assets - _TC", company="_Test Company")
|
||||||
|
|
||||||
|
acc_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
|
||||||
|
acc_settings.book_deferred_entries_via_journal_entry = 1
|
||||||
|
acc_settings.submit_journal_entries = 1
|
||||||
|
acc_settings.save()
|
||||||
|
|
||||||
|
item = create_item("_Test Item for Deferred Accounting")
|
||||||
|
item.enable_deferred_expense = 1
|
||||||
|
item.deferred_expense_account = deferred_account
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
pi = make_purchase_invoice(item=item.name, qty=1, rate=100, do_not_save=True)
|
||||||
|
pi.set_posting_time = 1
|
||||||
|
pi.posting_date = '2019-03-15'
|
||||||
|
pi.items[0].enable_deferred_expense = 1
|
||||||
|
pi.items[0].service_start_date = "2019-01-10"
|
||||||
|
pi.items[0].service_end_date = "2019-03-15"
|
||||||
|
pi.items[0].deferred_expense_account = deferred_account
|
||||||
|
pi.save()
|
||||||
|
pi.submit()
|
||||||
|
|
||||||
|
pda1 = frappe.get_doc(dict(
|
||||||
|
doctype='Process Deferred Accounting',
|
||||||
|
posting_date=nowdate(),
|
||||||
|
start_date="2019-01-01",
|
||||||
|
end_date="2019-03-31",
|
||||||
|
type="Expense",
|
||||||
|
company="_Test Company"
|
||||||
|
))
|
||||||
|
|
||||||
|
pda1.insert()
|
||||||
|
pda1.submit()
|
||||||
|
|
||||||
|
expected_gle = [
|
||||||
|
["_Test Account Cost for Goods Sold - _TC", 0.0, 33.85, "2019-01-31"],
|
||||||
|
[deferred_account, 33.85, 0.0, "2019-01-31"],
|
||||||
|
["_Test Account Cost for Goods Sold - _TC", 0.0, 43.08, "2019-02-28"],
|
||||||
|
[deferred_account, 43.08, 0.0, "2019-02-28"],
|
||||||
|
["_Test Account Cost for Goods Sold - _TC", 0.0, 23.07, "2019-03-15"],
|
||||||
|
[deferred_account, 23.07, 0.0, "2019-03-15"]
|
||||||
|
]
|
||||||
|
|
||||||
|
gl_entries = gl_entries = frappe.db.sql("""select account, debit, credit, posting_date
|
||||||
|
from `tabGL Entry`
|
||||||
|
where voucher_type='Journal Entry' and voucher_detail_no=%s and posting_date <= %s
|
||||||
|
order by posting_date asc, account asc""", (pi.items[0].name, pi.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.credit)
|
||||||
|
self.assertEqual(expected_gle[i][2], gle.debit)
|
||||||
|
self.assertEqual(getdate(expected_gle[i][3]), gle.posting_date)
|
||||||
|
|
||||||
|
acc_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
|
||||||
|
acc_settings.book_deferred_entries_via_journal_entry = 0
|
||||||
|
acc_settings.submit_journal_entriessubmit_journal_entries = 0
|
||||||
|
acc_settings.save()
|
||||||
|
|
||||||
|
|
||||||
def unlink_payment_on_cancel_of_invoice(enable=1):
|
def unlink_payment_on_cancel_of_invoice(enable=1):
|
||||||
accounts_settings = frappe.get_doc("Accounts Settings")
|
accounts_settings = frappe.get_doc("Accounts Settings")
|
||||||
|
@ -582,14 +582,14 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
def validate_item_code(self):
|
def validate_item_code(self):
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
if not d.item_code:
|
if not d.item_code and self.is_opening == "No":
|
||||||
msgprint(_("Item Code required at Row No {0}").format(d.idx), raise_exception=True)
|
msgprint(_("Item Code required at Row No {0}").format(d.idx), raise_exception=True)
|
||||||
|
|
||||||
def validate_warehouse(self):
|
def validate_warehouse(self):
|
||||||
super(SalesInvoice, self).validate_warehouse()
|
super(SalesInvoice, self).validate_warehouse()
|
||||||
|
|
||||||
for d in self.get_item_list():
|
for d in self.get_item_list():
|
||||||
if not d.warehouse and frappe.get_cached_value("Item", d.item_code, "is_stock_item"):
|
if not d.warehouse and d.item_code and frappe.get_cached_value("Item", d.item_code, "is_stock_item"):
|
||||||
frappe.throw(_("Warehouse required for stock Item {0}").format(d.item_code))
|
frappe.throw(_("Warehouse required for stock Item {0}").format(d.item_code))
|
||||||
|
|
||||||
def validate_delivery_note(self):
|
def validate_delivery_note(self):
|
||||||
@ -1450,11 +1450,17 @@ def get_inter_company_details(doc, doctype):
|
|||||||
parties = frappe.db.get_all("Supplier", fields=["name"], filters={"disabled": 0, "is_internal_supplier": 1, "represents_company": doc.company})
|
parties = frappe.db.get_all("Supplier", fields=["name"], filters={"disabled": 0, "is_internal_supplier": 1, "represents_company": doc.company})
|
||||||
company = frappe.get_cached_value("Customer", doc.customer, "represents_company")
|
company = frappe.get_cached_value("Customer", doc.customer, "represents_company")
|
||||||
|
|
||||||
|
if not parties:
|
||||||
|
frappe.throw(_('No Supplier found for Inter Company Transactions which represents company {0}').format(frappe.bold(doc.company)))
|
||||||
|
|
||||||
party = get_internal_party(parties, "Supplier", doc)
|
party = get_internal_party(parties, "Supplier", doc)
|
||||||
else:
|
else:
|
||||||
parties = frappe.db.get_all("Customer", fields=["name"], filters={"disabled": 0, "is_internal_customer": 1, "represents_company": doc.company})
|
parties = frappe.db.get_all("Customer", fields=["name"], filters={"disabled": 0, "is_internal_customer": 1, "represents_company": doc.company})
|
||||||
company = frappe.get_cached_value("Supplier", doc.supplier, "represents_company")
|
company = frappe.get_cached_value("Supplier", doc.supplier, "represents_company")
|
||||||
|
|
||||||
|
if not parties:
|
||||||
|
frappe.throw(_('No Customer found for Inter Company Transactions which represents company {0}').format(frappe.bold(doc.company)))
|
||||||
|
|
||||||
party = get_internal_party(parties, "Customer", doc)
|
party = get_internal_party(parties, "Customer", doc)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -1519,14 +1525,22 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
|||||||
def update_details(source_doc, target_doc, source_parent):
|
def update_details(source_doc, target_doc, source_parent):
|
||||||
target_doc.inter_company_invoice_reference = source_doc.name
|
target_doc.inter_company_invoice_reference = source_doc.name
|
||||||
if target_doc.doctype in ["Purchase Invoice", "Purchase Order"]:
|
if target_doc.doctype in ["Purchase Invoice", "Purchase Order"]:
|
||||||
|
currency = frappe.db.get_value('Supplier', details.get('party'), 'default_currency')
|
||||||
target_doc.company = details.get("company")
|
target_doc.company = details.get("company")
|
||||||
target_doc.supplier = details.get("party")
|
target_doc.supplier = details.get("party")
|
||||||
target_doc.buying_price_list = source_doc.selling_price_list
|
target_doc.buying_price_list = source_doc.selling_price_list
|
||||||
|
|
||||||
|
if currency:
|
||||||
|
target_doc.currency = currency
|
||||||
else:
|
else:
|
||||||
|
currency = frappe.db.get_value('Customer', details.get('party'), 'default_currency')
|
||||||
target_doc.company = details.get("company")
|
target_doc.company = details.get("company")
|
||||||
target_doc.customer = details.get("party")
|
target_doc.customer = details.get("party")
|
||||||
target_doc.selling_price_list = source_doc.buying_price_list
|
target_doc.selling_price_list = source_doc.buying_price_list
|
||||||
|
|
||||||
|
if currency:
|
||||||
|
target_doc.currency = currency
|
||||||
|
|
||||||
doclist = get_mapped_doc(doctype, source_name, {
|
doclist = get_mapped_doc(doctype, source_name, {
|
||||||
doctype: {
|
doctype: {
|
||||||
"doctype": target_doctype,
|
"doctype": target_doctype,
|
||||||
|
@ -1720,8 +1720,6 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si.save()
|
si.save()
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
from erpnext.accounts.deferred_revenue import convert_deferred_revenue_to_income
|
|
||||||
|
|
||||||
pda1 = frappe.get_doc(dict(
|
pda1 = frappe.get_doc(dict(
|
||||||
doctype='Process Deferred Accounting',
|
doctype='Process Deferred Accounting',
|
||||||
posting_date=nowdate(),
|
posting_date=nowdate(),
|
||||||
@ -1745,51 +1743,53 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
check_gl_entries(self, si.name, expected_gle, "2019-01-30")
|
check_gl_entries(self, si.name, expected_gle, "2019-01-30")
|
||||||
|
|
||||||
def test_deferred_error_email(self):
|
def test_fixed_deferred_revenue(self):
|
||||||
deferred_account = create_account(account_name="Deferred Revenue",
|
deferred_account = create_account(account_name="Deferred Revenue",
|
||||||
parent_account="Current Liabilities - _TC", company="_Test Company")
|
parent_account="Current Liabilities - _TC", company="_Test Company")
|
||||||
|
|
||||||
|
acc_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
|
||||||
|
acc_settings.book_deferred_entries_based_on = 'Months'
|
||||||
|
acc_settings.save()
|
||||||
|
|
||||||
item = create_item("_Test Item for Deferred Accounting")
|
item = create_item("_Test Item for Deferred Accounting")
|
||||||
item.enable_deferred_revenue = 1
|
item.enable_deferred_revenue = 1
|
||||||
item.deferred_revenue_account = deferred_account
|
item.deferred_revenue_account = deferred_account
|
||||||
item.no_of_months = 12
|
item.no_of_months = 12
|
||||||
item.save()
|
item.save()
|
||||||
|
|
||||||
si = create_sales_invoice(item=item.name, posting_date="2019-01-10", do_not_submit=True)
|
si = create_sales_invoice(item=item.name, posting_date="2019-01-16", rate=50000, do_not_submit=True)
|
||||||
si.items[0].enable_deferred_revenue = 1
|
si.items[0].enable_deferred_revenue = 1
|
||||||
si.items[0].service_start_date = "2019-01-10"
|
si.items[0].service_start_date = "2019-01-16"
|
||||||
si.items[0].service_end_date = "2019-03-15"
|
si.items[0].service_end_date = "2019-03-31"
|
||||||
si.items[0].deferred_revenue_account = deferred_account
|
si.items[0].deferred_revenue_account = deferred_account
|
||||||
si.save()
|
si.save()
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
from erpnext.accounts.deferred_revenue import convert_deferred_revenue_to_income
|
pda1 = frappe.get_doc(dict(
|
||||||
|
|
||||||
acc_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
|
|
||||||
acc_settings.acc_frozen_upto = '2019-01-31'
|
|
||||||
acc_settings.save()
|
|
||||||
|
|
||||||
pda = frappe.get_doc(dict(
|
|
||||||
doctype='Process Deferred Accounting',
|
doctype='Process Deferred Accounting',
|
||||||
posting_date=nowdate(),
|
posting_date='2019-03-31',
|
||||||
start_date="2019-01-01",
|
start_date="2019-01-01",
|
||||||
end_date="2019-03-31",
|
end_date="2019-03-31",
|
||||||
type="Income",
|
type="Income",
|
||||||
company="_Test Company"
|
company="_Test Company"
|
||||||
))
|
))
|
||||||
|
|
||||||
pda.insert()
|
pda1.insert()
|
||||||
pda.submit()
|
pda1.submit()
|
||||||
|
|
||||||
email = frappe.db.sql(""" select name from `tabEmail Queue`
|
expected_gle = [
|
||||||
where message like %(txt)s """, {
|
[deferred_account, 10000.0, 0.0, "2019-01-31"],
|
||||||
'txt': "%%%s%%" % "Error while processing deferred accounting for {0}".format(pda.name)
|
["Sales - _TC", 0.0, 10000.0, "2019-01-31"],
|
||||||
})
|
[deferred_account, 20000.0, 0.0, "2019-02-28"],
|
||||||
|
["Sales - _TC", 0.0, 20000.0, "2019-02-28"],
|
||||||
|
[deferred_account, 20000.0, 0.0, "2019-03-31"],
|
||||||
|
["Sales - _TC", 0.0, 20000.0, "2019-03-31"]
|
||||||
|
]
|
||||||
|
|
||||||
self.assertTrue(email)
|
check_gl_entries(self, si.name, expected_gle, "2019-01-30")
|
||||||
|
|
||||||
acc_settings.load_from_db()
|
acc_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
|
||||||
acc_settings.acc_frozen_upto = None
|
acc_settings.book_deferred_entries_based_on = 'Days'
|
||||||
acc_settings.save()
|
acc_settings.save()
|
||||||
|
|
||||||
def test_inter_company_transaction(self):
|
def test_inter_company_transaction(self):
|
||||||
|
@ -45,7 +45,9 @@ class ShippingRule(Document):
|
|||||||
shipping_amount = 0.0
|
shipping_amount = 0.0
|
||||||
by_value = False
|
by_value = False
|
||||||
|
|
||||||
self.validate_countries(doc)
|
if doc.get_shipping_address():
|
||||||
|
# validate country only if there is address
|
||||||
|
self.validate_countries(doc)
|
||||||
|
|
||||||
if self.calculate_based_on == 'Net Total':
|
if self.calculate_based_on == 'Net Total':
|
||||||
value = doc.base_net_total
|
value = doc.base_net_total
|
||||||
|
@ -180,7 +180,7 @@ def get_advance_vouchers(suppliers, fiscal_year=None, company=None, from_date=No
|
|||||||
if company:
|
if company:
|
||||||
condition += "and company =%s" % (company)
|
condition += "and company =%s" % (company)
|
||||||
if from_date and to_date:
|
if from_date and to_date:
|
||||||
condition += "and posting_date between %s and %s" % (company, from_date, to_date)
|
condition += "and posting_date between %s and %s" % (from_date, to_date)
|
||||||
|
|
||||||
## Appending the same supplier again if length of suppliers list is 1
|
## Appending the same supplier again if length of suppliers list is 1
|
||||||
## since tuple of single element list contains None, For example ('Test Supplier 1', )
|
## since tuple of single element list contains None, For example ('Test Supplier 1', )
|
||||||
|
@ -602,10 +602,14 @@ def get_party_shipping_address(doctype, name):
|
|||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_partywise_advanced_payment_amount(party_type, posting_date = None, company=None):
|
def get_partywise_advanced_payment_amount(party_type, posting_date = None, future_payment=0, company=None):
|
||||||
cond = "1=1"
|
cond = "1=1"
|
||||||
if posting_date:
|
if posting_date:
|
||||||
cond = "posting_date <= '{0}'".format(posting_date)
|
if future_payment:
|
||||||
|
cond = "posting_date <= '{0}' OR DATE(creation) <= '{0}' """.format(posting_date)
|
||||||
|
else:
|
||||||
|
cond = "posting_date <= '{0}'".format(posting_date)
|
||||||
|
|
||||||
if company:
|
if company:
|
||||||
cond += "and company = '{0}'".format(company)
|
cond += "and company = '{0}'".format(company)
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ def make_sales_invoice():
|
|||||||
debit_to = 'Debtors - _TC2',
|
debit_to = 'Debtors - _TC2',
|
||||||
income_account = 'Sales - _TC2',
|
income_account = 'Sales - _TC2',
|
||||||
expense_account = 'Cost of Goods Sold - _TC2',
|
expense_account = 'Cost of Goods Sold - _TC2',
|
||||||
cost_center = '_Test Company 2 - _TC2')
|
cost_center = 'Main - _TC2')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,12 +135,5 @@ frappe.query_reports["Accounts Payable"] = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.dimension_filters.forEach((dimension) => {
|
erpnext.utils.add_dimensions('Accounts Payable', 9);
|
||||||
frappe.query_reports["Accounts Payable"].filters.splice(9, 0 ,{
|
|
||||||
"fieldname": dimension["fieldname"],
|
|
||||||
"label": __(dimension["label"]),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": dimension["document_type"]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
@ -104,12 +104,5 @@ frappe.query_reports["Accounts Payable Summary"] = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.dimension_filters.forEach((dimension) => {
|
erpnext.utils.add_dimensions('Accounts Payable Summary', 9);
|
||||||
frappe.query_reports["Accounts Payable Summary"].filters.splice(9, 0 ,{
|
|
||||||
"fieldname": dimension["fieldname"],
|
|
||||||
"label": __(dimension["label"]),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": dimension["document_type"]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
@ -199,12 +199,5 @@ frappe.query_reports["Accounts Receivable"] = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.dimension_filters.forEach((dimension) => {
|
erpnext.utils.add_dimensions('Accounts Receivable', 9);
|
||||||
frappe.query_reports["Accounts Receivable"].filters.splice(9, 0 ,{
|
|
||||||
"fieldname": dimension["fieldname"],
|
|
||||||
"label": __(dimension["label"]),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": dimension["document_type"]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
@ -169,9 +169,11 @@ class ReceivablePayableReport(object):
|
|||||||
|
|
||||||
def append_subtotal_row(self, party):
|
def append_subtotal_row(self, party):
|
||||||
sub_total_row = self.total_row_map.get(party)
|
sub_total_row = self.total_row_map.get(party)
|
||||||
self.data.append(sub_total_row)
|
|
||||||
self.data.append({})
|
if sub_total_row:
|
||||||
self.update_sub_total_row(sub_total_row, 'Total')
|
self.data.append(sub_total_row)
|
||||||
|
self.data.append({})
|
||||||
|
self.update_sub_total_row(sub_total_row, 'Total')
|
||||||
|
|
||||||
def get_voucher_balance(self, gle):
|
def get_voucher_balance(self, gle):
|
||||||
if self.filters.get("sales_person"):
|
if self.filters.get("sales_person"):
|
||||||
@ -232,7 +234,8 @@ class ReceivablePayableReport(object):
|
|||||||
|
|
||||||
if self.filters.get('group_by_party'):
|
if self.filters.get('group_by_party'):
|
||||||
self.append_subtotal_row(self.previous_party)
|
self.append_subtotal_row(self.previous_party)
|
||||||
self.data.append(self.total_row_map.get('Total'))
|
if self.data:
|
||||||
|
self.data.append(self.total_row_map.get('Total'))
|
||||||
|
|
||||||
def append_row(self, row):
|
def append_row(self, row):
|
||||||
self.allocate_future_payments(row)
|
self.allocate_future_payments(row)
|
||||||
@ -559,6 +562,14 @@ class ReceivablePayableReport(object):
|
|||||||
conditions, values = self.prepare_conditions()
|
conditions, values = self.prepare_conditions()
|
||||||
order_by = self.get_order_by_condition()
|
order_by = self.get_order_by_condition()
|
||||||
|
|
||||||
|
if self.filters.show_future_payments:
|
||||||
|
values.insert(2, self.filters.report_date)
|
||||||
|
|
||||||
|
date_condition = """AND (posting_date <= %s
|
||||||
|
OR (against_voucher IS NULL AND DATE(creation) <= %s))"""
|
||||||
|
else:
|
||||||
|
date_condition = "AND posting_date <=%s"
|
||||||
|
|
||||||
if self.filters.get(scrub(self.party_type)):
|
if self.filters.get(scrub(self.party_type)):
|
||||||
select_fields = "debit_in_account_currency as debit, credit_in_account_currency as credit"
|
select_fields = "debit_in_account_currency as debit, credit_in_account_currency as credit"
|
||||||
else:
|
else:
|
||||||
@ -574,9 +585,8 @@ class ReceivablePayableReport(object):
|
|||||||
docstatus < 2
|
docstatus < 2
|
||||||
and party_type=%s
|
and party_type=%s
|
||||||
and (party is not null and party != '')
|
and (party is not null and party != '')
|
||||||
and posting_date <= %s
|
{1} {2} {3}"""
|
||||||
{1} {2}"""
|
.format(select_fields, date_condition, conditions, order_by), values, as_dict=True)
|
||||||
.format(select_fields, conditions, order_by), values, as_dict=True)
|
|
||||||
|
|
||||||
def get_sales_invoices_or_customers_based_on_sales_person(self):
|
def get_sales_invoices_or_customers_based_on_sales_person(self):
|
||||||
if self.filters.get("sales_person"):
|
if self.filters.get("sales_person"):
|
||||||
|
@ -63,7 +63,7 @@ def make_sales_invoice():
|
|||||||
debit_to = 'Debtors - _TC2',
|
debit_to = 'Debtors - _TC2',
|
||||||
income_account = 'Sales - _TC2',
|
income_account = 'Sales - _TC2',
|
||||||
expense_account = 'Cost of Goods Sold - _TC2',
|
expense_account = 'Cost of Goods Sold - _TC2',
|
||||||
cost_center = '_Test Company 2 - _TC2',
|
cost_center = 'Main - _TC2',
|
||||||
do_not_save=1)
|
do_not_save=1)
|
||||||
|
|
||||||
si.append('payment_schedule', dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30))
|
si.append('payment_schedule', dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30))
|
||||||
@ -83,14 +83,14 @@ def make_payment(docname):
|
|||||||
|
|
||||||
def make_credit_note(docname):
|
def make_credit_note(docname):
|
||||||
create_sales_invoice(company="_Test Company 2",
|
create_sales_invoice(company="_Test Company 2",
|
||||||
customer = '_Test Customer 2',
|
customer = '_Test Customer 2',
|
||||||
currency = 'EUR',
|
currency = 'EUR',
|
||||||
qty = -1,
|
qty = -1,
|
||||||
warehouse = 'Finished Goods - _TC2',
|
warehouse = 'Finished Goods - _TC2',
|
||||||
debit_to = 'Debtors - _TC2',
|
debit_to = 'Debtors - _TC2',
|
||||||
income_account = 'Sales - _TC2',
|
income_account = 'Sales - _TC2',
|
||||||
expense_account = 'Cost of Goods Sold - _TC2',
|
expense_account = 'Cost of Goods Sold - _TC2',
|
||||||
cost_center = '_Test Company 2 - _TC2',
|
cost_center = 'Main - _TC2',
|
||||||
is_return = 1,
|
is_return = 1,
|
||||||
return_against = docname)
|
return_against = docname)
|
||||||
|
|
||||||
|
@ -111,7 +111,12 @@ frappe.query_reports["Accounts Receivable Summary"] = {
|
|||||||
"fieldname":"based_on_payment_terms",
|
"fieldname":"based_on_payment_terms",
|
||||||
"label": __("Based On Payment Terms"),
|
"label": __("Based On Payment Terms"),
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"show_future_payments",
|
||||||
|
"label": __("Show Future Payments"),
|
||||||
|
"fieldtype": "Check",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
onload: function(report) {
|
onload: function(report) {
|
||||||
@ -122,11 +127,4 @@ frappe.query_reports["Accounts Receivable Summary"] = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.dimension_filters.forEach((dimension) => {
|
erpnext.utils.add_dimensions('Accounts Receivable Summary', 9);
|
||||||
frappe.query_reports["Accounts Receivable Summary"].filters.splice(9, 0 ,{
|
|
||||||
"fieldname": dimension["fieldname"],
|
|
||||||
"label": __(dimension["label"]),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": dimension["document_type"]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
@ -33,7 +33,7 @@ class AccountsReceivableSummary(ReceivablePayableReport):
|
|||||||
self.get_party_total(args)
|
self.get_party_total(args)
|
||||||
|
|
||||||
party_advance_amount = get_partywise_advanced_payment_amount(self.party_type,
|
party_advance_amount = get_partywise_advanced_payment_amount(self.party_type,
|
||||||
self.filters.report_date, self.filters.company) or {}
|
self.filters.report_date, self.filters.show_future_payments, self.filters.company) or {}
|
||||||
|
|
||||||
for party, party_dict in iteritems(self.party_total):
|
for party, party_dict in iteritems(self.party_total):
|
||||||
if party_dict.outstanding == 0:
|
if party_dict.outstanding == 0:
|
||||||
|
@ -93,7 +93,7 @@ def get_assets(filters):
|
|||||||
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
|
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
|
||||||
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
|
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
|
||||||
from (SELECT a.asset_category,
|
from (SELECT a.asset_category,
|
||||||
ifnull(sum(case when ds.schedule_date < %(from_date)s then
|
ifnull(sum(case when ds.schedule_date < %(from_date)s and (ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s) then
|
||||||
ds.depreciation_amount
|
ds.depreciation_amount
|
||||||
else
|
else
|
||||||
0
|
0
|
||||||
@ -111,13 +111,11 @@ def get_assets(filters):
|
|||||||
0
|
0
|
||||||
end), 0) as depreciation_amount_during_the_period
|
end), 0) as depreciation_amount_during_the_period
|
||||||
from `tabAsset` a, `tabDepreciation Schedule` ds
|
from `tabAsset` a, `tabDepreciation Schedule` ds
|
||||||
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and a.name = ds.parent
|
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and a.name = ds.parent and ifnull(ds.journal_entry, '') != ''
|
||||||
group by a.asset_category
|
group by a.asset_category
|
||||||
union
|
union
|
||||||
SELECT a.asset_category,
|
SELECT a.asset_category,
|
||||||
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
|
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) then
|
||||||
and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s)
|
|
||||||
then
|
|
||||||
0
|
0
|
||||||
else
|
else
|
||||||
a.opening_accumulated_depreciation
|
a.opening_accumulated_depreciation
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
||||||
frappe.query_reports["Balance Sheet"] = $.extend({}, erpnext.financial_statements);
|
frappe.query_reports["Balance Sheet"] = $.extend({}, erpnext.financial_statements);
|
||||||
|
|
||||||
|
erpnext.utils.add_dimensions('Balance Sheet', 10);
|
||||||
|
|
||||||
frappe.query_reports["Balance Sheet"]["filters"].push({
|
frappe.query_reports["Balance Sheet"]["filters"].push({
|
||||||
"fieldname": "accumulated_values",
|
"fieldname": "accumulated_values",
|
||||||
"label": __("Accumulated Values"),
|
"label": __("Accumulated Values"),
|
||||||
|
@ -29,37 +29,60 @@ def execute(filters=None):
|
|||||||
for dimension in dimensions:
|
for dimension in dimensions:
|
||||||
dimension_items = cam_map.get(dimension)
|
dimension_items = cam_map.get(dimension)
|
||||||
if dimension_items:
|
if dimension_items:
|
||||||
for account, monthwise_data in iteritems(dimension_items):
|
data = get_final_data(dimension, dimension_items, filters, period_month_ranges, data, 0)
|
||||||
row = [dimension, account]
|
else:
|
||||||
totals = [0, 0, 0]
|
DCC_allocation = frappe.db.sql('''SELECT parent, sum(percentage_allocation) as percentage_allocation
|
||||||
for year in get_fiscal_years(filters):
|
FROM `tabDistributed Cost Center`
|
||||||
last_total = 0
|
WHERE cost_center IN %(dimension)s
|
||||||
for relevant_months in period_month_ranges:
|
AND parent NOT IN %(dimension)s
|
||||||
period_data = [0, 0, 0]
|
GROUP BY parent''',{'dimension':[dimension]})
|
||||||
for month in relevant_months:
|
if DCC_allocation:
|
||||||
if monthwise_data.get(year[0]):
|
filters['budget_against_filter'] = [DCC_allocation[0][0]]
|
||||||
month_data = monthwise_data.get(year[0]).get(month, {})
|
cam_map = get_dimension_account_month_map(filters)
|
||||||
for i, fieldname in enumerate(["target", "actual", "variance"]):
|
dimension_items = cam_map.get(DCC_allocation[0][0])
|
||||||
value = flt(month_data.get(fieldname))
|
if dimension_items:
|
||||||
period_data[i] += value
|
data = get_final_data(dimension, dimension_items, filters, period_month_ranges, data, DCC_allocation[0][1])
|
||||||
totals[i] += value
|
|
||||||
|
|
||||||
period_data[0] += last_total
|
|
||||||
|
|
||||||
if filters.get("show_cumulative"):
|
|
||||||
last_total = period_data[0] - period_data[1]
|
|
||||||
|
|
||||||
period_data[2] = period_data[0] - period_data[1]
|
|
||||||
row += period_data
|
|
||||||
totals[2] = totals[0] - totals[1]
|
|
||||||
if filters["period"] != "Yearly":
|
|
||||||
row += totals
|
|
||||||
data.append(row)
|
|
||||||
|
|
||||||
chart = get_chart_data(filters, columns, data)
|
chart = get_chart_data(filters, columns, data)
|
||||||
|
|
||||||
return columns, data, None, chart
|
return columns, data, None, chart
|
||||||
|
|
||||||
|
def get_final_data(dimension, dimension_items, filters, period_month_ranges, data, DCC_allocation):
|
||||||
|
|
||||||
|
for account, monthwise_data in iteritems(dimension_items):
|
||||||
|
row = [dimension, account]
|
||||||
|
totals = [0, 0, 0]
|
||||||
|
for year in get_fiscal_years(filters):
|
||||||
|
last_total = 0
|
||||||
|
for relevant_months in period_month_ranges:
|
||||||
|
period_data = [0, 0, 0]
|
||||||
|
for month in relevant_months:
|
||||||
|
if monthwise_data.get(year[0]):
|
||||||
|
month_data = monthwise_data.get(year[0]).get(month, {})
|
||||||
|
for i, fieldname in enumerate(["target", "actual", "variance"]):
|
||||||
|
value = flt(month_data.get(fieldname))
|
||||||
|
period_data[i] += value
|
||||||
|
totals[i] += value
|
||||||
|
|
||||||
|
period_data[0] += last_total
|
||||||
|
|
||||||
|
if DCC_allocation:
|
||||||
|
period_data[0] = period_data[0]*(DCC_allocation/100)
|
||||||
|
period_data[1] = period_data[1]*(DCC_allocation/100)
|
||||||
|
|
||||||
|
if(filters.get("show_cumulative")):
|
||||||
|
last_total = period_data[0] - period_data[1]
|
||||||
|
|
||||||
|
period_data[2] = period_data[0] - period_data[1]
|
||||||
|
row += period_data
|
||||||
|
totals[2] = totals[0] - totals[1]
|
||||||
|
if filters["period"] != "Yearly" :
|
||||||
|
row += totals
|
||||||
|
data.append(row)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
def get_columns(filters):
|
def get_columns(filters):
|
||||||
columns = [
|
columns = [
|
||||||
{
|
{
|
||||||
@ -366,7 +389,7 @@ def get_chart_data(filters, columns, data):
|
|||||||
budget_values[i] += values[index]
|
budget_values[i] += values[index]
|
||||||
actual_values[i] += values[index+1]
|
actual_values[i] += values[index+1]
|
||||||
index += 3
|
index += 3
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'data': {
|
'data': {
|
||||||
'labels': labels,
|
'labels': labels,
|
||||||
|
@ -5,6 +5,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
frappe.query_reports["Cash Flow"] = $.extend({},
|
frappe.query_reports["Cash Flow"] = $.extend({},
|
||||||
erpnext.financial_statements);
|
erpnext.financial_statements);
|
||||||
|
|
||||||
|
erpnext.utils.add_dimensions('Cash Flow', 10);
|
||||||
|
|
||||||
// The last item in the array is the definition for Presentation Currency
|
// The last item in the array is the definition for Presentation Currency
|
||||||
// filter. It won't be used in cash flow for now so we pop it. Please take
|
// filter. It won't be used in cash flow for now so we pop it. Please take
|
||||||
// of this if you are working here.
|
// of this if you are working here.
|
||||||
|
@ -33,7 +33,6 @@ frappe.query_reports["Consolidated Financial Statement"] = {
|
|||||||
"fieldname":"period_start_date",
|
"fieldname":"period_start_date",
|
||||||
"label": __("Start Date"),
|
"label": __("Start Date"),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"default": frappe.datetime.nowdate(),
|
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
@ -41,7 +40,6 @@ frappe.query_reports["Consolidated Financial Statement"] = {
|
|||||||
"fieldname":"period_end_date",
|
"fieldname":"period_end_date",
|
||||||
"label": __("End Date"),
|
"label": __("End Date"),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"default": frappe.datetime.add_months(frappe.datetime.nowdate(), 12),
|
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
@ -106,5 +104,16 @@ frappe.query_reports["Consolidated Financial Statement"] = {
|
|||||||
value = $value.wrap("<p></p>").parent().html();
|
value = $value.wrap("<p></p>").parent().html();
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
},
|
||||||
|
onload: function() {
|
||||||
|
let fiscal_year = frappe.defaults.get_user_default("fiscal_year")
|
||||||
|
|
||||||
|
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
|
||||||
|
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
|
||||||
|
frappe.query_report.set_filter_value({
|
||||||
|
period_start_date: fy.year_start_date,
|
||||||
|
period_end_date: fy.year_end_date
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,9 +56,8 @@ def get_period_list(from_fiscal_year, to_fiscal_year, period_start_date, period_
|
|||||||
to_date = add_months(start_date, months_to_add)
|
to_date = add_months(start_date, months_to_add)
|
||||||
start_date = to_date
|
start_date = to_date
|
||||||
|
|
||||||
if to_date == get_first_day(to_date):
|
# Subtract one day from to_date, as it may be first day in next fiscal year or month
|
||||||
# if to_date is the first day, get the last day of previous month
|
to_date = add_days(to_date, -1)
|
||||||
to_date = add_days(to_date, -1)
|
|
||||||
|
|
||||||
if to_date <= year_end_date:
|
if to_date <= year_end_date:
|
||||||
# the normal case
|
# the normal case
|
||||||
@ -387,11 +386,43 @@ def set_gl_entries_by_account(
|
|||||||
key: value
|
key: value
|
||||||
})
|
})
|
||||||
|
|
||||||
|
distributed_cost_center_query = ""
|
||||||
|
if filters and filters.get('cost_center'):
|
||||||
|
distributed_cost_center_query = """
|
||||||
|
UNION ALL
|
||||||
|
SELECT posting_date,
|
||||||
|
account,
|
||||||
|
debit*(DCC_allocation.percentage_allocation/100) as debit,
|
||||||
|
credit*(DCC_allocation.percentage_allocation/100) as credit,
|
||||||
|
is_opening,
|
||||||
|
fiscal_year,
|
||||||
|
debit_in_account_currency*(DCC_allocation.percentage_allocation/100) as debit_in_account_currency,
|
||||||
|
credit_in_account_currency*(DCC_allocation.percentage_allocation/100) as credit_in_account_currency,
|
||||||
|
account_currency
|
||||||
|
FROM `tabGL Entry`,
|
||||||
|
(
|
||||||
|
SELECT parent, sum(percentage_allocation) as percentage_allocation
|
||||||
|
FROM `tabDistributed Cost Center`
|
||||||
|
WHERE cost_center IN %(cost_center)s
|
||||||
|
AND parent NOT IN %(cost_center)s
|
||||||
|
AND is_cancelled = 0
|
||||||
|
GROUP BY parent
|
||||||
|
) as DCC_allocation
|
||||||
|
WHERE company=%(company)s
|
||||||
|
{additional_conditions}
|
||||||
|
AND posting_date <= %(to_date)s
|
||||||
|
AND cost_center = DCC_allocation.parent
|
||||||
|
""".format(additional_conditions=additional_conditions.replace("and cost_center in %(cost_center)s ", ''))
|
||||||
|
|
||||||
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year, debit_in_account_currency, credit_in_account_currency, account_currency from `tabGL Entry`
|
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year, debit_in_account_currency, credit_in_account_currency, account_currency from `tabGL Entry`
|
||||||
where company=%(company)s
|
where company=%(company)s
|
||||||
{additional_conditions}
|
{additional_conditions}
|
||||||
and posting_date <= %(to_date)s
|
and posting_date <= %(to_date)s
|
||||||
order by account, posting_date""".format(additional_conditions=additional_conditions), gl_filters, as_dict=True) #nosec
|
and is_cancelled = 0
|
||||||
|
{distributed_cost_center_query}
|
||||||
|
order by account, posting_date""".format(
|
||||||
|
additional_conditions=additional_conditions,
|
||||||
|
distributed_cost_center_query=distributed_cost_center_query), gl_filters, as_dict=True) #nosec
|
||||||
|
|
||||||
if filters and filters.get('presentation_currency'):
|
if filters and filters.get('presentation_currency'):
|
||||||
convert_to_presentation_currency(gl_entries, get_currency(filters))
|
convert_to_presentation_currency(gl_entries, get_currency(filters))
|
||||||
@ -489,4 +520,4 @@ def get_columns(periodicity, period_list, accumulated_values=1, company=None):
|
|||||||
"width": 150
|
"width": 150
|
||||||
})
|
})
|
||||||
|
|
||||||
return columns
|
return columns
|
@ -164,12 +164,5 @@ frappe.query_reports["General Ledger"] = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.dimension_filters.forEach((dimension) => {
|
erpnext.utils.add_dimensions('General Ledger', 15)
|
||||||
frappe.query_reports["General Ledger"].filters.splice(15, 0 ,{
|
|
||||||
"fieldname": dimension["fieldname"],
|
|
||||||
"label": __(dimension["label"]),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": dimension["document_type"]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
@ -128,18 +128,53 @@ def get_gl_entries(filters):
|
|||||||
filters['company_fb'] = frappe.db.get_value("Company",
|
filters['company_fb'] = frappe.db.get_value("Company",
|
||||||
filters.get("company"), 'default_finance_book')
|
filters.get("company"), 'default_finance_book')
|
||||||
|
|
||||||
|
distributed_cost_center_query = ""
|
||||||
|
if filters and filters.get('cost_center'):
|
||||||
|
select_fields_with_percentage = """, debit*(DCC_allocation.percentage_allocation/100) as debit, credit*(DCC_allocation.percentage_allocation/100) as credit, debit_in_account_currency*(DCC_allocation.percentage_allocation/100) as debit_in_account_currency,
|
||||||
|
credit_in_account_currency*(DCC_allocation.percentage_allocation/100) as credit_in_account_currency """
|
||||||
|
|
||||||
|
distributed_cost_center_query = """
|
||||||
|
UNION ALL
|
||||||
|
SELECT name as gl_entry,
|
||||||
|
posting_date,
|
||||||
|
account,
|
||||||
|
party_type,
|
||||||
|
party,
|
||||||
|
voucher_type,
|
||||||
|
voucher_no,
|
||||||
|
cost_center, project,
|
||||||
|
against_voucher_type,
|
||||||
|
against_voucher,
|
||||||
|
account_currency,
|
||||||
|
remarks, against,
|
||||||
|
is_opening, `tabGL Entry`.creation {select_fields_with_percentage}
|
||||||
|
FROM `tabGL Entry`,
|
||||||
|
(
|
||||||
|
SELECT parent, sum(percentage_allocation) as percentage_allocation
|
||||||
|
FROM `tabDistributed Cost Center`
|
||||||
|
WHERE cost_center IN %(cost_center)s
|
||||||
|
AND parent NOT IN %(cost_center)s
|
||||||
|
GROUP BY parent
|
||||||
|
) as DCC_allocation
|
||||||
|
WHERE company=%(company)s
|
||||||
|
{conditions}
|
||||||
|
AND posting_date <= %(to_date)s
|
||||||
|
AND cost_center = DCC_allocation.parent
|
||||||
|
""".format(select_fields_with_percentage=select_fields_with_percentage, conditions=get_conditions(filters).replace("and cost_center in %(cost_center)s ", ''))
|
||||||
|
|
||||||
gl_entries = frappe.db.sql(
|
gl_entries = frappe.db.sql(
|
||||||
"""
|
"""
|
||||||
select
|
select
|
||||||
name as gl_entry, posting_date, account, party_type, party,
|
name as gl_entry, posting_date, account, party_type, party,
|
||||||
voucher_type, voucher_no, cost_center, project,
|
voucher_type, voucher_no, cost_center, project,
|
||||||
against_voucher_type, against_voucher, account_currency,
|
against_voucher_type, against_voucher, account_currency,
|
||||||
remarks, against, is_opening {select_fields}
|
remarks, against, is_opening, creation {select_fields}
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where company=%(company)s {conditions}
|
where company=%(company)s {conditions}
|
||||||
|
{distributed_cost_center_query}
|
||||||
{order_by_statement}
|
{order_by_statement}
|
||||||
""".format(
|
""".format(
|
||||||
select_fields=select_fields, conditions=get_conditions(filters),
|
select_fields=select_fields, conditions=get_conditions(filters), distributed_cost_center_query=distributed_cost_center_query,
|
||||||
order_by_statement=order_by_statement
|
order_by_statement=order_by_statement
|
||||||
),
|
),
|
||||||
filters, as_dict=1)
|
filters, as_dict=1)
|
||||||
|
@ -4,11 +4,18 @@
|
|||||||
frappe.query_reports["Item-wise Purchase Register"] = {
|
frappe.query_reports["Item-wise Purchase Register"] = {
|
||||||
"filters": [
|
"filters": [
|
||||||
{
|
{
|
||||||
"fieldname":"date_range",
|
"fieldname":"from_date",
|
||||||
"label": __("Date Range"),
|
"label": __("From Date"),
|
||||||
"fieldtype": "DateRange",
|
"fieldtype": "Date",
|
||||||
"default": [frappe.datetime.add_months(frappe.datetime.get_today(),-1), frappe.datetime.get_today()],
|
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||||
"reqd": 1
|
"reqd": 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"to_date",
|
||||||
|
"label": __("To Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today(),
|
||||||
|
"reqd": 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
|
@ -14,7 +14,6 @@ def execute(filters=None):
|
|||||||
|
|
||||||
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
|
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
|
||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
filters.update({"from_date": filters.get("date_range")[0], "to_date": filters.get("date_range")[1]})
|
|
||||||
columns = get_columns(additional_table_columns, filters)
|
columns = get_columns(additional_table_columns, filters)
|
||||||
|
|
||||||
company_currency = erpnext.get_company_currency(filters.company)
|
company_currency = erpnext.get_company_currency(filters.company)
|
||||||
@ -266,13 +265,6 @@ def get_columns(additional_table_columns, filters):
|
|||||||
'fieldtype': 'Currency',
|
'fieldtype': 'Currency',
|
||||||
'options': 'currency',
|
'options': 'currency',
|
||||||
'width': 100
|
'width': 100
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'currency',
|
|
||||||
'label': _('Currency'),
|
|
||||||
'fieldtype': 'Currency',
|
|
||||||
'width': 80,
|
|
||||||
'hidden': 1
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -4,11 +4,18 @@
|
|||||||
frappe.query_reports["Item-wise Sales Register"] = {
|
frappe.query_reports["Item-wise Sales Register"] = {
|
||||||
"filters": [
|
"filters": [
|
||||||
{
|
{
|
||||||
"fieldname": "date_range",
|
"fieldname":"from_date",
|
||||||
"label": __("Date Range"),
|
"label": __("From Date"),
|
||||||
"fieldtype": "DateRange",
|
"fieldtype": "Date",
|
||||||
"default": [frappe.datetime.add_months(frappe.datetime.get_today(),-1), frappe.datetime.get_today()],
|
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||||
"reqd": 1
|
"reqd": 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"to_date",
|
||||||
|
"label": __("To Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today(),
|
||||||
|
"reqd": 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "customer",
|
"fieldname": "customer",
|
||||||
|
@ -14,7 +14,6 @@ def execute(filters=None):
|
|||||||
|
|
||||||
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
|
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
|
||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
filters.update({"from_date": filters.get("date_range") and filters.get("date_range")[0], "to_date": filters.get("date_range") and filters.get("date_range")[1]})
|
|
||||||
columns = get_columns(additional_table_columns, filters)
|
columns = get_columns(additional_table_columns, filters)
|
||||||
|
|
||||||
company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency")
|
company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency")
|
||||||
@ -224,7 +223,7 @@ def get_columns(additional_table_columns, filters):
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
if filters.get('group_by') != 'Terriotory':
|
if filters.get('group_by') != 'Territory':
|
||||||
columns.extend([
|
columns.extend([
|
||||||
{
|
{
|
||||||
'label': _("Territory"),
|
'label': _("Territory"),
|
||||||
@ -305,13 +304,6 @@ def get_columns(additional_table_columns, filters):
|
|||||||
'fieldtype': 'Currency',
|
'fieldtype': 'Currency',
|
||||||
'options': 'currency',
|
'options': 'currency',
|
||||||
'width': 100
|
'width': 100
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'currency',
|
|
||||||
'label': _('Currency'),
|
|
||||||
'fieldtype': 'Currency',
|
|
||||||
'width': 80,
|
|
||||||
'hidden': 1
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -537,6 +529,13 @@ def get_tax_accounts(item_list, columns, company_currency,
|
|||||||
'fieldtype': 'Currency',
|
'fieldtype': 'Currency',
|
||||||
'options': 'currency',
|
'options': 'currency',
|
||||||
'width': 100
|
'width': 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'currency',
|
||||||
|
'label': _('Currency'),
|
||||||
|
'fieldtype': 'Currency',
|
||||||
|
'width': 80,
|
||||||
|
'hidden': 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
frappe.query_reports["Ordered Items To Be Billed"] = {
|
|
||||||
"filters": [
|
|
||||||
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
"add_total_row": 1,
|
|
||||||
"apply_user_permissions": 1,
|
|
||||||
"creation": "2013-02-21 14:26:44",
|
|
||||||
"disabled": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "Report",
|
|
||||||
"idx": 3,
|
|
||||||
"is_standard": "Yes",
|
|
||||||
"modified": "2017-11-06 13:04:51.559061",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Accounts",
|
|
||||||
"name": "Ordered Items To Be Billed",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`customer_name` as \"Customer Name:150\",\n`tabSales Order`.`status` as \"Status\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project` as \"Project\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.base_amount as \"Amount:Currency:110\",\n (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1)) as \"Billed Amount:Currency:110\",\n (`tabSales Order Item`.base_amount - (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1))) as \"Pending Amount:Currency:120\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\",\n `tabSales Order`.`company` as \"Company:Link/Company:\"\nfrom\n `tabSales Order`, `tabSales Order Item`\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status != \"Closed\"\n and `tabSales Order Item`.amount > 0\n and `tabSales Order Item`.billed_amt < `tabSales Order Item`.amount\norder by `tabSales Order`.transaction_date asc",
|
|
||||||
"ref_doctype": "Sales Invoice",
|
|
||||||
"report_name": "Ordered Items To Be Billed",
|
|
||||||
"report_type": "Script Report",
|
|
||||||
"roles": [
|
|
||||||
{
|
|
||||||
"role": "Accounts Manager"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "Accounts User"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
# 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 erpnext.accounts.report.non_billed_report import get_ordered_to_be_billed_data
|
|
||||||
|
|
||||||
def execute(filters=None):
|
|
||||||
columns = get_column()
|
|
||||||
args = get_args()
|
|
||||||
data = get_ordered_to_be_billed_data(args)
|
|
||||||
return columns, data
|
|
||||||
|
|
||||||
def get_column():
|
|
||||||
return [
|
|
||||||
_("Sales Order") + ":Link/Sales Order:120", _("Status") + "::120", _("Date") + ":Date:100",
|
|
||||||
_("Suplier") + ":Link/Customer:120", _("Customer Name") + "::120",
|
|
||||||
_("Project") + ":Link/Project:120", _("Item Code") + ":Link/Item:120",
|
|
||||||
_("Amount") + ":Currency:100", _("Billed Amount") + ":Currency:100", _("Pending Amount") + ":Currency:100",
|
|
||||||
_("Item Name") + "::120", _("Description") + "::120", _("Company") + ":Link/Company:120",
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_args():
|
|
||||||
return {'doctype': 'Sales Order', 'party': 'customer',
|
|
||||||
'date': 'transaction_date', 'order': 'transaction_date', 'order_by': 'asc'}
|
|
@ -6,6 +6,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
frappe.query_reports["Profit and Loss Statement"] = $.extend({},
|
frappe.query_reports["Profit and Loss Statement"] = $.extend({},
|
||||||
erpnext.financial_statements);
|
erpnext.financial_statements);
|
||||||
|
|
||||||
|
erpnext.utils.add_dimensions('Profit and Loss Statement', 10);
|
||||||
|
|
||||||
frappe.query_reports["Profit and Loss Statement"]["filters"].push(
|
frappe.query_reports["Profit and Loss Statement"]["filters"].push(
|
||||||
{
|
{
|
||||||
"fieldname": "project",
|
"fieldname": "project",
|
||||||
|
@ -105,6 +105,7 @@ def accumulate_values_into_parents(accounts, accounts_by_name):
|
|||||||
|
|
||||||
def prepare_data(accounts, filters, total_row, parent_children_map, based_on):
|
def prepare_data(accounts, filters, total_row, parent_children_map, based_on):
|
||||||
data = []
|
data = []
|
||||||
|
new_accounts = accounts
|
||||||
company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency")
|
company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency")
|
||||||
|
|
||||||
for d in accounts:
|
for d in accounts:
|
||||||
@ -118,6 +119,19 @@ def prepare_data(accounts, filters, total_row, parent_children_map, based_on):
|
|||||||
"currency": company_currency,
|
"currency": company_currency,
|
||||||
"based_on": based_on
|
"based_on": based_on
|
||||||
}
|
}
|
||||||
|
if based_on == 'cost_center':
|
||||||
|
cost_center_doc = frappe.get_doc("Cost Center",d.name)
|
||||||
|
if not cost_center_doc.enable_distributed_cost_center:
|
||||||
|
DCC_allocation = frappe.db.sql("""SELECT parent, sum(percentage_allocation) as percentage_allocation
|
||||||
|
FROM `tabDistributed Cost Center`
|
||||||
|
WHERE cost_center IN %(cost_center)s
|
||||||
|
AND parent NOT IN %(cost_center)s
|
||||||
|
GROUP BY parent""",{'cost_center': [d.name]})
|
||||||
|
if DCC_allocation:
|
||||||
|
for account in new_accounts:
|
||||||
|
if account['name'] == DCC_allocation[0][0]:
|
||||||
|
for value in value_fields:
|
||||||
|
d[value] += account[value]*(DCC_allocation[0][1]/100)
|
||||||
|
|
||||||
for key in value_fields:
|
for key in value_fields:
|
||||||
row[key] = flt(d.get(key, 0.0), 3)
|
row[key] = flt(d.get(key, 0.0), 3)
|
||||||
|
@ -56,11 +56,4 @@ frappe.query_reports["Purchase Register"] = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.dimension_filters.forEach((dimension) => {
|
erpnext.utils.add_dimensions('Purchase Register', 7);
|
||||||
frappe.query_reports["Purchase Register"].filters.splice(7, 0 ,{
|
|
||||||
"fieldname": dimension["fieldname"],
|
|
||||||
"label": __(dimension["label"]),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": dimension["document_type"]
|
|
||||||
});
|
|
||||||
});
|
|
@ -68,12 +68,5 @@ frappe.query_reports["Sales Register"] = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.dimension_filters.forEach((dimension) => {
|
erpnext.utils.add_dimensions('Sales Register', 7);
|
||||||
frappe.query_reports["Sales Register"].filters.splice(7, 0 ,{
|
|
||||||
"fieldname": dimension["fieldname"],
|
|
||||||
"label": __(dimension["label"]),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": dimension["document_type"]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
@ -102,14 +102,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
"initial_depth": 3
|
"initial_depth": 3
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.dimension_filters.forEach((dimension) => {
|
erpnext.utils.add_dimensions('Trial Balance', 6);
|
||||||
frappe.query_reports["Trial Balance"].filters.splice(6, 0 ,{
|
|
||||||
"fieldname": dimension["fieldname"],
|
|
||||||
"label": __(dimension["label"]),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": dimension["document_type"]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,6 +57,9 @@ def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verb
|
|||||||
|
|
||||||
frappe.cache().hset("fiscal_years", company, fiscal_years)
|
frappe.cache().hset("fiscal_years", company, fiscal_years)
|
||||||
|
|
||||||
|
if not transaction_date and not fiscal_year:
|
||||||
|
return fiscal_years
|
||||||
|
|
||||||
if transaction_date:
|
if transaction_date:
|
||||||
transaction_date = getdate(transaction_date)
|
transaction_date = getdate(transaction_date)
|
||||||
|
|
||||||
@ -79,6 +82,23 @@ def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verb
|
|||||||
if verbose==1: frappe.msgprint(error_msg)
|
if verbose==1: frappe.msgprint(error_msg)
|
||||||
raise FiscalYearError(error_msg)
|
raise FiscalYearError(error_msg)
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_fiscal_year_filter_field(company=None):
|
||||||
|
field = {
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"options": [],
|
||||||
|
"operator": "Between",
|
||||||
|
"query_value": True
|
||||||
|
}
|
||||||
|
fiscal_years = get_fiscal_years(company=company)
|
||||||
|
for fiscal_year in fiscal_years:
|
||||||
|
field["options"].append({
|
||||||
|
"label": fiscal_year.name,
|
||||||
|
"value": fiscal_year.name,
|
||||||
|
"query_value": [fiscal_year.year_start_date.strftime("%Y-%m-%d"), fiscal_year.year_end_date.strftime("%Y-%m-%d")]
|
||||||
|
})
|
||||||
|
return field
|
||||||
|
|
||||||
def validate_fiscal_year(date, fiscal_year, company, label="Date", doc=None):
|
def validate_fiscal_year(date, fiscal_year, company, label="Date", doc=None):
|
||||||
years = [f[0] for f in get_fiscal_years(date, label=_(label), company=company)]
|
years = [f[0] for f in get_fiscal_years(date, label=_(label), company=company)]
|
||||||
if fiscal_year not in years:
|
if fiscal_year not in years:
|
||||||
@ -817,7 +837,7 @@ def create_payment_gateway_account(gateway):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def update_cost_center(docname, cost_center_name, cost_center_number, company):
|
def update_cost_center(docname, cost_center_name, cost_center_number, company, merge):
|
||||||
'''
|
'''
|
||||||
Renames the document by adding the number as a prefix to the current name and updates
|
Renames the document by adding the number as a prefix to the current name and updates
|
||||||
all transaction where it was present.
|
all transaction where it was present.
|
||||||
@ -833,7 +853,7 @@ def update_cost_center(docname, cost_center_name, cost_center_number, company):
|
|||||||
|
|
||||||
new_name = get_autoname_with_number(cost_center_number, cost_center_name, docname, company)
|
new_name = get_autoname_with_number(cost_center_number, cost_center_name, docname, company)
|
||||||
if docname != new_name:
|
if docname != new_name:
|
||||||
frappe.rename_doc("Cost Center", docname, new_name, force=1)
|
frappe.rename_doc("Cost Center", docname, new_name, force=1, merge=merge)
|
||||||
return new_name
|
return new_name
|
||||||
|
|
||||||
def validate_field_number(doctype_name, docname, number_value, company, field_name):
|
def validate_field_number(doctype_name, docname, number_value, company, field_name):
|
||||||
@ -942,4 +962,4 @@ def get_voucherwise_gl_entries(future_stock_vouchers, posting_date):
|
|||||||
tuple([posting_date] + [d[1] for d in future_stock_vouchers]), as_dict=1):
|
tuple([posting_date] + [d[1] for d in future_stock_vouchers]), as_dict=1):
|
||||||
gl_entries.setdefault((d.voucher_type, d.voucher_no), []).append(d)
|
gl_entries.setdefault((d.voucher_type, d.voucher_no), []).append(d)
|
||||||
|
|
||||||
return gl_entries
|
return gl_entries
|
||||||
|
@ -5,14 +5,23 @@ import frappe
|
|||||||
import json
|
import json
|
||||||
from frappe.utils import nowdate, add_months, get_date_str
|
from frappe.utils import nowdate, add_months, get_date_str
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.dashboard_fixtures import _get_fiscal_year
|
||||||
|
from erpnext.buying.dashboard_fixtures import get_company_for_dashboards
|
||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
|
|
||||||
|
fiscal_year = _get_fiscal_year(nowdate())
|
||||||
|
|
||||||
|
if not fiscal_year:
|
||||||
|
return frappe._dict()
|
||||||
|
|
||||||
|
year_start_date = get_date_str(fiscal_year.get('year_start_date'))
|
||||||
|
year_end_date = get_date_str(fiscal_year.get('year_end_date'))
|
||||||
|
|
||||||
return frappe._dict({
|
return frappe._dict({
|
||||||
"dashboards": get_dashboards(),
|
"dashboards": get_dashboards(),
|
||||||
"charts": get_charts(),
|
"charts": get_charts(fiscal_year, year_start_date, year_end_date),
|
||||||
"number_cards": get_number_cards(),
|
"number_cards": get_number_cards(fiscal_year, year_start_date, year_end_date),
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_dashboards():
|
def get_dashboards():
|
||||||
@ -31,12 +40,7 @@ def get_dashboards():
|
|||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
fiscal_year = get_fiscal_year(date=nowdate())
|
def get_charts(fiscal_year, year_start_date, year_end_date):
|
||||||
year_start_date = get_date_str(fiscal_year[1])
|
|
||||||
year_end_date = get_date_str(fiscal_year[2])
|
|
||||||
|
|
||||||
|
|
||||||
def get_charts():
|
|
||||||
company = get_company_for_dashboards()
|
company = get_company_for_dashboards()
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -55,8 +59,8 @@ def get_charts():
|
|||||||
"company": company,
|
"company": company,
|
||||||
"status": "In Location",
|
"status": "In Location",
|
||||||
"filter_based_on": "Fiscal Year",
|
"filter_based_on": "Fiscal Year",
|
||||||
"from_fiscal_year": fiscal_year[0],
|
"from_fiscal_year": fiscal_year.get('name'),
|
||||||
"to_fiscal_year": fiscal_year[0],
|
"to_fiscal_year": fiscal_year.get('name'),
|
||||||
"period_start_date": year_start_date,
|
"period_start_date": year_start_date,
|
||||||
"period_end_date": year_end_date,
|
"period_end_date": year_end_date,
|
||||||
"date_based_on": "Purchase Date",
|
"date_based_on": "Purchase Date",
|
||||||
@ -134,7 +138,7 @@ def get_charts():
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_number_cards():
|
def get_number_cards(fiscal_year, year_start_date, year_end_date):
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"name": "Total Assets",
|
"name": "Total Assets",
|
||||||
@ -172,14 +176,4 @@ def get_number_cards():
|
|||||||
"filters_json": "[]",
|
"filters_json": "[]",
|
||||||
"doctype": "Number Card"
|
"doctype": "Number Card"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_company_for_dashboards():
|
|
||||||
company = frappe.defaults.get_defaults().company
|
|
||||||
if company:
|
|
||||||
return company
|
|
||||||
else:
|
|
||||||
company_list = frappe.get_list("Company")
|
|
||||||
if company_list:
|
|
||||||
return company_list[0].name
|
|
||||||
return None
|
|
@ -1,559 +1,140 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"autoname": "field:asset_name",
|
||||||
"allow_import": 0,
|
"creation": "2017-10-19 16:50:22.879545",
|
||||||
"allow_rename": 0,
|
"doctype": "DocType",
|
||||||
"autoname": "field:asset_name",
|
"editable_grid": 1,
|
||||||
"beta": 0,
|
"engine": "InnoDB",
|
||||||
"creation": "2017-10-19 16:50:22.879545",
|
"field_order": [
|
||||||
"custom": 0,
|
"asset_name",
|
||||||
"docstatus": 0,
|
"asset_category",
|
||||||
"doctype": "DocType",
|
"company",
|
||||||
"document_type": "",
|
"column_break_3",
|
||||||
"editable_grid": 1,
|
"item_code",
|
||||||
"engine": "InnoDB",
|
"item_name",
|
||||||
|
"section_break_6",
|
||||||
|
"maintenance_team",
|
||||||
|
"column_break_9",
|
||||||
|
"maintenance_manager",
|
||||||
|
"maintenance_manager_name",
|
||||||
|
"section_break_8",
|
||||||
|
"asset_maintenance_tasks"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "asset_name",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Asset Name",
|
||||||
"columns": 0,
|
"options": "Asset",
|
||||||
"fieldname": "asset_name",
|
"reqd": 1,
|
||||||
"fieldtype": "Link",
|
"unique": 1
|
||||||
"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": "Asset Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset",
|
|
||||||
"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
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "asset_name.asset_category",
|
"fetch_from": "asset_name.asset_category",
|
||||||
"fieldname": "asset_category",
|
"fieldname": "asset_category",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Asset Category"
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Asset Category",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "asset_name.item_code",
|
"fetch_from": "asset_name.item_code",
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Item Code"
|
||||||
"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 Code",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "asset_name.item_name",
|
"fetch_from": "asset_name.item_name",
|
||||||
"fieldname": "item_name",
|
"fieldname": "item_name",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Item Name"
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_3",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Column Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_3",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "company",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"label": "Company",
|
||||||
"collapsible": 0,
|
"options": "Company",
|
||||||
"columns": 0,
|
"reqd": 1
|
||||||
"fieldname": "company",
|
},
|
||||||
"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": "Company",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "section_break_6",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Section Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "select_serial_no",
|
|
||||||
"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": "Select Serial No",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Serial No",
|
|
||||||
"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,
|
"fieldname": "maintenance_team",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Maintenance Team",
|
||||||
"columns": 0,
|
"options": "Asset Maintenance Team",
|
||||||
"fieldname": "serial_no",
|
"reqd": 1
|
||||||
"fieldtype": "Small Text",
|
},
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Serial No",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_9",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Column Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_6",
|
|
||||||
"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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "maintenance_team",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Maintenance Team",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset Maintenance Team",
|
|
||||||
"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
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_9",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "maintenance_team.maintenance_manager",
|
"fetch_from": "maintenance_team.maintenance_manager",
|
||||||
"fieldname": "maintenance_manager",
|
"fieldname": "maintenance_manager",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"ignore_user_permissions": 0,
|
"label": "Maintenance Manager",
|
||||||
"ignore_xss_filter": 0,
|
"read_only": 1
|
||||||
"in_filter": 0,
|
},
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Maintenance Manager",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "maintenance_team.maintenance_manager_name",
|
"fetch_from": "maintenance_team.maintenance_manager_name",
|
||||||
"fieldname": "maintenance_manager_name",
|
"fieldname": "maintenance_manager_name",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Maintenance Manager Name"
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Maintenance Manager Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "section_break_8",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Section Break",
|
||||||
"bold": 0,
|
"label": "Tasks"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_8",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Tasks",
|
|
||||||
"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,
|
"fieldname": "asset_maintenance_tasks",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Table",
|
||||||
"bold": 0,
|
"label": "Maintenance Tasks",
|
||||||
"collapsible": 0,
|
"options": "Asset Maintenance Task",
|
||||||
"columns": 0,
|
"reqd": 1
|
||||||
"fieldname": "asset_maintenance_tasks",
|
|
||||||
"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": "Maintenance Tasks",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset Maintenance Task",
|
|
||||||
"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,
|
"links": [],
|
||||||
"hide_heading": 0,
|
"modified": "2020-05-28 20:28:32.993823",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "Administrator",
|
||||||
"idx": 0,
|
"module": "Assets",
|
||||||
"image_view": 0,
|
"name": "Asset Maintenance",
|
||||||
"in_create": 0,
|
"owner": "Administrator",
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-05-22 17:20:54.711885",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Assets",
|
|
||||||
"name": "Asset Maintenance",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"cancel": 0,
|
"delete": 1,
|
||||||
"create": 1,
|
"email": 1,
|
||||||
"delete": 1,
|
"export": 1,
|
||||||
"email": 1,
|
"print": 1,
|
||||||
"export": 1,
|
"read": 1,
|
||||||
"if_owner": 0,
|
"report": 1,
|
||||||
"import": 0,
|
"role": "Quality Manager",
|
||||||
"permlevel": 0,
|
"share": 1,
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Quality Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"cancel": 0,
|
"delete": 1,
|
||||||
"create": 1,
|
"email": 1,
|
||||||
"delete": 1,
|
"export": 1,
|
||||||
"email": 1,
|
"print": 1,
|
||||||
"export": 1,
|
"read": 1,
|
||||||
"if_owner": 0,
|
"report": 1,
|
||||||
"import": 0,
|
"role": "Manufacturing User",
|
||||||
"permlevel": 0,
|
"share": 1,
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Manufacturing User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"sort_field": "modified",
|
||||||
"read_only": 0,
|
"sort_order": "DESC",
|
||||||
"read_only_onload": 0,
|
"track_changes": 1
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
@ -38,10 +38,10 @@ class AssetMaintenance(Document):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def assign_tasks(asset_maintenance_name, assign_to_member, maintenance_task, next_due_date):
|
def assign_tasks(asset_maintenance_name, assign_to_member, maintenance_task, next_due_date):
|
||||||
team_member = frappe.get_doc('User', assign_to_member).email
|
team_member = frappe.db.get_value('User', assign_to_member, "email")
|
||||||
args = {
|
args = {
|
||||||
'doctype' : 'Asset Maintenance',
|
'doctype' : 'Asset Maintenance',
|
||||||
'assign_to' : team_member,
|
'assign_to' : [team_member],
|
||||||
'name' : asset_maintenance_name,
|
'name' : asset_maintenance_name,
|
||||||
'description' : maintenance_task,
|
'description' : maintenance_task,
|
||||||
'date' : next_due_date
|
'date' : next_due_date
|
||||||
@ -77,7 +77,7 @@ def calculate_next_due_date(periodicity, start_date = None, end_date = None, las
|
|||||||
|
|
||||||
def update_maintenance_log(asset_maintenance, item_code, item_name, task):
|
def update_maintenance_log(asset_maintenance, item_code, item_name, task):
|
||||||
asset_maintenance_log = frappe.get_value("Asset Maintenance Log", {"asset_maintenance": asset_maintenance,
|
asset_maintenance_log = frappe.get_value("Asset Maintenance Log", {"asset_maintenance": asset_maintenance,
|
||||||
"task": task.maintenance_task, "maintenance_status": ('in',['Planned','Overdue'])})
|
"task": task.name, "maintenance_status": ('in',['Planned','Overdue'])})
|
||||||
|
|
||||||
if not asset_maintenance_log:
|
if not asset_maintenance_log:
|
||||||
asset_maintenance_log = frappe.get_doc({
|
asset_maintenance_log = frappe.get_doc({
|
||||||
@ -86,7 +86,7 @@ def update_maintenance_log(asset_maintenance, item_code, item_name, task):
|
|||||||
"asset_name": asset_maintenance,
|
"asset_name": asset_maintenance,
|
||||||
"item_code": item_code,
|
"item_code": item_code,
|
||||||
"item_name": item_name,
|
"item_name": item_name,
|
||||||
"task": task.maintenance_task,
|
"task": task.name,
|
||||||
"has_certificate": task.certificate_required,
|
"has_certificate": task.certificate_required,
|
||||||
"description": task.description,
|
"description": task.description,
|
||||||
"assign_to_name": task.assign_to_name,
|
"assign_to_name": task.assign_to_name,
|
||||||
|
@ -1,819 +1,210 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"autoname": "naming_series:",
|
||||||
"allow_import": 0,
|
"creation": "2017-10-23 16:58:44.424309",
|
||||||
"allow_rename": 0,
|
"doctype": "DocType",
|
||||||
"autoname": "naming_series:",
|
"document_type": "Document",
|
||||||
"beta": 0,
|
"editable_grid": 1,
|
||||||
"creation": "2017-10-23 16:58:44.424309",
|
"engine": "InnoDB",
|
||||||
"custom": 0,
|
"field_order": [
|
||||||
"docstatus": 0,
|
"asset_maintenance",
|
||||||
"doctype": "DocType",
|
"naming_series",
|
||||||
"document_type": "Document",
|
"asset_name",
|
||||||
"editable_grid": 1,
|
"column_break_2",
|
||||||
"engine": "InnoDB",
|
"item_code",
|
||||||
|
"item_name",
|
||||||
|
"section_break_5",
|
||||||
|
"task",
|
||||||
|
"task_name",
|
||||||
|
"maintenance_type",
|
||||||
|
"periodicity",
|
||||||
|
"assign_to_name",
|
||||||
|
"column_break_6",
|
||||||
|
"due_date",
|
||||||
|
"completion_date",
|
||||||
|
"maintenance_status",
|
||||||
|
"section_break_12",
|
||||||
|
"has_certificate",
|
||||||
|
"certificate_attachement",
|
||||||
|
"section_break_6",
|
||||||
|
"description",
|
||||||
|
"column_break_9",
|
||||||
|
"actions_performed",
|
||||||
|
"amended_from"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "asset_maintenance",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Asset Maintenance",
|
||||||
"bold": 0,
|
"options": "Asset Maintenance"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "asset_maintenance",
|
|
||||||
"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": "Asset Maintenance",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset Maintenance",
|
|
||||||
"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,
|
"fieldname": "naming_series",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Select",
|
||||||
"allow_on_submit": 0,
|
"label": "Series",
|
||||||
"bold": 0,
|
"options": "ACC-AML-.YYYY.-",
|
||||||
"collapsible": 0,
|
"reqd": 1
|
||||||
"columns": 0,
|
},
|
||||||
"default": "",
|
|
||||||
"fieldname": "naming_series",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Series",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "ACC-AML-.YYYY.-",
|
|
||||||
"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
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fetch_from": "asset_maintenance.asset_name",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "asset_name",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Read Only",
|
||||||
"bold": 0,
|
"label": "Asset Name"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "asset_maintenance.asset_name",
|
|
||||||
"fieldname": "asset_name",
|
|
||||||
"fieldtype": "Read Only",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Asset Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_2",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 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,
|
"fetch_from": "asset_maintenance.item_code",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "item_code",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Read Only",
|
||||||
"bold": 0,
|
"label": "Item Code"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "asset_maintenance.item_code",
|
|
||||||
"fieldname": "item_code",
|
|
||||||
"fieldtype": "Read Only",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item Code",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fetch_from": "asset_maintenance.item_name",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "item_name",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Read Only",
|
||||||
"bold": 0,
|
"label": "Item Name"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "asset_maintenance.item_name",
|
|
||||||
"fieldname": "item_name",
|
|
||||||
"fieldtype": "Read Only",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "section_break_5",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Section Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_5",
|
|
||||||
"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,
|
"fieldname": "task",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Task",
|
||||||
"bold": 0,
|
"options": "Asset Maintenance Task"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "task",
|
|
||||||
"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": "Task",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset Maintenance Task",
|
|
||||||
"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,
|
"fetch_from": "task.maintenance_type",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "maintenance_type",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Read Only",
|
||||||
"bold": 0,
|
"label": "Maintenance Type"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "task.maintenance_type",
|
|
||||||
"fieldname": "maintenance_type",
|
|
||||||
"fieldtype": "Read Only",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Maintenance Type",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fetch_from": "task.periodicity",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "periodicity",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Data",
|
||||||
"bold": 0,
|
"label": "Periodicity",
|
||||||
"collapsible": 0,
|
"read_only": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fetch_from": "task.periodicity",
|
|
||||||
"fieldname": "periodicity",
|
|
||||||
"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": "Periodicity",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fetch_from": "task.assign_to_name",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "assign_to_name",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Read Only",
|
||||||
"bold": 0,
|
"label": "Assign To"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "task.assign_to_name",
|
|
||||||
"fieldname": "assign_to_name",
|
|
||||||
"fieldtype": "Read Only",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Assign To",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_6",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_6",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fetch_from": "task.next_due_date",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "due_date",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Date",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Due Date",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fetch_from": "task.next_due_date",
|
},
|
||||||
"fieldname": "due_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Due Date",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "completion_date",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Date",
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 1,
|
||||||
"bold": 0,
|
"label": "Completion Date"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "completion_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Completion Date",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "maintenance_status",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Select",
|
||||||
"allow_on_submit": 0,
|
"in_standard_filter": 1,
|
||||||
"bold": 0,
|
"label": "Maintenance Status",
|
||||||
"collapsible": 0,
|
"options": "Planned\nCompleted\nCancelled\nOverdue",
|
||||||
"columns": 0,
|
"reqd": 1
|
||||||
"fieldname": "maintenance_status",
|
},
|
||||||
"fieldtype": "Select",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 1,
|
|
||||||
"label": "Maintenance Status",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Planned\nCompleted\nCancelled\nOverdue",
|
|
||||||
"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
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "section_break_12",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Section Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_12",
|
|
||||||
"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,
|
"default": "0",
|
||||||
"allow_in_quick_entry": 0,
|
"fetch_from": "task.certificate_required",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "has_certificate",
|
||||||
"bold": 0,
|
"fieldtype": "Check",
|
||||||
"collapsible": 0,
|
"label": "Has Certificate "
|
||||||
"columns": 0,
|
},
|
||||||
"fetch_from": "task.certificate_required",
|
|
||||||
"fieldname": "has_certificate",
|
|
||||||
"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": "Has Certificate ",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"depends_on": "eval:doc.has_certificate",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "certificate_attachement",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Attach",
|
||||||
"bold": 0,
|
"label": "Certificate"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:doc.has_certificate",
|
|
||||||
"fieldname": "certificate_attachement",
|
|
||||||
"fieldtype": "Attach",
|
|
||||||
"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": "Certificate",
|
|
||||||
"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,
|
"fieldname": "section_break_6",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_6",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fetch_from": "task.description",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "description",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Read Only",
|
||||||
"bold": 0,
|
"label": "Description",
|
||||||
"collapsible": 0,
|
"read_only": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fetch_from": "task.description",
|
|
||||||
"fieldname": "description",
|
|
||||||
"fieldtype": "Read Only",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Description",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_9",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Section Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_9",
|
|
||||||
"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_on_submit": 1,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "actions_performed",
|
||||||
"allow_on_submit": 1,
|
"fieldtype": "Text Editor",
|
||||||
"bold": 0,
|
"label": "Actions performed"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "actions_performed",
|
|
||||||
"fieldtype": "Text Editor",
|
|
||||||
"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": "Actions performed",
|
|
||||||
"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,
|
"fieldname": "amended_from",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Amended From",
|
||||||
"bold": 0,
|
"no_copy": 1,
|
||||||
"collapsible": 0,
|
"options": "Asset Maintenance Log",
|
||||||
"columns": 0,
|
"print_hide": 1,
|
||||||
"fieldname": "amended_from",
|
"read_only": 1
|
||||||
"fieldtype": "Link",
|
},
|
||||||
"hidden": 0,
|
{
|
||||||
"ignore_user_permissions": 0,
|
"fetch_from": "task.maintenance_task",
|
||||||
"ignore_xss_filter": 0,
|
"fieldname": "task_name",
|
||||||
"in_filter": 0,
|
"fieldtype": "Data",
|
||||||
"in_global_search": 0,
|
"in_preview": 1,
|
||||||
"in_list_view": 0,
|
"label": "Task Name",
|
||||||
"in_standard_filter": 0,
|
"read_only": 1
|
||||||
"label": "Amended From",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Asset Maintenance Log",
|
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"is_submittable": 1,
|
||||||
"hide_heading": 0,
|
"links": [],
|
||||||
"hide_toolbar": 0,
|
"modified": "2020-05-28 20:51:48.238397",
|
||||||
"idx": 0,
|
"modified_by": "Administrator",
|
||||||
"image_view": 0,
|
"module": "Assets",
|
||||||
"in_create": 0,
|
"name": "Asset Maintenance Log",
|
||||||
"is_submittable": 1,
|
"owner": "Administrator",
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-08-21 14:44:51.457835",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Assets",
|
|
||||||
"name": "Asset Maintenance Log",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"print": 1,
|
||||||
"import": 0,
|
"read": 1,
|
||||||
"permlevel": 0,
|
"report": 1,
|
||||||
"print": 1,
|
"role": "Manufacturing User",
|
||||||
"read": 1,
|
"share": 1,
|
||||||
"report": 1,
|
"submit": 1,
|
||||||
"role": "Manufacturing User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 1,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"sort_field": "modified",
|
||||||
"read_only": 0,
|
"sort_order": "DESC",
|
||||||
"read_only_onload": 0,
|
"track_changes": 1,
|
||||||
"show_name_in_global_search": 0,
|
"track_seen": 1
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"title_field": "",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 1,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
@ -7,5 +7,4 @@ import frappe
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class AssetMaintenanceTask(Document):
|
class AssetMaintenanceTask(Document):
|
||||||
def autoname(self):
|
pass
|
||||||
self.name = self.maintenance_task
|
|
||||||
|
@ -5,13 +5,24 @@ import frappe
|
|||||||
import json
|
import json
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.dashboard_fixtures import _get_fiscal_year
|
||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
|
|
||||||
|
fiscal_year = _get_fiscal_year(nowdate())
|
||||||
|
|
||||||
|
if not fiscal_year:
|
||||||
|
return frappe._dict()
|
||||||
|
|
||||||
|
company = frappe.get_doc("Company", get_company_for_dashboards())
|
||||||
|
fiscal_year_name = fiscal_year.get("name")
|
||||||
|
start_date = str(fiscal_year.get("year_start_date"))
|
||||||
|
end_date = str(fiscal_year.get("year_end_date"))
|
||||||
|
|
||||||
return frappe._dict({
|
return frappe._dict({
|
||||||
"dashboards": get_dashboards(),
|
"dashboards": get_dashboards(),
|
||||||
"charts": get_charts(),
|
"charts": get_charts(company, fiscal_year_name, start_date, end_date),
|
||||||
"number_cards": get_number_cards(),
|
"number_cards": get_number_cards(company, fiscal_year_name, start_date, end_date),
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_company_for_dashboards():
|
def get_company_for_dashboards():
|
||||||
@ -24,12 +35,6 @@ def get_company_for_dashboards():
|
|||||||
return company_list[0].name
|
return company_list[0].name
|
||||||
return None
|
return None
|
||||||
|
|
||||||
company = frappe.get_doc("Company", get_company_for_dashboards())
|
|
||||||
fiscal_year = get_fiscal_year(nowdate(), as_dict=1)
|
|
||||||
fiscal_year_name = fiscal_year.get("name")
|
|
||||||
start_date = str(fiscal_year.get("year_start_date"))
|
|
||||||
end_date = str(fiscal_year.get("year_end_date"))
|
|
||||||
|
|
||||||
def get_dashboards():
|
def get_dashboards():
|
||||||
return [{
|
return [{
|
||||||
"name": "Buying",
|
"name": "Buying",
|
||||||
@ -48,7 +53,7 @@ def get_dashboards():
|
|||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def get_charts():
|
def get_charts(company, fiscal_year_name, start_date, end_date):
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"name": "Purchase Order Analysis",
|
"name": "Purchase Order Analysis",
|
||||||
@ -139,7 +144,7 @@ def get_charts():
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_number_cards():
|
def get_number_cards(company, fiscal_year_name, start_date, end_date):
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"name": "Annual Purchase",
|
"name": "Annual Purchase",
|
||||||
@ -150,8 +155,7 @@ def get_number_cards():
|
|||||||
["Purchase Order", "transaction_date", "Between", [start_date, end_date], False],
|
["Purchase Order", "transaction_date", "Between", [start_date, end_date], False],
|
||||||
["Purchase Order", "status", "not in", ["Draft", "Cancelled", "Closed", None], False],
|
["Purchase Order", "status", "not in", ["Draft", "Cancelled", "Closed", None], False],
|
||||||
["Purchase Order", "docstatus", "=", 1, False],
|
["Purchase Order", "docstatus", "=", 1, False],
|
||||||
["Purchase Order", "company", "=", company.name, False],
|
["Purchase Order", "company", "=", company.name, False]
|
||||||
["Purchase Order", "transaction_date", "Between", [start_date,end_date], False]
|
|
||||||
]),
|
]),
|
||||||
"function": "Sum",
|
"function": "Sum",
|
||||||
"is_public": 1,
|
"is_public": 1,
|
||||||
|
@ -34,6 +34,11 @@
|
|||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Other Reports",
|
"label": "Other Reports",
|
||||||
"links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Items To Be Requested\",\n \"name\": \"Items To Be Requested\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase History\",\n \"name\": \"Item-wise Purchase History\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Subcontracted Raw Materials To Be Transferred\",\n \"name\": \"Subcontracted Raw Materials To Be Transferred\",\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Subcontracted Item To Be Received\",\n \"name\": \"Subcontracted Item To Be Received\",\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Quoted Item Comparison\",\n \"name\": \"Quoted Item Comparison\",\n \"onboard\": 1,\n \"reference_doctype\": \"Supplier Quotation\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Material Requests for which Supplier Quotations are not created\",\n \"name\": \"Material Requests for which Supplier Quotations are not created\",\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"reference_doctype\": \"Address\",\n \"route_options\": {\n \"party_type\": \"Supplier\"\n },\n \"type\": \"report\"\n }\n]"
|
"links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Items To Be Requested\",\n \"name\": \"Items To Be Requested\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase History\",\n \"name\": \"Item-wise Purchase History\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Subcontracted Raw Materials To Be Transferred\",\n \"name\": \"Subcontracted Raw Materials To Be Transferred\",\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Subcontracted Item To Be Received\",\n \"name\": \"Subcontracted Item To Be Received\",\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Quoted Item Comparison\",\n \"name\": \"Quoted Item Comparison\",\n \"onboard\": 1,\n \"reference_doctype\": \"Supplier Quotation\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Material Requests for which Supplier Quotations are not created\",\n \"name\": \"Material Requests for which Supplier Quotations are not created\",\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"reference_doctype\": \"Address\",\n \"route_options\": {\n \"party_type\": \"Supplier\"\n },\n \"type\": \"report\"\n }\n]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": 0,
|
||||||
|
"label": "Regional",
|
||||||
|
"links": "[\n {\n \"description\": \"Import Italian Purchase Invoices\",\n \"label\": \"Import Supplier Invoice\",\n \"name\": \"Import Supplier Invoice\",\n \"type\": \"doctype\"\n } \n]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"cards_label": "",
|
"cards_label": "",
|
||||||
|
@ -11,21 +11,21 @@ frappe.tour['Buying Settings'] = [
|
|||||||
{
|
{
|
||||||
fieldname: "supp_master_name",
|
fieldname: "supp_master_name",
|
||||||
title: "Supplier Naming By",
|
title: "Supplier Naming By",
|
||||||
description: __("By default, the Item Name is set as per the Item Code entered. If you want Items to be named by a set ") + "<a href='https://docs.erpnext.com/docs/user/manual/en/setting-up/settings/naming-series' target='_blank'>Naming Series</a>" + __(" choose the 'Naming Series' option."),
|
description: __("By default, the Supplier Name is set as per the Supplier Name entered. If you want Suppliers to be named by a ") + "<a href='https://docs.erpnext.com/docs/user/manual/en/setting-up/settings/naming-series' target='_blank'>Naming Series</a>" + __(" choose the 'Naming Series' option."),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "buying_price_list",
|
fieldname: "buying_price_list",
|
||||||
title: "Default Buying Price List",
|
title: "Default Buying Price List",
|
||||||
description: __("Configure the default Price List when creating a new Buying transaction, the default is set as 'Standard Buying'. Item prices will be fetched from this Price List.")
|
description: __("Configure the default Price List when creating a new Purchase transaction. Item prices will be fetched from this Price List.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "po_required",
|
fieldname: "po_required",
|
||||||
title: "Purchase Order Required for Purchase Invoice & Receipt Creation",
|
title: "Purchase Order Required for Purchase Invoice & Receipt Creation",
|
||||||
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice or Receipt without creating a Purchase Order first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Order' checkbox in supplier master.")
|
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice or Receipt without creating a Purchase Order first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Order' checkbox in the Supplier master.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "pr_required",
|
fieldname: "pr_required",
|
||||||
title: "Purchase Receipt Required for Purchase Invoice Creation",
|
title: "Purchase Receipt Required for Purchase Invoice Creation",
|
||||||
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice without creating a Purchase Receipt first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Receipt' checkbox in supplier master.")
|
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice without creating a Purchase Receipt first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Receipt' checkbox in the Supplier master.")
|
||||||
}
|
}
|
||||||
];
|
];
|
File diff suppressed because it is too large
Load Diff
@ -71,6 +71,15 @@ class PurchaseOrder(BuyingController):
|
|||||||
"compare_fields": [["project", "="], ["item_code", "="],
|
"compare_fields": [["project", "="], ["item_code", "="],
|
||||||
["uom", "="], ["conversion_factor", "="]],
|
["uom", "="], ["conversion_factor", "="]],
|
||||||
"is_child_table": True
|
"is_child_table": True
|
||||||
|
},
|
||||||
|
"Material Request": {
|
||||||
|
"ref_dn_field": "material_request",
|
||||||
|
"compare_fields": [["company", "="]],
|
||||||
|
},
|
||||||
|
"Material Request Item": {
|
||||||
|
"ref_dn_field": "material_request_item",
|
||||||
|
"compare_fields": [["project", "="], ["item_code", "="]],
|
||||||
|
"is_child_table": True
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
self.assertEqual(po.get("items")[0].amount, 1400)
|
self.assertEqual(po.get("items")[0].amount, 1400)
|
||||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 3)
|
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 3)
|
||||||
|
|
||||||
|
|
||||||
def test_add_new_item_in_update_child_qty_rate(self):
|
def test_add_new_item_in_update_child_qty_rate(self):
|
||||||
po = create_purchase_order(do_not_save=1)
|
po = create_purchase_order(do_not_save=1)
|
||||||
po.items[0].qty = 4
|
po.items[0].qty = 4
|
||||||
@ -144,7 +144,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
self.assertEquals(len(po.get('items')), 2)
|
self.assertEquals(len(po.get('items')), 2)
|
||||||
self.assertEqual(po.status, 'To Receive and Bill')
|
self.assertEqual(po.status, 'To Receive and Bill')
|
||||||
|
|
||||||
|
|
||||||
def test_remove_item_in_update_child_qty_rate(self):
|
def test_remove_item_in_update_child_qty_rate(self):
|
||||||
po = create_purchase_order(do_not_save=1)
|
po = create_purchase_order(do_not_save=1)
|
||||||
po.items[0].qty = 4
|
po.items[0].qty = 4
|
||||||
@ -185,6 +185,23 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
self.assertEquals(len(po.get('items')), 1)
|
self.assertEquals(len(po.get('items')), 1)
|
||||||
self.assertEqual(po.status, 'To Receive and Bill')
|
self.assertEqual(po.status, 'To Receive and Bill')
|
||||||
|
|
||||||
|
def test_update_child_qty_rate_perm(self):
|
||||||
|
po = create_purchase_order(item_code= "_Test Item", qty=4)
|
||||||
|
|
||||||
|
user = 'test@example.com'
|
||||||
|
test_user = frappe.get_doc('User', user)
|
||||||
|
test_user.add_roles("Accounts User")
|
||||||
|
frappe.set_user(user)
|
||||||
|
|
||||||
|
# update qty
|
||||||
|
trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 200, 'qty' : 7, 'docname': po.items[0].name}])
|
||||||
|
self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Purchase Order', trans_item, po.name)
|
||||||
|
|
||||||
|
# add new item
|
||||||
|
trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 100, 'qty' : 2}])
|
||||||
|
self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Purchase Order', trans_item, po.name)
|
||||||
|
frappe.set_user("Administrator")
|
||||||
|
|
||||||
def test_update_qty(self):
|
def test_update_qty(self):
|
||||||
po = create_purchase_order()
|
po = create_purchase_order()
|
||||||
|
|
||||||
@ -689,7 +706,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
po.save()
|
po.save()
|
||||||
self.assertEqual(po.schedule_date, add_days(nowdate(), 2))
|
self.assertEqual(po.schedule_date, add_days(nowdate(), 2))
|
||||||
|
|
||||||
|
|
||||||
def test_po_optional_blanket_order(self):
|
def test_po_optional_blanket_order(self):
|
||||||
"""
|
"""
|
||||||
Expected result: Blanket order Ordered Quantity should only be affected on Purchase Order with against_blanket_order = 1.
|
Expected result: Blanket order Ordered Quantity should only be affected on Purchase Order with against_blanket_order = 1.
|
||||||
|
@ -25,6 +25,7 @@ class RequestforQuotation(BuyingController):
|
|||||||
self.validate_duplicate_supplier()
|
self.validate_duplicate_supplier()
|
||||||
self.validate_supplier_list()
|
self.validate_supplier_list()
|
||||||
validate_for_items(self)
|
validate_for_items(self)
|
||||||
|
super(RequestforQuotation, self).set_qty_as_per_stock_uom()
|
||||||
self.update_email_id()
|
self.update_email_id()
|
||||||
|
|
||||||
def validate_duplicate_supplier(self):
|
def validate_duplicate_supplier(self):
|
||||||
@ -278,6 +279,7 @@ def create_rfq_items(sq_doc, supplier, data):
|
|||||||
"description": data.description,
|
"description": data.description,
|
||||||
"qty": data.qty,
|
"qty": data.qty,
|
||||||
"rate": data.rate,
|
"rate": data.rate,
|
||||||
|
"conversion_factor": data.conversion_factor if data.conversion_factor else None,
|
||||||
"supplier_part_no": frappe.db.get_value("Item Supplier", {'parent': data.item_code, 'supplier': supplier}, "supplier_part_no"),
|
"supplier_part_no": frappe.db.get_value("Item Supplier", {'parent': data.item_code, 'supplier': supplier}, "supplier_part_no"),
|
||||||
"warehouse": data.warehouse or '',
|
"warehouse": data.warehouse or '',
|
||||||
"request_for_quotation_item": data.name,
|
"request_for_quotation_item": data.name,
|
||||||
|
@ -6,12 +6,14 @@ from __future__ import unicode_literals
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
|
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
||||||
|
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
||||||
|
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import create_supplier_quotation
|
||||||
|
|
||||||
class TestRequestforQuotation(unittest.TestCase):
|
class TestRequestforQuotation(unittest.TestCase):
|
||||||
def test_quote_status(self):
|
def test_quote_status(self):
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
|
||||||
rfq = make_request_for_quotation()
|
rfq = make_request_for_quotation()
|
||||||
|
|
||||||
self.assertEqual(rfq.get('suppliers')[0].quote_status, 'Pending')
|
self.assertEqual(rfq.get('suppliers')[0].quote_status, 'Pending')
|
||||||
@ -31,7 +33,6 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
self.assertEqual(rfq.get('suppliers')[1].quote_status, 'No Quote')
|
self.assertEqual(rfq.get('suppliers')[1].quote_status, 'No Quote')
|
||||||
|
|
||||||
def test_make_supplier_quotation(self):
|
def test_make_supplier_quotation(self):
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
|
||||||
rfq = make_request_for_quotation()
|
rfq = make_request_for_quotation()
|
||||||
|
|
||||||
sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier)
|
sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier)
|
||||||
@ -51,15 +52,13 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
self.assertEqual(sq1.get('items')[0].qty, 5)
|
self.assertEqual(sq1.get('items')[0].qty, 5)
|
||||||
|
|
||||||
def test_make_supplier_quotation_with_special_characters(self):
|
def test_make_supplier_quotation_with_special_characters(self):
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
|
||||||
|
|
||||||
frappe.delete_doc_if_exists("Supplier", "_Test Supplier '1", force=1)
|
frappe.delete_doc_if_exists("Supplier", "_Test Supplier '1", force=1)
|
||||||
supplier = frappe.new_doc("Supplier")
|
supplier = frappe.new_doc("Supplier")
|
||||||
supplier.supplier_name = "_Test Supplier '1"
|
supplier.supplier_name = "_Test Supplier '1"
|
||||||
supplier.supplier_group = "_Test Supplier Group"
|
supplier.supplier_group = "_Test Supplier Group"
|
||||||
supplier.insert()
|
supplier.insert()
|
||||||
|
|
||||||
rfq = make_request_for_quotation(supplier_wt_appos)
|
rfq = make_request_for_quotation(supplier_data=supplier_wt_appos)
|
||||||
|
|
||||||
sq = make_supplier_quotation(rfq.name, supplier_wt_appos[0].get("supplier"))
|
sq = make_supplier_quotation(rfq.name, supplier_wt_appos[0].get("supplier"))
|
||||||
sq.submit()
|
sq.submit()
|
||||||
@ -76,7 +75,6 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
frappe.form_dict.name = None
|
frappe.form_dict.name = None
|
||||||
|
|
||||||
def test_make_supplier_quotation_from_portal(self):
|
def test_make_supplier_quotation_from_portal(self):
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import create_supplier_quotation
|
|
||||||
rfq = make_request_for_quotation()
|
rfq = make_request_for_quotation()
|
||||||
rfq.get('items')[0].rate = 100
|
rfq.get('items')[0].rate = 100
|
||||||
rfq.supplier = rfq.suppliers[0].supplier
|
rfq.supplier = rfq.suppliers[0].supplier
|
||||||
@ -90,12 +88,34 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
self.assertEqual(supplier_quotation_doc.get('items')[0].qty, 5)
|
self.assertEqual(supplier_quotation_doc.get('items')[0].qty, 5)
|
||||||
self.assertEqual(supplier_quotation_doc.get('items')[0].amount, 500)
|
self.assertEqual(supplier_quotation_doc.get('items')[0].amount, 500)
|
||||||
|
|
||||||
|
def test_make_multi_uom_supplier_quotation(self):
|
||||||
|
item_code = "_Test Multi UOM RFQ Item"
|
||||||
|
if not frappe.db.exists('Item', item_code):
|
||||||
|
item = make_item(item_code, {'stock_uom': '_Test UOM'})
|
||||||
|
row = item.append('uoms', {
|
||||||
|
'uom': 'Kg',
|
||||||
|
'conversion_factor': 2
|
||||||
|
})
|
||||||
|
row.db_update()
|
||||||
|
|
||||||
def make_request_for_quotation(supplier_data=None):
|
rfq = make_request_for_quotation(item_code="_Test Multi UOM RFQ Item", uom="Kg", conversion_factor=2)
|
||||||
|
rfq.get('items')[0].rate = 100
|
||||||
|
rfq.supplier = rfq.suppliers[0].supplier
|
||||||
|
|
||||||
|
self.assertEqual(rfq.items[0].stock_qty, 10)
|
||||||
|
|
||||||
|
supplier_quotation_name = create_supplier_quotation(rfq)
|
||||||
|
supplier_quotation = frappe.get_doc('Supplier Quotation', supplier_quotation_name)
|
||||||
|
|
||||||
|
self.assertEqual(supplier_quotation.items[0].qty, 5)
|
||||||
|
self.assertEqual(supplier_quotation.items[0].stock_qty, 10)
|
||||||
|
|
||||||
|
def make_request_for_quotation(**args):
|
||||||
"""
|
"""
|
||||||
:param supplier_data: List containing supplier data
|
:param supplier_data: List containing supplier data
|
||||||
"""
|
"""
|
||||||
supplier_data = supplier_data if supplier_data else get_supplier_data()
|
args = frappe._dict(args)
|
||||||
|
supplier_data = args.get("supplier_data") if args.get("supplier_data") else get_supplier_data()
|
||||||
rfq = frappe.new_doc('Request for Quotation')
|
rfq = frappe.new_doc('Request for Quotation')
|
||||||
rfq.transaction_date = nowdate()
|
rfq.transaction_date = nowdate()
|
||||||
rfq.status = 'Draft'
|
rfq.status = 'Draft'
|
||||||
@ -106,11 +126,13 @@ def make_request_for_quotation(supplier_data=None):
|
|||||||
rfq.append('suppliers', data)
|
rfq.append('suppliers', data)
|
||||||
|
|
||||||
rfq.append("items", {
|
rfq.append("items", {
|
||||||
"item_code": "_Test Item",
|
"item_code": args.item_code or "_Test Item",
|
||||||
"description": "_Test Item",
|
"description": "_Test Item",
|
||||||
"uom": "_Test UOM",
|
"uom": args.uom or "_Test UOM",
|
||||||
"qty": 5,
|
"stock_uom": args.stock_uom or "_Test UOM",
|
||||||
"warehouse": "_Test Warehouse - _TC",
|
"qty": args.qty or 5,
|
||||||
|
"conversion_factor": args.conversion_factor or 1.0,
|
||||||
|
"warehouse": args.warehouse or "_Test Warehouse - _TC",
|
||||||
"schedule_date": nowdate()
|
"schedule_date": nowdate()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "hash",
|
"autoname": "hash",
|
||||||
"creation": "2016-02-25 08:04:02.452958",
|
"creation": "2016-02-25 08:04:02.452958",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -9,6 +10,7 @@
|
|||||||
"supplier_part_no",
|
"supplier_part_no",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"item_name",
|
"item_name",
|
||||||
|
"schedule_date",
|
||||||
"section_break_5",
|
"section_break_5",
|
||||||
"description",
|
"description",
|
||||||
"item_group",
|
"item_group",
|
||||||
@ -18,9 +20,11 @@
|
|||||||
"image_view",
|
"image_view",
|
||||||
"quantity",
|
"quantity",
|
||||||
"qty",
|
"qty",
|
||||||
|
"stock_uom",
|
||||||
"col_break2",
|
"col_break2",
|
||||||
"schedule_date",
|
|
||||||
"uom",
|
"uom",
|
||||||
|
"conversion_factor",
|
||||||
|
"stock_qty",
|
||||||
"warehouse_and_reference",
|
"warehouse_and_reference",
|
||||||
"warehouse",
|
"warehouse",
|
||||||
"project_name",
|
"project_name",
|
||||||
@ -33,7 +37,7 @@
|
|||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"bold": 1,
|
"bold": 1,
|
||||||
"columns": 3,
|
"columns": 2,
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@ -98,7 +102,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "quantity",
|
"fieldname": "quantity",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Quantity"
|
"label": "Quantity & Stock"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bold": 1,
|
"bold": 1,
|
||||||
@ -129,12 +133,12 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "uom",
|
"fieldname": "uom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "UOM",
|
"label": "UOM",
|
||||||
"oldfieldname": "uom",
|
"oldfieldname": "uom",
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "UOM",
|
"options": "UOM",
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
"read_only": 1,
|
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
@ -144,7 +148,7 @@
|
|||||||
"label": "Warehouse and Reference"
|
"label": "Warehouse and Reference"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 3,
|
"columns": 2,
|
||||||
"fieldname": "warehouse",
|
"fieldname": "warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@ -202,6 +206,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
|
"default": "0",
|
||||||
"fieldname": "page_break",
|
"fieldname": "page_break",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Page Break",
|
"label": "Page Break",
|
||||||
@ -219,10 +224,36 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "section_break_23",
|
"fieldname": "section_break_23",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "stock_uom",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Stock UOM",
|
||||||
|
"options": "UOM",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1,
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "conversion_factor",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "UOM Conversion Factor",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1,
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "stock_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Qty as per Stock UOM",
|
||||||
|
"no_copy": 1,
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-05-01 17:50:23.703801",
|
"links": [],
|
||||||
|
"modified": "2020-06-12 19:10:36.333441",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Request for Quotation Item",
|
"name": "Request for Quotation Item",
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/buying",
|
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/buying",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_complete": 0,
|
"is_complete": 0,
|
||||||
"modified": "2020-05-27 17:17:52.075947",
|
"modified": "2020-06-01 12:55:09.234944",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Buying",
|
"name": "Buying",
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
{
|
{
|
||||||
"action": "Update Settings",
|
"action": "Show Form Tour",
|
||||||
"creation": "2020-05-06 15:53:44.667414",
|
"creation": "2020-05-06 15:53:44.667414",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Onboarding Step",
|
"doctype": "Onboarding Step",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_complete": 0,
|
"is_complete": 0,
|
||||||
"is_mandatory": 0,
|
"is_mandatory": 1,
|
||||||
"is_single": 0,
|
"is_single": 1,
|
||||||
"is_skipped": 0,
|
"is_skipped": 0,
|
||||||
"modified": "2020-05-12 18:30:06.323797",
|
"modified": "2020-06-01 12:52:57.668870",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"name": "Buying Settings",
|
"name": "Buying Settings",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"reference_document": "Buying Settings",
|
"reference_document": "Buying Settings",
|
||||||
"show_full_form": 0,
|
"show_full_form": 0,
|
||||||
"title": "Configure Buying Settings.",
|
"title": "Configure Buying Settings.",
|
||||||
"validate_action": 1
|
"validate_action": 0
|
||||||
}
|
}
|
@ -4,6 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
from frappe.utils import flt
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
columns = get_columns(filters)
|
columns = get_columns(filters)
|
||||||
@ -54,15 +55,16 @@ def get_columns(filters):
|
|||||||
"width": 140
|
"width": 140
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": _("Description"),
|
"label": _("Item"),
|
||||||
"fieldname": "description",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Link",
|
||||||
"width": 200
|
"options": "Item",
|
||||||
|
"width": 150
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": _("Quantity"),
|
"label": _("Quantity"),
|
||||||
"fieldname": "quantity",
|
"fieldname": "quantity",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Float",
|
||||||
"width": 140
|
"width": 140
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -118,7 +120,7 @@ def get_columns(filters):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": _("Purchase Order Amount(Company Currency)"),
|
"label": _("Purchase Order Amount(Company Currency)"),
|
||||||
"fieldname": "purchase_order_amt_usd",
|
"fieldname": "purchase_order_amt_in_company_currency",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"width": 140
|
"width": 140
|
||||||
},
|
},
|
||||||
@ -175,17 +177,17 @@ def get_data(filters):
|
|||||||
"requesting_site": po.warehouse,
|
"requesting_site": po.warehouse,
|
||||||
"requestor": po.owner,
|
"requestor": po.owner,
|
||||||
"material_request_no": po.material_request,
|
"material_request_no": po.material_request,
|
||||||
"description": po.description,
|
"item_code": po.item_code,
|
||||||
"quantity": po.qty,
|
"quantity": flt(po.qty),
|
||||||
"unit_of_measurement": po.stock_uom,
|
"unit_of_measurement": po.stock_uom,
|
||||||
"status": po.status,
|
"status": po.status,
|
||||||
"purchase_order_date": po.transaction_date,
|
"purchase_order_date": po.transaction_date,
|
||||||
"purchase_order": po.parent,
|
"purchase_order": po.parent,
|
||||||
"supplier": po.supplier,
|
"supplier": po.supplier,
|
||||||
"estimated_cost": mr_record.get('amount'),
|
"estimated_cost": flt(mr_record.get('amount')),
|
||||||
"actual_cost": pi_records.get(po.name),
|
"actual_cost": flt(pi_records.get(po.name)),
|
||||||
"purchase_order_amt": po.amount,
|
"purchase_order_amt": flt(po.amount),
|
||||||
"purchase_order_amt_in_company_currency": po.base_amount,
|
"purchase_order_amt_in_company_currency": flt(po.base_amount),
|
||||||
"expected_delivery_date": po.schedule_date,
|
"expected_delivery_date": po.schedule_date,
|
||||||
"actual_delivery_date": pr_records.get(po.name)
|
"actual_delivery_date": pr_records.get(po.name)
|
||||||
}
|
}
|
||||||
@ -198,9 +200,14 @@ def get_mapped_mr_details(conditions):
|
|||||||
SELECT
|
SELECT
|
||||||
par.transaction_date,
|
par.transaction_date,
|
||||||
par.per_ordered,
|
par.per_ordered,
|
||||||
|
par.owner,
|
||||||
child.name,
|
child.name,
|
||||||
child.parent,
|
child.parent,
|
||||||
child.amount
|
child.amount,
|
||||||
|
child.qty,
|
||||||
|
child.item_code,
|
||||||
|
child.uom,
|
||||||
|
par.status
|
||||||
FROM `tabMaterial Request` par, `tabMaterial Request Item` child
|
FROM `tabMaterial Request` par, `tabMaterial Request Item` child
|
||||||
WHERE
|
WHERE
|
||||||
par.per_ordered>=0
|
par.per_ordered>=0
|
||||||
@ -217,7 +224,15 @@ def get_mapped_mr_details(conditions):
|
|||||||
procurement_record_details = dict(
|
procurement_record_details = dict(
|
||||||
material_request_date=record.transaction_date,
|
material_request_date=record.transaction_date,
|
||||||
material_request_no=record.parent,
|
material_request_no=record.parent,
|
||||||
estimated_cost=record.amount
|
requestor=record.owner,
|
||||||
|
item_code=record.item_code,
|
||||||
|
estimated_cost=flt(record.amount),
|
||||||
|
quantity=flt(record.qty),
|
||||||
|
unit_of_measurement=record.uom,
|
||||||
|
status=record.status,
|
||||||
|
actual_cost=0,
|
||||||
|
purchase_order_amt=0,
|
||||||
|
purchase_order_amt_in_company_currency=0
|
||||||
)
|
)
|
||||||
procurement_record_against_mr.append(procurement_record_details)
|
procurement_record_against_mr.append(procurement_record_details)
|
||||||
return mr_records, procurement_record_against_mr
|
return mr_records, procurement_record_against_mr
|
||||||
@ -259,7 +274,7 @@ def get_po_entries(conditions):
|
|||||||
child.warehouse,
|
child.warehouse,
|
||||||
child.material_request,
|
child.material_request,
|
||||||
child.material_request_item,
|
child.material_request_item,
|
||||||
child.description,
|
child.item_code,
|
||||||
child.stock_uom,
|
child.stock_uom,
|
||||||
child.qty,
|
child.qty,
|
||||||
child.amount,
|
child.amount,
|
||||||
|
@ -15,7 +15,7 @@ class TestProcurementTracker(unittest.TestCase):
|
|||||||
def test_result_for_procurement_tracker(self):
|
def test_result_for_procurement_tracker(self):
|
||||||
filters = {
|
filters = {
|
||||||
'company': '_Test Procurement Company',
|
'company': '_Test Procurement Company',
|
||||||
'cost_center': '_Test Cost Center - _TC'
|
'cost_center': 'Main - _TPC'
|
||||||
}
|
}
|
||||||
expected_data = self.generate_expected_data()
|
expected_data = self.generate_expected_data()
|
||||||
report = execute(filters)
|
report = execute(filters)
|
||||||
@ -33,24 +33,27 @@ class TestProcurementTracker(unittest.TestCase):
|
|||||||
country="Pakistan"
|
country="Pakistan"
|
||||||
)).insert()
|
)).insert()
|
||||||
warehouse = create_warehouse("_Test Procurement Warehouse", company="_Test Procurement Company")
|
warehouse = create_warehouse("_Test Procurement Warehouse", company="_Test Procurement Company")
|
||||||
mr = make_material_request(company="_Test Procurement Company", warehouse=warehouse)
|
mr = make_material_request(company="_Test Procurement Company", warehouse=warehouse, cost_center="Main - _TPC")
|
||||||
po = make_purchase_order(mr.name)
|
po = make_purchase_order(mr.name)
|
||||||
po.supplier = "_Test Supplier"
|
po.supplier = "_Test Supplier"
|
||||||
po.get("items")[0].cost_center = "_Test Cost Center - _TC"
|
po.get("items")[0].cost_center = "Main - _TPC"
|
||||||
po.submit()
|
po.submit()
|
||||||
pr = make_purchase_receipt(po.name)
|
pr = make_purchase_receipt(po.name)
|
||||||
|
pr.get("items")[0].cost_center = "Main - _TPC"
|
||||||
pr.submit()
|
pr.submit()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
date_obj = datetime.date(datetime.now())
|
date_obj = datetime.date(datetime.now())
|
||||||
|
|
||||||
|
po.load_from_db()
|
||||||
|
|
||||||
expected_data = {
|
expected_data = {
|
||||||
"material_request_date": date_obj,
|
"material_request_date": date_obj,
|
||||||
"cost_center": "_Test Cost Center - _TC",
|
"cost_center": "Main - _TPC",
|
||||||
"project": None,
|
"project": None,
|
||||||
"requesting_site": "_Test Procurement Warehouse - _TPC",
|
"requesting_site": "_Test Procurement Warehouse - _TPC",
|
||||||
"requestor": "Administrator",
|
"requestor": "Administrator",
|
||||||
"material_request_no": mr.name,
|
"material_request_no": mr.name,
|
||||||
"description": '_Test Item 1',
|
"item_code": '_Test Item',
|
||||||
"quantity": 10.0,
|
"quantity": 10.0,
|
||||||
"unit_of_measurement": "_Test UOM",
|
"unit_of_measurement": "_Test UOM",
|
||||||
"status": "To Bill",
|
"status": "To Bill",
|
||||||
@ -58,9 +61,9 @@ class TestProcurementTracker(unittest.TestCase):
|
|||||||
"purchase_order": po.name,
|
"purchase_order": po.name,
|
||||||
"supplier": "_Test Supplier",
|
"supplier": "_Test Supplier",
|
||||||
"estimated_cost": 0.0,
|
"estimated_cost": 0.0,
|
||||||
"actual_cost": None,
|
"actual_cost": 0.0,
|
||||||
"purchase_order_amt": 5000.0,
|
"purchase_order_amt": po.net_total,
|
||||||
"purchase_order_amt_in_company_currency": 300000.0,
|
"purchase_order_amt_in_company_currency": po.base_net_total,
|
||||||
"expected_delivery_date": date_obj,
|
"expected_delivery_date": date_obj,
|
||||||
"actual_delivery_date": date_obj
|
"actual_delivery_date": date_obj
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
return [
|
config = [
|
||||||
{
|
{
|
||||||
"label": _("Purchasing"),
|
"label": _("Purchasing"),
|
||||||
"icon": "fa fa-star",
|
"icon": "fa fa-star",
|
||||||
@ -243,3 +244,21 @@ def get_data():
|
|||||||
},
|
},
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
regional = {
|
||||||
|
"label": _("Regional"),
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Import Supplier Invoice",
|
||||||
|
"description": _("Import Italian Supplier Invoice."),
|
||||||
|
"onboard": 1,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
countries = frappe.get_all("Company", fields="country")
|
||||||
|
countries = [country["country"] for country in countries]
|
||||||
|
if "Italy" in countries:
|
||||||
|
config.append(regional)
|
||||||
|
return config
|
@ -20,6 +20,7 @@ from erpnext.exceptions import InvalidCurrency
|
|||||||
from six import text_type
|
from six import text_type
|
||||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||||
from erpnext.stock.get_item_details import get_item_warehouse
|
from erpnext.stock.get_item_details import get_item_warehouse
|
||||||
|
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
|
||||||
|
|
||||||
force_item_fields = ("item_group", "brand", "stock_uom", "is_fixed_asset", "item_tax_rate", "pricing_rules")
|
force_item_fields = ("item_group", "brand", "stock_uom", "is_fixed_asset", "item_tax_rate", "pricing_rules")
|
||||||
|
|
||||||
@ -1137,8 +1138,8 @@ def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname,
|
|||||||
child_item.item_name = item.item_name
|
child_item.item_name = item.item_name
|
||||||
child_item.description = item.description
|
child_item.description = item.description
|
||||||
child_item.delivery_date = trans_item.get('delivery_date') or p_doc.delivery_date
|
child_item.delivery_date = trans_item.get('delivery_date') or p_doc.delivery_date
|
||||||
|
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
||||||
child_item.uom = item.stock_uom
|
child_item.uom = item.stock_uom
|
||||||
child_item.conversion_factor = get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
|
||||||
child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
|
child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
|
||||||
if not child_item.warehouse:
|
if not child_item.warehouse:
|
||||||
frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.")
|
frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.")
|
||||||
@ -1157,8 +1158,8 @@ def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docna
|
|||||||
child_item.item_name = item.item_name
|
child_item.item_name = item.item_name
|
||||||
child_item.description = item.description
|
child_item.description = item.description
|
||||||
child_item.schedule_date = trans_item.get('schedule_date') or p_doc.schedule_date
|
child_item.schedule_date = trans_item.get('schedule_date') or p_doc.schedule_date
|
||||||
|
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
||||||
child_item.uom = item.stock_uom
|
child_item.uom = item.stock_uom
|
||||||
child_item.conversion_factor = get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
|
||||||
child_item.base_rate = 1 # Initiallize value will update in parent validation
|
child_item.base_rate = 1 # Initiallize value will update in parent validation
|
||||||
child_item.base_amount = 1 # Initiallize value will update in parent validation
|
child_item.base_amount = 1 # Initiallize value will update in parent validation
|
||||||
return child_item
|
return child_item
|
||||||
@ -1190,6 +1191,26 @@ def check_and_delete_children(parent, data):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"):
|
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"):
|
||||||
|
def check_permissions(doc, perm_type='create'):
|
||||||
|
try:
|
||||||
|
doc.check_permission(perm_type)
|
||||||
|
except:
|
||||||
|
action = "add" if perm_type == 'create' else "update"
|
||||||
|
frappe.throw(_("You do not have permissions to {} items in a Sales Order.").format(action), title=_("Insufficient Permissions"))
|
||||||
|
|
||||||
|
def get_new_child_item(item_row):
|
||||||
|
if parent_doctype == "Sales Order":
|
||||||
|
return set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_row)
|
||||||
|
if parent_doctype == "Purchase Order":
|
||||||
|
return set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_row)
|
||||||
|
|
||||||
|
def validate_quantity(child_item, d):
|
||||||
|
if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty):
|
||||||
|
frappe.throw(_("Cannot set quantity less than delivered quantity"))
|
||||||
|
|
||||||
|
if parent_doctype == "Purchase Order" and flt(d.get("qty")) < flt(child_item.received_qty):
|
||||||
|
frappe.throw(_("Cannot set quantity less than received quantity"))
|
||||||
|
|
||||||
data = json.loads(trans_items)
|
data = json.loads(trans_items)
|
||||||
|
|
||||||
sales_doctypes = ['Sales Order', 'Sales Invoice', 'Delivery Note', 'Quotation']
|
sales_doctypes = ['Sales Order', 'Sales Invoice', 'Delivery Note', 'Quotation']
|
||||||
@ -1201,20 +1222,29 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
new_child_flag = False
|
new_child_flag = False
|
||||||
if not d.get("docname"):
|
if not d.get("docname"):
|
||||||
new_child_flag = True
|
new_child_flag = True
|
||||||
if parent_doctype == "Sales Order":
|
check_permissions(parent, 'create')
|
||||||
child_item = set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
|
child_item = get_new_child_item(d)
|
||||||
if parent_doctype == "Purchase Order":
|
|
||||||
child_item = set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
|
|
||||||
else:
|
else:
|
||||||
|
check_permissions(parent, 'write')
|
||||||
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
||||||
if flt(child_item.get("rate")) == flt(d.get("rate")) and flt(child_item.get("qty")) == flt(d.get("qty")):
|
|
||||||
|
prev_rate, new_rate = flt(child_item.get("rate")), flt(d.get("rate"))
|
||||||
|
prev_qty, new_qty = flt(child_item.get("qty")), flt(d.get("qty"))
|
||||||
|
prev_con_fac, new_con_fac = flt(child_item.get("conversion_factor")), flt(d.get("conversion_factor"))
|
||||||
|
|
||||||
|
if parent_doctype == 'Sales Order':
|
||||||
|
prev_date, new_date = child_item.get("delivery_date"), d.get("delivery_date")
|
||||||
|
elif parent_doctype == 'Purchase Order':
|
||||||
|
prev_date, new_date = child_item.get("schedule_date"), d.get("schedule_date")
|
||||||
|
|
||||||
|
rate_unchanged = prev_rate == new_rate
|
||||||
|
qty_unchanged = prev_qty == new_qty
|
||||||
|
conversion_factor_unchanged = prev_con_fac == new_con_fac
|
||||||
|
date_unchanged = prev_date == new_date if prev_date and new_date else False # in case of delivery note etc
|
||||||
|
if rate_unchanged and qty_unchanged and conversion_factor_unchanged and date_unchanged:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty):
|
validate_quantity(child_item, d)
|
||||||
frappe.throw(_("Cannot set quantity less than delivered quantity"))
|
|
||||||
|
|
||||||
if parent_doctype == "Purchase Order" and flt(d.get("qty")) < flt(child_item.received_qty):
|
|
||||||
frappe.throw(_("Cannot set quantity less than received quantity"))
|
|
||||||
|
|
||||||
child_item.qty = flt(d.get("qty"))
|
child_item.qty = flt(d.get("qty"))
|
||||||
precision = child_item.precision("rate") or 2
|
precision = child_item.precision("rate") or 2
|
||||||
@ -1225,6 +1255,18 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
else:
|
else:
|
||||||
child_item.rate = flt(d.get("rate"))
|
child_item.rate = flt(d.get("rate"))
|
||||||
|
|
||||||
|
if d.get("conversion_factor"):
|
||||||
|
if child_item.stock_uom == child_item.uom:
|
||||||
|
child_item.conversion_factor = 1
|
||||||
|
else:
|
||||||
|
child_item.conversion_factor = flt(d.get('conversion_factor'))
|
||||||
|
|
||||||
|
if d.get("delivery_date") and parent_doctype == 'Sales Order':
|
||||||
|
child_item.delivery_date = d.get('delivery_date')
|
||||||
|
|
||||||
|
if d.get("schedule_date") and parent_doctype == 'Purchase Order':
|
||||||
|
child_item.schedule_date = d.get('schedule_date')
|
||||||
|
|
||||||
if flt(child_item.price_list_rate):
|
if flt(child_item.price_list_rate):
|
||||||
if flt(child_item.rate) > flt(child_item.price_list_rate):
|
if flt(child_item.rate) > flt(child_item.price_list_rate):
|
||||||
# if rate is greater than price_list_rate, set margin
|
# if rate is greater than price_list_rate, set margin
|
||||||
@ -1260,6 +1302,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
parent.set_qty_as_per_stock_uom()
|
parent.set_qty_as_per_stock_uom()
|
||||||
parent.calculate_taxes_and_totals()
|
parent.calculate_taxes_and_totals()
|
||||||
if parent_doctype == "Sales Order":
|
if parent_doctype == "Sales Order":
|
||||||
|
make_packing_list(parent)
|
||||||
parent.set_gross_profit()
|
parent.set_gross_profit()
|
||||||
frappe.get_doc('Authorization Control').validate_approving_authority(parent.doctype,
|
frappe.get_doc('Authorization Control').validate_approving_authority(parent.doctype,
|
||||||
parent.company, parent.base_grand_total)
|
parent.company, parent.base_grand_total)
|
||||||
|
@ -349,7 +349,7 @@ class BuyingController(StockController):
|
|||||||
})
|
})
|
||||||
|
|
||||||
if not rm.rate:
|
if not rm.rate:
|
||||||
rm.rate = get_valuation_rate(raw_material_data.item_code, self.supplier_warehouse,
|
rm.rate = get_valuation_rate(raw_material_data.rm_item_code, self.supplier_warehouse,
|
||||||
self.doctype, self.name, currency=self.company_currency, company=self.company)
|
self.doctype, self.name, currency=self.company_currency, company=self.company)
|
||||||
|
|
||||||
rm.amount = qty * flt(rm.rate)
|
rm.amount = qty * flt(rm.rate)
|
||||||
|
@ -70,7 +70,7 @@ def validate_item_variant_attributes(item, args=None):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
attributes_list = attribute_values.get(attribute.lower(), [])
|
attributes_list = attribute_values.get(attribute.lower(), [])
|
||||||
validate_item_attribute_value(attributes_list, attribute, value, item.name)
|
validate_item_attribute_value(attributes_list, attribute, value, item.name, from_variant=True)
|
||||||
|
|
||||||
def validate_is_incremental(numeric_attribute, attribute, value, item):
|
def validate_is_incremental(numeric_attribute, attribute, value, item):
|
||||||
from_range = numeric_attribute.from_range
|
from_range = numeric_attribute.from_range
|
||||||
@ -93,13 +93,20 @@ def validate_is_incremental(numeric_attribute, attribute, value, item):
|
|||||||
.format(attribute, from_range, to_range, increment, item),
|
.format(attribute, from_range, to_range, increment, item),
|
||||||
InvalidItemAttributeValueError, title=_('Invalid Attribute'))
|
InvalidItemAttributeValueError, title=_('Invalid Attribute'))
|
||||||
|
|
||||||
def validate_item_attribute_value(attributes_list, attribute, attribute_value, item):
|
def validate_item_attribute_value(attributes_list, attribute, attribute_value, item, from_variant=True):
|
||||||
allow_rename_attribute_value = frappe.db.get_single_value('Item Variant Settings', 'allow_rename_attribute_value')
|
allow_rename_attribute_value = frappe.db.get_single_value('Item Variant Settings', 'allow_rename_attribute_value')
|
||||||
if allow_rename_attribute_value:
|
if allow_rename_attribute_value:
|
||||||
pass
|
pass
|
||||||
elif attribute_value not in attributes_list:
|
elif attribute_value not in attributes_list:
|
||||||
frappe.throw(_("The value {0} is already assigned to an exisiting Item {2}.").format(
|
if from_variant:
|
||||||
attribute_value, attribute, item), InvalidItemAttributeValueError, title=_('Rename Not Allowed'))
|
frappe.throw(_("{0} is not a valid Value for Attribute {1} of Item {2}.").format(
|
||||||
|
frappe.bold(attribute_value), frappe.bold(attribute), frappe.bold(item)), InvalidItemAttributeValueError, title=_("Invalid Value"))
|
||||||
|
else:
|
||||||
|
msg = _("The value {0} is already assigned to an existing Item {1}.").format(
|
||||||
|
frappe.bold(attribute_value), frappe.bold(item))
|
||||||
|
msg += "<br>" + _("To still proceed with editing this Attribute Value, enable {0} in Item Variant Settings.").format(frappe.bold("Allow Rename Attribute Value"))
|
||||||
|
|
||||||
|
frappe.throw(msg, InvalidItemAttributeValueError, title=_('Edit Not Allowed'))
|
||||||
|
|
||||||
def get_attribute_values(item):
|
def get_attribute_values(item):
|
||||||
if not frappe.flags.attribute_values:
|
if not frappe.flags.attribute_values:
|
||||||
|
@ -361,7 +361,7 @@ class SellingController(StockController):
|
|||||||
self.po_no = ', '.join(list(set([d.po_no for d in po_nos if d.po_no])))
|
self.po_no = ', '.join(list(set([d.po_no for d in po_nos if d.po_no])))
|
||||||
|
|
||||||
def set_gross_profit(self):
|
def set_gross_profit(self):
|
||||||
if self.doctype == "Sales Order":
|
if self.doctype in ["Sales Order", "Quotation"]:
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
item.gross_profit = flt(((item.base_rate - item.valuation_rate) * item.stock_qty), self.precision("amount", item))
|
item.gross_profit = flt(((item.base_rate - item.valuation_rate) * item.stock_qty), self.precision("amount", item))
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@ class QualityInspectionNotSubmittedError(frappe.ValidationError): pass
|
|||||||
class StockController(AccountsController):
|
class StockController(AccountsController):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
super(StockController, self).validate()
|
super(StockController, self).validate()
|
||||||
self.validate_inspection()
|
if not self.get('is_return'):
|
||||||
|
self.validate_inspection()
|
||||||
self.validate_serialized_batch()
|
self.validate_serialized_batch()
|
||||||
self.validate_customer_provided_item()
|
self.validate_customer_provided_item()
|
||||||
|
|
||||||
@ -226,8 +227,8 @@ class StockController(AccountsController):
|
|||||||
|
|
||||||
def check_expense_account(self, item):
|
def check_expense_account(self, item):
|
||||||
if not item.get("expense_account"):
|
if not item.get("expense_account"):
|
||||||
frappe.throw(_("Expense Account not set for Item {0}. Please set an Expense Account for the item in the Items table").format(item.item_code))
|
frappe.throw(_("Row #{0}: Expense Account not set for Item {1}. Please set an Expense Account in the Items table")
|
||||||
|
.format(item.idx, frappe.bold(item.item_code)), title=_("Expense Account Missing"))
|
||||||
else:
|
else:
|
||||||
is_expense_account = frappe.db.get_value("Account",
|
is_expense_account = frappe.db.get_value("Account",
|
||||||
item.get("expense_account"), "report_type")=="Profit and Loss"
|
item.get("expense_account"), "report_type")=="Profit and Loss"
|
||||||
|
@ -155,7 +155,7 @@ def has_website_permission(doc, ptype, user, verbose=False):
|
|||||||
return frappe.db.exists(doctype, get_customer_filter(doc, customers))
|
return frappe.db.exists(doctype, get_customer_filter(doc, customers))
|
||||||
elif suppliers:
|
elif suppliers:
|
||||||
fieldname = 'suppliers' if doctype == 'Request for Quotation' else 'supplier'
|
fieldname = 'suppliers' if doctype == 'Request for Quotation' else 'supplier'
|
||||||
return frappe.db.exists(doctype, filters={
|
return frappe.db.exists(doctype, {
|
||||||
'name': doc.name,
|
'name': doc.name,
|
||||||
fieldname: ["in", suppliers]
|
fieldname: ["in", suppliers]
|
||||||
})
|
})
|
||||||
|
@ -29,6 +29,9 @@
|
|||||||
"requires_fulfilment",
|
"requires_fulfilment",
|
||||||
"fulfilment_deadline",
|
"fulfilment_deadline",
|
||||||
"fulfilment_terms",
|
"fulfilment_terms",
|
||||||
|
"authorised_by_section",
|
||||||
|
"signee_company",
|
||||||
|
"signed_by_company",
|
||||||
"sb_references",
|
"sb_references",
|
||||||
"document_type",
|
"document_type",
|
||||||
"cb_links",
|
"cb_links",
|
||||||
@ -223,10 +226,28 @@
|
|||||||
"options": "Contract",
|
"options": "Contract",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "signee_company",
|
||||||
|
"fieldtype": "Signature",
|
||||||
|
"label": "Signee (Company)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "signed_by_company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Signed By (Company)",
|
||||||
|
"options": "User",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "authorised_by_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Authorised By"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-09-30 00:56:41.559681",
|
"links": [],
|
||||||
|
"modified": "2020-03-30 06:56:07.257932",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Contract",
|
"name": "Contract",
|
||||||
|
@ -29,6 +29,9 @@ class Contract(Document):
|
|||||||
self.update_contract_status()
|
self.update_contract_status()
|
||||||
self.update_fulfilment_status()
|
self.update_fulfilment_status()
|
||||||
|
|
||||||
|
def before_submit(self):
|
||||||
|
self.signed_by_company = frappe.session.user
|
||||||
|
|
||||||
def before_update_after_submit(self):
|
def before_update_after_submit(self):
|
||||||
self.update_contract_status()
|
self.update_contract_status()
|
||||||
self.update_fulfilment_status()
|
self.update_fulfilment_status()
|
||||||
|
@ -1,306 +1,106 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"allow_rename": 1,
|
||||||
"allow_import": 0,
|
"autoname": "field:title",
|
||||||
"allow_rename": 0,
|
"creation": "2018-04-16 06:44:48.791312",
|
||||||
"autoname": "field:title",
|
"doctype": "DocType",
|
||||||
"beta": 0,
|
"editable_grid": 1,
|
||||||
"creation": "2018-04-16 06:44:48.791312",
|
"engine": "InnoDB",
|
||||||
"custom": 0,
|
"field_order": [
|
||||||
"docstatus": 0,
|
"title",
|
||||||
"doctype": "DocType",
|
"contract_terms",
|
||||||
"document_type": "",
|
"sb_fulfilment",
|
||||||
"editable_grid": 1,
|
"requires_fulfilment",
|
||||||
"engine": "InnoDB",
|
"fulfilment_terms"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "title",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Data",
|
||||||
"bold": 0,
|
"label": "Title",
|
||||||
"collapsible": 0,
|
"unique": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "title",
|
|
||||||
"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": "Title",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "contract_terms",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Text Editor",
|
||||||
"bold": 0,
|
"label": "Contract Terms and Conditions",
|
||||||
"collapsible": 0,
|
"read_only": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "sb_terms",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "sb_fulfilment",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Section Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "contract_terms",
|
|
||||||
"fieldtype": "Text Editor",
|
|
||||||
"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": "Contract Terms and Conditions",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "0",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "requires_fulfilment",
|
||||||
"bold": 0,
|
"fieldtype": "Check",
|
||||||
"collapsible": 0,
|
"label": "Requires Fulfilment"
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "sb_fulfilment",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"depends_on": "eval:doc.requires_fulfilment==1",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "fulfilment_terms",
|
||||||
"bold": 0,
|
"fieldtype": "Table",
|
||||||
"collapsible": 0,
|
"label": "Fulfilment Terms and Conditions",
|
||||||
"columns": 0,
|
"options": "Contract Template Fulfilment Terms"
|
||||||
"fieldname": "requires_fulfilment",
|
|
||||||
"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": "Requires Fulfilment",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:doc.requires_fulfilment==1",
|
|
||||||
"fieldname": "fulfilment_terms",
|
|
||||||
"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": "Fulfilment Terms and Conditions",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Contract Template Fulfilment Terms",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"links": [],
|
||||||
"hide_heading": 0,
|
"modified": "2020-06-03 00:24:58.179816",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "Administrator",
|
||||||
"idx": 0,
|
"module": "CRM",
|
||||||
"image_view": 0,
|
"name": "Contract Template",
|
||||||
"in_create": 0,
|
"owner": "Administrator",
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-04-17 07:36:05.217599",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "CRM",
|
|
||||||
"name": "Contract Template",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 1,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "System Manager",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "System Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 1,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "Sales Manager",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Sales Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 1,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "Purchase Manager",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Purchase Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 1,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "HR Manager",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "HR Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"sort_field": "modified",
|
||||||
"read_only": 0,
|
"sort_order": "DESC",
|
||||||
"read_only_onload": 0,
|
"track_changes": 1
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
@ -6,6 +6,7 @@
|
|||||||
"creation": "2013-04-10 11:45:37",
|
"creation": "2013-04-10 11:45:37",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "Document",
|
||||||
|
"email_append_to": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"organization_lead",
|
"organization_lead",
|
||||||
@ -448,7 +449,7 @@
|
|||||||
"idx": 5,
|
"idx": 5,
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-05-11 20:27:45.868960",
|
"modified": "2020-06-18 14:39:41.835416",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Lead",
|
"name": "Lead",
|
||||||
@ -508,8 +509,10 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"search_fields": "lead_name,lead_owner,status",
|
"search_fields": "lead_name,lead_owner,status",
|
||||||
|
"sender_field": "email_id",
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"subject_field": "title",
|
||||||
"title_field": "title"
|
"title_field": "title"
|
||||||
}
|
}
|
@ -96,6 +96,7 @@ frappe.ui.form.on("Opportunity", {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
frm.add_custom_button(__("Reopen"), function() {
|
frm.add_custom_button(__("Reopen"), function() {
|
||||||
|
frm.set_value("lost_reasons",[])
|
||||||
frm.set_value("status", "Open");
|
frm.set_value("status", "Open");
|
||||||
frm.save();
|
frm.save();
|
||||||
});
|
});
|
||||||
|
@ -3,11 +3,7 @@ from frappe import _
|
|||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
return {
|
return {
|
||||||
'fieldname': 'prevdoc_docname',
|
'fieldname': 'opportunity',
|
||||||
'non_standard_fieldnames': {
|
|
||||||
'Supplier Quotation': 'opportunity',
|
|
||||||
'Quotation': 'opportunity'
|
|
||||||
},
|
|
||||||
'transactions': [
|
'transactions': [
|
||||||
{
|
{
|
||||||
'items': ['Quotation', 'Supplier Quotation']
|
'items': ['Quotation', 'Supplier Quotation']
|
||||||
|
@ -30,24 +30,32 @@
|
|||||||
"fieldname": "text",
|
"fieldname": "text",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Tweet",
|
"label": "Tweet",
|
||||||
"mandatory_depends_on": "eval:doc.twitter ==1"
|
"mandatory_depends_on": "eval:doc.twitter ==1",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "image",
|
"fieldname": "image",
|
||||||
"fieldtype": "Attach Image",
|
"fieldtype": "Attach Image",
|
||||||
"label": "Image"
|
"label": "Image",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "twitter",
|
"fieldname": "twitter",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Twitter"
|
"label": "Twitter",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "linkedin",
|
"fieldname": "linkedin",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "LinkedIn"
|
"label": "LinkedIn",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
@ -56,13 +64,17 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Social Media Post",
|
"options": "Social Media Post",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.twitter ==1",
|
"depends_on": "eval:doc.twitter ==1",
|
||||||
"fieldname": "content",
|
"fieldname": "content",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Twitter"
|
"label": "Twitter",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
@ -70,7 +82,9 @@
|
|||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Post Status",
|
"label": "Post Status",
|
||||||
"options": "\nScheduled\nPosted\nError",
|
"options": "\nScheduled\nPosted\nError",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
@ -78,7 +92,9 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Twitter Post Id",
|
"label": "Twitter Post Id",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
@ -86,68 +102,89 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "LinkedIn Post Id",
|
"label": "LinkedIn Post Id",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "campaign_name",
|
"fieldname": "campaign_name",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Campaign",
|
"label": "Campaign",
|
||||||
"options": "Campaign"
|
"options": "Campaign",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_6",
|
"fieldname": "column_break_6",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"label": "Share On"
|
"label": "Share On",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_14",
|
"fieldname": "column_break_14",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "tweet_preview",
|
"fieldname": "tweet_preview",
|
||||||
"fieldtype": "HTML"
|
"fieldtype": "HTML",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"depends_on": "eval:doc.linkedin==1",
|
"depends_on": "eval:doc.linkedin==1",
|
||||||
"fieldname": "linkedin_section",
|
"fieldname": "linkedin_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "LinkedIn"
|
"label": "LinkedIn",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "attachments_section",
|
"fieldname": "attachments_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Attachments"
|
"label": "Attachments",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "linkedin_post",
|
"fieldname": "linkedin_post",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Text",
|
||||||
"label": "Post",
|
"label": "Post",
|
||||||
"mandatory_depends_on": "eval:doc.linkedin ==1"
|
"mandatory_depends_on": "eval:doc.linkedin ==1",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_15",
|
"fieldname": "column_break_15",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"fieldname": "scheduled_time",
|
"fieldname": "scheduled_time",
|
||||||
"fieldtype": "Datetime",
|
"fieldtype": "Datetime",
|
||||||
"label": "Scheduled Time",
|
"label": "Scheduled Time",
|
||||||
"read_only_depends_on": "eval:doc.post_status == \"Posted\""
|
"read_only_depends_on": "eval:doc.post_status == \"Posted\"",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-21 15:10:04.953713",
|
"modified": "2020-06-14 10:31:33.961381",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Social Media Post",
|
"name": "Social Media Post",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
@ -157,6 +194,35 @@
|
|||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "System Manager",
|
"role": "System Manager",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cancel": 1,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Sales User",
|
||||||
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cancel": 1,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Sales Manager",
|
||||||
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
def get_data():
|
||||||
|
return {
|
||||||
|
'fieldname': 'assessment_plan',
|
||||||
|
'non_standard_fieldnames': {
|
||||||
|
},
|
||||||
|
'transactions': [
|
||||||
|
{
|
||||||
|
'label': _('Assessment'),
|
||||||
|
'items': ['Assessment Result']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
25
erpnext/education/doctype/course/course_dashboard.py
Normal file
25
erpnext/education/doctype/course/course_dashboard.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
def get_data():
|
||||||
|
return {
|
||||||
|
'fieldname': 'course',
|
||||||
|
'non_standard_fieldnames': {
|
||||||
|
},
|
||||||
|
'transactions': [
|
||||||
|
{
|
||||||
|
'label': _('Course'),
|
||||||
|
'items': ['Course Enrollment', 'Course Schedule']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _('Student'),
|
||||||
|
'items': ['Student Group']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _('Assessment'),
|
||||||
|
'items': ['Assessment Plan']
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2017-07-18 15:21:21.527136",
|
"creation": "2017-07-18 15:21:21.527136",
|
||||||
@ -7,6 +8,7 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"fee_structure",
|
"fee_structure",
|
||||||
|
"posting_date",
|
||||||
"due_date",
|
"due_date",
|
||||||
"naming_series",
|
"naming_series",
|
||||||
"fee_creation_status",
|
"fee_creation_status",
|
||||||
@ -259,10 +261,18 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "dimension_col_break",
|
"fieldname": "dimension_col_break",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "Today",
|
||||||
|
"fieldname": "posting_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"label": "Posting Date",
|
||||||
|
"reqd": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-05-26 09:10:34.522409",
|
"links": [],
|
||||||
|
"modified": "2020-05-15 08:39:20.682837",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Education",
|
"module": "Education",
|
||||||
"name": "Fee Schedule",
|
"name": "Fee Schedule",
|
||||||
|
@ -87,6 +87,7 @@ def generate_fee(fee_schedule):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
fees_doc.posting_date = doc.posting_date
|
||||||
fees_doc.student = student.student
|
fees_doc.student = student.student
|
||||||
fees_doc.student_name = student.student_name
|
fees_doc.student_name = student.student_name
|
||||||
fees_doc.program = student.program
|
fees_doc.program = student.program
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user