Merge branch 'develop' into jam_enterprise_emp_benefit
This commit is contained in:
commit
8c6b7557db
@ -115,7 +115,6 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
|||||||
}
|
}
|
||||||
this.frm.toggle_reqd("supplier_warehouse", this.frm.doc.is_subcontracted==="Yes");
|
this.frm.toggle_reqd("supplier_warehouse", this.frm.doc.is_subcontracted==="Yes");
|
||||||
|
|
||||||
var me = this;
|
|
||||||
if (doc.docstatus == 1 && !doc.inter_company_invoice_reference) {
|
if (doc.docstatus == 1 && !doc.inter_company_invoice_reference) {
|
||||||
frappe.model.with_doc("Supplier", me.frm.doc.supplier, function() {
|
frappe.model.with_doc("Supplier", me.frm.doc.supplier, function() {
|
||||||
var supplier = frappe.model.get_doc("Supplier", me.frm.doc.supplier);
|
var supplier = frappe.model.get_doc("Supplier", me.frm.doc.supplier);
|
||||||
|
|||||||
@ -81,7 +81,6 @@ class PurchaseInvoice(BuyingController):
|
|||||||
self.validate_write_off_account()
|
self.validate_write_off_account()
|
||||||
self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount", "items")
|
self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount", "items")
|
||||||
self.validate_fixed_asset()
|
self.validate_fixed_asset()
|
||||||
self.validate_fixed_asset_account()
|
|
||||||
self.create_remarks()
|
self.create_remarks()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
validate_inter_company_party(self.doctype, self.supplier, self.company, self.inter_company_invoice_reference)
|
validate_inter_company_party(self.doctype, self.supplier, self.company, self.inter_company_invoice_reference)
|
||||||
@ -176,7 +175,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
if self.update_stock:
|
if self.update_stock:
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
if not d.warehouse:
|
if not d.warehouse:
|
||||||
frappe.throw(_("Warehouse required at Row No {0}").format(d.idx))
|
frappe.throw(_("Warehouse required at Row No {0}, please set default warehouse for the item {1} for the company {2}").
|
||||||
|
format(d.idx, d.item_code, self.company))
|
||||||
|
|
||||||
super(PurchaseInvoice, self).validate_warehouse()
|
super(PurchaseInvoice, self).validate_warehouse()
|
||||||
|
|
||||||
@ -390,10 +390,10 @@ class PurchaseInvoice(BuyingController):
|
|||||||
warehouse_account = get_warehouse_account_map()
|
warehouse_account = get_warehouse_account_map()
|
||||||
|
|
||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
if flt(item.base_net_amount) and item.item_code in stock_items:
|
if flt(item.base_net_amount):
|
||||||
account_currency = get_account_currency(item.expense_account)
|
account_currency = get_account_currency(item.expense_account)
|
||||||
|
|
||||||
if self.update_stock and self.auto_accounting_for_stock:
|
if self.update_stock and self.auto_accounting_for_stock and item.item_code in stock_items:
|
||||||
val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
|
val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
|
||||||
|
|
||||||
# warehouse account
|
# warehouse account
|
||||||
@ -435,7 +435,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
|
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
|
||||||
"credit": flt(item.rm_supp_cost)
|
"credit": flt(item.rm_supp_cost)
|
||||||
}, warehouse_account[self.supplier_warehouse]["account_currency"]))
|
}, warehouse_account[self.supplier_warehouse]["account_currency"]))
|
||||||
else:
|
elif not item.is_fixed_asset:
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": item.expense_account,
|
"account": item.expense_account,
|
||||||
@ -478,11 +478,17 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
asset_amount = flt(item.net_amount) + flt(item.item_tax_amount/self.conversion_rate)
|
asset_amount = flt(item.net_amount) + flt(item.item_tax_amount/self.conversion_rate)
|
||||||
base_asset_amount = flt(item.base_net_amount + item.item_tax_amount)
|
base_asset_amount = flt(item.base_net_amount + item.item_tax_amount)
|
||||||
|
item.expense_account = item.expense_account or asset_accounts[0]
|
||||||
|
|
||||||
|
if (not item.expense_account or frappe.db.get_value('Account',
|
||||||
|
item.expense_account, 'account_type') != 'Asset Received But Not Billed'):
|
||||||
|
frappe.throw(_("Row {0}: Expense account must be of type Asset Received But Not Billed").
|
||||||
|
format(item.idx))
|
||||||
|
|
||||||
if not self.update_stock:
|
if not self.update_stock:
|
||||||
asset_rbnb_currency = get_account_currency(asset_accounts[0])
|
asset_rbnb_currency = get_account_currency(item.expense_account)
|
||||||
gl_entries.append(self.get_gl_dict({
|
gl_entries.append(self.get_gl_dict({
|
||||||
"account": asset_accounts[0],
|
"account": item.expense_account,
|
||||||
"against": self.supplier,
|
"against": self.supplier,
|
||||||
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
|
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
|
||||||
"debit": base_asset_amount,
|
"debit": base_asset_amount,
|
||||||
@ -517,7 +523,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
if item.item_tax_amount and not cint(erpnext.is_perpetual_inventory_enabled(self.company)):
|
if item.item_tax_amount and not cint(erpnext.is_perpetual_inventory_enabled(self.company)):
|
||||||
asset_eiiav_currency = get_account_currency(asset_accounts[0])
|
asset_eiiav_currency = get_account_currency(asset_accounts[1])
|
||||||
gl_entries.append(self.get_gl_dict({
|
gl_entries.append(self.get_gl_dict({
|
||||||
"account": asset_accounts[1],
|
"account": asset_accounts[1],
|
||||||
"against": self.supplier,
|
"against": self.supplier,
|
||||||
@ -750,13 +756,6 @@ class PurchaseInvoice(BuyingController):
|
|||||||
for pr in set(updated_pr):
|
for pr in set(updated_pr):
|
||||||
frappe.get_doc("Purchase Receipt", pr).update_billing_percentage(update_modified=update_modified)
|
frappe.get_doc("Purchase Receipt", pr).update_billing_percentage(update_modified=update_modified)
|
||||||
|
|
||||||
def validate_fixed_asset_account(self):
|
|
||||||
for d in self.get('items'):
|
|
||||||
if d.is_fixed_asset:
|
|
||||||
account_type = frappe.db.get_value("Account", d.expense_account, "account_type")
|
|
||||||
if account_type != 'Fixed Asset':
|
|
||||||
frappe.throw(_("Row {0}# Account must be of type 'Fixed Asset'").format(d.idx))
|
|
||||||
|
|
||||||
def on_recurring(self, reference_doc, auto_repeat_doc):
|
def on_recurring(self, reference_doc, auto_repeat_doc):
|
||||||
self.due_date = None
|
self.due_date = None
|
||||||
|
|
||||||
|
|||||||
1
erpnext/accounts/page/pos/pos.js
Normal file → Executable file
1
erpnext/accounts/page/pos/pos.js
Normal file → Executable file
@ -1051,6 +1051,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
item_name: obj.name === obj.item_name ? "" : obj.item_name,
|
item_name: obj.name === obj.item_name ? "" : obj.item_name,
|
||||||
item_image: obj.image,
|
item_image: obj.image,
|
||||||
item_stock: __('Stock Qty') + ": " + me.get_actual_qty(obj),
|
item_stock: __('Stock Qty') + ": " + me.get_actual_qty(obj),
|
||||||
|
item_uom: obj.stock_uom,
|
||||||
color: frappe.get_palette(obj.item_name),
|
color: frappe.get_palette(obj.item_name),
|
||||||
abbr: frappe.get_abbr(obj.item_name)
|
abbr: frappe.get_abbr(obj.item_name)
|
||||||
})).tooltip().appendTo($wrap);
|
})).tooltip().appendTo($wrap);
|
||||||
|
|||||||
@ -487,7 +487,7 @@ def get_patry_tax_withholding_details(ref_doc):
|
|||||||
|
|
||||||
if tax.valid_till and date_diff(tax.valid_till, ref_doc.posting_date) > 0:
|
if tax.valid_till and date_diff(tax.valid_till, ref_doc.posting_date) > 0:
|
||||||
tax_mapper.update({
|
tax_mapper.update({
|
||||||
"rate": tax.applicable_percentage
|
"rate": tax.applicable_percent
|
||||||
})
|
})
|
||||||
|
|
||||||
prepare_tax_withholding_details(tax_mapper, tax_withholding_details)
|
prepare_tax_withholding_details(tax_mapper, tax_withholding_details)
|
||||||
|
|||||||
@ -15,6 +15,10 @@ from erpnext.accounts.report.cash_flow.cash_flow import (get_cash_flow_accounts,
|
|||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
columns, data, message, chart = [], [], [], []
|
columns, data, message, chart = [], [], [], []
|
||||||
|
|
||||||
|
if not filters.get('company'):
|
||||||
|
return columns, data, message, chart
|
||||||
|
|
||||||
fiscal_year = get_fiscal_year_data(filters.get('from_fiscal_year'), filters.get('to_fiscal_year'))
|
fiscal_year = get_fiscal_year_data(filters.get('from_fiscal_year'), filters.get('to_fiscal_year'))
|
||||||
companies_column, companies = get_companies(filters)
|
companies_column, companies = get_companies(filters)
|
||||||
columns = get_columns(companies_column)
|
columns = get_columns(companies_column)
|
||||||
|
|||||||
@ -11,6 +11,9 @@ from erpnext.accounts.utils import get_account_currency
|
|||||||
|
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
|
if not filters:
|
||||||
|
return [], []
|
||||||
|
|
||||||
account_details = {}
|
account_details = {}
|
||||||
|
|
||||||
if filters and filters.get('print_in_account_currency') and \
|
if filters and filters.get('print_in_account_currency') and \
|
||||||
|
|||||||
@ -82,7 +82,7 @@ frappe.ui.form.on('Asset', {
|
|||||||
}
|
}
|
||||||
if (frm.doc.status != 'Fully Depreciated') {
|
if (frm.doc.status != 'Fully Depreciated') {
|
||||||
frm.add_custom_button(__("Asset Adjustment"), function() {
|
frm.add_custom_button(__("Asset Adjustment"), function() {
|
||||||
frm.trigger("create_asset_maintenance");
|
frm.trigger("create_asset_adjustment");
|
||||||
}, __("Make"));
|
}, __("Make"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +157,13 @@ frappe.ui.form.on('Asset', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
available_for_use_date: function(frm) {
|
||||||
|
$.each(frm.doc.finance_books || [], function(i, d) {
|
||||||
|
if(!d.depreciation_start_date) d.depreciation_start_date = frm.doc.available_for_use_date;
|
||||||
|
});
|
||||||
|
refresh_field("finance_books");
|
||||||
|
},
|
||||||
|
|
||||||
is_existing_asset: function(frm) {
|
is_existing_asset: function(frm) {
|
||||||
// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
|
// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
|
||||||
},
|
},
|
||||||
@ -226,6 +233,22 @@ frappe.ui.form.on('Asset', {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
create_asset_adjustment: function(frm) {
|
||||||
|
frappe.call({
|
||||||
|
args: {
|
||||||
|
"asset": frm.doc.name,
|
||||||
|
"asset_category": frm.doc.asset_category,
|
||||||
|
"company": frm.doc.company
|
||||||
|
},
|
||||||
|
method: "erpnext.assets.doctype.asset.asset.create_asset_adjustment",
|
||||||
|
freeze: 1,
|
||||||
|
callback: function(r) {
|
||||||
|
var doclist = frappe.model.sync(r.message);
|
||||||
|
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
calculate_depreciation: function(frm) {
|
calculate_depreciation: function(frm) {
|
||||||
frappe.db.get_value("Asset Settings", {'name':"Asset Settings"}, 'schedule_based_on_fiscal_year', (data) => {
|
frappe.db.get_value("Asset Settings", {'name':"Asset Settings"}, 'schedule_based_on_fiscal_year', (data) => {
|
||||||
if (data.schedule_based_on_fiscal_year == 1) {
|
if (data.schedule_based_on_fiscal_year == 1) {
|
||||||
@ -321,6 +344,42 @@ erpnext.asset.transfer_asset = function(frm) {
|
|||||||
},
|
},
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": __("Select Serial No"),
|
||||||
|
"fieldname": "serial_nos",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Serial No",
|
||||||
|
"get_query": function () {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
'asset': frm.doc.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"onchange": function() {
|
||||||
|
let val = this.get_value();
|
||||||
|
if (val) {
|
||||||
|
let serial_nos = dialog.get_value("serial_no") || val;
|
||||||
|
if (serial_nos) {
|
||||||
|
serial_nos = serial_nos.split('\n');
|
||||||
|
serial_nos.push(val);
|
||||||
|
|
||||||
|
const unique_sn = serial_nos.filter(function(elem, index, self) {
|
||||||
|
return index === self.indexOf(elem);
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.set_value("serial_no", unique_sn.join('\n'));
|
||||||
|
dialog.set_value("serial_nos", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": __("Serial No"),
|
||||||
|
"fieldname": "serial_no",
|
||||||
|
"read_only": 1,
|
||||||
|
"fieldtype": "Small Text"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": __("Date"),
|
"label": __("Date"),
|
||||||
"fieldname": "transfer_date",
|
"fieldname": "transfer_date",
|
||||||
@ -342,8 +401,9 @@ erpnext.asset.transfer_asset = function(frm) {
|
|||||||
args: {
|
args: {
|
||||||
"asset": frm.doc.name,
|
"asset": frm.doc.name,
|
||||||
"transaction_date": args.transfer_date,
|
"transaction_date": args.transfer_date,
|
||||||
"source_warehouse": frm.doc.location,
|
"source_location": frm.doc.location,
|
||||||
"target_warehouse": args.target_location,
|
"target_location": args.target_location,
|
||||||
|
"serial_no": args.serial_no,
|
||||||
"company": frm.doc.company
|
"company": frm.doc.company
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -51,7 +51,7 @@ class Asset(AccountsController):
|
|||||||
|
|
||||||
def validate_in_use_date(self):
|
def validate_in_use_date(self):
|
||||||
if not self.available_for_use_date:
|
if not self.available_for_use_date:
|
||||||
frappe.throw(_("Available for use data is required"))
|
frappe.throw(_("Available for use date is required"))
|
||||||
|
|
||||||
def set_missing_values(self):
|
def set_missing_values(self):
|
||||||
if not self.asset_category:
|
if not self.asset_category:
|
||||||
@ -162,6 +162,9 @@ class Asset(AccountsController):
|
|||||||
frappe.throw(_("Row {0}: Expected Value After Useful Life must be less than Gross Purchase Amount")
|
frappe.throw(_("Row {0}: Expected Value After Useful Life must be less than Gross Purchase Amount")
|
||||||
.format(row.idx))
|
.format(row.idx))
|
||||||
|
|
||||||
|
if not row.depreciation_start_date:
|
||||||
|
frappe.throw(_("Row {0}: Depreciation Start Date is required").format(row.idx))
|
||||||
|
|
||||||
if not self.is_existing_asset:
|
if not self.is_existing_asset:
|
||||||
self.opening_accumulated_depreciation = 0
|
self.opening_accumulated_depreciation = 0
|
||||||
self.number_of_depreciations_booked = 0
|
self.number_of_depreciations_booked = 0
|
||||||
@ -418,10 +421,24 @@ def create_asset_maintenance(asset, item_code, item_name, asset_category, compan
|
|||||||
})
|
})
|
||||||
return asset_maintenance
|
return asset_maintenance
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def create_asset_adjustment(asset, asset_category, company):
|
||||||
|
asset_maintenance = frappe.new_doc("Asset Adjustment")
|
||||||
|
asset_maintenance.update({
|
||||||
|
"asset": asset,
|
||||||
|
"company": company,
|
||||||
|
"asset_category": asset_category
|
||||||
|
})
|
||||||
|
return asset_maintenance
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def transfer_asset(args):
|
def transfer_asset(args):
|
||||||
import json
|
import json
|
||||||
args = json.loads(args)
|
args = json.loads(args)
|
||||||
|
|
||||||
|
if args.get('serial_no'):
|
||||||
|
args['quantity'] = len(args.get('serial_no').split('\n'))
|
||||||
|
|
||||||
movement_entry = frappe.new_doc("Asset Movement")
|
movement_entry = frappe.new_doc("Asset Movement")
|
||||||
movement_entry.update(args)
|
movement_entry.update(args)
|
||||||
movement_entry.insert()
|
movement_entry.insert()
|
||||||
|
|||||||
@ -2,6 +2,18 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on('Asset Adjustment', {
|
frappe.ui.form.on('Asset Adjustment', {
|
||||||
|
setup: function(frm) {
|
||||||
|
frm.add_fetch('company', 'cost_center', 'cost_center');
|
||||||
|
frm.set_query('cost_center', function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
company: frm.doc.company,
|
||||||
|
is_group: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
asset: function(frm) {
|
asset: function(frm) {
|
||||||
frm.trigger("set_current_asset_value");
|
frm.trigger("set_current_asset_value");
|
||||||
},
|
},
|
||||||
@ -11,7 +23,6 @@ frappe.ui.form.on('Asset Adjustment', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
set_current_asset_value: function(frm) {
|
set_current_asset_value: function(frm) {
|
||||||
debugger
|
|
||||||
if (frm.doc.finance_book && frm.doc.asset) {
|
if (frm.doc.finance_book && frm.doc.asset) {
|
||||||
frm.call({
|
frm.call({
|
||||||
method: "erpnext.assets.doctype.asset_adjustment.asset_adjustment.get_current_asset_value",
|
method: "erpnext.assets.doctype.asset_adjustment.asset_adjustment.get_current_asset_value",
|
||||||
|
|||||||
@ -41,6 +41,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -72,6 +73,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -103,6 +105,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -134,6 +137,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -165,6 +169,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -194,6 +199,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -203,7 +209,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "date",
|
"fieldname": "date",
|
||||||
"fieldtype": "Datetime",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
@ -224,6 +230,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -254,6 +261,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -284,6 +292,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -314,6 +323,39 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "cost_center",
|
||||||
|
"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": "Cost Center",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Cost Center",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -344,6 +386,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -357,7 +400,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-05-11 21:45:03.459696",
|
"modified": "2018-05-17 11:12:38.110774",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset Adjustment",
|
"name": "Asset Adjustment",
|
||||||
@ -366,7 +409,6 @@
|
|||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
@ -386,7 +428,6 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
@ -406,7 +447,6 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
|
|||||||
@ -16,12 +16,14 @@ class AssetAdjustment(Document):
|
|||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.make_depreciation_entry()
|
self.make_depreciation_entry()
|
||||||
self.reschedule_depreciations()
|
self.reschedule_depreciations(self.new_asset_value)
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
if self.journal_entry:
|
if self.journal_entry:
|
||||||
frappe.throw(_("Cancel the journal entry {0} first").format(self.journal_entry))
|
frappe.throw(_("Cancel the journal entry {0} first").format(self.journal_entry))
|
||||||
|
|
||||||
|
self.reschedule_depreciations(self.current_asset_value)
|
||||||
|
|
||||||
def set_difference_amount(self):
|
def set_difference_amount(self):
|
||||||
self.difference_amount = flt(self.current_asset_value - self.new_asset_value)
|
self.difference_amount = flt(self.current_asset_value - self.new_asset_value)
|
||||||
|
|
||||||
@ -47,12 +49,13 @@ class AssetAdjustment(Document):
|
|||||||
je.append("accounts", {
|
je.append("accounts", {
|
||||||
"account": accumulated_depreciation_account,
|
"account": accumulated_depreciation_account,
|
||||||
"credit_in_account_currency": self.difference_amount,
|
"credit_in_account_currency": self.difference_amount,
|
||||||
|
"cost_center": depreciation_cost_center or self.cost_center
|
||||||
})
|
})
|
||||||
|
|
||||||
je.append("accounts", {
|
je.append("accounts", {
|
||||||
"account": depreciation_expense_account,
|
"account": depreciation_expense_account,
|
||||||
"debit_in_account_currency": self.difference_amount,
|
"debit_in_account_currency": self.difference_amount,
|
||||||
"cost_center": depreciation_cost_center
|
"cost_center": depreciation_cost_center or self.cost_center
|
||||||
})
|
})
|
||||||
|
|
||||||
je.flags.ignore_permissions = True
|
je.flags.ignore_permissions = True
|
||||||
@ -60,11 +63,11 @@ class AssetAdjustment(Document):
|
|||||||
|
|
||||||
self.db_set("journal_entry", je.name)
|
self.db_set("journal_entry", je.name)
|
||||||
|
|
||||||
def reschedule_depreciations(self):
|
def reschedule_depreciations(self, asset_value):
|
||||||
asset = frappe.get_doc('Asset', self.asset)
|
asset = frappe.get_doc('Asset', self.asset)
|
||||||
|
|
||||||
for d in asset.finance_books:
|
for d in asset.finance_books:
|
||||||
d.value_after_depreciation = self.new_asset_value
|
d.value_after_depreciation = asset_value
|
||||||
|
|
||||||
if d.depreciation_method in ("Straight Line", "Manual"):
|
if d.depreciation_method in ("Straight Line", "Manual"):
|
||||||
end_date = max([s.schedule_date for s in asset.schedules if cint(s.finance_book_id) == d.idx])
|
end_date = max([s.schedule_date for s in asset.schedules if cint(s.finance_book_id) == d.idx])
|
||||||
|
|||||||
@ -55,7 +55,5 @@ class AssetMovement(Document):
|
|||||||
frappe.db.set_value("Asset", self.asset, "location", location)
|
frappe.db.set_value("Asset", self.asset, "location", location)
|
||||||
|
|
||||||
if self.serial_no:
|
if self.serial_no:
|
||||||
serial_nos = get_serial_nos(self.serial_no)
|
for d in get_serial_nos(self.serial_no):
|
||||||
|
frappe.db.set_value('Serial No', d, 'location', location)
|
||||||
frappe.db.sql(""" update `tabSerial No` set location = %s where name in (%s)"""
|
|
||||||
%('%s', ','.join(['%s'] * len(serial_nos))), (location, tuple(serial_nos)))
|
|
||||||
|
|||||||
@ -621,8 +621,8 @@ class AccountsController(TransactionBase):
|
|||||||
def validate_fixed_asset(self):
|
def validate_fixed_asset(self):
|
||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
if d.is_fixed_asset:
|
if d.is_fixed_asset:
|
||||||
if d.qty > 1:
|
# if d.qty > 1:
|
||||||
frappe.throw(_("Row #{0}: Qty must be 1, as item is a fixed asset. Please use separate row for multiple qty.").format(d.idx))
|
# frappe.throw(_("Row #{0}: Qty must be 1, as item is a fixed asset. Please use separate row for multiple qty.").format(d.idx))
|
||||||
|
|
||||||
if d.meta.get_field("asset") and d.asset:
|
if d.meta.get_field("asset") and d.asset:
|
||||||
asset = frappe.get_doc("Asset", d.asset)
|
asset = frappe.get_doc("Asset", d.asset)
|
||||||
@ -635,8 +635,8 @@ class AccountsController(TransactionBase):
|
|||||||
frappe.throw(_("Row #{0}: Asset {1} does not linked to Item {2}")
|
frappe.throw(_("Row #{0}: Asset {1} does not linked to Item {2}")
|
||||||
.format(d.idx, d.asset, d.item_code))
|
.format(d.idx, d.asset, d.item_code))
|
||||||
|
|
||||||
elif asset.docstatus != 1:
|
# elif asset.docstatus != 1:
|
||||||
frappe.throw(_("Row #{0}: Asset {1} must be submitted").format(d.idx, d.asset))
|
# frappe.throw(_("Row #{0}: Asset {1} must be submitted").format(d.idx, d.asset))
|
||||||
|
|
||||||
elif self.doctype == "Purchase Invoice":
|
elif self.doctype == "Purchase Invoice":
|
||||||
# if asset.status != "Submitted":
|
# if asset.status != "Submitted":
|
||||||
|
|||||||
@ -366,7 +366,7 @@ def get_expense_account(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
|
|
||||||
return frappe.db.sql("""select tabAccount.name from `tabAccount`
|
return frappe.db.sql("""select tabAccount.name from `tabAccount`
|
||||||
where (tabAccount.report_type = "Profit and Loss"
|
where (tabAccount.report_type = "Profit and Loss"
|
||||||
or tabAccount.account_type in ("Expense Account", "Fixed Asset", "Temporary"))
|
or tabAccount.account_type in ("Expense Account", "Fixed Asset", "Temporary", "Asset Received But Not Billed"))
|
||||||
and tabAccount.is_group=0
|
and tabAccount.is_group=0
|
||||||
and tabAccount.docstatus!=2
|
and tabAccount.docstatus!=2
|
||||||
and tabAccount.{key} LIKE %(txt)s
|
and tabAccount.{key} LIKE %(txt)s
|
||||||
|
|||||||
@ -139,6 +139,37 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "total_exemption_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Total Exemption Amount",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -243,7 +274,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-05-15 16:16:46.075493",
|
"modified": "2018-05-16 19:03:57.624215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Employee Tax Exemption Declaration",
|
"name": "Employee Tax Exemption Declaration",
|
||||||
|
|||||||
@ -19,3 +19,6 @@ class EmployeeTaxExemptionDeclaration(Document):
|
|||||||
"docstatus": 1}):
|
"docstatus": 1}):
|
||||||
frappe.throw(_("Tax Declaration of {0} for period {1} already submitted.")\
|
frappe.throw(_("Tax Declaration of {0} for period {1} already submitted.")\
|
||||||
.format(self.employee, self.payroll_period), frappe.DocstatusTransitionError)
|
.format(self.employee, self.payroll_period), frappe.DocstatusTransitionError)
|
||||||
|
self.total_exemption_amount = 0
|
||||||
|
for item in self.declarations:
|
||||||
|
self.total_exemption_amount += item.amount
|
||||||
|
|||||||
@ -14,7 +14,7 @@ class EmployeeTransfer(Document):
|
|||||||
if frappe.get_value("Employee", self.employee, "status") == "Left":
|
if frappe.get_value("Employee", self.employee, "status") == "Left":
|
||||||
frappe.throw(_("Cannot transfer Employee with status Left"))
|
frappe.throw(_("Cannot transfer Employee with status Left"))
|
||||||
if self.new_company and self.company == self.new_company:
|
if self.new_company and self.company == self.new_company:
|
||||||
frappe.throw_("New Company must be different from current company")
|
frappe.throw(_("New Company must be different from current company"))
|
||||||
|
|
||||||
def before_submit(self):
|
def before_submit(self):
|
||||||
if getdate(self.transfer_date) > getdate():
|
if getdate(self.transfer_date) > getdate():
|
||||||
|
|||||||
@ -50,8 +50,11 @@ frappe.ui.form.on("Leave Application", {
|
|||||||
date: frm.doc.posting_date
|
date: frm.doc.posting_date
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if (!r.exc && r.message) {
|
if (!r.exc && r.message['leave_allocation']) {
|
||||||
leave_details = r.message;
|
leave_details = r.message['leave_allocation'];
|
||||||
|
}
|
||||||
|
if (!r.exc && r.message['leave_approver']) {
|
||||||
|
frm.set_value('leave_approver', r.message['leave_approver']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -74,6 +77,13 @@ frappe.ui.form.on("Leave Application", {
|
|||||||
if(frm.doc.__islocal && !in_list(frappe.user_roles, "Employee")) {
|
if(frm.doc.__islocal && !in_list(frappe.user_roles, "Employee")) {
|
||||||
frm.set_intro(__("Fill the form and save it"));
|
frm.set_intro(__("Fill the form and save it"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!frm.doc.employee && frappe.defaults.get_user_permissions()) {
|
||||||
|
const perm = frappe.defaults.get_user_permissions();
|
||||||
|
if (perm && perm['Employee']) {
|
||||||
|
frm.set_value('employee', perm['Employee']["docs"][0])
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
employee: function(frm) {
|
employee: function(frm) {
|
||||||
|
|||||||
@ -374,7 +374,12 @@ def get_leave_details(employee, date):
|
|||||||
"pending_leaves": leaves_pending,
|
"pending_leaves": leaves_pending,
|
||||||
"remaining_leaves": remaining_leaves}
|
"remaining_leaves": remaining_leaves}
|
||||||
|
|
||||||
return leave_allocation
|
ret = {
|
||||||
|
'leave_allocation': leave_allocation,
|
||||||
|
'leave_approver': get_leave_approver(employee)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_leave_balance_on(employee, leave_type, date, allocation_records=None,
|
def get_leave_balance_on(employee, leave_type, date, allocation_records=None,
|
||||||
@ -603,3 +608,10 @@ def get_approved_leaves_for_period(employee, leave_type, from_date, to_date):
|
|||||||
|
|
||||||
return leave_days
|
return leave_days
|
||||||
|
|
||||||
|
def get_leave_approver(employee, department=None):
|
||||||
|
if not department:
|
||||||
|
department = frappe.db.get_value('Employee', employee, 'department')
|
||||||
|
|
||||||
|
if department:
|
||||||
|
return frappe.db.get_value('Department Approver', {'parent': department,
|
||||||
|
'parentfield': 'leave_approver', 'idx': 1}, 'approver')
|
||||||
|
|||||||
@ -34,3 +34,12 @@ class SalaryComponent(Document):
|
|||||||
self.salary_component_abbr = self.salary_component_abbr.strip()
|
self.salary_component_abbr = self.salary_component_abbr.strip()
|
||||||
self.salary_component_abbr = append_number_if_name_exists('Salary Component', self.salary_component_abbr,
|
self.salary_component_abbr = append_number_if_name_exists('Salary Component', self.salary_component_abbr,
|
||||||
'salary_component_abbr', separator='_', filters={"name": ["!=", self.name]})
|
'salary_component_abbr', separator='_', filters={"name": ["!=", self.name]})
|
||||||
|
|
||||||
|
def calculate_tax(self, annual_earning):
|
||||||
|
taxable_amount = 0
|
||||||
|
for slab in self.taxable_salary_slabs:
|
||||||
|
if annual_earning > slab.from_amount and annual_earning < slab.to_amount:
|
||||||
|
taxable_amount += (annual_earning - slab.from_amount) * slab.percent_deduction *.01
|
||||||
|
elif annual_earning > slab.from_amount and annual_earning > slab.to_amount:
|
||||||
|
taxable_amount += (slab.to_amount - slab.from_amount) * slab.percent_deduction * .01
|
||||||
|
return taxable_amount
|
||||||
|
|||||||
@ -40,6 +40,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -72,6 +73,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -101,6 +103,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -132,6 +135,100 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "is_tax_applicable",
|
||||||
|
"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": "Is Tax Applicable",
|
||||||
|
"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": "is_flexible_benefit",
|
||||||
|
"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": "Is Flexible Benefit",
|
||||||
|
"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": "variable_based_on_taxable_salary",
|
||||||
|
"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": "Variable Based On Taxable Salary",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -161,6 +258,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -192,6 +290,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -225,6 +324,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -258,6 +358,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -290,6 +391,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -321,6 +423,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -351,6 +454,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -383,6 +487,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -413,6 +518,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -445,6 +551,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -458,7 +565,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-10-02 13:57:22.769751",
|
"modified": "2018-05-16 22:42:59.974450",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Salary Detail",
|
"name": "Salary Detail",
|
||||||
|
|||||||
@ -16,6 +16,7 @@ from erpnext.hr.doctype.additional_salary_component.additional_salary_component
|
|||||||
from erpnext.hr.doctype.employee_benefit_application.employee_benefit_application import get_employee_benefit_application, get_amount
|
from erpnext.hr.doctype.employee_benefit_application.employee_benefit_application import get_employee_benefit_application, get_amount
|
||||||
from erpnext.hr.doctype.payroll_period.payroll_period import get_payroll_period_days
|
from erpnext.hr.doctype.payroll_period.payroll_period import get_payroll_period_days
|
||||||
from erpnext.hr.doctype.employee_benefit_claim.employee_benefit_claim import get_employee_benefit_claim
|
from erpnext.hr.doctype.employee_benefit_claim.employee_benefit_claim import get_employee_benefit_claim
|
||||||
|
from erpnext.hr.utils import get_payroll_period
|
||||||
|
|
||||||
class SalarySlip(TransactionBase):
|
class SalarySlip(TransactionBase):
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
@ -61,6 +62,10 @@ class SalarySlip(TransactionBase):
|
|||||||
amount = self.eval_condition_and_formula(struct_row, data)
|
amount = self.eval_condition_and_formula(struct_row, data)
|
||||||
if amount and struct_row.statistical_component == 0:
|
if amount and struct_row.statistical_component == 0:
|
||||||
self.update_component_row(struct_row, amount, key)
|
self.update_component_row(struct_row, amount, key)
|
||||||
|
if key=="deductions" and struct_row.variable_based_on_taxable_salary:
|
||||||
|
tax_row, amount = self.calculate_pro_rata_tax(struct_row.salary_component)
|
||||||
|
if tax_row and amount:
|
||||||
|
self.update_component_row(frappe._dict(tax_row), amount, key)
|
||||||
|
|
||||||
additional_components = get_additional_salary_component(self.employee, self.start_date, self.end_date)
|
additional_components = get_additional_salary_component(self.employee, self.start_date, self.end_date)
|
||||||
if additional_components:
|
if additional_components:
|
||||||
@ -518,6 +523,52 @@ class SalarySlip(TransactionBase):
|
|||||||
status = "Cancelled"
|
status = "Cancelled"
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
def calculate_pro_rata_tax(self, salary_component):
|
||||||
|
# Calculate total tax payable earnings
|
||||||
|
tax_applicable_components = []
|
||||||
|
for earning in self._salary_structure_doc.earnings:
|
||||||
|
#all tax applicable earnings which are not flexi
|
||||||
|
if earning.is_tax_applicable and not earning.is_flexible_benefit:
|
||||||
|
tax_applicable_components.append(earning.salary_component)
|
||||||
|
total_taxable_earning = 0
|
||||||
|
for earning in self.earnings:
|
||||||
|
if earning.salary_component in tax_applicable_components:
|
||||||
|
total_taxable_earning += earning.amount
|
||||||
|
|
||||||
|
# Get payroll period, prorata frequency
|
||||||
|
days = date_diff(self.end_date, self.start_date) + 1
|
||||||
|
payroll_period = get_payroll_period(self.start_date, self.end_date, self.company)
|
||||||
|
if not payroll_period:
|
||||||
|
frappe.throw(_("Start and end dates not in a valid Payroll Period"))
|
||||||
|
total_days = date_diff(payroll_period.end_date, payroll_period.start_date) + 1
|
||||||
|
prorata_frequency = flt(total_days)/flt(days)
|
||||||
|
annual_earning = total_taxable_earning * prorata_frequency
|
||||||
|
|
||||||
|
# Calculate total exemption declaration
|
||||||
|
exemption_amount = 0
|
||||||
|
if frappe.db.exists("Employee Tax Exemption Declaration", {"employee": self.employee,
|
||||||
|
"payroll_period": payroll_period.name, "docstatus": 1}):
|
||||||
|
exemption_amount = frappe.db.get_value("Employee Tax Exemption Declaration",
|
||||||
|
{"employee": self.employee, "payroll_period": payroll_period.name, "docstatus": 1}, #fix period
|
||||||
|
"total_exemption_amount")
|
||||||
|
annual_earning = annual_earning - exemption_amount
|
||||||
|
|
||||||
|
# Get tax calc by component
|
||||||
|
component = frappe.get_doc("Salary Component", salary_component)
|
||||||
|
annual_tax = component.calculate_tax(annual_earning)
|
||||||
|
|
||||||
|
# Calc prorata tax
|
||||||
|
pro_rata_tax = annual_tax/prorata_frequency
|
||||||
|
|
||||||
|
# Data for update_component_row
|
||||||
|
struct_row = {}
|
||||||
|
struct_row['depends_on_lwp'] = 0
|
||||||
|
struct_row['salary_component'] = component.name
|
||||||
|
struct_row['abbr'] = component.salary_component_abbr
|
||||||
|
struct_row['do_not_include_in_total'] = 0
|
||||||
|
|
||||||
|
return struct_row, pro_rata_tax
|
||||||
|
|
||||||
def unlink_ref_doc_from_salary_slip(ref_no):
|
def unlink_ref_doc_from_salary_slip(ref_no):
|
||||||
linked_ss = frappe.db.sql_list("""select name from `tabSalary Slip`
|
linked_ss = frappe.db.sql_list("""select name from `tabSalary Slip`
|
||||||
where journal_entry=%s and docstatus < 2""", (ref_no))
|
where journal_entry=%s and docstatus < 2""", (ref_no))
|
||||||
|
|||||||
@ -192,17 +192,20 @@ frappe.ui.form.on('Salary Detail', {
|
|||||||
callback: function(data) {
|
callback: function(data) {
|
||||||
if(data.message){
|
if(data.message){
|
||||||
var result = data.message;
|
var result = data.message;
|
||||||
frappe.model.set_value(cdt, cdn, 'condition',result.condition);
|
frappe.model.set_value(cdt, cdn, 'condition', result.condition);
|
||||||
frappe.model.set_value(cdt, cdn, 'amount_based_on_formula',result.amount_based_on_formula);
|
frappe.model.set_value(cdt, cdn, 'amount_based_on_formula', result.amount_based_on_formula);
|
||||||
if(result.amount_based_on_formula == 1){
|
if(result.amount_based_on_formula == 1){
|
||||||
frappe.model.set_value(cdt, cdn, 'formula',result.formula);
|
frappe.model.set_value(cdt, cdn, 'formula', result.formula);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
frappe.model.set_value(cdt, cdn, 'amount',result.amount);
|
frappe.model.set_value(cdt, cdn, 'amount', result.amount);
|
||||||
}
|
}
|
||||||
frappe.model.set_value(cdt, cdn, 'statistical_component',result.statistical_component);
|
frappe.model.set_value(cdt, cdn, 'statistical_component', result.statistical_component);
|
||||||
frappe.model.set_value(cdt, cdn, 'depends_on_lwp',result.depends_on_lwp);
|
frappe.model.set_value(cdt, cdn, 'depends_on_lwp', result.depends_on_lwp);
|
||||||
frappe.model.set_value(cdt, cdn, 'do_not_include_in_total',result.do_not_include_in_total);
|
frappe.model.set_value(cdt, cdn, 'do_not_include_in_total', result.do_not_include_in_total);
|
||||||
|
frappe.model.set_value(cdt, cdn, 'variable_based_on_taxable_salary', result.variable_based_on_taxable_salary);
|
||||||
|
frappe.model.set_value(cdt, cdn, 'is_tax_applicable', result.is_tax_applicable);
|
||||||
|
frappe.model.set_value(cdt, cdn, 'is_flexible_benefit', result.is_flexible_benefit);
|
||||||
refresh_field("earnings");
|
refresh_field("earnings");
|
||||||
refresh_field("deductions");
|
refresh_field("deductions");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,7 +50,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "to_amount",
|
"fieldname": "to_amount",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
@ -147,7 +147,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-04-13 20:09:36.675987",
|
"modified": "2018-05-16 18:18:23.802576",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Taxable Salary Slab",
|
"name": "Taxable Salary Slab",
|
||||||
|
|||||||
@ -234,3 +234,10 @@ def get_leave_period(from_date, to_date, company):
|
|||||||
|
|
||||||
if leave_period:
|
if leave_period:
|
||||||
return leave_period
|
return leave_period
|
||||||
|
|
||||||
|
def get_payroll_period(from_date, to_date, company):
|
||||||
|
payroll_period = frappe.db.sql("""select pp.name, pd.start_date, pd.end_date from
|
||||||
|
`tabPayroll Period Date` pd join `tabPayroll Period` pp on
|
||||||
|
pd.parent=pp.name where pd.start_date<=%s and pd.end_date>= %s
|
||||||
|
and pp.company=%s""", (from_date, to_date, company), as_dict=1)
|
||||||
|
return payroll_period[0] if payroll_period else None
|
||||||
|
|||||||
2
erpnext/public/js/pos/pos_item.html
Normal file → Executable file
2
erpnext/public/js/pos/pos_item.html
Normal file → Executable file
@ -25,7 +25,7 @@
|
|||||||
{% } %}
|
{% } %}
|
||||||
</div>
|
</div>
|
||||||
<span class="price-info">
|
<span class="price-info">
|
||||||
{{item_price}}
|
{{item_price}} / {{item_uom}}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user