mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-23 23:19:20 +00:00
Merge branch 'version-12-hotfix' into import-italian-invoice
This commit is contained in:
@@ -605,10 +605,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)
|
||||||
|
|
||||||
|
|||||||
@@ -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"]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|||||||
@@ -534,7 +534,7 @@ class ReceivablePayableReport(object):
|
|||||||
|
|
||||||
def get_ageing_data(self, entry_date, row):
|
def get_ageing_data(self, entry_date, row):
|
||||||
# [0-30, 30-60, 60-90, 90-120, 120-above]
|
# [0-30, 30-60, 60-90, 90-120, 120-above]
|
||||||
row.range1 = row.range2 = row.range3 = row.range4 = range5 = 0.0
|
row.range1 = row.range2 = row.range3 = row.range4 = row.range5 = 0.0
|
||||||
|
|
||||||
if not (self.age_as_on and entry_date):
|
if not (self.age_as_on and entry_date):
|
||||||
return
|
return
|
||||||
@@ -559,6 +559,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 +582,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"):
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ 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,
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -160,12 +160,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"]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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"]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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]
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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']
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -95,10 +95,10 @@ def create_sales_order(shopify_order, shopify_settings, company=None):
|
|||||||
items = get_order_items(shopify_order.get("line_items"), shopify_settings)
|
items = get_order_items(shopify_order.get("line_items"), shopify_settings)
|
||||||
|
|
||||||
if not items:
|
if not items:
|
||||||
message = 'Following items are exists in order but relevant record not found in Product master'
|
message = 'Following items exists in the shopify order but relevant records were not found in the shopify Product master'
|
||||||
message += "\n" + ", ".join(product_not_exists)
|
message += "\n" + ", ".join(product_not_exists)
|
||||||
|
|
||||||
make_shopify_log(status="Error", exception=e, rollback=True)
|
make_shopify_log(status="Error", exception=message, rollback=True)
|
||||||
|
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|||||||
@@ -182,7 +182,8 @@ def set_items_in_sales_order(new_sales_order, woocommerce_settings, order, sys_l
|
|||||||
company_abbr = frappe.db.get_value('Company', woocommerce_settings.company, 'abbr')
|
company_abbr = frappe.db.get_value('Company', woocommerce_settings.company, 'abbr')
|
||||||
|
|
||||||
default_warehouse = _("Stores - {0}", sys_lang).format(company_abbr)
|
default_warehouse = _("Stores - {0}", sys_lang).format(company_abbr)
|
||||||
if not frappe.db.exists("Warehouse", default_warehouse):
|
if not frappe.db.exists("Warehouse", default_warehouse) \
|
||||||
|
and not woocommerce_settings.warehouse:
|
||||||
frappe.throw(_("Please set Warehouse in Woocommerce Settings"))
|
frappe.throw(_("Please set Warehouse in Woocommerce Settings"))
|
||||||
|
|
||||||
for item in order.get("line_items"):
|
for item in order.get("line_items"):
|
||||||
|
|||||||
@@ -428,14 +428,23 @@ def get_leave_details(employee, date):
|
|||||||
leave_allocation = {}
|
leave_allocation = {}
|
||||||
for d in allocation_records:
|
for d in allocation_records:
|
||||||
allocation = allocation_records.get(d, frappe._dict())
|
allocation = allocation_records.get(d, frappe._dict())
|
||||||
|
|
||||||
|
total_allocated_leaves = frappe.db.get_value('Leave Allocation', {
|
||||||
|
'from_date': ('<=', date),
|
||||||
|
'to_date': ('>=', date),
|
||||||
|
'leave_type': allocation.leave_type,
|
||||||
|
}, 'SUM(total_leaves_allocated)') or 0
|
||||||
|
|
||||||
remaining_leaves = get_leave_balance_on(employee, d, date, to_date = allocation.to_date,
|
remaining_leaves = get_leave_balance_on(employee, d, date, to_date = allocation.to_date,
|
||||||
consider_all_leaves_in_the_allocation_period=True)
|
consider_all_leaves_in_the_allocation_period=True)
|
||||||
|
|
||||||
end_date = allocation.to_date
|
end_date = allocation.to_date
|
||||||
leaves_taken = get_leaves_for_period(employee, d, allocation.from_date, end_date) * -1
|
leaves_taken = get_leaves_for_period(employee, d, allocation.from_date, end_date) * -1
|
||||||
leaves_pending = get_pending_leaves_for_period(employee, d, allocation.from_date, end_date)
|
leaves_pending = get_pending_leaves_for_period(employee, d, allocation.from_date, end_date)
|
||||||
|
|
||||||
leave_allocation[d] = {
|
leave_allocation[d] = {
|
||||||
"total_leaves": allocation.total_leaves_allocated,
|
"total_leaves": total_allocated_leaves,
|
||||||
|
"expired_leaves": total_allocated_leaves - (remaining_leaves + leaves_taken),
|
||||||
"leaves_taken": leaves_taken,
|
"leaves_taken": leaves_taken,
|
||||||
"pending_leaves": leaves_pending,
|
"pending_leaves": leaves_pending,
|
||||||
"remaining_leaves": remaining_leaves}
|
"remaining_leaves": remaining_leaves}
|
||||||
|
|||||||
@@ -4,11 +4,12 @@
|
|||||||
<table class="table table-bordered small">
|
<table class="table table-bordered small">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 20%">{{ __("Leave Type") }}</th>
|
<th style="width: 16%">{{ __("Leave Type") }}</th>
|
||||||
<th style="width: 20%" class="text-right">{{ __("Total Allocated Leaves") }}</th>
|
<th style="width: 16%" class="text-right">{{ __("Total Allocated Leaves") }}</th>
|
||||||
<th style="width: 20%" class="text-right">{{ __("Used Leaves") }}</th>
|
<th style="width: 16%" class="text-right">{{ __("Expired Leaves") }}</th>
|
||||||
<th style="width: 20%" class="text-right">{{ __("Pending Leaves") }}</th>
|
<th style="width: 16%" class="text-right">{{ __("Used Leaves") }}</th>
|
||||||
<th style="width: 20%" class="text-right">{{ __("Available Leaves") }}</th>
|
<th style="width: 16%" class="text-right">{{ __("Pending Leaves") }}</th>
|
||||||
|
<th style="width: 16%" class="text-right">{{ __("Available Leaves") }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</thead>
|
</thead>
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td> {%= key %} </td>
|
<td> {%= key %} </td>
|
||||||
<td class="text-right"> {%= value["total_leaves"] %} </td>
|
<td class="text-right"> {%= value["total_leaves"] %} </td>
|
||||||
|
<td class="text-right"> {%= value["expired_leaves"] %} </td>
|
||||||
<td class="text-right"> {%= value["leaves_taken"] %} </td>
|
<td class="text-right"> {%= value["leaves_taken"] %} </td>
|
||||||
<td class="text-right"> {%= value["pending_leaves"] %} </td>
|
<td class="text-right"> {%= value["pending_leaves"] %} </td>
|
||||||
<td class="text-right"> {%= value["remaining_leaves"] %} </td>
|
<td class="text-right"> {%= value["remaining_leaves"] %} </td>
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ def get_template():
|
|||||||
|
|
||||||
args = frappe.local.form_dict
|
args = frappe.local.form_dict
|
||||||
|
|
||||||
|
if getdate(args.from_date) > getdate(args.to_date):
|
||||||
|
frappe.throw(_("To Date should be greater than From Date"))
|
||||||
|
|
||||||
w = UnicodeWriter()
|
w = UnicodeWriter()
|
||||||
w = add_header(w)
|
w = add_header(w)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +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
|
from frappe.utils import flt, add_days
|
||||||
from erpnext.hr.doctype.leave_application.leave_application \
|
from erpnext.hr.doctype.leave_application.leave_application \
|
||||||
import get_leave_balance_on, get_leaves_for_period
|
import get_leave_balance_on, get_leaves_for_period
|
||||||
|
|
||||||
@@ -26,8 +26,8 @@ def get_columns(leave_types):
|
|||||||
for leave_type in leave_types:
|
for leave_type in leave_types:
|
||||||
columns.append(_(leave_type) + " " + _("Opening") + ":Float:160")
|
columns.append(_(leave_type) + " " + _("Opening") + ":Float:160")
|
||||||
columns.append(_(leave_type) + " " + _("Allocated") + ":Float:160")
|
columns.append(_(leave_type) + " " + _("Allocated") + ":Float:160")
|
||||||
columns.append(_(leave_type) + " " + _("Expired") + ":Float:160")
|
|
||||||
columns.append(_(leave_type) + " " + _("Taken") + ":Float:160")
|
columns.append(_(leave_type) + " " + _("Taken") + ":Float:160")
|
||||||
|
columns.append(_(leave_type) + " " + _("Expired") + ":Float:160")
|
||||||
columns.append(_(leave_type) + " " + _("Balance") + ":Float:160")
|
columns.append(_(leave_type) + " " + _("Balance") + ":Float:160")
|
||||||
|
|
||||||
return columns
|
return columns
|
||||||
@@ -84,7 +84,7 @@ def calculate_leaves_details(filters, leave_type, employee):
|
|||||||
# removing expired leaves
|
# removing expired leaves
|
||||||
leaves_taken = leaves_deducted - remove_expired_leave(ledger_entries)
|
leaves_taken = leaves_deducted - remove_expired_leave(ledger_entries)
|
||||||
|
|
||||||
opening = get_leave_balance_on(employee.name, leave_type, filters.from_date)
|
opening = get_leave_balance_on(employee.name, leave_type, add_days(filters.from_date, -1))
|
||||||
|
|
||||||
new_allocation , expired_allocation = get_allocated_and_expired_leaves(ledger_entries, filters.from_date, filters.to_date)
|
new_allocation , expired_allocation = get_allocated_and_expired_leaves(ledger_entries, filters.from_date, filters.to_date)
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ def calculate_leaves_details(filters, leave_type, employee):
|
|||||||
#Formula for calculating closing balance
|
#Formula for calculating closing balance
|
||||||
closing = max(opening + new_allocation - (leaves_taken + expired_leaves), 0)
|
closing = max(opening + new_allocation - (leaves_taken + expired_leaves), 0)
|
||||||
|
|
||||||
return [opening, new_allocation, expired_leaves, leaves_taken, closing]
|
return [opening, new_allocation, leaves_taken, expired_leaves, closing]
|
||||||
|
|
||||||
|
|
||||||
def remove_expired_leave(records):
|
def remove_expired_leave(records):
|
||||||
@@ -113,7 +113,7 @@ def get_allocated_and_expired_leaves(records, from_date, to_date):
|
|||||||
expired_leaves = 0
|
expired_leaves = 0
|
||||||
|
|
||||||
for record in records:
|
for record in records:
|
||||||
if record.to_date <= getdate(to_date) and record.leaves>0:
|
if record.to_date < getdate(to_date) and record.leaves>0:
|
||||||
expired_leaves += record.leaves
|
expired_leaves += record.leaves
|
||||||
|
|
||||||
if record.from_date >= getdate(from_date) and record.leaves>0:
|
if record.from_date >= getdate(from_date) and record.leaves>0:
|
||||||
|
|||||||
@@ -45,16 +45,16 @@ def get_columns():
|
|||||||
'fieldtype': 'Float',
|
'fieldtype': 'Float',
|
||||||
'fieldname': 'new_allocation',
|
'fieldname': 'new_allocation',
|
||||||
'width': 120,
|
'width': 120,
|
||||||
}, {
|
|
||||||
'label': _('Expired Leaves'),
|
|
||||||
'fieldtype': 'Float',
|
|
||||||
'fieldname': 'expired_leaves',
|
|
||||||
'width': 120,
|
|
||||||
}, {
|
}, {
|
||||||
'label': _('Leaves Taken'),
|
'label': _('Leaves Taken'),
|
||||||
'fieldtype': 'float',
|
'fieldtype': 'float',
|
||||||
'fieldname': 'leaves_taken',
|
'fieldname': 'leaves_taken',
|
||||||
'width': 120,
|
'width': 120,
|
||||||
|
}, {
|
||||||
|
'label': _('Expired Leaves'),
|
||||||
|
'fieldtype': 'Float',
|
||||||
|
'fieldname': 'expired_leaves',
|
||||||
|
'width': 120,
|
||||||
}, {
|
}, {
|
||||||
'label': _('Closing Balance'),
|
'label': _('Closing Balance'),
|
||||||
'fieldtype': 'float',
|
'fieldtype': 'float',
|
||||||
@@ -96,8 +96,8 @@ def get_data(filters):
|
|||||||
leave_details = calculate_leaves_details(filters, leave_type, employee)
|
leave_details = calculate_leaves_details(filters, leave_type, employee)
|
||||||
row.opening_balance = flt(leave_details[0])
|
row.opening_balance = flt(leave_details[0])
|
||||||
row.new_allocation = flt(leave_details[1])
|
row.new_allocation = flt(leave_details[1])
|
||||||
row.expired_leaves = flt(leave_details[2])
|
row.leaves_taken = flt(leave_details[2])
|
||||||
row.leaves_taken = flt(leave_details[3])
|
row.expired_leaves = flt(leave_details[3])
|
||||||
row.closing_balance = flt(leave_details[4])
|
row.closing_balance = flt(leave_details[4])
|
||||||
|
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
|||||||
@@ -667,4 +667,5 @@ execute:frappe.delete_doc_if_exists("Page", "appointment-analytic")
|
|||||||
erpnext.patches.v12_0.unset_customer_supplier_based_on_type_of_item_price
|
erpnext.patches.v12_0.unset_customer_supplier_based_on_type_of_item_price
|
||||||
erpnext.patches.v12_0.set_serial_no_status #2020-05-21
|
erpnext.patches.v12_0.set_serial_no_status #2020-05-21
|
||||||
erpnext.patches.v12_0.update_price_list_currency_in_bom
|
erpnext.patches.v12_0.update_price_list_currency_in_bom
|
||||||
|
erpnext.patches.v12_0.update_uom_conversion_factor
|
||||||
erpnext.patches.v12_0.set_italian_import_supplier_invoice_permissions
|
erpnext.patches.v12_0.set_italian_import_supplier_invoice_permissions
|
||||||
11
erpnext/patches/v12_0/update_uom_conversion_factor.py
Normal file
11
erpnext/patches/v12_0/update_uom_conversion_factor.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe, json
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
from erpnext.setup.setup_wizard.operations.install_fixtures import add_uom_data
|
||||||
|
|
||||||
|
frappe.reload_doc("setup", "doctype", "UOM Conversion Factor")
|
||||||
|
frappe.reload_doc("setup", "doctype", "UOM")
|
||||||
|
frappe.reload_doc("stock", "doctype", "UOM Category")
|
||||||
|
|
||||||
|
add_uom_data()
|
||||||
@@ -62,7 +62,7 @@ erpnext.financial_statements = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function get_filters(){
|
function get_filters() {
|
||||||
let filters = [
|
let filters = [
|
||||||
{
|
{
|
||||||
"fieldname":"company",
|
"fieldname":"company",
|
||||||
@@ -129,15 +129,6 @@ function get_filters(){
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
erpnext.dimension_filters.forEach((dimension) => {
|
|
||||||
filters.push({
|
|
||||||
"fieldname": dimension["fieldname"],
|
|
||||||
"label": __(dimension["label"]),
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": dimension["document_type"]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -191,6 +191,23 @@ $.extend(erpnext.utils, {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
add_dimensions: function(report_name, index) {
|
||||||
|
let filters = frappe.query_reports[report_name].filters;
|
||||||
|
|
||||||
|
erpnext.dimension_filters.forEach((dimension) => {
|
||||||
|
let found = filters.some(el => el.fieldname === dimension['fieldname']);
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
filters.splice(index, 0 ,{
|
||||||
|
"fieldname": dimension["fieldname"],
|
||||||
|
"label": __(dimension["label"]),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": dimension["document_type"]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
make_subscription: function(doctype, docname) {
|
make_subscription: function(doctype, docname) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "frappe.automation.doctype.auto_repeat.auto_repeat.make_auto_repeat",
|
method: "frappe.automation.doctype.auto_repeat.auto_repeat.make_auto_repeat",
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from erpnext.controllers.taxes_and_totals import get_itemised_tax
|
from erpnext.controllers.taxes_and_totals import get_itemised_tax
|
||||||
|
from six import iteritems
|
||||||
|
|
||||||
def update_itemised_tax_data(doc):
|
def update_itemised_tax_data(doc):
|
||||||
if not doc.taxes: return
|
if not doc.taxes: return
|
||||||
@@ -9,7 +11,14 @@ def update_itemised_tax_data(doc):
|
|||||||
|
|
||||||
for row in doc.items:
|
for row in doc.items:
|
||||||
tax_rate = 0.0
|
tax_rate = 0.0
|
||||||
if itemised_tax.get(row.item_code):
|
item_tax_rate = frappe.parse_json(row.item_tax_rate)
|
||||||
|
|
||||||
|
# First check if tax rate is present
|
||||||
|
# If not then look up in item_wise_tax_detail
|
||||||
|
if item_tax_rate:
|
||||||
|
for account, rate in iteritems(item_tax_rate):
|
||||||
|
tax_rate += rate
|
||||||
|
elif itemised_tax.get(row.item_code):
|
||||||
tax_rate = sum([tax.get('tax_rate', 0) for d, tax in itemised_tax.get(row.item_code).items()])
|
tax_rate = sum([tax.get('tax_rate', 0) for d, tax in itemised_tax.get(row.item_code).items()])
|
||||||
|
|
||||||
row.tax_rate = flt(tax_rate, row.precision("tax_rate"))
|
row.tax_rate = flt(tax_rate, row.precision("tax_rate"))
|
||||||
|
|||||||
@@ -1571,5 +1571,19 @@
|
|||||||
"to_uom": "Parts Per Million",
|
"to_uom": "Parts Per Million",
|
||||||
"abbr": "ppm",
|
"abbr": "ppm",
|
||||||
"value": "10000"
|
"value": "10000"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "Mass",
|
||||||
|
"from_uom": "Pound",
|
||||||
|
"to_uom": "Ounce",
|
||||||
|
"abbr": "oz",
|
||||||
|
"value": "16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "Mass",
|
||||||
|
"from_uom": "Gram",
|
||||||
|
"to_uom": "Ounce",
|
||||||
|
"abbr": "oz",
|
||||||
|
"value": "0.035274"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -335,13 +335,14 @@ def add_uom_data():
|
|||||||
"category_name": _(d.get("category"))
|
"category_name": _(d.get("category"))
|
||||||
}).insert(ignore_permissions=True)
|
}).insert(ignore_permissions=True)
|
||||||
|
|
||||||
uom_conversion = frappe.get_doc({
|
if not frappe.db.exists("UOM Conversion Factor", {"from_uom": _(d.get("from_uom")), "to_uom": _(d.get("to_uom"))}):
|
||||||
"doctype": "UOM Conversion Factor",
|
uom_conversion = frappe.get_doc({
|
||||||
"category": _(d.get("category")),
|
"doctype": "UOM Conversion Factor",
|
||||||
"from_uom": _(d.get("from_uom")),
|
"category": _(d.get("category")),
|
||||||
"to_uom": _(d.get("to_uom")),
|
"from_uom": _(d.get("from_uom")),
|
||||||
"value": d.get("value")
|
"to_uom": _(d.get("to_uom")),
|
||||||
}).insert(ignore_permissions=True)
|
"value": d.get("value")
|
||||||
|
}).insert(ignore_permissions=True)
|
||||||
|
|
||||||
def add_market_segments():
|
def add_market_segments():
|
||||||
records = [
|
records = [
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ def apply_cart_settings(party=None, quotation=None):
|
|||||||
def set_price_list_and_rate(quotation, cart_settings):
|
def set_price_list_and_rate(quotation, cart_settings):
|
||||||
"""set price list based on billing territory"""
|
"""set price list based on billing territory"""
|
||||||
|
|
||||||
_set_price_list(quotation, cart_settings)
|
_set_price_list(cart_settings, quotation)
|
||||||
|
|
||||||
# reset values
|
# reset values
|
||||||
quotation.price_list_currency = quotation.currency = \
|
quotation.price_list_currency = quotation.currency = \
|
||||||
@@ -334,23 +334,28 @@ def set_price_list_and_rate(quotation, cart_settings):
|
|||||||
# set it in cookies for using in product page
|
# set it in cookies for using in product page
|
||||||
frappe.local.cookie_manager.set_cookie("selling_price_list", quotation.selling_price_list)
|
frappe.local.cookie_manager.set_cookie("selling_price_list", quotation.selling_price_list)
|
||||||
|
|
||||||
def _set_price_list(quotation, cart_settings):
|
def _set_price_list(cart_settings, quotation=None):
|
||||||
"""Set price list based on customer or shopping cart default"""
|
"""Set price list based on customer or shopping cart default"""
|
||||||
from erpnext.accounts.party import get_default_price_list
|
from erpnext.accounts.party import get_default_price_list
|
||||||
|
|
||||||
# check if customer price list exists
|
# check if customer price list exists
|
||||||
selling_price_list = None
|
selling_price_list = None
|
||||||
if quotation.party_name:
|
if quotation and quotation.get("party_name"):
|
||||||
selling_price_list = frappe.db.get_value('Customer', quotation.party_name, 'default_price_list')
|
selling_price_list = frappe.db.get_value('Customer', quotation.get("party_name"), 'default_price_list')
|
||||||
|
|
||||||
# else check for territory based price list
|
# else check for territory based price list
|
||||||
if not selling_price_list:
|
if not selling_price_list:
|
||||||
selling_price_list = cart_settings.price_list
|
selling_price_list = cart_settings.price_list
|
||||||
|
|
||||||
if not selling_price_list and quotation.party_name:
|
party_name = quotation.get("party_name") if quotation else get_party().get("name")
|
||||||
selling_price_list = get_default_price_list(frappe.get_doc("Customer", quotation.party_name))
|
|
||||||
|
|
||||||
quotation.selling_price_list = selling_price_list
|
if not selling_price_list and party_name:
|
||||||
|
selling_price_list = get_default_price_list(frappe.get_doc("Customer", party_name))
|
||||||
|
|
||||||
|
if quotation:
|
||||||
|
quotation.selling_price_list = selling_price_list
|
||||||
|
|
||||||
|
return selling_price_list
|
||||||
|
|
||||||
def set_taxes(quotation, cart_settings):
|
def set_taxes(quotation, cart_settings):
|
||||||
"""set taxes based on billing territory"""
|
"""set taxes based on billing territory"""
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from erpnext.shopping_cart.cart import _get_cart_quotation
|
from erpnext.shopping_cart.cart import _get_cart_quotation, _set_price_list
|
||||||
from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings \
|
from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings \
|
||||||
import get_shopping_cart_settings, show_quantity_in_website
|
import get_shopping_cart_settings, show_quantity_in_website
|
||||||
from erpnext.utilities.product import get_price, get_qty_in_stock, get_non_stock_item_status
|
from erpnext.utilities.product import get_price, get_qty_in_stock, get_non_stock_item_status
|
||||||
@@ -21,9 +21,11 @@ def get_product_info_for_website(item_code, skip_quotation_creation=False):
|
|||||||
if not skip_quotation_creation:
|
if not skip_quotation_creation:
|
||||||
cart_quotation = _get_cart_quotation()
|
cart_quotation = _get_cart_quotation()
|
||||||
|
|
||||||
|
selling_price_list = cart_quotation.get("selling_price_list") if cart_quotation else _set_price_list(cart_settings, None)
|
||||||
|
|
||||||
price = get_price(
|
price = get_price(
|
||||||
item_code,
|
item_code,
|
||||||
cart_quotation.selling_price_list,
|
selling_price_list,
|
||||||
cart_settings.default_customer_group,
|
cart_settings.default_customer_group,
|
||||||
cart_settings.company
|
cart_settings.company
|
||||||
)
|
)
|
||||||
@@ -42,7 +44,7 @@ def get_product_info_for_website(item_code, skip_quotation_creation=False):
|
|||||||
|
|
||||||
if product_info["price"]:
|
if product_info["price"]:
|
||||||
if frappe.session.user != "Guest":
|
if frappe.session.user != "Guest":
|
||||||
item = cart_quotation.get({"item_code": item_code})
|
item = cart_quotation.get({"item_code": item_code}) if cart_quotation else None
|
||||||
if item:
|
if item:
|
||||||
product_info["qty"] = item[0].qty
|
product_info["qty"] = item[0].qty
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,16 @@ frappe.ui.form.on('Pick List', {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
frm.set_query('item_code', 'locations', () => {
|
frm.set_query('item_code', 'locations', () => {
|
||||||
|
return erpnext.queries.item({ "is_stock_item": 1 });
|
||||||
|
});
|
||||||
|
frm.set_query('batch_no', 'locations', (frm, cdt, cdn) => {
|
||||||
|
const row = locals[cdt][cdn];
|
||||||
return {
|
return {
|
||||||
|
query: 'erpnext.controllers.queries.get_batch_no',
|
||||||
filters: {
|
filters: {
|
||||||
is_stock_item: 1
|
item_code: row.item_code,
|
||||||
}
|
warehouse: row.warehouse
|
||||||
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ class PickList(Document):
|
|||||||
for item in self.locations:
|
for item in self.locations:
|
||||||
if not frappe.get_cached_value('Item', item.item_code, 'has_serial_no'):
|
if not frappe.get_cached_value('Item', item.item_code, 'has_serial_no'):
|
||||||
continue
|
continue
|
||||||
|
if not item.serial_no:
|
||||||
|
frappe.throw(_("Row #{0}: {1} does not have any available serial numbers in {2}".format(
|
||||||
|
frappe.bold(item.idx), frappe.bold(item.item_code), frappe.bold(item.warehouse))))
|
||||||
if len(item.serial_no.split('\n')) == item.picked_qty:
|
if len(item.serial_no.split('\n')) == item.picked_qty:
|
||||||
continue
|
continue
|
||||||
frappe.throw(_('For item {0} at row {1}, count of serial numbers does not match with the picked quantity')
|
frappe.throw(_('For item {0} at row {1}, count of serial numbers does not match with the picked quantity')
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ def get_child_warehouses(warehouse):
|
|||||||
lft, rgt = frappe.get_cached_value("Warehouse", warehouse, ["lft", "rgt"])
|
lft, rgt = frappe.get_cached_value("Warehouse", warehouse, ["lft", "rgt"])
|
||||||
|
|
||||||
return frappe.db.sql_list("""select name from `tabWarehouse`
|
return frappe.db.sql_list("""select name from `tabWarehouse`
|
||||||
where lft >= %s and rgt =< %s""", (lft, rgt))
|
where lft >= %s and rgt <= %s""", (lft, rgt))
|
||||||
|
|
||||||
def get_warehouses_based_on_account(account, company=None):
|
def get_warehouses_based_on_account(account, company=None):
|
||||||
warehouses = []
|
warehouses = []
|
||||||
|
|||||||
Reference in New Issue
Block a user