blob: d24d56b4bbb6525b8a30d23710bfaacbfd981c44 [file] [log] [blame]
Anand Doshi885e0742015-03-03 14:55:30 +05301# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
Rushabh Mehtae67d1fb2013-08-05 14:59:54 +05302# License: GNU General Public License v3. See license.txt
Nabin Haitbf495c92013-01-30 12:49:08 +05303
Chillar Anand915b3432021-09-02 16:44:59 +05304
Nabin Hait004c1ed2022-01-31 13:20:18 +05305import copy
Nabin Hait5b0ec642022-01-31 18:07:04 +05306
7import frappe
Rushabh Mehta793ba6b2014-02-14 15:47:51 +05308from frappe import _
Nabin Haite2c200a2015-05-28 13:00:37 +05309from frappe.model.meta import get_field_precision
Chillar Anand915b3432021-09-02 16:44:59 +053010from frappe.utils import cint, cstr, flt, formatdate, getdate, now
11
12import erpnext
13from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
14 get_accounting_dimensions,
15)
Nabin Haitb9bc7d62016-05-16 14:38:47 +053016from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
Chillar Anand915b3432021-09-02 16:44:59 +053017
Nabin Haitbf495c92013-01-30 12:49:08 +053018
Mangesh-Khairnare5c733b2019-08-08 15:44:11 +053019class ClosedAccountingPeriod(frappe.ValidationError): pass
Nabin Haitbf495c92013-01-30 12:49:08 +053020
Nabin Haita77b8c92020-12-21 14:45:50 +053021def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, update_outstanding='Yes', from_repost=False):
Nabin Hait2e296fa2013-08-28 18:53:11 +053022 if gl_map:
23 if not cancel:
Mangesh-Khairnare5c733b2019-08-08 15:44:11 +053024 validate_accounting_period(gl_map)
Nabin Hait2e296fa2013-08-28 18:53:11 +053025 gl_map = process_gl_map(gl_map, merge_entries)
nabinhaitc3432922014-07-29 18:06:18 +053026 if gl_map and len(gl_map) > 1:
Nabin Haita77b8c92020-12-21 14:45:50 +053027 save_entries(gl_map, adv_adj, update_outstanding, from_repost)
Deepesh Garg4c8d15b2021-04-26 15:24:34 +053028 # Post GL Map proccess there may no be any GL Entries
29 elif gl_map:
nabinhait4859b482014-07-30 14:28:24 +053030 frappe.throw(_("Incorrect number of General Ledger Entries found. You might have selected a wrong Account in the transaction."))
Nabin Hait2e296fa2013-08-28 18:53:11 +053031 else:
Deepesh Garg2a9c5ba2020-04-30 10:38:58 +053032 make_reverse_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding)
Anand Doshi652bc072014-04-16 15:21:46 +053033
Mangesh-Khairnare5c733b2019-08-08 15:44:11 +053034def validate_accounting_period(gl_map):
35 accounting_periods = frappe.db.sql(""" SELECT
36 ap.name as name
37 FROM
38 `tabAccounting Period` ap, `tabClosed Document` cd
39 WHERE
40 ap.name = cd.parent
41 AND ap.company = %(company)s
42 AND cd.closed = 1
43 AND cd.document_type = %(voucher_type)s
44 AND %(date)s between ap.start_date and ap.end_date
45 """, {
46 'date': gl_map[0].posting_date,
47 'company': gl_map[0].company,
48 'voucher_type': gl_map[0].voucher_type
49 }, as_dict=1)
50
51 if accounting_periods:
Deepesh Garg069a54e2020-08-10 16:01:01 +053052 frappe.throw(_("You cannot create or cancel any accounting entries with in the closed Accounting Period {0}")
53 .format(frappe.bold(accounting_periods[0].name)), ClosedAccountingPeriod)
Mangesh-Khairnare5c733b2019-08-08 15:44:11 +053054
Nabin Hait19f8fa52021-02-22 22:27:22 +053055def process_gl_map(gl_map, merge_entries=True, precision=None):
Nabin Hait6099af52022-01-31 17:24:50 +053056 if not gl_map:
57 return []
58
Nabin Hait004c1ed2022-01-31 13:20:18 +053059 gl_map = distribute_gl_based_on_cost_center_allocation(gl_map, precision)
60
Nabin Haitbf495c92013-01-30 12:49:08 +053061 if merge_entries:
Nabin Hait19f8fa52021-02-22 22:27:22 +053062 gl_map = merge_similar_entries(gl_map, precision)
Anand Doshi602e8252015-11-16 19:05:46 +053063
Nabin Hait004c1ed2022-01-31 13:20:18 +053064 gl_map = toggle_debit_credit_if_negative(gl_map)
Deepesh Garg5ba3b282021-11-25 15:42:30 +053065
Nabin Hait27994c22013-08-26 16:53:30 +053066 return gl_map
Anand Doshi652bc072014-04-16 15:21:46 +053067
Nabin Hait004c1ed2022-01-31 13:20:18 +053068def distribute_gl_based_on_cost_center_allocation(gl_map, precision=None):
69 cost_center_allocation = get_cost_center_allocation_data(gl_map[0]["company"], gl_map[0]["posting_date"])
70 if not cost_center_allocation:
71 return gl_map
Deepesh Garg5ba3b282021-11-25 15:42:30 +053072
Nabin Hait004c1ed2022-01-31 13:20:18 +053073 new_gl_map = []
74 for d in gl_map:
75 cost_center = d.get("cost_center")
76 if cost_center and cost_center_allocation.get(cost_center):
77 for sub_cost_center, percentage in cost_center_allocation.get(cost_center, {}).items():
78 gle = copy.deepcopy(d)
79 gle.cost_center = sub_cost_center
80 for field in ("debit", "credit", "debit_in_account_currency", "credit_in_company_currency"):
81 gle[field] = flt(flt(d.get(field)) * percentage / 100, precision)
82 new_gl_map.append(gle)
83 else:
84 new_gl_map.append(d)
85
86 return new_gl_map
87
88def get_cost_center_allocation_data(company, posting_date):
89 par = frappe.qb.DocType("Cost Center Allocation")
90 child = frappe.qb.DocType("Cost Center Allocation Percentage")
91
92 records = (
Nabin Hait6099af52022-01-31 17:24:50 +053093 frappe.qb.from_(par).inner_join(child).on(par.name == child.parent)
Nabin Hait004c1ed2022-01-31 13:20:18 +053094 .select(par.main_cost_center, child.cost_center, child.percentage)
95 .where(par.docstatus == 1)
96 .where(par.company == company)
97 .where(par.valid_from <= posting_date)
98 .orderby(par.valid_from, order=frappe.qb.desc)
99 ).run(as_dict=True)
100
101 cc_allocation = frappe._dict()
102 for d in records:
103 cc_allocation.setdefault(d.main_cost_center, frappe._dict())\
104 .setdefault(d.cost_center, d.percentage)
Nabin Hait5b0ec642022-01-31 18:07:04 +0530105
Nabin Hait004c1ed2022-01-31 13:20:18 +0530106 return cc_allocation
Deepesh Garg5ba3b282021-11-25 15:42:30 +0530107
Nabin Hait19f8fa52021-02-22 22:27:22 +0530108def merge_similar_entries(gl_map, precision=None):
Nabin Haitbf495c92013-01-30 12:49:08 +0530109 merged_gl_map = []
deepeshgarg0073d11ac02019-05-19 00:02:01 +0530110 accounting_dimensions = get_accounting_dimensions()
Nabin Haitbf495c92013-01-30 12:49:08 +0530111 for entry in gl_map:
Anand Doshi652bc072014-04-16 15:21:46 +0530112 # if there is already an entry in this account then just add it
Nabin Haitbf495c92013-01-30 12:49:08 +0530113 # to that entry
deepeshgarg0073d11ac02019-05-19 00:02:01 +0530114 same_head = check_if_in_list(entry, merged_gl_map, accounting_dimensions)
Nabin Haitbf495c92013-01-30 12:49:08 +0530115 if same_head:
Nabin Hait2e296fa2013-08-28 18:53:11 +0530116 same_head.debit = flt(same_head.debit) + flt(entry.debit)
Nabin Haitc561a492015-08-19 19:22:34 +0530117 same_head.debit_in_account_currency = \
118 flt(same_head.debit_in_account_currency) + flt(entry.debit_in_account_currency)
Nabin Hait2e296fa2013-08-28 18:53:11 +0530119 same_head.credit = flt(same_head.credit) + flt(entry.credit)
Nabin Haitc561a492015-08-19 19:22:34 +0530120 same_head.credit_in_account_currency = \
121 flt(same_head.credit_in_account_currency) + flt(entry.credit_in_account_currency)
Nabin Haitbf495c92013-01-30 12:49:08 +0530122 else:
123 merged_gl_map.append(entry)
Anand Doshi652bc072014-04-16 15:21:46 +0530124
thefalconx33bfc43d32019-12-13 15:09:51 +0530125 company = gl_map[0].company if gl_map else erpnext.get_default_company()
126 company_currency = erpnext.get_company_currency(company)
Nabin Hait19f8fa52021-02-22 22:27:22 +0530127
128 if not precision:
129 precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"), company_currency)
thefalconx33bfc43d32019-12-13 15:09:51 +0530130
Nabin Hait815a49e2013-08-07 17:00:01 +0530131 # filter zero debit and credit entries
thefalconx33bfc43d32019-12-13 15:09:51 +0530132 merged_gl_map = filter(lambda x: flt(x.debit, precision)!=0 or flt(x.credit, precision)!=0, merged_gl_map)
Achilles Rasquinha908289d2018-03-08 13:10:51 +0530133 merged_gl_map = list(merged_gl_map)
Rushabh Mehta708e47a2018-08-08 16:37:31 +0530134
Nabin Haitbf495c92013-01-30 12:49:08 +0530135 return merged_gl_map
136
deepeshgarg0073d11ac02019-05-19 00:02:01 +0530137def check_if_in_list(gle, gl_map, dimensions=None):
Ankush91527152021-08-11 11:17:50 +0530138 account_head_fieldnames = ['voucher_detail_no', 'party', 'against_voucher',
Saqib9198caa2021-08-24 17:26:23 +0530139 'cost_center', 'against_voucher_type', 'party_type', 'project', 'finance_book']
deepeshgarg0073d11ac02019-05-19 00:02:01 +0530140
141 if dimensions:
142 account_head_fieldnames = account_head_fieldnames + dimensions
143
Nabin Haitbb777562013-08-29 18:19:37 +0530144 for e in gl_map:
deepeshgarg0073d11ac02019-05-19 00:02:01 +0530145 same_head = True
146 if e.account != gle.account:
147 same_head = False
Ankush91527152021-08-11 11:17:50 +0530148 continue
deepeshgarg0073d11ac02019-05-19 00:02:01 +0530149
150 for fieldname in account_head_fieldnames:
151 if cstr(e.get(fieldname)) != cstr(gle.get(fieldname)):
152 same_head = False
Ankush91527152021-08-11 11:17:50 +0530153 break
deepeshgarg0073d11ac02019-05-19 00:02:01 +0530154
155 if same_head:
156 return e
Nabin Haitbf495c92013-01-30 12:49:08 +0530157
Nabin Hait004c1ed2022-01-31 13:20:18 +0530158def toggle_debit_credit_if_negative(gl_map):
159 for entry in gl_map:
160 # toggle debit, credit if negative entry
161 if flt(entry.debit) < 0:
162 entry.credit = flt(entry.credit) - flt(entry.debit)
163 entry.debit = 0.0
164
165 if flt(entry.debit_in_account_currency) < 0:
166 entry.credit_in_account_currency = \
167 flt(entry.credit_in_account_currency) - flt(entry.debit_in_account_currency)
168 entry.debit_in_account_currency = 0.0
169
170 if flt(entry.credit) < 0:
171 entry.debit = flt(entry.debit) - flt(entry.credit)
172 entry.credit = 0.0
173
174 if flt(entry.credit_in_account_currency) < 0:
175 entry.debit_in_account_currency = \
176 flt(entry.debit_in_account_currency) - flt(entry.credit_in_account_currency)
177 entry.credit_in_account_currency = 0.0
178
179 update_net_values(entry)
180
181 return gl_map
182
183def update_net_values(entry):
184 # In some scenarios net value needs to be shown in the ledger
185 # This method updates net values as debit or credit
186 if entry.post_net_value and entry.debit and entry.credit:
187 if entry.debit > entry.credit:
188 entry.debit = entry.debit - entry.credit
189 entry.debit_in_account_currency = entry.debit_in_account_currency \
190 - entry.credit_in_account_currency
191 entry.credit = 0
192 entry.credit_in_account_currency = 0
193 else:
194 entry.credit = entry.credit - entry.debit
195 entry.credit_in_account_currency = entry.credit_in_account_currency \
196 - entry.debit_in_account_currency
197
198 entry.debit = 0
199 entry.debit_in_account_currency = 0
200
Nabin Haita77b8c92020-12-21 14:45:50 +0530201def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
202 if not from_repost:
203 validate_cwip_accounts(gl_map)
Rushabh Mehta708e47a2018-08-08 16:37:31 +0530204
Nabin Haite2c200a2015-05-28 13:00:37 +0530205 round_off_debit_credit(gl_map)
Deepesh Garg2a9c5ba2020-04-30 10:38:58 +0530206
207 if gl_map:
208 check_freezing_date(gl_map[0]["posting_date"], adv_adj)
209
Nabin Haitbf495c92013-01-30 12:49:08 +0530210 for entry in gl_map:
Nabin Haita77b8c92020-12-21 14:45:50 +0530211 make_entry(entry, adv_adj, update_outstanding, from_repost)
Rushabh Mehta708e47a2018-08-08 16:37:31 +0530212
Nabin Haita77b8c92020-12-21 14:45:50 +0530213def make_entry(args, adv_adj, update_outstanding, from_repost=False):
Nabin Haitddc3bb22020-03-17 17:04:18 +0530214 gle = frappe.new_doc("GL Entry")
215 gle.update(args)
Anand Doshi6dfd4302015-02-10 14:41:27 +0530216 gle.flags.ignore_permissions = 1
Nabin Haita77b8c92020-12-21 14:45:50 +0530217 gle.flags.from_repost = from_repost
Nabin Hait19f8fa52021-02-22 22:27:22 +0530218 gle.flags.adv_adj = adv_adj
219 gle.flags.update_outstanding = update_outstanding or 'Yes'
Nabin Haitaeba24e2013-08-23 15:17:36 +0530220 gle.submit()
Anand Doshi652bc072014-04-16 15:21:46 +0530221
Nabin Haita77b8c92020-12-21 14:45:50 +0530222 if not from_repost:
223 validate_expense_against_budget(args)
Deepesh Garg2a9c5ba2020-04-30 10:38:58 +0530224
Anurag Mishra7e1987e2019-08-05 10:18:57 +0530225def validate_cwip_accounts(gl_map):
Ankush91527152021-08-11 11:17:50 +0530226 """Validate that CWIP account are not used in Journal Entry"""
227 if gl_map and gl_map[0].voucher_type != "Journal Entry":
228 return
Maricad00c5982019-11-12 19:17:43 +0530229
Ankush91527152021-08-11 11:17:50 +0530230 cwip_enabled = any(cint(ac.enable_cwip_accounting) for ac in frappe.db.get_all("Asset Category", "enable_cwip_accounting"))
231 if cwip_enabled:
232 cwip_accounts = [d[0] for d in frappe.db.sql("""select name from tabAccount
233 where account_type = 'Capital Work in Progress' and is_group=0""")]
Anurag Mishra7e1987e2019-08-05 10:18:57 +0530234
Ankush91527152021-08-11 11:17:50 +0530235 for entry in gl_map:
236 if entry.account in cwip_accounts:
237 frappe.throw(
238 _("Account: <b>{0}</b> is capital Work in progress and can not be updated by Journal Entry").format(entry.account))
Anurag Mishra7e1987e2019-08-05 10:18:57 +0530239
Nabin Haite2c200a2015-05-28 13:00:37 +0530240def round_off_debit_credit(gl_map):
241 precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"),
Rushabh Mehta708e47a2018-08-08 16:37:31 +0530242 currency=frappe.get_cached_value('Company', gl_map[0].company, "default_currency"))
Anand Doshi602e8252015-11-16 19:05:46 +0530243
Nabin Haite2c200a2015-05-28 13:00:37 +0530244 debit_credit_diff = 0.0
245 for entry in gl_map:
246 entry.debit = flt(entry.debit, precision)
247 entry.credit = flt(entry.credit, precision)
248 debit_credit_diff += entry.debit - entry.credit
Anand Doshi602e8252015-11-16 19:05:46 +0530249
Nabin Haite2c200a2015-05-28 13:00:37 +0530250 debit_credit_diff = flt(debit_credit_diff, precision)
Rushabh Mehta708e47a2018-08-08 16:37:31 +0530251
Nabin Haitd2a966e2017-05-05 10:41:16 +0530252 if gl_map[0]["voucher_type"] in ("Journal Entry", "Payment Entry"):
Nabin Haitfb24a272016-02-18 19:18:07 +0530253 allowance = 5.0 / (10**precision)
254 else:
Nabin Haitd2a966e2017-05-05 10:41:16 +0530255 allowance = .5
Rushabh Mehta708e47a2018-08-08 16:37:31 +0530256
Saqib Ansarib0e160f2021-04-22 13:23:50 +0530257 if abs(debit_credit_diff) > allowance:
Nabin Haite2c200a2015-05-28 13:00:37 +0530258 frappe.throw(_("Debit and Credit not equal for {0} #{1}. Difference is {2}.")
259 .format(gl_map[0].voucher_type, gl_map[0].voucher_no, debit_credit_diff))
Anand Doshi602e8252015-11-16 19:05:46 +0530260
Saqib Ansariaa4f7502021-04-28 14:42:49 +0530261 elif abs(debit_credit_diff) >= (1.0 / (10**precision)):
Nabin Hait34c551d2019-07-03 10:34:31 +0530262 make_round_off_gle(gl_map, debit_credit_diff, precision)
Anand Doshi602e8252015-11-16 19:05:46 +0530263
Nabin Hait34c551d2019-07-03 10:34:31 +0530264def make_round_off_gle(gl_map, debit_credit_diff, precision):
Nabin Hait2e4de832017-09-19 14:53:16 +0530265 round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(gl_map[0].company)
Zarrar3523b772018-08-14 16:28:14 +0530266 round_off_account_exists = False
Nabin Hait80069a62015-05-28 19:19:59 +0530267 round_off_gle = frappe._dict()
Zarrar3523b772018-08-14 16:28:14 +0530268 for d in gl_map:
269 if d.account == round_off_account:
270 round_off_gle = d
Saqibc6e016e2021-06-04 10:08:22 +0530271 if d.debit:
272 debit_credit_diff -= flt(d.debit)
Zarrar3523b772018-08-14 16:28:14 +0530273 else:
Saqibc6e016e2021-06-04 10:08:22 +0530274 debit_credit_diff += flt(d.credit)
Zarrar3523b772018-08-14 16:28:14 +0530275 round_off_account_exists = True
276
Nabin Hait34c551d2019-07-03 10:34:31 +0530277 if round_off_account_exists and abs(debit_credit_diff) <= (1.0 / (10**precision)):
278 gl_map.remove(round_off_gle)
279 return
280
Zarrar3523b772018-08-14 16:28:14 +0530281 if not round_off_gle:
282 for k in ["voucher_type", "voucher_no", "company",
Ankush Menat23c30e42021-02-24 11:03:24 +0530283 "posting_date", "remarks"]:
Zarrar3523b772018-08-14 16:28:14 +0530284 round_off_gle[k] = gl_map[0][k]
Anand Doshi602e8252015-11-16 19:05:46 +0530285
Nabin Haite2c200a2015-05-28 13:00:37 +0530286 round_off_gle.update({
287 "account": round_off_account,
Nabin Haitd4507ac2016-01-20 16:14:27 +0530288 "debit_in_account_currency": abs(debit_credit_diff) if debit_credit_diff < 0 else 0,
289 "credit_in_account_currency": debit_credit_diff if debit_credit_diff > 0 else 0,
Nabin Haite2c200a2015-05-28 13:00:37 +0530290 "debit": abs(debit_credit_diff) if debit_credit_diff < 0 else 0,
291 "credit": debit_credit_diff if debit_credit_diff > 0 else 0,
Nabin Hait3c671462015-05-28 13:19:01 +0530292 "cost_center": round_off_cost_center,
293 "party_type": None,
294 "party": None,
Ankush Menat23c30e42021-02-24 11:03:24 +0530295 "is_opening": "No",
Nabin Hait3c671462015-05-28 13:19:01 +0530296 "against_voucher_type": None,
297 "against_voucher": None
Nabin Haite2c200a2015-05-28 13:00:37 +0530298 })
Anand Doshi602e8252015-11-16 19:05:46 +0530299
Zarrar3523b772018-08-14 16:28:14 +0530300 if not round_off_account_exists:
301 gl_map.append(round_off_gle)
Nabin Haite2c200a2015-05-28 13:00:37 +0530302
Nabin Hait2e4de832017-09-19 14:53:16 +0530303def get_round_off_account_and_cost_center(company):
Rushabh Mehta708e47a2018-08-08 16:37:31 +0530304 round_off_account, round_off_cost_center = frappe.get_cached_value('Company', company,
Nabin Hait2e4de832017-09-19 14:53:16 +0530305 ["round_off_account", "round_off_cost_center"]) or [None, None]
306 if not round_off_account:
307 frappe.throw(_("Please mention Round Off Account in Company"))
308
309 if not round_off_cost_center:
310 frappe.throw(_("Please mention Round Off Cost Center in Company"))
311
312 return round_off_account, round_off_cost_center
313
Deepesh Garg2a9c5ba2020-04-30 10:38:58 +0530314def make_reverse_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
315 adv_adj=False, update_outstanding="Yes"):
316 """
317 Get original gl entries of the voucher
318 and make reverse gl entries by swapping debit and credit
319 """
Anand Doshi652bc072014-04-16 15:21:46 +0530320
Nabin Hait2e296fa2013-08-28 18:53:11 +0530321 if not gl_entries:
Deepesh Gargff574502022-02-06 22:56:12 +0530322 gl_entry = frappe.qb.DocType("GL Entry")
323 gl_entries = (frappe.qb.from_(
324 gl_entry
325 ).select(
326 '*'
327 ).where(
328 gl_entry.voucher_type == voucher_type
329 ).where(
330 gl_entry.voucher_no == voucher_no
331 ).where(
332 gl_entry.is_cancelled == 0
333 ).for_update()).run(as_dict=1)
Nabin Hait56548cb2016-07-01 15:58:39 +0530334
Nabin Hait27994c22013-08-26 16:53:30 +0530335 if gl_entries:
Deepesh Garg069a54e2020-08-10 16:01:01 +0530336 validate_accounting_period(gl_entries)
Nabin Hait27994c22013-08-26 16:53:30 +0530337 check_freezing_date(gl_entries[0]["posting_date"], adv_adj)
Deepesh Garg069a54e2020-08-10 16:01:01 +0530338 set_as_cancel(gl_entries[0]['voucher_type'], gl_entries[0]['voucher_no'])
Anand Doshi652bc072014-04-16 15:21:46 +0530339
Deepesh Garg2a9c5ba2020-04-30 10:38:58 +0530340 for entry in gl_entries:
Deepesh Gargffec8652022-02-02 17:14:42 +0530341 new_gle = copy.deepcopy(entry)
342 new_gle['name'] = None
343 debit = new_gle.get('debit', 0)
344 credit = new_gle.get('credit', 0)
Anand Doshi652bc072014-04-16 15:21:46 +0530345
Deepesh Gargffec8652022-02-02 17:14:42 +0530346 debit_in_account_currency = new_gle.get('debit_in_account_currency', 0)
347 credit_in_account_currency = new_gle.get('credit_in_account_currency', 0)
Rushabh Mehta708e47a2018-08-08 16:37:31 +0530348
Deepesh Gargffec8652022-02-02 17:14:42 +0530349 new_gle['debit'] = credit
350 new_gle['credit'] = debit
351 new_gle['debit_in_account_currency'] = credit_in_account_currency
352 new_gle['credit_in_account_currency'] = debit_in_account_currency
Deepesh Garg2a9c5ba2020-04-30 10:38:58 +0530353
Deepesh Gargffec8652022-02-02 17:14:42 +0530354 new_gle['remarks'] = "On cancellation of " + new_gle['voucher_no']
355 new_gle['is_cancelled'] = 1
Deepesh Garg2a9c5ba2020-04-30 10:38:58 +0530356
Deepesh Gargffec8652022-02-02 17:14:42 +0530357 if new_gle['debit'] or new_gle['credit']:
358 make_entry(new_gle, adv_adj, "Yes")
Deepesh Garg2a9c5ba2020-04-30 10:38:58 +0530359
360
361def check_freezing_date(posting_date, adv_adj=False):
362 """
363 Nobody can do GL Entries where posting date is before freezing date
364 except authorized person
Deepesh Garg13d2e7b2021-09-16 18:54:57 +0530365
366 Administrator has all the roles so this check will be bypassed if any role is allowed to post
367 Hence stop admin to bypass if accounts are freezed
Deepesh Garg2a9c5ba2020-04-30 10:38:58 +0530368 """
369 if not adv_adj:
370 acc_frozen_upto = frappe.db.get_value('Accounts Settings', None, 'acc_frozen_upto')
371 if acc_frozen_upto:
372 frozen_accounts_modifier = frappe.db.get_value( 'Accounts Settings', None,'frozen_accounts_modifier')
373 if getdate(posting_date) <= getdate(acc_frozen_upto) \
Noah Jacob2bb383b2021-10-13 16:20:08 +0530374 and (frozen_accounts_modifier not in frappe.get_roles() or frappe.session.user == 'Administrator'):
Deepesh Garg2a9c5ba2020-04-30 10:38:58 +0530375 frappe.throw(_("You are not authorized to add or update entries before {0}").format(formatdate(acc_frozen_upto)))
376
377def set_as_cancel(voucher_type, voucher_no):
378 """
379 Set is_cancelled=1 in all original gl entries for the voucher
380 """
Deepesh Garg069a54e2020-08-10 16:01:01 +0530381 frappe.db.sql("""UPDATE `tabGL Entry` SET is_cancelled = 1,
Deepesh Garg2a9c5ba2020-04-30 10:38:58 +0530382 modified=%s, modified_by=%s
383 where voucher_type=%s and voucher_no=%s and is_cancelled = 0""",
384 (now(), frappe.session.user, voucher_type, voucher_no))