Compare commits

...

583 Commits

Author SHA1 Message Date
Mohammad Hussain Nagaria
282a30144a feat: Employee reminders (#25735)
* feat: Add reminders section to HR Settings

* refactor: Extract generic function for getting Employees

* feat: Employee Work Anniversary Reminder

* feat: Daily Holiday Reminder

* fix: Unnecessary params and replace [] with .get()

* test: Daily Holiday Reminders

* test: is_holiday basic tests

* refactor: Move employee reminders code to separate module

* feat: Add advance reminder to HR settings

* feat: Advance Holiday Reminders

* refactor: get_holidays_for_employee

* feat: Email holiday reminders in advance + tests

* fix: Remove unused import

* refactor: HR Setting Reminder Section

* refactor: Remove Daily Holiday Reminders feat

* feat: Reminder miss warning

* fix: Failing test and function name change

* chore: Add patch for field rename

* chore: Rename frequency label

* fix: Failing patch test

* fix: sider and removed description of fields

* fix: email alignment

Co-authored-by: pateljannat <pateljannat2308@gmail.com>
Co-authored-by: Jannat Patel <31363128+pateljannat@users.noreply.github.com>
(cherry picked from commit 24b2a31581)

# Conflicts:
#	erpnext/hooks.py
#	erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_request.py
#	erpnext/hr/doctype/employee/employee.py
#	erpnext/hr/doctype/employee/test_employee.py
#	erpnext/hr/doctype/hr_settings/hr_settings.json
#	erpnext/hr/doctype/hr_settings/hr_settings.py
#	erpnext/hr/doctype/upload_attendance/upload_attendance.py
#	erpnext/hr/utils.py
#	erpnext/patches.txt
#	erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.py
#	erpnext/payroll/doctype/payroll_period/payroll_period.py
#	erpnext/payroll/doctype/salary_slip/salary_slip.py
#	erpnext/public/js/utils.js
#	erpnext/setup/doctype/employee/employee_reminders.py
#	erpnext/setup/doctype/employee/test_employee_reminders.py
2025-01-12 00:13:13 +00:00
rohitwaghchaure
c6c7d7832a Merge pull request #45207 from rohitwaghchaure/fixed-support-29140
fix: incorrect valuation rate for PI based revaluation
2025-01-11 10:07:54 +05:30
rohitwaghchaure
edb254e43e Merge pull request #45214 from rohitwaghchaure/fixed-support-29172
fix: delivery_document_no column issue
2025-01-11 10:07:26 +05:30
Rohit Waghchaure
61efb2bb39 fix: delivery_document_no column issue 2025-01-10 18:19:48 +05:30
ruthra kumar
856ec08484 Merge pull request #45195 from sokumon/coa-ui
fix: coa actions cleanup
2025-01-10 16:08:19 +05:30
rohitwaghchaure
31005c5984 Merge pull request #45076 from frappe/valuation_in_ageing_report
feat: Added valuation of quantity for each age group in stock ageing …
2025-01-10 14:25:50 +05:30
Rohit Waghchaure
14ce2337df fix: incorrect valuation rate for PI based revaluation 2025-01-10 14:20:48 +05:30
rohitwaghchaure
e4d3235b9c Merge pull request #45204 from frappe/mergify/bp/develop/pr-45197
fix: precision loss causing process loss variance (backport #45197)
2025-01-10 12:00:37 +05:30
rohitwaghchaure
5ccf4a1783 chore: fix conflicts 2025-01-10 11:25:53 +05:30
FATHIH MOHAMMED
1ef9f7f8fd fix: precision loss causing process loss variance
(cherry picked from commit d84601b2a3)

# Conflicts:
#	erpnext/stock/doctype/stock_entry/stock_entry.py
2025-01-10 05:49:59 +00:00
sokumon
108a91d788 fix: coa actions cleanup 2025-01-09 16:49:24 +05:30
rohitwaghchaure
1f1c01d88e Merge pull request #44988 from frappe/35225
feat: Validate sub assembly and material request items in Production …
2025-01-09 16:28:29 +05:30
rohitwaghchaure
90339511aa Merge pull request #45190 from diptanilsaha/fix-typo-in-manufacturing-settings
fix: typo in manufacturing settings
2025-01-09 16:26:01 +05:30
diptanilsaha
a9b761f862 fix: typo in manufacturing settings 2025-01-09 16:05:40 +05:30
rohitwaghchaure
4ec824d71e Merge pull request #45183 from rohitwaghchaure/fixed-support-29059
fix: not able to see create Quality Inspection button
2025-01-09 14:36:52 +05:30
rohitwaghchaure
bb9dd7b8cc Merge pull request #45180 from rohitwaghchaure/fixed-support-28867
fix: do not add ordered items from Quotation to new Sales Order
2025-01-09 14:34:13 +05:30
Rohit Waghchaure
b291835ccd fix: not able to see create Quality Inspection button 2025-01-09 14:31:01 +05:30
Rohit Waghchaure
2e930eb97b fix: do not add ordered items from Quotation to new Sales Order 2025-01-09 13:52:34 +05:30
rohitwaghchaure
00dadc1a89 Merge pull request #45177 from rohitwaghchaure/fixed-support-29008
fix: timeout error for work order
2025-01-09 13:47:17 +05:30
Rohit Waghchaure
b4ceda6f2c fix: timeout error for work order 2025-01-09 13:27:43 +05:30
Khushi Rawat
7ea73d8265 chore: removal of decapitalization feature (#45162)
* chore: removal of decapitalization feature

* fix: rearrangement of asset capitalization doctype fields
2025-01-08 20:44:12 +05:30
Raffael Meyer
9e760e54a5 fix(Timesheet): ignore permissions when updating Task and Project (#45168) 2025-01-08 13:36:31 +01:00
Ejaaz Khan
81d8f257aa refactor: validate due date code and message according to doctype (#45126)
* refactor: change message of date comparision and refactor code

* refactor: commonify function call for sales and purchase invoice

* refactor: remove redundant mandatory error validation
2025-01-08 12:49:02 +05:30
Mihir Kandoi
dbb572eec1 test: Valuation of ageing stock 2025-01-08 11:52:24 +05:30
ruthra kumar
2b453219fc Merge pull request #45148 from frappe/l10n_develop
fix: sync translations from crowdin
2025-01-08 09:01:02 +05:30
ruthra kumar
ca44a31420 Merge pull request #45154 from ruthra-kumar/remove_possible_deadlock_in_auto_reconcile
fix: possible deadlock while using auto reconciliation
2025-01-08 09:00:42 +05:30
ruthra kumar
4620025dcd chore: remove 'Experimental' tag 2025-01-08 08:22:37 +05:30
ruthra kumar
5df9a8ab99 Merge pull request #45112 from marination/bank-reco-bank-balance
fix: Missing company filter breaks `get_account_balance` in Bank Reco
2025-01-08 08:16:21 +05:30
Frappe PR Bot
731822efac fix: Spanish translations 2025-01-07 21:48:22 +05:30
rohitwaghchaure
a24d7e8ecd Merge pull request #45144 from rohitwaghchaure/fixed-support-28796
fix: issue in returning components against the SCO
2025-01-07 18:31:18 +05:30
Rohit Waghchaure
729ce1dc50 fix: issue in returning components against the SCO 2025-01-07 18:11:56 +05:30
Diptanil Saha
31dd32dcdf fix: serial and batch no. buttons on pos (#45048) 2025-01-07 18:06:02 +05:30
Khushi Rawat
6850019649 feat: work in progress status for asset (#45066)
* feat: work in progress status for asset

* fix: test case correction

* fix(patch): added patch to update status of assets

* fix: updated tests
2025-01-07 17:38:21 +05:30
Diptanil Saha
2788739c1e feat: pos configuration for print receipt on complete order (#45024) 2025-01-07 17:35:01 +05:30
Diptanil Saha
9f77793f16 chore: removal of tally migration feature (#45100) 2025-01-07 17:28:46 +05:30
Ejaaz Khan
a0f17f8e73 refactor: change sales invoice button position (#45130) 2025-01-07 17:17:59 +05:30
Venkatesh
dc5bff9008 fix: ignore crm deal in tax_rule search filter (#45134) 2025-01-07 17:11:31 +05:30
ruthra kumar
3bc74f219a Merge pull request #45121 from ruthra-kumar/revert_44989
fix: discount resetting on date change
2025-01-07 11:20:43 +05:30
ruthra kumar
886281f81a fix: discount resetting on date change
revert #44989
2025-01-07 11:14:42 +05:30
Raffael Meyer
9eede907f8 fix(Project): make status in confirmation dialog translatable (#45118) 2025-01-06 22:12:53 +00:00
Raffael Meyer
6f5fea6b52 refactor(Project): extract custom button function (#45116) 2025-01-06 21:58:38 +00:00
Frappe PR Bot
3ca3707603 fix: sync translations from crowdin (#45113) 2025-01-06 18:25:54 +01:00
marination
d7bf73cffa fix: Override pre-commit behaviour due to conflicts with CI 2025-01-06 21:14:41 +05:30
marination
8de0fe78ea fix: Missing company filter breaks get_account_balance in Bank Reco 2025-01-06 20:27:06 +05:30
Mihir Kandoi
87f1f6e15c fix: Attempt to fix status updater 1 2025-01-06 19:47:44 +05:30
rohitwaghchaure
7afe3cccd6 Merge pull request #45107 from rohitwaghchaure/fixed-support-28773
fix: Returned Qty in Work Order Consumed Materials report
2025-01-06 16:05:54 +05:30
Rohit Waghchaure
30d68a31e0 fix: Returned Qty in Work Order Consumed Materials report 2025-01-06 15:23:57 +05:30
Diptanil Saha
d79e561248 fix: update customer contact details on pos (#45071)
* fix: update customer contact details on pos

* refactor: removed console log statement
2025-01-06 14:53:44 +05:30
ruthra kumar
03abde6993 Merge pull request #45006 from diptanilsaha/fix-price_list_rate-for-pos-search-term
fix: pos search by term items price
2025-01-06 14:08:51 +05:30
ruthra kumar
c7370e214f Merge pull request #45099 from sokumon/new-button-in-coa
fix: show new button in coa if create access
2025-01-06 13:49:12 +05:30
sokumon
3125bc8a16 fix: show new button in coa if create access 2025-01-06 12:26:06 +05:30
rohitwaghchaure
7bbd70a7e2 Merge pull request #45097 from iamejaaz/subcontracting-links
feat: add subcontracting links in manufacturing workspace
2025-01-06 12:22:23 +05:30
rohitwaghchaure
acb5eeb281 Merge pull request #45084 from frappe/45082
fix: Alternative Items button in Work Order
2025-01-06 12:21:25 +05:30
Mihir Kandoi
b8838bd9b9 fix: Alternative Item button dissapearing on Save event 2025-01-06 11:22:06 +05:30
Ejaaz Khan
d42ee40b17 refactor: revert modified by in subcontracting 2025-01-06 11:00:54 +05:30
ruthra kumar
19f1e089bd Merge pull request #45047 from Abdeali099/use-constants
refactor: use variables for app name, title, and home route in hooks
2025-01-06 10:51:32 +05:30
Ejaaz Khan
bddffbb04f feat: add subcontracting links on manufacturing 2025-01-06 10:49:26 +05:30
ruthra kumar
2b88c13002 Merge pull request #45081 from frappe/mergify/copy/develop/pr-44949
Add phone number field when channel is phone on Payment Request doctype (copy #44949)
2025-01-06 10:09:54 +05:30
ruthra kumar
988b680244 Merge pull request #44952 from mahsem/Hold_to_On_Hold
fix: Hold_to_On_Hold
2025-01-06 08:44:33 +05:30
ruthra kumar
4d74724a34 Merge pull request #44943 from creative-paramu/bank_reconcilation_company_filter
fix: Bank Reconciliation Statement Report Company Filter
2025-01-06 08:35:44 +05:30
ruthra kumar
b6fe43b63a Merge pull request #45051 from aerele/currency-validation
fix: ignore currency validation while canceling the voucher
2025-01-06 08:25:05 +05:30
ruthra kumar
d39fa07620 Merge pull request #45088 from frappe/l10n_develop
fix: sync translations from crowdin
2025-01-06 06:19:28 +05:30
Frappe PR Bot
34a4efbc59 fix: Esperanto translations 2025-01-05 20:36:22 +05:30
Frappe PR Bot
d34ebcfe9a fix: German translations 2025-01-05 20:36:19 +05:30
Frappe PR Bot
7b5f026b8b fix: Bosnian translations 2025-01-05 20:36:16 +05:30
Frappe PR Bot
630009e28f fix: Persian translations 2025-01-05 20:36:12 +05:30
Frappe PR Bot
9727bcc281 fix: Chinese Simplified translations 2025-01-05 20:36:09 +05:30
Frappe PR Bot
3c96ccf990 fix: Turkish translations 2025-01-05 20:36:06 +05:30
Frappe PR Bot
74791fd619 fix: Swedish translations 2025-01-05 20:36:02 +05:30
Frappe PR Bot
ee3f3fc799 fix: Russian translations 2025-01-05 20:35:59 +05:30
Frappe PR Bot
7bcd5f5bcb fix: Polish translations 2025-01-05 20:35:56 +05:30
Frappe PR Bot
af027cf980 fix: Hungarian translations 2025-01-05 20:35:53 +05:30
Frappe PR Bot
b3e2e8e123 fix: Arabic translations 2025-01-05 20:35:49 +05:30
Frappe PR Bot
43408c1b6d fix: Spanish translations 2025-01-05 20:35:46 +05:30
Frappe PR Bot
609f789807 fix: French translations 2025-01-05 20:35:42 +05:30
Frappe PR Bot
cacc90c224 chore: update POT file (#45092) 2025-01-05 11:26:50 +01:00
rohitwaghchaure
a76c3b5f3f Merge pull request #45087 from rohitwaghchaure/fixed-support-28646
fix: invoice against purchase receipt with returned quantity
2025-01-04 20:37:08 +05:30
Frappe PR Bot
ae4e55bf3a fix: Persian translations 2025-01-04 20:28:58 +05:30
Frappe PR Bot
07ba0281f7 fix: Swedish translations 2025-01-04 20:28:52 +05:30
Rohit Waghchaure
d5babf4237 fix: invoice against purchase receipt with returned quantity 2025-01-04 19:59:19 +05:30
rohitwaghchaure
9e86a02a91 Merge pull request #45083 from rohitwaghchaure/fixed-support-28669
fix: consider expired batches in stock reco
2025-01-04 19:26:05 +05:30
Mihir Kandoi
e28382afc1 fix: Alternative Items button in Work Order 2025-01-04 17:22:16 +05:30
Mihir Kandoi
1f2d7da426 fix: Fixed final test case 2025-01-04 15:22:28 +05:30
Mihir Kandoi
f996f71d16 fix: Fixed more test cases 2025-01-04 15:17:31 +05:30
Rohit Waghchaure
f51c9f578c fix: consider expired batches in stock reco 2025-01-04 12:58:07 +05:30
ruthra kumar
ba90a6a4bf chore: fix json 2025-01-04 05:45:58 +05:30
Joseph Mania
947ab72441 refactor: phone number field when channel is phone on Payment Request (#44949)
Co-authored-by: maniamartial <martialamania19@gmail.com>
(cherry picked from commit cfa062df86)
2025-01-04 05:29:34 +05:30
ruthra kumar
5245c54de9 Merge pull request #44983 from Sanket322/budget_based_on_distribution
fix: add monthly distributation and write query in qb
2025-01-04 05:17:10 +05:30
Frappe PR Bot
e39638bdcd fix: sync translations from crowdin (#45055) 2025-01-03 16:07:51 +01:00
Mihir Kandoi
839b79ffd0 fix: Test case for ageing report 2025-01-03 20:00:36 +05:30
Mihir Kandoi
2f80c4dee5 feat: Added valuation of quantity for each age group in stock ageing report 2025-01-03 16:51:44 +05:30
Ankush Menat
4f690affc9 perf: Skip link checking on repost's remove_attached_file (#45061)
This is internal detail, doesn't need to do horrible link checks in
framework.
2025-01-02 16:59:31 +00:00
ruthra kumar
413fef332a Merge pull request #45056 from ruthra-kumar/partial_revert_44989
chore: partial revert #44989
2025-01-02 20:56:33 +05:30
ruthra kumar
63d547fb4a chore: partial revert #44989 2025-01-02 20:50:28 +05:30
rohitwaghchaure
3221c89218 Merge pull request #45053 from sokumon/ux-issues
fix(style): set image width in BOM
2025-01-02 19:00:25 +05:30
sokumon
b634ba7f54 fix(style): set image width in BOM 2025-01-02 17:37:46 +05:30
venkat102
49885f8eae fix: ignore party account validation while canceling the voucher 2025-01-02 17:27:34 +05:30
Abdeali Chharchhoda
71d1205f53 refactor: use variables for app name, title, and home route in hooks 2025-01-02 16:40:12 +05:30
venkat102
15d488b9aa fix: ignore currency validation while canceling the voucher 2025-01-02 16:10:12 +05:30
rohitwaghchaure
bdece96510 Merge pull request #45043 from rohitwaghchaure/fixed-github-44909
fix: validate components and their qty as per BOM in the stock entry
2025-01-02 13:44:29 +05:30
Rohit Waghchaure
b1de82ddad fix: validate components and their qty as per BOM in the stock entry 2025-01-02 13:11:19 +05:30
Mihir Kandoi
5dacfd5cda fix: Test case and refactored some code 2025-01-02 12:28:01 +05:30
ruthra kumar
e609a6a038 Merge pull request #45040 from ruthra-kumar/use_idx_for_identifying
refactor: use `idx` for identifying row
2025-01-02 12:16:40 +05:30
rohitwaghchaure
1f26feca2e Merge pull request #45039 from rohitwaghchaure/fixed-github-34729
fix: removed unused code
2025-01-02 12:16:16 +05:30
ruthra kumar
51354c894a refactor: use idx for identifying row 2025-01-02 11:54:55 +05:30
ruthra kumar
53d8e32961 Merge pull request #45033 from frappe/l10n_develop
fix: sync translations from crowdin
2025-01-02 10:47:35 +05:30
Rohit Waghchaure
dc5f2d35ac fix: removed unused code 2025-01-02 10:26:51 +05:30
rohitwaghchaure
d2b0e0fa2d Merge pull request #45036 from rohitwaghchaure/fixed-support-28464
fix: Auto BOM cost update issue
2025-01-02 10:24:25 +05:30
Rohit Waghchaure
28ea3ddd51 fix: BOM cost update issue 2025-01-02 09:44:32 +05:30
Frappe PR Bot
81a6e42620 fix: Persian translations 2025-01-01 19:47:03 +05:30
Mihir Kandoi
015fd4a05b fix: Made requested changes by mentor and fixed some bugs in Production Plan Summary report 2025-01-01 16:51:48 +05:30
rohitwaghchaure
5e977cf5a7 Merge pull request #44999 from frappe/fix_multiple_sco_pr
fix: Added patch and fallback code to prevent future issues similar …
2025-01-01 16:35:41 +05:30
rohitwaghchaure
e92af10f14 fix: slow stock transactions (#45025) 2025-01-01 14:50:26 +05:30
Mihir Kandoi
d1d01482df fix: Removed patch as instructed by mentor 2025-01-01 13:49:49 +05:30
ruthra kumar
8aa3157307 Merge pull request #44989 from aerele/update_apply_pricing_rules
fix: apply apply_pricing_rule on date change
2025-01-01 10:11:30 +05:30
rohitwaghchaure
b84c8ff960 fix: incorrect quality inspection linked in purchase receipt (#44985) 2025-01-01 08:30:00 +05:30
rohitwaghchaure
7db9bcaeac fix: precision issue (#45013) 2025-01-01 08:29:14 +05:30
rohitwaghchaure
a9cc23f242 fix: duplicate validate for stock closing entry (#45016) 2025-01-01 08:28:52 +05:30
Mihir Kandoi
575fb43f9c fix: Fixed logic in if condition causing tests to fail 2024-12-31 20:33:05 +05:30
Frappe PR Bot
2cd915fb4d fix: sync translations from crowdin (#45014)
* fix: Swedish translations

* fix: Persian translations
2024-12-31 15:41:15 +01:00
ruthra kumar
b60bd17d1d refactor: store result in variable before enumeration
helps to inspect result while debugging
2024-12-31 17:04:37 +05:30
ruthra kumar
c6634d03ad Merge pull request #44987 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-31 16:58:45 +05:30
ruthra kumar
fa3c882656 Merge pull request #44940 from aerele/bank_reconciliation_multi_currency
fix(Bank Reconciliation Tool): fetch amount in company  currency
2024-12-31 15:57:27 +05:30
ruthra kumar
e58d73525b Merge pull request #44903 from ljain112/fix-bank-reco
fix: set paid amount in party currency in bank reco payment entry
2024-12-31 15:52:35 +05:30
ruthra kumar
ebc0ed8a31 Merge pull request #44884 from ljain112/fix-item-tax-template
fix: update item_tax_rate in backend
2024-12-31 15:50:39 +05:30
diptanilsaha
2beb485d77 fix: load search term price with customer default price list 2024-12-31 14:55:01 +05:30
diptanilsaha
4b6cae156e fix: load price list rate for pos search term 2024-12-31 13:22:18 +05:30
Mihir Kandoi
65dc3505c4 fix: Added patch and fallback code to prevent future issues similiar to helpdesk ticket 28246 2024-12-31 12:53:30 +05:30
Khushi Rawat
079ec864de fix: copy accounting dimensions to asset and sales invoice (#44964)
* fix: copy accounting dimensions to asset and sales invoice

* fix: replace sql query with query builder

* refactor: reuse function for accounting dimensions

* fix: loop handling

* fix: use explicit param
2024-12-31 07:05:51 +00:00
rohitwaghchaure
7c4aecf834 fix: negative stock balance (#44990) 2024-12-31 12:30:15 +05:30
Vishnu VS
d6980a9493 fix(report): Purchase Order Analysis pymysql.err (#44957) 2024-12-31 12:21:57 +05:30
Diptanil Saha
d1ae0d784e fix: load customer default price list in pos during item selection (#44991)
fix: load customer default price list in pos
2024-12-31 12:14:29 +05:30
DHINESH00
2cbab9b875 fix: apply apply_pricing_rule date change 2024-12-30 22:47:37 +05:30
Mihir Kandoi
22d38c2af4 feat: Validate sub assembly and material request items in Production Plan and fix Production Plan summary reports not showing correct received quantity from subcontracted POs 2024-12-30 20:12:14 +05:30
Frappe PR Bot
7a5d958aba fix: Swedish translations 2024-12-30 19:48:02 +05:30
Sanket322
27195c7c96 fix: add monthly distributation and write query in qb 2024-12-30 17:56:17 +05:30
ruthra kumar
54cb99eae3 Merge pull request #44855 from mahsem/in_contex_translation_fixes
fix: in_context_translation_fixes
2024-12-30 15:56:01 +05:30
ruthra kumar
7926bf066a Merge pull request #44975 from aerele/filter-project
fix: add company filter to project
2024-12-30 15:27:37 +05:30
DHINESH00
a984aaae36 fix: fetch amount in company currency 2024-12-30 15:15:33 +05:30
ruthra kumar
bb0cf3bf78 Merge pull request #44761 from aerele/pos_discount
fix: apply discount on qty change
2024-12-30 14:56:02 +05:30
venkat102
b92f8bc514 fix: include company in filter condition 2024-12-30 14:18:55 +05:30
venkat102
1a7b09e576 fix: add company filter to project 2024-12-30 14:18:13 +05:30
ruthra kumar
ee418ffefa Merge pull request #44883 from aerele/account-party-validation
fix: Validate party on non receivable / payable account
2024-12-30 13:32:54 +05:30
Diptanil Saha
98cbb7e900 fix: pos payment using non-default mode of payment (#44920)
* fix: pos payment using non-default mode of payment (#41108)

* fix: included css syntax

* refactor: created a function to sanitize the class name

* refactor: reusing method to sanitize class name

* refactor: function rename
2024-12-30 13:27:49 +05:30
ruthra kumar
867aa9dd86 Merge pull request #44552 from HUMENTH/develop
Fix: Added Order Number and Order Date fields to the Blanket Order form.
2024-12-30 12:32:34 +05:30
ruthra kumar
4f398d8edc Merge pull request #44921 from ljain112/fix-val-itt
fix: get item tax template based on posting date
2024-12-30 12:28:58 +05:30
ruthra kumar
93b70b98bb Merge pull request #44906 from Sanket322/company_address_in_purchase_invoice
fix: set/update billing address on change of company
2024-12-30 12:22:08 +05:30
Himanshu Shivhare
5a284df51d refactor: Order Number and Order Date fields to Blanket Order 2024-12-30 12:11:32 +05:30
ruthra kumar
784a62eae8 Merge pull request #44958 from ruthra-kumar/fix_test_data_issue_on_manufacturing
refactor(test): make manufacturing test idempotent
2024-12-30 11:29:58 +05:30
ruthra kumar
f3be246df3 refactor(test): make manufacturing test idempotent 2024-12-30 11:03:25 +05:30
rohitwaghchaure
9fdeb5f826 fix: incorrect filter for BOM (#44954) 2024-12-30 09:47:16 +05:30
Frappe PR Bot
e216547084 fix: sync translations from crowdin (#44944) 2024-12-29 18:31:46 +01:00
mahsem
92b1f314ef fix: Hold_to_On_Hold 2024-12-29 14:15:52 +01:00
Frappe PR Bot
6e0dd271f5 chore: update POT file (#44951) 2024-12-29 11:33:25 +01:00
creative-paramu
50c92034ba Bank Reconciliation Statement Report Company Filter 2024-12-27 17:54:20 +05:30
rohitwaghchaure
9661c1d081 fix: ignore validate while making WO from MR (#44939) 2024-12-27 16:43:11 +05:30
ruthra kumar
6f8d6c81d5 Merge pull request #44904 from Sanket322/ignore_duplicate
fix: ignore duplicate while creating default templates
2024-12-27 14:46:58 +05:30
ljain112
70b1077286 fix: set paid amount in party currency in bank reco payment entry 2024-12-27 14:21:00 +05:30
ruthra kumar
bcae2810b9 Merge pull request #44892 from Sanket322/payment_schedule_in_is_paid
fix: clear payment schedule in purchase invoice for is_paid
2024-12-27 13:23:07 +05:30
rohitwaghchaure
303c52f134 fix: ignore inventory dimension for SABB and Pick List (#44933) 2024-12-27 12:57:52 +05:30
Sanket322
187c74ae09 fix: use meta to check field instead of doctype 2024-12-27 12:53:41 +05:30
ruthra kumar
0589fa7f3e refactor: early return is always better
validate_advance_entries() has a heavy IO bound operation. Early
return on unwanted cases is always better.
2024-12-27 12:48:25 +05:30
Sanket322
cb197fd01f fix: move code from purchase invoice to buying controller 2024-12-27 12:35:36 +05:30
Diptanil Saha
cfcc24a341 fix (pos closing entry): validation for 100 pc discount on pos invoice (#44899) 2024-12-27 11:34:41 +05:30
ruthra kumar
4f29908aa9 Merge pull request #44907 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-27 11:34:32 +05:30
ruthra kumar
e85142f996 Merge pull request #44816 from mahsem/strings_for_translation
fix: strings for translation
2024-12-27 10:56:57 +05:30
ruthra kumar
78b0b3047c Merge pull request #44815 from mahsem/relabel_rate_to_tax_rate
fix: relabel rate to tax rate
2024-12-27 10:54:30 +05:30
Shreyas Sojitra
751a0a93ef fix: attribute order in create multiple variants dialog (#44800)
* Fix : show multiple variants dialog

Fixed attribute order in create multiple variant dialog.

* fix(dialog): attribute order in create multiple variants dialog

Fixed attribute order in create multiple variant dialog.
2024-12-27 10:53:17 +05:30
rohitwaghchaure
c9088f4955 refactor: stock closing balance -> stock closing entry (#44489)
* refactor: stock closing balance

* perf: batchwise balance history report

* fix: stock ageing data for stock balance report
2024-12-26 22:57:58 +05:30
rohitwaghchaure
ab1cca0c40 fix: not able to make purchase receipt from SCR (#44919) 2024-12-26 19:09:45 +05:30
Frappe PR Bot
8f82219986 fix: Turkish translations 2024-12-26 18:35:12 +05:30
Frappe PR Bot
f5e53c9661 fix: Swedish translations 2024-12-26 18:35:08 +05:30
Nabin Hait
b998933ef0 fix: Show order tax amount in customer currency on the portal (#44915) 2024-12-26 18:18:35 +05:30
Diptanil Saha
ac26622d6e fix: limit discount value to 100 in pos cart (#44916)
* fix: limit discount value to 100 in pos cart

* fix: error message on invalid discount
2024-12-26 12:45:53 +00:00
ljain112
976e35d547 fix: get item tax template based on posting date 2024-12-26 17:18:39 +05:30
rohitwaghchaure
1319ce4bc1 fix: material request status (#44917) 2024-12-26 15:58:39 +05:30
rohitwaghchaure
614a8f106d fix: allow zero valuation rate (#44902) 2024-12-25 22:20:23 +05:30
Frappe PR Bot
888da9c1ab fix: Turkish translations 2024-12-25 18:30:08 +05:30
Frappe PR Bot
9f8448bb15 fix: Spanish translations 2024-12-25 18:29:59 +05:30
Sanket322
0adfebee85 fix: set/update billing address on change of company 2024-12-25 18:14:10 +05:30
Sanket322
9368485594 fix: ignore duplicate while creating default templates 2024-12-25 15:22:53 +05:30
Frappe PR Bot
8bcfd2429d fix: sync translations from crowdin (#44898)
* fix: Swedish translations

* fix: Turkish translations

* fix: Persian translations
2024-12-24 12:47:12 +00:00
ruthra kumar
42c8ce68ad Merge pull request #44787 from vishakhdesai/refactor-bt-allocation-query
fix: refactor query in`get_total_allocated_amount` in bank_transaction
2024-12-24 17:52:30 +05:30
ruthra kumar
0b113815c9 Merge pull request #44860 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-24 17:03:44 +05:30
ruthra kumar
7378eff0ca Merge pull request #44878 from aerele/consolidated-financial-pnl
fix: show profit and loss after period closing
2024-12-24 17:02:43 +05:30
ruthra kumar
f0a34aa587 Merge pull request #44889 from aerele/payment-entry-clearance-date
refactor: use db_set instead of set_value to trigger notification
2024-12-24 16:42:02 +05:30
Sanket322
e1fc239f3d fix: clear payment schedule in purchase invoice for is_paid 2024-12-24 16:38:51 +05:30
Karuppasamy923
8abbece7c4 fix: Set account type payable for advance account 2024-12-24 16:00:40 +05:30
venkat102
f8b923edfe refactor: use db_set instead of set_value to trigger notification 2024-12-24 15:34:39 +05:30
ljain112
de54c0b41f fix: update item_tax_rate in backend 2024-12-24 15:15:30 +05:30
rohitwaghchaure
021d077808 fix: set project in GL from the SLE (#44879) 2024-12-24 14:49:41 +05:30
Karuppasamy923
a10a15b2c3 test: add unit test to validate on non receivable / payable account 2024-12-24 13:54:37 +05:30
Karuppasamy923
c6a2d86ba6 fix: validate party on non receivable / payable account 2024-12-24 13:53:25 +05:30
ruthra kumar
c59d3bda7e Merge pull request #44794 from ljain112/fix-ldc
fix: correct tds rate with lower deduction certificate
2024-12-24 13:44:30 +05:30
venkat102
dc5cd93bf0 fix: show profit and loss after period closing 2024-12-24 12:35:38 +05:30
Abdeali Chharchhodawala
d4b21f532a fix: add Stock UOM when adding new item in POS list (#44780) 2024-12-24 10:22:32 +05:30
ruthra kumar
60694838f3 Merge pull request #44763 from vishakhdesai/fix-si-issue
fix: Paid + Write Off Amount issue in Sales Invoice
2024-12-24 10:17:16 +05:30
rohitwaghchaure
079b86044e fix: posting_time issue (#44870) 2024-12-24 09:06:37 +05:30
Khushi Rawat
0b1c3208a0 Merge pull request #44854 from khushi8112/asset-fields-precision-check
fix: asset fields precision check
2024-12-24 00:00:34 +05:30
Khushi Rawat
2f7e6230a6 fix: test case correction 2024-12-23 23:37:51 +05:30
mahsem
1f4e1811de fix: whitespace 2024-12-23 17:42:33 +01:00
Diptanil Saha
948556def5 Merge pull request #44856 from diptanilsaha/fix-pos-invoice-advanced-received
fix: fetch advance payment entries on pos invoice
2024-12-23 20:59:00 +05:30
rohitwaghchaure
c9b143b509 fix: stock entry not fetching expired batches (#44863) 2024-12-23 20:28:06 +05:30
rohitwaghchaure
7d41805d0e fix: Warehouse wise Stock Value chart roles (#44865) 2024-12-23 20:27:19 +05:30
rohitwaghchaure
54d7b742ab perf: slow query related to stock ledger entry (#44861) 2024-12-23 18:36:43 +05:30
Frappe PR Bot
2aff3ced52 fix: Esperanto translations 2024-12-23 17:32:50 +05:30
Frappe PR Bot
7497f0ca52 fix: German translations 2024-12-23 17:32:46 +05:30
Frappe PR Bot
42f2b965d1 fix: Bosnian translations 2024-12-23 17:32:43 +05:30
Frappe PR Bot
70405d9026 fix: Persian translations 2024-12-23 17:32:39 +05:30
Frappe PR Bot
4c5e9c005c fix: Chinese Simplified translations 2024-12-23 17:32:34 +05:30
Frappe PR Bot
789469f784 fix: Turkish translations 2024-12-23 17:32:31 +05:30
Frappe PR Bot
643163cc24 fix: Swedish translations 2024-12-23 17:32:26 +05:30
Frappe PR Bot
e98881cc56 fix: Russian translations 2024-12-23 17:32:21 +05:30
Frappe PR Bot
ab36dfe5ef fix: Polish translations 2024-12-23 17:32:17 +05:30
Frappe PR Bot
3892f2a1fa fix: Hungarian translations 2024-12-23 17:32:14 +05:30
Frappe PR Bot
abf624b994 fix: Arabic translations 2024-12-23 17:32:10 +05:30
Frappe PR Bot
05ceb25abc fix: Spanish translations 2024-12-23 17:32:04 +05:30
Frappe PR Bot
5cb86b1367 fix: French translations 2024-12-23 17:32:00 +05:30
rohitwaghchaure
a515a399cf fix: incoming rate should be zero for rejected items (#44857) 2024-12-23 16:58:07 +05:30
mahsem
a87e7fde03 fix: in_contex_translation_fixes 2024-12-23 11:30:00 +01:00
Diptanil Saha
a7078e5702 fix: fetch advance payment entries on pos invoice 2024-12-23 15:54:16 +05:30
Khushi Rawat
92b8768ae2 fix: asset field precision check 2024-12-23 15:42:18 +05:30
rohitwaghchaure
a2c2b8b5ad fix: do not validate qc for scrap item (#44844) 2024-12-23 15:39:04 +05:30
ruthra kumar
2dfd7472a4 Merge pull request #44850 from ruthra-kumar/remove_hardcoded_names_in_test
refacto(test): remove hardcoded names
2024-12-23 15:25:26 +05:30
ruthra kumar
ab91abb144 refacto(test): remove hardcoded names 2024-12-23 14:54:15 +05:30
Nijith anil
6f00a87a9c fix(ux): purchase invoice link in error message (#44797)
* fix(ux): purchase invoice link in error message

* chore: fix linter

---------

Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2024-12-23 09:18:32 +00:00
ruthra kumar
ab01b8fc63 Merge pull request #44738 from aerele/tds-section-code
fix: fetch tax withholding category from the voucher
2024-12-23 14:34:17 +05:30
ruthra kumar
10b7c3e0ac Merge pull request #44716 from ljain112/fix-gp-serial
fix: avg. buying amount for product bundle item with serial and batch no in gross profit report
2024-12-23 14:33:14 +05:30
ruthra kumar
fc57fb22a5 Merge pull request #44813 from vishakhdesai/acc-rec-fix
fix: update correct cost center in Accounts Receivable Report
2024-12-23 14:20:28 +05:30
ruthra kumar
fad00fedaa Merge pull request #44808 from aerele/difference_posting_date_in_si_pi
feat: Added difference_posting_date field in Sales Invoice Advance and Purchase Invoice Advance
2024-12-23 14:09:07 +05:30
Mihir Kandoi
b7699012b2 feat: Create subcontracted PO from Material Request (#44745)
* feat: Create subcontracted PO from Material Request

* fix: Made minor changes in logic to pass all test cases

* refactor: Made changes suggested by mentor and simplified logic

* test: Made changes to tests
2024-12-23 13:11:44 +05:30
ruthra kumar
cf57cb73f0 Merge pull request #44786 from ljain112/fic-adv-pv
fix: correct args for get_advance_payment_entries_for_regional
2024-12-23 12:57:42 +05:30
ruthra kumar
a2a642a5b1 Merge pull request #44751 from ljain112/fix-gp-service-item
fix: buying rate for service item in gross profit report
2024-12-23 11:45:18 +05:30
ljain112
cc3f4bb0b0 fix: avg. buying amount for product bundle item with serial and batch no in gross profit report 2024-12-23 11:22:41 +05:30
ruthra kumar
5567a41a2a Merge pull request #44681 from frappe/mergify/bp/develop/pr-44679
fix: Stock Entry uses incorrect company when generated from Pick List (backport #44679)
2024-12-23 11:12:34 +05:30
ruthra kumar
bcb7617630 Merge pull request #44644 from barredterra/lost-quotation-permissions
fix: permissions for marking Quotation as lost
2024-12-23 11:10:26 +05:30
rohitwaghchaure
fe0036e707 fix: incorrect Material Transferred for Manufacturing qty (#44823) 2024-12-23 10:57:47 +05:30
ruthra kumar
b1c9716fec Merge pull request #44812 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-23 10:21:55 +05:30
ruthra kumar
c100b68ad1 Merge pull request #44826 from Abdeali099/bank-account-typo-fix
fix: Remove typo from `Bank Account` on trash
2024-12-23 10:21:24 +05:30
ruthra kumar
085ef5df8f Merge pull request #44825 from deepeshgarg007/ledger_repost
fix: Ledger repost support for extending app doctypes
2024-12-23 09:44:43 +05:30
Abdeali Chharchhoda
ba28f6bf73 fix: Remove typo 2024-12-23 08:48:46 +05:30
Deepesh Garg
919abd2c03 fix: Add hooks for repost allowed doctypes 2024-12-22 20:34:31 +05:30
Frappe PR Bot
31803a2f53 chore: update POT file (#44822) 2024-12-22 15:09:01 +01:00
Frappe PR Bot
a4c34ad759 fix: Swedish translations 2024-12-22 17:22:40 +05:30
mahsem
3be633f6f1 fix: strings for translation 2024-12-21 15:08:19 +01:00
mahsem
1eb8b0ceef fix: relabel rate to tax rate 2024-12-21 13:49:54 +01:00
Frappe PR Bot
bf4d696f17 fix: Persian translations 2024-12-21 17:09:33 +05:30
Frappe PR Bot
7cd6bfc8a4 fix: Swedish translations 2024-12-21 17:09:29 +05:30
rohitwaghchaure
56f561cdaa fix: Duplicate entry ' EF1DE8B2E1B6' for key 'PRIMARY' (#44809) 2024-12-21 10:01:12 +05:30
vishakhdesai
3b36ce560c fix: do not set cost_center update_voucher_balance as it is set in init_voucher_balance 2024-12-20 18:41:51 +05:30
vishakhdesai
09776e9a5a fix: update correct cost center in Accounts Receivable Report 2024-12-20 18:03:42 +05:30
Frappe PR Bot
913001e44c fix: Turkish translations 2024-12-20 17:02:43 +05:30
Frappe PR Bot
5057a4e1b2 fix: Swedish translations 2024-12-20 17:02:40 +05:30
Frappe PR Bot
afea92c01d fix: Spanish translations 2024-12-20 17:02:36 +05:30
ruthra kumar
a764d16674 Merge pull request #44703 from mahsem/Swedish_tax_templates
fix: Swedish tax templates
2024-12-20 14:11:47 +05:30
rs-rethik
854e37c05c fix: update query 2024-12-20 14:00:54 +05:30
rs-rethik
2d58e845e6 refactor: convert sql query to query builder 2024-12-20 12:42:47 +05:30
ruthra kumar
6db1b3fef8 Merge pull request #44795 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-20 12:14:33 +05:30
rs-rethik
c14a2d73bf test: add unit test to validate journal entry posting date 2024-12-20 12:13:35 +05:30
rs-rethik
ff1d040a6e feat: use difference_posting_date for journal entry posting_date 2024-12-20 12:10:08 +05:30
rs-rethik
225e56cbca feat: add difference_posting_date field 2024-12-20 12:07:20 +05:30
ruthra kumar
82306c5a85 Merge pull request #44665 from mahsem/Swedish_2024_COA
fix: add Swedish_2024_COA
2024-12-20 11:56:11 +05:30
rohitwaghchaure
a7b5e2565b fix: slow posting datetime update (#44799) 2024-12-20 10:12:12 +05:30
Deepesh Garg
ed231abb54 fix: Ledger repost support for extending app doctypes 2024-12-19 17:06:54 +05:30
Frappe PR Bot
e3a7f2f2e7 fix: Persian translations 2024-12-19 17:05:19 +05:30
Frappe PR Bot
b9e96f62ef fix: Turkish translations 2024-12-19 17:05:14 +05:30
Frappe PR Bot
51137cf001 fix: Swedish translations 2024-12-19 17:05:10 +05:30
ljain112
cb9c12d495 fix: correct tds rate with lower deduction certificate 2024-12-19 16:27:04 +05:30
rohitwaghchaure
3662a6a41d fix: closing stock balance permissions (#44791) 2024-12-19 14:59:33 +05:30
ruthra kumar
93ec962aae Merge pull request #44746 from ljain112/fix-itt
fix: correct args for get_item_tax_map
2024-12-19 13:52:33 +05:30
rohitwaghchaure
90baa38f64 perf: SABB (#44764) 2024-12-19 13:00:31 +05:30
vishakhdesai
2ce07865d3 fix: failing tests fixed 2024-12-19 12:55:11 +05:30
vishakhdesai
6b847cdb62 fix: refactor query in get_total_allocated_amount in bank_transaction 2024-12-19 12:27:06 +05:30
ljain112
df13a4cc2f fix: correct args for get_advance_payment_entries_for_regional 2024-12-19 12:04:04 +05:30
ruthra kumar
700dc05b55 Merge pull request #44785 from ruthra-kumar/expanded_screenshot
chore: expand screenshot section by default
2024-12-19 10:55:45 +05:30
ruthra kumar
ce9f10b387 chore: expand screenshot section by default 2024-12-19 10:43:36 +05:30
Mihir Kandoi
3eba6bf3dd feat(subcontracting): Added provision to create multiple Subcontracting Orders against a single Purchase Order (#44711)
* feat(subcontracting): Added provision to create multiple Subcontracting Orders from a single Subcontracted Purchase Order

* refactor(new_sc_flow_2): Fixed error thrown by semgrep
2024-12-18 20:38:21 +05:30
rohitwaghchaure
779dd2d798 fix: POS Closing entry issue (#44772) 2024-12-18 20:19:36 +05:30
ruthra kumar
6f99e9959d Merge pull request #44771 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-18 17:54:02 +05:30
vishakhdesai
1fd7ba7c88 fix: Paid + Write Off Amount issue in Sales Invoice 2024-12-18 17:29:55 +05:30
Nabin Hait
febdf4c61e fix: added docs.frappe.io in documentation_url (#44776) 2024-12-18 11:58:22 +00:00
Frappe PR Bot
c798a68e5d fix: Persian translations 2024-12-18 15:42:28 +05:30
Frappe PR Bot
663372a23e fix: Swedish translations 2024-12-18 15:42:23 +05:30
ruthra kumar
7fed467354 Merge pull request #44765 from ljain112/fix-pl-error
fix: 'str' object has no attribute 'get_sql'
2024-12-18 14:12:29 +05:30
ljain112
9a43acb65c fix: 'str' object has no attribute 'get_sql' 2024-12-18 13:47:37 +05:30
ruthra kumar
54eedaeeff Merge pull request #44758 from ruthra-kumar/fix_broken_link
fix: use utility method to generate url
2024-12-18 11:02:01 +05:30
ruthra kumar
b970eb8b15 fix: use utility method to generate url 2024-12-18 10:54:21 +05:30
DHINESH00
352b82bc0b fix: apply discount on qty change 2024-12-18 10:51:04 +05:30
ruthra kumar
878f76455b Merge pull request #44708 from aerele/pricing-rule-discount
fix: update discount when pricing rule is changed
2024-12-17 20:42:04 +05:30
ruthra kumar
5c9e8fb4da Merge pull request #44695 from ljain112/fix-fin-stat
fix: User permissions in financial statements
2024-12-17 20:37:35 +05:30
ljain112
5ea131c763 fix: using query.walk() for escaping 2024-12-17 18:49:38 +05:30
ljain112
8d6e79a16f fix: buying rate for service item in gross profit report 2024-12-17 17:54:08 +05:30
ruthra kumar
7ac7a40aec Merge pull request #44739 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-17 17:30:04 +05:30
ruthra kumar
3342fa1440 Merge pull request #44685 from aerele/mop-bank-account
fix: set company bank account if default account not set in mode of p…
2024-12-17 17:18:35 +05:30
ljain112
fe4eb8e6db fix: correct args for get_item_tax_map 2024-12-17 17:03:41 +05:30
ruthra kumar
a819b1feaa Merge pull request #44742 from ruthra-kumar/readme_update
chore: update readme
2024-12-17 15:55:16 +05:30
ruthra kumar
8205000195 chore: move screenshots to key features 2024-12-17 15:41:26 +05:30
Frappe PR Bot
4387e09ee8 fix: Swedish translations 2024-12-17 14:52:45 +05:30
Frappe PR Bot
3be6390a12 fix: Spanish translations 2024-12-17 14:52:34 +05:30
ruthra kumar
c33b9922a5 chore: more screenshots 2024-12-17 14:17:08 +05:30
ruthra kumar
c25ef357a5 chore: update headers 2024-12-17 14:15:12 +05:30
venkat102
09e64594db fix: fetch tax withholding category from the voucher 2024-12-17 13:15:41 +05:30
venkat102
1663c7983e chore: use get function 2024-12-17 13:15:02 +05:30
rohitwaghchaure
1f5d7072e7 fix: purchase return entry issue (#44721) 2024-12-17 12:29:20 +05:30
ruthra kumar
37fb6d12da Merge pull request #44660 from vorasmit/tds-jv-base-total
fix: better indicator base amount for Tax Witholding in Journal Entry
2024-12-17 11:49:37 +05:30
ruthra kumar
94c64235d4 Merge pull request #44650 from aerele/multiselect_cc_in_process_statement_of_accounts
feat: Multiselect cc in process statement of accounts
2024-12-17 11:34:54 +05:30
ruthra kumar
8b89cc69c1 Merge pull request #44712 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-17 11:29:19 +05:30
mahsem
8a5f7ec4d7 feat: swedish COA 2024-12-17 11:22:42 +05:30
rs-rethik
5401cf9647 chore: remove irrelevant import 2024-12-17 11:10:25 +05:30
rs-rethik
494ac04f8e refactor: convert sql query to query builder 2024-12-17 11:10:25 +05:30
rs-rethik
2a6be127ef fix: update cc_to multiselect in process statement of accounts 2024-12-17 11:10:25 +05:30
rs-rethik
4de180feee feat: change type link to multiselect 2024-12-17 11:10:25 +05:30
rohitwaghchaure
852596dbe6 fix: pos invoice return reference missing (#44720) 2024-12-17 11:05:18 +05:30
ruthra kumar
84dff3601a Merge pull request #44646 from barredterra/validate-discount-date
feat: validate discount date in payment schedule
2024-12-17 10:58:15 +05:30
Frappe PR Bot
b565b67cc7 fix: Esperanto translations 2024-12-17 10:38:22 +05:30
Frappe PR Bot
12634d0bd6 fix: German translations 2024-12-17 10:38:22 +05:30
Frappe PR Bot
fda57420a5 fix: Bosnian translations 2024-12-17 10:38:22 +05:30
Frappe PR Bot
bf0cfc4704 fix: Persian translations 2024-12-17 10:38:22 +05:30
Frappe PR Bot
4af0365719 fix: Chinese Simplified translations 2024-12-17 10:38:22 +05:30
Frappe PR Bot
30d2a2bce5 fix: Turkish translations 2024-12-17 10:38:22 +05:30
Frappe PR Bot
e82f993d94 fix: Swedish translations 2024-12-17 10:38:22 +05:30
Frappe PR Bot
9e8304c16f fix: Russian translations 2024-12-17 10:38:21 +05:30
Frappe PR Bot
efa00fd9c6 fix: Polish translations 2024-12-17 10:38:21 +05:30
Frappe PR Bot
e90d2c2cfe fix: Hungarian translations 2024-12-17 10:38:21 +05:30
Frappe PR Bot
30735b339d fix: Arabic translations 2024-12-17 10:38:21 +05:30
Frappe PR Bot
7eb7a7fa36 fix: Spanish translations 2024-12-17 10:38:21 +05:30
Frappe PR Bot
0e68c433db fix: French translations 2024-12-17 10:38:21 +05:30
rohitwaghchaure
95da0913f6 fix: unsupported operand type (#44722) 2024-12-17 09:19:58 +05:30
rohitwaghchaure
5f539619bc fix: delink SABB from cancelled SLEs (#44691) 2024-12-16 22:23:13 +05:30
ruthra kumar
5d16e4aefe Merge pull request #44714 from ruthra-kumar/update_readme
chore: update readme
2024-12-16 19:55:39 +05:30
ruthra kumar
ac4ee1b005 chore: more changes
- reduce image count and update hero image
- update docker setup
2024-12-16 19:28:30 +05:30
ruthra kumar
9ebdd4d79a Merge pull request #44713 from ruthra-kumar/ci_trigger
fix: broken CI
2024-12-16 16:52:18 +05:30
ruthra kumar
dc02cb8119 chore: update readme 2024-12-16 16:44:38 +05:30
ruthra kumar
eb1e36ca22 fix: broken CI
- always install wkhtmltopdf
- remove specific version on mariadb-client
2024-12-16 16:27:13 +05:30
ruthra kumar
f8cf1983a4 Merge pull request #44704 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-16 10:45:17 +05:30
venkat102
8338d1d5b4 fix: update discount when pricing rule is changed 2024-12-15 22:55:24 +05:30
Frappe PR Bot
62c553edeb chore: update POT file (#44707) 2024-12-15 12:27:21 +01:00
Frappe PR Bot
37fc2068b5 fix: Persian translations 2024-12-15 12:55:00 +05:30
Frappe PR Bot
15d2ca0c06 fix: Persian translations 2024-12-14 12:54:15 +05:30
Frappe PR Bot
4d34eefde4 fix: Swedish translations 2024-12-14 12:54:09 +05:30
mahsem
73112fa3c9 fix: Swedish tax templates 2024-12-14 07:12:19 +01:00
mahsem
6119d4384a fix: better description of tab name (#44697) 2024-12-13 19:46:31 +01:00
ruthra kumar
4409dadfe2 Merge pull request #44585 from blaggacao/fix/old-data-from-2009-in-migration
fix: migration; make it resilient against old, non-conforming data
2024-12-13 18:22:06 +05:30
ruthra kumar
3a4d8a7bbd Merge pull request #44676 from ljain112/fix-ac-rec-pay,emt-term
fix: remove invalid filter in Account Receivable report
2024-12-13 17:08:41 +05:30
ljain112
578ca230fe fix: remove invalid filter in Account Receivable report 2024-12-13 16:37:19 +05:30
ruthra kumar
d07f9d746a refactor: ignore selective malformed json 2024-12-13 16:00:39 +05:30
Navin R C
48b49cdea4 fix: SQL syntax error in Purchase Receipt query for empty filters (#44636)
fix(po-analysis): handle SQL error due to empty data in IN() clause

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-12-13 10:19:38 +00:00
ruthra kumar
168baae118 Merge pull request #44696 from akhilnarang/add-type-selling-workspace
fix(selling): set workspace type and app
2024-12-13 15:17:06 +05:30
ruthra kumar
693b073088 Merge pull request #44556 from aerele/ledger-summary-report
feat: add accounting dimensions in ledger summary reports
2024-12-13 15:12:18 +05:30
ruthra kumar
2c5b5d4117 Merge pull request #44604 from akhilnarang/drop-pytz-usage
refactor: drop pytz
2024-12-13 15:02:14 +05:30
Akhil Narang
f704ade417 fix(selling): set workspace type and app
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
2024-12-13 14:40:15 +05:30
Khushi Rawat
d8f55923c9 Merge pull request #44690 from khushi8112/handle-zero-salvage-value-case
fix: handle zero salvage value case
2024-12-13 14:31:03 +05:30
ljain112
a626372d66 fix: User permissions in financial statements 2024-12-13 13:46:15 +05:30
Khushi Rawat
325b20491a fix: make rate of depreciation mandatory 2024-12-13 12:36:30 +05:30
Khushi Rawat
d84aeef0bb fix: handle zero salvage value case 2024-12-13 12:31:38 +05:30
ruthra kumar
faa6a3dec0 Merge pull request #43930 from lbrandh/fix_timestrings
fix: use get_datetime_as_string with correct time format
2024-12-13 12:07:56 +05:30
Diógenes Souza
d2cab83003 fix: Wrong allocated_amount for sales_team in gross_profit report (#42989)
* fix: Wrong allocated_amount for sales_team in gross_profit report

* style: Removes whitespaces

---------

Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2024-12-13 11:56:55 +05:30
venkat102
91c7e3d5f3 fix: set company bank account if default account not set in mode of payment 2024-12-13 11:22:17 +05:30
Nicolas Pereira
cd693b5fa4 fix: Stock Entry uses incorrect company when generated from Pick List (#44679)
(cherry picked from commit 00898be8e4)
2024-12-13 04:52:54 +00:00
ruthra kumar
63123471b3 Merge pull request #44621 from mahsem/doc.status_POS
fix: add doc.status to translation from POS
2024-12-13 10:22:23 +05:30
ruthra kumar
ecc213b06f Merge pull request #44668 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-13 10:12:57 +05:30
ruthra kumar
b584212edb chore: Update images in readme (#44667)
* chore: image files

* chore: typo and links

* chore: update logo

* chore: link screenshots

* chore: change image width

* chore: border radius for images

* chore: more formatting
2024-12-12 17:09:22 +05:30
rohitwaghchaure
4385349e36 fix: validate returned serial nos and batches (#44669) 2024-12-12 15:24:40 +05:30
Venkatesh
9ef9ff3de8 fix: make projected qty editable after submit (#44670) 2024-12-12 14:56:20 +05:30
Frappe PR Bot
4d12134552 fix: German translations 2024-12-12 12:37:03 +05:30
Frappe PR Bot
7199b6c094 fix: Swedish translations 2024-12-12 12:36:59 +05:30
rohitwaghchaure
15c7d26378 fix: valuation rate for batch in stock reconciliation (#44657)
fix: valuation rate for batch in stock reco
2024-12-11 21:02:38 +05:30
ruthra kumar
033075c023 Merge pull request #44663 from ruthra-kumar/update_readme
chore: update readme
2024-12-11 20:59:44 +05:30
ruthra kumar
4c68fa46e7 chore: use numbered list 2024-12-11 20:33:34 +05:30
ruthra kumar
a793017628 chore: update readme 2024-12-11 20:28:15 +05:30
Smit Vora
56a0a0db18 fix: better indicator base amount for Tax Witholding in Journal Entry 2024-12-11 17:57:47 +05:30
Venkatesh
3595783202 Merge pull request #44533 from aerele/consolidated-gl
Consider against_voucher_no when voucher_no is filtered
2024-12-11 10:32:30 +00:00
ruthra kumar
67ac3a5173 Merge pull request #44651 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-11 14:58:17 +05:30
ruthra kumar
3f4832631f Merge pull request #44493 from aerele/free-item-seperate-row
fix: update free item qty while adding same item in seperate row
2024-12-11 14:53:59 +05:30
ruthra kumar
542d0140f2 Merge pull request #44652 from frappe/ruthra-kumar-patch-1 2024-12-11 12:57:57 +05:30
ruthra kumar
d9408eae44 chore: footer logo 2024-12-11 12:55:41 +05:30
ruthra kumar
644c48ba46 chore: add end tag 2024-12-11 12:51:59 +05:30
ruthra kumar
687894584f chore(readme): update links 2024-12-11 12:46:24 +05:30
ruthra kumar
f03a0d8015 Update README.md 2024-12-11 12:40:53 +05:30
Frappe PR Bot
3a2b805a55 fix: Persian translations 2024-12-11 12:38:28 +05:30
Frappe PR Bot
ae89a81ecb fix: Swedish translations 2024-12-11 12:38:24 +05:30
Sugesh393
79fd881ad5 chore: update variable names 2024-12-11 11:29:21 +05:30
Khushi Rawat
eac3ae5627 Merge pull request #44647 from khushi8112/rename-cost-to-value
fix: switched asset terminology from cost to value
2024-12-11 01:09:26 +05:30
Khushi Rawat
ee9a2952d6 fix: switched asset terminology from cost to value 2024-12-11 00:18:04 +05:30
barredterra
11644241fa feat: validate discount date in payment schedule 2024-12-10 17:23:00 +01:00
ruthra kumar
a7d964212e Merge pull request #44293 from ruthra-kumar/refactor_transaction_js
refactor: move `item_code` reactivity to server-side
2024-12-10 21:12:42 +05:30
barredterra
4d5241486f fix: permissions for marking Quotation as lost 2024-12-10 14:28:22 +01:00
ruthra kumar
1467610109 fix: linter; dont change doc after DB update 2024-12-10 17:48:13 +05:30
ruthra kumar
267d9606f8 refactor(test): disable unwanted dimensions 2024-12-10 17:48:13 +05:30
ruthra kumar
22c1608745 test: assert all reqd are set 2024-12-10 17:48:13 +05:30
ruthra kumar
c97e058bc6 chore: rename and move test file 2024-12-10 17:48:13 +05:30
ruthra kumar
8a710f85e2 refactor: replcate deprecated cur_frm 2024-12-10 17:48:13 +05:30
ruthra kumar
6ea9c0c48d refactor: pass config through boot 2024-12-10 17:48:13 +05:30
ruthra kumar
67b28a7864 refactor: configurable reactivity 2024-12-10 17:48:13 +05:30
ruthra kumar
b21d5934e6 refactor: make it configurable 2024-12-10 17:48:13 +05:30
ruthra kumar
a06a6ccaa6 test: auto-filling of basic details on items 2024-12-10 17:48:13 +05:30
ruthra kumar
5b4987e160 chore: cleanup code 2024-12-10 17:48:13 +05:30
ruthra kumar
364126d2e4 refactor: remove unneccesary 'item' variable 2024-12-10 17:48:13 +05:30
ruthra kumar
d68f30769a refactor: only use 'item_obj' 2024-12-10 17:48:13 +05:30
ruthra kumar
d0153065b0 chore: rename method 2024-12-10 17:48:13 +05:30
ruthra kumar
af580c9977 refactor: dynamic dimension handling and more 2024-12-10 17:48:13 +05:30
ruthra kumar
88e6b572a8 refactor: move remaining logic
Handle internal parties
conversion factor and applying pricing list rate
2024-12-10 17:48:13 +05:30
ruthra kumar
600d92100c refactor: use helper method to fetch item details 2024-12-10 17:48:12 +05:30
ruthra kumar
ce1ee98a12 refactor: moving item code trigger to server side
1 to 1 barebones migration
2024-12-10 17:48:12 +05:30
ruthra kumar
f2783fbb55 Merge pull request #44630 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-10 15:47:29 +05:30
Khushi Rawat
968762cb3e Merge pull request #44631 from khushi8112/salvage-value-precision
fix: precision check for salvage value
2024-12-10 13:38:05 +05:30
Khushi Rawat
da09316d4c fix: precision check for salvage value 2024-12-10 12:54:02 +05:30
Frappe PR Bot
b839663c48 fix: Swedish translations 2024-12-10 12:32:47 +05:30
ruthra kumar
01d1c67869 Merge pull request #44581 from ljain112/fix-drop-ship
fix: allow all dispatch address for drop ship invoice
2024-12-10 10:17:47 +05:30
mahsem
94d7e5964b fix: add doc.status to translation from POS 2024-12-09 16:24:23 +01:00
rohitwaghchaure
f5c038cd1b fix: 'Use Multi-Level BOM' checkbox default value (#44618) 2024-12-09 20:22:51 +05:30
rohitwaghchaure
616bb383c5 fix: do not allow to inward same serial nos multiple times (#44617) 2024-12-09 19:01:33 +05:30
Sugesh393
7614f166d8 refactor: convert sql queries to qb queries 2024-12-09 18:32:45 +05:30
ruthra kumar
6e02e29e4e Merge pull request #44545 from ljain112/fix-pr-adv
fix: only show advance payment entries where "book_advance_payments_in_separate_party_account" is true
2024-12-09 16:25:47 +05:30
ruthra kumar
d847f75ade chore: remove 'debug' param and linter fix 2024-12-09 15:59:40 +05:30
rohitwaghchaure
314c7b8d2a fix: not able to make sales return entry (#44605) 2024-12-09 14:55:47 +05:30
ruthra kumar
2195529c26 Merge pull request #44607 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-09 14:02:32 +05:30
ruthra kumar
f9f8ef0e17 Merge pull request #44513 from ljain112/draft-status-color
fix: correct color for draft in list view
2024-12-09 13:33:48 +05:30
rohitwaghchaure
9ad79625e0 fix: description overwrite on qty change (#44606) 2024-12-09 12:37:36 +05:30
Frappe PR Bot
603ca0963a fix: Turkish translations 2024-12-09 12:35:01 +05:30
Frappe PR Bot
0c18fb575e fix: Swedish translations 2024-12-09 12:34:58 +05:30
ruthra kumar
a08a66df92 Merge pull request #44495 from devdiogenes/prevent-set_payment_schedule-si-return
fix: Prevent set_payment_schedule when creating Sales Invoice that is return
2024-12-09 12:21:04 +05:30
Akhil Narang
af3743f09e refactor: drop pytz
Follow up to https://github.com/frappe/frappe/pull/28093 so I can drop the pytz dependency

Signed-off-by: Akhil Narang <me@akhilnarang.dev>
2024-12-09 11:37:09 +05:30
ruthra kumar
a6aaaa5525 Merge pull request #44582 from mahsem/doc.status
fix: add doc.status for translation
2024-12-09 11:20:46 +05:30
Frappe PR Bot
f0270f69f0 fix: sync translations from crowdin (#44583)
* fix: Swedish translations

* fix: Swedish translations

* fix: French translations

* fix: Spanish translations

* fix: Arabic translations

* fix: Hungarian translations

* fix: Polish translations

* fix: Russian translations

* fix: Swedish translations

* fix: Turkish translations

* fix: Chinese Simplified translations

* fix: Persian translations

* fix: Bosnian translations

* fix: German translations

* fix: Esperanto translations
2024-12-08 19:49:02 +01:00
Frappe PR Bot
426fe96e5f chore: update POT file (#44599) 2024-12-08 11:04:16 +01:00
rohitwaghchaure
42d238da14 fix: BOM has not attr required items (#44598) 2024-12-08 15:28:35 +05:30
rohitwaghchaure
8806d17ef1 fix: currency symbol in SCO and SCR (#44577) 2024-12-07 14:05:36 +05:30
rohitwaghchaure
d871e21a40 fix: BOM name issue (#44586) 2024-12-07 12:20:58 +05:30
David
14a57795d5 fix: migration; make it resilient against old, non-conforming data 2024-12-06 17:52:54 +01:00
rohitwaghchaure
93e9517f5d fix: BOM for variant items (#44580) 2024-12-06 22:14:50 +05:30
mahsem
dda272220b fix: add docstatus for translation 2024-12-06 14:59:16 +01:00
ljain112
125a352bc2 fix: allow all dispatch address for drop ship invoice 2024-12-06 17:41:44 +05:30
rohitwaghchaure
b7a3c6b6ca fix: BOM name issue (#44575)
fix: bom name issue
2024-12-06 16:54:38 +05:30
Raffael Meyer
72256565bb fix(Bank Transaction): error in party matching should not block submitting (#44416) 2024-12-06 10:19:23 +01:00
ruthra kumar
d5a208cf69 Merge pull request #44538 from mahsem/patch-10
fix: add labels for translation in purchase_order_analysis.py
2024-12-06 12:18:43 +05:30
ruthra kumar
cc931d20c2 Merge pull request #44539 from mahsem/patch-11
fix: add labels for translation in production_analytics.py
2024-12-06 12:14:36 +05:30
ruthra kumar
0e38e9417d Merge pull request #44541 from mahsem/patch-12
fix: add labels for translation in quality_inspection_summary.py
2024-12-06 12:13:34 +05:30
ruthra kumar
c116815c14 Merge pull request #44558 from mahsem/patch-4
fix: add string for translation in delayed_tasks_summary.py
2024-12-06 12:12:42 +05:30
ruthra kumar
53d183ae03 Merge pull request #44559 from mahsem/patch-9
fix: add strings for translation payment_terms_status_for_sales_order.py
2024-12-06 12:07:58 +05:30
ruthra kumar
93c75901cf Merge pull request #44560 from mahsem/patch-13
fix: add labels for translation in sales_order_analysis.py
2024-12-06 11:37:54 +05:30
ruthra kumar
e8e13674ef Merge pull request #44557 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-06 11:32:45 +05:30
Sugesh393
b9f9fc0afe Merge branch 'develop' of https://github.com/aerele/erpnext into ledger-summary-report 2024-12-05 21:34:36 +05:30
mahsem
8a554a5538 fix: add labels for translation in sales_order_analysis.py 2024-12-05 16:40:00 +01:00
mahsem
7d244051c8 fix: add strings for translation payment_terms_status_for_sales_order.py 2024-12-05 16:20:31 +01:00
mahsem
84b54f549a fix: add string for translation in delayed_tasks_summary.py 2024-12-05 16:13:07 +01:00
Frappe PR Bot
c26114b66a fix: Turkish translations 2024-12-05 19:52:53 +05:30
Frappe PR Bot
98da9b56e9 fix: Swedish translations 2024-12-05 19:52:48 +05:30
Sugesh393
9610a33d23 fix: remove irrelavent conditions 2024-12-05 18:51:29 +05:30
Deepesh Garg
1ac292285e chore: Ignore stock validation for non stock invoices (#44549)
* chore: Ignore stock validation for non stock invoices

* chore: Ignore stock validation for non stock invoices
2024-12-05 18:14:23 +05:30
David Arnold
30c3892f9d chore: adapt filter signature to frappe/frappe#28218 (#44553) 2024-12-05 11:32:32 +00:00
rohitwaghchaure
1571dff3ef fix: variant qty while making work order from BOM (#44548) 2024-12-05 15:51:33 +05:30
rohitwaghchaure
024c442087 fix: not able to make PO for returned qty from material request (#44540) 2024-12-05 15:29:34 +05:30
rohitwaghchaure
7249cf0001 fix: update qty in SABB if qty changed in stock reco (#44542) 2024-12-05 15:28:38 +05:30
ljain112
ffd6a8424b fix: only show advance payment entries where "book_advance_payments_in_separate_party_account" is true 2024-12-05 15:18:44 +05:30
Khushi Rawat
322c788760 Merge pull request #44537 from mahsem/patch-9
fix: add title for translation in  asset.js
2024-12-05 15:12:39 +05:30
mahsem
6ff4704345 fix: add labels for translation in quality_inspection_summary.py 2024-12-05 09:17:35 +01:00
mahsem
9b09116576 fix: add labels for translation in production_analytics.py 2024-12-05 09:02:05 +01:00
mahsem
342a398bec fix: add labels for translation in purchase_order_analysis.py 2024-12-05 08:41:02 +01:00
mahsem
61439132a4 fix: add title for translation in asset.js 2024-12-05 08:37:43 +01:00
rohitwaghchaure
14f2b0ab0e fix: consider zero valuation rate for serial nos (#44532) 2024-12-05 12:50:27 +05:30
rohitwaghchaure
5413cf9f1f fix: incorrect stock UOM for BOM raw materials (#44528)
fix: incorrect stock uom for BOM raw materials
2024-12-05 11:00:11 +05:30
ruthra kumar
707d8eddc5 Merge pull request #44503 from mahsem/patch-7
fix: add strings for translation in pos_item_cart.js
2024-12-05 10:18:10 +05:30
Sugesh393
901bcd5c43 feat: add accounting dimensions in ledger summary reports 2024-12-05 10:14:15 +05:30
ruthra kumar
abd2314894 Merge pull request #44511 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-05 10:13:24 +05:30
ruthra kumar
fb5cbc43a2 Merge pull request #44512 from mahsem/patch-8
fix: add label strings for translation in pos_controller.js
2024-12-05 10:11:40 +05:30
ruthra kumar
31efaf6dbf chore: linter fix 2024-12-05 10:10:34 +05:30
ruthra kumar
2f38390b48 Merge pull request #44501 from mahsem/patch-5
fix: strings for translation in pos_past_order_summary.js
2024-12-05 10:00:17 +05:30
mahsem
138ffc4e93 refactor: translatable label on pos payments (#42081)
* Use better description in pos_payment.js 

Use Change Amount instead of Change and To Be Paid in pos_payment.js and be consistent with other strings

* change_amount_pos_payment.js
2024-12-05 09:59:43 +05:30
ruthra kumar
ba8ba79335 Merge pull request #44500 from mahsem/patch-4
fix: add labels for translation in sales_order.js
2024-12-05 09:58:05 +05:30
rohitwaghchaure
353610ce61 fix: inv dimensions fields not creating for standard doctype (#44504) 2024-12-04 21:26:15 +05:30
ljain112
143acf2330 fix: correct color for draft in list view 2024-12-04 20:40:08 +05:30
mahsem
bd77a5557d fix: add label strings for translation in pos_controller.js 2024-12-04 15:40:55 +01:00
Frappe PR Bot
163ff71ece fix: Persian translations 2024-12-04 19:48:36 +05:30
Frappe PR Bot
6a9a4f10f0 fix: Turkish translations 2024-12-04 19:48:28 +05:30
Frappe PR Bot
663b66ca1d fix: Swedish translations 2024-12-04 19:48:24 +05:30
David Arnold
029dc948fe fix: client-side taxes calculation (#44510)
closes: #44328
2024-12-04 13:08:50 +00:00
rohitwaghchaure
4001166ecc fix: required by date in the reorder material request (#44497) 2024-12-04 17:45:07 +05:30
rohitwaghchaure
b4534e56e4 fix: duplicate required items in the CSV (#44498) 2024-12-04 17:43:51 +05:30
mahsem
4b72b60f1a fix: add strings for translation in pos_item_cart.js 2024-12-04 10:12:34 +01:00
mahsem
23c846d4b9 fix: strings for translation in pos_past_order_summary.js 2024-12-04 09:07:09 +01:00
mahsem
d544328ffe fix: add labels for translation in sales_order.js 2024-12-04 08:58:16 +01:00
mahsem
6585fabdb1 fix: add strings for translation in timesheet.js (#44496) 2024-12-04 13:05:48 +05:30
ruthra kumar
e6be1021f9 Merge pull request #44453 from n-traore/vf_ohada_charts_accounts
feat: Create Syscohada charts of accounts
2024-12-04 11:44:05 +05:30
Diógenes Souza
d1dc7ec7bf Merge branch 'frappe:develop' into prevent-set_payment_schedule-si-return 2024-12-03 17:51:03 -03:00
Frappe PR Bot
f74c99be9d fix: sync translations from crowdin (#44486)
fix: Turkish translations
2024-12-03 21:09:01 +01:00
Raffael Meyer
032ef62b14 fix: if-block + indentation (#44494) 2024-12-03 20:06:50 +00:00
venkat102
329d14957b fix: validate negative qty 2024-12-04 01:08:54 +05:30
venkat102
8bce382834 fix: update free item qty while adding same item in seperate row 2024-12-04 00:56:36 +05:30
Raffael Meyer
657c85638c fix: get value from dict (#44492)
`doc.taxes` is not always a `frappe._dict`, it can also be a regular `dict`. Resolves #44328
2024-12-03 19:03:57 +00:00
ruthra kumar
483fd124fc Merge pull request #44339 from vishakhdesai/hd-ticket-20084
fix: move `validate_total_debit_and_credit` from`validate` to`on_submit` in Journal Entry
2024-12-03 18:08:59 +05:30
ruthra kumar
c3ace82db8 refactor: validate debit and credit on before_submit 2024-12-03 17:42:11 +05:30
ruthra kumar
88b0af1696 Merge pull request #44467 from ljain112/fix-multi-gp
fix: Multiple Fixes in Gross Profit Report
2024-12-03 17:29:31 +05:30
ruthra kumar
fc0122ce76 chore: fix typo 2024-12-03 15:39:30 +05:30
ruthra kumar
d0c522ee46 Merge pull request #44450 from aerele/payment-request-partial-payment-pr
fix: calculate submitted payment entry amount for grand total
2024-12-03 14:51:47 +05:30
ruthra kumar
f11eab06c3 Merge pull request #44415 from ljain112/fix-incoming-rate
fix: adjusted incoming rate for zero rated item in purchase receipt
2024-12-03 14:24:33 +05:30
ruthra kumar
9bbb953e26 Merge pull request #44373 from Ninad1306/valuation_rate_fix
fix: Always Calculate `sales_incoming_rate` for Internal Transfers
2024-12-03 14:17:04 +05:30
ruthra kumar
f21283d829 Merge pull request #44470 from ruthra-kumar/rearrange_fields_in_company
refactor(UI): Rearranging fields under new sections
2024-12-03 10:29:25 +05:30
ruthra kumar
94de5c4e7e Merge pull request #44473 from frappe/l10n_develop
fix: sync translations from crowdin
2024-12-03 10:16:39 +05:30
Frappe PR Bot
dc645b3906 fix: Persian translations 2024-12-02 17:26:34 +05:30
Frappe PR Bot
f758dfcbe1 fix: Swedish translations 2024-12-02 17:26:22 +05:30
Frappe PR Bot
fdfd51c0fd fix: Spanish translations 2024-12-02 17:26:07 +05:30
ruthra kumar
7244754d28 refactor(UI): Rearranging fields under new sections 2024-12-02 15:37:38 +05:30
ljain112
4e6a5893e7 fix: correct buying amount for product bundel 2024-12-02 15:20:20 +05:30
Sagar Vora
7cc111f790 fix: set correct unallocated amount in Payment Entry (#43958)
* fix: set correct unallocated amount in Payment Entry

* fix: add checkbox and other logic fix

* fix: patch to set is_exchange_gain_loss in Payment Entry deductions

* fix: consider deductions except exch. gain/loss

* fix: set exchange gain loss in payment entry

* fix: separate function to set exchange gain loss

* fix: failing test cases

* fix: add cash disc. row first

* fix: review changes

* fix: changes as per review

* fix: failing test cases

* fix: review

* fix: wait for request to complete before updating exchange gain loss

* fix: review

---------

Co-authored-by: vishakhdesai <vishakhdesai@gmail.com>
Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2024-12-02 14:54:29 +05:30
rohitwaghchaure
7de9c14a2c fix: incorrect Gross Margin on project (#44461) 2024-12-02 14:22:41 +05:30
ljain112
a86b223aed fix: remove queries 2024-12-02 14:08:21 +05:30
ruthra kumar
810a2c8fc1 Merge pull request #44412 from ljain112/fix-common-party
fix: handle multi currency in common party journal entry
2024-12-02 12:38:34 +05:30
ruthra kumar
6b6798bee6 Merge pull request #44437 from Abdeali099/report-data-trnslation
fix: Added translation for `Account` column
2024-12-02 12:22:38 +05:30
Abdeali Chharchhoda
e355b18c0c Merge branch 'develop' into report-data-trnslation 2024-12-02 11:33:00 +05:30
Abdeali Chharchhoda
a4f8315602 fix: Translate Party Account column label 2024-12-02 11:23:10 +05:30
Frappe PR Bot
6df0ea153d fix: sync translations from crowdin (#44432)
* fix: Swedish translations

* fix: Turkish translations

* fix: Swedish translations

* fix: Persian translations

* fix: French translations

* fix: Spanish translations

* fix: Arabic translations

* fix: Hungarian translations

* fix: Polish translations

* fix: Russian translations

* fix: German translations

* fix: Swedish translations

* fix: Turkish translations

* fix: Chinese Simplified translations

* fix: Persian translations

* fix: Bosnian translations

* fix: Esperanto translations
2024-12-01 22:35:17 +00:00
Khushi Rawat
74624828e7 Merge pull request #44456 from khushi8112/missing-ctx-argument
fix: missing ctx in API function calls
2024-12-01 20:28:54 +05:30
Khushi Rawat
55cb1c54e0 fix: missing ctx in API function calls 2024-12-01 17:59:44 +05:30
Frappe PR Bot
bd042d0fff chore: update POT file (#44455) 2024-12-01 11:18:19 +01:00
Nelly Traore
aa8254963c feat: add Syscohada charts of accounts 2024-11-30 19:51:48 +00:00
Nabin Hait
04c7c0bb66 fix: Reordered fields for asset doctype (#44423) 2024-11-30 22:00:17 +05:30
Sagar Vora
279dcabf38 Merge pull request #44443 from sagarvora/minor-perfs
perf: reduce queries during transaction save
2024-11-30 00:45:46 +05:30
Sagar Vora
9ee4f58e1b Merge pull request #44439 from Abdeali099/translation-bug
fix: added fieldname to avoid fieldname to translate
2024-11-30 00:24:53 +05:30
Sagar Vora
b6b8a06fda perf: reduce queries during transaction save 2024-11-30 00:20:18 +05:30
Sagar Vora
6de7320ef4 perf: cache product bundle items at document level (#44440) 2024-11-29 17:21:32 +00:00
Abdeali Chharchhoda
b80022133c fix: added fieldname to avoid fieldname to translate 2024-11-29 18:13:03 +05:30
rohitwaghchaure
810c72a30c fix: number format in the message (#44435) 2024-11-29 18:12:48 +05:30
Sugesh393
9bee2d430c test: add new unit test to validate paid amount in payment request 2024-11-29 17:44:22 +05:30
Abdeali Chharchhoda
de6cbd382f fix: Added translation for Account column 2024-11-29 17:42:11 +05:30
Sugesh393
561a159aec fix: calculate submitted payment entry as paid amount 2024-11-29 17:39:40 +05:30
rohitwaghchaure
7f7564b581 fix: precision calculation causing 0.1 discrepancy (#44431) 2024-11-29 17:09:41 +05:30
rohitwaghchaure
4050ea07eb fix: source warehouse not set in required items of WO (#44426)
fix: source warehouse not set in required items of WO on data import
2024-11-29 17:01:08 +05:30
rohitwaghchaure
5266f236b7 fix: SABB print for packed items (#44413) 2024-11-29 15:49:00 +05:30
rohitwaghchaure
d37d7b9811 fix: do not validate stock during inward (#44417) 2024-11-29 15:24:06 +05:30
ruthra kumar
76bd1017f4 Merge pull request #44302 from Abdeali099/refactor-payment-request
fix: Minor Updates in `Payment Request` and `Payment Entry`
2024-11-29 14:39:49 +05:30
ruthra kumar
2b3c829662 Merge pull request #44414 from blaggacao/fix/configure-test-type-checking
test: configure test-time type checking
2024-11-29 12:16:35 +05:30
ruthra kumar
da5dba997d Merge pull request #44411 from frappe/l10n_develop
fix: sync translations from crowdin
2024-11-29 10:36:59 +05:30
David
2394da419e test: configure test-time type checking
see: https://github.com/frappe/frappe/pull/28554
2024-11-28 23:36:24 +01:00
ljain112
3182c6981c fix: adjusted incoming rate for zero rated item in purchase receipt 2024-11-28 20:45:17 +05:30
ljain112
e371f68d66 fix: handle multi currency in common party journal entry 2024-11-28 19:50:01 +05:30
Frappe PR Bot
44c33cd12a fix: Turkish translations 2024-11-28 16:25:23 +05:30
Frappe PR Bot
4066df8652 fix: Swedish translations 2024-11-28 16:25:18 +05:30
Frappe PR Bot
a6d8383e43 fix: Spanish translations 2024-11-28 16:25:11 +05:30
Ninad Parikh
69bd90b038 fix: Data Should be Computed in Backend to Maintain Consistent Behaviour (#44195) 2024-11-28 15:59:52 +05:30
ruthra kumar
5de7db2be0 Merge pull request #44405 from ruthra-kumar/typeerror_on_transactionjs
fix: typeerror on transaction.js
2024-11-28 14:46:10 +05:30
ruthra kumar
46ce8780f2 fix: typeerror on transaction.js 2024-11-28 14:41:26 +05:30
Khushi Rawat
af5dae8682 Merge pull request #44400 from khushi8112/asset-depreciation-error-index-error
fix: IndexError in Asset Depreciation Ledger when query result is empty
2024-11-28 12:56:21 +05:30
Khushi Rawat
1737de7c10 chore: removed print statement 2024-11-28 11:41:00 +05:30
Khushi Rawat
7c393e5aa0 fix: IndexError in Asset Depreciation Ledger when query result is empty 2024-11-28 11:36:05 +05:30
Khushi Rawat
9a5d68f1f4 Merge pull request #44187 from khushi8112/progressive-disclosure-assets
style: added progressive disclosure to assets
2024-11-27 22:00:19 +05:30
Raffael Meyer
f6776c7d6b feat: add Company Contact Person in selling transactions (#44362) 2024-11-27 15:51:59 +01:00
ruthra kumar
ea6ddd5df6 Merge pull request #44346 from aerele/payment-request-partial-payment-pr
fix: reduce paid amount from grand total
2024-11-27 20:08:22 +05:30
ruthra kumar
e7808981cf Merge pull request #44382 from frappe/l10n_develop
fix: sync translations from crowdin
2024-11-27 19:56:32 +05:30
ruthra kumar
78a1b211a1 Merge pull request #44316 from Ninad1306/pos_closing_entry_fix
fix: Initially Closing Amount Should be Equal to Expected Amount
2024-11-27 19:56:05 +05:30
ruthra kumar
4d164d5854 Merge pull request #44392 from aerele/purchase_receipt_typo
chore: Fix typo "Purchase Reecipt"
2024-11-27 19:53:58 +05:30
vimalraj27
21049bae91 chore: Fix typo "Purchase Reecipt" 2024-11-27 18:03:39 +05:30
Sugesh393
82907672d9 fix: reduce paid amount from grand total 2024-11-27 17:41:16 +05:30
ruthra kumar
7efe05baf2 Merge pull request #44386 from Abdeali099/popup-msg-translation
fix: Add translation for showing mandatory fields in error msg
2024-11-27 17:28:54 +05:30
ruthra kumar
46b15f6040 Merge pull request #44327 from aerele/gl-transaction-currency
fix: set debit transaction currency in gl entry
2024-11-27 17:28:00 +05:30
akashdubey22
3de5ce74e1 refactor: updated print format for general ledger (#44057)
* refactor: update General Ledger print format

* Update general_ledger.html

* Update general_ledger.html

Removed extra spaces

* refactor: use letter-spacing for titles

* Update general_ledger.html

Comment added back

* Update general_ledger.html

* refactor: adding Remarks conditions & print party_type

* refactor: added Remarks column & adjusted spaces

Remarks column will be printed when Show Remarks is checked.

* Update general_ledger.html

Removed whitespace

* Update general_ledger.html

Fixed by removing colspan=2 in Opening Balance.

---------

Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2024-11-27 17:26:47 +05:30
ruthra kumar
676c93411e Merge pull request #44378 from aerele/pb-item-filter
fix: filter item with search fields
2024-11-27 17:19:39 +05:30
Abdeali Chharchhoda
214dfab269 fix: Add filter for outstanding_amount to fetch open PRs 2024-11-27 17:18:10 +05:30
Abdeali Chharchhoda
e1b3193b04 Merge branch 'develop' into refactor-payment-request 2024-11-27 17:05:39 +05:30
Abdeali Chharchhoda
f42ec6a124 fix: Add translation for showing mandatory fields in error msg 2024-11-27 16:53:50 +05:30
ruthra kumar
e3770bc9e1 Merge pull request #44359 from aerele/period-closing-voucher
fix: check difference with company currency
2024-11-27 16:53:22 +05:30
ruthra kumar
4dbd8054e8 Merge pull request #44323 from ljain112/fix-gross-profit-returned-invoices
fix: update gross profit for returned invoices
2024-11-27 16:49:17 +05:30
ruthra kumar
1ea5c5d821 Merge pull request #44376 from vishakhdesai/remove-precision
fix: remove field precision in Sales and Purchase Order for percentage fields
2024-11-27 16:48:31 +05:30
Frappe PR Bot
c9fb59a158 fix: Persian translations 2024-11-27 16:28:19 +05:30
Frappe PR Bot
02225e6a33 fix: Turkish translations 2024-11-27 16:28:14 +05:30
venkat102
ebfbee3da5 fix: filter item with search fields 2024-11-27 14:02:11 +05:30
vishakhdesai
eff9cd10cd fix: remove field precision in SO and PO for percentage fields 2024-11-27 12:43:34 +05:30
Ninad1306
94d3fc9fde test: validate buying workflow 2024-11-27 12:06:11 +05:30
Ninad1306
d049c97884 fix: always set sales incoming rate for internal transfers 2024-11-27 12:05:39 +05:30
venkat102
e2bae4cf07 fix: check difference with company currency 2024-11-26 22:13:57 +05:30
vishakhdesai
8b5d4c0236 fix: move validate_total_debit_and_credit from validate to on_submit in Journal Entry 2024-11-26 14:26:02 +05:30
Sugesh393
bbe3bc95d0 test: add unit test to validate outstanding amount in payment request 2024-11-26 13:59:45 +05:30
Sugesh393
38e7d0a41e fix: set outstanding amount while creating payment request for invoices 2024-11-26 13:58:52 +05:30
venkat102
6e19c06e58 fix: set debit transaction currency in gl entry 2024-11-26 00:03:42 +05:30
ljain112
af5a3e5a48 fix: test case 2024-11-25 19:05:08 +05:30
ljain112
00403515a8 fix: gp for return invoice 2024-11-25 18:45:17 +05:30
ljain112
8a42601e99 fix: update gross profit for returned invoices 2024-11-25 17:31:07 +05:30
Ninad1306
af9524920b fix: initially closing amt should be equal to expected amt 2024-11-25 10:44:25 +05:30
Khushi Rawat
4bdc6a0021 style: move depreciation details to a new tab 2024-11-20 11:56:34 +05:30
Khushi Rawat
87065d0387 chore: pre-commit check 2024-11-18 14:45:02 +05:30
Khushi Rawat
e3d734c890 style: added progressive disclosure to assets 2024-11-18 14:40:32 +05:30
lukas.brandhoff
0c83f48f78 fix: use get_datetime_as_string with correct time format 2024-10-30 11:46:21 +00:00
devdiogenes
ac0cb9db5a fix: Prevent set_payment_schedule when creating Sales Invoice that is return 2024-07-26 14:33:42 -03:00
368 changed files with 158245 additions and 30313 deletions

View File

@@ -10,6 +10,7 @@ WEBSITE_REPOS = [
DOCUMENTATION_DOMAINS = [
"docs.erpnext.com",
"docs.frappe.io",
"frappeframework.com",
]

View File

@@ -6,7 +6,7 @@ cd ~ || exit
sudo apt update
sudo apt remove mysql-server mysql-client
sudo apt install libcups2-dev redis-server mariadb-client-10.6
sudo apt install libcups2-dev redis-server mariadb-client
pip install frappe-bench
@@ -51,13 +51,9 @@ fi
install_whktml() {
if [ "$(lsb_release -rs)" = "22.04" ]; then
wget -O /tmp/wkhtmltox.deb https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb
sudo apt install /tmp/wkhtmltox.deb
else
echo "Please update this script to support wkhtmltopdf for $(lsb_release -ds)"
exit 1
fi
wget -O /tmp/wkhtmltox.deb https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb
sudo apt install /tmp/wkhtmltox.deb
}
install_whktml &
wkpid=$!

164
README.md
View File

@@ -1,57 +1,100 @@
<div align="center">
<a href="https://erpnext.com">
<img src="https://raw.githubusercontent.com/frappe/erpnext/develop/erpnext/public/images/erpnext-logo.png" height="128">
<img src="./erpnext/public/images/v16/erpnext.svg" alt="ERPNext Logo" height="80px" width="80xp"/>
</a>
<h2>ERPNext</h2>
<p align="center">
<p>ERP made simple</p>
<p>Powerful, Intuitive and Open-Source ERP</p>
</p>
[![CI](https://github.com/frappe/erpnext/actions/workflows/server-tests-mariadb.yml/badge.svg?event=schedule)](https://github.com/frappe/erpnext/actions/workflows/server-tests-mariadb.yml)
[![Open Source Helpers](https://www.codetriage.com/frappe/erpnext/badges/users.svg)](https://www.codetriage.com/frappe/erpnext)
[![codecov](https://codecov.io/gh/frappe/erpnext/branch/develop/graph/badge.svg?token=0TwvyUg3I5)](https://codecov.io/gh/frappe/erpnext)
[![docker pulls](https://img.shields.io/docker/pulls/frappe/erpnext-worker.svg)](https://hub.docker.com/r/frappe/erpnext-worker)
[https://erpnext.com](https://erpnext.com)
</div>
ERPNext as a monolith includes the following areas for managing businesses:
1. [Accounting](https://erpnext.com/open-source-accounting)
1. [Warehouse Management](https://erpnext.com/distribution/warehouse-management-system)
1. [CRM](https://erpnext.com/open-source-crm)
1. [Sales](https://erpnext.com/open-source-sales-purchase)
1. [Purchase](https://erpnext.com/open-source-sales-purchase)
1. [HRMS](https://erpnext.com/open-source-hrms)
1. [Project Management](https://erpnext.com/open-source-projects)
1. [Support](https://erpnext.com/open-source-help-desk-software)
1. [Asset Management](https://erpnext.com/open-source-asset-management-software)
1. [Quality Management](https://erpnext.com/docs/user/manual/en/quality-management)
1. [Manufacturing](https://erpnext.com/open-source-manufacturing-erp-software)
1. [Website Management](https://erpnext.com/open-source-website-builder-software)
1. [Customize ERPNext](https://erpnext.com/docs/user/manual/en/customize-erpnext)
1. [And More](https://erpnext.com/docs/user/manual/en/)
ERPNext is built on the [Frappe Framework](https://github.com/frappe/frappe), a full-stack web app framework built with Python & JavaScript.
## Installation
<div align="center" style="max-height: 40px;">
<a href="https://frappecloud.com/erpnext/signup">
<img src=".github/try-on-f-cloud-button.svg" height="40">
</a>
<a href="https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/frappe/frappe_docker/main/pwd.yml">
<img src="https://raw.githubusercontent.com/play-with-docker/stacks/master/assets/images/button.png" alt="Try in PWD" height="37"/>
</a>
<div align="center">
<img src="./erpnext/public/images/v16/hero_image.png"/>
</div>
> Login for the PWD site: (username: Administrator, password: admin)
<div align="center">
<a href="https://erpnext-demo.frappe.cloud/app/home">Live Demo</a>
-
<a href="https://erpnext.com">Website</a>
-
<a href="https://docs.erpnext.com">Documentation</a>
</div>
### Containerized Installation
## ERPNext
Use docker to deploy ERPNext in production or for development of [Frappe](https://github.com/frappe/frappe) apps. See https://github.com/frappe/frappe_docker for more details.
100% Open-Source ERP system to help you run your business.
### Motivation
Running a business is a complex task - handling invoices, tracking stock, managing personnel and even more ad-hoc activities. In a market where software is sold separately to manage each of these tasks, ERPNext does all of the above and more, for free.
### Key Features
- **Accounting**: All the tools you need to manage cash flow in one place, right from recording transactions to summarizing and analyzing financial reports.
- **Order Management**: Track inventory levels, replenish stock, and manage sales orders, customers, suppliers, shipments, deliverables, and order fulfillment.
- **Manufacturing**: Simplifies the production cycle, helps track material consumption, exhibits capacity planning, handles subcontracting, and more!
- **Asset Management**: From purchase to perishment, IT infrastructure to equipment. Cover every branch of your organization, all in one centralized system.
- **Projects**: Delivery both internal and external Projects on time, budget and Profitability. Track tasks, timesheets, and issues by project.
<details open>
<summary>More</summary>
<img src="https://erpnext.com/files/v16_bom.png"/>
<img src="https://erpnext.com/files/v16_stock_summary.png"/>
<img src="https://erpnext.com/files/v16_job_card.png"/>
<img src="https://erpnext.com/files/v16_tasks.png"/>
</details>
### Under the Hood
- [**Frappe Framework**](https://github.com/frappe/frappe): A full-stack web application framework written in Python and Javascript. The framework provides a robust foundation for building web applications, including a database abstraction layer, user authentication, and a REST API.
- [**Frappe UI**](https://github.com/frappe/frappe-ui): A Vue-based UI library, to provide a modern user interface. The Frappe UI library provides a variety of components that can be used to build single-page applications on top of the Frappe Framework.
## Production Setup
### Managed Hosting
You can try [Frappe Cloud](https://frappecloud.com), a simple, user-friendly and sophisticated [open-source](https://github.com/frappe/press) platform to host Frappe applications with peace of mind.
It takes care of installation, setup, upgrades, monitoring, maintenance and support of your Frappe deployments. It is a fully featured developer platform with an ability to manage and control multiple Frappe deployments.
<div>
<a href="https://erpnext-demo.frappe.cloud/app/home" target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://frappe.io/files/try-on-fc-white.png">
<img src="https://frappe.io/files/try-on-fc-black.png" alt="Try on Frappe Cloud" height="28" />
</picture>
</a>
</div>
### Self-Hosted
#### Docker
Prerequisites: docker, docker-compose, git. Refer [Docker Documentation](https://docs.docker.com) for more details on Docker setup.
Run following commands:
```
git clone https://github.com/frappe/frappe_docker
cd frappe_docker
docker compose -f pwd.yml up -d
```
After a couple of minutes, site should be accessible on your localhost port: 8080. Use below default login credentials to access the site.
- Username: Administrator
- Password: admin
See [Frappe Docker](https://github.com/frappe/frappe_docker?tab=readme-ov-file#to-run-on-arm64-architecture-follow-this-instructions) for ARM based docker setup.
## Development Setup
### Manual Install
The Easy Way: our install script for bench will install all dependencies (e.g. MariaDB). See https://github.com/frappe/bench for more details.
@@ -59,6 +102,35 @@ The Easy Way: our install script for bench will install all dependencies (e.g. M
New passwords will be created for the ERPNext "Administrator" user, the MariaDB root user, and the frappe user (the script displays the passwords and saves them to ~/frappe_passwords.txt).
### Local
To setup the repository locally follow the steps mentioned below:
1. Setup bench by following the [Installation Steps](https://frappeframework.com/docs/user/en/installation) and start the server
```
bench start
```
2. In a separate terminal window, run the following commands:
```
# Create a new site
bench new-site erpnext.dev
# Map your site to localhost
bench --site erpnext.dev add-to-hosts
```
3. Get the ERPNext app and install it
```
# Get the ERPNext app
bench get-app https://github.com/frappe/erpnext
# Install the app
bench --site erpnext.dev install-app erpnext
```
4. Open the URL `http://erpnext.dev:8000/app` in your browser, you should see the app running
## Learning and community
1. [Frappe School](https://frappe.school) - Learn Frappe Framework and ERPNext from the various courses by the maintainers or from the community.
@@ -73,14 +145,18 @@ New passwords will be created for the ERPNext "Administrator" user, the MariaDB
1. [Report Security Vulnerabilities](https://erpnext.com/security)
1. [Pull Request Requirements](https://github.com/frappe/erpnext/wiki/Contribution-Guidelines)
## License
GNU/General Public License (see [license.txt](license.txt))
The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappe Technologies Pvt Ltd (Frappe) and Contributors.
By contributing to ERPNext, you agree that your contributions will be licensed under its GNU General Public License (v3).
## Logo and Trademark Policy
Please read our [Logo and Trademark Policy](TRADEMARK_POLICY.md).
<br />
<br />
<div align="center" style="padding-top: 0.75rem;">
<a href="https://frappe.io" target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://frappe.io/files/Frappe-white.png">
<img src="https://frappe.io/files/Frappe-black.png" alt="Frappe Technologies" height="28"/>
</picture>
</a>
</div>

View File

@@ -131,7 +131,7 @@
"description": "Rate at which this tax is applied",
"fieldname": "tax_rate",
"fieldtype": "Float",
"label": "Rate",
"label": "Tax Rate",
"oldfieldname": "tax_rate",
"oldfieldtype": "Currency"
},

View File

@@ -10,6 +10,7 @@ frappe.treeview_settings["Account"] = {
fieldtype: "Select",
options: erpnext.utils.get_tree_options("company"),
label: __("Company"),
render_on_toolbar: true,
default: erpnext.utils.get_tree_default("company"),
on_change: function () {
var me = frappe.treeview_settings["Account"].treeview;
@@ -182,7 +183,9 @@ frappe.treeview_settings["Account"] = {
function () {
frappe.set_route("Tree", "Cost Center", { company: get_company() });
},
__("View")
__("View"),
"default",
true
);
treeview.page.add_inner_button(
@@ -190,31 +193,12 @@ frappe.treeview_settings["Account"] = {
function () {
frappe.set_route("Form", "Opening Invoice Creation Tool", { company: get_company() });
},
__("View")
__("View"),
"default",
true
);
treeview.page.add_inner_button(
__("Period Closing Voucher"),
function () {
frappe.set_route("List", "Period Closing Voucher", { company: get_company() });
},
__("View")
);
treeview.page.add_inner_button(
__("Journal Entry"),
function () {
frappe.new_doc("Journal Entry", { company: get_company() });
},
__("Create")
);
treeview.page.add_inner_button(
__("Company"),
function () {
frappe.new_doc("Company");
},
__("Create")
);
treeview.page.add_divider_to_button_group(__("View"));
// financial statements
for (let report of [
@@ -231,25 +215,28 @@ frappe.treeview_settings["Account"] = {
function () {
frappe.set_route("query-report", report, { company: get_company() });
},
__("Financial Statements")
__("View")
);
}
},
post_render: function (treeview) {
frappe.treeview_settings["Account"].treeview["tree"] = treeview.tree;
treeview.page.set_primary_action(
__("New"),
function () {
let root_company = treeview.page.fields_dict.root_company.get_value();
if (root_company) {
frappe.throw(__("Please add the account to root level Company - {0}"), [root_company]);
} else {
treeview.new_node();
}
},
"add"
);
if (treeview.can_create) {
treeview.page.set_primary_action(
__("New"),
function () {
let root_company = treeview.page.fields_dict.root_company.get_value();
if (root_company) {
frappe.throw(__("Please add the account to root level Company - {0}"), [
root_company,
]);
} else {
treeview.new_node();
}
},
"add"
);
}
},
toolbar: [
{

View File

@@ -0,0 +1,34 @@
import json
from pathlib import Path
syscohada_countries = [
"bj", # Bénin
"bf", # Burkina-Faso
"cm", # Cameroun
"cf", # Centrafrique
"ci", # Côte d'Ivoire
"cg", # Congo
"km", # Comores
"ga", # Gabon
"gn", # Guinée
"gw", # Guinée-Bissau
"gq", # Guinée Equatoriale
"ml", # Mali
"ne", # Niger
"cd", # République Démocratique du Congo
"sn", # Sénégal
"td", # Tchad
"tg", # Togo
]
folder = Path(__file__).parent
generic_charts = Path(folder).glob("syscohada*.json")
for file in generic_charts:
with open(file) as f:
chart = json.load(f)
for country in syscohada_countries:
chart["country_code"] = country
json_object = json.dumps(chart, indent=4)
with open(Path(folder, file.name.replace("syscohada", country)), "w") as outfile:
outfile.write(json_object)

View File

@@ -104,7 +104,7 @@
"fieldname": "rate",
"fieldtype": "Float",
"in_list_view": 1,
"label": "Rate",
"label": "Tax Rate",
"oldfieldname": "rate",
"oldfieldtype": "Currency"
},

View File

@@ -48,7 +48,7 @@ class BankAccount(Document):
self.name = self.account_name + " - " + self.bank
def on_trash(self):
delete_contact_and_address("BankAccount", self.name)
delete_contact_and_address("Bank Account", self.name)
def validate(self):
self.validate_company()

View File

@@ -117,9 +117,9 @@ class BankClearance(Document):
)
else:
frappe.db.set_value(
d.payment_document, d.payment_entry, "clearance_date", d.clearance_date
)
# using db_set to trigger notification
payment_entry = frappe.get_doc(d.payment_document, d.payment_entry)
payment_entry.db_set("clearance_date", d.clearance_date)
clearance_date_updated = True

View File

@@ -120,6 +120,7 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
args: {
bank_account: frm.doc.bank_account,
till_date: frappe.datetime.add_days(frm.doc.bank_statement_from_date, -1),
company: frm.doc.company,
},
callback: (response) => {
frm.set_value("account_opening_balance", response.message);
@@ -135,6 +136,7 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
args: {
bank_account: frm.doc.bank_account,
till_date: frm.doc.bank_statement_to_date,
company: frm.doc.company,
},
callback: (response) => {
frm.cleared_balance = response.message;

View File

@@ -12,6 +12,7 @@ from frappe.utils import cint, flt
from erpnext import get_default_cost_center
from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_total_allocated_amount
from erpnext.accounts.party import get_party_account
from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_statement import (
get_amounts_not_reflected_in_system,
get_entries,
@@ -78,10 +79,17 @@ def get_bank_transactions(bank_account, from_date=None, to_date=None):
@frappe.whitelist()
def get_account_balance(bank_account, till_date):
def get_account_balance(bank_account, till_date, company):
# returns account balance till the specified date
account = frappe.db.get_value("Bank Account", bank_account, "account")
filters = frappe._dict({"account": account, "report_date": till_date, "include_pos_transactions": 1})
filters = frappe._dict(
{
"account": account,
"report_date": till_date,
"include_pos_transactions": 1,
"company": company,
}
)
data = get_entries(filters)
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
@@ -93,11 +101,7 @@ def get_account_balance(bank_account, till_date):
amounts_not_reflected_in_system = get_amounts_not_reflected_in_system(filters)
bank_bal = (
flt(balance_as_per_system) - flt(total_debit) + flt(total_credit) + amounts_not_reflected_in_system
)
return bank_bal
return flt(balance_as_per_system) - flt(total_debit) + flt(total_credit) + amounts_not_reflected_in_system
@frappe.whitelist()
@@ -304,54 +308,56 @@ def create_payment_entry_bts(
bank_transaction = frappe.db.get_values(
"Bank Transaction",
bank_transaction_name,
fieldname=["name", "unallocated_amount", "deposit", "bank_account"],
fieldname=["name", "unallocated_amount", "deposit", "bank_account", "currency"],
as_dict=True,
)[0]
paid_amount = bank_transaction.unallocated_amount
payment_type = "Receive" if bank_transaction.deposit > 0.0 else "Pay"
company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
company = frappe.get_value("Account", company_account, "company")
payment_entry_dict = {
"company": company,
"payment_type": payment_type,
"reference_no": reference_number,
"reference_date": reference_date,
"party_type": party_type,
"party": party,
"posting_date": posting_date,
"paid_amount": paid_amount,
"received_amount": paid_amount,
}
payment_entry = frappe.new_doc("Payment Entry")
bank_account = frappe.get_cached_value("Bank Account", bank_transaction.bank_account, "account")
company = frappe.get_cached_value("Account", bank_account, "company")
party_account = get_party_account(party_type, party, company)
payment_entry.update(payment_entry_dict)
bank_currency = bank_transaction.currency
party_currency = frappe.get_cached_value("Account", party_account, "account_currency")
if mode_of_payment:
payment_entry.mode_of_payment = mode_of_payment
if project:
payment_entry.project = project
if cost_center:
payment_entry.cost_center = cost_center
if payment_type == "Receive":
payment_entry.paid_to = company_account
else:
payment_entry.paid_from = company_account
exc_rate = get_exchange_rate(bank_currency, party_currency, posting_date)
payment_entry.validate()
amt_in_bank_acc_currency = bank_transaction.unallocated_amount
amount_in_party_currency = bank_transaction.unallocated_amount * exc_rate
pe = frappe.new_doc("Payment Entry")
pe.payment_type = payment_type
pe.company = company
pe.reference_no = reference_number
pe.reference_date = reference_date
pe.party_type = party_type
pe.party = party
pe.posting_date = posting_date
pe.paid_from = party_account if payment_type == "Receive" else bank_account
pe.paid_to = party_account if payment_type == "Pay" else bank_account
pe.paid_from_account_currency = party_currency if payment_type == "Receive" else bank_currency
pe.paid_to_account_currency = party_currency if payment_type == "Pay" else bank_currency
pe.paid_amount = amount_in_party_currency if payment_type == "Receive" else amt_in_bank_acc_currency
pe.received_amount = amount_in_party_currency if payment_type == "Pay" else amt_in_bank_acc_currency
pe.mode_of_payment = mode_of_payment
pe.project = project
pe.cost_center = cost_center
pe.validate()
if allow_edit:
return payment_entry
return pe
payment_entry.insert()
pe.insert()
pe.submit()
payment_entry.submit()
vouchers = json.dumps(
[
{
"payment_doctype": "Payment Entry",
"payment_name": payment_entry.name,
"amount": paid_amount,
"payment_name": pe.name,
"amount": amt_in_bank_acc_currency,
}
]
)
@@ -480,8 +486,12 @@ def get_linked_payments(
def subtract_allocations(gl_account, vouchers):
"Look up & subtract any existing Bank Transaction allocations"
copied = []
voucher_docs = [(voucher.get("doctype"), voucher.get("name")) for voucher in vouchers]
voucher_allocated_amounts = get_total_allocated_amount(voucher_docs)
for voucher in vouchers:
rows = get_total_allocated_amount(voucher.get("doctype"), voucher.get("name"))
rows = voucher_allocated_amounts.get((voucher.get("doctype"), voucher.get("name"))) or []
filtered_row = list(filter(lambda row: row.get("gl_account") == gl_account, rows))
if amount := None if not filtered_row else filtered_row[0]["total"]:
@@ -719,7 +729,7 @@ def get_pe_matching_query(
(ref_rank + amount_rank + party_rank + 1).as_("rank"),
ConstantColumn("Payment Entry").as_("doctype"),
pe.name,
pe.paid_amount_after_tax.as_("paid_amount"),
pe.base_paid_amount_after_tax.as_("paid_amount"),
pe.reference_no,
pe.reference_date,
pe.party,

View File

@@ -154,10 +154,16 @@ class BankTransaction(Document):
"""
remaining_amount = self.unallocated_amount
to_remove = []
payment_entry_docs = [(pe.payment_document, pe.payment_entry) for pe in self.payment_entries]
pe_bt_allocations = get_total_allocated_amount(payment_entry_docs)
for payment_entry in self.payment_entries:
if payment_entry.allocated_amount == 0.0:
unallocated_amount, should_clear, latest_transaction = get_clearance_details(
self, payment_entry
self,
payment_entry,
pe_bt_allocations.get((payment_entry.payment_document, payment_entry.payment_entry))
or [],
)
if 0.0 == unallocated_amount:
@@ -208,13 +214,17 @@ class BankTransaction(Document):
if self.party_type and self.party:
return
result = AutoMatchParty(
bank_party_account_number=self.bank_party_account_number,
bank_party_iban=self.bank_party_iban,
bank_party_name=self.bank_party_name,
description=self.description,
deposit=self.deposit,
).match()
result = None
try:
result = AutoMatchParty(
bank_party_account_number=self.bank_party_account_number,
bank_party_iban=self.bank_party_iban,
bank_party_name=self.bank_party_name,
description=self.description,
deposit=self.deposit,
).match()
except Exception:
frappe.log_error(title=_("Error in party matching for Bank Transaction {0}").format(self.name))
if not result:
return
@@ -228,7 +238,7 @@ def get_doctypes_for_bank_reconciliation():
return frappe.get_hooks("bank_reconciliation_doctypes")
def get_clearance_details(transaction, payment_entry):
def get_clearance_details(transaction, payment_entry, bt_allocations):
"""
There should only be one bank gle for a voucher.
Could be none for a Bank Transaction.
@@ -237,7 +247,6 @@ def get_clearance_details(transaction, payment_entry):
"""
gl_bank_account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
gles = get_related_bank_gl_entries(payment_entry.payment_document, payment_entry.payment_entry)
bt_allocations = get_total_allocated_amount(payment_entry.payment_document, payment_entry.payment_entry)
unallocated_amount = min(
transaction.unallocated_amount,
@@ -290,44 +299,52 @@ def get_related_bank_gl_entries(doctype, docname):
)
def get_total_allocated_amount(doctype, docname):
def get_total_allocated_amount(docs):
"""
Gets the sum of allocations for a voucher on each bank GL account
along with the latest bank transaction name & date
NOTE: query may also include just saved vouchers/payments but with zero allocated_amount
"""
if not docs:
return {}
# nosemgrep: frappe-semgrep-rules.rules.frappe-using-db-sql
result = frappe.db.sql(
"""
SELECT total, latest_name, latest_date, gl_account FROM (
SELECT total, latest_name, latest_date, gl_account, payment_document, payment_entry FROM (
SELECT
ROW_NUMBER() OVER w AS rownum,
SUM(btp.allocated_amount) OVER(PARTITION BY ba.account) AS total,
SUM(btp.allocated_amount) OVER(PARTITION BY ba.account, btp.payment_document, btp.payment_entry) AS total,
FIRST_VALUE(bt.name) OVER w AS latest_name,
FIRST_VALUE(bt.date) OVER w AS latest_date,
ba.account AS gl_account
ba.account AS gl_account,
btp.payment_document,
btp.payment_entry
FROM
`tabBank Transaction Payments` btp
LEFT JOIN `tabBank Transaction` bt ON bt.name=btp.parent
LEFT JOIN `tabBank Account` ba ON ba.name=bt.bank_account
WHERE
btp.payment_document = %(doctype)s
AND btp.payment_entry = %(docname)s
(btp.payment_document, btp.payment_entry) IN %(docs)s
AND bt.docstatus = 1
WINDOW w AS (PARTITION BY ba.account ORDER BY bt.date desc)
WINDOW w AS (PARTITION BY ba.account, btp.payment_document, btp.payment_entry ORDER BY bt.date DESC)
) temp
WHERE
rownum = 1
""",
dict(doctype=doctype, docname=docname),
dict(docs=docs),
as_dict=True,
)
payment_allocation_details = {}
for row in result:
# Why is this *sometimes* a byte string?
if isinstance(row["latest_name"], bytes):
row["latest_name"] = row["latest_name"].decode()
row["latest_date"] = frappe.utils.getdate(row["latest_date"])
return result
payment_allocation_details.setdefault((row["payment_document"], row["payment_entry"]), []).append(row)
return payment_allocation_details
def get_paid_amount(payment_entry, currency, gl_bank_account):

View File

@@ -490,13 +490,20 @@ def get_actual_expense(args):
def get_accumulated_monthly_budget(monthly_distribution, posting_date, fiscal_year, annual_budget):
distribution = {}
if monthly_distribution:
for d in frappe.db.sql(
"""select mdp.month, mdp.percentage_allocation
from `tabMonthly Distribution Percentage` mdp, `tabMonthly Distribution` md
where mdp.parent=md.name and md.fiscal_year=%s""",
fiscal_year,
as_dict=1,
):
mdp = frappe.qb.DocType("Monthly Distribution Percentage")
md = frappe.qb.DocType("Monthly Distribution")
res = (
frappe.qb.from_(mdp)
.join(md)
.on(mdp.parent == md.name)
.select(mdp.month, mdp.percentage_allocation)
.where(md.fiscal_year == fiscal_year)
.where(md.name == monthly_distribution)
.run(as_dict=True)
)
for d in res:
distribution.setdefault(d.month, d.percentage_allocation)
dt = frappe.get_cached_value("Fiscal Year", fiscal_year, "year_start_date")

View File

@@ -188,7 +188,7 @@ class TestExchangeRateRevaluation(AccountsTestMixin, IntegrationTestCase):
pe = get_payment_entry(si.doctype, si.name)
pe.paid_amount = 95
pe.source_exchange_rate = 84.211
pe.source_exchange_rate = 84.2105
pe.received_amount = 8000
pe.references = []
pe.save().submit()
@@ -229,7 +229,7 @@ class TestExchangeRateRevaluation(AccountsTestMixin, IntegrationTestCase):
row = next(x for x in je.accounts if x.account == self.debtors_usd)
self.assertEqual(flt(row.credit_in_account_currency, precision), 5.0) # in USD
row = next(x for x in je.accounts if x.account != self.debtors_usd)
self.assertEqual(flt(row.debit_in_account_currency, precision), 421.06) # in INR
self.assertEqual(flt(row.debit_in_account_currency, precision), 421.05) # in INR
# total_debit and total_credit will be 0.0, as JV is posting only to account currency fields
self.assertEqual(flt(je.total_debit, precision), 0.0)

View File

@@ -13,7 +13,11 @@ import erpnext
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_checks_for_pl_and_bs_accounts,
)
from erpnext.accounts.party import validate_party_frozen_disabled, validate_party_gle_currency
from erpnext.accounts.party import (
validate_account_party_type,
validate_party_frozen_disabled,
validate_party_gle_currency,
)
from erpnext.accounts.utils import get_account_currency, get_fiscal_year
from erpnext.exceptions import InvalidAccountCurrency
@@ -268,8 +272,12 @@ class GLEntry(Document):
def validate_party(self):
validate_party_frozen_disabled(self.party_type, self.party)
validate_account_party_type(self)
def validate_currency(self):
if self.is_cancelled:
return
company_currency = erpnext.get_company_currency(self.company)
account_currency = get_account_currency(self.account)

View File

@@ -78,3 +78,48 @@ class TestGLEntry(IntegrationTestCase):
"SELECT current from tabSeries where name = %s", naming_series
)[0][0]
self.assertEqual(old_naming_series_current_value + 2, new_naming_series_current_value)
def test_validate_account_party_type(self):
jv = make_journal_entry(
"_Test Account Cost for Goods Sold - _TC",
"_Test Bank - _TC",
100,
"_Test Cost Center - _TC",
save=False,
submit=False,
)
for row in jv.accounts:
row.party_type = "Supplier"
break
jv.save()
try:
jv.submit()
except Exception as e:
self.assertEqual(
str(e),
"Party Type and Party can only be set for Receivable / Payable account_Test Account Cost for Goods Sold - _TC",
)
jv1 = make_journal_entry(
"_Test Account Cost for Goods Sold - _TC",
"_Test Bank - _TC",
100,
"_Test Cost Center - _TC",
save=False,
submit=False,
)
for row in jv.accounts:
row.party_type = "Customer"
break
jv1.save()
try:
jv1.submit()
except Exception as e:
self.assertEqual(
str(e),
"Party Type and Party can only be set for Receivable / Payable account_Test Account Cost for Goods Sold - _TC",
)

View File

@@ -127,9 +127,6 @@ class JournalEntry(AccountsController):
self.set_amounts_in_company_currency()
self.validate_debit_credit_amount()
self.set_total_debit_credit()
# Do not validate while importing via data import
if not frappe.flags.in_import:
self.validate_total_debit_and_credit()
if not frappe.flags.is_reverse_depr_entry:
self.validate_against_jv()
@@ -184,6 +181,11 @@ class JournalEntry(AccountsController):
else:
return self._cancel()
def before_submit(self):
# Do not validate while importing via data import
if not frappe.flags.in_import:
self.validate_total_debit_and_credit()
def on_submit(self):
self.validate_cheque_info()
self.check_credit_limit()

View File

@@ -27,6 +27,18 @@ frappe.ui.form.on("Payment Entry", {
erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype);
// project excluded in setup_dimension_filters
frm.set_query("project", function (doc) {
let filters = {
company: doc.company,
};
if (doc.party_type == "Customer") filters.customer = doc.party;
return {
query: "erpnext.controllers.queries.get_project_name",
filters,
};
});
if (frm.is_new()) {
set_default_party_type(frm);
}
@@ -324,11 +336,6 @@ frappe.ui.form.on("Payment Entry", {
"write_off_difference_amount",
frm.doc.difference_amount && frm.doc.party && frm.doc.total_allocated_amount > party_amount
);
frm.toggle_display(
"set_exchange_gain_loss",
frm.doc.paid_amount && frm.doc.received_amount && frm.doc.difference_amount
);
},
set_dynamic_labels: function (frm) {
@@ -1119,36 +1126,34 @@ frappe.ui.form.on("Payment Entry", {
},
set_unallocated_amount: function (frm) {
var unallocated_amount = 0;
var total_deductions = frappe.utils.sum(
$.map(frm.doc.deductions || [], function (d) {
return flt(d.amount);
})
);
let unallocated_amount = 0;
let deductions_to_consider = 0;
for (const row of frm.doc.deductions || []) {
if (!row.is_exchange_gain_loss) deductions_to_consider += flt(row.amount);
}
const included_taxes = get_included_taxes(frm);
if (frm.doc.party) {
if (
frm.doc.payment_type == "Receive" &&
frm.doc.base_total_allocated_amount < frm.doc.base_received_amount + total_deductions &&
frm.doc.total_allocated_amount <
frm.doc.paid_amount + total_deductions / frm.doc.source_exchange_rate
) {
unallocated_amount =
(frm.doc.base_received_amount +
total_deductions -
flt(frm.doc.base_total_taxes_and_charges) -
frm.doc.base_total_allocated_amount) /
frm.doc.source_exchange_rate;
} else if (
frm.doc.payment_type == "Pay" &&
frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions &&
frm.doc.total_allocated_amount <
frm.doc.received_amount + total_deductions / frm.doc.target_exchange_rate
frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount + deductions_to_consider
) {
unallocated_amount =
(frm.doc.base_paid_amount +
flt(frm.doc.base_total_taxes_and_charges) -
(total_deductions + frm.doc.base_total_allocated_amount)) /
deductions_to_consider -
frm.doc.base_total_allocated_amount -
included_taxes) /
frm.doc.source_exchange_rate;
} else if (
frm.doc.payment_type == "Pay" &&
frm.doc.base_total_allocated_amount < frm.doc.base_received_amount - deductions_to_consider
) {
unallocated_amount =
(frm.doc.base_received_amount -
deductions_to_consider -
frm.doc.base_total_allocated_amount -
included_taxes) /
frm.doc.target_exchange_rate;
}
}
@@ -1242,77 +1247,85 @@ frappe.ui.form.on("Payment Entry", {
},
write_off_difference_amount: function (frm) {
frm.events.set_deductions_entry(frm, "write_off_account");
frm.events.set_write_off_deduction(frm);
},
set_exchange_gain_loss: function (frm) {
frm.events.set_deductions_entry(frm, "exchange_gain_loss_account");
base_paid_amount: function (frm) {
frm.events.set_exchange_gain_loss_deduction(frm);
},
set_deductions_entry: function (frm, account) {
if (frm.doc.difference_amount) {
frappe.call({
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_company_defaults",
args: {
company: frm.doc.company,
},
callback: function (r, rt) {
if (r.message) {
const write_off_row = $.map(frm.doc["deductions"] || [], function (t) {
return t.account == r.message[account] ? t : null;
});
base_received_amount: function (frm) {
frm.events.set_exchange_gain_loss_deduction(frm);
},
const difference_amount = flt(
frm.doc.difference_amount,
precision("difference_amount")
);
set_exchange_gain_loss_deduction: async function (frm) {
// wait for allocate_party_amount_against_ref_docs to finish
await frappe.after_ajax();
const base_paid_amount = frm.doc.base_paid_amount || 0;
const base_received_amount = frm.doc.base_received_amount || 0;
const exchange_gain_loss = flt(
base_paid_amount - base_received_amount,
get_deduction_amount_precision()
);
const add_deductions = (details) => {
let row = null;
if (!write_off_row.length && difference_amount) {
row = frm.add_child("deductions");
row.account = details[account];
row.cost_center = details["cost_center"];
} else {
row = write_off_row[0];
}
if (row) {
row.amount = flt(row.amount) + difference_amount;
} else {
frappe.msgprint(__("No gain or loss in the exchange rate"));
}
refresh_field("deductions");
};
if (!r.message[account]) {
frappe.prompt(
{
label: __("Please Specify Account"),
fieldname: account,
fieldtype: "Link",
options: "Account",
get_query: () => ({
filters: {
company: frm.doc.company,
},
}),
},
(values) => {
const details = Object.assign({}, r.message, values);
add_deductions(details);
},
__(frappe.unscrub(account))
);
} else {
add_deductions(r.message);
}
frm.events.set_unallocated_amount(frm);
}
},
});
if (!exchange_gain_loss) {
frm.events.delete_exchange_gain_loss(frm);
return;
}
const account_fieldname = "exchange_gain_loss_account";
let row = (frm.doc.deductions || []).find((t) => t.is_exchange_gain_loss);
if (!row) {
const response = await get_company_defaults(frm.doc.company);
const account =
response.message?.[account_fieldname] ||
(await prompt_for_missing_account(frm, account_fieldname));
row = frm.add_child("deductions");
row.account = account;
row.cost_center = response.message?.cost_center;
row.is_exchange_gain_loss = 1;
}
row.amount = exchange_gain_loss;
frm.refresh_field("deductions");
frm.events.set_unallocated_amount(frm);
},
delete_exchange_gain_loss: function (frm) {
const exchange_gain_loss_row = (frm.doc.deductions || []).find((row) => row.is_exchange_gain_loss);
if (!exchange_gain_loss_row) return;
exchange_gain_loss_row.amount = 0;
frm.get_field("deductions").grid.grid_rows[exchange_gain_loss_row.idx - 1].remove();
frm.refresh_field("deductions");
},
set_write_off_deduction: async function (frm) {
const difference_amount = flt(frm.doc.difference_amount, get_deduction_amount_precision());
if (!difference_amount) return;
const account_fieldname = "write_off_account";
const response = await get_company_defaults(frm.doc.company);
const write_off_account =
response.message?.[account_fieldname] ||
(await prompt_for_missing_account(frm, account_fieldname));
if (!write_off_account) return;
let row = (frm.doc["deductions"] || []).find((t) => t.account == write_off_account);
if (!row) {
row = frm.add_child("deductions");
row.account = write_off_account;
row.cost_center = response.message?.cost_center;
}
row.amount = flt(row.amount) + difference_amount;
frm.refresh_field("deductions");
frm.events.set_unallocated_amount(frm);
},
bank_account: function (frm) {
@@ -1327,6 +1340,24 @@ frappe.ui.form.on("Payment Entry", {
if (r.message) {
if (!frm.doc.mode_of_payment) {
frm.set_value(field, r.message.account);
} else {
frappe.call({
method: "frappe.client.get_value",
args: {
doctype: "Mode of Payment Account",
filters: {
parent: frm.doc.mode_of_payment,
company: frm.doc.company,
},
fieldname: "default_account",
parent: "Mode of Payment",
},
callback: function (res) {
if (!res.message.default_account) {
frm.set_value(field, r.message.account);
}
},
});
}
frm.set_value("bank", r.message.bank);
frm.set_value("bank_account_no", r.message.bank_account_no);
@@ -1778,6 +1809,13 @@ frappe.ui.form.on("Advance Taxes and Charges", {
});
frappe.ui.form.on("Payment Entry Deduction", {
before_deductions_remove: function (doc, cdt, cdn) {
const row = frappe.get_doc(cdt, cdn);
if (row.is_exchange_gain_loss && row.amount) {
frappe.throw(__("Cannot delete Exchange Gain/Loss row"));
}
},
amount: function (frm) {
frm.events.set_unallocated_amount(frm);
},
@@ -1799,3 +1837,53 @@ function set_default_party_type(frm) {
if (party_type) frm.set_value("party_type", party_type);
}
function get_included_taxes(frm) {
let included_taxes = 0;
for (const tax of frm.doc.taxes) {
if (!tax.included_in_paid_amount) continue;
if (tax.add_deduct_tax == "Add") {
included_taxes += tax.base_tax_amount;
} else {
included_taxes -= tax.base_tax_amount;
}
}
return included_taxes;
}
function get_company_defaults(company) {
return frappe.call({
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_company_defaults",
args: {
company: company,
},
});
}
function prompt_for_missing_account(frm, account) {
return new Promise((resolve) => {
const dialog = frappe.prompt(
{
label: __(frappe.unscrub(account)),
fieldname: account,
fieldtype: "Link",
options: "Account",
get_query: () => ({
filters: {
company: frm.doc.company,
},
}),
},
(values) => resolve(values?.[account]),
__("Please Specify Account")
);
dialog.on_hide = () => resolve("");
});
}
function get_deduction_amount_precision() {
return frappe.meta.get_field_precision(frappe.meta.get_field("Payment Entry Deduction", "amount"));
}

View File

@@ -56,7 +56,6 @@
"section_break_34",
"total_allocated_amount",
"base_total_allocated_amount",
"set_exchange_gain_loss",
"column_break_36",
"unallocated_amount",
"difference_amount",
@@ -391,11 +390,6 @@
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "set_exchange_gain_loss",
"fieldtype": "Button",
"label": "Set Exchange Gain / Loss"
},
{
"fieldname": "column_break_36",
"fieldtype": "Column Break"
@@ -802,7 +796,7 @@
"table_fieldname": "payment_entries"
}
],
"modified": "2024-05-31 17:07:06.197249",
"modified": "2024-11-07 11:19:19.320883",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",

View File

@@ -985,6 +985,7 @@ class PaymentEntry(AccountsController):
self.set_amounts_in_company_currency()
self.set_total_allocated_amount()
self.set_unallocated_amount()
self.set_exchange_gain_loss()
self.set_difference_amount()
def validate_amounts(self):
@@ -1083,10 +1084,10 @@ class PaymentEntry(AccountsController):
if d.exchange_rate is None:
d.exchange_rate = 1
allocated_amount_in_pe_exchange_rate = flt(
allocated_amount_in_ref_exchange_rate = flt(
flt(d.allocated_amount) * flt(d.exchange_rate), self.precision("base_paid_amount")
)
d.exchange_gain_loss = base_allocated_amount - allocated_amount_in_pe_exchange_rate
d.exchange_gain_loss = base_allocated_amount - allocated_amount_in_ref_exchange_rate
return base_allocated_amount
def set_total_allocated_amount(self):
@@ -1104,29 +1105,80 @@ class PaymentEntry(AccountsController):
def set_unallocated_amount(self):
self.unallocated_amount = 0
if self.party:
total_deductions = sum(flt(d.amount) for d in self.get("deductions"))
included_taxes = self.get_included_taxes()
if (
self.payment_type == "Receive"
and self.base_total_allocated_amount < self.base_received_amount + total_deductions
and self.total_allocated_amount
< flt(self.paid_amount) + (total_deductions / self.source_exchange_rate)
):
self.unallocated_amount = (
self.base_received_amount + total_deductions - self.base_total_allocated_amount
) / self.source_exchange_rate
self.unallocated_amount -= included_taxes
elif (
self.payment_type == "Pay"
and self.base_total_allocated_amount < (self.base_paid_amount - total_deductions)
and self.total_allocated_amount
< flt(self.received_amount) + (total_deductions / self.target_exchange_rate)
):
self.unallocated_amount = (
self.base_paid_amount - (total_deductions + self.base_total_allocated_amount)
) / self.target_exchange_rate
self.unallocated_amount -= included_taxes
if not self.party:
return
deductions_to_consider = sum(
flt(d.amount) for d in self.get("deductions") if not d.is_exchange_gain_loss
)
included_taxes = self.get_included_taxes()
if self.payment_type == "Receive" and self.base_total_allocated_amount < (
self.base_paid_amount + deductions_to_consider
):
self.unallocated_amount = (
self.base_paid_amount
+ deductions_to_consider
- self.base_total_allocated_amount
- included_taxes
) / self.source_exchange_rate
elif self.payment_type == "Pay" and self.base_total_allocated_amount < (
self.base_received_amount - deductions_to_consider
):
self.unallocated_amount = (
self.base_received_amount
- deductions_to_consider
- self.base_total_allocated_amount
- included_taxes
) / self.target_exchange_rate
def set_exchange_gain_loss(self):
exchange_gain_loss = flt(
self.base_paid_amount - self.base_received_amount,
self.precision("amount", "deductions"),
)
exchange_gain_loss_rows = [row for row in self.get("deductions") if row.is_exchange_gain_loss]
exchange_gain_loss_row = exchange_gain_loss_rows.pop(0) if exchange_gain_loss_rows else None
for row in exchange_gain_loss_rows:
self.remove(row)
if not exchange_gain_loss:
if exchange_gain_loss_row:
self.remove(exchange_gain_loss_row)
return
if not exchange_gain_loss_row:
values = frappe.get_cached_value(
"Company", self.company, ("exchange_gain_loss_account", "cost_center"), as_dict=True
)
for fieldname, value in values.items():
if value:
continue
label = _(frappe.get_meta("Company").get_label(fieldname))
return frappe.msgprint(
_("Please set {0} in Company {1} to account for Exchange Gain / Loss").format(
label, get_link_to_form("Company", self.company)
),
title=_("Missing Default in Company"),
indicator="red" if self.docstatus.is_submitted() else "yellow",
raise_exception=self.docstatus.is_submitted(),
)
exchange_gain_loss_row = self.append(
"deductions",
{
"account": values.exchange_gain_loss_account,
"cost_center": values.cost_center,
"is_exchange_gain_loss": 1,
},
)
exchange_gain_loss_row.amount = exchange_gain_loss
def set_difference_amount(self):
base_unallocated_amount = flt(self.unallocated_amount) * (
@@ -1154,11 +1206,13 @@ class PaymentEntry(AccountsController):
def get_included_taxes(self):
included_taxes = 0
for tax in self.get("taxes"):
if tax.included_in_paid_amount:
if tax.add_deduct_tax == "Add":
included_taxes += tax.base_tax_amount
else:
included_taxes -= tax.base_tax_amount
if not tax.included_in_paid_amount:
continue
if tax.add_deduct_tax == "Add":
included_taxes += tax.base_tax_amount
else:
included_taxes -= tax.base_tax_amount
return included_taxes
@@ -1318,11 +1372,19 @@ class PaymentEntry(AccountsController):
dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
gle.update(
{
dr_or_cr: allocated_amount_in_company_currency,
dr_or_cr + "_in_account_currency": d.allocated_amount,
"cost_center": cost_center,
}
self.get_gl_dict(
{
"account": self.party_account,
"party_type": self.party_type,
"party": self.party,
"against": against_account,
"account_currency": self.party_account_currency,
"cost_center": cost_center,
dr_or_cr + "_in_account_currency": d.allocated_amount,
dr_or_cr: allocated_amount_in_company_currency,
},
item=self,
)
)
if self.book_advance_payments_in_separate_party_account:
@@ -2006,8 +2068,8 @@ class PaymentEntry(AccountsController):
def get_matched_payment_request_of_references(references=None):
"""
Get those `Payment Requests` which are matched with `References`.\n
- Amount must be same.
- Only single `Payment Request` available for this amount.
- Amount must be same.
- Only single `Payment Request` available for this amount.
Example: [(reference_doctype, reference_name, allocated_amount, payment_request), ...]
"""
@@ -2109,7 +2171,7 @@ def get_outstanding_of_references_with_payment_term(references=None):
def get_outstanding_of_references_with_no_payment_term(references):
"""
Fetch outstanding amount of `References` which have no `Payment Term` set.\n
- Fetch outstanding amount from `References` it self.
- Fetch outstanding amount from `References` it self.
Note: `None` is used for allocation of `Payment Request`
Example: {(reference_doctype, reference_name, None): outstanding_amount, ...}
@@ -2923,9 +2985,6 @@ def get_payment_entry(
update_accounting_dimensions(pe, doc)
if party_account and bank:
pe.set_exchange_rate(ref_doc=doc)
pe.set_amounts()
if discount_amount:
base_total_discount_loss = 0
if frappe.db.get_single_value("Accounts Settings", "book_tax_discount_loss"):
@@ -2935,7 +2994,8 @@ def get_payment_entry(
pe, doc, discount_amount, base_total_discount_loss, party_account_currency
)
pe.set_difference_amount()
pe.set_exchange_rate(ref_doc=doc)
pe.set_amounts()
# If PE is created from PR directly, then no need to find open PRs for the references
if not created_from_payment_request:
@@ -2947,7 +3007,7 @@ def get_payment_entry(
def get_open_payment_requests_for_references(references=None):
"""
Fetch all unpaid Payment Requests for the references. \n
- Each reference can have multiple Payment Requests. \n
- Each reference can have multiple Payment Requests. \n
Example: {("Sales Invoice", "SINV-00001"): {"PREQ-00001": 1000, "PREQ-00002": 2000}}
"""
@@ -2971,6 +3031,7 @@ def get_open_payment_requests_for_references(references=None):
.where(Tuple(PR.reference_doctype, PR.reference_name).isin(list(refs)))
.where(PR.status != "Paid")
.where(PR.docstatus == 1)
.where(PR.outstanding_amount > 0) # to avoid old PRs with 0 outstanding amount
.orderby(Coalesce(PR.transaction_date, PR.creation), order=frappe.qb.asc)
).run(as_dict=True)
@@ -3285,13 +3346,14 @@ def set_pending_discount_loss(pe, doc, discount_amount, base_total_discount_loss
book_tax_loss = frappe.db.get_single_value("Accounts Settings", "book_tax_discount_loss")
account_type = "round_off_account" if book_tax_loss else "default_discount_account"
pe.set_gain_or_loss(
account_details={
pe.append(
"deductions",
{
"account": frappe.get_cached_value("Company", pe.company, account_type),
"cost_center": pe.cost_center
or frappe.get_cached_value("Company", pe.company, "cost_center"),
"amount": discount_amount * positive_negative,
}
},
)

View File

@@ -488,16 +488,9 @@ class TestPaymentEntry(IntegrationTestCase):
self.assertEqual(pe.deductions[0].account, "Write Off - _TC")
# Exchange loss
self.assertEqual(pe.difference_amount, 300.0)
pe.append(
"deductions",
{
"account": "_Test Exchange Gain/Loss - _TC",
"cost_center": "_Test Cost Center - _TC",
"amount": 300.0,
},
)
self.assertEqual(pe.deductions[-1].amount, 300.0)
pe.deductions[-1].account = "_Test Exchange Gain/Loss - _TC"
pe.deductions[-1].cost_center = "_Test Cost Center - _TC"
pe.insert()
pe.submit()
@@ -561,16 +554,10 @@ class TestPaymentEntry(IntegrationTestCase):
pe.reference_no = "1"
pe.reference_date = "2016-01-01"
self.assertEqual(pe.difference_amount, 100)
self.assertEqual(pe.deductions[0].amount, 100)
pe.deductions[0].account = "_Test Exchange Gain/Loss - _TC"
pe.deductions[0].cost_center = "_Test Cost Center - _TC"
pe.append(
"deductions",
{
"account": "_Test Exchange Gain/Loss - _TC",
"cost_center": "_Test Cost Center - _TC",
"amount": 100,
},
)
pe.insert()
pe.submit()
@@ -660,16 +647,9 @@ class TestPaymentEntry(IntegrationTestCase):
pe.set_exchange_rate()
pe.set_amounts()
self.assertEqual(pe.difference_amount, 500)
pe.append(
"deductions",
{
"account": "_Test Exchange Gain/Loss - _TC",
"cost_center": "_Test Cost Center - _TC",
"amount": 500,
},
)
self.assertEqual(pe.deductions[0].amount, 500)
pe.deductions[0].account = "_Test Exchange Gain/Loss - _TC"
pe.deductions[0].cost_center = "_Test Cost Center - _TC"
pe.insert()
pe.submit()
@@ -1539,7 +1519,7 @@ class TestPaymentEntry(IntegrationTestCase):
parent_account="Current Liabilities - _TC",
account_name="Advances Paid",
company=company,
account_type="Liability",
account_type="Payable",
)
frappe.db.set_value(

View File

@@ -9,6 +9,7 @@
"cost_center",
"amount",
"column_break_2",
"is_exchange_gain_loss",
"description"
],
"fields": [
@@ -45,12 +46,20 @@
"fieldname": "description",
"fieldtype": "Small Text",
"label": "Description"
},
{
"default": "0",
"depends_on": "eval:doc.is_exchange_gain_loss",
"fieldname": "is_exchange_gain_loss",
"fieldtype": "Check",
"label": "Is Exchange Gain / Loss?",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:09.454552",
"modified": "2024-11-05 16:07:47.307971",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry Deduction",

View File

@@ -18,6 +18,7 @@ class PaymentEntryDeduction(Document):
amount: DF.Currency
cost_center: DF.Link
description: DF.SmallText | None
is_exchange_gain_loss: DF.Check
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data

View File

@@ -153,10 +153,7 @@ class PaymentReconciliation(Document):
self.add_payment_entries(non_reconciled_payments)
def get_payment_entries(self):
if self.default_advance_account:
party_account = [self.receivable_payable_account, self.default_advance_account]
else:
party_account = [self.receivable_payable_account]
party_account = [self.receivable_payable_account]
order_doctype = "Sales Order" if self.party_type == "Customer" else "Purchase Order"
condition = frappe._dict(
@@ -187,6 +184,7 @@ class PaymentReconciliation(Document):
self.party,
party_account,
order_doctype,
default_advance_account=self.default_advance_account,
against_all_orders=True,
limit=self.payment_limit,
condition=condition,

View File

@@ -60,7 +60,9 @@
"payment_order",
"amended_from",
"column_break_pnyv",
"payment_url"
"payment_url",
"column_break_iiuv",
"phone_number"
],
"fields": [
{
@@ -378,6 +380,7 @@
"read_only": 1
},
{
"depends_on": "eval: doc.payment_channel==\"Phone\"",
"fetch_from": "payment_gateway_account.payment_channel",
"fieldname": "payment_channel",
"fieldtype": "Select",
@@ -444,13 +447,22 @@
"fieldtype": "Data",
"label": "Party Name",
"read_only": 1
},
{
"fieldname": "column_break_iiuv",
"fieldtype": "Column Break"
},
{
"fieldname": "phone_number",
"fieldtype": "Data",
"label": "Phone Number"
}
],
"in_create": 1,
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2024-10-23 12:23:40.117336",
"modified": "2025-01-04 05:39:32.448857",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",

View File

@@ -3,7 +3,7 @@ import json
import frappe
from frappe import _, qb
from frappe.model.document import Document
from frappe.query_builder.functions import Sum
from frappe.query_builder.functions import Abs, Sum
from frappe.utils import flt, nowdate
from frappe.utils.background_jobs import enqueue
@@ -81,6 +81,7 @@ class PaymentRequest(Document):
payment_order: DF.Link | None
payment_request_type: DF.Literal["Outward", "Inward"]
payment_url: DF.Data | None
phone_number: DF.Data | None
print_format: DF.Literal[None]
project: DF.Link | None
reference_doctype: DF.Link | None
@@ -221,6 +222,7 @@ class PaymentRequest(Document):
sender=self.email_to,
currency=self.currency,
payment_gateway=self.payment_gateway,
phone_number=self.phone_number,
)
controller.validate_transaction_currency(self.currency)
@@ -563,6 +565,8 @@ def make_payment_request(**args):
# fetches existing payment request `grand_total` amount
existing_payment_request_amount = get_existing_payment_request_amount(ref_doc.doctype, ref_doc.name)
existing_paid_amount = get_existing_paid_amount(ref_doc.doctype, ref_doc.name)
def validate_and_calculate_grand_total(grand_total, existing_payment_request_amount):
grand_total -= existing_payment_request_amount
if not grand_total:
@@ -582,6 +586,15 @@ def make_payment_request(**args):
else:
grand_total = validate_and_calculate_grand_total(grand_total, existing_payment_request_amount)
if existing_paid_amount:
if ref_doc.party_account_currency == ref_doc.currency:
if ref_doc.conversion_rate:
grand_total -= flt(existing_paid_amount / ref_doc.conversion_rate)
else:
grand_total -= flt(existing_paid_amount)
else:
grand_total -= flt(existing_paid_amount / ref_doc.conversion_rate)
if draft_payment_request:
frappe.db.set_value(
"Payment Request", draft_payment_request, "grand_total", grand_total, update_modified=False
@@ -632,6 +645,7 @@ def make_payment_request(**args):
or args.order_type == "Shopping Cart" # compat for webshop app
or gateway_account.get("payment_channel", "Email") != "Email"
),
"phone_number": args.get("phone_number") if args.get("phone_number") else None,
}
)
@@ -758,6 +772,29 @@ def get_existing_payment_request_amount(ref_dt, ref_dn, statuses: list | None =
return response[0][0] if response[0] else 0
def get_existing_paid_amount(doctype, name):
PL = frappe.qb.DocType("Payment Ledger Entry")
PER = frappe.qb.DocType("Payment Entry Reference")
query = (
frappe.qb.from_(PL)
.left_join(PER)
.on(
(PER.reference_doctype == PL.against_voucher_type) & (PER.reference_name == PL.against_voucher_no)
)
.select(Abs(Sum(PL.amount)).as_("total_paid_amount"))
.where(PL.against_voucher_type.eq(doctype))
.where(PL.against_voucher_no.eq(name))
.where(PL.amount < 0)
.where(PL.delinked == 0)
.where(PER.docstatus == 1)
.where(PER.payment_request.isnull())
)
response = query.run()
return response[0][0] if response[0] else 0
def get_gateway_details(args): # nosemgrep
"""
Return gateway and payment account of default payment gateway

View File

@@ -1,7 +1,7 @@
const INDICATORS = {
"Partially Paid": "orange",
Cancelled: "red",
Draft: "gray",
Draft: "red",
Failed: "red",
Initiated: "green",
Paid: "blue",

View File

@@ -8,6 +8,7 @@ from unittest.mock import patch
import frappe
from frappe.tests import IntegrationTestCase, UnitTestCase
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_terms_template
from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
@@ -689,3 +690,48 @@ class TestPaymentRequest(IntegrationTestCase):
so.load_from_db()
self.assertEqual(so.advance_payment_status, "Requested")
def test_partial_paid_invoice_with_payment_request(self):
si = create_sales_invoice(currency="INR", qty=1, rate=5000)
si.save()
si.submit()
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
pe.reference_no = "PAYEE0002"
pe.reference_date = frappe.utils.nowdate()
pe.paid_amount = 2500
pe.references[0].allocated_amount = 2500
pe.save()
pe.submit()
si.load_from_db()
pr = make_payment_request(dt="Sales Invoice", dn=si.name, mute_email=1)
self.assertEqual(pr.grand_total, si.outstanding_amount)
def test_partial_paid_invoice_with_submitted_payment_entry(self):
pi = make_purchase_invoice(currency="INR", qty=1, rate=5000)
pi.save()
pi.submit()
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
pe.reference_no = "PURINV0001"
pe.reference_date = frappe.utils.nowdate()
pe.paid_amount = 2500
pe.references[0].allocated_amount = 2500
pe.save()
pe.submit()
pe.cancel()
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
pe.reference_no = "PURINV0002"
pe.reference_date = frappe.utils.nowdate()
pe.paid_amount = 2500
pe.references[0].allocated_amount = 2500
pe.save()
pe.submit()
pi.load_from_db()
pr = make_payment_request(dt="Purchase Invoice", dn=pi.name, mute_email=1)
self.assertEqual(pr.grand_total, pi.outstanding_amount)

View File

@@ -171,9 +171,7 @@ class PeriodClosingVoucher(AccountsController):
pl_account_balances = self.get_account_balances_based_on_dimensions(report_type="Profit and Loss")
for dimensions, account_balances in pl_account_balances.items():
for acc, balances in account_balances.items():
balance_in_company_currency = flt(balances.debit_in_account_currency) - flt(
balances.credit_in_account_currency
)
balance_in_company_currency = flt(balances.debit) - flt(balances.credit)
if balance_in_company_currency and acc != "balances":
self.pl_accounts_reverse_gle.append(
self.get_gle_for_pl_account(acc, balances, dimensions)

View File

@@ -12,15 +12,15 @@
</thead>
<tbody>
<tr>
<td class="text-left font-bold">{{ _('Grand Total') }}</td>
<td class="text-left font-bold">{{ _("Grand Total") }}</td>
<td class='text-right'> {{ frappe.utils.fmt_money(data.grand_total or '', currency=currency) }}</td>
</tr>
<tr>
<td class="text-left font-bold">{{ _('Net Total') }}</td>
<td class="text-left font-bold">{{ _("Net Total") }}</td>
<td class='text-right'> {{ frappe.utils.fmt_money(data.net_total or '', currency=currency) }}</td>
</tr>
<tr>
<td class="text-left font-bold">{{ _('Total Quantity') }}</td>
<td class="text-left font-bold">{{ _("Total Quantity") }}</td>
<td class='text-right'>{{ data.total_quantity or '' }}</td>
</tr>
@@ -44,7 +44,7 @@
<tbody>
{% for d in data.payment_reconciliation %}
<tr>
<td class="text-left">{{ d.mode_of_payment }}</td>
<td class="text-left">{{ _(d.mode_of_payment) }}</td>
<td class='text-right'> {{ frappe.utils.fmt_money(d.expected_amount - d.opening_amount, currency=currency) }}</td>
</tr>
{% endfor %}
@@ -63,7 +63,7 @@
<thead>
<tr>
<th class="text-left">{{ _("Account") }}</th>
<th class="text-left">{{ _("Rate") }}</th>
<th class="text-left">{{ _("Tax Rate") }}</th>
<th class="text-right">{{ _("Amount") }}</th>
</tr>
</thead>

View File

@@ -147,7 +147,7 @@ frappe.ui.form.on("POS Closing Entry", {
frm.doc.grand_total += flt(doc.grand_total);
frm.doc.net_total += flt(doc.net_total);
frm.doc.total_quantity += flt(doc.total_qty);
refresh_payments(doc, frm);
refresh_payments(doc, frm, false);
refresh_taxes(doc, frm);
refresh_fields(frm);
set_html_data(frm);
@@ -172,7 +172,7 @@ function set_form_data(data, frm) {
frm.doc.grand_total += flt(d.grand_total);
frm.doc.net_total += flt(d.net_total);
frm.doc.total_quantity += flt(d.total_qty);
refresh_payments(d, frm);
refresh_payments(d, frm, true);
refresh_taxes(d, frm);
});
}
@@ -186,7 +186,7 @@ function add_to_pos_transaction(d, frm) {
});
}
function refresh_payments(d, frm) {
function refresh_payments(d, frm, is_new) {
d.payments.forEach((p) => {
const payment = frm.doc.payment_reconciliation.find(
(pay) => pay.mode_of_payment === p.mode_of_payment
@@ -196,9 +196,7 @@ function refresh_payments(d, frm) {
}
if (payment) {
payment.expected_amount += flt(p.amount);
if (payment.closing_amount === 0) {
payment.closing_amount = payment.expected_amount;
}
if (is_new) payment.closing_amount = payment.expected_amount;
payment.difference = payment.closing_amount - payment.expected_amount;
} else {
frm.add_child("payment_reconciliation", {

View File

@@ -14,7 +14,7 @@
"fieldname": "rate",
"fieldtype": "Percent",
"in_list_view": 1,
"label": "Rate",
"label": "Tax Rate",
"read_only": 1
},
{

View File

@@ -48,6 +48,7 @@
"shipping_address",
"company_address",
"company_address_display",
"company_contact_person",
"currency_and_price_list",
"currency",
"conversion_rate",
@@ -1549,10 +1550,10 @@
},
{
"fieldname": "utm_medium",
"print_hide": 1,
"fieldtype": "Link",
"label": "Medium",
"options": "UTM Medium"
"options": "UTM Medium",
"print_hide": 1
},
{
"fieldname": "utm_campaign",
@@ -1571,12 +1572,19 @@
"oldfieldtype": "Select",
"options": "UTM Source",
"print_hide": 1
},
{
"fieldname": "company_contact_person",
"fieldtype": "Link",
"label": "Company Contact Person",
"options": "Contact",
"print_hide": 1
}
],
"icon": "fa fa-file-text",
"is_submittable": 1,
"links": [],
"modified": "2024-06-28 10:55:34.941200",
"modified": "2024-11-26 13:10:50.309570",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice",
@@ -1630,4 +1638,4 @@
"title_field": "title",
"track_changes": 1,
"track_seen": 1
}
}

View File

@@ -32,12 +32,8 @@ class POSInvoice(SalesInvoice):
from erpnext.accounts.doctype.payment_schedule.payment_schedule import PaymentSchedule
from erpnext.accounts.doctype.pos_invoice_item.pos_invoice_item import POSInvoiceItem
from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail
from erpnext.accounts.doctype.sales_invoice_advance.sales_invoice_advance import (
SalesInvoiceAdvance,
)
from erpnext.accounts.doctype.sales_invoice_payment.sales_invoice_payment import (
SalesInvoicePayment,
)
from erpnext.accounts.doctype.sales_invoice_advance.sales_invoice_advance import SalesInvoiceAdvance
from erpnext.accounts.doctype.sales_invoice_payment.sales_invoice_payment import SalesInvoicePayment
from erpnext.accounts.doctype.sales_invoice_timesheet.sales_invoice_timesheet import (
SalesInvoiceTimesheet,
)
@@ -74,6 +70,7 @@ class POSInvoice(SalesInvoice):
company: DF.Link
company_address: DF.Link | None
company_address_display: DF.TextEditor | None
company_contact_person: DF.Link | None
consolidated_invoice: DF.Link | None
contact_display: DF.SmallText | None
contact_email: DF.Data | None

View File

@@ -118,11 +118,13 @@ class POSInvoiceMergeLog(Document):
sales = [d for d in pos_invoice_docs if d.get("is_return") == 0]
sales_invoice, credit_note = "", ""
if returns:
credit_note = self.process_merging_into_credit_note(returns)
sales_invoice_doc = None
if sales:
sales_invoice = self.process_merging_into_sales_invoice(sales)
sales_invoice_doc = self.process_merging_into_sales_invoice(sales)
sales_invoice = sales_invoice_doc.name
if returns:
credit_note = self.process_merging_into_credit_note(returns, sales_invoice_doc)
self.save() # save consolidated_sales_invoice & consolidated_credit_note ref in merge log
self.update_pos_invoices(pos_invoice_docs, sales_invoice, credit_note)
@@ -133,6 +135,7 @@ class POSInvoiceMergeLog(Document):
self.update_pos_invoices(pos_invoice_docs)
self.serial_and_batch_bundle_reference_for_pos_invoice()
self.cancel_linked_invoices()
self.delink_serial_and_batch_bundle()
def process_merging_into_sales_invoice(self, data):
sales_invoice = self.get_new_sales_invoice()
@@ -140,20 +143,35 @@ class POSInvoiceMergeLog(Document):
sales_invoice.is_consolidated = 1
sales_invoice.set_posting_time = 1
sales_invoice.posting_date = getdate(self.posting_date)
sales_invoice.posting_time = get_time(self.posting_time)
if not sales_invoice.posting_date:
sales_invoice.posting_date = getdate(self.posting_date)
if not sales_invoice.posting_time:
sales_invoice.posting_time = get_time(self.posting_time)
sales_invoice.save()
sales_invoice.submit()
self.consolidated_invoice = sales_invoice.name
return sales_invoice.name
return sales_invoice
def process_merging_into_credit_note(self, data):
def process_merging_into_credit_note(self, data, sales_invoice_doc=None):
credit_note = self.get_new_sales_invoice()
credit_note.is_return = 1
credit_note = self.merge_pos_invoice_into(credit_note, data)
referenes = {}
if sales_invoice_doc:
credit_note.return_against = sales_invoice_doc.name
for d in sales_invoice_doc.items:
referenes[d.item_code] = d.name
for d in credit_note.items:
d.sales_invoice_item = referenes.get(d.item_code)
credit_note.is_consolidated = 1
credit_note.set_posting_time = 1
@@ -181,6 +199,10 @@ class POSInvoiceMergeLog(Document):
for doc in data:
map_doc(doc, invoice, table_map={"doctype": invoice.doctype})
if doc.get("posting_date"):
invoice.posting_date = getdate(doc.posting_date)
invoice.posting_time = get_time(doc.posting_time)
if doc.redeem_loyalty_points:
invoice.loyalty_redemption_account = doc.loyalty_redemption_account
invoice.loyalty_redemption_cost_center = doc.loyalty_redemption_cost_center
@@ -298,6 +320,8 @@ class POSInvoiceMergeLog(Document):
sales_invoice = frappe.new_doc("Sales Invoice")
sales_invoice.customer = self.customer
sales_invoice.is_pos = 1
sales_invoice.posting_date = None
sales_invoice.posting_time = None
return sales_invoice
@@ -320,8 +344,45 @@ class POSInvoiceMergeLog(Document):
for table_name in ["items", "packed_items"]:
pos_invoice.set_serial_and_batch_bundle(table_name)
def delink_serial_and_batch_bundle(self):
bundles = self.get_serial_and_batch_bundles()
if not bundles:
return
sle_table = frappe.qb.DocType("Stock Ledger Entry")
query = (
frappe.qb.update(sle_table)
.set(sle_table.serial_and_batch_bundle, None)
.where(sle_table.serial_and_batch_bundle.isin(bundles) & sle_table.is_cancelled == 1)
)
query.run()
def get_serial_and_batch_bundles(self):
pos_invoices = []
for d in self.pos_invoices:
pos_invoices.append(d.pos_invoice)
if pos_invoices:
return frappe.get_all(
"POS Invoice Item",
filters={
"docstatus": 1,
"parent": ["in", pos_invoices],
"serial_and_batch_bundle": ["is", "set"],
},
pluck="serial_and_batch_bundle",
)
return []
def cancel_linked_invoices(self):
for si_name in [self.consolidated_invoice, self.consolidated_credit_note]:
invoices = [self.consolidated_invoice, self.consolidated_credit_note]
if not invoices:
return
invoices.reverse()
for si_name in invoices:
if not si_name:
continue
si = frappe.get_doc("Sales Invoice", si_name)
@@ -503,6 +564,9 @@ def cancel_merge_logs(merge_logs, closing_entry=None):
try:
for log in merge_logs:
merge_log = frappe.get_doc("POS Invoice Merge Log", log)
if merge_log.docstatus == 2:
continue
merge_log.flags.ignore_permissions = True
merge_log.cancel()

View File

@@ -25,6 +25,7 @@
"hide_unavailable_items",
"auto_add_item_to_cart",
"validate_stock_on_save",
"print_receipt_on_order_complete",
"column_break_16",
"update_stock",
"ignore_pricing_rule",
@@ -374,24 +375,30 @@
},
{
"fieldname": "utm_campaign",
"print_hide": 1,
"fieldtype": "Link",
"label": "Campaign",
"options": "UTM Campaign"
"options": "UTM Campaign",
"print_hide": 1
},
{
"fieldname": "utm_source",
"print_hide": 1,
"fieldtype": "Link",
"label": "Source",
"options": "UTM Source"
"options": "UTM Source",
"print_hide": 1
},
{
"fieldname": "utm_medium",
"print_hide": 1,
"fieldtype": "Link",
"label": "Medium",
"options": "UTM Campaign"
"options": "UTM Campaign",
"print_hide": 1
},
{
"default": "0",
"fieldname": "print_receipt_on_order_complete",
"fieldtype": "Check",
"label": "Print Receipt on Order Complete"
}
],
"icon": "icon-cog",
@@ -419,7 +426,7 @@
"link_fieldname": "pos_profile"
}
],
"modified": "2024-06-28 10:51:48.543766",
"modified": "2025-01-01 11:07:03.161950",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",
@@ -448,4 +455,4 @@
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}
}

View File

@@ -46,6 +46,7 @@ class POSProfile(Document):
letter_head: DF.Link | None
payments: DF.Table[POSPaymentMethod]
print_format: DF.Link | None
print_receipt_on_order_complete: DF.Check
select_print_heading: DF.Link | None
selling_price_list: DF.Link | None
tax_category: DF.Link | None

View File

@@ -415,6 +415,8 @@ def get_pricing_rule_for_item(args, doc=None, for_validate=False):
"parent": args.parent,
"parenttype": args.parenttype,
"child_docname": args.get("child_docname"),
"discount_percentage": 0.0,
"discount_amount": 0,
}
)

View File

@@ -651,8 +651,17 @@ def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None):
qty = pricing_rule.free_qty or 1
if pricing_rule.is_recursive:
transaction_qty = (args.get("qty") if args else doc.total_qty) - pricing_rule.apply_recursion_over
if transaction_qty:
transaction_qty = sum(
[
row.qty
for row in doc.items
if not row.is_free_item
and row.item_code == args.item_code
and row.pricing_rules == args.pricing_rules
]
)
transaction_qty = transaction_qty - pricing_rule.apply_recursion_over
if transaction_qty and transaction_qty > 0:
qty = flt(transaction_qty) * qty / pricing_rule.recurse_for
if pricing_rule.round_free_qty:
qty = (flt(transaction_qty) // pricing_rule.recurse_for) * (pricing_rule.free_qty or 1)

View File

@@ -1,7 +1,6 @@
{
"actions": [],
"autoname": "format:ACC-PPR-{#####}",
"beta": 1,
"creation": "2023-03-30 21:28:39.793927",
"default_view": "List",
"doctype": "DocType",
@@ -158,7 +157,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2024-08-27 14:48:56.715320",
"modified": "2025-01-08 08:22:14.798085",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Process Payment Reconciliation",
@@ -192,4 +191,4 @@
"sort_order": "DESC",
"states": [],
"title_field": "company"
}
}

View File

@@ -212,7 +212,7 @@ def trigger_reconciliation_for_queued_docs():
unique_filters = set()
queue_size = 5
fields = ["company", "party_type", "party", "receivable_payable_account"]
fields = ["company", "party_type", "party", "receivable_payable_account", "default_advance_account"]
def get_filters_as_tuple(fields, doc):
filters = ()

View File

@@ -1,7 +1,6 @@
{
"actions": [],
"autoname": "format:PPR-LOG-{##}",
"beta": 1,
"creation": "2023-03-13 15:00:09.149681",
"default_view": "List",
"doctype": "DocType",
@@ -110,7 +109,7 @@
"in_create": 1,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-03-27 13:10:18.769659",
"modified": "2025-01-08 08:22:19.104975",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Process Payment Reconciliation Log",

View File

@@ -244,9 +244,9 @@
},
{
"fieldname": "cc_to",
"fieldtype": "Link",
"fieldtype": "Table MultiSelect",
"label": "CC To",
"options": "User"
"options": "Process Statement Of Accounts CC"
},
{
"default": "1",
@@ -400,7 +400,7 @@
}
],
"links": [],
"modified": "2024-10-18 17:51:39.108481",
"modified": "2024-12-11 12:11:13.543134",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Process Statement Of Accounts",

View File

@@ -31,6 +31,9 @@ class ProcessStatementOfAccounts(Document):
if TYPE_CHECKING:
from frappe.types import DF
from erpnext.accounts.doctype.process_statement_of_accounts_cc.process_statement_of_accounts_cc import (
ProcessStatementOfAccountsCC,
)
from erpnext.accounts.doctype.process_statement_of_accounts_customer.process_statement_of_accounts_customer import (
ProcessStatementOfAccountsCustomer,
)
@@ -41,7 +44,7 @@ class ProcessStatementOfAccounts(Document):
ageing_based_on: DF.Literal["Due Date", "Posting Date"]
based_on_payment_terms: DF.Check
body: DF.TextEditor | None
cc_to: DF.Link | None
cc_to: DF.TableMultiSelect[ProcessStatementOfAccountsCC]
collection_name: DF.DynamicLink | None
company: DF.Link
cost_center: DF.TableMultiSelect[PSOACostCenter]
@@ -324,7 +327,7 @@ def get_recipients_and_cc(customer, doc):
cc = []
if doc.cc_to != "":
try:
cc = [frappe.get_value("User", doc.cc_to, "email")]
cc = [frappe.get_value("User", user.cc, "email") for user in doc.cc_to]
except Exception:
pass

View File

@@ -0,0 +1,32 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2024-12-11 12:10:04.654593",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"cc"
],
"fields": [
{
"fieldname": "cc",
"fieldtype": "Link",
"in_list_view": 1,
"label": "CC",
"options": "User"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-12-11 12:10:39.772598",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Process Statement Of Accounts CC",
"owner": "Administrator",
"permissions": [],
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -0,0 +1,23 @@
# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class ProcessStatementOfAccountsCC(Document):
# begin: auto-generated types
# This code is auto-generated. Do not modify anything in this block.
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from frappe.types import DF
cc: DF.Link | None
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data
# end: auto-generated types
pass

View File

@@ -403,6 +403,8 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
hide_fields(this.frm.doc);
if (cint(this.frm.doc.is_paid)) {
this.frm.set_value("allocate_advances_automatically", 0);
this.frm.set_value("payment_terms_template", "");
this.frm.set_value("payment_schedule", []);
if (!this.frm.doc.company) {
this.frm.set_value("is_paid", 0);
frappe.msgprint(__("Please specify Company to proceed"));

View File

@@ -1683,7 +1683,12 @@ class PurchaseInvoice(BuyingController):
if pi:
pi = pi[0][0]
frappe.throw(_("Supplier Invoice No exists in Purchase Invoice {0}").format(pi))
frappe.throw(
_("Supplier Invoice No exists in Purchase Invoice {0}").format(
get_link_to_form("Purchase Invoice", pi)
)
)
def update_billing_status_in_pr(self, update_modified=True):
if self.is_return and not self.update_billed_amount_in_purchase_receipt:

View File

@@ -1742,6 +1742,30 @@ class TestPurchaseInvoice(IntegrationTestCase, StockTestMixin):
frappe.db.set_single_value("Buying Settings", "set_landed_cost_based_on_purchase_invoice_rate", 1)
# Cost of Item is zero in Purchase Receipt
pr = make_purchase_receipt(qty=1, rate=0)
stock_value_difference = frappe.db.get_value(
"Stock Ledger Entry",
{"voucher_type": "Purchase Receipt", "voucher_no": pr.name},
"stock_value_difference",
)
self.assertEqual(stock_value_difference, 0)
pi = create_purchase_invoice_from_receipt(pr.name)
for row in pi.items:
row.rate = 150
pi.save()
pi.submit()
stock_value_difference = frappe.db.get_value(
"Stock Ledger Entry",
{"voucher_type": "Purchase Receipt", "voucher_no": pr.name},
"stock_value_difference",
)
self.assertEqual(stock_value_difference, 150)
# Increase the cost of the item
pr = make_purchase_receipt(qty=1, rate=100)
@@ -1821,6 +1845,52 @@ class TestPurchaseInvoice(IntegrationTestCase, StockTestMixin):
frappe.db.set_single_value("Buying Settings", "maintain_same_rate", 1)
def test_adjust_incoming_rate_for_rejected_item(self):
frappe.db.set_single_value("Buying Settings", "maintain_same_rate", 0)
frappe.db.set_single_value("Buying Settings", "set_landed_cost_based_on_purchase_invoice_rate", 1)
# Cost of Item is zero in Purchase Receipt
pr = make_purchase_receipt(qty=1, rejected_qty=1, rate=0)
stock_value_difference = frappe.db.get_value(
"Stock Ledger Entry",
{"voucher_type": "Purchase Receipt", "voucher_no": pr.name},
"stock_value_difference",
)
self.assertEqual(stock_value_difference, 0)
pi = create_purchase_invoice_from_receipt(pr.name)
for row in pi.items:
row.qty = 1
row.rate = 150
pi.save()
pi.submit()
stock_value_difference = frappe.db.get_value(
"Stock Ledger Entry",
{"voucher_type": "Purchase Receipt", "voucher_no": pr.name, "warehouse": pi.items[0].warehouse},
"stock_value_difference",
)
self.assertEqual(stock_value_difference, 150)
stock_value_difference = frappe.db.get_value(
"Stock Ledger Entry",
{
"voucher_type": "Purchase Receipt",
"voucher_no": pr.name,
"warehouse": pi.items[0].rejected_warehouse,
},
"stock_value_difference",
)
self.assertFalse(stock_value_difference)
frappe.db.set_single_value("Buying Settings", "set_landed_cost_based_on_purchase_invoice_rate", 0)
frappe.db.set_single_value("Buying Settings", "maintain_same_rate", 1)
def test_item_less_defaults(self):
pi = frappe.new_doc("Purchase Invoice")
pi.supplier = "_Test Supplier"
@@ -2441,6 +2511,34 @@ class TestPurchaseInvoice(IntegrationTestCase, StockTestMixin):
item.reload()
self.assertEqual(item.last_purchase_rate, 0)
def test_invoice_against_returned_pr(self):
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
make_purchase_invoice as make_purchase_invoice_from_pr,
)
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
make_purchase_return_against_rejected_warehouse,
)
item = make_item("_Test Item For Invoice Against Returned PR", properties={"is_stock_item": 1}).name
original_value = frappe.db.get_single_value(
"Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice"
)
frappe.db.set_single_value("Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice", 0)
pr = make_purchase_receipt(item_code=item, qty=5, rejected_qty=5, rate=100)
pr_return = make_purchase_return_against_rejected_warehouse(pr.name)
pr_return.submit()
pi = make_purchase_invoice_from_pr(pr.name)
pi.save()
self.assertEqual(pi.items[0].qty, 5.0)
frappe.db.set_single_value(
"Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice", original_value
)
def set_advance_flag(company, flag, default_account):
frappe.db.set_value(

View File

@@ -14,7 +14,8 @@
"advance_amount",
"allocated_amount",
"exchange_gain_loss",
"ref_exchange_rate"
"ref_exchange_rate",
"difference_posting_date"
],
"fields": [
{
@@ -30,7 +31,7 @@
"width": "180px"
},
{
"columns": 3,
"columns": 2,
"fieldname": "reference_name",
"fieldtype": "Dynamic Link",
"in_list_view": 1,
@@ -40,7 +41,7 @@
"read_only": 1
},
{
"columns": 3,
"columns": 2,
"fieldname": "remarks",
"fieldtype": "Text",
"in_list_view": 1,
@@ -111,13 +112,20 @@
"label": "Reference Exchange Rate",
"non_negative": 1,
"read_only": 1
},
{
"columns": 2,
"fieldname": "difference_posting_date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "Difference Posting Date"
}
],
"idx": 1,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:24.072896",
"modified": "2024-12-20 12:04:46.729972",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Advance",

View File

@@ -16,6 +16,7 @@ class PurchaseInvoiceAdvance(Document):
advance_amount: DF.Currency
allocated_amount: DF.Currency
difference_posting_date: DF.Date | None
exchange_gain_loss: DF.Currency
parent: DF.Data
parentfield: DF.Data

View File

@@ -1,6 +1,8 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import inspect
import frappe
from frappe import _, qb
from frappe.model.document import Document
@@ -142,6 +144,8 @@ class RepostAccountingLedger(Document):
@frappe.whitelist()
def start_repost(account_repost_doc=str) -> None:
from erpnext.accounts.general_ledger import make_reverse_gl_entries
frappe.flags.through_repost_accounting_ledger = True
if account_repost_doc:
repost_doc = frappe.get_doc("Repost Accounting Ledger", account_repost_doc)
@@ -177,6 +181,14 @@ def start_repost(account_repost_doc=str) -> None:
if not repost_doc.delete_cancelled_entries:
doc.make_gl_entries(1)
doc.make_gl_entries()
elif doc.doctype in frappe.get_hooks("repost_allowed_doctypes"):
if hasattr(doc, "make_gl_entries") and callable(doc.make_gl_entries):
if not repost_doc.delete_cancelled_entries:
if "cancel" in inspect.getfullargspec(doc.make_gl_entries):
doc.make_gl_entries(cancel=1)
else:
make_reverse_gl_entries(voucher_type=doc.doctype, voucher_no=doc.name)
doc.make_gl_entries()
def get_allowed_types_from_settings():

View File

@@ -993,47 +993,51 @@ frappe.ui.form.on("Sales Invoice", {
refresh: function (frm) {
if (frm.doc.docstatus === 0 && !frm.doc.is_return) {
frm.add_custom_button(__("Fetch Timesheet"), function () {
let d = new frappe.ui.Dialog({
title: __("Fetch Timesheet"),
fields: [
{
label: __("From"),
fieldname: "from_time",
fieldtype: "Date",
reqd: 1,
frm.add_custom_button(
__("Timesheet"),
function () {
let d = new frappe.ui.Dialog({
title: __("Fetch Timesheet"),
fields: [
{
label: __("From"),
fieldname: "from_time",
fieldtype: "Date",
reqd: 1,
},
{
fieldtype: "Column Break",
fieldname: "col_break_1",
},
{
label: __("To"),
fieldname: "to_time",
fieldtype: "Date",
reqd: 1,
},
{
label: __("Project"),
fieldname: "project",
fieldtype: "Link",
options: "Project",
default: frm.doc.project,
},
],
primary_action: function () {
const data = d.get_values();
frm.events.add_timesheet_data(frm, {
from_time: data.from_time,
to_time: data.to_time,
project: data.project,
});
d.hide();
},
{
fieldtype: "Column Break",
fieldname: "col_break_1",
},
{
label: __("To"),
fieldname: "to_time",
fieldtype: "Date",
reqd: 1,
},
{
label: __("Project"),
fieldname: "project",
fieldtype: "Link",
options: "Project",
default: frm.doc.project,
},
],
primary_action: function () {
const data = d.get_values();
frm.events.add_timesheet_data(frm, {
from_time: data.from_time,
to_time: data.to_time,
project: data.project,
});
d.hide();
},
primary_action_label: __("Get Timesheets"),
});
d.show();
});
primary_action_label: __("Get Timesheets"),
});
d.show();
},
__("Get Items From")
);
}
if (frm.doc.is_debit_note) {

View File

@@ -161,8 +161,9 @@
"dispatch_address",
"company_address_section",
"company_address",
"company_addr_col_break",
"company_address_display",
"company_addr_col_break",
"company_contact_person",
"terms_tab",
"payment_schedule_section",
"ignore_default_payment_terms_template",
@@ -2203,6 +2204,13 @@
"oldfieldtype": "Select",
"options": "UTM Source",
"print_hide": 1
},
{
"fieldname": "company_contact_person",
"fieldtype": "Link",
"label": "Company Contact Person",
"options": "Contact",
"print_hide": 1
}
],
"icon": "fa fa-file-text",
@@ -2215,7 +2223,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2024-07-18 15:30:39.428519",
"modified": "2024-11-26 12:34:09.110690",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
@@ -2270,4 +2278,4 @@
"title_field": "title",
"track_changes": 1,
"track_seen": 1
}
}

View File

@@ -98,6 +98,7 @@ class SalesInvoice(SellingController):
company: DF.Link
company_address: DF.Link | None
company_address_display: DF.TextEditor | None
company_contact_person: DF.Link | None
company_tax_id: DF.Data | None
contact_display: DF.SmallText | None
contact_email: DF.Data | None
@@ -153,7 +154,6 @@ class SalesInvoice(SellingController):
party_account_currency: DF.Link | None
payment_schedule: DF.Table[PaymentSchedule]
payment_terms_template: DF.Link | None
payment_url: DF.Data | None
payments: DF.Table[SalesInvoicePayment]
plc_conversion_rate: DF.Float
po_date: DF.Date | None
@@ -323,9 +323,7 @@ class SalesInvoice(SellingController):
self.set_against_income_account()
self.validate_time_sheets_are_submitted()
self.validate_multiple_billing("Delivery Note", "dn_detail", "amount")
if not self.is_return:
self.validate_serial_numbers()
else:
if self.is_return:
self.timesheets = []
self.update_packing_list()
self.set_billing_hours_and_amount()
@@ -364,7 +362,7 @@ class SalesInvoice(SellingController):
if self.update_stock:
frappe.throw(_("'Update Stock' cannot be checked for fixed asset sale"))
elif asset.status in ("Scrapped", "Cancelled", "Capitalized", "Decapitalized") or (
elif asset.status in ("Scrapped", "Cancelled", "Capitalized") or (
asset.status == "Sold" and not self.is_return
):
frappe.throw(
@@ -506,7 +504,7 @@ class SalesInvoice(SellingController):
frappe.throw(_("Total payments amount can't be greater than {}").format(-invoice_total))
def validate_pos_paid_amount(self):
if len(self.payments) == 0 and self.is_pos:
if len(self.payments) == 0 and self.is_pos and flt(self.grand_total) > 0:
frappe.throw(_("At least one mode of payment is required for POS invoice."))
def check_if_consolidated_invoice(self):
@@ -1010,9 +1008,9 @@ class SalesInvoice(SellingController):
def validate_pos(self):
if self.is_return:
invoice_total = self.rounded_total or self.grand_total
if flt(self.paid_amount) + flt(self.write_off_amount) - flt(invoice_total) > 1.0 / (
10.0 ** (self.precision("grand_total") + 1.0)
):
if abs(flt(self.paid_amount)) + abs(flt(self.write_off_amount)) - abs(
flt(invoice_total)
) > 1.0 / (10.0 ** (self.precision("grand_total") + 1.0)):
frappe.throw(_("Paid amount + Write Off Amount can not be greater than Grand Total"))
def validate_warehouse(self):
@@ -1703,16 +1701,11 @@ class SalesInvoice(SellingController):
self.set("write_off_amount", reference_doc.get("write_off_amount"))
self.due_date = None
def validate_serial_numbers(self):
"""
validate serial number agains Delivery Note and Sales Invoice
"""
for item in self.items:
item.set_serial_no_against_delivery_note()
item.validate_serial_against_delivery_note()
def update_project(self):
unique_projects = list(set([d.project for d in self.get("items") if d.project]))
if self.project and self.project not in unique_projects:
unique_projects.append(self.project)
for p in unique_projects:
project = frappe.get_doc("Project", p)
project.update_billed_amount()

View File

@@ -15,7 +15,7 @@ frappe.listview_settings["Sales Invoice"] = {
],
get_indicator: function (doc) {
const status_colors = {
Draft: "grey",
Draft: "red",
Unpaid: "orange",
Paid: "green",
Return: "gray",

View File

@@ -43,6 +43,7 @@ from erpnext.stock.doctype.stock_entry.test_stock_entry import (
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
create_stock_reconciliation,
)
from erpnext.stock.get_item_details import get_item_tax_map
from erpnext.stock.utils import get_incoming_rate, get_stock_balance
@@ -2871,13 +2872,26 @@ class TestSalesInvoice(IntegrationTestCase):
item.save()
sales_invoice = create_sales_invoice(item="T Shirt", rate=700, do_not_submit=True)
item_tax_map = get_item_tax_map(
doc=sales_invoice,
tax_template=sales_invoice.items[0].item_tax_template,
)
self.assertEqual(sales_invoice.items[0].item_tax_template, "_Test Account Excise Duty @ 12 - _TC")
self.assertEqual(sales_invoice.items[0].item_tax_rate, item_tax_map)
# Apply discount
sales_invoice.apply_discount_on = "Net Total"
sales_invoice.discount_amount = 300
sales_invoice.save()
item_tax_map = get_item_tax_map(
doc=sales_invoice,
tax_template=sales_invoice.items[0].item_tax_template,
)
self.assertEqual(sales_invoice.items[0].item_tax_template, "_Test Account Excise Duty @ 10 - _TC")
self.assertEqual(sales_invoice.items[0].item_tax_rate, item_tax_map)
@IntegrationTestCase.change_settings("Selling Settings", {"enable_discount_accounting": 1})
def test_sales_invoice_with_discount_accounting_enabled(self):
@@ -4167,6 +4181,88 @@ class TestSalesInvoice(IntegrationTestCase):
self.assertTrue(jv)
self.assertEqual(jv[0], si.grand_total)
@IntegrationTestCase.change_settings("Accounts Settings", {"enable_common_party_accounting": True})
def test_common_party_with_different_currency_in_debtor_and_creditor(self):
from erpnext.accounts.doctype.account.test_account import create_account
from erpnext.accounts.doctype.opening_invoice_creation_tool.test_opening_invoice_creation_tool import (
make_customer,
)
from erpnext.accounts.doctype.party_link.party_link import create_party_link
from erpnext.buying.doctype.supplier.test_supplier import create_supplier
from erpnext.setup.utils import get_exchange_rate
creditors = create_account(
account_name="Creditors INR",
parent_account="Accounts Payable - _TC",
company="_Test Company",
account_currency="INR",
account_type="Payable",
)
debtors = create_account(
account_name="Debtors USD",
parent_account="Accounts Receivable - _TC",
company="_Test Company",
account_currency="USD",
account_type="Receivable",
)
# create a customer
customer = make_customer(customer="_Test Common Party USD")
cust_doc = frappe.get_doc("Customer", customer)
cust_doc.default_currency = "USD"
test_account_details = {
"company": "_Test Company",
"account": debtors,
}
cust_doc.append("accounts", test_account_details)
cust_doc.save()
# create a supplier
supplier = create_supplier(supplier_name="_Test Common Party INR").name
supp_doc = frappe.get_doc("Supplier", supplier)
supp_doc.default_currency = "INR"
test_account_details = {
"company": "_Test Company",
"account": creditors,
}
supp_doc.append("accounts", test_account_details)
supp_doc.save()
# create a party link between customer & supplier
create_party_link("Supplier", supplier, customer)
# create a sales invoice
si = create_sales_invoice(
customer=customer,
currency="USD",
conversion_rate=get_exchange_rate("USD", "INR"),
debit_to=debtors,
do_not_save=1,
)
si.party_account_currency = "USD"
si.save()
si.submit()
# check outstanding of sales invoice
si.reload()
self.assertEqual(si.status, "Paid")
self.assertEqual(flt(si.outstanding_amount), 0.0)
# check creation of journal entry
jv = frappe.get_all(
"Journal Entry Account",
{
"account": si.debit_to,
"party_type": "Customer",
"party": si.customer,
"reference_type": si.doctype,
"reference_name": si.name,
},
pluck="credit_in_account_currency",
)
self.assertTrue(jv)
self.assertEqual(jv[0], si.grand_total)
def test_invoice_remarks(self):
si = frappe.copy_doc(self.globalTestRecords["Sales Invoice"][0])
si.po_no = "Test PO"
@@ -4194,6 +4290,20 @@ class TestSalesInvoice(IntegrationTestCase):
self.assertTrue(all([x == "Credit Note" for x in gl_entries]))
def test_total_billed_amount(self):
si = create_sales_invoice(do_not_submit=True)
project = frappe.new_doc("Project")
project.project_name = "Test Total Billed Amount"
project.save()
si.project = project.name
si.save()
si.submit()
doc = frappe.get_doc("Project", project.name)
self.assertEqual(doc.total_billed_amount, si.grand_total)
def set_advance_flag(company, flag, default_account):
frappe.db.set_value(

View File

@@ -14,7 +14,8 @@
"advance_amount",
"allocated_amount",
"exchange_gain_loss",
"ref_exchange_rate"
"ref_exchange_rate",
"difference_posting_date"
],
"fields": [
{
@@ -30,7 +31,7 @@
"width": "250px"
},
{
"columns": 3,
"columns": 2,
"fieldname": "reference_name",
"fieldtype": "Dynamic Link",
"in_list_view": 1,
@@ -41,7 +42,7 @@
"read_only": 1
},
{
"columns": 3,
"columns": 2,
"fieldname": "remarks",
"fieldtype": "Text",
"in_list_view": 1,
@@ -112,13 +113,20 @@
"label": "Reference Exchange Rate",
"non_negative": 1,
"read_only": 1
},
{
"columns": 2,
"fieldname": "difference_posting_date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "Difference Posting Date"
}
],
"idx": 1,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:36.003704",
"modified": "2024-12-20 11:58:28.962370",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Advance",

View File

@@ -16,6 +16,7 @@ class SalesInvoiceAdvance(Document):
advance_amount: DF.Currency
allocated_amount: DF.Currency
difference_posting_date: DF.Date | None
exchange_gain_loss: DF.Currency
parent: DF.Data
parentfield: DF.Data

View File

@@ -8,7 +8,7 @@ from frappe.model.document import Document
from frappe.utils.data import cint
from erpnext.assets.doctype.asset.depreciation import get_disposal_account_and_cost_center
from erpnext.stock.doctype.serial_no.serial_no import get_delivery_note_serial_no, get_serial_nos
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
class SalesInvoiceItem(Document):
@@ -128,39 +128,3 @@ class SalesInvoiceItem(Document):
self.income_account = disposal_account
if not self.cost_center:
self.cost_center = depreciation_cost_center
def set_serial_no_against_delivery_note(self):
"""Set serial no based on delivery note."""
if self.serial_no and self.delivery_note and self.qty != len(get_serial_nos(self.serial_no)):
self.serial_no = get_delivery_note_serial_no(self.item_code, self.qty, self.delivery_note)
def validate_serial_against_delivery_note(self):
"""Ensure the serial numbers in this Sales Invoice Item are same as in the linked Delivery Note."""
if not self.delivery_note or not self.dn_detail:
return
serial_nos = frappe.db.get_value("Delivery Note Item", self.dn_detail, "serial_no") or ""
dn_serial_nos = set(get_serial_nos(serial_nos))
serial_nos = self.serial_no or ""
si_serial_nos = set(get_serial_nos(serial_nos))
serial_no_diff = si_serial_nos - dn_serial_nos
if serial_no_diff:
dn_link = frappe.utils.get_link_to_form("Delivery Note", self.delivery_note)
msg = (
_("Row #{0}: The following serial numbers are not present in Delivery Note {1}:").format(
self.idx, dn_link
)
+ " "
+ ", ".join(frappe.bold(d) for d in serial_no_diff)
)
frappe.throw(msg=msg, title=_("Serial Nos Mismatch"))
if self.serial_no and cint(self.qty) != len(si_serial_nos):
frappe.throw(
_(
"Row #{0}: {1} serial numbers are required for Item {2}. You have provided {3} serial numbers."
).format(self.idx, self.qty, self.item_code, len(si_serial_nos))
)

View File

@@ -247,14 +247,14 @@ def get_tax_row_for_tds(tax_details, tax_amount):
}
def get_lower_deduction_certificate(company, tax_details, pan_no):
def get_lower_deduction_certificate(company, posting_date, tax_details, pan_no):
ldc_name = frappe.db.get_value(
"Lower Deduction Certificate",
{
"pan_no": pan_no,
"tax_withholding_category": tax_details.tax_withholding_category,
"valid_from": (">=", tax_details.from_date),
"valid_upto": ("<=", tax_details.to_date),
"valid_from": ("<=", posting_date),
"valid_upto": (">=", posting_date),
"company": company,
},
"name",
@@ -302,7 +302,7 @@ def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=N
tax_amount = 0
if party_type == "Supplier":
ldc = get_lower_deduction_certificate(inv.company, tax_details, pan_no)
ldc = get_lower_deduction_certificate(inv.company, posting_date, tax_details, pan_no)
if tax_deducted:
net_total = inv.tax_withholding_net_total
if ldc:
@@ -539,7 +539,7 @@ def get_tds_amount(ldc, parties, inv, tax_details, vouchers):
)
supp_credit_amt = supp_jv_credit_amt
supp_credit_amt += inv.tax_withholding_net_total
supp_credit_amt += inv.get("tax_withholding_net_total", 0)
for type in payment_entry_amounts:
if type.payment_type == "Pay":
@@ -551,9 +551,9 @@ def get_tds_amount(ldc, parties, inv, tax_details, vouchers):
cumulative_threshold = tax_details.get("cumulative_threshold", 0)
if inv.doctype != "Payment Entry":
tax_withholding_net_total = inv.base_tax_withholding_net_total
tax_withholding_net_total = inv.get("base_tax_withholding_net_total", 0)
else:
tax_withholding_net_total = inv.tax_withholding_net_total
tax_withholding_net_total = inv.get("tax_withholding_net_total", 0)
if (threshold and tax_withholding_net_total >= threshold) or (
cumulative_threshold and (supp_credit_amt + supp_inv_credit_amt) >= cumulative_threshold

View File

@@ -262,6 +262,7 @@ class TestUnreconcilePayment(AccountsTestMixin, IntegrationTestCase):
pe1.paid_from = self.debtors_usd
pe1.paid_from_account_currency = "USD"
pe1.source_exchange_rate = 75
pe1.paid_amount = 100
pe1.received_amount = 75 * 100
pe1.save()
# Allocate payment against both invoices
@@ -279,6 +280,7 @@ class TestUnreconcilePayment(AccountsTestMixin, IntegrationTestCase):
pe2.paid_from = self.debtors_usd
pe2.paid_from_account_currency = "USD"
pe2.source_exchange_rate = 75
pe2.paid_amount = 100
pe2.received_amount = 75 * 100
pe2.save()
# Allocate payment against both invoices

Some files were not shown because too many files have changed in this diff Show More