mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-27 00:44:45 +00:00
feat: sales commission payout
This commit is contained in:
@@ -73,26 +73,11 @@ class ProcessSalesCommission(Document):
|
|||||||
doc.to_date = self.to_date
|
doc.to_date = self.to_date
|
||||||
doc.pay_via_salary = self.pay_via_salary
|
doc.pay_via_salary = self.pay_via_salary
|
||||||
doc.process_sales_commission_reference = self.name
|
doc.process_sales_commission_reference = self.name
|
||||||
doc.set("contributions", [])
|
doc.add_contributions()
|
||||||
self.add_contributions(doc, sales_persons_details_map[record], filter_date)
|
|
||||||
doc.insert()
|
doc.insert()
|
||||||
if not frappe.db.get_single_value("Selling Settings", "approval_required_for_sales_commission_payout"):
|
if not frappe.db.get_single_value("Selling Settings", "approval_required_for_sales_commission_payout"):
|
||||||
doc.reload()
|
doc.reload()
|
||||||
if self.pay_via_salary and doc.employee:
|
if self.pay_via_salary and doc.employee:
|
||||||
if frappe.db.exists('Salary Structure Assignment', {'employee': doc.employee}):
|
if frappe.db.exists('Salary Structure Assignment', {'employee': doc.employee}):
|
||||||
doc.submit()
|
doc.submit()
|
||||||
|
doc.payout_entry()
|
||||||
def add_contributions(self, doc, records, filter_date):
|
|
||||||
for items in records:
|
|
||||||
sales_record_details = frappe.db.get_value(self.commission_based_on, filters={"name": items["parent"]}, fieldname=["customer", filter_date], as_dict=True)
|
|
||||||
contribution = {
|
|
||||||
"document_type": self.commission_based_on,
|
|
||||||
"order_or_invoice": items["parent"],
|
|
||||||
"customer": sales_record_details["customer"],
|
|
||||||
"posting_date": sales_record_details[filter_date],
|
|
||||||
"contribution_percent": items["allocated_percentage"],
|
|
||||||
"contribution_amount": items["allocated_amount"],
|
|
||||||
"commission_rate": items["commission_rate"],
|
|
||||||
"commission_amount": items["incentives"],
|
|
||||||
}
|
|
||||||
doc.append("contributions", contribution)
|
|
||||||
@@ -18,6 +18,18 @@ frappe.ui.form.on('Sales Commission', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get_contributions: function (frm) {
|
||||||
|
frm.clear_table("contributions");
|
||||||
|
return frappe.call({
|
||||||
|
doc: frm.doc,
|
||||||
|
method: 'add_contributions',
|
||||||
|
}).then(r => {
|
||||||
|
frm.dirty();
|
||||||
|
frm.save();
|
||||||
|
frm.refresh();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
add_context_buttons: function (frm) {
|
add_context_buttons: function (frm) {
|
||||||
if (!frm.doc.reference_name) {
|
if (!frm.doc.reference_name) {
|
||||||
if (frm.doc.pay_via_salary) {
|
if (frm.doc.pay_via_salary) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"commission_based_on",
|
"commission_based_on",
|
||||||
"process_sales_commission_reference",
|
"process_sales_commission_reference",
|
||||||
"section_break_15",
|
"section_break_15",
|
||||||
|
"get_contributions",
|
||||||
"contributions",
|
"contributions",
|
||||||
"section_break_17",
|
"section_break_17",
|
||||||
"total_contribution",
|
"total_contribution",
|
||||||
@@ -208,12 +209,18 @@
|
|||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Reference Name",
|
"label": "Reference Name",
|
||||||
"options": "reference_doctype"
|
"options": "reference_doctype"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.docstatus==0",
|
||||||
|
"fieldname": "get_contributions",
|
||||||
|
"fieldtype": "Button",
|
||||||
|
"label": "Get Contributions"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-09-20 15:46:26.805073",
|
"modified": "2021-09-30 15:52:00.814442",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Payroll",
|
"module": "Payroll",
|
||||||
"name": "Sales Commission",
|
"name": "Sales Commission",
|
||||||
|
|||||||
@@ -21,6 +21,28 @@ class SalesCommission(Document):
|
|||||||
if not frappe.db.get_single_value("Payroll Settings", "salary_component_for_sales_commission"):
|
if not frappe.db.get_single_value("Payroll Settings", "salary_component_for_sales_commission"):
|
||||||
frappe.throw(_("Please set {0} in {1}").format(frappe.bold("Salary Component for Sales Commission"), get_link_to_form("Payroll Settings", "Payroll Settings")))
|
frappe.throw(_("Please set {0} in {1}").format(frappe.bold("Salary Component for Sales Commission"), get_link_to_form("Payroll Settings", "Payroll Settings")))
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def add_contributions(self):
|
||||||
|
self.set("contributions", [])
|
||||||
|
filter_date = "transaction_date" if self.commission_based_on=="Sales Order" else "posting_date"
|
||||||
|
records = [entry.name for entry in frappe.db.get_all(self.commission_based_on, filters={"company": self.company, filter_date: ('between', [self.from_date, self.to_date])})]
|
||||||
|
sales_persons_details = frappe.get_all("Sales Team", filters={"parent": ['in', records], "sales_person": self.sales_person}, fields=["sales_person", "commission_rate", "incentives", "allocated_percentage", "allocated_amount", "parent"])
|
||||||
|
if sales_persons_details:
|
||||||
|
for record in sales_persons_details:
|
||||||
|
if add(record, self.sales_person):
|
||||||
|
record_details = frappe.db.get_value(self.commission_based_on, filters={"name": record["parent"]}, fieldname=["customer", filter_date], as_dict=True)
|
||||||
|
contribution = {
|
||||||
|
"document_type": self.commission_based_on,
|
||||||
|
"order_or_invoice": record["parent"],
|
||||||
|
"customer": record_details["customer"],
|
||||||
|
"posting_date": record_details[filter_date],
|
||||||
|
"contribution_percent": record["allocated_percentage"],
|
||||||
|
"contribution_amount": record["allocated_amount"],
|
||||||
|
"commission_rate": record["commission_rate"],
|
||||||
|
"commission_amount": record["incentives"],
|
||||||
|
}
|
||||||
|
self.append("contributions", contribution)
|
||||||
|
|
||||||
def calculate_total_contribution_and_total_commission_amount(self):
|
def calculate_total_contribution_and_total_commission_amount(self):
|
||||||
total_contribution, total_commission_amount = 0,0
|
total_contribution, total_commission_amount = 0,0
|
||||||
for entry in self.contributions:
|
for entry in self.contributions:
|
||||||
@@ -34,14 +56,6 @@ class SalesCommission(Document):
|
|||||||
self.total_contribution = total_contribution
|
self.total_contribution = total_contribution
|
||||||
self.total_commission_amount = total_commission_amount
|
self.total_commission_amount = total_commission_amount
|
||||||
|
|
||||||
def on_submit(self):
|
|
||||||
if not self.employee:
|
|
||||||
frappe.throw(_("No employee is linked to Sales Person: {0}. Please select an employee for {1} to submit this document.").format(frappe.bold(self.sales_person), get_link_to_form("Sales Person", self.sales_person)))
|
|
||||||
if self.pay_via_salary:
|
|
||||||
self.make_additional_salary()
|
|
||||||
else:
|
|
||||||
self.make_payment_entry()
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def payout_entry(self, mode_of_payment=None):
|
def payout_entry(self, mode_of_payment=None):
|
||||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
|
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
|
||||||
@@ -56,11 +70,12 @@ class SalesCommission(Document):
|
|||||||
else:
|
else:
|
||||||
self.make_payment_entry(mode_of_payment, paid_from, paid_to)
|
self.make_payment_entry(mode_of_payment, paid_from, paid_to)
|
||||||
|
|
||||||
|
|
||||||
def make_additional_salary(self):
|
def make_additional_salary(self):
|
||||||
|
currency = frappe.get_value("Company", self.company, "default_currency")
|
||||||
doc = frappe.new_doc("Additional Salary")
|
doc = frappe.new_doc("Additional Salary")
|
||||||
doc.employee = self.employee
|
doc.employee = self.employee
|
||||||
doc.company = self.company
|
doc.company = self.company
|
||||||
|
doc.currency = currency
|
||||||
doc.salary_component = frappe.db.get_single_value("Payroll Settings", "salary_component_for_sales_commission")
|
doc.salary_component = frappe.db.get_single_value("Payroll Settings", "salary_component_for_sales_commission")
|
||||||
doc.payroll_date = self.to_date
|
doc.payroll_date = self.to_date
|
||||||
doc.amount = self.total_commission_amount
|
doc.amount = self.total_commission_amount
|
||||||
@@ -100,4 +115,12 @@ class SalesCommission(Document):
|
|||||||
reference['total_amount'] = self.total_commission_amount
|
reference['total_amount'] = self.total_commission_amount
|
||||||
reference['outstanding_amount'] = self.total_commission_amount
|
reference['outstanding_amount'] = self.total_commission_amount
|
||||||
reference['allocated_amount'] = self.total_commission_amount
|
reference['allocated_amount'] = self.total_commission_amount
|
||||||
doc.append("references", reference)
|
doc.append("references", reference)
|
||||||
|
|
||||||
|
def add(record, sales_person):
|
||||||
|
previous_contibutions = frappe.get_all("Contributions", filters={"order_or_invoice":record["parent"], "docstatus":["!=", 2]}, fields=["parent"])
|
||||||
|
if previous_contibutions:
|
||||||
|
for contributions in previous_contibutions:
|
||||||
|
if frappe.db.get_value("Sales Commission", {"name":contributions["parent"]}, fieldname=["sales_person"]) == sales_person:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
Reference in New Issue
Block a user