Employee Benefit (#14571)
* Rename - filed is_pro_rata_applicable to pay_against_benefit_claim * Employee Benefit Application - Validate previous benefit claim * Employee Benefit Claim - Code refactor * Salary Slip - additional salary - fix
This commit is contained in:
parent
c526cad183
commit
55a2f4da71
@ -78,7 +78,7 @@ var calculate_all = function(doc) {
|
||||
if(cint(tbl[i].amount) > 0) {
|
||||
total_amount += flt(tbl[i].amount);
|
||||
}
|
||||
if(tbl[i].is_pro_rata_applicable == 1){
|
||||
if(tbl[i].pay_against_benefit_claim != 1){
|
||||
pro_rata_dispensed_amount += flt(tbl[i].amount);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ from frappe.utils import date_diff, getdate, rounded, add_days, cstr, cint
|
||||
from frappe.model.document import Document
|
||||
from erpnext.hr.doctype.payroll_period.payroll_period import get_payroll_period_days
|
||||
from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure
|
||||
from erpnext.hr.utils import get_sal_slip_total_benefit_given, get_holidays_for_employee
|
||||
from erpnext.hr.utils import get_sal_slip_total_benefit_given, get_holidays_for_employee, get_previous_claimed_amount
|
||||
|
||||
class EmployeeBenefitApplication(Document):
|
||||
def validate(self):
|
||||
@ -17,9 +17,22 @@ class EmployeeBenefitApplication(Document):
|
||||
if self.max_benefits <= 0:
|
||||
frappe.throw(_("Employee {0} has no maximum benefit amount").format(self.employee))
|
||||
self.validate_max_benefit_for_component()
|
||||
self.validate_prev_benefit_claim()
|
||||
if self.remainig_benefits > 0:
|
||||
self.validate_remaining_benefit_amount()
|
||||
|
||||
def validate_prev_benefit_claim(self):
|
||||
if self.employee_benefits:
|
||||
for benefit in self.employee_benefits:
|
||||
if benefit.pay_against_benefit_claim == 1:
|
||||
payroll_period = frappe.get_doc("Payroll Period", self.payroll_period)
|
||||
benefit_claimed = get_previous_claimed_amount(self.employee, payroll_period, component = benefit.earning_component)
|
||||
benefit_given = get_sal_slip_total_benefit_given(self.employee, payroll_period, component = benefit.earning_component)
|
||||
benefit_claim_remining = benefit_claimed - benefit_given
|
||||
if benefit_claimed > 0 and benefit_claim_remining > benefit.amount:
|
||||
frappe.throw(_("An amount of {0} already claimed for the component {1},\
|
||||
set the amount equal or greater than {2}").format(benefit_claimed, benefit.earning_component, benefit_claim_remining))
|
||||
|
||||
def validate_remaining_benefit_amount(self):
|
||||
# check salary structure earnings have flexi component (sum of max_benefit_amount)
|
||||
# without pro-rata which satisfy the remainig_benefits
|
||||
@ -37,8 +50,8 @@ class EmployeeBenefitApplication(Document):
|
||||
if salary_structure.earnings:
|
||||
for earnings in salary_structure.earnings:
|
||||
if earnings.is_flexible_benefit == 1 and earnings.salary_component not in benefit_components:
|
||||
is_pro_rata_applicable, max_benefit_amount = frappe.db.get_value("Salary Component", earnings.salary_component, ["is_pro_rata_applicable", "max_benefit_amount"])
|
||||
if is_pro_rata_applicable == 1:
|
||||
pay_against_benefit_claim, max_benefit_amount = frappe.db.get_value("Salary Component", earnings.salary_component, ["pay_against_benefit_claim", "max_benefit_amount"])
|
||||
if pay_against_benefit_claim != 1:
|
||||
pro_rata_amount += max_benefit_amount
|
||||
else:
|
||||
non_pro_rata_amount += max_benefit_amount
|
||||
@ -113,7 +126,7 @@ def get_max_benefits_remaining(employee, on_date, payroll_period):
|
||||
sal_struct = frappe.get_doc("Salary Structure", sal_struct_name)
|
||||
for sal_struct_row in sal_struct.get("earnings"):
|
||||
salary_component = frappe.get_doc("Salary Component", sal_struct_row.salary_component)
|
||||
if salary_component.depends_on_lwp == 1 and salary_component.is_pro_rata_applicable == 1:
|
||||
if salary_component.depends_on_lwp == 1 and salary_component.pay_against_benefit_claim != 1:
|
||||
have_depends_on_lwp = True
|
||||
benefit_amount = get_benefit_pro_rata_ratio_amount(sal_struct, salary_component.max_benefit_amount)
|
||||
amount_per_day = benefit_amount / payroll_period_days
|
||||
@ -188,8 +201,8 @@ def get_benefit_pro_rata_ratio_amount(sal_struct, component_max):
|
||||
total_pro_rata_max = 0
|
||||
benefit_amount = 0
|
||||
for sal_struct_row in sal_struct.get("earnings"):
|
||||
is_pro_rata_applicable, max_benefit_amount = frappe.db.get_value("Salary Component", sal_struct_row.salary_component, ["is_pro_rata_applicable", "max_benefit_amount"])
|
||||
if sal_struct_row.is_flexible_benefit == 1 and is_pro_rata_applicable == 1:
|
||||
pay_against_benefit_claim, max_benefit_amount = frappe.db.get_value("Salary Component", sal_struct_row.salary_component, ["pay_against_benefit_claim", "max_benefit_amount"])
|
||||
if sal_struct_row.is_flexible_benefit == 1 and pay_against_benefit_claim != 1:
|
||||
total_pro_rata_max += max_benefit_amount
|
||||
if total_pro_rata_max > 0:
|
||||
benefit_amount = component_max * sal_struct.max_benefits / total_pro_rata_max
|
||||
|
@ -53,8 +53,8 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_from": "earning_component.is_pro_rata_applicable",
|
||||
"fieldname": "is_pro_rata_applicable",
|
||||
"fetch_from": "earning_component.pay_against_benefit_claim",
|
||||
"fieldname": "pay_against_benefit_claim",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -63,7 +63,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Is Pro-rata Applicable",
|
||||
"label": "Pay Against Benefit Claim",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
@ -157,7 +157,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-05-26 12:00:37.588822",
|
||||
"modified": "2018-06-13 17:34:57.783584",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Employee Benefit Application Detail",
|
||||
|
@ -43,7 +43,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -77,7 +77,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -87,38 +87,39 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_from": "employee.department",
|
||||
"fieldname": "department",
|
||||
"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": "Department",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Department",
|
||||
"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,
|
||||
"fetch_from": "employee.department",
|
||||
"fieldname": "department",
|
||||
"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": "Department",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Department",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Today",
|
||||
"fieldname": "claim_date",
|
||||
@ -143,7 +144,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -174,7 +175,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -207,7 +208,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -241,7 +242,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -251,8 +252,8 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_from": "earning_component.is_pro_rata_applicable",
|
||||
"fieldname": "is_pro_rata_applicable",
|
||||
"fetch_from": "earning_component.pay_against_benefit_claim",
|
||||
"fieldname": "pay_against_benefit_claim",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -261,7 +262,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Is Pro-Rata Applicable",
|
||||
"label": "Pay Against Benefit Claim",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
@ -269,7 +270,7 @@
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
@ -307,7 +308,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -340,7 +341,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -372,7 +373,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -403,7 +404,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -435,7 +436,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -449,7 +450,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-05-26 12:43:21.082282",
|
||||
"modified": "2018-06-18 11:14:59.895298",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Employee Benefit Claim",
|
||||
@ -542,4 +543,4 @@
|
||||
"title_field": "employee_name",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from erpnext.hr.doctype.employee_benefit_application.employee_benefit_application import get_max_benefits
|
||||
from erpnext.hr.utils import get_payroll_period
|
||||
from erpnext.hr.utils import get_payroll_period, get_previous_claimed_amount
|
||||
from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure
|
||||
|
||||
class EmployeeBenefitClaim(Document):
|
||||
@ -21,12 +21,12 @@ class EmployeeBenefitClaim(Document):
|
||||
self.validate_max_benefit_for_component(payroll_period)
|
||||
self.validate_max_benefit_for_sal_struct(max_benefits)
|
||||
self.validate_benefit_claim_amount(max_benefits, payroll_period)
|
||||
if not self.is_pro_rata_applicable:
|
||||
if self.pay_against_benefit_claim:
|
||||
self.validate_non_pro_rata_benefit_claim(max_benefits, payroll_period)
|
||||
|
||||
def validate_benefit_claim_amount(self, max_benefits, payroll_period):
|
||||
claimed_amount = self.claimed_amount
|
||||
claimed_amount += self.get_previous_claimed_amount(payroll_period)
|
||||
claimed_amount += get_previous_claimed_amount(self.employee, payroll_period)
|
||||
if max_benefits < claimed_amount:
|
||||
frappe.throw(_("Maximum benefit of employee {0} exceeds {1} by the sum {2} of previous claimed\
|
||||
amount").format(self.employee, max_benefits, claimed_amount-max_benefits))
|
||||
@ -37,7 +37,7 @@ class EmployeeBenefitClaim(Document):
|
||||
|
||||
def validate_max_benefit_for_component(self, payroll_period):
|
||||
claimed_amount = self.claimed_amount
|
||||
claimed_amount += self.get_previous_claimed_amount(payroll_period, self.earning_component)
|
||||
claimed_amount += get_previous_claimed_amount(self.employee, payroll_period, component = self.earning_component)
|
||||
if claimed_amount > self.max_amount_eligible:
|
||||
frappe.throw(_("Maximum amount eligible for the component {0} exceeds {1}").format(self.earning_component, self.max_amount_eligible))
|
||||
|
||||
@ -51,7 +51,7 @@ class EmployeeBenefitClaim(Document):
|
||||
if not pro_rata_amount:
|
||||
pro_rata_amount = 0
|
||||
|
||||
claimed_amount += self.get_previous_claimed_amount(payroll_period, True)
|
||||
claimed_amount += get_previous_claimed_amount(self.employee, payroll_period, non_pro_rata = True)
|
||||
if max_benefits < pro_rata_amount + claimed_amount:
|
||||
frappe.throw(_("Maximum benefit of employee {0} exceeds {1} by the sum {2} of benefit application pro-rata component\
|
||||
amount and previous claimed amount").format(self.employee, max_benefits, pro_rata_amount+claimed_amount-max_benefits))
|
||||
@ -63,13 +63,13 @@ class EmployeeBenefitClaim(Document):
|
||||
total_pro_rata_max = 0
|
||||
benefit_amount_total = 0
|
||||
for sal_struct_row in sal_struct.get("earnings"):
|
||||
is_pro_rata_applicable, max_benefit_amount = frappe.db.get_value("Salary Component", sal_struct_row.salary_component, ["is_pro_rata_applicable", "max_benefit_amount"])
|
||||
if sal_struct_row.is_flexible_benefit == 1 and is_pro_rata_applicable == 1:
|
||||
pay_against_benefit_claim, max_benefit_amount = frappe.db.get_value("Salary Component", sal_struct_row.salary_component, ["pay_against_benefit_claim", "max_benefit_amount"])
|
||||
if sal_struct_row.is_flexible_benefit == 1 and pay_against_benefit_claim != 1:
|
||||
total_pro_rata_max += max_benefit_amount
|
||||
if total_pro_rata_max > 0:
|
||||
for sal_struct_row in sal_struct.get("earnings"):
|
||||
is_pro_rata_applicable, max_benefit_amount = frappe.db.get_value("Salary Component", sal_struct_row.salary_component, ["is_pro_rata_applicable", "max_benefit_amount"])
|
||||
if sal_struct_row.is_flexible_benefit == 1 and is_pro_rata_applicable == 1:
|
||||
pay_against_benefit_claim, max_benefit_amount = frappe.db.get_value("Salary Component", sal_struct_row.salary_component, ["pay_against_benefit_claim", "max_benefit_amount"])
|
||||
if sal_struct_row.is_flexible_benefit == 1 and pay_against_benefit_claim != 1:
|
||||
component_max = max_benefit_amount
|
||||
benefit_amount = component_max * sal_struct.max_benefits / total_pro_rata_max
|
||||
if benefit_amount > component_max:
|
||||
@ -91,35 +91,11 @@ class EmployeeBenefitClaim(Document):
|
||||
return frappe.db.get_value("Employee Benefit Application", application, "pro_rata_dispensed_amount")
|
||||
return False
|
||||
|
||||
def get_previous_claimed_amount(self, payroll_period, non_pro_rata=False, component=False):
|
||||
total_claimed_amount = 0
|
||||
query = """
|
||||
select sum(claimed_amount) as 'total_amount'
|
||||
from `tabEmployee Benefit Claim`
|
||||
where employee=%(employee)s
|
||||
and docstatus = 1
|
||||
and (claim_date between %(start_date)s and %(end_date)s)
|
||||
"""
|
||||
if non_pro_rata:
|
||||
query += "and is_pro_rata_applicable = 0"
|
||||
if component:
|
||||
query += "and earning_component = %(component)s"
|
||||
|
||||
sum_of_claimed_amount = frappe.db.sql(query, {
|
||||
'employee': self.employee,
|
||||
'start_date': payroll_period.start_date,
|
||||
'end_date': payroll_period.end_date,
|
||||
'component': component
|
||||
}, as_dict=True)
|
||||
if sum_of_claimed_amount and sum_of_claimed_amount[0].total_amount > 0:
|
||||
total_claimed_amount = sum_of_claimed_amount[0].total_amount
|
||||
return total_claimed_amount
|
||||
|
||||
def get_benefit_claim_amount(employee, start_date, end_date, struct_row):
|
||||
benefit_claim_details = frappe.db.sql("""
|
||||
select claimed_amount from `tabEmployee Benefit Claim`
|
||||
where employee=%(employee)s
|
||||
and docstatus = 1 and is_pro_rata_applicable = 0
|
||||
and docstatus = 1 and pay_against_benefit_claim = 1
|
||||
and earning_component = %(earning_component)s
|
||||
and (claim_date between %(start_date)s and %(end_date)s)
|
||||
""", {
|
||||
|
@ -540,7 +540,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "is_flexible_benefit",
|
||||
"fieldname": "is_pro_rata_applicable",
|
||||
"fieldname": "pay_against_benefit_claim",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -549,7 +549,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Is Pro-rata Applicable",
|
||||
"label": "Pay Against Benefit Claim",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@ -1002,7 +1002,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-06-19 11:37:27.521796",
|
||||
"modified": "2018-06-19 11:37:37.521796",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Salary Component",
|
||||
|
@ -87,7 +87,7 @@ class SalarySlip(TransactionBase):
|
||||
self.update_component_row(frappe._dict(tax_row), amount, "deductions")
|
||||
|
||||
def add_employee_flexi_benefits(self, struct_row):
|
||||
if frappe.db.get_value("Salary Component", struct_row.salary_component, "is_pro_rata_applicable") == 1:
|
||||
if frappe.db.get_value("Salary Component", struct_row.salary_component, "pay_against_benefit_claim") != 1:
|
||||
benefit_component_amount = get_benefit_component_amount(self.employee, self.start_date, self.end_date, struct_row, self._salary_structure_doc, self.payment_days, self.total_working_days)
|
||||
if benefit_component_amount:
|
||||
self.update_component_row(struct_row, benefit_component_amount, "earnings")
|
||||
|
@ -353,3 +353,27 @@ def calculate_hra_exemption_for_period(doc):
|
||||
# Don't delete this method, used for localization
|
||||
# Indian HRA Exemption Calculation
|
||||
return {}
|
||||
|
||||
def get_previous_claimed_amount(employee, payroll_period, non_pro_rata=False, component=False):
|
||||
total_claimed_amount = 0
|
||||
query = """
|
||||
select sum(claimed_amount) as 'total_amount'
|
||||
from `tabEmployee Benefit Claim`
|
||||
where employee=%(employee)s
|
||||
and docstatus = 1
|
||||
and (claim_date between %(start_date)s and %(end_date)s)
|
||||
"""
|
||||
if non_pro_rata:
|
||||
query += "and pay_against_benefit_claim = 1"
|
||||
if component:
|
||||
query += "and earning_component = %(component)s"
|
||||
|
||||
sum_of_claimed_amount = frappe.db.sql(query, {
|
||||
'employee': employee,
|
||||
'start_date': payroll_period.start_date,
|
||||
'end_date': payroll_period.end_date,
|
||||
'component': component
|
||||
}, as_dict=True)
|
||||
if sum_of_claimed_amount and sum_of_claimed_amount[0].total_amount > 0:
|
||||
total_claimed_amount = sum_of_claimed_amount[0].total_amount
|
||||
return total_claimed_amount
|
||||
|
Loading…
Reference in New Issue
Block a user