4
4
import frappe
5
5
import erpnext
6
6
from frappe import _
7
- from frappe .utils import get_link_to_form
7
+ from frappe .utils import get_link_to_form , flt , nowdate
8
8
from erpnext .accounts .general_ledger import make_gl_entries
9
9
from erpnext .controllers .accounts_controller import (
10
10
AccountsController ,
13
13
class SalesCommission (AccountsController ):
14
14
def validate (self ):
15
15
self .validate_from_to_dates ()
16
-
16
+ self . validate_omit_transaction_duplicates ()
17
17
self .validate_salary_component ()
18
18
self .calculate_total_contribution_and_total_commission_amount ()
19
19
self .create_employee ()
20
20
21
21
def validate_from_to_dates (self ):
22
22
return super ().validate_from_to_dates ("from_date" , "to_date" )
23
23
24
+ def validate_omit_transaction_duplicates (self ):
25
+ # TODO chequear por solapamiento de fechas
26
+ if not self .omit_sales_person_transactions :
27
+ return
28
+
29
+ previous_contibutions = frappe .get_all (
30
+ "Sales Commission" ,
31
+ filters = {
32
+ "sales_person" : self .sales_person ,
33
+ "docstatus" : 1 ,
34
+ "from_date" : self .from_date ,
35
+ "to_date" : self .to_date ,
36
+ },
37
+ pluck = "name"
38
+ )
39
+ if previous_contibutions :
40
+ frappe .throw (_ ("Este vendedor ya tiene liquidado ventas en el período seleccionado" ))
41
+
24
42
def validate_amount (self ):
25
43
if self .total_commission_amount <= 0 :
26
44
frappe .throw (_ ("Total Commission Amount should be greater than 0" ))
@@ -46,15 +64,15 @@ def make_gl_entries(self, cancel=False):
46
64
def get_gl_entries (self ):
47
65
gl_entry = []
48
66
49
- sales_commission_expense_account = frappe .get_value ("Company" , self .company , "sales_commission_expense_account" ) # DEBIT
50
- payment_account_sales_commission = frappe .get_value ("Company" , self .company , "payment_account_sales_commission" ) # CREDIT
67
+ sales_commission_expense_account = frappe .get_value ("Company" , self .company , "sales_commission_expense_account" )
68
+ payment_account_sales_commission = frappe .get_value ("Company" , self .company , "payment_account_sales_commission" )
51
69
52
70
if not sales_commission_expense_account or not payment_account_sales_commission :
53
71
frappe .throw (_ ("Debe configurar la Cuenta de Pago Comisión Vendedores y la Cuenta de Gastos Comisión Vendedores en la Compañia." ))
54
72
55
73
gl_entry .append (
56
74
self .get_gl_dict ({
57
- "posting_date" : self . creation . date (),
75
+ "posting_date" : nowdate (),
58
76
"account" : payment_account_sales_commission ,
59
77
"credit" : self .total_commission_amount ,
60
78
"credit_in_account_currency" : self .total_commission_amount ,
@@ -69,7 +87,7 @@ def get_gl_entries(self):
69
87
70
88
gl_entry .append (
71
89
self .get_gl_dict ({
72
- "posting_date" : self . creation . date (),
90
+ "posting_date" : nowdate (),
73
91
"account" : sales_commission_expense_account ,
74
92
"debit" : self .total_commission_amount ,
75
93
"debit_in_account_currency" : self .total_commission_amount ,
@@ -86,28 +104,69 @@ def add_contributions(self, process_sales_commission):
86
104
self .set ("contributions" , [])
87
105
filter_date = "transaction_date" if self .commission_based_on == "Sales Order" else "posting_date"
88
106
customer_field = "customer" if self .commission_based_on != "Payment Entry" else "party"
89
- records = [entry .name for entry in frappe .db .get_all (self .commission_based_on , filters = {"company" : self .company , "docstatus" : 1 , filter_date : ('between' , [self .from_date , self .to_date ])})]
90
- sales_persons_details = frappe .get_all (
91
- "Sales Team" , filters = {"parent" : ['in' , records ], "sales_person" : self .sales_person },
92
- fields = ["sales_person" , "commission_rate" , "incentives" , "allocated_percentage" , "allocated_amount" , "parent" ])
93
- if sales_persons_details :
94
- for record in sales_persons_details :
95
- if add_record (record , self .sales_person ):
96
- record_details = frappe .db .get_value (self .commission_based_on , filters = {"name" : record ["parent" ]}, fieldname = [customer_field , filter_date ], as_dict = True )
97
- contribution = {
98
- "document_type" : self .commission_based_on ,
99
- "order_or_invoice" : record ["parent" ],
100
- "customer" : record_details .get (customer_field ),
101
- "posting_date" : record_details [filter_date ],
102
- "contribution_percent" : record ["allocated_percentage" ],
103
- "contribution_amount" : record ["allocated_amount" ],
104
- "commission_rate" : record ["commission_rate" ],
105
- "commission_amount" : record ["incentives" ],
106
- "process_sales_commission" : process_sales_commission ,
107
- }
108
- self .append ("contributions" , contribution )
107
+
108
+ if self .omit_sales_person_transactions :
109
+ filter_fieldname = self .get_filter_commission_against_field ()
110
+ filter_value = self .commission_against_filter
111
+ commission_rate = frappe .get_value ("Sales Person" , self .sales_person , "commission_rate" )
112
+ filter_value_sql = f"AND { filter_fieldname } = '{ filter_value } '" if filter_fieldname and filter_value else ""
113
+ records = frappe .db .sql (f"""
114
+ SELECT { filter_fieldname } AS commission_filter, SUM(total) AS allocated_amount
115
+ FROM `tab{ self .commission_based_on } `
116
+ WHERE docstatus = 1
117
+ AND company = '{ self .company } '
118
+ AND { filter_date } BETWEEN '{ self .from_date } ' AND '{ self .to_date } '
119
+ { filter_value_sql }
120
+ GROUP BY { filter_fieldname }
121
+ """ , as_dict = True )
122
+
123
+ commission_rate = frappe .get_value ("Sales Person" , self .sales_person , "commission_rate" )
124
+
125
+ for record in records :
126
+ record ['commission_rate' ] = commission_rate
127
+ record ['incentives' ] = flt (record ['allocated_amount' ] * flt (commission_rate ) / 100.0 , self .precision ("total_contribution" ))
128
+ record ['allocated_percentage' ] = 100
129
+ contribution = {
130
+ "commission_filter" : record ["commission_filter" ],
131
+ "contribution_percent" : record ["allocated_percentage" ],
132
+ "contribution_amount" : record ["allocated_amount" ],
133
+ "commission_rate" : record ["commission_rate" ],
134
+ "commission_amount" : record ["incentives" ],
135
+ "process_sales_commission" : process_sales_commission ,
136
+ }
137
+ self .append ("contributions" , contribution )
138
+ else :
139
+ records = [entry .name for entry in frappe .db .get_all (self .commission_based_on , filters = {"company" : self .company , "docstatus" : 1 , filter_date : ('between' , [self .from_date , self .to_date ])})]
140
+
141
+ sales_persons_details = frappe .get_all (
142
+ "Sales Team" , filters = {"parent" : ['in' , records ], "sales_person" : self .sales_person },
143
+ fields = ["sales_person" , "commission_rate" , "incentives" , "allocated_percentage" , "allocated_amount" , "parent" ])
144
+
145
+ if sales_persons_details :
146
+ for record in sales_persons_details :
147
+ if add_record (record , self .sales_person ):
148
+ record_details = frappe .db .get_value (self .commission_based_on , filters = {"name" : record ["parent" ]}, fieldname = [customer_field , filter_date ], as_dict = True )
149
+ contribution = {
150
+ "document_type" : self .commission_based_on ,
151
+ "order_or_invoice" : record ["parent" ],
152
+ "customer" : record_details .get (customer_field ),
153
+ "posting_date" : record_details [filter_date ],
154
+ "contribution_percent" : record ["allocated_percentage" ],
155
+ "contribution_amount" : record ["allocated_amount" ],
156
+ "commission_rate" : record ["commission_rate" ],
157
+ "commission_amount" : record ["incentives" ],
158
+ "process_sales_commission" : process_sales_commission ,
159
+ }
160
+ self .append ("contributions" , contribution )
109
161
self .calculate_total_contribution_and_total_commission_amount ()
110
162
163
+ def get_filter_commission_against_field (self ):
164
+ commission_based_on_meta = frappe .get_meta (self .commission_based_on )
165
+ for field in commission_based_on_meta .fields :
166
+ if field .fieldtype == "Link" and field .options == self .commission_against :
167
+ return field .fieldname
168
+ frappe .throw (f"{ self .commission_based_on } no tiene campo { self .commission_against } " )
169
+
111
170
def calculate_total_contribution_and_total_commission_amount (self ):
112
171
total_contribution , total_commission_amount = 0 , 0
113
172
for entry in self .contributions :
0 commit comments