Merge branch 'develop' into fix-job-opening
This commit is contained in:
commit
3f13b0ec97
@ -78,6 +78,8 @@ class TestPeriodClosingVoucher(unittest.TestCase):
|
|||||||
expense_account="Cost of Goods Sold - TPC",
|
expense_account="Cost of Goods Sold - TPC",
|
||||||
rate=400,
|
rate=400,
|
||||||
debit_to="Debtors - TPC",
|
debit_to="Debtors - TPC",
|
||||||
|
currency="USD",
|
||||||
|
customer="_Test Customer USD",
|
||||||
)
|
)
|
||||||
create_sales_invoice(
|
create_sales_invoice(
|
||||||
company=company,
|
company=company,
|
||||||
@ -86,6 +88,8 @@ class TestPeriodClosingVoucher(unittest.TestCase):
|
|||||||
expense_account="Cost of Goods Sold - TPC",
|
expense_account="Cost of Goods Sold - TPC",
|
||||||
rate=200,
|
rate=200,
|
||||||
debit_to="Debtors - TPC",
|
debit_to="Debtors - TPC",
|
||||||
|
currency="USD",
|
||||||
|
customer="_Test Customer USD",
|
||||||
)
|
)
|
||||||
|
|
||||||
pcv = self.make_period_closing_voucher(submit=False)
|
pcv = self.make_period_closing_voucher(submit=False)
|
||||||
@ -119,14 +123,17 @@ class TestPeriodClosingVoucher(unittest.TestCase):
|
|||||||
surplus_account = create_account()
|
surplus_account = create_account()
|
||||||
cost_center = create_cost_center("Test Cost Center 1")
|
cost_center = create_cost_center("Test Cost Center 1")
|
||||||
|
|
||||||
create_sales_invoice(
|
si = create_sales_invoice(
|
||||||
company=company,
|
company=company,
|
||||||
income_account="Sales - TPC",
|
income_account="Sales - TPC",
|
||||||
expense_account="Cost of Goods Sold - TPC",
|
expense_account="Cost of Goods Sold - TPC",
|
||||||
cost_center=cost_center,
|
cost_center=cost_center,
|
||||||
rate=400,
|
rate=400,
|
||||||
debit_to="Debtors - TPC",
|
debit_to="Debtors - TPC",
|
||||||
|
currency="USD",
|
||||||
|
customer="_Test Customer USD",
|
||||||
)
|
)
|
||||||
|
|
||||||
jv = make_journal_entry(
|
jv = make_journal_entry(
|
||||||
account1="Cash - TPC",
|
account1="Cash - TPC",
|
||||||
account2="Sales - TPC",
|
account2="Sales - TPC",
|
||||||
|
|||||||
@ -752,7 +752,7 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
title="_Test Pricing Rule with Min Qty - 2",
|
title="_Test Pricing Rule with Min Qty - 2",
|
||||||
)
|
)
|
||||||
|
|
||||||
si = create_sales_invoice(do_not_submit=True, customer="_Test Customer 1", qty=1, currency="USD")
|
si = create_sales_invoice(do_not_submit=True, customer="_Test Customer 1", qty=1)
|
||||||
item = si.items[0]
|
item = si.items[0]
|
||||||
item.stock_qty = 1
|
item.stock_qty = 1
|
||||||
si.save()
|
si.save()
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"creation": "2013-01-10 16:34:08",
|
"creation": "2013-01-10 16:34:08",
|
||||||
"description": "Standard tax template that can be applied to all Purchase Transactions. This template can contain list of tax heads and also other expense heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Consider Tax or Charge for: In this section you can specify if the tax / charge is only for valuation (not a part of total) or only for total (does not add value to the item) or for both.\n10. Add or Deduct: Whether you want to add or deduct the tax.",
|
"description": "Standard tax template that can be applied to all Purchase Transactions. This template can contain list of tax heads and also other expense heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Consider Tax or Charge for: In this section you can specify if the tax / charge is only for valuation (not a part of total) or only for total (does not add value to the item) or for both.\n10. Add or Deduct: Whether you want to add or deduct the tax.",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Setup",
|
"document_type": "Setup",
|
||||||
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"title",
|
"title",
|
||||||
"is_default",
|
"is_default",
|
||||||
@ -74,7 +76,8 @@
|
|||||||
],
|
],
|
||||||
"icon": "fa fa-money",
|
"icon": "fa fa-money",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"modified": "2019-11-25 13:05:26.220275",
|
"links": [],
|
||||||
|
"modified": "2022-05-16 16:15:29.059370",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Taxes and Charges Template",
|
"name": "Purchase Taxes and Charges Template",
|
||||||
@ -103,6 +106,10 @@
|
|||||||
"role": "Purchase User"
|
"role": "Purchase User"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"show_title_field_in_link": 1,
|
||||||
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
|
"title_field": "title",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@ -861,27 +861,44 @@ frappe.ui.form.on('Sales Invoice', {
|
|||||||
|
|
||||||
set_timesheet_data: function(frm, timesheets) {
|
set_timesheet_data: function(frm, timesheets) {
|
||||||
frm.clear_table("timesheets")
|
frm.clear_table("timesheets")
|
||||||
timesheets.forEach(timesheet => {
|
timesheets.forEach(async (timesheet) => {
|
||||||
if (frm.doc.currency != timesheet.currency) {
|
if (frm.doc.currency != timesheet.currency) {
|
||||||
frappe.call({
|
const exchange_rate = await frm.events.get_exchange_rate(
|
||||||
method: "erpnext.setup.utils.get_exchange_rate",
|
frm, timesheet.currency, frm.doc.currency
|
||||||
args: {
|
)
|
||||||
from_currency: timesheet.currency,
|
frm.events.append_time_log(frm, timesheet, exchange_rate)
|
||||||
to_currency: frm.doc.currency
|
|
||||||
},
|
|
||||||
callback: function(r) {
|
|
||||||
if (r.message) {
|
|
||||||
exchange_rate = r.message;
|
|
||||||
frm.events.append_time_log(frm, timesheet, exchange_rate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
frm.events.append_time_log(frm, timesheet, 1.0);
|
frm.events.append_time_log(frm, timesheet, 1.0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async get_exchange_rate(frm, from_currency, to_currency) {
|
||||||
|
if (
|
||||||
|
frm.exchange_rates
|
||||||
|
&& frm.exchange_rates[from_currency]
|
||||||
|
&& frm.exchange_rates[from_currency][to_currency]
|
||||||
|
) {
|
||||||
|
return frm.exchange_rates[from_currency][to_currency];
|
||||||
|
}
|
||||||
|
|
||||||
|
return frappe.call({
|
||||||
|
method: "erpnext.setup.utils.get_exchange_rate",
|
||||||
|
args: {
|
||||||
|
from_currency,
|
||||||
|
to_currency
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
if (r.message) {
|
||||||
|
// cache exchange rates
|
||||||
|
frm.exchange_rates = frm.exchange_rates || {};
|
||||||
|
frm.exchange_rates[from_currency] = frm.exchange_rates[from_currency] || {};
|
||||||
|
frm.exchange_rates[from_currency][to_currency] = r.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
append_time_log: function(frm, time_log, exchange_rate) {
|
append_time_log: function(frm, time_log, exchange_rate) {
|
||||||
const row = frm.add_child("timesheets");
|
const row = frm.add_child("timesheets");
|
||||||
row.activity_type = time_log.activity_type;
|
row.activity_type = time_log.activity_type;
|
||||||
@ -892,7 +909,7 @@ frappe.ui.form.on('Sales Invoice', {
|
|||||||
row.billing_hours = time_log.billing_hours;
|
row.billing_hours = time_log.billing_hours;
|
||||||
row.billing_amount = flt(time_log.billing_amount) * flt(exchange_rate);
|
row.billing_amount = flt(time_log.billing_amount) * flt(exchange_rate);
|
||||||
row.timesheet_detail = time_log.name;
|
row.timesheet_detail = time_log.name;
|
||||||
row.project_name = time_log.project_name;
|
row.project_name = time_log.project_name;
|
||||||
|
|
||||||
frm.refresh_field("timesheets");
|
frm.refresh_field("timesheets");
|
||||||
frm.trigger("calculate_timesheet_totals");
|
frm.trigger("calculate_timesheet_totals");
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"creation": "2013-01-10 16:34:09",
|
"creation": "2013-01-10 16:34:09",
|
||||||
@ -77,7 +78,8 @@
|
|||||||
],
|
],
|
||||||
"icon": "fa fa-money",
|
"icon": "fa fa-money",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"modified": "2019-11-25 13:06:03.279099",
|
"links": [],
|
||||||
|
"modified": "2022-05-16 16:14:52.061672",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Taxes and Charges Template",
|
"name": "Sales Taxes and Charges Template",
|
||||||
@ -113,7 +115,10 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"show_title_field_in_link": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC",
|
"sort_order": "ASC",
|
||||||
|
"states": [],
|
||||||
|
"title_field": "title",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@ -897,3 +897,18 @@ def get_default_contact(doctype, name):
|
|||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def add_party_account(party_type, party, company, account):
|
||||||
|
doc = frappe.get_doc(party_type, party)
|
||||||
|
account_exists = False
|
||||||
|
for d in doc.get("accounts"):
|
||||||
|
if d.account == account:
|
||||||
|
account_exists = True
|
||||||
|
|
||||||
|
if not account_exists:
|
||||||
|
accounts = {"company": company, "account": account}
|
||||||
|
|
||||||
|
doc.append("accounts", accounts)
|
||||||
|
|
||||||
|
doc.save()
|
||||||
|
|||||||
@ -198,10 +198,12 @@ def get_loan_entries(filters):
|
|||||||
amount_field = (loan_doc.disbursed_amount).as_("credit")
|
amount_field = (loan_doc.disbursed_amount).as_("credit")
|
||||||
posting_date = (loan_doc.disbursement_date).as_("posting_date")
|
posting_date = (loan_doc.disbursement_date).as_("posting_date")
|
||||||
account = loan_doc.disbursement_account
|
account = loan_doc.disbursement_account
|
||||||
|
salary_condition = loan_doc.docstatus == 1
|
||||||
else:
|
else:
|
||||||
amount_field = (loan_doc.amount_paid).as_("debit")
|
amount_field = (loan_doc.amount_paid).as_("debit")
|
||||||
posting_date = (loan_doc.posting_date).as_("posting_date")
|
posting_date = (loan_doc.posting_date).as_("posting_date")
|
||||||
account = loan_doc.payment_account
|
account = loan_doc.payment_account
|
||||||
|
salary_condition = loan_doc.repay_from_salary == 0
|
||||||
|
|
||||||
query = (
|
query = (
|
||||||
frappe.qb.from_(loan_doc)
|
frappe.qb.from_(loan_doc)
|
||||||
@ -214,14 +216,12 @@ def get_loan_entries(filters):
|
|||||||
posting_date,
|
posting_date,
|
||||||
)
|
)
|
||||||
.where(loan_doc.docstatus == 1)
|
.where(loan_doc.docstatus == 1)
|
||||||
|
.where(salary_condition)
|
||||||
.where(account == filters.get("account"))
|
.where(account == filters.get("account"))
|
||||||
.where(posting_date <= getdate(filters.get("report_date")))
|
.where(posting_date <= getdate(filters.get("report_date")))
|
||||||
.where(ifnull(loan_doc.clearance_date, "4000-01-01") > getdate(filters.get("report_date")))
|
.where(ifnull(loan_doc.clearance_date, "4000-01-01") > getdate(filters.get("report_date")))
|
||||||
)
|
)
|
||||||
|
|
||||||
if doctype == "Loan Repayment":
|
|
||||||
query.where(loan_doc.repay_from_salary == 0)
|
|
||||||
|
|
||||||
entries = query.run(as_dict=1)
|
entries = query.run(as_dict=1)
|
||||||
loan_docs.extend(entries)
|
loan_docs.extend(entries)
|
||||||
|
|
||||||
@ -267,15 +267,17 @@ def get_loan_amount(filters):
|
|||||||
amount_field = Sum(loan_doc.disbursed_amount)
|
amount_field = Sum(loan_doc.disbursed_amount)
|
||||||
posting_date = (loan_doc.disbursement_date).as_("posting_date")
|
posting_date = (loan_doc.disbursement_date).as_("posting_date")
|
||||||
account = loan_doc.disbursement_account
|
account = loan_doc.disbursement_account
|
||||||
|
salary_condition = loan_doc.docstatus == 1
|
||||||
else:
|
else:
|
||||||
amount_field = Sum(loan_doc.amount_paid)
|
amount_field = Sum(loan_doc.amount_paid)
|
||||||
posting_date = (loan_doc.posting_date).as_("posting_date")
|
posting_date = (loan_doc.posting_date).as_("posting_date")
|
||||||
account = loan_doc.payment_account
|
account = loan_doc.payment_account
|
||||||
|
salary_condition = loan_doc.repay_from_salary == 0
|
||||||
amount = (
|
amount = (
|
||||||
frappe.qb.from_(loan_doc)
|
frappe.qb.from_(loan_doc)
|
||||||
.select(amount_field)
|
.select(amount_field)
|
||||||
.where(loan_doc.docstatus == 1)
|
.where(loan_doc.docstatus == 1)
|
||||||
|
.where(salary_condition)
|
||||||
.where(account == filters.get("account"))
|
.where(account == filters.get("account"))
|
||||||
.where(posting_date > getdate(filters.get("report_date")))
|
.where(posting_date > getdate(filters.get("report_date")))
|
||||||
.where(ifnull(loan_doc.clearance_date, "4000-01-01") <= getdate(filters.get("report_date")))
|
.where(ifnull(loan_doc.clearance_date, "4000-01-01") <= getdate(filters.get("report_date")))
|
||||||
|
|||||||
@ -262,7 +262,10 @@ def get_report_summary(summary_data, currency):
|
|||||||
def get_chart_data(columns, data):
|
def get_chart_data(columns, data):
|
||||||
labels = [d.get("label") for d in columns[2:]]
|
labels = [d.get("label") for d in columns[2:]]
|
||||||
datasets = [
|
datasets = [
|
||||||
{"name": account.get("account").replace("'", ""), "values": [account.get("total")]}
|
{
|
||||||
|
"name": account.get("account").replace("'", ""),
|
||||||
|
"values": [account.get(d.get("fieldname")) for d in columns[2:]],
|
||||||
|
}
|
||||||
for account in data
|
for account in data
|
||||||
if account.get("parent_account") == None and account.get("currency")
|
if account.get("parent_account") == None and account.get("currency")
|
||||||
]
|
]
|
||||||
|
|||||||
@ -34,6 +34,7 @@ from erpnext.accounts.doctype.pricing_rule.utils import (
|
|||||||
from erpnext.accounts.party import (
|
from erpnext.accounts.party import (
|
||||||
get_party_account,
|
get_party_account,
|
||||||
get_party_account_currency,
|
get_party_account_currency,
|
||||||
|
get_party_gle_currency,
|
||||||
validate_party_frozen_disabled,
|
validate_party_frozen_disabled,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.utils import get_account_currency, get_fiscal_years, validate_fiscal_year
|
from erpnext.accounts.utils import get_account_currency, get_fiscal_years, validate_fiscal_year
|
||||||
@ -168,6 +169,7 @@ class AccountsController(TransactionBase):
|
|||||||
|
|
||||||
self.validate_party()
|
self.validate_party()
|
||||||
self.validate_currency()
|
self.validate_currency()
|
||||||
|
self.validate_party_account_currency()
|
||||||
|
|
||||||
if self.doctype in ["Purchase Invoice", "Sales Invoice"]:
|
if self.doctype in ["Purchase Invoice", "Sales Invoice"]:
|
||||||
pos_check_field = "is_pos" if self.doctype == "Sales Invoice" else "is_paid"
|
pos_check_field = "is_pos" if self.doctype == "Sales Invoice" else "is_paid"
|
||||||
@ -1447,6 +1449,27 @@ class AccountsController(TransactionBase):
|
|||||||
# at quotation / sales order level and we shouldn't stop someone
|
# at quotation / sales order level and we shouldn't stop someone
|
||||||
# from creating a sales invoice if sales order is already created
|
# from creating a sales invoice if sales order is already created
|
||||||
|
|
||||||
|
def validate_party_account_currency(self):
|
||||||
|
if self.doctype not in ("Sales Invoice", "Purchase Invoice"):
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.is_opening == "Yes":
|
||||||
|
return
|
||||||
|
|
||||||
|
party_type, party = self.get_party()
|
||||||
|
party_gle_currency = get_party_gle_currency(party_type, party, self.company)
|
||||||
|
party_account = (
|
||||||
|
self.get("debit_to") if self.doctype == "Sales Invoice" else self.get("credit_to")
|
||||||
|
)
|
||||||
|
party_account_currency = get_account_currency(party_account)
|
||||||
|
|
||||||
|
if not party_gle_currency and (party_account_currency != self.currency):
|
||||||
|
frappe.throw(
|
||||||
|
_("Party Account {0} currency and document currency should be same").format(
|
||||||
|
frappe.bold(party_account)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def delink_advance_entries(self, linked_doc_name):
|
def delink_advance_entries(self, linked_doc_name):
|
||||||
total_allocated_amount = 0
|
total_allocated_amount = 0
|
||||||
for adv in self.advances:
|
for adv in self.advances:
|
||||||
|
|||||||
@ -448,8 +448,6 @@ class LoanRepayment(AccountsController):
|
|||||||
"remarks": remarks,
|
"remarks": remarks,
|
||||||
"cost_center": self.cost_center,
|
"cost_center": self.cost_center,
|
||||||
"posting_date": getdate(self.posting_date),
|
"posting_date": getdate(self.posting_date),
|
||||||
"party_type": self.applicant_type if self.repay_from_salary else "",
|
|
||||||
"party": self.applicant if self.repay_from_salary else "",
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -359,7 +359,7 @@ erpnext.patches.v13_0.set_work_order_qty_in_so_from_mr
|
|||||||
erpnext.patches.v13_0.update_accounts_in_loan_docs
|
erpnext.patches.v13_0.update_accounts_in_loan_docs
|
||||||
erpnext.patches.v14_0.update_batch_valuation_flag
|
erpnext.patches.v14_0.update_batch_valuation_flag
|
||||||
erpnext.patches.v14_0.delete_non_profit_doctypes
|
erpnext.patches.v14_0.delete_non_profit_doctypes
|
||||||
erpnext.patches.v14_0.update_employee_advance_status
|
erpnext.patches.v13_0.update_employee_advance_status
|
||||||
erpnext.patches.v13_0.add_cost_center_in_loans
|
erpnext.patches.v13_0.add_cost_center_in_loans
|
||||||
erpnext.patches.v13_0.set_return_against_in_pos_invoice_references
|
erpnext.patches.v13_0.set_return_against_in_pos_invoice_references
|
||||||
erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022
|
erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022
|
||||||
|
|||||||
@ -16,6 +16,7 @@ from frappe.utils import (
|
|||||||
comma_and,
|
comma_and,
|
||||||
date_diff,
|
date_diff,
|
||||||
flt,
|
flt,
|
||||||
|
get_link_to_form,
|
||||||
getdate,
|
getdate,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -45,6 +46,7 @@ class PayrollEntry(Document):
|
|||||||
|
|
||||||
def before_submit(self):
|
def before_submit(self):
|
||||||
self.validate_employee_details()
|
self.validate_employee_details()
|
||||||
|
self.validate_payroll_payable_account()
|
||||||
if self.validate_attendance:
|
if self.validate_attendance:
|
||||||
if self.validate_employee_attendance():
|
if self.validate_employee_attendance():
|
||||||
frappe.throw(_("Cannot Submit, Employees left to mark attendance"))
|
frappe.throw(_("Cannot Submit, Employees left to mark attendance"))
|
||||||
@ -66,6 +68,14 @@ class PayrollEntry(Document):
|
|||||||
if len(emp_with_sal_slip):
|
if len(emp_with_sal_slip):
|
||||||
frappe.throw(_("Salary Slip already exists for {0}").format(comma_and(emp_with_sal_slip)))
|
frappe.throw(_("Salary Slip already exists for {0}").format(comma_and(emp_with_sal_slip)))
|
||||||
|
|
||||||
|
def validate_payroll_payable_account(self):
|
||||||
|
if frappe.db.get_value("Account", self.payroll_payable_account, "account_type"):
|
||||||
|
frappe.throw(
|
||||||
|
_(
|
||||||
|
"Account type cannot be set for payroll payable account {0}, please remove and try again"
|
||||||
|
).format(frappe.bold(get_link_to_form("Account", self.payroll_payable_account)))
|
||||||
|
)
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
frappe.delete_doc(
|
frappe.delete_doc(
|
||||||
"Salary Slip",
|
"Salary Slip",
|
||||||
|
|||||||
@ -234,7 +234,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "actual_start_date",
|
"fieldname": "actual_start_date",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Date",
|
||||||
"label": "Actual Start Date (via Time Sheet)",
|
"label": "Actual Start Date (via Time Sheet)",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@ -458,7 +458,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"max_attachments": 4,
|
"max_attachments": 4,
|
||||||
"modified": "2022-01-29 13:58:27.712714",
|
"modified": "2022-05-25 22:45:06.108499",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Project",
|
"name": "Project",
|
||||||
|
|||||||
@ -789,11 +789,23 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
if(this.frm.doc.is_pos && (update_paid_amount===undefined || update_paid_amount)) {
|
if(this.frm.doc.is_pos && (update_paid_amount===undefined || update_paid_amount)) {
|
||||||
$.each(this.frm.doc['payments'] || [], function(index, data) {
|
$.each(this.frm.doc['payments'] || [], function(index, data) {
|
||||||
if(data.default && payment_status && total_amount_to_pay > 0) {
|
if(data.default && payment_status && total_amount_to_pay > 0) {
|
||||||
let base_amount = flt(total_amount_to_pay, precision("base_amount", data));
|
let base_amount, amount;
|
||||||
|
|
||||||
|
if (me.frm.doc.party_account_currency == me.frm.doc.currency) {
|
||||||
|
// if customer/supplier currency is same as company currency
|
||||||
|
// total_amount_to_pay is already in customer/supplier currency
|
||||||
|
// so base_amount has to be calculated using total_amount_to_pay
|
||||||
|
base_amount = flt(total_amount_to_pay * me.frm.doc.conversion_rate, precision("base_amount", data));
|
||||||
|
amount = flt(total_amount_to_pay, precision("amount", data));
|
||||||
|
} else {
|
||||||
|
base_amount = flt(total_amount_to_pay, precision("base_amount", data));
|
||||||
|
amount = flt(total_amount_to_pay / me.frm.doc.conversion_rate, precision("amount", data));
|
||||||
|
}
|
||||||
|
|
||||||
frappe.model.set_value(data.doctype, data.name, "base_amount", base_amount);
|
frappe.model.set_value(data.doctype, data.name, "base_amount", base_amount);
|
||||||
let amount = flt(total_amount_to_pay / me.frm.doc.conversion_rate, precision("amount", data));
|
|
||||||
frappe.model.set_value(data.doctype, data.name, "amount", amount);
|
frappe.model.set_value(data.doctype, data.name, "amount", amount);
|
||||||
payment_status = false;
|
payment_status = false;
|
||||||
|
|
||||||
} else if(me.frm.doc.paid_amount) {
|
} else if(me.frm.doc.paid_amount) {
|
||||||
frappe.model.set_value(data.doctype, data.name, "amount", 0.0);
|
frappe.model.set_value(data.doctype, data.name, "amount", 0.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ erpnext.setup_auto_gst_taxation = (doctype) => {
|
|||||||
'shipping_address': frm.doc.shipping_address || '',
|
'shipping_address': frm.doc.shipping_address || '',
|
||||||
'shipping_address_name': frm.doc.shipping_address_name || '',
|
'shipping_address_name': frm.doc.shipping_address_name || '',
|
||||||
'customer_address': frm.doc.customer_address || '',
|
'customer_address': frm.doc.customer_address || '',
|
||||||
|
'company_address': frm.doc.company_address,
|
||||||
'supplier_address': frm.doc.supplier_address,
|
'supplier_address': frm.doc.supplier_address,
|
||||||
'customer': frm.doc.customer,
|
'customer': frm.doc.customer,
|
||||||
'supplier': frm.doc.supplier,
|
'supplier': frm.doc.supplier,
|
||||||
|
|||||||
@ -448,7 +448,7 @@ class Gstr1Report(object):
|
|||||||
hsn_code = self.item_hsn_map.get(item_code)
|
hsn_code = self.item_hsn_map.get(item_code)
|
||||||
tax_rate = 0
|
tax_rate = 0
|
||||||
taxable_value = items.get(item_code)
|
taxable_value = items.get(item_code)
|
||||||
for rates in hsn_wise_tax_rate.get(hsn_code):
|
for rates in hsn_wise_tax_rate.get(hsn_code, []):
|
||||||
if taxable_value > rates.get("minimum_taxable_value"):
|
if taxable_value > rates.get("minimum_taxable_value"):
|
||||||
tax_rate = rates.get("tax_rate")
|
tax_rate = rates.get("tax_rate")
|
||||||
|
|
||||||
|
|||||||
@ -1285,6 +1285,14 @@ class TestPurchaseReceipt(FrappeTestCase):
|
|||||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import (
|
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import (
|
||||||
make_purchase_invoice as create_purchase_invoice,
|
make_purchase_invoice as create_purchase_invoice,
|
||||||
)
|
)
|
||||||
|
from erpnext.accounts.party import add_party_account
|
||||||
|
|
||||||
|
add_party_account(
|
||||||
|
"Supplier",
|
||||||
|
"_Test Supplier USD",
|
||||||
|
"_Test Company with perpetual inventory",
|
||||||
|
"_Test Payable USD - TCP1",
|
||||||
|
)
|
||||||
|
|
||||||
pi = create_purchase_invoice(
|
pi = create_purchase_invoice(
|
||||||
company="_Test Company with perpetual inventory",
|
company="_Test Company with perpetual inventory",
|
||||||
@ -1293,6 +1301,7 @@ class TestPurchaseReceipt(FrappeTestCase):
|
|||||||
expense_account="_Test Account Cost for Goods Sold - TCP1",
|
expense_account="_Test Account Cost for Goods Sold - TCP1",
|
||||||
currency="USD",
|
currency="USD",
|
||||||
conversion_rate=70,
|
conversion_rate=70,
|
||||||
|
supplier="_Test Supplier USD",
|
||||||
)
|
)
|
||||||
|
|
||||||
pr = create_purchase_receipt(pi.name)
|
pr = create_purchase_receipt(pi.name)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user