Compare commits

..

736 Commits

Author SHA1 Message Date
Saurabh
f843d6aa53 Merge branch 'v12-pre-release' into version-12 2020-08-24 10:11:45 +05:30
Saurabh
c6ed332903 bumped to version 12.11.0 2020-08-24 10:25:29 +05:50
Nabin Hait
ad07abeb3f chore: Added change log 2020-08-23 11:27:05 +05:30
rohitwaghchaure
6bb2038323 Merge pull request #23084 from nextchamp-saqib/pos-search-fix-pre-release
fix: cannot search items in offline pos
2020-08-21 13:13:50 +05:30
Nabin Hait
3d1df94ad2 fix:Validate Job offer against vacancies (#23108) 2020-08-20 19:39:03 +05:30
Deepesh Garg
53aee98103 Merge pull request #23104 from deepeshgarg007/rcm_submit_v12
fix: Unable to submit reverse charge invoice
2020-08-20 19:35:48 +05:30
Marica
e52bd5c699 fix: Create Opoortunity without Default Company from Email (#23099)
* fix: Create Opoortunity without Default Company from Email

* fix: Add Prompt to Select Company

* Update communication.js

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-08-20 19:11:59 +05:30
Deepesh Garg
e1f9148351 Merge branch 'v12-pre-release' of https://github.com/frappe/erpnext into rcm_submit_v12 2020-08-20 16:49:43 +05:30
Deepesh Garg
093fb84377 fix: Unable to submit reverse charge invoice 2020-08-20 16:44:08 +05:30
Rucha Mahabal
737d305f45 Merge pull request #23094 from nextchamp-saqib/sr-no-selector-fix-pre-release
fix: val is not defined
2020-08-20 15:01:28 +05:30
Saqib Ansari
193222a336 fix: val is not defined 2020-08-20 12:53:43 +05:30
rohitwaghchaure
46bea91469 Merge pull request #23093 from rohitwaghchaure/not-able-to-submit-dn
fix: not able to submit delivery note
2020-08-20 12:28:35 +05:30
Rohit Waghchaure
f09d472fcd fix: not able to submit delivery note 2020-08-20 12:20:23 +05:30
Suraj Shetty
4ff1a4361d refactor: Format and sanitise user inputs to search queries. (#23091)
* refactor: Sanitize whitelisted method inputs

Co-authored-by: Prssanna Desai <prssud@gmail.com>
Co-authored-by: Shivam Mishra <scmmishra@users.noreply.github.com>

* refactor: Format and sanitize tax_account_query inputs

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
Co-authored-by: Prssanna Desai <prssud@gmail.com>
Co-authored-by: Shivam Mishra <scmmishra@users.noreply.github.com>

* refactor: Validate and sanitize search inputs via decorator

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
Co-authored-by: Prssanna Desai <prssud@gmail.com>
Co-authored-by: Shivam Mishra <scmmishra@users.noreply.github.com>

* style: Minor formatting fix

* refactor: Validate and sanitize search inputs using decorator

* fix: Typo

* fix: Remove unwanted import statement

* refactor: Repalce validate_and_sanitize_search_inputs() with validate_and_sanitize_search_inputs

Co-authored-by: Prssanna Desai <prssud@gmail.com>
Co-authored-by: Shivam Mishra <scmmishra@users.noreply.github.com>

Co-authored-by: Prssanna Desai <prssud@gmail.com>
Co-authored-by: Shivam Mishra <scmmishra@users.noreply.github.com>
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-08-20 11:27:19 +05:30
Deepesh Garg
c7c72b76c6 Merge pull request #23087 from deepeshgarg007/rcm_deduction_hotfix
fix: Do not update total for RCM invvoices if net taxes are zero
2020-08-19 18:39:09 +05:30
Deepesh Garg
6aa3191cad fix: Do not update total for RCM invvoices if net taxes are zero 2020-08-19 18:36:43 +05:30
Saqib Ansari
1fdfcc00d6 fix: cannot search items in offline pos 2020-08-19 17:26:38 +05:30
Deepesh Garg
af45eceeb2 fix: Total calculations for multicurrency RCM invoices (#23071) 2020-08-18 19:32:00 +05:30
Rucha Mahabal
7234330db9 Merge pull request #23032 from frappe/revert-23031-patch-4
Revert "fix: AttributeError: 'ProgramFee' object has no attribute 'course'"
2020-08-14 11:21:49 +05:30
Rucha Mahabal
2fa9b3a713 Revert "fix: AttributeError: 'ProgramFee' object has no attribute 'course'" 2020-08-14 11:21:23 +05:30
Rucha Mahabal
1aec8f57f2 Merge pull request #23031 from aakvatech/patch-4
fix: AttributeError: 'ProgramFee' object has no attribute 'course'
2020-08-14 11:21:18 +05:30
aakvatech
24f350a1a8 fix: AttributeError: 'ProgramFee' object has no attribute 'course'
Error occurs while program enrollment on new student.

This happens on version 12 and not on version 13.

Version 12 uses
course_list = [course.course for course in program.get_all_children()]

where as version 13 uses
course_list = [course.course for course in program.courses]

erpnext/erpnext/education/doctype/program_enrollment/program_enrollment.py
2020-08-14 06:59:44 +03:00
Nabin Hait
387e0878b6 Merge branch 'version-12-hotfix' into v12-pre-release 2020-08-13 09:28:27 +05:30
Saqib
6c536bb6e0 fix: cannot change customer fields if credit exhausted (#22838)
* fix: cannot change customer fields if credit exhausted

* fix: order based on company

* fix: sort current limits w.r.t company before compare

* fix: CustomerCreditLimit Object is not subscriptable
2020-08-13 09:27:50 +05:30
Nabin Hait
0a061d4082 Merge branch 'version-12-hotfix' into v12-pre-release 2020-08-13 09:23:22 +05:30
Nabin Hait
af9d653fb4 Inclusive tax based on item quantity v12 (#23015)
* fix: Calculate taxes if tax is based on item quantity and inclusive on item price

* git commit -m "fix: Add missing semicolon"

* fix: Calculate taxes if tax is based on item quantity

Co-authored-by: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com>
2020-08-13 09:22:05 +05:30
Anupam Kumar
8969e19594 fix: Opportunity/Quotation Lost Reason Fix (#23016) 2020-08-13 09:19:53 +05:30
Deepesh Garg
a979fcc25b fix: Project link not set in accounts other than profit and loss accounts (#22049)
* fix: project link not set in accounts other than profilt and loss accounts

* fix: cannot find get_allow_cost_center_in_entry_of_bs_account

* fix: remove enable_allow_cost_center_in_entry_of_bs_account

* chore: add tests and remove test based on allow_cost_center_for_bs_accounts

* fix: travis

* fix: Test Cases

* fix: Patch to remove Property Setter

* fix: Test Cases

* fix: Remove v13 patch

* fix: Procurement Tracker test case

* fix: Proccurement tracker report test

* fix: Codacy

* fix: Remove duplicate project field

Co-authored-by: Saqib Ansari <nextchamp.saqib@gmail.com>
Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2020-08-12 21:06:25 +05:30
Rucha Mahabal
9bd041c14c fix: don't set asset maintenance log status as Overdue when Completed or Cancelled (#23012)
* fix: don't set maintenance log status as Overdue when Completed or Cancelled

* fix: set draft indicators for Asset Maintenance Log listview
2020-08-12 19:34:54 +05:30
Deepesh Garg
1bb6ef3356 fix: Update state code and union territory for Daman and Diu (#22989)
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2020-08-12 19:34:23 +05:30
Deepesh Garg
5cc5bc246a fix: Cancellation of accounting transactions within closed accounting period (#22986) 2020-08-12 17:56:57 +05:30
Rucha Mahabal
2a0ed798aa fix: TypeError while setting transfer_qty in Stock Entry (#22931)
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-08-12 14:32:23 +05:30
Marica
033d98cd68 Merge pull request #23002 from AfshanKhan/fix-duplicate-dropdown-PO-v12
fix: moved custom_make_buttons to PurchaseOrderController to avoid duplication of dropdown options
2020-08-11 20:57:11 +05:30
Afshan
ec3dc95e6e fix: moved custom_make_buttons to PurchaseOrderController to avoid duplication of dropdown options 2020-08-11 20:42:16 +05:30
Deepesh Garg
57d86a3bc1 Merge pull request #22973 from marination/opportunity-from-email-fix
fix: Creating opportunity from email
2020-08-10 16:12:00 +05:30
marination
265916543d fix: Creating opportunity from email 2020-08-10 14:42:30 +05:30
Deepesh Garg
f63182df5a Merge pull request #22968 from deepeshgarg007/gst_export_wopay_v12
fix: GSTR 1 report for exports without payment of Tax
2020-08-10 11:29:56 +05:30
Deepesh Garg
9d455cf4a6 fix: GSTR 1 report for exports without payment of Tax 2020-08-10 09:57:28 +05:30
Deepesh Garg
ff9c40fde6 Merge pull request #22730 from deepeshgarg007/gstr3b_cess_v12_hotfix
fix: Multiple GST fixes
2020-08-08 22:15:25 +05:30
Deepesh Garg
f0f20bb434 fix: RCM taxable value in GSTR3b report 2020-08-08 20:58:01 +05:30
Deepesh Garg
bbfd5a4cc8 fix: Test Cases 2020-08-08 19:46:09 +05:30
Deepesh Garg
3ae4a83504 fix: Add print for debug 2020-08-08 17:52:45 +05:30
Deepesh Garg
1da33f4129 fix: Test case 2020-08-07 22:51:33 +05:30
Deepesh Garg
b8eff8d141 fix: Test case 2020-08-07 22:02:14 +05:30
Deepesh Garg
67e07b69dd fix: More print statements for debugging 2020-08-07 15:59:03 +05:30
Deepesh Garg
7d262d1a08 Merge pull request #22928 from deepeshgarg007/paymemnt_reco_multi_v12
fix: Multi currency payment reconciliation
2020-08-07 15:36:37 +05:30
Deepesh Garg
5f8e8a3c29 fix: Add debug print statement 2020-08-07 10:05:22 +05:30
Deepesh Garg
2169bb7640 fix: Add print 2020-08-06 23:16:33 +05:30
Deepesh Garg
33754b9dc8 fix: add print for debug 2020-08-06 22:17:37 +05:30
Deepesh Garg
bb451360ba Merge branch 'version-12-hotfix' of https://github.com/frappe/erpnext into gstr3b_cess_v12_hotfix 2020-08-06 21:50:27 +05:30
Afshan
2cf4168009 fix: show or hide section or attributes depending on other attributes… (#22933)
* fix: show or hide section or attributes depending on other attributes for better UI

* fix:depends on: batch_no for retain sample

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-08-06 19:04:35 +05:30
Shivam Mishra
80c016a1ad Merge pull request #22935 from scmmishra/fix-product-configurator
fix: handle product_info null in item_configure
2020-08-06 11:39:32 +00:00
Shivam Mishra
3619628e60 fix: handle product_info null 2020-08-06 17:08:14 +05:30
Marica
e2e9633ee1 Merge pull request #22927 from deepeshgarg007/price_rule_fix_v12
fix: Error due to comma in Pricing rule name
2020-08-06 16:57:18 +05:30
Shivam Mishra
abd111331e Merge pull request #22934 from scmmishra/fix-product-configurator
fix: unbound error in product configurator 61b9727
2020-08-06 11:22:39 +00:00
Shivam Mishra
61b9727fa2 fix: unbound error in product configurator 2020-08-06 16:47:43 +05:30
Marica
74643c804d Merge branch 'version-12-hotfix' into price_rule_fix_v12 2020-08-06 14:38:59 +05:30
Marica
e7162a86c6 Merge pull request #22930 from deepeshgarg007/payment_reco_cost_center_fix_v12
fix: Add default cost center in payment reconciliation JV
2020-08-06 14:31:52 +05:30
Deepesh Garg
b3cdd91d65 fix: Tests 2020-08-06 13:18:42 +05:30
Deepesh Garg
dd64cd1512 fix: Add default cost center in payment reconciliation JV 2020-08-06 11:46:25 +05:30
Deepesh Garg
024c78f522 fix: Hide currency link fields 2020-08-06 11:31:00 +05:30
Deepesh Garg
e6ec549c81 fix: Multi currency payment reconciliation 2020-08-06 11:30:46 +05:30
Deepesh Garg
579167d1de fix: Remove print statement 2020-08-06 11:27:27 +05:30
Deepesh Garg
10604664d4 fix: Error due to commma in Pricing rule name 2020-08-06 11:27:18 +05:30
Marica
97e96cec51 fix: get_regional_address_details missing positional arg 'company' (#22920) 2020-08-05 17:10:50 +05:30
Anurag Mishra
d2593f0af5 fix: set half day date None if half day is unchecked (#22905) 2020-08-04 19:29:56 +05:30
Rucha Mahabal
02fcf569e6 fix: SQL query in accounts receivable, payable reports (#22891) 2020-08-03 20:41:37 +05:30
Marica
9afebd311f fix: Reposition description in Warehouse (#22896) 2020-08-03 20:39:41 +05:30
Rucha Mahabal
4f6a25539a fix: TypeError while concatenating account number and name in COA (#22886) 2020-08-03 15:51:39 +05:30
Nabin Hait
ec46b8c73b fix: Bank Clearance of POS purchase invoice (#22884) 2020-08-03 15:39:29 +05:30
Marica
a9cfe0c95c fix: Misleading description in Warehouse (#22879) 2020-08-03 14:56:46 +05:30
Rucha Mahabal
3d2fa59e6d fix(Education): course wise assessment report labels (#22805)
* fix: add labels to chart datasets in course wise assessment

* fix: change label for final grade

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-07-30 13:27:47 +05:30
Rucha Mahabal
b2eddedfb1 fix: change owner fieldtype to Link in Lead Owner Efficiency Report (#22840) 2020-07-29 17:19:11 +05:30
Marica
b7efef79dc fix: Exploded Item Rate (#22816) 2020-07-27 14:54:59 +05:30
bhavesh95863
ca6ec72ade fix: Add missing translation function for freeze message (#22812)
* fix[missing translation function]

missing translation function

* fix[missing translation function for message]

missing translation function for message

* fix[add missing translation function]

add missing translation function

* Update payroll_entry.js

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2020-07-26 14:03:03 +05:30
Deepesh Garg
680f2600be Merge pull request #22303 from P-Froggy/fix-payment-entry-wrong-bank-account-fetch-v12
fix: Set Value of wrong Bank Account Field in Payment Entry
2020-07-24 19:04:51 +05:30
Mangesh-Khairnar
af9e44f059 fix(payment-request): do not set guest as administrator (#22803) 2020-07-24 18:18:49 +05:30
Deepesh Garg
dde92e0fdb Merge branch 'version-12-hotfix' of https://github.com/frappe/erpnext into gstr3b_cess_v12_hotfix 2020-07-24 14:09:02 +05:30
Deepesh Garg
d9aa115aaf fix: Remove print and add Cess account 2020-07-24 14:08:05 +05:30
rohitwaghchaure
6a48988c76 fix: incorrect stock value in return case (#22528)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-07-24 10:46:55 +05:30
Nabin Hait
e62da1455c fix: Other charges on income tax (#22798) 2020-07-24 09:20:41 +05:30
Anupam Kumar
45a3580c20 Unable to change link from new lead to existing customer (#22795) 2020-07-24 08:53:24 +05:30
Rucha Mahabal
9abb8e309e fix(Education): descriptions not copied while creating fees from fee structure (#22793) 2020-07-24 08:52:53 +05:30
Rucha Mahabal
c5b6ba7556 Merge pull request #22794 from Mangesh-Khairnar/maintainance-visit-fixes
fix(maintenance-visit): change fieldtype of status to select
2020-07-24 00:10:09 +05:30
Mangesh-Khairnar
cf902a1e2d fix(maintenance-visit): change fieldtype of status to select 2020-07-23 23:55:58 +05:30
Sun Howwrongbum
4e3df334db fix: [v12] incorrect available_qty being set (#22541)
* fix: incorrect available_qty being set

* style: descriptive variables
2020-07-23 20:06:15 +05:30
Deepesh Garg
9067adf141 fix: Add print for debug 2020-07-23 19:48:18 +05:30
Deepesh Garg
d18eb0e63e Merge pull request #22702 from pipech/v12-hotfix-transaction_pricing_rule
fix(pricing): transaction pricing rule
2020-07-23 19:19:55 +05:30
aakvatech
3adeab45ce Update transaction.js (#22788)
Added frappe.flags.hide_serial_batch_dialog = true that was missing in version-12
2020-07-23 12:14:36 +05:30
Marica
0fee76f409 fix: Dont merge items if both exist in stock reco (#22784)
* fix: incorrect stock after merging items

* fix: Readability fix

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2020-07-22 18:53:40 +05:30
Marica
74963e9711 fix: Serial No Rename does not affect Stock Ledger Entry (#22780) 2020-07-22 18:17:25 +05:30
Deepesh Garg
7d8887916e Merge pull request #22755 from deepeshgarg007/hsn_code_report_v12
fix: Tax amounts in HSN Wise Outward summary
2020-07-22 16:26:38 +05:30
Deepesh Garg
e077c0a270 fix: Randomly failing test (#22773)
* fix(travis): Item Tax tempate template test

* fix: Update tests

* fix: Test

* fix: Do not use random customers

* fix: Remove every bit of randomness from this test
2020-07-22 16:12:12 +05:30
Afshan
517108d10a fix: added set query for filters in MR (#22770)
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-07-22 15:51:48 +05:30
Afshan
a7094641d4 style: moved parent warehouse to top section also added a section break for better look (#22772)
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-07-22 15:45:37 +05:30
Deepesh Garg
ad94f7516b Merge pull request #22763 from DeeMysterio/fs-hotfix
fix(report): fix alignment in script report that extends financial_statements.js
2020-07-22 14:46:08 +05:30
Diksha Jadhav
1943d413a4 fix(report): fix alignment in script report that extends financial_statements.js 2020-07-21 17:59:12 +05:30
Deepesh Garg
82fbef4163 fix: Remove print statements 2020-07-21 14:54:21 +05:30
Deepesh Garg
83ad6df229 fix: Tax amounts in HSN Wise Outward summary 2020-07-21 14:25:51 +05:30
Deepesh Garg
b9ba63b0d8 fix: Test Case 2020-07-20 18:08:56 +05:30
Marica
bc248bfaed Merge pull request #22646 from rohitwaghchaure/incorrect-qty-after-transaction-stock-reco
fix: incorrect qty after transaction in stock ledger entry
2020-07-20 15:51:37 +05:30
Deepesh Garg
0b31d6f630 fix: Test Case 2020-07-20 13:34:46 +05:30
Marica
7e461ce860 Merge branch 'version-12-hotfix' into incorrect-qty-after-transaction-stock-reco 2020-07-20 11:34:29 +05:30
Deepesh Garg
6946796047 fix: Tests 2020-07-19 22:23:13 +05:30
Deepesh Garg
6d39066d86 fix: Multiple fixes in GST 2020-07-17 22:20:04 +05:30
Deepesh Garg
b6da70efec fix: Cess amount in GSTR 3B report 2020-07-17 22:19:34 +05:30
rohitwaghchaure
3068fe43c6 Merge branch 'version-12-hotfix' into v12-hotfix-transaction_pricing_rule 2020-07-17 14:46:45 +05:30
rohitwaghchaure
7709c640b5 Merge pull request #22720 from rohitwaghchaure/fixed-incorrect-currency-symbol-in-stock-balance-report
fix: currency symbol not showing as per company currency in stock bal…
2020-07-17 14:35:13 +05:30
rohitwaghchaure
8558e26648 Merge pull request #22716 from rohitwaghchaure/fixed-actual-qty-showing-as-zero
Fix: Stock Reconciliation Invalid Quantity for Batched Item
2020-07-17 12:07:45 +05:30
Rohit Waghchaure
34a91bd7e6 fix: currency symbol not showing as per company currency in stock balance 2020-07-17 11:24:40 +05:30
rohitwaghchaure
785462b513 Update stock_reconciliation.js 2020-07-17 10:55:05 +05:30
Rohit Waghchaure
0d5f8c5050 fix: for past dated stock reco, batched item showing the current available qty instead of quantity as per posting date 2020-07-17 08:57:31 +05:30
Deepesh Garg
13088173eb Merge pull request #22703 from deepeshgarg007/rcm_ountry_fix
fix: Update RCM only for indian countries
2020-07-15 23:58:16 +05:30
Deepesh Garg
c10dd29282 fix: Update RCM only for indian countries 2020-07-15 23:57:03 +05:30
Deepesh Garg
95da4157a9 Merge pull request #22699 from rohitwaghchaure/fixed-not-able-to-submit-si-hotfix
fix: not able to submit sales invoice
2020-07-15 21:50:45 +05:30
Poranut Chollavorn
1411d002f6 fix(pricing): transaction pricing rule
add tranasction type to transaction pricing rule selector
2020-07-15 14:55:20 +00:00
rohitwaghchaure
0f2601a6a6 Merge pull request #22649 from rohitwaghchaure/fixed-incorrect-balance-qty-in-stock-ledger
fix: incorrect balance qty in stock ledger report
2020-07-15 17:20:04 +05:30
Rohit Waghchaure
c785ff9874 fix: not able to submit sales invoice 2020-07-15 17:17:23 +05:30
rohitwaghchaure
ab9cbc1e2c Merge pull request #22690 from marination/pr-project-stock-ledger-fix
fix: Added Project Field in Purchase Receipt for Stock Ledger Tagging
2020-07-15 15:42:58 +05:30
rohitwaghchaure
237dc4250a Merge pull request #22667 from ruchamahabal/fix-healthcare-setup-v12
fix(Healthcare): set company in Healthcare Service Unit setup
2020-07-15 14:33:42 +05:30
marination
71fa045ba4 fix: Added Project Field in Purchase Receipt for Stock Ledger Tagging 2020-07-15 12:54:19 +05:30
rohitwaghchaure
5e5e82a9f6 Merge pull request #22684 from nabinhait/company-abbr-replace
fix: Replace company abbr
2020-07-15 12:31:19 +05:30
Deepesh Garg
898dafe748 fix: Period list fixes in financial statements (#22679) 2020-07-15 12:17:23 +05:30
Deepesh Garg
1f7e941d68 fix(GST): Do not add tax amount in grand total for reverse charge invoices (#22686)
* fix(GST): Do not add tax amount in grand total for reverse charge invoices

* fix: Code cleanup

* fix: Remove print statements
2020-07-14 22:05:45 +05:30
Nabin Hait
395f44c8b7 fix: Replace company abbr 2020-07-14 20:46:25 +05:30
Rucha Mahabal
ea1662c15b Merge pull request #22659 from bhavesh95863/patch-3
fix: Quotation list view blank if quotation_to field not set as a standard filter
2020-07-13 19:55:54 +05:30
bhavesh95863
fd8c856af2 fix:whitespace missing
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2020-07-13 18:48:47 +05:30
Rucha Mahabal
672497ba63 Merge branch 'version-12-hotfix' into fix-healthcare-setup-v12 2020-07-13 16:39:05 +05:30
Rucha Mahabal
9c410d8a27 fix(Healthcare): set company in Healthcare Service Unit setup 2020-07-13 16:27:59 +05:30
Deepesh Garg
8317ff8bb2 Merge branch 'version-12-hotfix' into fixed-incorrect-balance-qty-in-stock-ledger 2020-07-12 17:21:25 +05:30
bhavesh95863
70eb94280e fix: Quotation list view blank if quotation_to field not set as a standard filter
fix: Quotation list view  blank if quotation_to field not set as a standard filter
2020-07-12 02:59:00 +05:30
Deepesh Garg
fef3a79bf5 Merge pull request #22656 from sagarvora/fix-ewaybill-json
fix: ewaybill json had json dump of json dump, and other related fixes
2020-07-11 21:41:44 +05:30
Sagar Vora
9bcf4eb5bc fix: ewaybill json had json dump of json dump, and other related fixes 2020-07-11 17:44:20 +05:30
Marica
1696a8982c fix: Pricing Rule breaks if no item_code (#22653) 2020-07-10 22:51:32 +05:30
Rohit Waghchaure
671fc7b919 fix: incorrect balance qty in stock ledger report 2020-07-10 18:11:04 +05:30
Rohit Waghchaure
335815a75d fix: incorrect qty after transaction in stock ledger entry 2020-07-10 14:23:12 +05:30
rohitwaghchaure
b856548d47 fix: incorrect delivered qty in Supplier-Wise Sales Analytics (#22642)
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-07-10 13:19:57 +05:30
rohitwaghchaure
1c26bf5b07 fix: Due to decimal issue make purchase receipt button not showing from PO (#22643)
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-07-10 13:17:22 +05:30
Anurag Mishra
b3041ea7cd fix: fix: not working without from_amount and percentage_deduction (#22399) 2020-07-10 13:09:21 +05:30
Marica
ea7625556c fix: General Message in previous doc validation for buying and selling (#22639) 2020-07-10 12:36:47 +05:30
Marica
8e887f39a2 fix: Skip Progress and Completed by fields on Task Duplication (#22640) 2020-07-10 12:31:08 +05:30
Marica
8f038aa832 fix: Error message in Product Bundle (#22638) 2020-07-10 12:13:14 +05:30
Rohan
fda2633e40 fix: fetch project-related info in Timesheet (#22422)
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-07-09 11:38:20 +05:30
Rohan
817040b986 fix: setup status indicators for Job Offer and Job Applicant (#22444)
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-07-08 15:59:44 +05:30
rohitwaghchaure
45624cae77 Merge pull request #22599 from frappe/shopping-cart-issue
refactor: shopping cart
2020-07-08 13:09:59 +05:30
Anupam K
8c48a6a865 upating shopping_cart.js 2020-07-08 12:22:45 +05:30
Deepesh Garg
adb7c16349 Merge pull request #22604 from frappe/mergify/bp/version-12-hotfix/pr-22601
fix: Payment reco error in multi-company setup (bp #22601)
2020-07-07 18:41:44 +05:30
Marica
aafd674c07 Merge pull request #22606 from Thunderbottom/whitelist-query-v12
fix: whitelist all query functions for search widget
2020-07-07 16:51:45 +05:30
Chinmay D. Pai
75c2e28788 fix: whitelist all query functions for search widget
Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2020-07-07 16:46:04 +05:30
Anupam K
321aba642d shopping cart issue fixes 2020-07-07 15:46:44 +05:30
Deepesh Garg
402b273d9b fix: Pass company
(cherry picked from commit ca351e3549)
2020-07-07 10:06:49 +00:00
Deepesh Garg
e0a9ae612e fix: Payment reco error in multicompany setup
(cherry picked from commit e2fdff5777)
2020-07-07 10:06:49 +00:00
bhavesh95863
b9e4df557b fix: Message field mandtory even after unchecking collect progress checkbox (#22594)
Message field mandtory even after unchecking collect progress checkbox
2020-07-06 18:29:37 +05:30
rohitwaghchaure
632bd3b310 Merge pull request #22587 from frappe/mergify/bp/version-12-hotfix/pr-22577
fix: Consider company fiscal year for getting balance (bp #22577)
2020-07-06 13:20:54 +05:30
Deepesh Garg
735d7f732d fix: Consider company fiscal for getting balalnce
(cherry picked from commit 96d40ec9da)
2020-07-06 07:09:00 +00:00
Deepesh Garg
455c1dda7a Merge pull request #22575 from deepeshgarg007/uae_item_tax_fix_v12
fix: Update item tax only if item code available
2020-07-03 21:33:35 +05:30
Deepesh Garg
1b18bf0388 fix: Update item tax only if item code available 2020-07-03 21:28:40 +05:30
Faris Ansari
336ca33a98 fix: Set label if domains is set (#22523) 2020-07-02 14:58:20 +05:30
Afshan
3c0f38fa02 fix: made "Subscription Section", "Auto Repeat" and Hub Publishing" collapsible by default (#22535) 2020-07-02 14:52:50 +05:30
Sahil Khan
fd30b8f422 Merge branch 'v12-pre-release' into version-12 2020-07-02 13:06:22 +05:30
Sahil Khan
30e33bef9e bumped to version 12.10.1 2020-07-02 13:26:22 +05:50
sahil28297
67e64dbc01 Merge pull request #22552 from frappe/mergify/bp/v12-pre-release/pr-22347
Revert "fix: update remark on submitting payment entry" (bp #22347)
2020-07-02 12:00:44 +05:30
Deepesh Garg
bae83679c0 Revert "fix: update remark on submitting payment entry"
(cherry picked from commit 7d035fac36)
2020-07-02 06:29:15 +00:00
Marica
0c12c7339c Merge pull request #22538 from frappe/mergify/bp/version-12-hotfix/pr-22496
fix: take parent cost center for child if no cost center at child (bp #22496)
2020-07-01 17:00:22 +05:30
Anurag Mishra
bf8a26c31e fix: take parent cost center for child if no cost center at child (#22496)
(cherry picked from commit ba5f571b0d)
2020-07-01 11:07:57 +00:00
Marica
fb36d01dd2 Merge pull request #22534 from frappe/mergify/bp/version-12-hotfix/pr-22512
feat: Autofill Supplier pop-up when only 1 Supplier in RFQ (bp #22512)
2020-07-01 12:09:46 +05:30
Afshan
c8d6e8f19d feat: Autofill Supplier pop-up when only 1 Supplier in RFQ
(cherry picked from commit 06f11aba0b)
2020-07-01 06:32:19 +00:00
mergify[bot]
4e17c40589 fix: Refactor dashboard links in leave policy (bp #22519) (#22529)
* fix: Refactor dashboard links in leave policy (#22519)

* fix: refactor dashboard links in leave policy

* fx: code fix

* fix: add labels to links

* fix: code change

(cherry picked from commit ec84afa86d)

* fix: remove extra lines

Co-authored-by: Michelle Alva <50285544+michellealva@users.noreply.github.com>
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2020-06-30 18:12:47 +05:30
Marica
5d5cb0ac28 fix: Set Root as Parent if no parent in new tree view node (#22507) 2020-06-30 08:21:07 +05:30
mergify[bot]
a20957d355 fix: handle nonetype issue for packed items (#22493) (#22494)
(cherry picked from commit 73edba0e10)

Co-authored-by: Mangesh-Khairnar <mkhairnar10@gmail.com>
2020-06-29 17:36:43 +05:30
rohitwaghchaure
f8efa0508a Merge pull request #22490 from frappe/mergify/bp/version-12-hotfix/pr-22488
fix: letter head not found in opening invoice creation tool (bp #22488)
2020-06-28 21:22:04 +05:30
Rohit Waghchaure
6aa7c404f8 fix: letter head not found in opening invoice creation tool
(cherry picked from commit 04cf2e029f)
2020-06-28 14:36:56 +00:00
rohitwaghchaure
105a44e0d2 Merge pull request #22484 from frappe/mergify/bp/version-12-hotfix/pr-22450
fix: Disable Renaming in Serial No (bp #22450)
2020-06-28 16:29:45 +05:30
rohitwaghchaure
7919ced975 Merge pull request #22372 from rohitwaghchaure/fixed-completed-qty-not-updated-in-wo
fix: completed qty not updated in work order
2020-06-28 15:22:56 +05:30
rohitwaghchaure
848e7c2e0e Merge pull request #22485 from frappe/mergify/bp/version-12-hotfix/pr-22478
fix: apply filters in all transactions (bp #22478)
2020-06-28 15:17:59 +05:30
rohitwaghchaure
104b317929 fix: indentation
(cherry picked from commit d5736711ce)
2020-06-28 09:45:01 +00:00
michellealva
ad0aca2fc6 fix: apply filters in all transactions
(cherry picked from commit 08f842d12e)
2020-06-28 09:45:01 +00:00
marination
584a8f52a5 fix: Disable Renaming in Serial No
(cherry picked from commit f311f52f6e)
2020-06-28 05:48:56 +00:00
rohitwaghchaure
48e2baa903 Merge pull request #22475 from frappe/mergify/bp/version-12-hotfix/pr-22468
fix: enable show_configure_button when shopping cart is enabled (bp #22468)
2020-06-28 11:13:34 +05:30
rohitwaghchaure
43d539f321 Merge pull request #22460 from britlog/version-12-hotfix
fix: product_info
2020-06-28 11:05:55 +05:30
britlog
0e7ab9526c fix: product_info 2020-06-26 15:24:23 +02:00
rohitwaghchaure
8a542bc9df Update shopping_cart_settings.js
(cherry picked from commit 13e8c32172)
2020-06-26 11:54:16 +00:00
Anupam K
e73dec158b enable show_configure_button when shopping cart is enabled
(cherry picked from commit 27d27c924d)
2020-06-26 11:54:16 +00:00
Deepesh Garg
2155916001 Merge pull request #22457 from frappe/clarkejj-patch-2
fix: stock_ageing.py report convert string numeric to flt value
2020-06-26 17:03:56 +05:30
rohitwaghchaure
78383c3133 Merge pull request #22469 from marination/production-plan-ux-hotfix
fix: Handling Empty tables in Production Plan
2020-06-26 15:06:14 +05:30
marination
cfc47bc011 fix: Sales Order to MR test failing
- Items to Manufacture can come as doc.items from Sales Order
2020-06-26 14:06:04 +05:30
marination
6bd8c048b6 fix: Handling Empty tables in Production Plan 2020-06-26 12:53:05 +05:30
mergify[bot]
6089023df7 fix: grammatical fix on error message (#22464)
Before:

Fiscal Year: 2020 does not exists

After:

Fiscal Year 2020 Does Not Exist

(cherry picked from commit 978722621f)

Co-authored-by: Michelle Alva <50285544+michellealva@users.noreply.github.com>
2020-06-26 09:23:36 +05:30
John Clarke
3cb8173034 fix: stock_ageing.py report convert string numeric to flt value
This PR combines these two PRs below applied to develop, to be applied to version-12-hotfix

(The mergifyio process failed for some reason.)

https://github.com/frappe/erpnext/pull/22430

https://github.com/frappe/erpnext/pull/22206
2020-06-25 07:30:10 -06:00
mergify[bot]
d9e7b480eb fix: cannot cancel assets with repair pending (#22440) (#22453)
* fix: cannot cancel assets with repair pending

* fix: message

* Update asset.py

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
(cherry picked from commit 40847aeac3)

Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2020-06-25 17:11:36 +05:30
Marica
7691937e59 Merge pull request #22437 from sunhoww/patch-2
fix: [v12] UnboundLocalError when setting product_info
2020-06-25 14:23:13 +05:30
Sun Howwrongbum
99a9f98688 fix: UnboundLocalError when setting product_info 2020-06-25 10:05:00 +05:30
Deepesh Garg
7b23cb27ce Merge pull request #22435 from frappe/mergify/bp/version-12-hotfix/pr-22434
fix: change error messages in RFQ (bp #22434)
2020-06-25 09:29:10 +05:30
Michelle Alva
c28adea2d0 fix: change error messages in RFQ
Before:
1. Row {0}: For supplier {0} Email Address is required to send email
2. Email sent to supplier
3. Request for Quotation is disabled to access from portal, for more check portal settings.
4. Supplier Quotation created.


After:
1. Row {0}: For Supplier {0} Email Address is Required to Send Email
2. Email sent to Supplier
3. The Access to Request for Quotation From Portal is Disabled. To Allow Access, Enable it in Portal Settings.
4. Supplier Quotation Created.

(cherry picked from commit da0385cd39)
2020-06-25 03:52:13 +00:00
Marica
57804e9d87 Merge pull request #22427 from frappe/mergify/bp/version-12-hotfix/pr-22410
fix: add error prompt for wrong date range (bp #22410)
2020-06-24 21:32:18 +05:30
Kenneth Sequeira
bf81b42219 fix: add error prompt for wrong date range
(cherry picked from commit f5b7bd9dcb)
2020-06-24 14:06:59 +00:00
gavin
1a3fd763ac Merge pull request #22409 from revant/release-action-on-v12
ci: github release action for v12
2020-06-23 21:33:56 +05:30
Revant Nandgaonkar
0a6b5bc83f ci: github release action for v12 2020-06-23 20:11:35 +05:30
Marica
fb18f78b77 fix: Update Packed Items via Update Items in SO (#22404)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-06-23 19:19:08 +05:30
mergify[bot]
835b1b4f0d fix: Insert Supplier Group via List View (#22403) (#22407)
(cherry picked from commit 7af7bb8311)

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-06-23 19:18:18 +05:30
mergify[bot]
3c18669057 fix: staffing Plan validation (#22379) (#22396)
(cherry picked from commit 36560c8406)

Co-authored-by: Anurag Mishra <32095923+Anurag810@users.noreply.github.com>
2020-06-23 10:49:48 +05:30
mergify[bot]
57a0fa5e87 fix: resetting lost reason in opportunity and quotation (#22378) (#22381)
(cherry picked from commit 71da90034d)

Co-authored-by: Anupam Kumar <anupamvns0099@gmail.com>
2020-06-23 10:45:08 +05:30
rohitwaghchaure
578bdff141 fix: offline pos not working for special character item (#22391) 2020-06-23 10:34:52 +05:30
rohitwaghchaure
c20b962842 Merge pull request #22389 from kennethsequeira/purchase_inv_due_12
fix: status error in purchase invoice
2020-06-22 23:47:32 +05:30
Deepesh Garg
5c4b738833 Merge pull request #22387 from AfshanKhan/V12_ISS_20_21_02455
fix: Set default reference Id for "On Previous Row Amount" and "On Previous Row Total"
2020-06-22 23:09:44 +05:30
Kenneth Sequeira
8a1f2ed65a fix:status error in purchase invoice 2020-06-22 22:40:04 +05:30
Afshan
def13f14a3 style: formate according to Codacy/PR Quality Review 2020-06-22 21:58:27 +05:30
Afshan
7e04dcae0a style: formate according to Codacy/PR Quality Review 2020-06-22 21:58:04 +05:30
Afshan
21a75eb2ba fix: set row_id by default as previous row for On Previous Row Amount and On Previous Row Total 2020-06-22 21:57:34 +05:30
rohitwaghchaure
290dbf470a Merge pull request #22384 from rohitwaghchaure/fixed-subcontract-item-for-alternative-item
fix: alternative item not working for subcontract
2020-06-22 21:52:26 +05:30
Rohit Waghchaure
171699537c fix: alternative item not working for subcontract 2020-06-22 20:48:28 +05:30
Deepesh Garg
91346d5e9e Merge pull request #22340 from frappe/mergify/bp/version-12-hotfix/pr-22312
fix: Email digest html view fix (bp #22312)
2020-06-22 19:08:56 +05:30
Marica
06ca3b5112 Purchase receipt to invoice hotfix (#22146)
* fix: Handle rows with same item code from Purchase Receipt to Invoice.

* fix: Handle rows with same item code from Purchase Receipt to Invoice.

* fix: Added patch, fixed tests, fixed delivery note behaviour

* chore: Added comments amd fixed typo

* fix: Added patch to patches.txt

* fix: Patch fix and simplification, json timestamp updation.

* fix: Set Purchase Receipt and Delivery Note detail patch (#21607)

* fix: Set Purchase Receipt and Delievry Note detail patch

* fix: Reload purchase receipt item

* fix(set_purchase_receipt_delivery_note_detail): commit after every 100 sql updates (#22016)

Co-authored-by: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com>
Co-authored-by: sahil28297 <37302950+sahil28297@users.noreply.github.com>
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-06-22 18:04:48 +05:30
Kenneth Sequeira
e220be5415 fix: Batch No label in Purchase Receipt (#22360) 2020-06-22 17:33:04 +05:30
mergify[bot]
413c2b229a fix: 'Last Purchase Rate' taking wrong on BOM (#20689) (#22370)
* fix: 'Last Purchase Rate' taking wrong on BOM. #20228

* fix: Added condition for None purchase order and purchase receipt (#20689)

* fix: fetch last purchase rate

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
(cherry picked from commit 2866617c82)

Co-authored-by: Lokesh Waingankar <59611773+lokesh-indictrans@users.noreply.github.com>
2020-06-22 17:26:42 +05:30
Anurag Mishra
1039079e37 fix: set cost center in child table (#22373) 2020-06-22 17:25:53 +05:30
rohitwaghchaure
60cb5ac419 Merge pull request #22330 from pipech/v12-hotfix-clear_pricing_rule_value
fix(pricing_rule): apply_on logic dont get cleanup
2020-06-22 14:47:29 +05:30
Rohit Waghchaure
ebbbc85fc0 added validation and clear fields for Apply Rule On Other 2020-06-22 13:44:11 +05:30
rohitwaghchaure
7f6d36cdc9 Merge pull request #22369 from frappe/mergify/bp/version-12-hotfix/pr-22241
fix: Minor fixes in cost center (bp #22241)
2020-06-22 13:00:19 +05:30
Marica
4a9de4dc07 Merge branch 'version-12-hotfix' into v12-hotfix-clear_pricing_rule_value 2020-06-22 12:48:55 +05:30
Marica
cb555ae825 Merge pull request #22368 from frappe/mergify/bp/version-12-hotfix/pr-21582
feat: Enabled translation on html files in LMS [Proposal] (bp #21582)
2020-06-22 12:45:18 +05:30
Rohit Waghchaure
e5ffe3fea4 fix: completed qty not updated in work order 2020-06-22 12:36:23 +05:30
Marica
7fcf958d08 Merge branch 'version-12-hotfix' into mergify/bp/version-12-hotfix/pr-21582 2020-06-22 12:07:39 +05:30
Deepesh Garg
cfe9ed0dfa fix: Test
(cherry picked from commit bef80b7981)
2020-06-22 05:54:53 +00:00
Deepesh Garg
f2fe8053dc fix: Validation for group cost center
(cherry picked from commit 0d880079b1)
2020-06-22 05:54:53 +00:00
Deepesh Garg
aa22cca67a fix: Minor fixes in cost center
(cherry picked from commit 817cbc4b48)
2020-06-22 05:54:52 +00:00
rohitwaghchaure
c4893df048 Merge pull request #22088 from deepeshgarg007/rcm_version-12-hotfix
fix(India): Reverse charge mechanism for GST
2020-06-22 11:20:38 +05:30
Alvaro
b16b24fd10 feat: Enabled translation on html files in LMS [Proposal] (#21582)
* :fix:  translation fix for html files in LMS

* fix: typo in translation

* Update content.html

* Update content.html

* Update profile.html

Co-authored-by: Shivam Mishra <scmmishra@users.noreply.github.com>
Co-authored-by: Marica <maricadsouza221197@gmail.com>
(cherry picked from commit 43be163b32)
2020-06-22 05:39:42 +00:00
Deepesh Garg
2f2385b354 Merge pull request #22365 from frappe/mergify/bp/version-12-hotfix/pr-22350
fix: Skipping total row for tree-view reports (bp #22350)
2020-06-21 22:11:32 +05:30
Afshan
8a2a32820a fix: adding json for checked add total row
(cherry picked from commit 84c6973742)
2020-06-21 13:59:25 +00:00
Afshan
41462f3c36 fix: test case
(cherry picked from commit 3fbe6e9e4b)
2020-06-21 13:59:25 +00:00
Afshan
a9ff40db67 fix: Skipping*
(cherry picked from commit 65f00cea15)
2020-06-21 13:59:24 +00:00
Afshan
0d95f56474 Skiping total row for tree-view reports
(cherry picked from commit fbd66574ad)
2020-06-21 13:59:24 +00:00
rohitwaghchaure
da65ddc68a Merge pull request #22362 from rohitwaghchaure/fixed-popup-is-coming-for-non-serialized-items
fix: Serial no / batch no Popup is coming for the non serialized items
2020-06-20 20:54:55 +05:30
Rohit Waghchaure
368f5e29d2 fix: Serial no / batch no Popup is coming for the non serialized items 2020-06-20 20:48:28 +05:30
Deepesh Garg
92f97b6a68 Merge pull request #22347 from frappe/revert-21743-payment-remark-fix-v12
Revert "fix: update remark on submitting payment entry"
2020-06-19 17:29:20 +05:30
Deepesh Garg
7d035fac36 Revert "fix: update remark on submitting payment entry" 2020-06-19 17:28:58 +05:30
Marica
6c1a5e8a44 Merge branch 'version-12-hotfix' into v12-hotfix-clear_pricing_rule_value 2020-06-19 14:28:06 +05:30
rohitwaghchaure
995bdd3c48 Merge pull request #22250 from marination/rfq-multi-uom-hotfix
feat: Multi UOM support in Request for Quotation
2020-06-19 13:17:36 +05:30
mergify[bot]
5acc06dfe6 fix: Student Admission (#22280)
* Student Admission fix

* adding check for application

* adding check for application

* updating error message

* added date_diff for date comparision

(cherry picked from commit c6592c880a)

Co-authored-by: Anupam Kumar <anupamvns0099@gmail.com>
Co-authored-by: Anurag Mishra <32095923+Anurag810@users.noreply.github.com>
2020-06-19 11:58:51 +05:30
Anupam K
168d070d73 email digest html fix
(cherry picked from commit bd449c8d07)
2020-06-19 06:09:49 +00:00
mergify[bot]
6f3e5e1891 refactor: show service instead of services (#22339)
(cherry picked from commit 25702a1c55)

Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
2020-06-19 11:10:42 +05:30
rohitwaghchaure
d48e33dbd7 Merge pull request #22327 from frappe/mergify/bp/v12-pre-release/pr-22287
fix: Quality procedure fixes (bp #22287)
2020-06-19 11:01:41 +05:30
rohitwaghchaure
7af8ca1bd1 Merge pull request #22338 from frappe/mergify/bp/v12-pre-release/pr-22334
fix: Customer Group label in Item-wise Sales History report (bp #22334)
2020-06-19 11:00:31 +05:30
rohitwaghchaure
a3e92489c2 Merge pull request #22337 from frappe/mergify/bp/version-12-hotfix/pr-22334
fix: Customer Group label in Item-wise Sales History report (bp #22334)
2020-06-19 11:00:17 +05:30
Kenneth Sequeira
4793e9c24c fix: Customer Group label in Itemwise Sales report
(cherry picked from commit 766f978858)
2020-06-19 05:29:07 +00:00
rohitwaghchaure
dd8dcd29c3 Merge pull request #22332 from marination/item-edit-hotfix
fix: Unabled to create batched item
2020-06-19 10:57:25 +05:30
Kenneth Sequeira
10624f3fa6 fix: Customer Group label in Itemwise Sales report
(cherry picked from commit 766f978858)
2020-06-19 05:26:23 +00:00
Marica
a0aa16c68c Merge branch 'version-12-hotfix' into item-edit-hotfix 2020-06-18 22:02:32 +05:30
marination
67361bef73 fix: Unabled to create batched item 2020-06-18 21:47:36 +05:30
Poranut Chollavorn
acf399c4e0 fix(pricing_rule): apply_on logic dont get cleanup 2020-06-18 14:41:26 +00:00
Sahil Khan
66a33bf7d9 Merge branch 'v12-pre-release' into version-12 2020-06-18 20:06:18 +05:30
Sahil Khan
aa27a0e85c bumped to version 12.10.0 2020-06-18 20:26:18 +05:50
sahil28297
a9dbff0eae chore: correct version in release note 2020-06-18 20:03:00 +05:30
Marica
a9ed42f93d fix: Quality procedure fixes (#22287)
* fix: Quality Procedure Fixes

- Dont prompt error message if parent is the same in child
- filter child procedure field
- Disable New button in tree view
- Editable grid for Quality Procedure Proces table.

* chore: Remove unnecessary get_doc

* fix: Codacy

Co-authored-by: Anurag Mishra <32095923+Anurag810@users.noreply.github.com>
(cherry picked from commit cce1116b4e)
2020-06-18 13:48:34 +00:00
Marica
cce1116b4e fix: Quality procedure fixes (#22287)
* fix: Quality Procedure Fixes

- Dont prompt error message if parent is the same in child
- filter child procedure field
- Disable New button in tree view
- Editable grid for Quality Procedure Proces table.

* chore: Remove unnecessary get_doc

* fix: Codacy

Co-authored-by: Anurag Mishra <32095923+Anurag810@users.noreply.github.com>
2020-06-18 19:15:49 +05:30
Deepesh Garg
fc488a2b46 fix: Do not copy Item Tax template from SO to PO (#22326) 2020-06-18 18:19:49 +05:30
Nabin Hait
f53ee9026b chore: Added Change log 2020-06-18 18:13:51 +05:30
mergify[bot]
5bd479e8ee refactor: handle exceptions when updating addresses (#22307) (#22316)
* refactor: handle exceptions when updating addresses

* refactor: fold common statements in a loop

(cherry picked from commit 34d2bfbb3e)

Co-authored-by: Shivam Mishra <scmmishra@users.noreply.github.com>
2020-06-18 17:04:45 +05:30
mergify[bot]
531ef15e30 refactor: handle exceptions when updating addresses (#22307) (#22315)
* refactor: handle exceptions when updating addresses

* refactor: fold common statements in a loop

(cherry picked from commit 34d2bfbb3e)

Co-authored-by: Shivam Mishra <scmmishra@users.noreply.github.com>
2020-06-18 17:04:36 +05:30
Deepesh Garg
6dc6da1ce2 Merge pull request #22324 from deepeshgarg007/item_tax_map_v12
fix: Do not copy Item Tax template from SO to PO
2020-06-18 17:02:56 +05:30
Deepesh Garg
f9dbcef5c9 fix: Do not copy Item Tax template from SO to PO 2020-06-18 17:01:32 +05:30
mergify[bot]
1ca4370033 fix: asset maintenance fixes (#21277) (#22294)
* fix: asset maintenance fixes

* fix: tests

(cherry picked from commit 9c494d3e72)

Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2020-06-18 15:39:13 +05:30
mergify[bot]
62882ea65b fix: asset maintenance fixes (#21277) (#22300)
* fix: asset maintenance fixes

* fix: tests

(cherry picked from commit 9c494d3e72)

Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2020-06-18 15:30:04 +05:30
mergify[bot]
0c08324fab chore: add standard queries hooks to whitelist (#21939) (#22305)
standard queries are used within the search widget, and now require to
be whitelisted before they can be executed through the search widget.

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>

Co-authored-by: sahil28297 <37302950+sahil28297@users.noreply.github.com>
(cherry picked from commit 96100e9507)

Co-authored-by: Chinmay Pai <chinmaydpai@gmail.com>
2020-06-18 15:29:46 +05:30
mergify[bot]
2417d9492f fix(HR): typo in error message in Employee Balance Report (#22306) (#22313)
* fix: typo in date error message

* fix: error message cleanup in Leave Balance report

(cherry picked from commit af6a0f3a9d)

Co-authored-by: Kenneth Sequeira <33246109+kennethsequeira@users.noreply.github.com>
2020-06-18 15:28:39 +05:30
Marica
c6886e28f2 Merge branch 'version-12-hotfix' into rfq-multi-uom-hotfix 2020-06-18 14:42:27 +05:30
marination
b865d58b81 fix: Patch simplification
- Also, apply patch to all docs
2020-06-18 14:43:31 +05:30
Kenneth Sequeira
af6a0f3a9d fix(HR): typo in error message in Employee Balance Report (#22306)
* fix: typo in date error message

* fix: error message cleanup in Leave Balance report
2020-06-18 14:34:11 +05:30
rohitwaghchaure
130d254b5a Merge pull request #22310 from rohitwaghchaure/fixed-incorrect-variable-used-pre-release
fix: incorrect variable used while adding items in the submitted sale…
2020-06-18 14:18:22 +05:30
Rohit Waghchaure
82abcc94fa fix: incorrect variable used while adding items in the submitted sales order 2020-06-18 14:17:16 +05:30
rohitwaghchaure
f635a1739e Merge pull request #22308 from rohitwaghchaure/fixed-incorrect-variable-used
fix: incorrect variable used while adding new item in the submitted Sales Order
2020-06-18 14:00:51 +05:30
Rohit Waghchaure
c75236579f fix: incorrect variable used while adding items in the submitted sales order 2020-06-18 13:59:23 +05:30
Mangesh-Khairnar
6a0bd556d7 fix: update shopify api version (#22297) 2020-06-18 12:48:52 +05:30
mergify[bot]
5d042ad496 fix: update shopify api version (#22284) (#22299)
Co-authored-by: Saurabh <saurabh@erpnext.com>
(cherry picked from commit 53b601523b)

Co-authored-by: Mangesh-Khairnar <mkhairnar10@gmail.com>
2020-06-18 09:47:15 +05:30
mergify[bot]
59938a46eb fix: typo for language in Terms description (#22270) (#22272)
(cherry picked from commit c159556c24)

Co-authored-by: Kenneth Sequeira <33246109+kennethsequeira@users.noreply.github.com>
2020-06-18 09:46:03 +05:30
P-Froggy
1284b9b17d fix: Set Value of wrong Bank Account Field in Payment Entry
Company bank account was wrongly inserted into the field "Party Bank Account" in payment entry, instead of "Bank Account".
Adds filters for "Party Bank Account" based on selected Party (I forgot to create a PR for version-12 back in February, see commit #393a626).
Also changes the label of "Default Bank Account" to "Default Company Bank Account", like suggested in PR #20632

#### Please Note
This is kind of a revert of PR #19390. However, it seems like the function "get_party_bank_account" in Bank Account doctype changed how it worked since it is clearly pulling the default company bank account.
2020-06-18 02:11:15 +02:00
Marica
c5c179490b Merge pull request #22293 from marination/variant-error-msg-pre-release
fix: Typo in Item Variant Error Message
2020-06-17 19:24:11 +05:30
Marica
1345bc2f82 Merge pull request #22291 from marination/variant-error-msg-hotfix
fix: Typo in Item Variant error message
2020-06-17 19:23:42 +05:30
marination
e256a7439e fix: Typo 2020-06-17 19:20:56 +05:30
marination
e67195b0b9 fix: Typo 2020-06-17 19:06:56 +05:30
Deepesh Garg
e4eb353065 Merge branch 'version-12-hotfix' into rcm_version-12-hotfix 2020-06-17 15:33:45 +05:30
Marica
b665da7cb4 Merge pull request #22282 from frappe/mergify/bp/v12-pre-release/pr-22281
fix: Message Formatting for missing Expense Account (bp #22281)
2020-06-17 13:55:25 +05:30
marination
7be4ba9351 fix: Message Formatting
(cherry picked from commit 17ec1d6b28)
2020-06-17 08:24:16 +00:00
Marica
41dadba990 Merge pull request #22281 from marination/expense-account-message
fix: Message Formatting for missing Expense Account
2020-06-17 13:51:09 +05:30
marination
17ec1d6b28 fix: Message Formatting 2020-06-17 13:46:21 +05:30
rohitwaghchaure
d4c2c4e170 Merge pull request #22276 from frappe/mergify/bp/v12-pre-release/pr-22268
fix: pos, serial no popup coming two times (bp #22268)
2020-06-17 12:27:20 +05:30
rohitwaghchaure
23a2d789ec Merge pull request #22277 from frappe/mergify/bp/v12-pre-release/pr-22248
fix: v12 travis (bp #22248)
2020-06-17 12:27:07 +05:30
Rohit Waghchaure
5e68fdbaee fix: travis
(cherry picked from commit e4834d2a37)
2020-06-17 05:40:14 +00:00
rohitwaghchaure
9c55efa8c6 fix: pos, serial no popup comin two times (#22268)
(cherry picked from commit 03f688acd9)
2020-06-17 05:35:50 +00:00
rohitwaghchaure
256b6950f5 Merge pull request #22273 from frappe/mergify/bp/v12-pre-release/pr-22267
refactor: hide company currency fields in the routing (bp #22267)
2020-06-17 10:59:58 +05:30
rohitwaghchaure
956368e457 refactor: hide company currency fields in the routing (#22267)
(cherry picked from commit fd3ff6be18)
2020-06-17 04:13:12 +00:00
rohitwaghchaure
fd3ff6be18 refactor: hide company currency fields in the routing (#22267) 2020-06-17 09:37:41 +05:30
rohitwaghchaure
03f688acd9 fix: pos, serial no popup comin two times (#22268) 2020-06-17 09:36:23 +05:30
rohitwaghchaure
fd5c577b40 Merge pull request #22248 from rohitwaghchaure/fixed-version-12-hotfix-travis
fix: v12 travis
2020-06-16 09:55:26 +05:30
Rohit Waghchaure
e4834d2a37 fix: travis 2020-06-15 22:24:56 +05:30
marination
1e76bdcc3c feat: Multi UOM support in Request for Quotation 2020-06-15 17:53:47 +05:30
Sahil Khan
b6c6406206 Merge branch 'version-12-hotfix' of https://github.com/frappe/erpnext into v12-pre-release 2020-06-15 16:58:22 +05:30
rohitwaghchaure
253a698708 Merge pull request #22247 from marination/backflush-rm-rate-hotfix
fix: Wrong key sent to get_valuation_rate
2020-06-15 14:50:02 +05:30
marination
b819d8cdb6 fix: Wrong key sent to gte_valuation_rate 2020-06-15 14:47:37 +05:30
P-Froggy
84f44588d8 fix: Validation of Purchase Order against Material Request missing (#22224)
Validation of Purchase Order and Purchase Order Item against the linked Material Request Item was missing.
This way, it was possible to exchange items while making a purchase order and still fulfill the material request, even though the items did not match.

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-06-15 13:40:54 +05:30
rohitwaghchaure
14961e55c8 Merge pull request #22196 from marination/add-to-cart-stock-hotfix
fix: Handle unavailable Variants in Website
2020-06-15 13:11:18 +05:30
rohitwaghchaure
db48fc2559 Merge pull request #22218 from marination/update-items-permission-fix-hotfix
fix: submitted sales order can be updated with no permission
2020-06-15 13:10:15 +05:30
marination
713cbcea44 fix: Travis 2020-06-15 12:09:04 +05:30
marination
0a31e2ea92 fix: Fetch cart setting from argument 2020-06-15 12:02:28 +05:30
rohitwaghchaure
087278baba Merge pull request #22209 from frappe/michellealva-expense-claim
fix: add filter for cost center in expense table
2020-06-15 10:36:31 +05:30
rohitwaghchaure
faff772619 Merge pull request #22220 from Anurag810/quality_procedure_fix_v12
fix: Child is shown in Parent process if added from tree view
2020-06-15 10:34:09 +05:30
Deepesh Garg
fa1af6d74e Merge pull request #22200 from marination/qi-on-return-hotfix
fix: Don't prompt for Quality Inspection on Return Documents.
2020-06-14 17:10:13 +05:30
rohitwaghchaure
01d2548235 Merge pull request #22238 from rohitwaghchaure/item-none-not-found-opening-creation-tool
fix: item none not found while making sales invoice using opening inv…
2020-06-14 15:09:08 +05:30
Rohit Waghchaure
5b11d18d86 fix: item none not found while making sales invoice using opening invoice creation tool 2020-06-14 14:06:12 +05:30
Deepesh Garg
e4cd23746b fix: Consider Overseas category in RCM 2020-06-14 13:20:09 +05:30
Deepesh Garg
d2ed36f167 Merge pull request #22229 from deepeshgarg007/financial_statement_to_date
fix: Data not appearing properly for some fiscal_year in financial statements
2020-06-13 19:19:55 +05:30
Deepesh Garg
1222fb074f fix: Data not appearing properly for some fiscal_year in financial statemets 2020-06-13 19:16:37 +05:30
Abhishek Balam
486be1049c fix(HR): Rename due_advance_amount field in Employee Advance for v12 (#22216)
* added patch for moving data

* changed fieldname and references for easier debugging

* style: Added EOF

* reload doc for patch
2020-06-13 01:18:29 +05:30
Anurag Mishra
9319153ab3 fix: Child is shown in Parent process if added from tree view 2020-06-12 17:04:25 +05:30
rohitwaghchaure
9ea539d335 Merge pull request #22158 from pipech/v12-hotfix-pricing_rule-missing_income_account
fix(pricing_rule): missing income account when getting free product
2020-06-12 17:00:13 +05:30
marination
f6054a2de8 fix: Added PO test and conversion factor fix
- Don't change conversion factor if stock uom and uom is the same
- Added PO test
- Added Accounts User basic role in PO
- Minor fixes, wrong variables
2020-06-12 16:28:44 +05:30
Saqib Ansari
6a9f368292 fix: unexpected removal of print hide field 2020-06-12 16:25:57 +05:30
Saqib Ansari
9ee4841520 fix: cannot update delivery date 2020-06-12 16:25:38 +05:30
Saqib Ansari
39e125b8a2 fix: label 2020-06-12 16:25:28 +05:30
Saqib Ansari
37b614af0e fix: submitted sales order can be updated with no permission 2020-06-12 16:25:07 +05:30
Marica
1dc3c40b00 Merge branch 'version-12-hotfix' into qi-on-return-hotfix 2020-06-12 12:32:27 +05:30
Marica
8ce5e04777 Update stock_controller.py 2020-06-12 12:32:12 +05:30
Michelle Alva
d6cdc3378a fix: add filter for cost center in expense table
Added filter for cost center in expense table (company and group_node filter)
2020-06-12 10:30:32 +05:30
Deepesh Garg
18ccd6b253 Merge pull request #22204 from marination/account-tree-hotfix
fix: Check for Company before rendering tree in Account Tree
2020-06-12 10:03:21 +05:30
marination
5ee33bdbe9 fix: Check for Company before rendering tree in Account Tree 2020-06-11 20:31:08 +05:30
marination
a965773c97 fix: Don't prompt for Quality Inspection on Return Documents. 2020-06-11 16:45:36 +05:30
marination
821606f001 fix: Handle unavailable Variants in Website 2020-06-11 13:32:58 +05:30
Deepesh Garg
95695f0628 Merge pull request #22189 from frappe/mergify/bp/version-12-hotfix/pr-22188
fix: Update payment schedule based on payment terms (bp #22188)
2020-06-10 22:31:28 +05:30
Deepesh Garg
755b8490e7 fix: Update payment schedule based on payment terms
(cherry picked from commit a0fd97f2ac)
2020-06-10 16:52:58 +00:00
Rohan
8a2c719359 fix: only auto-set serial nos and batches if allowed in Stock Settings (v12) (#21779)
* fix: only auto-set serial nos and batches if allowed in Stock Settings

* fix: bug with setting disabled batch no in Pick List

* Remove auto_set_batch_no

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-06-10 19:11:20 +05:30
rohitwaghchaure
eaa6218003 Merge pull request #22183 from marination/website-price-list-hotfix
fix: Prioritize Default Customer Price List in Portal
2020-06-10 19:07:00 +05:30
marination
8710866886 fix: Prioritize Default Customer Price List in Portal 2020-06-10 18:28:14 +05:30
rohitwaghchaure
f09db536af Merge pull request #22178 from rohitwaghchaure/code-cleanup-for-handling-batch-case-in-SI
fix: Cannot read property 'has_batch_no' of undefined
2020-06-10 17:07:05 +05:30
Rohit Waghchaure
c848b97757 fix: Cannot read property 'has_batch_no' of undefined 2020-06-10 17:04:40 +05:30
rohitwaghchaure
8fcd86cb9e Merge pull request #22062 from marination/procurement-tracker
fix: Procurement Tracker Data Consistency
2020-06-10 14:13:19 +05:30
rohitwaghchaure
8c69991c12 Merge pull request #22097 from marination/valuation-rate-hotfix
fix: '>=' not supported between instances of 'str' and 'int'
2020-06-10 14:12:03 +05:30
rohitwaghchaure
6b07ae89c0 Merge pull request #22168 from pipech/v12-hotfix-loyalty_program
fix(loyalty): loyalty point entry use wrong tier
2020-06-10 12:53:12 +05:30
mergify[bot]
703cee6abf fix: update program course (#22166) (#22173)
(cherry picked from commit 934e30ecac)

Co-authored-by: Anupam Kumar <anupamvns0099@gmail.com>
2020-06-10 12:51:29 +05:30
Poranut Chollavorn
5a5361815f docs(loyalty): fix wrong comment 2020-06-09 15:16:28 +00:00
Poranut Chollavorn
9831c5beca fix(loyalty): loyalty point entry use wrong tier 2020-06-09 15:06:44 +00:00
rohitwaghchaure
139627b331 Merge pull request #22148 from marination/finished-good-valuation-hotfix
fix: Finished Product Valuation at Repack
2020-06-09 17:41:58 +05:30
Poranut Chollavorn
dfd410ded2 fix(pricing_rule): missing income account 2020-06-09 03:16:49 +00:00
Deepesh Garg
02e3fc141a Merge pull request #22150 from deepeshgarg007/tdss_desscription_default
fix(accounting): Tax Withholding Category Description default
2020-06-08 14:05:54 +05:30
Deepesh Garg
65fb3f2c48 fix: Remove strip 2020-06-08 14:00:27 +05:30
Kevin Chan
5befddca39 fix: Tax Withholding Category Description default
This commit fixes a bug that happens when a Purchase Invoice uses a
Tax Withholding Category without a category_name. The category_name is
used as the tax description which is a required field. The bug was
fixed by using the Tax Withholding Category's name as the description
if the category_name is empty.
2020-06-08 14:00:17 +05:30
marination
189663f576 fix: Finished Product Valuation at Repack 2020-06-08 13:12:00 +05:30
rohitwaghchaure
b56156296b Merge pull request #22093 from marination/shippinng-address-hotfix
fix: Apply shipping rule without address too
2020-06-08 10:36:30 +05:30
mergify[bot]
6732c9ab14 fix: fetch tax lines within the shipping lines (#22138) (#22139)
(cherry picked from commit 3031128167)

Co-authored-by: Mangesh-Khairnar <mkhairnar10@gmail.com>
2020-06-07 18:59:06 +05:30
Deepesh Garg
38546cae33 Merge pull request #22068 from marination/item-attribute-hotfix
fix: Misleading Error message for Item Attribute.
2020-06-05 11:21:33 +05:30
P-Froggy
efdb55a083 fix: Wrong Ordered-Status Indicator for Material Request Items (#22117)
The indicator displaying if a material request item has been ordered or not (green/orange) used the wrong quantity field for determining the status.
The qty field is not in stock uom while the ordered_qty field is. Now, the stock_qty field is used for correct comparison with ordered_qty.
2020-06-05 10:56:30 +05:30
Marica
a569fa36bd Merge branch 'version-12-hotfix' into valuation-rate-hotfix 2020-06-04 15:31:35 +05:30
rohitwaghchaure
237ee1a9c6 Merge pull request #22110 from rohitwaghchaure/routing-operations-not-in-a-sequence-hotfix
fix: routing operations not added sequentially in the BOM
2020-06-04 14:52:08 +05:30
Rohit Waghchaure
1ae2376a83 fix: routing operations not added sequentially in the BOM 2020-06-04 14:50:22 +05:30
rohitwaghchaure
d0d35f03d0 Merge pull request #22108 from rohitwaghchaure/fixed-import-supplier-invoice-not-worked-v12
fix: import supplier invoice not working
2020-06-04 14:35:10 +05:30
Rohit Waghchaure
58a43be4f5 fix: import supplier invoice not working 2020-06-04 14:32:57 +05:30
Deepesh Garg
869d0c37b8 Merge pull request #22099 from frappe/mergify/bp/version-12-hotfix/pr-22098
fix: Error when no data is present in AR/AP report (bp #22098)
2020-06-03 22:40:30 +05:30
Deepesh Garg
c84961be85 fix: Error when no data is present in AR/AP reeport
(cherry picked from commit 7135a75e5e)
2020-06-03 16:49:52 +00:00
marination
89dd0bad28 fix: '>=' not supported between instances of 'str' and 'int' 2020-06-03 17:22:56 +05:30
Sahil Khan
b293e4b110 Merge branch 'v12-pre-release' into version-12 2020-06-03 15:10:41 +05:30
Sahil Khan
be104e5dcf bumped to version 12.9.4 2020-06-03 15:30:41 +05:50
sahil28297
051ae36bec Merge pull request #22094 from nextchamp-saqib/asset-error-fix-pre
fix: cannot create existing assets
2020-06-03 14:50:21 +05:30
sahil28297
12ad34b44a Merge pull request #22091 from nextchamp-saqib/asset-error-fix
fix: cannot create existing assets
2020-06-03 14:50:16 +05:30
Saqib Ansari
fc975cfc3a fix: cannot create existing assets 2020-06-03 14:48:38 +05:30
marination
1a1ce9a743 fix: Apply shipping rule without address too 2020-06-03 14:42:46 +05:30
Saqib Ansari
4e3caa8ece fix: cannot create existing assets 2020-06-03 14:15:16 +05:30
Deepesh Garg
28c9f3103f Merge pull request #22087 from MyuddinKhatri/purchase-receipt-hotfix
fix(stock): create purchase invoice from purchase receipt dashboard
2020-06-03 13:37:36 +05:30
Deepesh Garg
c417cf079c fix(India): Reverse charge mechanism for GST 2020-06-03 11:31:26 +05:30
Myuddin khatri
99f5ece31c fix(stock): able to create purchase invoice from purchase receipt dashboard
able to create purchase invoice from purchase receipt dashboard
2020-06-03 11:27:18 +05:30
gavin
5448be6f34 Merge pull request #22079 from frappe/mergify/bp/version-12-hotfix/pr-21491
feat(Tally migration): Errored documents handling (bp #21491)
2020-06-03 01:41:07 +05:30
mergify[bot]
38ed43ca59 Merge branch 'version-12-hotfix' into mergify/bp/version-12-hotfix/pr-21491 2020-06-02 09:26:34 +00:00
Gavin D'souza
2e825a108f chore: verbose error message for coa recursion
(cherry picked from commit cb1376b036)
2020-06-02 08:24:58 +00:00
Gavin D'souza
43a19da27a fix: un-using buggy JS frappe.new_doc
(cherry picked from commit 0c353a64a4)
2020-06-02 08:24:58 +00:00
Gavin D'souza
8ea9b0a415 feat: maintain tally voucher numbers
feat: create seperate customer and supplier entries for same party if
case exists

(cherry picked from commit af612ddb6d)
2020-06-02 08:24:58 +00:00
Gavin D'souza
d50cceaafa feat: prompt that company and COA will be overwritten
(cherry picked from commit 51305a028b)
2020-06-02 08:24:58 +00:00
Gavin D'souza
0a7afd77e2 fix: toggle read only for accounts post daybook data processing
style: code comments and updates
(cherry picked from commit f4926a8205)
2020-06-02 08:24:58 +00:00
Gavin D'souza
adb864828a perf: reduce JS memory heap and maintain namespaces
(cherry picked from commit 6b850b7e71)
2020-06-02 08:24:57 +00:00
Gavin D'souza
18d432a843 fix: table cleanups, updated summary block
(cherry picked from commit 0d61b35b0b)
2020-06-02 08:24:57 +00:00
Gavin D'souza
d3d511d31a fix: run summary logger
style: indent fixes
(cherry picked from commit 27b7172fa4)
2020-06-02 08:24:57 +00:00
Gavin D'souza
6950c10c6f feat: handle resolve and unresolved errors
restructured and reused components

(cherry picked from commit 2e1b531f4f)
2020-06-02 08:24:57 +00:00
Gavin D'souza
28a6e1deec feat: maintain logs of errors successfully fixed
(cherry picked from commit 640636bbcd)
2020-06-02 08:24:57 +00:00
Gavin D'souza
2f5208b08d feat: order failed import log by creation, handle rollbacks and commits
(cherry picked from commit 1b5eea691c)
2020-06-02 08:24:56 +00:00
Gavin D'souza
7ee6e83605 perf: reduce failed_error_log size
(cherry picked from commit 0805307514)
2020-06-02 08:24:56 +00:00
Gavin D'souza
0a2bbfaf24 feat: error log handling
fix: toggle required accounts
(cherry picked from commit 82e7a9de28)
2020-06-02 08:24:56 +00:00
Gavin D'souza
2ab6c8fa60 fix: set default round off acount
(cherry picked from commit 38c677689d)
2020-06-02 08:24:56 +00:00
Gavin D'souza
61381963b7 feat: Error logging via doc
fix: Handle duplicate company and COA
feat: Error logging via doc
feat: fetch defaults for accounts
(cherry picked from commit 2de4a5a7c8)
2020-06-02 08:24:56 +00:00
Gavin D'souza
5c448de2ae feat: Add Failed error logs
fix: set defaults
(cherry picked from commit defeb73747)
2020-06-02 08:24:55 +00:00
marination
f42d656cd3 fix: Misleading Error message for Item Attribute. 2020-06-01 12:03:20 +05:30
marination
144facf203 fix: Procurement Tracker Data Consistency 2020-05-31 20:11:40 +05:30
Deepesh Garg
0cd8102e0e Merge pull request #22059 from frappe/mergify/bp/version-12-hotfix/pr-22057
fix(ewb): remove checksum validation for TRANSIN (bp #22057)
2020-05-30 20:22:51 +05:30
karthikeyan5
ffbc812271 fix(ewb): remove checksum validation for TRANSIN
(cherry picked from commit ca46bedfcb)
2020-05-30 14:25:39 +00:00
Deepesh Garg
056854fd9e Merge pull request #22056 from marination/qty-validation-in-stock-entry-hotfix
fix: '<' not supported between instances of 'str' and 'int'
2020-05-30 19:49:57 +05:30
Rohit Waghchaure
e7e3af1684 fix: '<' not supported between instances of 'str' and 'int' 2020-05-30 18:38:41 +05:30
rohitwaghchaure
f214789e4b fix: routing operations table is blank on pull of operations in BOM (#22040) 2020-05-29 21:27:31 +05:30
mergify[bot]
0407f018dd fix: cannot assign same task to other asset maintenance (#22024) (#22032)
(cherry picked from commit cd8b5d1e4c)

Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2020-05-29 21:26:40 +05:30
mergify[bot]
592965a4d9 fix: disposed asset creates inconsistencies in asset depr report (#22021) (#22030)
(cherry picked from commit 3c460364b5)

Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2020-05-29 21:26:29 +05:30
mergify[bot]
5b695d6e9f fix: transaction date not found in sales invoice (bp #22001) (#22029)
* fix: transaction date not found in sales invoice

(cherry picked from commit 603cc3d05e)

* chore: tests

(cherry picked from commit dd39ba0014)

Co-authored-by: Saqib Ansari <nextchamp.saqib@gmail.com>
2020-05-29 21:26:16 +05:30
Deepesh Garg
245b8be435 Merge pull request #22033 from frappe/mergify/bp/version-12-hotfix/pr-21597
fix: cannot make payment entry against shareholder (bp #21597)
2020-05-29 13:21:59 +05:30
Saqib
840225d47b fix: cannot make payment entry against shareholder (#21597)
(cherry picked from commit d46696fa03)
2020-05-29 05:57:59 +00:00
Mangesh-Khairnar
0fcb79f361 fix: make transaction date of the oldest transaction as the last integration date (#22017)
* fix: make transaction date of the oldest transaction as the last integration date

* fix: only save end date when transactions are returned
2020-05-29 10:17:18 +05:30
Rucha Mahabal
74ddc04031 Merge pull request #22002 from frappe/mergify/bp/version-12-hotfix/pr-21999
fix: change modified time (bp #21999)
2020-05-28 13:03:18 +05:30
Michelle Alva
d65000a361 fix: change modified time
changed modified time to sync the changes

(cherry picked from commit 8653419c4c)
2020-05-28 07:31:23 +00:00
Deepesh Garg
6f37035617 Merge pull request #21920 from marination/import-italian-invoice
chore: Added Italian Import Supplier Invoice to Menu
2020-05-28 12:33:12 +05:30
Marica
aa6280f5cd Merge branch 'version-12-hotfix' into import-italian-invoice 2020-05-28 12:20:35 +05:30
mergify[bot]
64078da47b fix: change description for field (#21995) (#21996)
grammatical fixes for description of Default Customer

(cherry picked from commit f7beeff2d8)

Co-authored-by: Michelle Alva <50285544+michellealva@users.noreply.github.com>
2020-05-28 11:10:32 +05:30
Deepesh Garg
d9013dc7c9 Merge pull request #21987 from deepeshgarg007/tds_computation_summary_v12
fix: TDS computation summary report
2020-05-27 22:56:36 +05:30
Deepesh Garg
a23f929005 fix: TDS computation summary report 2020-05-27 22:51:36 +05:30
Marica
4f75a3a29b Merge branch 'version-12-hotfix' into import-italian-invoice 2020-05-27 21:53:18 +05:30
marination
d9e6900e07 fix: Added permission via regional setup and patch 2020-05-27 21:53:01 +05:30
Deepesh Garg
b4a3e5f70b fix: Total for ageing column 121-Above (#21973) 2020-05-27 20:30:41 +05:30
Deepesh Garg
aee9a61e0d fix: Post Dated unallocated amount not considered in Advance Amount in AR/AP summary (#21838)
* fix: Post Dated unallocateed amount not considered in Advance Amount in AR/AP summary report

* fix: Add future payment filter in AR/AP summary

* fix: Show unallocated future payments only till current creation date

* fix: Remove extra query

* fix: Remove debug

* fix: Condition
2020-05-27 12:46:18 +05:30
Deepesh Garg
ccb8edd7a3 Merge pull request #21941 from deepeshgarg007/acc_dim_report_filter_v12
fix: Do not add filters in report on accounting dimension creation if it already exists
2020-05-26 19:41:06 +05:30
Deepesh Garg
bb2bcc8a30 fix: Remove console statement 2020-05-26 19:31:33 +05:30
Deepesh Garg
9720406086 fix: Do not add filters in report on accounting dimension creation if it already exists 2020-05-26 19:31:21 +05:30
mergify[bot]
3c0e22c98c fix: shopify error message on failure of sales order creation (#21924) (#21937)
(cherry picked from commit 7402451b96)

Co-authored-by: Mangesh-Khairnar <mkhairnar10@gmail.com>
2020-05-26 18:37:25 +05:30
mergify[bot]
f912d78023 fix: check for warehouse in the woocommerce settings (#21925) (#21936)
(cherry picked from commit ddc170521f)

Co-authored-by: Mangesh-Khairnar <mkhairnar10@gmail.com>
2020-05-26 18:21:31 +05:30
Rohan
61257d829e fix: throw error if no serial numbers are found in Pick List (#21914)
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-05-26 18:11:39 +05:30
Andrew McLeod
c9014b1ba9 fix: website_list_for_contact, fix changed frappe.db.exist keyword argument (#21827) 2020-05-26 18:09:00 +05:30
Anurag Mishra
9ad46f7487 fix: Added column Expired Leave (#21859) 2020-05-26 18:08:08 +05:30
Deepesh Garg
b094178734 fix(UAE): Incorrect VAT rate display in Sales Invoice (#21883) 2020-05-26 18:02:08 +05:30
Anurag Mishra
a3ec869c58 fix: showing Wrong balance on allocation boundary dates (#21908) 2020-05-26 18:00:27 +05:30
mergify[bot]
7177514b0d fix: adding dashboard in course and assessment plan (#21889) (#21919)
* Adding dashboards

* adding dashboard in course and assessment plan

(cherry picked from commit 0a147d5c76)

Co-authored-by: Anupam Kumar <anupamvns0099@gmail.com>
2020-05-26 17:59:24 +05:30
marination
277f5273a4 chore: Add Import Supplier Invoice to Menu 2020-05-25 21:49:33 +05:30
Saqib
8ae7bb2bc4 fix: fetch depreciation amount only if depr entry is made (#21894) 2020-05-25 19:20:54 +05:30
Sahil Khan
7aa8eab228 Merge branch 'v12-pre-release' into version-12 2020-05-25 19:02:37 +05:30
Sahil Khan
70439c9cd8 bumped to version 12.9.3 2020-05-25 19:22:37 +05:50
Anurag Mishra
bbec37f713 fix: Validation for dates (#21887) 2020-05-25 18:39:26 +05:30
mergify[bot]
8ddf30201f fix: Item Price and Add to Cart not showing on Website (#21905) (#21916)
* fix: Item Price and Add to Cart not showing on Website

* fix: Use None as default argument

(cherry picked from commit 4e70ecb97d)

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-05-25 18:38:54 +05:30
Marica
4e70ecb97d fix: Item Price and Add to Cart not showing on Website (#21905)
* fix: Item Price and Add to Cart not showing on Website

* fix: Use None as default argument
2020-05-25 18:26:42 +05:30
rohitwaghchaure
666dd27d42 Merge pull request #21911 from rohitwaghchaure/fixed-comparison-operator
fix: comparison operator
2020-05-25 16:39:37 +05:30
Rohit Waghchaure
410196974e fix: comparison operator 2020-05-25 16:38:22 +05:30
Rohan
b9d5c71405 fix: filter batches based on item and warehouse in Pick List (#21778)
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-05-25 15:25:42 +05:30
Vishal Dhayagude
18b3c4802b fix: pound, gram to Ounce converion factor added (#21710)
* fix: pound, grams to Ounce converion factor added

* fix: patch date updated for UOM Conversion Factor

* fix: grams move to gram

* fix: duplicate entry of uom converion factor and patch added

* fix: typo fix

* fix: minor changes

* Update patches.txt

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-05-25 15:13:09 +05:30
rohitwaghchaure
cbe476d455 Merge pull request #21900 from rohitwaghchaure/fixed-stock-and-account-value-comparison-report-hotfix
fix: local variable 'lft' referenced before assignment
2020-05-25 12:50:50 +05:30
Rohit Waghchaure
b4b6b694af fix: local variable 'lft' referenced before assignment 2020-05-25 12:49:27 +05:30
rohitwaghchaure
aa299d0faf Merge pull request #21868 from rohitwaghchaure/delivery-date-not-allowed-to-change-after-submit
fix: allow on submit for the delivery date field not working for sale…
2020-05-25 11:11:11 +05:30
sahil28297
1f6c5c295f fix(patch): rerun remove_duplicate_leave_ledger_entries (#21874) 2020-05-22 15:52:46 +05:30
sahil28297
5d8dafc2ec fix(patch): rerun remove_duplicate_leave_ledger_entries (#21875) 2020-05-22 14:18:08 +05:30
Saurabh
34eb306e39 Merge pull request #21873 from frappe/sahil28297-patch-3
fix(patch): rerun remove_duplicate_leave_ledger_entries
2020-05-22 13:48:53 +05:30
sahil28297
439af124f9 fix(patch): rerun remove_duplicate_leave_ledger_entries 2020-05-22 13:42:55 +05:30
Sahil Khan
8abcf42e20 Merge branch 'v12-pre-release' into version-12 2020-05-22 13:37:26 +05:30
Sahil Khan
485f6cd7a2 bumped to version 12.9.2 2020-05-22 13:57:25 +05:50
Nabin Hait
5447decd9e fix: Remove duplicate leave ledger entry (#21870)
* fix: Remove duplicate leave ledger entry

* fix: Remove duplicate leave ledger entry
2020-05-22 13:13:09 +05:30
Nabin Hait
1287f16acd fix: Remove duplicate leave ledger entry (#21867) 2020-05-22 13:13:04 +05:30
Rohit Waghchaure
589c5335d1 fix: allow on submit for the delivery date field not working for sales order 2020-05-22 12:41:07 +05:30
Deepesh Garg
5f82999397 fix: Item tax template not getting mapped from source to traget doc (#21863) 2020-05-22 12:29:19 +05:30
Nabin Hait
115cedb8e9 fix: Remove duplicate leave ledger entry (#21864) 2020-05-22 12:27:19 +05:30
mergify[bot]
d2491e403b fix: convert goals point to flt (#21840) (#21858)
(cherry picked from commit 4c779300fd)

Co-authored-by: Anurag Mishra <32095923+Anurag810@users.noreply.github.com>
2020-05-22 11:43:14 +05:30
mergify[bot]
44d6ce49b5 fix: expense account error message in DN (#21851) (#21856)
Changed error message if expense account not set for item in Delivery Note.
Earlier: Expense or Difference account is mandatory for Item IT - 6 as it impacts overall stock value
After fix: Expense Account not set for Item IT - 6. Please set an Expense Account for the item in the Items table

(cherry picked from commit 1763d3e706)

Co-authored-by: Michelle Alva <50285544+michellealva@users.noreply.github.com>
2020-05-22 11:06:19 +05:30
sahil28297
7b795734e8 Merge pull request #21855 from frappe/mergify/bp/v12-pre-release/pr-21846
fix: set customer and supplier details using sql (bp #21846)
2020-05-22 11:05:40 +05:30
Chinmay Pai
b6bbd0efcf fix: set customer and supplier details using sql (#21846)
* fix: set customer and supplier details using sql

instead of slowing down the query with get_doc and save()
we can just use sql to update the required values for
customer and supplier

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>

* chore: remove extra quote

Co-authored-by: Himanshu <himanshuwarekar@yahoo.com>

* fix: update sql query to include tabPrice List

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>

Co-authored-by: Himanshu <himanshuwarekar@yahoo.com>
(cherry picked from commit baef43977b)
2020-05-22 05:29:49 +00:00
mergify[bot]
7522e598db fix: set customer and supplier details using sql (#21846) (#21854)
* fix: set customer and supplier details using sql

instead of slowing down the query with get_doc and save()
we can just use sql to update the required values for
customer and supplier

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>

* chore: remove extra quote

Co-authored-by: Himanshu <himanshuwarekar@yahoo.com>

* fix: update sql query to include tabPrice List

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>

Co-authored-by: Himanshu <himanshuwarekar@yahoo.com>
(cherry picked from commit baef43977b)

Co-authored-by: Chinmay Pai <chinmaydpai@gmail.com>
2020-05-22 10:59:16 +05:30
Marica
5ec0289d98 fix: Added Inactive serial no status (#21850) 2020-05-22 10:49:07 +05:30
Marica
576374a8a7 fix: Added Inactive serial no status (#21849) 2020-05-22 10:49:00 +05:30
mergify[bot]
030abc14a4 fix(patch): Handle single value in patch (#21823) (#21833)
(cherry picked from commit 5cef8db4db)

Co-authored-by: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com>
2020-05-21 18:57:24 +05:30
Anurag Mishra
4c779300fd fix: convert goals point to flt (#21840) 2020-05-21 18:47:30 +05:30
sahil28297
c5921c605f fix(set_serial_no_status): auto commit on many writes (#21841) 2020-05-21 18:46:42 +05:30
sahil28297
da23bb6bf4 fix(set_serial_no_status): auto commit on many writes (#21843) 2020-05-21 18:46:38 +05:30
Sahil Khan
0c303c4f54 Merge branch 'v12-pre-release' into version-12 2020-05-21 15:26:42 +05:30
Sahil Khan
746e879187 bumped to version 12.9.1 2020-05-21 15:46:42 +05:50
Suraj Shetty
a24362a83f Merge pull request #21836 from frappe/surajshetty3416-patch-1 2020-05-21 15:25:18 +05:30
Suraj Shetty
69a5a7f11e fix(patch): Handle single value in patch 2020-05-21 15:23:06 +05:30
Sahil Khan
d062a4b6b5 Merge branch 'v12-pre-release' into version-12 2020-05-21 15:00:37 +05:30
Sahil Khan
ab79a9554b bumped to version 12.9.0 2020-05-21 15:20:37 +05:50
rohitwaghchaure
3e5a65e090 Merge pull request #21829 from marination/italian-invoice-import-hotfix
fix: Supplier Invoice No not fetched in Import Supplier Invoice
2020-05-21 14:23:20 +05:30
rohitwaghchaure
f5d8d6e4e6 Merge pull request #21830 from marination/italian-invoice-import-pre-release
fix: Supplier Invoice No not fetched in Import Supplier Invoice
2020-05-21 14:22:36 +05:30
rohitwaghchaure
fae4805d3f Merge pull request #21826 from marination/pick-list-dn-pre-release
fix: Fetch customer into Delivery Note from Pick List
2020-05-21 14:20:31 +05:30
rohitwaghchaure
bc55dafdae Merge pull request #21825 from marination/pick-list-dn-hotfix
fix: Fetch customer into Delivery Note from Pick List
2020-05-21 14:19:05 +05:30
marination
cb74ff870d fix: Supplier Invoice No not fetched in Import Supplier Invoice 2020-05-21 14:06:57 +05:30
marination
d1458c6c0a fix: Supplier Invoice No not fetched in Import Supplier Invoice 2020-05-21 14:06:14 +05:30
marination
3c84ef3b5e fix: Fetch customer into Delivery Note from Pick List 2020-05-21 13:18:06 +05:30
marination
a8b2f222ea fix: Fetch customer into Delivery Note from Pick List 2020-05-21 13:17:22 +05:30
Marica
2894640d56 fix: plc conversion rate set infinitely (#21822) 2020-05-21 12:08:15 +05:30
Marica
ee1c3831bc fix: plc conversion rate set infinitely (#21821) 2020-05-21 12:08:04 +05:30
rohitwaghchaure
fc5f5c8fd9 Merge pull request #21819 from rohitwaghchaure/tax-template-not-applied-if-valid-from-blank-hotfix
fix: item tax template not applied if valid from is blank
2020-05-21 10:24:33 +05:30
rohitwaghchaure
a45ff8e3ba Merge pull request #21818 from rohitwaghchaure/tax-template-not-applied-if-valid-from-blank
fix: item tax template not applied if valid from is blank
2020-05-21 10:22:37 +05:30
Rohit Waghchaure
2caac24071 fix: item tax template not applied if valid from is blank 2020-05-21 10:15:03 +05:30
Rohit Waghchaure
74dd64501c fix: item tax template not applied if valid from is blank 2020-05-21 10:09:42 +05:30
Deepesh Garg
bd8b94c9dd Merge pull request #21816 from deepeshgarg007/trial_balance_project_filter_pre
fix: Project filter in Trial Baalance Report
2020-05-20 22:28:53 +05:30
Deepesh Garg
928bc96d76 Merge pull request #21815 from deepeshgarg007/trial_balance_project_filter_v12
fix: Project filter in Trial Baalance Report
2020-05-20 22:28:35 +05:30
Deepesh Garg
d1569b9581 fix: Project filter in Trial Baalance Report 2020-05-20 22:20:23 +05:30
Deepesh Garg
67c9f00917 fix: Project filter in Trial Baalance Report 2020-05-20 22:18:30 +05:30
mergify[bot]
c75303b0ab feat: remove website settings from boot (#21801) (#21809)
(cherry picked from commit e091789332)

Co-authored-by: Shivam Mishra <scmmishra@users.noreply.github.com>
2020-05-20 18:24:05 +05:30
Anupam Kumar
ee56de3091 enable Allow Rename in sales stage (#21800) 2020-05-20 16:15:16 +05:30
Anupam Kumar
938cde30e3 enable Allow Rename in sales stage (#21803) 2020-05-20 16:14:58 +05:30
Marica
d53d6cabb4 fix: Validate Payment Gateway only if it exists in Payment Request. (#21806) 2020-05-20 16:13:38 +05:30
Marica
0550b3537d fix: Validate Payment Gateway only if it exists in Payment Request. (#21807) 2020-05-20 16:13:34 +05:30
Deepesh Garg
ea6f08cb26 Merge pull request #21798 from deepeshgarg007/general_ledger_against_voucher_v12_pre
fix: Against voucher in General Ledger
2020-05-20 11:32:13 +05:30
Deepesh Garg
96a05f65aa fix: Against voucher in General Ledger 2020-05-20 11:26:14 +05:30
rohitwaghchaure
0e63f4ba08 Merge pull request #21794 from deepeshgarg007/general_ledger_against_voucher_v12
fix: Against voucher in General Ledger
2020-05-20 10:30:20 +05:30
Deepesh Garg
74b943392b Merge pull request #21786 from anupamvs/sales-order-tax-hotfix
fix: tax id is not fetched when creating sales order from quotation
2020-05-19 21:49:34 +05:30
Anupam K
9245133b99 tax id is not fetched in when creating sales order from quoation 2020-05-19 21:37:19 +05:30
Deepesh Garg
05aae4341e fix: Against voucher in General Ledger 2020-05-19 20:59:51 +05:30
rohitwaghchaure
e85c3a50cd refactor: changed the fieldtype from data to small text (#21789) 2020-05-19 20:30:11 +05:30
Deepesh Garg
dc04d44a20 Merge pull request #21791 from deepeshgarg007/gst_1_instate_v1
fix: Tax amount in GSTR-1 JSON
2020-05-19 20:01:18 +05:30
Deepesh Garg
e2e5ba345c fix: Tax amount in GSTR-1 JSON 2020-05-19 19:56:51 +05:30
rohitwaghchaure
07924d3c7c refactor: changed the fieldtype from data to small text (#21783) 2020-05-19 19:05:17 +05:30
Deepesh Garg
bd29244d66 Merge pull request #21787 from deepeshgarg007/gst_1_instate
fix: Instate Invoice not appearing in GSTR-1 report
2020-05-19 19:04:11 +05:30
Deepesh Garg
b384ed74cd fix: Instate Invoice not appearing in GSTR-1 report 2020-05-19 18:53:08 +05:30
Shivam Mishra
72892a40d6 refactor: use text editor in issue web form (#21772) 2020-05-19 16:36:25 +05:30
Himanshu
8209507a8f fix: add naming series (#21775) 2020-05-19 16:02:41 +05:30
Himanshu
ca5384343f Merge pull request #21773 from scmmishra/issue-form-pre-12
refactor: use text editor in issue web form
2020-05-19 15:23:46 +05:30
Shivam Mishra
a4e92cf577 refactor: use text editor in issue web form 2020-05-19 15:12:18 +05:30
mergify[bot]
113048347c feat: save shipping address and contact to woocommerece customer (bp #21654) (#21771) 2020-05-19 14:36:29 +05:30
Himanshu
8b144a38cc fix: add naming series (#21770) 2020-05-19 14:27:01 +05:30
Nabin Hait
632c65cd59 chore: Added change log 2020-05-18 19:54:52 +05:30
Nabin Hait
70ab59f473 fix: merge conflict 2020-05-18 17:10:36 +05:30
Deepesh Garg
c4d6cca9f1 Merge pull request #21762 from frappe/mergify/bp/version-12-hotfix/pr-21761
fix: Validate Filters in Sales Funnel. (bp #21761)
2020-05-18 16:45:20 +05:30
Marica
795d318fcc fix: Validate Filters in Sales Funnel. (#21761)
* fix: Validate Filters in Sales Funnel.

* fix: Style fixes

(cherry picked from commit c734db5d45)
2020-05-18 09:15:45 +00:00
Himanshu
6dbb02d293 fix: show searchfields result (#21760) 2020-05-18 14:26:43 +05:30
rohitwaghchaure
ea4c91f51c fix: bom incorrect price list rate for raw material if price list currency is different from company currency (#21586)
* fix: bom incorrect price list rate for raw material if price list currency is different from company currency

* fixed test cases

* fixed base_rate calculation and added plc_conversion_rate trigger
2020-05-18 14:22:42 +05:30
Marica
395da09dae fix: Patch to set status in old serial no data (#21721)
* fix: Patch to set status in old serial no data

* fix: Avoid get_doc in patch

* fix: fetch all values and check status in one query
2020-05-18 11:18:56 +05:30
Raffael Meyer
9b08258955 fix: remove guest access (#21692) 2020-05-17 20:57:51 +05:30
rohitwaghchaure
7f2aedb67c fix: incorrect stock valuation for repack entry (#21737) 2020-05-17 20:28:21 +05:30
Anurag Mishra
1045dc49f5 fix: Future date half day validation (#21719)
* fix: Future date half day validation

* fix: Allow half day attendance only via leave application

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-05-17 20:17:39 +05:30
Deepesh Garg
a569fed4da Merge pull request #21746 from frappe/mergify/bp/version-12-hotfix/pr-21712
fix: error log title for failing bank transactions (bp #21712)
2020-05-16 17:15:05 +05:30
rohitwaghchaure
9af9b438af Merge pull request #21748 from rohitwaghchaure/fix-supplier-schema-save-issue-hotfix
fix: promotional scheme not able to save
2020-05-16 11:34:33 +05:30
Rohit Waghchaure
3e321d5c24 fix: promotional scheme not able to savce 2020-05-16 05:01:30 +05:30
Mangesh-Khairnar
e2f53cdc83 fix: error log title for failing bank transactions
(cherry picked from commit 4a9fd9ef6d)
2020-05-15 18:16:22 +00:00
Deepesh Garg
f9834504c8 Merge pull request #21745 from deepeshgarg007/coa_ux_v12
fix: Excel support and UX fixes for chart of accounts importer
2020-05-15 20:08:54 +05:30
Deepesh Garg
ec19926a97 Move logic for download template to dialog 2020-05-15 19:45:47 +05:30
Deepesh Garg
39790f05e7 fix: Linting fixes 2020-05-15 19:44:45 +05:30
Deepesh Garg
317b53a8b6 fix: Description on template selection 2020-05-15 19:44:36 +05:30
Deepesh Garg
101612e599 fix: Added template types for download 2020-05-15 19:44:27 +05:30
Deepesh Garg
838ed77797 fix: Blank chart preview 2020-05-15 19:44:18 +05:30
Deepesh Garg
8ff718249e fix: Linting Errors 2020-05-15 19:44:07 +05:30
Deepesh Garg
88c2ba54ab fix: Excel support and UX fixes for chart of accounts importer 2020-05-15 19:43:56 +05:30
rohitwaghchaure
a52fe009cc fix: user not able to view product (#21697) 2020-05-15 19:35:35 +05:30
Deepesh Garg
79b691fe18 fix: Better validation message for group accounts (#21726) 2020-05-15 19:23:16 +05:30
Deepesh Garg
29f1a219d1 Merge pull request #21743 from nextchamp-saqib/payment-remark-fix-v12
fix: update remark on submitting payment entry
2020-05-15 17:49:11 +05:30
Deepesh Garg
73e3ba2c30 Merge pull request #21744 from frappe/mergify/bp/version-12-hotfix/pr-21729
fix: Submit perm for other income and removed caching while getting hra and basic from company (bp #21729)
2020-05-15 17:47:10 +05:30
Nabin Hait
78f69e448b fix: Added submit permission in employee other income
(cherry picked from commit 200f80c3d3)
2020-05-15 11:28:08 +00:00
Nabin Hait
52890341d5 fix: Get basic and hra component from db, not from cache
(cherry picked from commit 10df3d5081)
2020-05-15 11:28:08 +00:00
Saqib Ansari
725684a0c3 fix: update remark on submitting payment entry 2020-05-15 16:39:45 +05:30
Deepesh Garg
dc59831aa9 Merge pull request #21700 from nextchamp-saqib/pur-inv-status-fix-v12
fix: purchase inv shows overdue for fraction of outstanding
2020-05-15 15:45:36 +05:30
Saqib Ansari
2fa841821a fix: add tests for set_status 2020-05-15 14:31:19 +05:30
rohitwaghchaure
3b14810564 Merge pull request #21714 from nextchamp-saqib/off-pos-tax-template-v12
fix: item tax template fetching in offline pos
2020-05-15 13:47:01 +05:30
Deepesh Garg
8ed066ba1f fix: Add misssing dimensions in GL entries (#21691)
* fix: Add misssing dimensions in GL entries

* fix: expnese_taxes_and_charges.json

* fix: Add project filter in trial balance report

* fix: Use current dimensions instead of dimensions from asset
2020-05-15 12:58:19 +05:30
Rohan
f344369068 format: better error messages for invalid coupon codes (v12) (#21598)
* format: better error messages for invalid coupon codes

* fix: remove unnecessary docstatus check
2020-05-15 12:09:16 +05:30
Mangesh-Khairnar
71d9a52a07 fix: duplicate leave expiry creation (#21506)
* fix: validate existing ledger entries to avoid duplicates

* patch: remove duplicate ledger entries created

* fix: consider only submitted ledger entries

* fix: delete duplicate leaves from the ledger

* fix: check if duplicate ledger entry exists

* chore: formatting changes

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-05-15 11:55:36 +05:30
Saqib Ansari
0af125f6fe fix: test 2020-05-15 05:26:41 +05:30
Saqib
b432f3358e fix: item price not fetching when customer is unset in item price (#21489)
* fix: item price not fetching when customer is unset in item price

* fix: item price of selling type has hidden supplier value

* fix: remove test variable

* fix: test

* Update erpnext/stock/get_item_details.py

Co-authored-by: Marica <maricadsouza221197@gmail.com>

* patch: invalid customer/supplier based on item price type

* fix: remove patches from develop branch

* fix: patch

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-05-15 04:25:10 +05:30
Saqib
441bb760ee Merge branch 'version-12-hotfix' into off-pos-tax-template-v12 2020-05-14 14:28:11 +05:30
Saqib
f69da75e33 Merge branch 'version-12-hotfix' into pur-inv-status-fix-v12 2020-05-14 14:27:44 +05:30
Saqib Ansari
12739ec464 fix: invalid conditional statement 2020-05-13 22:03:20 +05:30
Marica
6a317a8e78 fix: Add total rows in Report Purchase Order Items to be Received or Billed (#21711) 2020-05-13 18:58:03 +05:30
Saqib Ansari
cb1cc96210 fix: item tax template fetching in offline pos 2020-05-13 16:30:47 +05:30
Saqib Ansari
b47f5830f4 fix: purchase inv shows overdue for fraction of outstanding 2020-05-12 14:13:16 +05:30
mergify[bot]
855373a253 fix: Message for missing valuation rate (#21686) (#21688)
(cherry picked from commit 97715f2877)

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-05-11 21:26:18 +05:30
mergify[bot]
c8ed6b1e79 fix: Run income-tax-slab patch only if slab already exists in payroll period (#21684) (#21687)
(cherry picked from commit 85a89812a4)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-05-11 19:29:18 +05:30
sahil28297
00bbc76605 fix(patch): use translated string while setting notification template (#21678) 2020-05-11 19:28:49 +05:30
rohitwaghchaure
0df4f1738c Merge pull request #21602 from anupamvs/lead-customer-issue-hotfix
fix: adding Email and Phone in Contact child table
2020-05-11 13:02:41 +05:30
rohitwaghchaure
12a2da49ee Merge pull request #21662 from marination/barcode-update-fix
fix: Item Barcode stays the same after updation.
2020-05-11 11:01:13 +05:30
rohitwaghchaure
65d6efdaee Merge pull request #21666 from anupamvs/assessment-issue-hotfix
fix: Assessment Plan not getting created
2020-05-11 07:17:28 +05:30
rohitwaghchaure
f861a3e720 Merge pull request #21603 from rohitwaghchaure/fix-completed-qty-in-work-order-hotfix
fix: work order operation completed qty
2020-05-11 07:07:16 +05:30
Deepesh Garg
767d17ce2f Merge pull request #21672 from deepeshgarg007/budget_variance_report_v12
Budget variance report v12
2020-05-10 17:31:41 +05:30
Deepesh Garg
0f455060ab fix: Formatting fixes 2020-05-10 17:27:29 +05:30
Kevin Chan
861f2726a2 fix: Simplify get_dimension_account_month_map
This commit updates get_dimension_account_month_map to no longer show
the actual expense when there is no budget. This also removes the other
functions and queries related to it. Spaces are also converted to tabs.
2020-05-10 17:27:01 +05:30
Kevin Chan
55640be627 fix: Fix Budget Variance Report
This commit fixes a bug in Budget Variance Report where it combines the
actual expense amounts across different fiscal years. This was fixed by
updating the function and queries for computing the actual expense
amounts.
2020-05-10 17:26:29 +05:30
Kevin Chan
d837b6cedc style: Improve formatting
This commit improves indentations and makes sql queries more readable.
2020-05-10 17:26:16 +05:30
Anupam K
27b2988938 Assessment Plan not getting created 2020-05-09 16:44:36 +05:30
Anupam K
c739c2d355 Appending Email and Phone in Child Table 2020-05-08 17:38:14 +05:30
marination
231f65ff59 fix: Item Barcode stays the same after updation. 2020-05-08 16:43:02 +05:30
rohitwaghchaure
368afc551d Merge pull request #21640 from MyuddinKhatri/lead-update-fix-hotfix
fix(crm): fix lead while updating contact details (hotfix)
2020-05-08 10:37:28 +05:30
rohitwaghchaure
3a328b0413 Merge pull request #21645 from anupamvs/lms-label-hotfix
fix: renaming LMS to Learning Management System
2020-05-08 10:29:54 +05:30
rohitwaghchaure
970b21075e Merge pull request #21650 from anupamvs/payment-order-hotfix
fix: Payment Order not allowing to create Payment Entry
2020-05-08 10:26:55 +05:30
Deepesh Garg
d769a2036b Merge pull request #21648 from ruchamahabal/remove-old-analytics-v12
fix: delete old appointment analytics tree grid report
2020-05-08 10:23:46 +05:30
Anupam K
56a3b9abc4 Payment Order not allowing to create Payment Entry 2020-05-08 02:25:09 +05:30
Rucha Mahabal
6844dd75da fix: delete old appointment analytics tree grid report 2020-05-07 23:40:17 +05:30
Anupam K
0b6ef55e78 renaming LMS to Learning Management System 2020-05-07 19:51:46 +05:30
Myuddin khatri
cd0fcfd84c solved merge conflicts 2020-05-07 16:11:08 +05:30
rohitwaghchaure
43118e3551 Merge pull request #21635 from TurkerTunali/patch-3
fix: Job Card submitted qty
2020-05-07 16:08:21 +05:30
Türker Tunalı
9bd6d119c4 fix: Job Card submitted qty
Update Operation Status function in work order was throwing exception without checking the "Overproduction Percentage For Work Order" setting. To submit Job Card qty for more than the Work Order's "To Manufacture Qty" we need to apply this fix.
2020-05-07 12:38:37 +03:00
sahil28297
2aa045865f fix(item): patch to rename duplicate item_code values to name (#21619) 2020-05-07 12:11:23 +05:30
rohitwaghchaure
ec3a462acd fix: list index out of range (#21614) 2020-05-07 12:06:05 +05:30
Deepesh Garg
a6066009aa Merge pull request #21520 from nextchamp-saqib/sales-report-total-row-v12
chore: add total row in sales analytics report
2020-05-06 10:50:53 +05:30
Deepesh Garg
60b19fe935 Merge branch 'version-12-hotfix' into sales-report-total-row-v12 2020-05-06 10:48:38 +05:30
Deepesh Garg
70b52c37d5 Merge pull request #21606 from frappe/sahil28297-patch-1
fix(patch): reload Expense Claim doctype
2020-05-05 20:21:23 +05:30
sahil28297
178ad9b4d6 fix(patch): reload Expense Claim doctype 2020-05-05 20:07:48 +05:30
Rohit Waghchaure
b4311a41c5 fix: work order operation completed qty 2020-05-05 16:36:31 +05:30
Anupam K
c6e0dbb1c4 Appending Email and Phone in Child Table 2020-05-05 16:26:05 +05:30
rohitwaghchaure
d476eb79b4 fix: against voucher no not all records showing in case of Group By Voucher (consolidated) (#21591) 2020-05-05 16:17:03 +05:30
Saqib
10ea82001f chore: fix error message (#21594)
* chore: fix error message

* chore: add row idx
2020-05-05 16:14:12 +05:30
Saqib
794bb6ebdd fix: handle make_gl_entry in case of cwip enable after puchasing (#21530)
* fix: handle make_gl_entry in case of cwip enable after puchasing

* fix: invalid variable assignment

* fix: make gl entries if cwip has been booked even if cwip is disabled
* add tests

* fix: conditions

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-05-05 16:12:10 +05:30
Saqib Ansari
c3a9513978 fix: test 2020-05-04 20:24:30 +05:30
Deepesh Garg
a4a019f9d9 Merge pull request #21584 from frappe/sahil28297-patch-3
fix(patch): Reload GSTR 3B report
2020-05-04 19:26:46 +05:30
sahil28297
67ed21d443 fix(patch): Reload GSTR 3B report 2020-05-04 19:23:26 +05:30
rohitwaghchaure
c89d750e5c fix: heatmap not working for customer and supplier (#21579) 2020-05-04 18:53:26 +05:30
mergify[bot]
c253f0621d fix: fieldname update for 'Credit' and 'Debit' (#21405) (#21577)
* fix: fieldname update for 'Credit' and 'Debit'

'credit' updated to 'credit_in_account_currency'
'debit' updated to 'debit_in_account_currency'

* Update journal_entry.py

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
(cherry picked from commit f7a0b8b5b6)

Co-authored-by: Andy Zhu <andy007yan@gmail.com>
2020-05-04 12:40:39 +05:30
Deepesh Garg
3202b0a486 fix: Accounting Dimensions in Period Closing Voucher (#21565) 2020-05-04 11:12:19 +05:30
Rucha Mahabal
4a37ee8908 fix(Healthcare): remove hardcoded UOM during Item creation for templates (#21575) 2020-05-04 11:09:19 +05:30
Rucha Mahabal
bdbfd2ad0c fix: handle exception if sending Appointment Confirmation message fails (#21568) 2020-05-04 11:07:10 +05:30
Deepesh Garg
933d1262f2 Merge pull request #21376 from marination/commonify-warehouse-autofill-hotfix
chore: Commonify autofilling warehouses in child tables
2020-05-03 20:34:20 +05:30
rohitwaghchaure
c4752e36eb Merge pull request #21517 from marination/stock-balance-cleanup-hotfix
chore: Added company filter and minor cleanup in Stock Balance Report
2020-05-03 16:31:58 +05:30
Saqib Ansari
0da919c091 fix: test 2020-05-03 14:53:40 +05:30
Saqib
12b5d72e70 chore: add validation for gross purchase amount (#21535)
* chore: add validation for gross purchase amount

* fix: tests
2020-05-03 13:20:30 +05:30
Saqib Ansari
272d2bc0b3 fix: review fixes 2020-05-02 19:51:09 +05:30
Saqib Ansari
55b7904e2f fix: incorrect total in sales analytics for customer/item group 2020-05-02 19:39:42 +05:30
Marica
ed709b36b4 fix: variable referenced before assignment (#21561) 2020-05-02 17:55:47 +05:30
Saqib
bf1fc47564 fix: accounts payable shows advance amount of other company (#21549) 2020-05-01 18:15:20 +05:30
Deepesh Garg
db6953dc78 fix: Party Type filter in payment entry list view (#21542) 2020-05-01 15:01:04 +05:30
rohitwaghchaure
438e0f5d49 fix: 'NoneType' object is not iterable (#21538) 2020-05-01 10:50:02 +05:30
rohitwaghchaure
5a9476e0d4 Merge pull request #21502 from nextchamp-saqib/validate-paid-inv-msg-v12
chore: validate and warn payment against paid invoices
2020-05-01 10:37:32 +05:30
marination
f77a735469 fix: Make Company the first filter 2020-05-01 00:04:49 +05:30
Saqib Ansari
4451b7eda9 chore: calculate total row month-wise in sales analytics 2020-04-30 20:07:12 +05:30
mergify[bot]
426f0bc168 fix: only check for payment_account on bank entry (#21445) (#21518)
* fix: only check for payment_account on bank entry

Since all the fields (company, start and end date are mandatory before form submission, there is no need to check for them again after submission.

* fix: cur_frm to frm

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
(cherry picked from commit 95b186268c)

Co-authored-by: Michelle Alva <50285544+michellealva@users.noreply.github.com>
2020-04-30 19:53:59 +05:30
Saqib
a8b87ccce0 chore: asset accounts should have company currency (#21525) 2020-04-30 18:39:16 +05:30
Saqib Ansari
c31fc19f08 chore: add total row in sales analytics report 2020-04-30 16:29:21 +05:30
marination
5e817b2aee chore: Added company filter and minor cleanup in Stock Balance Report 2020-04-30 14:05:24 +05:30
Saqib Ansari
393857d7de chore: handle credit note validation 2020-04-30 13:24:51 +05:30
Saqib
0ffff47b64 feat: force cost center renaming from cost center form (#21504) 2020-04-30 11:29:03 +05:30
Saqib
6397590f07 fix: list index out of range error (#21468)
* fix: list index out of range error

* fix: condition
2020-04-30 11:04:51 +05:30
Nabin Hait
2620ac31f9 fix: Desk links for Income Tax Slab and Employee Other Income (#21511) 2020-04-30 11:03:57 +05:30
Nabin Hait
22c4f82fc6 fix: Tax calcualtion based on slab (#21497) 2020-04-30 11:03:01 +05:30
Nabin Hait
ae5414fced fix: Consider any kind of exemptions only if tax exemptions are allowed on tax slab (#21475) 2020-04-30 11:02:45 +05:30
Saqib
61584c8601 fix: print heading field shown in gst section for india region (#21500)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-04-30 10:58:01 +05:30
rohitwaghchaure
99dfe6c571 Merge pull request #21469 from Alchez/v12-update-lead-contact
fix: update lead if contact details are changed (v12)
2020-04-29 22:14:24 +05:30
Saqib Ansari
fd1ab37bc8 chore: validate and warn payment against paid invoices 2020-04-29 15:20:05 +05:30
Rohan Bansal
bd969477b1 fix: AttributeError 2020-04-29 13:09:16 +05:30
Deepesh Garg
a816788039 Merge pull request #21494 from deepeshgarg007/item_wise_sale_purchase_v12
fix: Group by filter fix in item wise sales and purchase register
2020-04-29 12:36:22 +05:30
Deepesh Garg
c099a410c8 fix: Group by filter fix in item wise sales and purchase register 2020-04-29 12:21:52 +05:30
Anurag Mishra
e33c44ae33 fix: Permission issue Employee Tax exemption (#21492) 2020-04-29 12:13:26 +05:30
Marica
4930233bbe Merge branch 'version-12-hotfix' into commonify-warehouse-autofill-hotfix 2020-04-29 11:36:48 +05:30
Deepesh Garg
e383727394 Merge pull request #21487 from rohitwaghchaure/not-able-to-make-payment-request-against-fees-hotfix
fix: payment request not able to make against fees
2020-04-29 09:36:55 +05:30
Rohit Waghchaure
3d2dcd8c59 fix: payment request not able to make against fees 2020-04-29 02:29:43 +05:30
Deepesh Garg
6647f45eb5 Merge pull request #21477 from deepeshgarg007/duplicate_code_v12
fix: Remove duplicate code from accounting dimension
2020-04-28 20:32:36 +05:30
Deepesh Garg
bd9625d150 fix: Remove duplicate code from accounting dimension 2020-04-28 20:26:56 +05:30
marination
c832291bd6 fix: Handle empty child table 2020-04-28 19:23:13 +05:30
Rohan Bansal
7c67c38bc5 fix: update lead if contact details are changed 2020-04-28 16:12:02 +05:30
Rucha Mahabal
8076deb080 Merge pull request #21465 from akurungadam/patch-3
fix: clinical procedure - set stock entry type
2020-04-28 15:37:30 +05:30
Anoop
dd8566ecde fix: clinical procedure - set stock entry type
clinical procedure - complete and consume - set stock entry type to "Material Issue"

report -
https://discuss.erpnext.com/t/cant-complete-and-consume/60927
2020-04-28 14:52:10 +05:30
Marica
fa7d496413 fix: Blanket Order in SO/PO child tables (#21444) 2020-04-28 13:00:51 +05:30
Deepesh Garg
3b8ad79445 Merge pull request #21458 from deepeshgarg007/gross_profit_width_v12
fix: Default column width in Gross profit report
2020-04-28 12:36:00 +05:30
Deepesh Garg
558c3284a0 fix: Default column width in Gross profit report 2020-04-28 12:03:05 +05:30
Nabin Hait
95f7807b78 fix: Income tax slab patch (#21448)
* fix: reload income_tax_slab_other_charges in patch

* fix: reload lower_deduction_certificate in patch
2020-04-28 11:15:57 +05:30
Deepesh Garg
6ece7fe265 Merge pull request #21438 from deepeshgarg007/ewb_bill_error_message_v12
fix: E-Way bill error message
2020-04-27 15:04:45 +05:30
Deepesh Garg
5aa2241439 fix: Test 2020-04-27 14:06:38 +05:30
Deepesh Garg
68d7b77314 fix: Utils messsage cleanup 2020-04-27 11:16:39 +05:30
Deepesh Garg
93e8b5d87e fix: E-way bill fix in List view 2020-04-27 11:15:23 +05:30
Deepesh Garg
6b082b5edb fix: E-way bill fix in sales invoice 2020-04-27 11:15:04 +05:30
Rucha Mahabal
093720b870 fix: add hook for sending appointment reminders in v12 (#21432) 2020-04-27 10:36:11 +05:30
Rucha Mahabal
e1697fd9cc Merge pull request #21429 from akurungadam/patch-2
fix: name 'patient' is not defined
2020-04-27 00:42:39 +05:30
Anoop
c2f952045c fix: name 'patient' is not defined
possible escape while refactoring, fixed in develop added here.

Reported via -
https://discuss.erpnext.com/t/healthcare-outpatient-sms-alert-error/60812
2020-04-27 00:33:26 +05:30
Nabin Hait
2b5bca4ce6 fix: Procurement tracker report (#21422)
* fix: procurement report data was not coming

* fix: leave allocation minor issue
2020-04-26 23:28:54 +05:30
Himanshu
de6f0f7a05 fix: add quality inspection template (#21424) 2020-04-26 23:27:29 +05:30
Anurag Mishra
1f3584b9a8 refactor: employee leave balance report v12 (#21282)
* fix: Employee Balance repor fixes

* refactor: Employee Leave Balance report For Version-12

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-04-26 21:05:09 +05:30
Deepesh Garg
5bfdf0af4d feat: Allow tax withholding category selection at invoice level (#20871)
* feat: Allow tax withholding category selection at invoice level

* fix: Linitng fixes

* feat: TDS calculation using common PAN

* fix: Add provision to deduct Lower TDS in purchase invoice

* fix: Consider only ref docs company while computing TDS

* fix: Default permission fixes

* fix: Add validation for dates in fiscal year

* fix: Undefined variable
2020-04-26 20:10:16 +05:30
rohitwaghchaure
14a50a9403 Merge pull request #21390 from marination/stock-entry-qty-hotfix
fix: Issues on qty trigger in Stock Entry Detail
2020-04-26 18:00:07 +05:30
marination
b724fec6c9 fix: Remove callback outside if condition 2020-04-26 17:18:41 +05:30
Nabin Hait
1d5ea4feee feat: Income tax slab (#21406)
* Feat: Multiple tax as per new taxation rule

* patch:for multiple tax slab, fix: payroll and exemption validation

* Test: Fixture

* feat: income tax slab with other charges and tax exempted deduction components

* fix: added missing init file

* fix: Patch fixed

* fix: Patch fixed

* fix: test fixes

* fix: validate duplicate exemption declaration

* fix: payment entry test case

Co-authored-by: Anurag Mishra <mishranaman123@gmail.com>
2020-04-26 12:37:52 +05:30
Saqib
7fedff260d fix: (ux) set jv voucher type depending on mode of payment (#21412) 2020-04-26 09:41:02 +05:30
rohitwaghchaure
9fc78e44ea Merge pull request #21402 from DeeMysterio/hotfix-si-actual-qty
feat(accounting): show actual qty for warehouse in sales invoice
2020-04-25 01:19:04 +05:30
Diksha Jadhav
be97087d32 feat(accounting): show actual qty for warehouse in sales invoice 2020-04-24 21:09:59 +05:30
Rucha Mahabal
b0f829e541 Merge pull request #21381 from anupamvs/email-camp-end-date-hotfix
fix: set end_date in Email Campaign
2020-04-24 20:44:18 +05:30
Rucha Mahabal
0455a96dcd Merge branch 'version-12-hotfix' into email-camp-end-date-hotfix 2020-04-24 20:04:55 +05:30
Deepesh Garg
d771ba2895 Merge pull request #21398 from nextchamp-saqib/tax-breakup-for-cn-v12
fix: show positive taxes in credit notes
2020-04-24 19:01:46 +05:30
rohitwaghchaure
c8e5b42dba Merge pull request #21395 from nextchamp-saqib/price-rule-fix
fix: rate gets overwritten when pricing rule is set
2020-04-24 16:46:47 +05:30
Saqib Ansari
424dbef139 fix: rate gets overwritten when pricing rule is set 2020-04-24 16:40:03 +05:30
Saqib Ansari
6256ca81b1 fix: show positive taxes in credit notes 2020-04-24 16:01:11 +05:30
marination
fda451f3e3 fix: Issues on qty trigger in Stock Entry Detail 2020-04-23 20:35:18 +05:30
Rucha Mahabal
2307385210 Merge branch 'version-12-hotfix' into email-camp-end-date-hotfix 2020-04-23 19:42:04 +05:30
Deepesh Garg
bd4b5da11b feat: Payment allocation based on payment terms (#20946)
* feat: Payment allocation based on payment terms

* fix: Add desccription for checkbox

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-04-23 16:09:08 +05:30
Anupam K
ef7f9c6ecc Review changes 2020-04-23 13:45:19 +05:30
Anupam K
097c643a59 setting end date in email campaign 2020-04-23 12:29:00 +05:30
Deepesh Garg
dd560d676e fix: Budget against accounting dimensions (#21269)
* fix: Budget warning against custom accounting dimension

* fix: Codacy
2020-04-23 10:35:35 +05:30
rohitwaghchaure
794fd75ca1 fix: bom update cost is not working (#21348)
* fix: bom update cost is not working

* added test case for bom cost
2020-04-23 09:48:31 +05:30
rohitwaghchaure
f49e66e721 fix: BOM stock report (#21377)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-04-23 09:45:26 +05:30
rohitwaghchaure
8fd1e08763 fix: incorrect out value in stock balance due to precision issue (#21378) 2020-04-23 09:44:54 +05:30
marination
c5d108c954 chore: Commonify autofilling warehouses in child tables 2020-04-23 00:38:19 +05:30
rohitwaghchaure
f2c43ca81e fix: patch and validation message to fix target warehouse issue (#21359) 2020-04-22 16:08:36 +05:30
Deepesh Garg
9d6ee99d99 Merge pull request #21368 from scmmishra/cal-report-12
fix: specify column width
2020-04-22 12:03:35 +05:30
Shivam Mishra
0578cf5a73 fix: specify column width 2020-04-22 11:53:18 +05:30
Michelle Alva
499f9198b9 fix: better error message due date (#21366) 2020-04-22 11:37:09 +05:30
Deepesh Garg
4daab871d5 Merge pull request #21354 from anupamvs/error-message-changes-hotfix
fix: Add better error message
2020-04-22 09:28:16 +05:30
Deepesh Garg
17585710b2 Merge pull request #21360 from rohitwaghchaure/fixed-unsupported-operand-type-issue
fix: unsupported operand type issue in pricing rule
2020-04-22 08:43:29 +05:30
Rohit Waghchaure
56e7887511 fix: unsupported operand type issue in pricing rule 2020-04-22 02:45:55 +05:30
Anupam K
08c782709a Better error message 2020-04-21 17:03:56 +05:30
Anupam Kumar
fb20982194 fix: on item change UOM not updated (#21254)
* fix: on item change UOM not updated

* removing uom from js
2020-04-21 12:57:08 +05:30
Marica
9453add3dd fix: Re-order Item Error Email format (#21343)
* fix: Re-order Item Error Email format

* fix: Translated strings
2020-04-21 12:53:17 +05:30
rohitwaghchaure
c62cf98d7e fix: scrap items order not showing correctly in stock entry (#21347) 2020-04-21 11:26:49 +05:30
rohitwaghchaure
ea8e302833 Merge pull request #21339 from scmmishra/issue-list-context-12
fix: filters as dictionary
2020-04-21 01:25:34 +05:30
rohitwaghchaure
5d3fd9dc43 Merge pull request #21344 from rohitwaghchaure/fixed_free_item_qty_hotfix
fix: free item quantity issue
2020-04-21 01:08:13 +05:30
rohitwaghchaure
c9ba147615 Merge pull request #21323 from marination/pick-list-enhance-hotfix
Pick list enhance hotfix
2020-04-21 01:07:50 +05:30
Rohit Waghchaure
7ef57533ec fix: free item quantity issue 2020-04-21 00:19:19 +05:30
gavin
712abe4cd2 Merge pull request #21338 from gavindsouza/tally-migration-fixes-v12
fix: Tally migration
2020-04-20 19:30:40 +05:30
Shivam Mishra
1a93977ef7 fix: filters as dictionary 2020-04-20 13:56:20 +05:30
Gavin D'souza
fc078c1d45 style: removed unused imports and updated formatting 2020-04-20 12:57:59 +05:30
Gavin D'souza
77532b96b8 fix: strip data fields of whitespaces 2020-04-20 12:57:48 +05:30
Gavin D'souza
4171c5ceeb fix(tally-migration): DocType improvement 2020-04-20 12:57:36 +05:30
Gavin D'souza
fa07e0fb9d fix: handle errors in enqueued methods and update status 2020-04-20 12:57:24 +05:30
Raffael Meyer
e80702b6c2 fix(regional): backport DATEV fix (#21281)
* fix: quote nonnumeric values

* fix(DATEV Settings): restrict max length of IDs

* fix: display Columns as Dynamic Link instead of as Data

* fix: add column "Belegfeld 1"

* fix: truncate column Buchungstext to 60 chars

* fix: make header compatible to current DATEV Format 7.00

* fix: column names and descriptions
2020-04-19 20:16:18 +05:30
Nabin Hait
5817adbb64 fix: Valid warehouse in woocommerce syncing and other small fixes (#21332)
* fix: Valid warehouse in woocommerce syncing

* fix: dmall fixes in gross & net profit report

* fix: company is required for getting party details

* fix: None issue while getting raw material rate based on last purchase rate
2020-04-19 19:28:32 +05:30
Anoop
4de4cb055f fix: removed reference to method not in version-12 (#21335)
removed scheduler event incorrectly added in this version.

as reported on discuss -
https://discuss.erpnext.com/t/internal-server-error-and-healthcare-module-missing/60479/6?u=akurungadam
2020-04-19 19:26:31 +05:30
Deepesh Garg
19c841eb64 fix: Total amount field ordering in transactions (#21315) 2020-04-18 22:14:14 +05:30
Deepesh Garg
5f10e0ac26 Merge pull request #21329 from rohitwaghchaure/fixed-account-name-in-gl_print-hotfix
fix: account name not showing in the gl print
2020-04-18 20:41:03 +05:30
Rohit Waghchaure
64bb910015 fix: account name not showing in the gl print 2020-04-18 19:04:20 +05:30
marination
6b7848232c fix: Use reload_doc in patch 2020-04-17 21:49:25 +05:30
marination
b9df3793fb fix: Commonified code and added server side validation 2020-04-17 21:47:58 +05:30
marination
09f95858c0 fix: Added patch to patches.txt 2020-04-17 21:47:41 +05:30
marination
fcd7548220 fix: Pick List Enhancements 2020-04-17 21:45:58 +05:30
Deepesh Garg
b882d7046b Merge pull request #21321 from Mangesh-Khairnar/gl-entry-label-fix
fix: add label to gl entry
2020-04-17 19:59:19 +05:30
Mangesh-Khairnar
b33f82d4e8 fix: add label to gl entry 2020-04-17 19:55:20 +05:30
rohitwaghchaure
cfb00fb887 Merge pull request #21314 from sahil28297/fix_italy_einvoicing_v12_hotfix
fix(patch): reload 'Import Supplier Invoice' doc
2020-04-17 13:29:12 +05:30
Sahil Khan
44f0c077ff fix(patch): reload 'Import Supplier Invoice' doc 2020-04-17 13:15:15 +05:30
Nabin Hait
3b2aa5ead3 fix: requested qty for customer provided item and rate for sales (#21300)
* fix: requested qty for customer provided item and rate for sales

* fix: requested qty for material transfer

* fix: customer provided item can be sales item

* fix: requested qty test cases
2020-04-17 10:52:23 +05:30
rohitwaghchaure
2c045179a3 Merge pull request #21310 from rohitwaghchaure/fixed_timer_issue_version_12_hotfix
fix: job card timer issue
2020-04-17 00:55:50 +05:30
Rohit Waghchaure
da83af1213 fix: job card timer issue 2020-04-17 00:54:20 +05:30
rohitwaghchaure
61fc2d3263 fix: job card time issue (#21306) 2020-04-16 23:57:49 +05:30
rohitwaghchaure
a66be0f5c5 Merge pull request #21295 from nabinhait/b12-7-pre-release-fix1
fix: requested qty calculation and some other small fixes
2020-04-16 19:19:17 +05:30
Nabin Hait
cf1f777ae2 Merge branch 'version-12-hotfix' into b12-7-pre-release-fix1 2020-04-16 19:08:35 +05:30
Deepesh Garg
c7b5309dcd Merge pull request #21105 from nextchamp-saqib/asset-cat-validation-v12
fix: no server side validations for accounts in asset category
2020-04-16 16:25:37 +05:30
Saqib
45d454b14d fix: serial and batch selection from delivery note bug fix (#21292) 2020-04-16 16:21:54 +05:30
Saqib Ansari
f390b8062c fix: incorrect transalation 2020-04-16 16:16:58 +05:30
Nabin Hait
90adf076f3 fix: Made received qty readonly and no-copy 2020-04-16 14:30:26 +05:30
Nabin Hait
2b6942d9ce fix: Made release date mandatory 2020-04-16 14:30:18 +05:30
Nabin Hait
4dca806737 fix: requested qty calculation fix for UOM 2020-04-16 14:28:22 +05:30
Deepesh Garg
3379cac956 Merge branch 'version-12-hotfix' into asset-cat-validation-v12 2020-04-16 11:23:21 +05:30
Deepesh Garg
ed48755a6f Merge pull request #21266 from vishdha/chart_account_hotfix
fix: Chart of account importer UX improved
2020-04-16 11:21:44 +05:30
vishdha
c43e759b87 fix: fix Transalation 2020-04-16 11:12:52 +05:30
rohitwaghchaure
05e9af60bd Merge pull request #21284 from marination/stock-entry-get-items-mr-hotfix
fix: Fetch Material Requests with type Issue as well in Stock Entry via Get Items from
2020-04-16 00:33:15 +05:30
Marica
de9220568e Merge pull request #21286 from nextchamp-saqib/warehouse-fix
fix: warehouse unset when cannot find item warehouse
2020-04-15 23:55:52 +05:30
Saqib Ansari
4879858657 fix: warehouse unset when cannot find item warehouse
* cannot set delivery date when all items gets deleted and new are added
2020-04-15 22:08:12 +05:30
Saqib Ansari
773eb6ce68 fix: pos not accessible without default customer 2020-04-15 22:08:04 +05:30
marination
8e1201d31e fix: Fetch Material Requests with type Issue as well in Stock Entry via Get Items from 2020-04-15 21:25:12 +05:30
rohitwaghchaure
bf401290d1 Merge pull request #21218 from marination/default-item-manufacturer-hotfix
feat: Provision to set Default Item Manufacturer
2020-04-15 16:36:01 +05:30
vishdha
af33f71562 fix: message bold 2020-04-14 17:20:48 +05:30
vishdha
25c26b5904 fix: Chart of account importer UX improved 2020-04-14 17:20:48 +05:30
Saqib Ansari
ae8a0940f5 fix: cannot iterate over dict_keys 2020-04-11 18:12:13 +05:30
Saqib Ansari
de423f8183 Merge branch 'asset-cat-validation-v12' of https://github.com/nextchamp-saqib/erpnext into asset-cat-validation-v12 2020-04-11 18:11:42 +05:30
Nabin Hait
c7bf050e8b Merge branch 'version-12-hotfix' into asset-cat-validation-v12 2020-04-11 10:21:17 +05:30
Saqib Ansari
39b8e150bf fix: travis 2020-04-10 12:39:34 +05:30
marination
849ec84852 feat: Provision to set Default Item Manufacturer
- Is Default checkbox added in Item Manufacturer
- Default Item Manufacturer and Part No fields added to Item Master
- Manufacturer Part No field editable in all child tables with validation
- Manufacturer and Part No auto fetched via get_item_details in child table
2020-04-09 14:50:03 +05:30
Saqib Ansari
de9c73c5cd fix: tests 2020-04-06 12:41:51 +05:30
Saqib Ansari
04201028d1 fix: tests 2020-04-02 22:18:12 +05:30
Saqib Ansari
086e5c4dac fix: no server side validations for accounts in asset category 2020-03-31 18:21:08 +05:30
Saqib Ansari
9578ead7f9 fix: no server side validations for accounts in asset category 2020-03-28 19:27:37 +05:30
407 changed files with 8643 additions and 8450 deletions

14
.github/workflows/docker-release.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
name: Trigger Docker build on release
on:
release:
types: [released]
jobs:
curl:
runs-on: ubuntu-latest
container:
image: alpine:latest
steps:
- name: curl
run: |
apk add curl bash
curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Travis-API-Version: 3" -H "Authorization: token ${{ secrets.TRAVIS_CI_TOKEN }}" -d '{"request":{"branch":"master"}}' https://api.travis-ci.com/repo/frappe%2Ffrappe_docker/requests

View File

@@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
__version__ = '12.8.0'
__version__ = '12.11.0'
def get_default_company(user=None):
'''Get default company for user'''

View File

@@ -159,7 +159,7 @@ def book_deferred_income_or_expense(doc, posting_date=None):
total_days, total_booking_days, account_currency)
make_gl_entries(doc, credit_account, debit_account, against,
amount, base_amount, end_date, project, account_currency, item.cost_center, item.name)
amount, base_amount, end_date, project, account_currency, item.cost_center, item)
if getdate(end_date) < getdate(posting_date) and not last_gl_entry:
_book_deferred_revenue_or_expense(item)
@@ -170,7 +170,7 @@ def book_deferred_income_or_expense(doc, posting_date=None):
_book_deferred_revenue_or_expense(item)
def make_gl_entries(doc, credit_account, debit_account, against,
amount, base_amount, posting_date, project, account_currency, cost_center, voucher_detail_no):
amount, base_amount, posting_date, project, account_currency, cost_center, item):
# GL Entry for crediting the amount in the deferred expense
from erpnext.accounts.general_ledger import make_gl_entries
@@ -184,10 +184,10 @@ def make_gl_entries(doc, credit_account, debit_account, against,
"credit": base_amount,
"credit_in_account_currency": amount,
"cost_center": cost_center,
"voucher_detail_no": voucher_detail_no,
"voucher_detail_no": item.name,
'posting_date': posting_date,
'project': project
}, account_currency)
}, account_currency, item=item)
)
# GL Entry to debit the amount from the expense
gl_entries.append(
@@ -197,10 +197,10 @@ def make_gl_entries(doc, credit_account, debit_account, against,
"debit": base_amount,
"debit_in_account_currency": amount,
"cost_center": cost_center,
"voucher_detail_no": voucher_detail_no,
"voucher_detail_no": item.name,
'posting_date': posting_date,
'project': project
}, account_currency)
}, account_currency, item=item)
)
if gl_entries:

View File

@@ -89,7 +89,7 @@ class Account(NestedSet):
throw(_("Root cannot be edited."), RootNotEditable)
if not self.parent_account and not self.is_group:
frappe.throw(_("Root Account must be a group"))
frappe.throw(_("The root account {0} must be a group").format(frappe.bold(self.name)))
def validate_root_company_and_sync_account_to_children(self):
# ignore validation while creating new compnay or while syncing to child companies
@@ -244,6 +244,8 @@ class Account(NestedSet):
super(Account, self).on_trash(True)
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_parent_account(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""select name from tabAccount
where is_group = 1 and docstatus != 2 and company = %s

View File

@@ -14,6 +14,9 @@ frappe.treeview_settings["Account"] = {
on_change: function() {
var me = frappe.treeview_settings['Account'].treeview;
var company = me.page.fields_dict.company.get_value();
if (!company) {
frappe.throw(__("Please set a Company"));
}
frappe.call({
method: "erpnext.accounts.doctype.account.account.get_root_company",
args: {

View File

@@ -225,7 +225,7 @@ def build_tree_from_json(chart_template, chart_data=None):
account['parent_account'] = parent
account['expandable'] = True if identify_is_group(child) else False
account['value'] = (child.get('account_number') + ' - ' + account_name) \
account['value'] = (cstr(child.get('account_number')).strip() + ' - ' + account_name) \
if child.get('account_number') else account_name
accounts.append(account)
_import_accounts(child, account['value'])

View File

@@ -69,6 +69,7 @@ class TestAccount(unittest.TestCase):
acc.account_name = "Accumulated Depreciation"
acc.parent_account = "Fixed Assets - _TC"
acc.company = "_Test Company"
acc.account_type = "Accumulated Depreciation"
acc.insert()
doc = frappe.get_doc("Account", "Securities and Deposits - _TC")
@@ -149,7 +150,7 @@ def _make_test_records(verbose):
# fixed asset depreciation
["_Test Fixed Asset", "Current Assets", 0, "Fixed Asset", None],
["_Test Accumulated Depreciations", "Current Assets", 0, None, None],
["_Test Accumulated Depreciations", "Current Assets", 0, "Accumulated Depreciation", None],
["_Test Depreciations", "Expenses", 0, None, None],
["_Test Gain/Loss on Asset Disposal", "Expenses", 0, None, None],

View File

@@ -162,9 +162,9 @@ def toggle_disabling(doc):
def get_doctypes_with_dimensions():
doclist = ["GL Entry", "Sales Invoice", "Purchase Invoice", "Payment Entry", "Asset",
"Expense Claim", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note", "Sales Invoice Item", "Purchase Invoice Item",
"Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item", "Purchase Receipt Item",
"Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule",
"Expense Claim", "Expense Claim Detail", "Expense Taxes and Charges", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note",
"Sales Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item",
"Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule",
"Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation",
"Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item", "Subscription",
"Subscription Plan"]
@@ -206,12 +206,13 @@ def get_dimension_filters():
WHERE disabled = 0
""", as_dict=1)
default_dimensions = frappe.db.sql("""SELECT parent, company, default_dimension
FROM `tabAccounting Dimension Detail`""", as_dict=1)
default_dimensions = frappe.db.sql("""SELECT p.fieldname, c.company, c.default_dimension
FROM `tabAccounting Dimension Detail` c, `tabAccounting Dimension` p
WHERE c.parent = p.name""", as_dict=1)
default_dimensions_map = {}
for dimension in default_dimensions:
default_dimensions_map.setdefault(dimension['company'], {})
default_dimensions_map[dimension['company']][dimension['parent']] = dimension['default_dimension']
default_dimensions_map.setdefault(dimension.company, {})
default_dimensions_map[dimension.company][dimension.fieldname] = dimension.default_dimension
return dimension_filters, default_dimensions_map

View File

@@ -1,210 +1,210 @@
{
"creation": "2013-06-24 15:49:57",
"description": "Settings for Accounts",
"doctype": "DocType",
"document_type": "Other",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"auto_accounting_for_stock",
"acc_frozen_upto",
"frozen_accounts_modifier",
"determine_address_tax_category_from",
"over_billing_allowance",
"column_break_4",
"credit_controller",
"check_supplier_invoice_uniqueness",
"make_payment_via_journal_entry",
"unlink_payment_on_cancellation_of_invoice",
"unlink_advance_payment_on_cancelation_of_order",
"book_asset_depreciation_entry_automatically",
"allow_cost_center_in_entry_of_bs_account",
"add_taxes_from_item_tax_template",
"automatically_fetch_payment_terms",
"print_settings",
"show_inclusive_tax_in_print",
"column_break_12",
"show_payment_schedule_in_print",
"currency_exchange_section",
"allow_stale",
"stale_days",
"report_settings_sb",
"use_custom_cash_flow"
],
"fields": [
{
"default": "1",
"description": "If enabled, the system will post accounting entries for inventory automatically.",
"fieldname": "auto_accounting_for_stock",
"fieldtype": "Check",
"hidden": 1,
"in_list_view": 1,
"label": "Make Accounting Entry For Every Stock Movement"
},
{
"description": "Accounting entry frozen up to this date, nobody can do / modify entry except role specified below.",
"fieldname": "acc_frozen_upto",
"fieldtype": "Date",
"in_list_view": 1,
"label": "Accounts Frozen Upto"
},
{
"description": "Users with this role are allowed to set frozen accounts and create / modify accounting entries against frozen accounts",
"fieldname": "frozen_accounts_modifier",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Role Allowed to Set Frozen Accounts & Edit Frozen Entries",
"options": "Role"
},
{
"default": "Billing Address",
"description": "Address used to determine Tax Category in transactions.",
"fieldname": "determine_address_tax_category_from",
"fieldtype": "Select",
"label": "Determine Address Tax Category From",
"options": "Billing Address\nShipping Address"
},
{
"fieldname": "column_break_4",
"fieldtype": "Column Break"
},
{
"description": "Role that is allowed to submit transactions that exceed credit limits set.",
"fieldname": "credit_controller",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Credit Controller",
"options": "Role"
},
{
"fieldname": "check_supplier_invoice_uniqueness",
"fieldtype": "Check",
"label": "Check Supplier Invoice Number Uniqueness"
},
{
"fieldname": "make_payment_via_journal_entry",
"fieldtype": "Check",
"label": "Make Payment via Journal Entry"
},
{
"default": "1",
"fieldname": "unlink_payment_on_cancellation_of_invoice",
"fieldtype": "Check",
"label": "Unlink Payment on Cancellation of Invoice"
},
{
"default": "1",
"fieldname": "unlink_advance_payment_on_cancelation_of_order",
"fieldtype": "Check",
"label": "Unlink Advance Payment on Cancelation of Order"
},
{
"default": "1",
"fieldname": "book_asset_depreciation_entry_automatically",
"fieldtype": "Check",
"label": "Book Asset Depreciation Entry Automatically"
},
{
"fieldname": "allow_cost_center_in_entry_of_bs_account",
"fieldtype": "Check",
"label": "Allow Cost Center In Entry of Balance Sheet Account"
},
{
"default": "1",
"fieldname": "add_taxes_from_item_tax_template",
"fieldtype": "Check",
"label": "Automatically Add Taxes and Charges from Item Tax Template"
},
{
"fieldname": "print_settings",
"fieldtype": "Section Break",
"label": "Print Settings"
},
{
"fieldname": "show_inclusive_tax_in_print",
"fieldtype": "Check",
"label": "Show Inclusive Tax In Print"
},
{
"fieldname": "column_break_12",
"fieldtype": "Column Break"
},
{
"fieldname": "show_payment_schedule_in_print",
"fieldtype": "Check",
"label": "Show Payment Schedule in Print"
},
{
"fieldname": "currency_exchange_section",
"fieldtype": "Section Break",
"label": "Currency Exchange Settings"
},
{
"default": "1",
"fieldname": "allow_stale",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Allow Stale Exchange Rates"
},
{
"default": "1",
"depends_on": "eval:doc.allow_stale==0",
"fieldname": "stale_days",
"fieldtype": "Int",
"label": "Stale Days"
},
{
"fieldname": "report_settings_sb",
"fieldtype": "Section Break",
"label": "Report Settings"
},
{
"default": "0",
"description": "Only select if you have setup Cash Flow Mapper documents",
"fieldname": "use_custom_cash_flow",
"fieldtype": "Check",
"label": "Use Custom Cash Flow Format"
},
{
"fieldname": "automatically_fetch_payment_terms",
"fieldtype": "Check",
"label": "Automatically Fetch Payment Terms"
},
{
"description": "Percentage you are allowed to bill more against the amount ordered. For example: If the order value is $100 for an item and tolerance is set as 10% then you are allowed to bill for $110.",
"fieldname": "over_billing_allowance",
"fieldtype": "Currency",
"label": "Over Billing Allowance (%)"
}
],
"icon": "icon-cog",
"idx": 1,
"issingle": 1,
"modified": "2019-07-04 18:20:55.789946",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "Accounts Manager",
"share": 1,
"write": 1
},
{
"read": 1,
"role": "Sales User"
},
{
"read": 1,
"role": "Purchase User"
}
],
"quick_entry": 1,
"sort_order": "ASC",
"track_changes": 1
"creation": "2013-06-24 15:49:57",
"description": "Settings for Accounts",
"doctype": "DocType",
"document_type": "Other",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"auto_accounting_for_stock",
"acc_frozen_upto",
"frozen_accounts_modifier",
"determine_address_tax_category_from",
"over_billing_allowance",
"column_break_4",
"credit_controller",
"check_supplier_invoice_uniqueness",
"make_payment_via_journal_entry",
"unlink_payment_on_cancellation_of_invoice",
"unlink_advance_payment_on_cancelation_of_order",
"book_asset_depreciation_entry_automatically",
"add_taxes_from_item_tax_template",
"automatically_fetch_payment_terms",
"print_settings",
"show_inclusive_tax_in_print",
"column_break_12",
"show_payment_schedule_in_print",
"currency_exchange_section",
"allow_stale",
"stale_days",
"report_settings_sb",
"use_custom_cash_flow"
],
"fields": [
{
"default": "1",
"description": "If enabled, the system will post accounting entries for inventory automatically.",
"fieldname": "auto_accounting_for_stock",
"fieldtype": "Check",
"hidden": 1,
"in_list_view": 1,
"label": "Make Accounting Entry For Every Stock Movement"
},
{
"description": "Accounting entry frozen up to this date, nobody can do / modify entry except role specified below.",
"fieldname": "acc_frozen_upto",
"fieldtype": "Date",
"in_list_view": 1,
"label": "Accounts Frozen Upto"
},
{
"description": "Users with this role are allowed to set frozen accounts and create / modify accounting entries against frozen accounts",
"fieldname": "frozen_accounts_modifier",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Role Allowed to Set Frozen Accounts & Edit Frozen Entries",
"options": "Role"
},
{
"default": "Billing Address",
"description": "Address used to determine Tax Category in transactions.",
"fieldname": "determine_address_tax_category_from",
"fieldtype": "Select",
"label": "Determine Address Tax Category From",
"options": "Billing Address\nShipping Address"
},
{
"fieldname": "column_break_4",
"fieldtype": "Column Break"
},
{
"description": "Role that is allowed to submit transactions that exceed credit limits set.",
"fieldname": "credit_controller",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Credit Controller",
"options": "Role"
},
{
"default": "0",
"fieldname": "check_supplier_invoice_uniqueness",
"fieldtype": "Check",
"label": "Check Supplier Invoice Number Uniqueness"
},
{
"default": "0",
"fieldname": "make_payment_via_journal_entry",
"fieldtype": "Check",
"label": "Make Payment via Journal Entry"
},
{
"default": "1",
"fieldname": "unlink_payment_on_cancellation_of_invoice",
"fieldtype": "Check",
"label": "Unlink Payment on Cancellation of Invoice"
},
{
"default": "1",
"fieldname": "unlink_advance_payment_on_cancelation_of_order",
"fieldtype": "Check",
"label": "Unlink Advance Payment on Cancelation of Order"
},
{
"default": "1",
"fieldname": "book_asset_depreciation_entry_automatically",
"fieldtype": "Check",
"label": "Book Asset Depreciation Entry Automatically"
},
{
"default": "1",
"fieldname": "add_taxes_from_item_tax_template",
"fieldtype": "Check",
"label": "Automatically Add Taxes and Charges from Item Tax Template"
},
{
"fieldname": "print_settings",
"fieldtype": "Section Break",
"label": "Print Settings"
},
{
"default": "0",
"fieldname": "show_inclusive_tax_in_print",
"fieldtype": "Check",
"label": "Show Inclusive Tax In Print"
},
{
"fieldname": "column_break_12",
"fieldtype": "Column Break"
},
{
"default": "0",
"fieldname": "show_payment_schedule_in_print",
"fieldtype": "Check",
"label": "Show Payment Schedule in Print"
},
{
"fieldname": "currency_exchange_section",
"fieldtype": "Section Break",
"label": "Currency Exchange Settings"
},
{
"default": "1",
"fieldname": "allow_stale",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Allow Stale Exchange Rates"
},
{
"default": "1",
"depends_on": "eval:doc.allow_stale==0",
"fieldname": "stale_days",
"fieldtype": "Int",
"label": "Stale Days"
},
{
"fieldname": "report_settings_sb",
"fieldtype": "Section Break",
"label": "Report Settings"
},
{
"default": "0",
"description": "Only select if you have setup Cash Flow Mapper documents",
"fieldname": "use_custom_cash_flow",
"fieldtype": "Check",
"label": "Use Custom Cash Flow Format"
},
{
"default": "0",
"fieldname": "automatically_fetch_payment_terms",
"fieldtype": "Check",
"label": "Automatically Fetch Payment Terms"
},
{
"description": "Percentage you are allowed to bill more against the amount ordered. For example: If the order value is $100 for an item and tolerance is set as 10% then you are allowed to bill for $110.",
"fieldname": "over_billing_allowance",
"fieldtype": "Currency",
"label": "Over Billing Allowance (%)"
}
],
"icon": "icon-cog",
"idx": 1,
"issingle": 1,
"modified": "2020-03-11 13:09:26.235848",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "Accounts Manager",
"share": 1,
"write": 1
},
{
"read": 1,
"role": "Sales User"
},
{
"read": 1,
"role": "Purchase User"
}
],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "ASC",
"track_changes": 1
}

View File

@@ -20,7 +20,6 @@ class AccountsSettings(Document):
self.validate_stale_days()
self.enable_payment_schedule_in_print()
self.enable_fields_for_cost_center_settings()
def validate_stale_days(self):
if not self.allow_stale and cint(self.stale_days) <= 0:
@@ -33,8 +32,3 @@ class AccountsSettings(Document):
for doctype in ("Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"):
make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check")
make_property_setter(doctype, "payment_schedule", "print_hide", 0 if show_in_print else 1, "Check")
def enable_fields_for_cost_center_settings(self):
show_field = 0 if cint(self.allow_cost_center_in_entry_of_bs_account) else 1
for doctype in ("Sales Invoice", "Purchase Invoice", "Payment Entry"):
make_property_setter(doctype, "cost_center", "hidden", show_field, "Check")

View File

@@ -60,12 +60,13 @@ class BankReconciliation(Document):
""".format(condition=condition), {"account": self.account, "from":self.from_date,
"to": self.to_date, "bank_account": self.bank_account}, as_dict=1)
pos_entries = []
pos_sales_invoices, pos_purchase_invoices = [], []
if self.include_pos_transactions:
pos_entries = frappe.db.sql("""
pos_sales_invoices = frappe.db.sql("""
select
"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit,
si.posting_date, si.debit_to as against_account, sip.clearance_date,
si.posting_date, si.customer as against_account, sip.clearance_date,
account.account_currency, 0 as credit
from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account
where
@@ -75,7 +76,20 @@ class BankReconciliation(Document):
si.posting_date ASC, si.name DESC
""", {"account":self.account, "from":self.from_date, "to":self.to_date}, as_dict=1)
entries = sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
pos_purchase_invoices = frappe.db.sql("""
select
"Purchase Invoice" as payment_document, pi.name as payment_entry, pi.paid_amount as credit,
pi.posting_date, pi.supplier as against_account, pi.clearance_date,
account.account_currency, 0 as debit
from `tabPurchase Invoice` pi, `tabAccount` account
where
pi.cash_bank_account=%(account)s and pi.docstatus=1 and account.name = pi.cash_bank_account
and pi.posting_date >= %(from)s and pi.posting_date <= %(to)s
order by
pi.posting_date ASC, pi.name DESC
""", {"account": self.account, "from": self.from_date, "to": self.to_date}, as_dict=1)
entries = sorted(list(payment_entries) + list(journal_entries + list(pos_sales_invoices) + list(pos_purchase_invoices)),
key=lambda k: k['posting_date'] or getdate(nowdate()))
self.set('payment_entries', [])

View File

@@ -9,6 +9,7 @@ from frappe.utils import flt, getdate, add_months, get_last_day, fmt_money, nowd
from frappe.model.naming import make_autoname
from erpnext.accounts.utils import get_fiscal_year
from frappe.model.document import Document
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
class BudgetError(frappe.ValidationError): pass
class DuplicateBudgetError(frappe.ValidationError): pass
@@ -98,30 +99,32 @@ def validate_expense_against_budget(args):
if not (args.get('account') and args.get('cost_center')) and args.item_code:
args.cost_center, args.account = get_item_details(args)
if not (args.cost_center or args.project) and not args.account:
if not args.account:
return
for budget_against in ['project', 'cost_center']:
for budget_against in ['project', 'cost_center'] + get_accounting_dimensions():
if (args.get(budget_against) and args.account
and frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"})):
if args.project and budget_against == 'project':
condition = "and b.project=%s" % frappe.db.escape(args.project)
args.budget_against_field = "Project"
doctype = frappe.unscrub(budget_against)
elif args.cost_center and budget_against == 'cost_center':
cc_lft, cc_rgt = frappe.db.get_value("Cost Center", args.cost_center, ["lft", "rgt"])
condition = """and exists(select name from `tabCost Center`
where lft<=%s and rgt>=%s and name=b.cost_center)""" % (cc_lft, cc_rgt)
args.budget_against_field = "Cost Center"
if frappe.get_cached_value('DocType', doctype, 'is_tree'):
lft, rgt = frappe.db.get_value(doctype, args.get(budget_against), ["lft", "rgt"])
condition = """and exists(select name from `tab%s`
where lft<=%s and rgt>=%s and name=b.%s)""" % (doctype, lft, rgt, budget_against) #nosec
args.is_tree = True
else:
condition = "and b.%s=%s" % (budget_against, frappe.db.escape(args.get(budget_against)))
args.is_tree = False
args.budget_against = args.get(budget_against)
args.budget_against_field = budget_against
args.budget_against_doctype = doctype
budget_records = frappe.db.sql("""
select
b.{budget_against_field} as budget_against, ba.budget_amount, b.monthly_distribution,
ifnull(b.applicable_on_material_request, 0) as for_material_request,
ifnull(applicable_on_purchase_order,0) as for_purchase_order,
ifnull(applicable_on_purchase_order, 0) as for_purchase_order,
ifnull(applicable_on_booking_actual_expenses,0) as for_actual_expenses,
b.action_if_annual_budget_exceeded, b.action_if_accumulated_monthly_budget_exceeded,
b.action_if_annual_budget_exceeded_on_mr, b.action_if_accumulated_monthly_budget_exceeded_on_mr,
@@ -132,9 +135,7 @@ def validate_expense_against_budget(args):
b.name=ba.parent and b.fiscal_year=%s
and ba.account=%s and b.docstatus=1
{condition}
""".format(condition=condition,
budget_against_field=frappe.scrub(args.get("budget_against_field"))),
(args.fiscal_year, args.account), as_dict=True)
""".format(condition=condition, budget_against_field=budget_against), (args.fiscal_year, args.account), as_dict=True) #nosec
if budget_records:
validate_budget_records(args, budget_records)
@@ -230,10 +231,10 @@ def get_ordered_amount(args, budget):
def get_other_condition(args, budget, for_doc):
condition = "expense_account = '%s'" % (args.expense_account)
budget_against_field = frappe.scrub(args.get("budget_against_field"))
budget_against_field = args.get("budget_against_field")
if budget_against_field and args.get(budget_against_field):
condition += " and child.%s = '%s'" %(budget_against_field, args.get(budget_against_field))
condition += " and child.%s = '%s'" % (budget_against_field, args.get(budget_against_field))
if args.get('fiscal_year'):
date_field = 'schedule_date' if for_doc == 'Material Request' else 'transaction_date'
@@ -246,19 +247,30 @@ def get_other_condition(args, budget, for_doc):
return condition
def get_actual_expense(args):
if not args.budget_against_doctype:
args.budget_against_doctype = frappe.unscrub(args.budget_against_field)
budget_against_field = args.get('budget_against_field')
condition1 = " and gle.posting_date <= %(month_end_date)s" \
if args.get("month_end_date") else ""
if args.budget_against_field == "Cost Center":
lft_rgt = frappe.db.get_value(args.budget_against_field,
args.budget_against, ["lft", "rgt"], as_dict=1)
if args.is_tree:
lft_rgt = frappe.db.get_value(args.budget_against_doctype,
args.get(budget_against_field), ["lft", "rgt"], as_dict=1)
args.update(lft_rgt)
condition2 = """and exists(select name from `tabCost Center`
where lft>=%(lft)s and rgt<=%(rgt)s and name=gle.cost_center)"""
elif args.budget_against_field == "Project":
condition2 = "and exists(select name from `tabProject` where name=gle.project and gle.project = %(budget_against)s)"
condition2 = """and exists(select name from `tab{doctype}`
where lft>=%(lft)s and rgt<=%(rgt)s
and name=gle.{budget_against_field})""".format(doctype=args.budget_against_doctype, #nosec
budget_against_field=budget_against_field)
else:
condition2 = """and exists(select name from `tab{doctype}`
where name=gle.{budget_against} and
gle.{budget_against} = %({budget_against})s)""".format(doctype=args.budget_against_doctype,
budget_against = budget_against_field)
return flt(frappe.db.sql("""
amount = flt(frappe.db.sql("""
select sum(gle.debit) - sum(gle.credit)
from `tabGL Entry` gle
where gle.account=%(account)s
@@ -267,7 +279,9 @@ def get_actual_expense(args):
and gle.company=%(company)s
and gle.docstatus=1
{condition2}
""".format(condition1=condition1, condition2=condition2), (args))[0][0])
""".format(condition1=condition1, condition2=condition2), (args))[0][0]) #nosec
return amount
def get_accumulated_monthly_budget(monthly_distribution, posting_date, fiscal_year, annual_budget):
distribution = {}

View File

@@ -13,7 +13,7 @@ from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journ
class TestBudget(unittest.TestCase):
def test_monthly_budget_crossed_ignore(self):
set_total_expense_zero("2013-02-28", "Cost Center")
set_total_expense_zero("2013-02-28", "cost_center")
budget = make_budget(budget_against="Cost Center")
@@ -26,7 +26,7 @@ class TestBudget(unittest.TestCase):
budget.cancel()
def test_monthly_budget_crossed_stop1(self):
set_total_expense_zero("2013-02-28", "Cost Center")
set_total_expense_zero("2013-02-28", "cost_center")
budget = make_budget(budget_against="Cost Center")
@@ -41,7 +41,7 @@ class TestBudget(unittest.TestCase):
budget.cancel()
def test_exception_approver_role(self):
set_total_expense_zero("2013-02-28", "Cost Center")
set_total_expense_zero("2013-02-28", "cost_center")
budget = make_budget(budget_against="Cost Center")
@@ -114,7 +114,7 @@ class TestBudget(unittest.TestCase):
budget.cancel()
def test_monthly_budget_crossed_stop2(self):
set_total_expense_zero("2013-02-28", "Project")
set_total_expense_zero("2013-02-28", "project")
budget = make_budget(budget_against="Project")
@@ -129,7 +129,7 @@ class TestBudget(unittest.TestCase):
budget.cancel()
def test_yearly_budget_crossed_stop1(self):
set_total_expense_zero("2013-02-28", "Cost Center")
set_total_expense_zero("2013-02-28", "cost_center")
budget = make_budget(budget_against="Cost Center")
@@ -141,7 +141,7 @@ class TestBudget(unittest.TestCase):
budget.cancel()
def test_yearly_budget_crossed_stop2(self):
set_total_expense_zero("2013-02-28", "Project")
set_total_expense_zero("2013-02-28", "project")
budget = make_budget(budget_against="Project")
@@ -153,7 +153,7 @@ class TestBudget(unittest.TestCase):
budget.cancel()
def test_monthly_budget_on_cancellation1(self):
set_total_expense_zero("2013-02-28", "Cost Center")
set_total_expense_zero("2013-02-28", "cost_center")
budget = make_budget(budget_against="Cost Center")
@@ -177,7 +177,7 @@ class TestBudget(unittest.TestCase):
budget.cancel()
def test_monthly_budget_on_cancellation2(self):
set_total_expense_zero("2013-02-28", "Project")
set_total_expense_zero("2013-02-28", "project")
budget = make_budget(budget_against="Project")
@@ -201,8 +201,8 @@ class TestBudget(unittest.TestCase):
budget.cancel()
def test_monthly_budget_against_group_cost_center(self):
set_total_expense_zero("2013-02-28", "Cost Center")
set_total_expense_zero("2013-02-28", "Cost Center", "_Test Cost Center 2 - _TC")
set_total_expense_zero("2013-02-28", "cost_center")
set_total_expense_zero("2013-02-28", "cost_center", "_Test Cost Center 2 - _TC")
budget = make_budget(budget_against="Cost Center", cost_center="_Test Company - _TC")
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
@@ -241,25 +241,30 @@ class TestBudget(unittest.TestCase):
def set_total_expense_zero(posting_date, budget_against_field=None, budget_against_CC=None):
if budget_against_field == "Project":
if budget_against_field == "project":
budget_against = "_Test Project"
else:
budget_against = budget_against_CC or "_Test Cost Center - _TC"
existing_expense = get_actual_expense(frappe._dict({
args = frappe._dict({
"account": "_Test Account Cost for Goods Sold - _TC",
"cost_center": "_Test Cost Center - _TC",
"monthly_end_date": posting_date,
"company": "_Test Company",
"fiscal_year": "_Test Fiscal Year 2013",
"budget_against_field": budget_against_field,
"budget_against": budget_against
}))
})
if not args.get(budget_against_field):
args[budget_against_field] = budget_against
existing_expense = get_actual_expense(args)
if existing_expense:
if budget_against_field == "Cost Center":
if budget_against_field == "cost_center":
make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Bank - _TC", -existing_expense, "_Test Cost Center - _TC", posting_date="2013-02-28", submit=True)
elif budget_against_field == "Project":
elif budget_against_field == "project":
make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Bank - _TC", -existing_expense, "_Test Cost Center - _TC", submit=True, project="_Test Project", posting_date="2013-02-28")

View File

@@ -17,17 +17,60 @@ frappe.ui.form.on('Chart of Accounts Importer', {
if (frm.page && frm.page.show_import_button) {
create_import_button(frm);
}
},
// show download template button when company is properly selected
if(frm.doc.company) {
// download the csv template file
frm.add_custom_button(__("Download template"), function () {
let get_template_url = 'erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.download_template';
open_url_post(frappe.request.url, { cmd: get_template_url, doctype: frm.doc.doctype });
});
} else {
frm.set_value("import_file", "");
}
download_template: function(frm) {
var d = new frappe.ui.Dialog({
title: __("Download Template"),
fields: [
{
label : "File Type",
fieldname: "file_type",
fieldtype: "Select",
reqd: 1,
options: ["Excel", "CSV"]
},
{
label: "Template Type",
fieldname: "template_type",
fieldtype: "Select",
reqd: 1,
options: ["Sample Template", "Blank Template"],
change: () => {
let template_type = d.get_value('template_type');
if (template_type === "Sample Template") {
d.set_df_property('template_type', 'description',
`The Sample Template contains all the required accounts pre filled in the template.
You can add more accounts or change existing accounts in the template as per your choice.`);
} else {
d.set_df_property('template_type', 'description',
`The Blank Template contains just the account type and root type required to build the Chart
of Accounts. Please enter the account names and add more rows as per your requirement.`);
}
}
}
],
primary_action: function() {
var data = d.get_values();
if (!data.template_type) {
frappe.throw(__('Please select <b>Template Type</b> to download template'));
}
open_url_post(
'/api/method/erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.download_template',
{
file_type: data.file_type,
template_type: data.template_type
}
);
d.hide();
},
primary_action_label: __('Download')
});
d.show();
},
import_file: function (frm) {
@@ -41,21 +84,24 @@ frappe.ui.form.on('Chart of Accounts Importer', {
},
company: function (frm) {
// validate that no Gl Entry record for the company exists.
frappe.call({
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.validate_company",
args: {
company: frm.doc.company
},
callback: function(r) {
if(r.message===false) {
frm.set_value("company", "");
frappe.throw(__("Transactions against the company already exist! "));
} else {
frm.trigger("refresh");
if (frm.doc.company) {
// validate that no Gl Entry record for the company exists.
frappe.call({
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.validate_company",
args: {
company: frm.doc.company
},
callback: function(r) {
if(r.message===false) {
frm.set_value("company", "");
frappe.throw(__(`Transactions against the company already exist!
Chart Of accounts can be imported for company with no transactions`));
} else {
frm.trigger("refresh");
}
}
}
});
});
}
}
});
@@ -77,7 +123,7 @@ var validate_csv_data = function(frm) {
};
var create_import_button = function(frm) {
frm.page.set_primary_action(__("Start Import"), function () {
frm.page.set_primary_action(__("Import"), function () {
frappe.call({
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.import_coa",
args: {
@@ -118,7 +164,8 @@ var generate_tree_preview = function(frm) {
args: {
file_name: frm.doc.import_file,
parent: parent,
doctype: 'Chart of Accounts Importer'
doctype: 'Chart of Accounts Importer',
file_type: frm.doc.file_type
},
onclick: function(node) {
parent = node.value;

View File

@@ -1,226 +1,71 @@
{
"allow_copy": 1,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2019-02-01 12:24:34.761380",
"custom": 0,
"actions": [],
"allow_copy": 1,
"creation": "2019-02-01 12:24:34.761380",
"description": "Import Chart of Accounts from a csv file",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Other",
"editable_grid": 1,
"engine": "InnoDB",
"doctype": "DocType",
"document_type": "Other",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"company",
"download_template",
"import_file",
"chart_preview",
"chart_tree"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Company",
"length": 0,
"no_copy": 0,
"options": "Company",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "company",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Company",
"options": "Company"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "import_file_section",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"depends_on": "company",
"fieldname": "import_file",
"fieldtype": "Attach",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Attach custom Chart of Accounts file",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"label": "Attach custom Chart of Accounts file"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "chart_preview",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Chart Preview",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldtype": "Section Break",
"label": "Chart Preview"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "chart_tree",
"fieldtype": "HTML",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Chart Tree",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"label": "Chart Tree"
},
{
"depends_on": "company",
"fieldname": "download_template",
"fieldtype": "Button",
"label": "Download Template"
}
],
"has_web_view": 0,
"hide_heading": 1,
"hide_toolbar": 1,
"idx": 0,
"image_view": 0,
"in_create": 1,
"is_submittable": 0,
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2019-02-04 23:10:30.136807",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Chart of Accounts Importer",
"name_case": "",
"owner": "Administrator",
],
"hide_toolbar": 1,
"in_create": 1,
"issingle": 1,
"links": [],
"modified": "2020-02-28 08:49:11.422846",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Chart of Accounts Importer",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"create": 1,
"read": 1,
"role": "Accounts Manager",
"share": 1,
"write": 1
}
],
"quick_entry": 1,
"read_only": 1,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "",
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0,
"track_views": 0
],
"quick_entry": 1,
"read_only": 1,
"sort_field": "modified",
"sort_order": "DESC"
}

View File

@@ -4,18 +4,28 @@
from __future__ import unicode_literals
from functools import reduce
import frappe, csv
import frappe, csv, os
from frappe import _
from frappe.utils import cstr
from frappe.utils import cstr, cint
from frappe.model.document import Document
from frappe.utils.csvutils import UnicodeWriter
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts, build_tree_from_json
from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file, read_xls_file_from_attached_file
class ChartofAccountsImporter(Document):
pass
@frappe.whitelist()
def validate_company(company):
parent_company, allow_account_creation_against_child_company = frappe.db.get_value('Company',
{'name': company}, ['parent_company',
'allow_account_creation_against_child_company'])
if parent_company and (not allow_account_creation_against_child_company):
frappe.throw(_("""{0} is a child company. Please import accounts against parent company
or enable {1} in company master""").format(frappe.bold(company),
frappe.bold('Allow Account Creation Against Child Company')), title='Wrong Company')
if frappe.db.get_all('GL Entry', {"company": company}, "name", limit=1):
return False
@@ -25,42 +35,85 @@ def import_coa(file_name, company):
unset_existing_data(company)
# create accounts
forest = build_forest(generate_data_from_csv(file_name))
file_doc, extension = get_file(file_name)
if extension == 'csv':
data = generate_data_from_csv(file_doc)
else:
data = generate_data_from_excel(file_doc, extension)
forest = build_forest(data)
create_charts(company, custom_chart=forest)
# trigger on_update for company to reset default accounts
set_default_accounts(company)
def generate_data_from_csv(file_name, as_dict=False):
''' read csv file and return the generated nested tree '''
if not file_name.endswith('.csv'):
frappe.throw("Only CSV files can be used to for importing data. Please check the file format you are trying to upload")
def get_file(file_name):
file_doc = frappe.get_doc("File", {"file_url": file_name})
parts = file_doc.get_extension()
extension = parts[1]
extension = extension.lstrip(".")
if extension not in ('csv', 'xlsx', 'xls'):
frappe.throw("Only CSV and Excel files can be used to for importing data. Please check the file format you are trying to upload")
return file_doc, extension
def generate_data_from_csv(file_doc, as_dict=False):
''' read csv file and return the generated nested tree '''
file_doc = frappe.get_doc('File', {"file_url": file_name})
file_path = file_doc.get_full_path()
data = []
with open(file_path, 'r') as in_file:
csv_reader = list(csv.reader(in_file))
headers = csv_reader[1][1:]
del csv_reader[0:2] # delete top row and headers row
headers = csv_reader[0]
del csv_reader[0] # delete top row and headers row
for row in csv_reader:
if as_dict:
data.append({frappe.scrub(header): row[index+1] for index, header in enumerate(headers)})
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
else:
if not row[2]: row[2] = row[1]
data.append(row[1:])
if not row[1]: row[1] = row[0]
data.append(row)
# convert csv data
return data
def generate_data_from_excel(file_doc, extension, as_dict=False):
content = file_doc.get_content()
if extension == "xlsx":
rows = read_xlsx_file_from_attached_file(fcontent=content)
elif extension == "xls":
rows = read_xls_file_from_attached_file(content)
data = []
headers = rows[0]
del rows[0]
for row in rows:
if as_dict:
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
else:
if not row[1]: row[1] = row[0]
data.append(row)
return data
@frappe.whitelist()
def get_coa(doctype, parent, is_root=False, file_name=None):
''' called by tree view (to fetch node's children) '''
file_doc, extension = get_file(file_name)
parent = None if parent==_('All Accounts') else parent
forest = build_forest(generate_data_from_csv(file_name))
if extension == 'csv':
data = generate_data_from_csv(file_doc)
else:
data = generate_data_from_excel(file_doc, extension)
forest = build_forest(data)
accounts = build_tree_from_json("", chart_data=forest) # returns alist of dict in a tree render-able form
# filter out to show data for the selected node only
@@ -91,15 +144,18 @@ def build_forest(data):
# returns the path of any node in list format
def return_parent(data, child):
from frappe import _
for row in data:
account_name, parent_account = row[0:2]
if parent_account == account_name == child:
return [parent_account]
elif account_name == child:
parent_account_list = return_parent(data, parent_account)
if not parent_account_list and parent_account:
frappe.throw(_("The parent account {0} does not exists")
.format(parent_account))
if not parent_account_list:
frappe.throw(_("The parent account {0} does not exists in the uploaded template").format(
frappe.bold(parent_account)))
return [child] + parent_account_list
charts_map, paths = {}, []
@@ -114,7 +170,7 @@ def build_forest(data):
error_messages.append("Row {0}: Please enter Account Name".format(line_no))
charts_map[account_name] = {}
if is_group == 1: charts_map[account_name]["is_group"] = is_group
if cint(is_group) == 1: charts_map[account_name]["is_group"] = is_group
if account_type: charts_map[account_name]["account_type"] = account_type
if root_type: charts_map[account_name]["root_type"] = root_type
if account_number: charts_map[account_name]["account_number"] = account_number
@@ -132,24 +188,94 @@ def build_forest(data):
return out
def build_response_as_excel(writer):
filename = frappe.generate_hash("", 10)
with open(filename, 'wb') as f:
f.write(cstr(writer.getvalue()).encode('utf-8'))
f = open(filename)
reader = csv.reader(f)
from frappe.utils.xlsxutils import make_xlsx
xlsx_file = make_xlsx(reader, "Chart Of Accounts Importer Template")
f.close()
os.remove(filename)
# write out response as a xlsx type
frappe.response['filename'] = 'coa_importer_template.xlsx'
frappe.response['filecontent'] = xlsx_file.getvalue()
frappe.response['type'] = 'binary'
@frappe.whitelist()
def download_template():
def download_template(file_type, template_type):
data = frappe._dict(frappe.local.form_dict)
writer = get_template(template_type)
if file_type == 'CSV':
# download csv file
frappe.response['result'] = cstr(writer.getvalue())
frappe.response['type'] = 'csv'
frappe.response['doctype'] = 'Chart of Accounts Importer'
else:
build_response_as_excel(writer)
def get_template(template_type):
fields = ["Account Name", "Parent Account", "Account Number", "Is Group", "Account Type", "Root Type"]
writer = UnicodeWriter()
writer.writerow(fields)
writer.writerow([_('Chart of Accounts Template')])
writer.writerow([_("Column Labels : ")] + fields)
writer.writerow([_("Start entering data from here : ")])
if template_type == 'Blank Template':
for root_type in get_root_types():
writer.writerow(['', '', '', 1, '', root_type])
for account in get_mandatory_group_accounts():
writer.writerow(['', '', '', 1, account, "Asset"])
for account_type in get_mandatory_account_types():
writer.writerow(['', '', '', 0, account_type.get('account_type'), account_type.get('root_type')])
else:
writer = get_sample_template(writer)
return writer
def get_sample_template(writer):
template = [
["Application Of Funds(Assets)", "", "", 1, "", "Asset"],
["Sources Of Funds(Liabilities)", "", "", 1, "", "Liability"],
["Equity", "", "", 1, "", "Equity"],
["Expenses", "", "", 1, "", "Expense"],
["Income", "", "", 1, "", "Income"],
["Bank Accounts", "Application Of Funds(Assets)", "", 1, "Bank", "Asset"],
["Cash In Hand", "Application Of Funds(Assets)", "", 1, "Cash", "Asset"],
["Stock Assets", "Application Of Funds(Assets)", "", 1, "Stock", "Asset"],
["Cost Of Goods Sold", "Expenses", "", 0, "Cost of Goods Sold", "Expense"],
["Asset Depreciation", "Expenses", "", 0, "Depreciation", "Expense"],
["Fixed Assets", "Application Of Funds(Assets)", "", 0, "Fixed Asset", "Asset"],
["Accounts Payable", "Sources Of Funds(Liabilities)", "", 0, "Payable", "Liability"],
["Accounts Receivable", "Application Of Funds(Assets)", "", 1, "Receivable", "Asset"],
["Stock Expenses", "Expenses", "", 0, "Stock Adjustment", "Expense"],
["Sample Bank", "Bank Accounts", "", 0, "Bank", "Asset"],
["Cash", "Cash In Hand", "", 0, "Cash", "Asset"],
["Stores", "Stock Assets", "", 0, "Stock", "Asset"],
]
for row in template:
writer.writerow(row)
return writer
# download csv file
frappe.response['result'] = cstr(writer.getvalue())
frappe.response['type'] = 'csv'
frappe.response['doctype'] = data.get('doctype')
@frappe.whitelist()
def validate_accounts(file_name):
accounts = generate_data_from_csv(file_name, as_dict=True)
file_doc, extension = get_file(file_name)
if extension == 'csv':
accounts = generate_data_from_csv(file_doc, as_dict=True)
else:
accounts = generate_data_from_excel(file_doc, extension, as_dict=True)
accounts_dict = {}
for account in accounts:
@@ -174,12 +300,38 @@ def validate_root(accounts):
for account in roots:
if not account.get("root_type") and account.get("account_name"):
error_messages.append("Please enter Root Type for account- {0}".format(account.get("account_name")))
elif account.get("root_type") not in ("Asset", "Liability", "Expense", "Income", "Equity") and account.get("account_name"):
elif account.get("root_type") not in get_root_types() and account.get("account_name"):
error_messages.append("Root Type for {0} must be one of the Asset, Liability, Income, Expense and Equity".format(account.get("account_name")))
if error_messages:
return "<br>".join(error_messages)
def get_root_types():
return ('Asset', 'Liability', 'Expense', 'Income', 'Equity')
def get_report_type(root_type):
if root_type in ('Asset', 'Liability', 'Equity'):
return 'Balance Sheet'
else:
return 'Profit and Loss'
def get_mandatory_group_accounts():
return ('Bank', 'Cash', 'Stock')
def get_mandatory_account_types():
return [
{'account_type': 'Cost of Goods Sold', 'root_type': 'Expense'},
{'account_type': 'Depreciation', 'root_type': 'Expense'},
{'account_type': 'Fixed Asset', 'root_type': 'Asset'},
{'account_type': 'Payable', 'root_type': 'Liability'},
{'account_type': 'Receivable', 'root_type': 'Asset'},
{'account_type': 'Stock Adjustment', 'root_type': 'Expense'},
{'account_type': 'Bank', 'root_type': 'Asset'},
{'account_type': 'Cash', 'root_type': 'Asset'},
{'account_type': 'Stock', 'root_type': 'Asset'}
]
def validate_account_types(accounts):
account_types_for_ledger = ["Cost of Goods Sold", "Depreciation", "Fixed Asset", "Payable", "Receivable", "Stock Adjustment"]
account_types = [accounts[d]["account_type"] for d in accounts if not accounts[d]['is_group'] == 1]

View File

@@ -18,7 +18,7 @@ frappe.ui.form.on('Cost Center', {
},
refresh: function(frm) {
if (!frm.is_new()) {
frm.add_custom_button(__('Update Cost Center Number'), function () {
frm.add_custom_button(__('Update Cost Center Name / Number'), function () {
frm.trigger("update_cost_center_number");
});
}
@@ -47,35 +47,51 @@ frappe.ui.form.on('Cost Center', {
},
update_cost_center_number: function(frm) {
var d = new frappe.ui.Dialog({
title: __('Update Cost Center Number'),
title: __('Update Cost Center Name / Number'),
fields: [
{
"label": 'Cost Center Number',
"label": "Cost Center Name",
"fieldname": "cost_center_name",
"fieldtype": "Data",
"reqd": 1,
"default": frm.doc.cost_center_name
},
{
"label": "Cost Center Number",
"fieldname": "cost_center_number",
"fieldtype": "Data",
"reqd": 1
"default": frm.doc.cost_center_number
},
{
"label": __("Merge with existing"),
"fieldname": "merge",
"fieldtype": "Check",
"default": 0
}
],
primary_action: function() {
var data = d.get_values();
if(data.cost_center_number === frm.doc.cost_center_number) {
if(data.cost_center_name === frm.doc.cost_center_name && data.cost_center_number === frm.doc.cost_center_number) {
d.hide();
return;
}
frappe.dom.freeze();
frappe.call({
method: "erpnext.accounts.utils.update_number_field",
method: "erpnext.accounts.utils.update_cost_center",
args: {
doctype_name: frm.doc.doctype,
name: frm.doc.name,
field_name: d.fields[0].fieldname,
number_value: data.cost_center_number,
company: frm.doc.company
docname: frm.doc.name,
cost_center_name: data.cost_center_name,
cost_center_number: cstr(data.cost_center_number),
company: frm.doc.company,
merge: data.merge
},
callback: function(r) {
frappe.dom.unfreeze();
if(!r.exc) {
if(r.message) {
frappe.set_route("Form", "Cost Center", r.message);
} else {
me.frm.set_value("cost_center_name", data.cost_center_name);
me.frm.set_value("cost_center_number", data.cost_center_number);
}
d.hide();

View File

@@ -2,7 +2,6 @@
"actions": [],
"allow_copy": 1,
"allow_import": 1,
"allow_rename": 1,
"creation": "2013-01-23 19:57:17",
"description": "Track separate Income and Expense for product verticals or divisions.",
"doctype": "DocType",
@@ -126,7 +125,7 @@
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2020-03-18 18:26:01.540170",
"modified": "2020-06-12 16:09:30.025214",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Cost Center",

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe, erpnext
from frappe import _
from frappe.utils import flt, fmt_money, getdate, formatdate
from frappe.utils import flt, fmt_money, getdate, formatdate, cint
from frappe.model.document import Document
from frappe.model.naming import set_name_from_naming_options
from frappe.model.meta import get_field_precision
@@ -75,12 +75,6 @@ class GLEntry(Document):
if not self.cost_center and self.voucher_type != 'Period Closing Voucher':
frappe.throw(_("{0} {1}: Cost Center is required for 'Profit and Loss' account {2}. Please set up a default Cost Center for the Company.")
.format(self.voucher_type, self.voucher_no, self.account))
else:
from erpnext.accounts.utils import get_allow_cost_center_in_entry_of_bs_account
if not get_allow_cost_center_in_entry_of_bs_account() and self.cost_center:
self.cost_center = None
if self.project:
self.project = None
def validate_dimensions_for_pl_and_bs(self):
@@ -115,8 +109,8 @@ class GLEntry(Document):
from tabAccount where name=%s""", self.account, as_dict=1)[0]
if ret.is_group==1:
frappe.throw(_("{0} {1}: Account {2} cannot be a Group")
.format(self.voucher_type, self.voucher_no, self.account))
frappe.throw(_('''{0} {1}: Account {2} is a Group Account and group accounts cannot be used in
transactions''').format(self.voucher_type, self.voucher_no, self.account))
if ret.docstatus==2:
frappe.throw(_("{0} {1}: Account {2} is inactive")
@@ -137,10 +131,17 @@ class GLEntry(Document):
return self.cost_center_company[self.cost_center]
def _check_is_group():
return cint(frappe.get_cached_value('Cost Center', self.cost_center, 'is_group'))
if self.cost_center and _get_cost_center_company() != self.company:
frappe.throw(_("{0} {1}: Cost Center {2} does not belong to Company {3}")
.format(self.voucher_type, self.voucher_no, self.cost_center, self.company))
if self.cost_center and _check_is_group():
frappe.throw(_("""{0} {1}: Cost Center {2} is a group cost center and group cost centers cannot
be used in transactions""").format(self.voucher_type, self.voucher_no, frappe.bold(self.cost_center)))
def validate_party(self):
validate_party_frozen_disabled(self.party_type, self.party)

View File

@@ -3,11 +3,12 @@
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe, json
import frappe, json, erpnext
from frappe import _
from frappe.utils import flt, getdate, nowdate, add_days
from erpnext.controllers.accounts_controller import AccountsController
from erpnext.accounts.general_ledger import make_gl_entries
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
class InvoiceDiscounting(AccountsController):
def validate(self):
@@ -81,10 +82,15 @@ class InvoiceDiscounting(AccountsController):
def make_gl_entries(self):
company_currency = frappe.get_cached_value('Company', self.company, "default_currency")
gl_entries = []
invoice_fields = ["debit_to", "party_account_currency", "conversion_rate", "cost_center"]
accounting_dimensions = get_accounting_dimensions()
invoice_fields.extend(accounting_dimensions)
for d in self.invoices:
inv = frappe.db.get_value("Sales Invoice", d.sales_invoice,
["debit_to", "party_account_currency", "conversion_rate", "cost_center"], as_dict=1)
inv = frappe.db.get_value("Sales Invoice", d.sales_invoice, invoice_fields, as_dict=1)
if d.outstanding_amount:
outstanding_in_company_currency = flt(d.outstanding_amount * inv.conversion_rate,
@@ -102,7 +108,7 @@ class InvoiceDiscounting(AccountsController):
"cost_center": inv.cost_center,
"against_voucher": d.sales_invoice,
"against_voucher_type": "Sales Invoice"
}, inv.party_account_currency))
}, inv.party_account_currency, item=inv))
gl_entries.append(self.get_gl_dict({
"account": self.accounts_receivable_credit,
@@ -115,7 +121,7 @@ class InvoiceDiscounting(AccountsController):
"cost_center": inv.cost_center,
"against_voucher": d.sales_invoice,
"against_voucher_type": "Sales Invoice"
}, ar_credit_account_currency))
}, ar_credit_account_currency, item=inv))
make_gl_entries(gl_entries, cancel=(self.docstatus == 2), update_outstanding='No')
@@ -128,16 +134,19 @@ class InvoiceDiscounting(AccountsController):
je.append("accounts", {
"account": self.bank_account,
"debit_in_account_currency": flt(self.total_amount) - flt(self.bank_charges),
"cost_center": erpnext.get_default_cost_center(self.company)
})
je.append("accounts", {
"account": self.bank_charges_account,
"debit_in_account_currency": flt(self.bank_charges)
"debit_in_account_currency": flt(self.bank_charges),
"cost_center": erpnext.get_default_cost_center(self.company)
})
je.append("accounts", {
"account": self.short_term_loan,
"credit_in_account_currency": flt(self.total_amount),
"cost_center": erpnext.get_default_cost_center(self.company),
"reference_type": "Invoice Discounting",
"reference_name": self.name
})
@@ -145,6 +154,7 @@ class InvoiceDiscounting(AccountsController):
je.append("accounts", {
"account": self.accounts_receivable_discounted,
"debit_in_account_currency": flt(d.outstanding_amount),
"cost_center": erpnext.get_default_cost_center(self.company),
"reference_type": "Invoice Discounting",
"reference_name": self.name,
"party_type": "Customer",
@@ -154,6 +164,7 @@ class InvoiceDiscounting(AccountsController):
je.append("accounts", {
"account": self.accounts_receivable_credit,
"credit_in_account_currency": flt(d.outstanding_amount),
"cost_center": erpnext.get_default_cost_center(self.company),
"reference_type": "Invoice Discounting",
"reference_name": self.name,
"party_type": "Customer",
@@ -171,13 +182,15 @@ class InvoiceDiscounting(AccountsController):
je.append("accounts", {
"account": self.short_term_loan,
"debit_in_account_currency": flt(self.total_amount),
"cost_center": erpnext.get_default_cost_center(self.company),
"reference_type": "Invoice Discounting",
"reference_name": self.name,
})
je.append("accounts", {
"account": self.bank_account,
"credit_in_account_currency": flt(self.total_amount)
"credit_in_account_currency": flt(self.total_amount),
"cost_center": erpnext.get_default_cost_center(self.company)
})
if getdate(self.loan_end_date) > getdate(nowdate()):
@@ -187,6 +200,7 @@ class InvoiceDiscounting(AccountsController):
je.append("accounts", {
"account": self.accounts_receivable_discounted,
"credit_in_account_currency": flt(outstanding_amount),
"cost_center": erpnext.get_default_cost_center(self.company),
"reference_type": "Invoice Discounting",
"reference_name": self.name,
"party_type": "Customer",
@@ -196,6 +210,7 @@ class InvoiceDiscounting(AccountsController):
je.append("accounts", {
"account": self.accounts_receivable_unpaid,
"debit_in_account_currency": flt(outstanding_amount),
"cost_center": erpnext.get_default_cost_center(self.company),
"reference_type": "Invoice Discounting",
"reference_name": self.name,
"party_type": "Customer",

View File

@@ -2,6 +2,7 @@
{
"doctype": "Item Tax Template",
"title": "_Test Account Excise Duty @ 10",
"company": "_Test Company",
"taxes": [
{
"doctype": "Item Tax Template Detail",
@@ -14,6 +15,7 @@
{
"doctype": "Item Tax Template",
"title": "_Test Account Excise Duty @ 12",
"company": "_Test Company",
"taxes": [
{
"doctype": "Item Tax Template Detail",
@@ -26,6 +28,7 @@
{
"doctype": "Item Tax Template",
"title": "_Test Account Excise Duty @ 15",
"company": "_Test Company",
"taxes": [
{
"doctype": "Item Tax Template Detail",
@@ -38,6 +41,7 @@
{
"doctype": "Item Tax Template",
"title": "_Test Account Excise Duty @ 20",
"company": "_Test Company",
"taxes": [
{
"doctype": "Item Tax Template Detail",
@@ -50,6 +54,7 @@
{
"doctype": "Item Tax Template",
"title": "_Test Item Tax Template 1",
"company": "_Test Company",
"taxes": [
{
"doctype": "Item Tax Template Detail",

View File

@@ -561,20 +561,20 @@ class JournalEntry(AccountsController):
if self.write_off_based_on == 'Accounts Receivable':
jd1.party_type = "Customer"
jd1.credit = flt(d.outstanding_amount, self.precision("credit", "accounts"))
jd1.credit_in_account_currency = flt(d.outstanding_amount, self.precision("credit", "accounts"))
jd1.reference_type = "Sales Invoice"
jd1.reference_name = cstr(d.name)
elif self.write_off_based_on == 'Accounts Payable':
jd1.party_type = "Supplier"
jd1.debit = flt(d.outstanding_amount, self.precision("debit", "accounts"))
jd1.debit_in_account_currency = flt(d.outstanding_amount, self.precision("debit", "accounts"))
jd1.reference_type = "Purchase Invoice"
jd1.reference_name = cstr(d.name)
jd2 = self.append('accounts', {})
if self.write_off_based_on == 'Accounts Receivable':
jd2.debit = total
jd2.debit_in_account_currency = total
elif self.write_off_based_on == 'Accounts Payable':
jd2.credit = total
jd2.credit_in_account_currency = total
self.validate_total_debit_and_credit()
@@ -836,13 +836,34 @@ def get_opening_accounts(company):
return [{"account": a, "balance": get_balance_on(a)} for a in accounts]
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_against_jv(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""select jv.name, jv.posting_date, jv.user_remark
from `tabJournal Entry` jv, `tabJournal Entry Account` jv_detail
where jv_detail.parent = jv.name and jv_detail.account = %s and ifnull(jv_detail.party, '') = %s
and (jv_detail.reference_type is null or jv_detail.reference_type = '')
and jv.docstatus = 1 and jv.`{0}` like %s order by jv.name desc limit %s, %s""".format(searchfield),
(filters.get("account"), cstr(filters.get("party")), "%{0}%".format(txt), start, page_len))
if not frappe.db.has_column('Journal Entry', searchfield):
return []
return frappe.db.sql("""
SELECT jv.name, jv.posting_date, jv.user_remark
FROM `tabJournal Entry` jv, `tabJournal Entry Account` jv_detail
WHERE jv_detail.parent = jv.name
AND jv_detail.account = %(account)s
AND IFNULL(jv_detail.party, '') = %(party)s
AND (
jv_detail.reference_type IS NULL
OR jv_detail.reference_type = ''
)
AND jv.docstatus = 1
AND jv.`{0}` LIKE %(txt)s
ORDER BY jv.name DESC
LIMIT %(offset)s, %(limit)s
""".format(searchfield), dict(
account=filters.get("account"),
party=cstr(filters.get("party")),
txt="%{0}%".format(txt),
offset=start,
limit=page_len
)
)
@frappe.whitelist()

View File

@@ -204,11 +204,8 @@ class TestJournalEntry(unittest.TestCase):
self.assertEqual(jv.inter_company_journal_entry_reference, "")
self.assertEqual(jv1.inter_company_journal_entry_reference, "")
def test_jv_for_enable_allow_cost_center_in_entry_of_bs_account(self):
def test_jv_with_cost_centre(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, cost_center = cost_center, save=False)
@@ -237,15 +234,45 @@ class TestJournalEntry(unittest.TestCase):
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_jv_with_project(self):
from erpnext.projects.doctype.project.test_project import make_project
project = make_project({
'project_name': 'Journal Entry Project',
'project_template_name': 'Test Project Template',
'start_date': '2020-01-01'
})
def test_jv_account_and_party_balance_for_enable_allow_cost_center_in_entry_of_bs_account(self):
jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, save=False)
for d in jv.accounts:
d.project = project.project_name
jv.voucher_type = "Bank Entry"
jv.multi_currency = 0
jv.cheque_no = "112233"
jv.cheque_date = nowdate()
jv.insert()
jv.submit()
expected_values = {
"_Test Cash - _TC": {
"project": project.project_name
},
"_Test Bank - _TC": {
"project": project.project_name
}
}
gl_entries = frappe.db.sql("""select account, project, debit, credit
from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s
order by account asc""", jv.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["project"], gle.project)
def test_jv_account_and_party_balance_with_cost_centre(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
from erpnext.accounts.utils import get_balance_on
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, cost_center = cost_center, save=False)
@@ -261,9 +288,6 @@ class TestJournalEntry(unittest.TestCase):
account_balance = get_balance_on(account="_Test Bank - _TC", cost_center=cost_center)
self.assertEqual(expected_account_balance, account_balance)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def make_journal_entry(account1, account2, amount, cost_center=None, posting_date=None, exchange_rate=1, save=True, submit=False, project=None):
if not cost_center:
cost_center = "_Test Cost Center - _TC"

View File

@@ -41,10 +41,16 @@ def get_loyalty_program_details_with_points(customer, loyalty_program=None, expi
loyalty_program = frappe.get_doc("Loyalty Program", loyalty_program)
lp_details.update(get_loyalty_details(customer, loyalty_program.name, expiry_date, company, include_expired_entry))
tier_spent_level = sorted([d.as_dict() for d in loyalty_program.collection_rules],
key=lambda rule:rule.min_spent, reverse=True)
# sort collection rule, first item on list will be lowest min_spent
tier_spent_level = sorted(
[d.as_dict() for d in loyalty_program.collection_rules],
key=lambda rule: rule.min_spent, reverse=False,
)
# looping and apply tier from lowest min_spent
for i, d in enumerate(tier_spent_level):
if i==0 or (lp_details.total_spent+current_transaction_amount) <= d.min_spent:
# if cumulative spend more than min_spent then continue to next tier
if (lp_details.total_spent + current_transaction_amount) >= d.min_spent:
lp_details.tier_name = d.tier_name
lp_details.collection_factor = d.collection_factor
else:

View File

@@ -68,6 +68,7 @@ class TestLoyaltyProgram(unittest.TestCase):
lpe = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_original.name, 'customer': si_original.customer})
customer.load_from_db()
self.assertEqual(si_original.get('loyalty_program'), customer.loyalty_program)
self.assertEqual(lpe.get('loyalty_program_tier'), customer.loyalty_program_tier)
self.assertEqual(lpe.loyalty_points, earned_points)

View File

@@ -68,6 +68,9 @@ class OpeningInvoiceCreationTool(Document):
if not self.company:
frappe.throw(_("Please select the Company"))
company_details = frappe.get_cached_value('Company', self.company,
["default_currency", "default_letter_head"], as_dict=1) or {}
for row in self.invoices:
if not row.qty:
row.qty = 1.0
@@ -99,6 +102,12 @@ class OpeningInvoiceCreationTool(Document):
if not args:
continue
if company_details:
args.update({
"currency": company_details.get("default_currency"),
"letter_head": company_details.get("default_letter_head")
})
doc = frappe.get_doc(args).insert()
doc.submit()
names.append(doc.name)
@@ -172,8 +181,7 @@ class OpeningInvoiceCreationTool(Document):
"due_date": row.due_date,
"posting_date": row.posting_date,
frappe.scrub(party_type): row.party,
"doctype": "Sales Invoice" if self.invoice_type == "Sales" else "Purchase Invoice",
"currency": frappe.get_cached_value('Company', self.company, "default_currency")
"doctype": "Sales Invoice" if self.invoice_type == "Sales" else "Purchase Invoice"
})
accounting_dimension = get_accounting_dimensions()

View File

@@ -25,7 +25,7 @@ frappe.ui.form.on('Payment Entry', {
});
frm.set_query("party_type", function() {
return{
"filters": {
filters: {
"name": ["in", Object.keys(frappe.boot.party_account_types)],
}
}
@@ -33,14 +33,16 @@ frappe.ui.form.on('Payment Entry', {
frm.set_query("party_bank_account", function() {
return {
filters: {
"is_company_account":0
is_company_account: 0,
party_type: frm.doc.party_type,
party: frm.doc.party
}
}
});
frm.set_query("bank_account", function() {
return {
filters: {
"is_company_account":1
is_company_account: 1
}
}
});
@@ -104,6 +106,21 @@ frappe.ui.form.on('Payment Entry', {
};
});
frm.set_query('payment_term', 'references', function(frm, cdt, cdn) {
const child = locals[cdt][cdn];
if (in_list(['Purchase Invoice', 'Sales Invoice'], child.reference_doctype) && child.reference_name) {
let payment_term_list = frappe.get_list('Payment Schedule', {'parent': child.reference_name});
payment_term_list = payment_term_list.map(pt => pt.payment_term);
return {
filters: {
'name': ['in', payment_term_list]
}
}
}
});
frm.set_query("reference_name", "references", function(doc, cdt, cdn) {
const child = locals[cdt][cdn];
const filters = {"docstatus": 1, "company": doc.company};
@@ -272,7 +289,7 @@ frappe.ui.form.on('Payment Entry', {
frm.set_value("contact_email", "");
frm.set_value("contact_person", "");
}
if(frm.doc.payment_type && frm.doc.party_type && frm.doc.party) {
if(frm.doc.payment_type && frm.doc.party_type && frm.doc.party && frm.doc.company) {
if(!frm.doc.posting_date) {
frappe.msgprint(__("Please select Posting Date before selecting Party"))
frm.set_value("party", "");
@@ -311,7 +328,7 @@ frappe.ui.form.on('Payment Entry', {
() => {
frm.set_party_account_based_on_party = false;
if (r.message.bank_account) {
frm.set_value("party_bank_account", r.message.bank_account);
frm.set_value("bank_account", r.message.bank_account);
}
}
]);
@@ -1018,4 +1035,4 @@ frappe.ui.form.on('Payment Entry', {
});
}
},
})
})

View File

@@ -6,7 +6,7 @@ from __future__ import unicode_literals
import frappe, erpnext, json
from frappe import _, scrub, ValidationError
from frappe.utils import flt, comma_or, nowdate, getdate
from erpnext.accounts.utils import get_outstanding_invoices, get_account_currency, get_balance_on, get_allow_cost_center_in_entry_of_bs_account
from erpnext.accounts.utils import get_outstanding_invoices, get_account_currency, get_balance_on
from erpnext.accounts.party import get_party_account
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
from erpnext.setup.utils import get_exchange_rate
@@ -60,6 +60,7 @@ class PaymentEntry(AccountsController):
self.set_remarks()
self.validate_duplicate_entry()
self.validate_allocated_amount()
self.validate_paid_invoices()
self.ensure_supplier_is_not_blocked()
self.set_status()
@@ -71,9 +72,9 @@ class PaymentEntry(AccountsController):
self.update_outstanding_amounts()
self.update_advance_paid()
self.update_expense_claim()
self.update_payment_schedule()
self.set_status()
def on_cancel(self):
self.setup_party_account_field()
self.make_gl_entries(cancel=1)
@@ -81,9 +82,10 @@ class PaymentEntry(AccountsController):
self.update_advance_paid()
self.update_expense_claim()
self.delink_advance_entry_references()
self.update_payment_schedule(cancel=1)
self.set_payment_req_status()
self.set_status()
def set_payment_req_status(self):
from erpnext.accounts.doctype.payment_request.payment_request import update_payment_req_status
update_payment_req_status(self, None)
@@ -94,10 +96,10 @@ class PaymentEntry(AccountsController):
def validate_duplicate_entry(self):
reference_names = []
for d in self.get("references"):
if (d.reference_doctype, d.reference_name) in reference_names:
if (d.reference_doctype, d.reference_name, d.payment_term) in reference_names:
frappe.throw(_("Row #{0}: Duplicate entry in References {1} {2}")
.format(d.idx, d.reference_doctype, d.reference_name))
reference_names.append((d.reference_doctype, d.reference_name))
reference_names.append((d.reference_doctype, d.reference_name, d.payment_term))
def set_bank_account_data(self):
if self.bank_account:
@@ -225,6 +227,8 @@ class PaymentEntry(AccountsController):
valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry")
elif self.party_type == "Employee":
valid_reference_doctypes = ("Expense Claim", "Journal Entry", "Employee Advance")
elif self.party_type == "Shareholder":
valid_reference_doctypes = ("Journal Entry")
for d in self.get("references"):
if not d.allocated_amount:
@@ -264,6 +268,25 @@ class PaymentEntry(AccountsController):
frappe.throw(_("{0} {1} must be submitted")
.format(d.reference_doctype, d.reference_name))
def validate_paid_invoices(self):
no_oustanding_refs = {}
for d in self.get("references"):
if not d.allocated_amount:
continue
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Fees"):
outstanding_amount, is_return = frappe.get_cached_value(d.reference_doctype, d.reference_name, ["outstanding_amount", "is_return"])
if outstanding_amount <= 0 and not is_return:
no_oustanding_refs.setdefault(d.reference_doctype, []).append(d)
for k, v in no_oustanding_refs.items():
frappe.msgprint(_("{} - {} now have {} as they had no outstanding amount left before submitting the Payment Entry.<br><br>\
If this is undesirable please cancel the corresponding Payment Entry.")
.format(k, frappe.bold(", ".join([d.reference_name for d in v])), frappe.bold("negative outstanding amount")),
title=_("Warning"), indicator="orange")
def validate_journal_entry(self):
for d in self.get("references"):
if d.allocated_amount and d.reference_doctype == "Journal Entry":
@@ -285,6 +308,38 @@ class PaymentEntry(AccountsController):
frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry")
.format(d.reference_name, dr_or_cr))
def update_payment_schedule(self, cancel=0):
invoice_payment_amount_map = {}
invoice_paid_amount_map = {}
for reference in self.get('references'):
if reference.payment_term and reference.reference_name:
key = (reference.payment_term, reference.reference_name)
invoice_payment_amount_map.setdefault(key, 0.0)
invoice_payment_amount_map[key] += reference.allocated_amount
if not invoice_paid_amount_map.get(key):
payment_schedule = frappe.get_all('Payment Schedule', filters={'parent': reference.reference_name},
fields=['paid_amount', 'payment_amount', 'payment_term'])
for term in payment_schedule:
invoice_key = (term.payment_term, reference.reference_name)
invoice_paid_amount_map.setdefault(invoice_key, {})
invoice_paid_amount_map[invoice_key]['outstanding'] = term.payment_amount - term.paid_amount
for key, amount in iteritems(invoice_payment_amount_map):
if cancel:
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` - %s
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
else:
outstanding = flt(invoice_paid_amount_map.get(key, {}).get('outstanding'))
if amount > outstanding:
frappe.throw(_('Cannot allocate more than {0} against payment term {1}').format(outstanding, key[0]))
if amount and outstanding:
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` + %s
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
def set_status(self):
if self.docstatus == 2:
self.status = 'Cancelled'
@@ -452,7 +507,7 @@ class PaymentEntry(AccountsController):
"against": against_account,
"account_currency": self.party_account_currency,
"cost_center": self.cost_center
})
}, item=self)
dr_or_cr = "credit" if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit"
@@ -496,7 +551,7 @@ class PaymentEntry(AccountsController):
"credit_in_account_currency": self.paid_amount,
"credit": self.base_paid_amount,
"cost_center": self.cost_center
})
}, item=self)
)
if self.payment_type in ("Receive", "Internal Transfer"):
gl_entries.append(
@@ -507,7 +562,7 @@ class PaymentEntry(AccountsController):
"debit_in_account_currency": self.received_amount,
"debit": self.base_received_amount,
"cost_center": self.cost_center
})
}, item=self)
)
def add_deductions_gl_entries(self, gl_entries):
@@ -602,7 +657,7 @@ def get_outstanding_reference_documents(args):
.format(frappe.db.escape(args["voucher_type"]), frappe.db.escape(args["voucher_no"]))
# Add cost center condition
if args.get("cost_center") and get_allow_cost_center_in_entry_of_bs_account():
if args.get("cost_center"):
condition += " and cost_center='%s'" % args.get("cost_center")
date_fields_dict = {
@@ -1012,15 +1067,22 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
if doc.doctype == "Purchase Invoice" and doc.invoice_is_blocked():
frappe.msgprint(_('{0} is on hold till {1}'.format(doc.name, doc.release_date)))
else:
pe.append("references", {
'reference_doctype': dt,
'reference_name': dn,
"bill_no": doc.get("bill_no"),
"due_date": doc.get("due_date"),
'total_amount': grand_total,
'outstanding_amount': outstanding_amount,
'allocated_amount': outstanding_amount
})
if (doc.doctype in ('Sales Invoice', 'Purchase Invoice')
and frappe.get_value('Payment Terms Template',
{'name': doc.payment_terms_template}, 'allocate_payment_based_on_payment_terms')):
for reference in get_reference_as_per_payment_terms(doc.payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
pe.append('references', reference)
else:
pe.append("references", {
'reference_doctype': dt,
'reference_name': dn,
"bill_no": doc.get("bill_no"),
"due_date": doc.get("due_date"),
'total_amount': grand_total,
'outstanding_amount': outstanding_amount,
'allocated_amount': outstanding_amount
})
pe.setup_party_account_field()
pe.set_missing_values()
@@ -1029,6 +1091,25 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
pe.set_amounts()
return pe
def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
references = []
for payment_term in payment_schedule:
payment_term_outstanding = flt(payment_term.payment_amount - payment_term.paid_amount,
payment_term.precision('payment_amount'))
if payment_term_outstanding:
references.append({
'reference_doctype': dt,
'reference_name': dn,
'bill_no': doc.get('bill_no'),
'due_date': doc.get('due_date'),
'total_amount': grand_total,
'outstanding_amount': outstanding_amount,
'payment_term': payment_term.payment_term,
'allocated_amount': payment_term_outstanding
})
return references
def get_paid_amount(dt, dn, party_type, party, account, due_date):
if party_type=="Customer":

View File

@@ -0,0 +1,12 @@
frappe.listview_settings['Payment Entry'] = {
onload: function(listview) {
listview.page.fields_dict.party_type.get_query = function() {
return {
"filters": {
"name": ["in", Object.keys(frappe.boot.party_account_types)],
}
};
};
}
};

View File

@@ -149,6 +149,30 @@ class TestPaymentEntry(unittest.TestCase):
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", pi.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 0)
def test_payment_entry_against_payment_terms(self):
si = create_sales_invoice(do_not_save=1, qty=1, rate=200)
create_payment_terms_template()
si.payment_terms_template = 'Test Receivable Template'
si.append('taxes', {
"charge_type": "On Net Total",
"account_head": "_Test Account Service Tax - _TC",
"cost_center": "_Test Cost Center - _TC",
"description": "Service Tax",
"rate": 18
})
si.save()
si.submit()
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
pe.submit()
si.load_from_db()
self.assertEqual(pe.references[0].payment_term, 'Basic Amount Receivable')
self.assertEqual(pe.references[1].payment_term, 'Tax Receivable')
self.assertEqual(si.payment_schedule[0].paid_amount, 200.0)
self.assertEqual(si.payment_schedule[1].paid_amount, 36.0)
def test_payment_against_sales_invoice_to_check_status(self):
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
@@ -438,11 +462,8 @@ class TestPaymentEntry(unittest.TestCase):
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 0)
def test_payment_entry_against_sales_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
def test_payment_entry_against_sales_invoice_with_cost_centre(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
@@ -477,39 +498,8 @@ class TestPaymentEntry(unittest.TestCase):
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_payment_entry_against_sales_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
si = create_sales_invoice(debit_to="Debtors - _TC")
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
pe.reference_no = "112211-2"
pe.reference_date = nowdate()
pe.paid_to = "_Test Bank - _TC"
pe.paid_amount = si.grand_total
pe.insert()
pe.submit()
gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
order by account asc""", pe.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(gle.cost_center, None)
def test_payment_entry_against_purchase_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
def test_payment_entry_against_purchase_invoice_with_cost_center(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
@@ -544,40 +534,9 @@ class TestPaymentEntry(unittest.TestCase):
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_payment_entry_against_purchase_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
pi = make_purchase_invoice(credit_to="Creditors - _TC")
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
pe.reference_no = "112222-2"
pe.reference_date = nowdate()
pe.paid_from = "_Test Bank - _TC"
pe.paid_amount = pi.grand_total
pe.insert()
pe.submit()
gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
order by account asc""", pe.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(gle.cost_center, None)
def test_payment_entry_account_and_party_balance_for_enable_allow_cost_center_in_entry_of_bs_account(self):
def test_payment_entry_account_and_party_balance_with_cost_center(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
from erpnext.accounts.utils import get_balance_on
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
@@ -608,5 +567,36 @@ class TestPaymentEntry(unittest.TestCase):
self.assertEqual(expected_party_balance, party_balance)
self.assertEqual(expected_party_account_balance, party_account_balance)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def create_payment_terms_template():
create_payment_term('Basic Amount Receivable')
create_payment_term('Tax Receivable')
if not frappe.db.exists('Payment Terms Template', 'Test Receivable Template'):
payment_term_template = frappe.get_doc({
'doctype': 'Payment Terms Template',
'template_name': 'Test Receivable Template',
'allocate_payment_based_on_payment_terms': 1,
'terms': [{
'doctype': 'Payment Terms Template Detail',
'payment_term': 'Basic Amount Receivable',
'invoice_portion': 84.746,
'credit_days_based_on': 'Day(s) after invoice date',
'credit_days': 1
},
{
'doctype': 'Payment Terms Template Detail',
'payment_term': 'Tax Receivable',
'invoice_portion': 15.254,
'credit_days_based_on': 'Day(s) after invoice date',
'credit_days': 2
}]
}).insert()
def create_payment_term(name):
if not frappe.db.exists('Payment Term', name):
frappe.get_doc({
'doctype': 'Payment Term',
'payment_term_name': name
}).insert()

View File

@@ -1,343 +1,107 @@
{
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"actions": [],
"creation": "2016-06-01 16:55:32.196722",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"reference_doctype",
"reference_name",
"due_date",
"bill_no",
"payment_term",
"column_break_4",
"total_amount",
"outstanding_amount",
"allocated_amount",
"exchange_rate"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fetch_if_empty": 0,
"fieldname": "reference_doctype",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Type",
"length": 0,
"no_copy": 0,
"options": "DocType",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fetch_if_empty": 0,
"fieldname": "reference_name",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Name",
"length": 0,
"no_copy": 0,
"options": "reference_doctype",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "due_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Due Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "bill_no",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Supplier Invoice No",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fetch_if_empty": 0,
"fieldname": "total_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Total Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fetch_if_empty": 0,
"fieldname": "outstanding_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Outstanding",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fetch_if_empty": 0,
"fieldname": "allocated_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Allocated",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"label": "Allocated"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:(doc.reference_doctype=='Purchase Invoice')",
"fetch_if_empty": 0,
"fieldname": "exchange_rate",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Exchange Rate",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"fieldname": "payment_term",
"fieldtype": "Link",
"label": "Payment Term",
"options": "Payment Term"
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2019-05-01 13:24:56.586677",
"links": [],
"modified": "2020-03-13 12:07:19.362539",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry Reference",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0,
"track_views": 0
"track_changes": 1
}

View File

@@ -26,6 +26,8 @@ class PaymentOrder(Document):
for d in self.references:
frappe.db.set_value(self.payment_order_type, d.get(frappe.scrub(self.payment_order_type)), ref_field, status)
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_mop_query(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql(""" select mode_of_payment from `tabPayment Order Reference`
where parent = %(parent)s and mode_of_payment like %(txt)s
@@ -36,6 +38,8 @@ def get_mop_query(doctype, txt, searchfield, start, page_len, filters):
'txt': "%%%s%%" % txt
})
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_supplier_query(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql(""" select supplier from `tabPayment Order Reference`
where parent = %(parent)s and supplier like %(txt)s and
@@ -80,10 +84,10 @@ def make_journal_entry(doc, supplier, mode_of_payment=None):
paid_amt += d.amount
je.append('accounts', {
'account': doc.references[0].account,
'account': doc.account,
'credit_in_account_currency': paid_amt
})
je.flags.ignore_mandatory = True
je.save()
frappe.msgprint(_("{0} {1} created").format(je.doctype, je.name))
frappe.msgprint(_("{0} {1} created").format(je.doctype, je.name))

View File

@@ -73,6 +73,10 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext
};
}
});
this.frm.set_value('party_type', '');
this.frm.set_value('party', '');
this.frm.set_value('receivable_payable_account', '');
},
refresh: function() {

View File

@@ -48,7 +48,8 @@ class PaymentReconciliation(Document):
select
"Journal Entry" as reference_type, t1.name as reference_name,
t1.posting_date, t1.remark as remarks, t2.name as reference_row,
{dr_or_cr} as amount, t2.is_advance
{dr_or_cr} as amount, t2.is_advance,
t2.account_currency as currency
from
`tabJournal Entry` t1, `tabJournal Entry Account` t2
where
@@ -88,7 +89,8 @@ class PaymentReconciliation(Document):
if self.party_type == 'Customer' else "Purchase Invoice")
return frappe.db.sql(""" SELECT `tab{doc}`.name as reference_name, %(voucher_type)s as reference_type,
(sum(`tabGL Entry`.{dr_or_cr}) - sum(`tabGL Entry`.{reconciled_dr_or_cr})) as amount
(sum(`tabGL Entry`.{dr_or_cr}) - sum(`tabGL Entry`.{reconciled_dr_or_cr})) as amount,
account_currency as currency
FROM `tab{doc}`, `tabGL Entry`
WHERE
(`tab{doc}`.name = `tabGL Entry`.against_voucher or `tab{doc}`.name = `tabGL Entry`.voucher_no)
@@ -101,10 +103,10 @@ class PaymentReconciliation(Document):
Having
amount > 0
""".format(
doc=voucher_type,
dr_or_cr=dr_or_cr,
reconciled_dr_or_cr=reconciled_dr_or_cr,
party_type_field=frappe.scrub(self.party_type)),
doc=voucher_type,
dr_or_cr=dr_or_cr,
reconciled_dr_or_cr=reconciled_dr_or_cr,
party_type_field=frappe.scrub(self.party_type)),
{
'party': self.party,
'party_type': self.party_type,
@@ -141,6 +143,7 @@ class PaymentReconciliation(Document):
ent.invoice_number = e.get('voucher_no')
ent.invoice_date = e.get('posting_date')
ent.amount = flt(e.get('invoice_amount'))
ent.currency = e.get('currency')
ent.outstanding_amount = e.get('outstanding_amount')
def reconcile(self, args):
@@ -170,7 +173,7 @@ class PaymentReconciliation(Document):
reconcile_against_document(lst)
if dr_or_cr_notes:
reconcile_dr_cr_note(dr_or_cr_notes)
reconcile_dr_cr_note(dr_or_cr_notes, self.company)
msgprint(_("Successfully Reconciled"))
self.get_unreconciled_entries()
@@ -261,7 +264,7 @@ class PaymentReconciliation(Document):
return cond
def reconcile_dr_cr_note(dr_cr_notes):
def reconcile_dr_cr_note(dr_cr_notes, company):
for d in dr_cr_notes:
voucher_type = ('Credit Note'
if d.voucher_type == 'Sales Invoice' else 'Debit Note')
@@ -269,10 +272,14 @@ def reconcile_dr_cr_note(dr_cr_notes):
reconcile_dr_or_cr = ('debit_in_account_currency'
if d.dr_or_cr == 'credit_in_account_currency' else 'credit_in_account_currency')
company_currency = erpnext.get_company_currency(company)
jv = frappe.get_doc({
"doctype": "Journal Entry",
"voucher_type": voucher_type,
"posting_date": today(),
"company": company,
"multi_currency": 1 if d.currency != company_currency else 0,
"accounts": [
{
'account': d.account,
@@ -280,7 +287,8 @@ def reconcile_dr_cr_note(dr_cr_notes):
'party_type': d.party_type,
d.dr_or_cr: abs(d.allocated_amount),
'reference_type': d.against_voucher_type,
'reference_name': d.against_voucher
'reference_name': d.against_voucher,
'cost_center': erpnext.get_default_cost_center(company)
},
{
'account': d.account,
@@ -289,7 +297,8 @@ def reconcile_dr_cr_note(dr_cr_notes):
reconcile_dr_or_cr: (abs(d.allocated_amount)
if abs(d.unadjusted_amount) > abs(d.allocated_amount) else abs(d.unadjusted_amount)),
'reference_type': d.voucher_type,
'reference_name': d.voucher_no
'reference_name': d.voucher_no,
'cost_center': erpnext.get_default_cost_center(company)
}
]
})

View File

@@ -1,183 +1,80 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2014-07-09 16:14:23.672922",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"actions": [],
"creation": "2014-07-09 16:14:23.672922",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"invoice_type",
"invoice_number",
"invoice_date",
"col_break1",
"amount",
"outstanding_amount",
"currency"
],
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "invoice_type",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Invoice Type",
"length": 0,
"no_copy": 0,
"options": "Sales Invoice\nPurchase Invoice\nJournal Entry",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
"fieldname": "invoice_type",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Invoice Type",
"options": "Sales Invoice\nPurchase Invoice\nJournal Entry",
"read_only": 1
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "invoice_number",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Invoice Number",
"length": 0,
"no_copy": 0,
"options": "invoice_type",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
"fieldname": "invoice_number",
"fieldtype": "Dynamic Link",
"in_list_view": 1,
"label": "Invoice Number",
"options": "invoice_type",
"read_only": 1
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "invoice_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Invoice Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
"fieldname": "invoice_date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "Invoice Date",
"read_only": 1
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "col_break1",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
"fieldname": "col_break1",
"fieldtype": "Column Break"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
"fieldname": "amount",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Amount",
"options": "currency",
"read_only": 1
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "outstanding_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Outstanding Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"fieldname": "outstanding_amount",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Outstanding Amount",
"options": "currency",
"read_only": 1
},
{
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 1,
"label": "Currency",
"options": "Currency"
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-07-11 03:28:03.588476",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Invoice",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_seen": 0
],
"istable": 1,
"links": [],
"modified": "2020-07-19 18:12:27.964073",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Invoice",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@@ -1,7 +1,9 @@
{
"actions": [],
"creation": "2014-07-09 16:13:35.452759",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"reference_type",
"reference_name",
@@ -16,7 +18,8 @@
"difference_account",
"difference_amount",
"sec_break1",
"remark"
"remark",
"currency"
],
"fields": [
{
@@ -73,6 +76,7 @@
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Amount",
"options": "currency",
"read_only": 1
},
{
@@ -81,6 +85,7 @@
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Allocated amount",
"options": "currency",
"reqd": 1
},
{
@@ -106,16 +111,25 @@
"fieldname": "difference_amount",
"fieldtype": "Currency",
"label": "Difference Amount",
"options": "currency",
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "section_break_10",
"fieldtype": "Section Break"
},
{
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 1,
"label": "Currency",
"options": "Currency"
}
],
"istable": 1,
"modified": "2019-06-24 00:08:11.150796",
"links": [],
"modified": "2020-07-19 18:12:41.682347",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Payment",

View File

@@ -69,7 +69,7 @@ class PaymentRequest(Document):
elif self.payment_request_type == 'Inward':
self.db_set('status', 'Requested')
send_mail = self.payment_gateway_validation()
send_mail = self.payment_gateway_validation() if self.payment_gateway else None
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart") \
@@ -140,9 +140,6 @@ class PaymentRequest(Document):
})
def set_as_paid(self):
if frappe.session.user == "Guest":
frappe.set_user("Administrator")
payment_entry = self.create_payment_entry()
self.make_invoice()
@@ -254,7 +251,7 @@ class PaymentRequest(Document):
if status in ["Authorized", "Completed"]:
redirect_to = None
self.run_method("set_as_paid")
self.set_as_paid()
# if shopping cart enabled and in session
if (shopping_cart_settings.enabled and hasattr(frappe.local, "session")
@@ -326,7 +323,7 @@ def make_payment_request(**args):
"reference_doctype": args.dt,
"reference_name": args.dn,
"party_type": args.get("party_type") or "Customer",
"party": args.get("party") or ref_doc.customer,
"party": args.get("party") or ref_doc.get("customer"),
"bank_account": bank_account
})
@@ -420,7 +417,7 @@ def make_payment_entry(docname):
def update_payment_req_status(doc, method):
from erpnext.accounts.doctype.payment_entry.payment_entry import get_reference_details
for ref in doc.references:
payment_request_name = frappe.db.get_value("Payment Request",
{"reference_doctype": ref.reference_doctype, "reference_name": ref.reference_name,
@@ -430,7 +427,7 @@ def update_payment_req_status(doc, method):
ref_details = get_reference_details(ref.reference_doctype, ref.reference_name, doc.party_account_currency)
pay_req_doc = frappe.get_doc('Payment Request', payment_request_name)
status = pay_req_doc.status
if status != "Paid" and not ref_details.outstanding_amount:
status = 'Paid'
elif status != "Partially Paid" and ref_details.outstanding_amount != ref_details.total_amount:

View File

@@ -1,243 +1,82 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "",
"beta": 0,
"creation": "2017-08-10 15:38:00.080575",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"actions": [],
"creation": "2017-08-10 15:38:00.080575",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"payment_term",
"description",
"due_date",
"invoice_portion",
"payment_amount",
"mode_of_payment",
"paid_amount"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "payment_term",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Payment Term",
"length": 0,
"no_copy": 0,
"options": "Payment Term",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"columns": 2,
"fieldname": "payment_term",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Payment Term",
"options": "Payment Term",
"print_hide": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fetch_from": "",
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Description",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"columns": 2,
"fieldname": "description",
"fieldtype": "Small Text",
"in_list_view": 1,
"label": "Description"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "due_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Due Date",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"columns": 2,
"fieldname": "due_date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "Due Date",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fetch_from": "",
"fieldname": "invoice_portion",
"fieldtype": "Percent",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Invoice Portion",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"columns": 2,
"fieldname": "invoice_portion",
"fieldtype": "Percent",
"in_list_view": 1,
"label": "Invoice Portion",
"print_hide": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "payment_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Payment Amount",
"length": 0,
"no_copy": 0,
"options": "currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"columns": 2,
"fieldname": "payment_amount",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Payment Amount",
"options": "currency",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "mode_of_payment",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Mode of Payment",
"length": 0,
"no_copy": 0,
"options": "Mode of Payment",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"fieldname": "mode_of_payment",
"fieldtype": "Link",
"label": "Mode of Payment",
"options": "Mode of Payment"
},
{
"fieldname": "paid_amount",
"fieldtype": "Currency",
"label": "Paid Amount"
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2018-09-06 17:35:44.580209",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Schedule",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0,
"track_views": 0
],
"istable": 1,
"links": [],
"modified": "2020-03-13 17:58:24.729526",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Schedule",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@@ -1,164 +1,84 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:template_name",
"beta": 0,
"creation": "2017-08-10 15:34:28.058054",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"actions": [],
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:template_name",
"creation": "2017-08-10 15:34:28.058054",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"template_name",
"allocate_payment_based_on_payment_terms",
"terms"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "template_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Template Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
"fieldname": "template_name",
"fieldtype": "Data",
"label": "Template Name",
"unique": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "terms",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payment Terms",
"length": 0,
"no_copy": 0,
"options": "Payment Terms Template Detail",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"fieldname": "terms",
"fieldtype": "Table",
"label": "Payment Terms",
"options": "Payment Terms Template Detail",
"reqd": 1
},
{
"default": "0",
"description": "If this checkbox is checked, paid amount will be splitted and allocated as per the amounts in payment schedule against each payment term",
"fieldname": "allocate_payment_based_on_payment_terms",
"fieldtype": "Check",
"label": "Allocate Payment Based On Payment Terms"
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-01-24 11:13:31.158613",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Terms Template",
"name_case": "",
"owner": "Administrator",
],
"links": [],
"modified": "2020-04-01 15:35:18.112619",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Terms Template",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
},
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"share": 1,
"write": 1
},
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"share": 1,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@@ -7,6 +7,8 @@ from frappe.utils import flt
from frappe import _
from erpnext.accounts.utils import get_account_currency
from erpnext.controllers.accounts_controller import AccountsController
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (get_accounting_dimensions,
get_dimension_filters)
class PeriodClosingVoucher(AccountsController):
def validate(self):
@@ -49,7 +51,15 @@ class PeriodClosingVoucher(AccountsController):
def make_gl_entries(self):
gl_entries = []
net_pl_balance = 0
pl_accounts = self.get_pl_balances()
dimension_fields = ['t1.cost_center']
accounting_dimensions = get_accounting_dimensions()
for dimension in accounting_dimensions:
dimension_fields.append('t1.{0}'.format(dimension))
dimension_filters, default_dimensions = get_dimension_filters()
pl_accounts = self.get_pl_balances(dimension_fields)
for acc in pl_accounts:
if flt(acc.balance_in_company_currency):
@@ -65,34 +75,41 @@ class PeriodClosingVoucher(AccountsController):
if flt(acc.balance_in_account_currency) > 0 else 0,
"credit": abs(flt(acc.balance_in_company_currency)) \
if flt(acc.balance_in_company_currency) > 0 else 0
}))
}, item=acc))
net_pl_balance += flt(acc.balance_in_company_currency)
if net_pl_balance:
cost_center = frappe.db.get_value("Company", self.company, "cost_center")
gl_entries.append(self.get_gl_dict({
gl_entry = self.get_gl_dict({
"account": self.closing_account_head,
"debit_in_account_currency": abs(net_pl_balance) if net_pl_balance > 0 else 0,
"debit": abs(net_pl_balance) if net_pl_balance > 0 else 0,
"credit_in_account_currency": abs(net_pl_balance) if net_pl_balance < 0 else 0,
"credit": abs(net_pl_balance) if net_pl_balance < 0 else 0,
"cost_center": cost_center
}))
})
for dimension in accounting_dimensions:
gl_entry.update({
dimension: default_dimensions.get(self.company, {}).get(dimension)
})
gl_entries.append(gl_entry)
from erpnext.accounts.general_ledger import make_gl_entries
make_gl_entries(gl_entries)
def get_pl_balances(self):
def get_pl_balances(self, dimension_fields):
"""Get balance for pl accounts"""
return frappe.db.sql("""
select
t1.account, t1.cost_center, t2.account_currency,
t1.account, t2.account_currency, {dimension_fields},
sum(t1.debit_in_account_currency) - sum(t1.credit_in_account_currency) as balance_in_account_currency,
sum(t1.debit) - sum(t1.credit) as balance_in_company_currency
from `tabGL Entry` t1, `tabAccount` t2
where t1.account = t2.name and t2.report_type = 'Profit and Loss'
and t2.docstatus < 2 and t2.company = %s
and t1.posting_date between %s and %s
group by t1.account, t1.cost_center
""", (self.company, self.get("year_start_date"), self.posting_date), as_dict=1)
group by t1.account, {dimension_fields}
""".format(dimension_fields = ', '.join(dimension_fields)), (self.company, self.get("year_start_date"), self.posting_date), as_dict=1)

View File

@@ -115,6 +115,8 @@ def get_item_groups(pos_profile):
def get_series():
return frappe.get_meta("Sales Invoice").get_field("naming_series").options or ""
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def pos_profile_query(doctype, txt, searchfield, start, page_len, filters):
user = frappe.session['user']
company = filters.get('company') or frappe.defaults.get_user_default('company')

View File

@@ -15,12 +15,12 @@ class TestPOSProfile(unittest.TestCase):
pos_profile = get_pos_profile("_Test Company") or {}
if pos_profile:
doc = frappe.get_doc("POS Profile", pos_profile.get("name"))
doc.append('item_groups', {'item_group': '_Test Item Group'})
doc.append('customer_groups', {'customer_group': '_Test Customer Group'})
doc.set('item_groups', [{'item_group': '_Test Item Group'}])
doc.set('customer_groups', [{'customer_group': '_Test Customer Group'}])
doc.save()
items = get_items_list(doc, doc.company)
customers = get_customers_list(doc)
products_count = frappe.db.sql(""" select count(name) from tabItem where item_group = '_Test Item Group'""", as_list=1)
customers_count = frappe.db.sql(""" select count(name) from tabCustomer where customer_group = '_Test Customer Group'""")

View File

@@ -17,6 +17,8 @@ from six import string_types
apply_on_dict = {"Item Code": "items",
"Item Group": "item_groups", "Brand": "brands"}
other_fields = ["other_item_code", "other_item_group", "other_brand"]
class PricingRule(Document):
def validate(self):
self.validate_mandatory()
@@ -51,6 +53,13 @@ class PricingRule(Document):
if tocheck and not self.get(tocheck):
throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError)
if self.apply_rule_on_other:
o_field = 'other_' + frappe.scrub(self.apply_rule_on_other)
if not self.get(o_field) and o_field in other_fields:
frappe.throw(_("For the 'Apply Rule On Other' condition the field {0} is mandatory")
.format(frappe.bold(self.apply_rule_on_other)))
if self.price_or_product_discount == 'Price' and not self.rate_or_discount:
throw(_("Rate or Discount is required for the price discount."), frappe.MandatoryError)
@@ -84,13 +93,27 @@ class PricingRule(Document):
for f in options:
if not f: continue
f = frappe.scrub(f)
if f!=fieldname:
self.set(f, None)
scrubbed_f = frappe.scrub(f)
if logic_field == 'apply_on':
apply_on_f = apply_on_dict.get(f, f)
else:
apply_on_f = scrubbed_f
if scrubbed_f != fieldname:
self.set(apply_on_f, None)
if self.mixed_conditions and self.get("same_item"):
self.same_item = 0
apply_rule_on_other = frappe.scrub(self.apply_rule_on_other or "")
cleanup_other_fields = (other_fields if not apply_rule_on_other
else [o_field for o_field in other_fields if o_field != 'other_' + apply_rule_on_other])
for other_field in cleanup_other_fields:
self.set(other_field, None)
def validate_rate_or_discount(self):
for field in ["Rate"]:
if flt(self.get(frappe.scrub(field))) < 0:
@@ -103,7 +126,7 @@ class PricingRule(Document):
self.same_item = 1
def validate_max_discount(self):
if self.rate_or_discount == "Discount Percentage" and self.items:
if self.rate_or_discount == "Discount Percentage" and self.get("items"):
for d in self.items:
max_discount = frappe.get_cached_value("Item", d.item_code, "max_discount")
if max_discount and flt(self.discount_percentage) > flt(max_discount):
@@ -241,13 +264,14 @@ def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=Fa
if pricing_rule.mixed_conditions or pricing_rule.apply_rule_on_other:
item_details.update({
'apply_rule_on_other_items': json.dumps(pricing_rule.apply_rule_on_other_items),
'price_or_product_discount': pricing_rule.price_or_product_discount,
'apply_rule_on': (frappe.scrub(pricing_rule.apply_rule_on_other)
if pricing_rule.apply_rule_on_other else frappe.scrub(pricing_rule.get('apply_on')))
})
if pricing_rule.coupon_code_based==1 and args.coupon_code==None:
return item_details
if not pricing_rule.validate_applied_rule:
if pricing_rule.price_or_product_discount == "Price":
apply_price_discount_rule(pricing_rule, item_details, args)
@@ -256,7 +280,7 @@ def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=Fa
item_details.has_pricing_rule = 1
item_details.pricing_rules = ','.join([d.pricing_rule for d in rules])
item_details.pricing_rules = frappe.as_json([d.pricing_rule for d in rules])
if not doc: return item_details
@@ -346,7 +370,7 @@ def set_discount_amount(rate, item_details):
def remove_pricing_rule_for_item(pricing_rules, item_details, item_code=None):
from erpnext.accounts.doctype.pricing_rule.utils import get_pricing_rule_items
for d in pricing_rules.split(','):
for d in json.loads(pricing_rules):
if not d or not frappe.db.exists("Pricing Rule", d): continue
pricing_rule = frappe.get_cached_doc('Pricing Rule', d)
@@ -412,14 +436,15 @@ def make_pricing_rule(doctype, docname):
return doc
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_item_uoms(doctype, txt, searchfield, start, page_len, filters):
items = [filters.get('value')]
if filters.get('apply_on') != 'Item Code':
field = frappe.scrub(filters.get('apply_on'))
items = [d.name for d in frappe.db.get_all("Item", filters={field: filters.get('value')})]
items = frappe.db.sql_list("""select name
from `tabItem` where {0} = %s""".format(field), filters.get('value'))
return frappe.get_all('UOM Conversion Detail',
filters = {'parent': ('in', items), 'uom': ("like", "{0}%".format(txt))},
fields = ["distinct uom"], as_list=1)
return frappe.get_all('UOM Conversion Detail', filters={
'parent': ('in', items),
'uom': ("like", "{0}%".format(txt))
}, fields = ["distinct uom"], as_list=1)

View File

@@ -385,6 +385,50 @@ class TestPricingRule(unittest.TestCase):
so.load_from_db()
self.assertEqual(so.items[1].is_free_item, 1)
self.assertEqual(so.items[1].item_code, "_Test Item 2")
def test_cumulative_pricing_rule(self):
frappe.delete_doc_if_exists('Pricing Rule', '_Test Cumulative Pricing Rule')
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Cumulative Pricing Rule",
"apply_on": "Item Code",
"currency": "USD",
"items": [{
"item_code": "_Test Item",
}],
"is_cumulative": 1,
"selling": 1,
"applicable_for": "Customer",
"customer": "_Test Customer",
"rate_or_discount": "Discount Percentage",
"rate": 0,
"min_amt": 0,
"max_amt": 10000,
"discount_percentage": 17.5,
"price_or_product_discount": "Price",
"company": "_Test Company",
"valid_from": frappe.utils.nowdate(),
"valid_upto": frappe.utils.nowdate()
}
frappe.get_doc(test_record.copy()).insert()
args = frappe._dict({
"item_code": "_Test Item",
"company": "_Test Company",
"price_list": "_Test Price List",
"currency": "_Test Currency",
"doctype": "Sales Invoice",
"conversion_rate": 1,
"price_list_currency": "_Test Currency",
"plc_conversion_rate": 1,
"order_type": "Sales",
"customer": "_Test Customer",
"name": None,
"transaction_date": frappe.utils.nowdate()
})
details = get_item_details(args)
self.assertTrue(details)
def make_pricing_rule(**args):
args = frappe._dict(args)

View File

@@ -4,13 +4,23 @@
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe, copy, json
from frappe import throw, _
import copy
import json
from six import string_types
from frappe.utils import flt, cint, get_datetime, get_link_to_form, today
import frappe
from erpnext.accounts.doctype.pricing_rule.pricing_rule import set_transaction_type
from erpnext.setup.doctype.item_group.item_group import get_child_item_groups
from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
from erpnext.stock.get_item_details import get_conversion_factor
from erpnext.stock.get_item_details import get_conversion_factor, get_default_income_account
from erpnext.stock.doctype.item.item import get_item_defaults
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
from erpnext.setup.doctype.brand.brand import get_brand_defaults
from frappe import _, throw
from frappe.utils import cint, flt, get_datetime, get_link_to_form, getdate, today
class MultiplePricingRuleConflict(frappe.ValidationError): pass
@@ -313,7 +323,9 @@ def apply_internal_priority(pricing_rules, field_set, args):
filtered_rules = []
for field in field_set:
if args.get(field):
filtered_rules = filter(lambda x: x[field]==args[field], pricing_rules)
# filter function always returns a filter object even if empty
# list conversion is necessary to check for an empty result
filtered_rules = list(filter(lambda x: x.get(field)==args.get(field), pricing_rules))
if filtered_rules: break
return filtered_rules or pricing_rules
@@ -330,9 +342,9 @@ def get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args):
if pr_doc.mixed_conditions:
amt = args.get('qty') * args.get("price_list_rate")
if args.get("item_code") != row.get("item_code"):
amt = row.get('qty') * (row.get("price_list_rate") or args.get("rate"))
amt = flt(row.get('qty')) * flt(row.get("price_list_rate") or args.get("rate"))
sum_qty += row.get("stock_qty") or args.get("stock_qty") or args.get("qty")
sum_qty += flt(row.get("stock_qty")) or flt(args.get("stock_qty")) or flt(args.get("qty"))
sum_amt += amt
if pr_doc.is_cumulative:
@@ -360,8 +372,7 @@ def get_qty_amount_data_for_cumulative(pr_doc, doc, items=[]):
sum_qty, sum_amt = [0, 0]
doctype = doc.get('parenttype') or doc.doctype
date_field = ('transaction_date'
if doc.get('transaction_date') else 'posting_date')
date_field = 'transaction_date' if frappe.get_meta(doctype).has_field('transaction_date') else 'posting_date'
child_doctype = '{0} Item'.format(doctype)
apply_on = frappe.scrub(pr_doc.get('apply_on'))
@@ -408,9 +419,28 @@ def apply_pricing_rule_on_transaction(doc):
values = {}
conditions = get_other_conditions(conditions, values, doc)
pricing_rules = frappe.db.sql(""" Select `tabPricing Rule`.* from `tabPricing Rule`
where {conditions} and `tabPricing Rule`.disable = 0
""".format(conditions = conditions), values, as_dict=1)
args = frappe._dict({
'doctype': doc.doctype,
'transaction_type': None,
})
set_transaction_type(args)
tran_type_condition = '{} = 1'.format(args.transaction_type)
sql = """
SELECT
`tabPricing Rule`.*
FROM
`tabPricing Rule`
WHERE
{conditions} and
{tran_type_condition} and
`tabPricing Rule`.disable = 0
""".format(
conditions=conditions,
tran_type_condition=tran_type_condition,
)
pricing_rules = frappe.db.sql(sql, values, as_dict=1)
if pricing_rules:
pricing_rules = filter_pricing_rules_for_qty_amount(doc.total_qty,
@@ -441,7 +471,7 @@ def apply_pricing_rule_on_transaction(doc):
doc.set_missing_values()
def get_applied_pricing_rules(item_row):
return (item_row.get("pricing_rules").split(',')
return (json.loads(item_row.get("pricing_rules"))
if item_row.get("pricing_rules") else [])
def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None):
@@ -475,6 +505,14 @@ def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None):
if item_details.get("parenttype") == 'Sales Order':
item_details.free_item_data['delivery_date'] = doc.delivery_date if doc else today()
company = args.get('company') or doc.company
item_details.free_item_data['income_account'] = get_default_income_account(
args=args,
item=get_item_defaults(free_item, company),
item_group=get_item_group_defaults(free_item, company),
brand=get_brand_defaults(free_item, company),
)
def apply_pricing_rule_for_free_items(doc, pricing_rule_args, set_missing_values=False):
if pricing_rule_args.get('item_code'):
items = [d.item_code for d in doc.items
@@ -502,18 +540,16 @@ def get_pricing_rule_items(pr_doc):
return list(set(apply_on_data))
def validate_coupon_code(coupon_name):
from frappe.utils import today,getdate
coupon=frappe.get_doc("Coupon Code",coupon_name)
coupon = frappe.get_doc("Coupon Code", coupon_name)
if coupon.valid_from:
if coupon.valid_from > getdate(today()) :
frappe.throw(_("Sorry,coupon code validity has not started"))
if coupon.valid_from > getdate(today()):
frappe.throw(_("Sorry, this coupon code's validity has not started"))
elif coupon.valid_upto:
if coupon.valid_upto < getdate(today()) :
frappe.throw(_("Sorry,coupon code validity has expired"))
elif coupon.used>=coupon.maximum_use:
frappe.throw(_("Sorry,coupon code are exhausted"))
else:
return
if coupon.valid_upto < getdate(today()):
frappe.throw(_("Sorry, this coupon code's validity has expired"))
elif coupon.used >= coupon.maximum_use:
frappe.throw(_("Sorry, this coupon code is no longer valid"))
def update_coupon_code_count(coupon_name,transaction_type):
coupon=frappe.get_doc("Coupon Code",coupon_name)

View File

@@ -261,12 +261,25 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
price_list: this.frm.doc.buying_price_list
}, function() {
me.apply_pricing_rule();
me.frm.doc.apply_tds = me.frm.supplier_tds ? 1 : 0;
me.frm.doc.tax_withholding_category = me.frm.supplier_tds;
me.frm.set_df_property("apply_tds", "read_only", me.frm.supplier_tds ? 0 : 1);
me.frm.set_df_property("tax_withholding_category", "hidden", me.frm.supplier_tds ? 0 : 1);
})
},
apply_tds: function(frm) {
var me = this;
if (!me.frm.doc.apply_tds) {
me.frm.set_value("tax_withholding_category", '');
me.frm.set_df_property("tax_withholding_category", "hidden", 1);
} else {
me.frm.set_value("tax_withholding_category", me.frm.supplier_tds);
me.frm.set_df_property("tax_withholding_category", "hidden", 0);
}
},
credit_to: function() {
var me = this;
if(this.frm.doc.credit_to) {

View File

@@ -1,5 +1,4 @@
{
"actions": [],
"allow_import": 1,
"autoname": "naming_series:",
"creation": "2013-05-21 16:16:39",
@@ -16,6 +15,7 @@
"is_paid",
"is_return",
"apply_tds",
"tax_withholding_category",
"column_break1",
"company",
"posting_date",
@@ -25,6 +25,7 @@
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
"project",
"sb_14",
"on_hold",
"release_date",
@@ -73,9 +74,9 @@
"base_total",
"base_net_total",
"column_break_28",
"total_net_weight",
"total",
"net_total",
"total_net_weight",
"taxes_section",
"tax_category",
"column_break_49",
@@ -962,8 +963,10 @@
{
"fieldname": "clearance_date",
"fieldtype": "Date",
"hidden": 1,
"label": "Clearance Date"
"label": "Clearance Date",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "col_br_payments",
@@ -1232,6 +1235,7 @@
"print_hide": 1
},
{
"collapsible": 1,
"fieldname": "subscription_section",
"fieldtype": "Section Break",
"label": "Subscription Section",
@@ -1284,13 +1288,26 @@
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
},
{
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
"options": "Project"
},
{
"fieldname": "tax_withholding_category",
"fieldtype": "Link",
"hidden": 1,
"label": "Tax Withholding Category",
"options": "Tax Withholding Category",
"print_hide": 1
}
],
"icon": "fa fa-file-text",
"idx": 204,
"is_submittable": 1,
"links": [],
"modified": "2019-12-30 19:13:49.610538",
"modified": "2020-08-20 11:08:19.611710",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",

View File

@@ -413,6 +413,8 @@ class PurchaseInvoice(BuyingController):
self.make_tax_gl_entries(gl_entries)
gl_entries = make_regional_gl_entries(gl_entries, self)
gl_entries = merge_similar_entries(gl_entries)
self.make_payment_gl_entries(gl_entries)
@@ -451,8 +453,9 @@ class PurchaseInvoice(BuyingController):
if self.party_account_currency==self.company_currency else grand_total,
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency)
"cost_center": self.cost_center,
"project": self.project
}, self.party_account_currency, item=self)
)
def make_item_gl_entries(self, gl_entries):
@@ -492,7 +495,7 @@ class PurchaseInvoice(BuyingController):
"debit": warehouse_debit_amount,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"cost_center": item.cost_center,
"project": item.project
"project": item.project or self.project
}, account_currency, item=item)
)
@@ -505,7 +508,7 @@ class PurchaseInvoice(BuyingController):
"cost_center": item.cost_center,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"credit": flt(amount),
"project": item.project
"project": item.project or self.project
}, item=item))
# sub-contracting warehouse
@@ -518,6 +521,7 @@ class PurchaseInvoice(BuyingController):
"account": supplier_warehouse_account,
"against": item.expense_account,
"cost_center": item.cost_center,
"project": item.project or self.project,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"credit": flt(item.rm_supp_cost)
}, warehouse_account[self.supplier_warehouse]["account_currency"], item=item))
@@ -536,7 +540,7 @@ class PurchaseInvoice(BuyingController):
"against": self.supplier,
"debit": amount,
"cost_center": item.cost_center,
"project": item.project
"project": item.project or self.project
}, account_currency, item=item))
# If asset is bought through this document and not linked to PR
@@ -549,7 +553,7 @@ class PurchaseInvoice(BuyingController):
"cost_center": item.cost_center,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"credit": flt(item.landed_cost_voucher_amount),
"project": item.project
"project": item.project or self.project
}, item=item))
gl_entries.append(self.get_gl_dict({
@@ -558,7 +562,7 @@ class PurchaseInvoice(BuyingController):
"cost_center": item.cost_center,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"debit": flt(item.landed_cost_voucher_amount),
"project": item.project
"project": item.project or self.project
}, item=item))
# update gross amount of asset bought through this document
@@ -584,7 +588,8 @@ class PurchaseInvoice(BuyingController):
"against": self.supplier,
"debit": flt(item.item_tax_amount, item.precision("item_tax_amount")),
"remarks": self.remarks or "Accounting Entry for Stock",
"cost_center": self.cost_center
"cost_center": self.cost_center,
"project": item.project or self.project
}, item=item)
)
@@ -613,7 +618,8 @@ class PurchaseInvoice(BuyingController):
"debit": base_asset_amount,
"debit_in_account_currency": (base_asset_amount
if arbnb_currency == self.company_currency else asset_amount),
"cost_center": item.cost_center
"cost_center": item.cost_center,
"project": item.project or self.project
}, item=item))
if item.item_tax_amount:
@@ -623,6 +629,7 @@ class PurchaseInvoice(BuyingController):
"against": self.supplier,
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
"cost_center": item.cost_center,
"project": item.project or self.project,
"credit": item.item_tax_amount,
"credit_in_account_currency": (item.item_tax_amount
if asset_eiiav_currency == self.company_currency else
@@ -639,7 +646,8 @@ class PurchaseInvoice(BuyingController):
"debit": base_asset_amount,
"debit_in_account_currency": (base_asset_amount
if cwip_account_currency == self.company_currency else asset_amount),
"cost_center": self.cost_center
"cost_center": self.cost_center,
"project": item.project or self.project
}, item=item))
if item.item_tax_amount and not cint(erpnext.is_perpetual_inventory_enabled(self.company)):
@@ -650,6 +658,7 @@ class PurchaseInvoice(BuyingController):
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
"cost_center": item.cost_center,
"credit": item.item_tax_amount,
"project": item.project or self.project,
"credit_in_account_currency": (item.item_tax_amount
if asset_eiiav_currency == self.company_currency else
item.item_tax_amount / self.conversion_rate)
@@ -665,7 +674,7 @@ class PurchaseInvoice(BuyingController):
"cost_center": item.cost_center,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"credit": flt(item.landed_cost_voucher_amount),
"project": item.project
"project": item.project or self.project
}, item=item))
gl_entries.append(self.get_gl_dict({
@@ -674,7 +683,7 @@ class PurchaseInvoice(BuyingController):
"cost_center": item.cost_center,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"debit": flt(item.landed_cost_voucher_amount),
"project": item.project
"project": item.project or self.project
}, item=item))
# update gross amount of assets bought through this document
@@ -709,7 +718,7 @@ class PurchaseInvoice(BuyingController):
"debit": stock_adjustment_amt,
"remarks": self.get("remarks") or _("Stock Adjustment"),
"cost_center": item.cost_center,
"project": item.project
"project": item.project or self.project
}, account_currency, item=item)
)
@@ -801,8 +810,9 @@ class PurchaseInvoice(BuyingController):
if self.party_account_currency==self.company_currency else self.paid_amount,
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency)
"cost_center": self.cost_center,
"project": self.project
}, self.party_account_currency, item=self)
)
gl_entries.append(
@@ -813,7 +823,7 @@ class PurchaseInvoice(BuyingController):
"credit_in_account_currency": self.base_paid_amount \
if bank_account_currency==self.company_currency else self.paid_amount,
"cost_center": self.cost_center
}, bank_account_currency)
}, bank_account_currency, item=self)
)
def make_write_off_gl_entry(self, gl_entries):
@@ -833,8 +843,9 @@ class PurchaseInvoice(BuyingController):
if self.party_account_currency==self.company_currency else self.write_off_amount,
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency)
"cost_center": self.cost_center,
"project": self.project
}, self.party_account_currency, item=self)
)
gl_entries.append(
self.get_gl_dict({
@@ -844,7 +855,7 @@ class PurchaseInvoice(BuyingController):
"credit_in_account_currency": self.base_write_off_amount \
if write_off_account_currency==self.company_currency else self.write_off_amount,
"cost_center": self.cost_center or self.write_off_cost_center
})
}, item=self)
)
def make_gle_for_rounding_adjustment(self, gl_entries):
@@ -863,8 +874,7 @@ class PurchaseInvoice(BuyingController):
"debit_in_account_currency": self.rounding_adjustment,
"debit": self.base_rounding_adjustment,
"cost_center": self.cost_center or round_off_cost_center,
}
))
}, item=self))
def on_cancel(self):
super(PurchaseInvoice, self).on_cancel()
@@ -959,7 +969,7 @@ class PurchaseInvoice(BuyingController):
if not self.apply_tds:
return
tax_withholding_details = get_party_tax_withholding_details(self)
tax_withholding_details = get_party_tax_withholding_details(self, self.tax_withholding_category)
if not tax_withholding_details:
return
@@ -982,6 +992,40 @@ class PurchaseInvoice(BuyingController):
# calculate totals again after applying TDS
self.calculate_taxes_and_totals()
def set_status(self, update=False, status=None, update_modified=True):
if self.is_new():
if self.get('amended_from'):
self.status = 'Draft'
return
precision = self.precision("outstanding_amount")
outstanding_amount = flt(self.outstanding_amount, precision)
due_date = getdate(self.due_date)
nowdate = getdate()
if not status:
if self.docstatus == 2:
status = "Cancelled"
elif self.docstatus == 1:
if outstanding_amount > 0 and due_date < nowdate:
self.status = "Overdue"
elif outstanding_amount > 0 and due_date >= nowdate:
self.status = "Unpaid"
#Check if outstanding amount is 0 due to debit note issued against invoice
elif outstanding_amount <= 0 and self.is_return == 0 and frappe.db.get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
self.status = "Debit Note Issued"
elif self.is_return == 1:
self.status = "Return"
elif outstanding_amount<=0:
self.status = "Paid"
else:
self.status = "Submitted"
else:
self.status = "Draft"
if update:
self.db_set('status', self.status, update_modified = update_modified)
def get_list_context(context=None):
from erpnext.controllers.website_list_for_contact import get_list_context
list_context = get_list_context(context)
@@ -993,6 +1037,10 @@ def get_list_context(context=None):
})
return list_context
@erpnext.allow_regional
def make_regional_gl_entries(gl_entries, doc):
return gl_entries
@frappe.whitelist()
def make_debit_note(source_name, target_doc=None):
from erpnext.controllers.sales_and_purchase_return import make_return_doc

View File

@@ -16,7 +16,7 @@ frappe.listview_settings['Purchase Invoice'] = {
} else if(frappe.datetime.get_diff(doc.due_date) < 0) {
return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<,Today"];
} else {
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due,>=,Today"];
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>=,Today"];
}
} else if(cint(doc.is_return)) {
return [__("Return"), "darkgrey", "is_return,=,Yes"];

View File

@@ -15,6 +15,7 @@ from erpnext.controllers.accounts_controller import get_payment_terms
from erpnext.exceptions import InvalidCurrency
from erpnext.stock.doctype.stock_entry.test_stock_entry import get_qty_after_transaction
from erpnext.accounts.doctype.account.test_account import get_inventory_account
from erpnext.projects.doctype.project.test_project import make_project
test_dependencies = ["Item", "Cost Center", "Payment Term", "Payment Terms Template"]
test_ignore = ["Serial No"]
@@ -86,6 +87,8 @@ class TestPurchaseInvoice(unittest.TestCase):
pe.submit()
pi_doc = frappe.get_doc('Purchase Invoice', pi_doc.name)
pi_doc.load_from_db()
self.assertTrue(pi_doc.status, "Paid")
self.assertRaises(frappe.LinkExistsError, pi_doc.cancel)
unlink_payment_on_cancel_of_invoice()
@@ -203,7 +206,9 @@ class TestPurchaseInvoice(unittest.TestCase):
pi.insert()
pi.submit()
pi.load_from_db()
self.assertTrue(pi.status, "Unpaid")
self.check_gle_for_pi(pi.name)
def check_gle_for_pi(self, pi):
@@ -234,6 +239,9 @@ class TestPurchaseInvoice(unittest.TestCase):
pi = frappe.copy_doc(test_records[0])
pi.insert()
pi.load_from_db()
self.assertTrue(pi.status, "Draft")
pi.naming_series = 'TEST-'
self.assertRaises(frappe.CannotChangeConstantError, pi.save)
@@ -248,6 +256,8 @@ class TestPurchaseInvoice(unittest.TestCase):
pi.get("taxes").pop(1)
pi.insert()
pi.submit()
pi.load_from_db()
self.assertTrue(pi.status, "Unpaid")
gl_entries = frappe.db.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
@@ -425,6 +435,8 @@ class TestPurchaseInvoice(unittest.TestCase):
)
def test_total_purchase_cost_for_project(self):
make_project({'project_name':'_Test Project'})
existing_purchase_cost = frappe.db.sql("""select sum(base_net_amount)
from `tabPurchase Invoice Item` where project = '_Test Project' and docstatus=1""")
existing_purchase_cost = existing_purchase_cost and existing_purchase_cost[0][0] or 0
@@ -599,6 +611,11 @@ class TestPurchaseInvoice(unittest.TestCase):
# return entry
pi1 = make_purchase_invoice(is_return=1, return_against=pi.name, qty=-2, rate=50, update_stock=1)
pi.load_from_db()
self.assertTrue(pi.status, "Debit Note Issued")
pi1.load_from_db()
self.assertTrue(pi1.status, "Return")
actual_qty_2 = get_qty_after_transaction()
self.assertEqual(actual_qty_1 - 2, actual_qty_2)
@@ -771,6 +788,8 @@ class TestPurchaseInvoice(unittest.TestCase):
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import get_outstanding_amount
pi = make_purchase_invoice(item_code = "_Test Item", qty = (5 * -1), rate=500, is_return = 1)
pi.load_from_db()
self.assertTrue(pi.status, "Return")
outstanding_amount = get_outstanding_amount(pi.doctype,
pi.name, "Creditors - _TC", pi.supplier, "Supplier")
@@ -791,11 +810,8 @@ class TestPurchaseInvoice(unittest.TestCase):
pi_doc = frappe.get_doc('Purchase Invoice', pi.name)
self.assertEqual(pi_doc.outstanding_amount, 0)
def test_purchase_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
def test_purchase_invoice_with_cost_center(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
@@ -821,13 +837,7 @@ class TestPurchaseInvoice(unittest.TestCase):
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_purchase_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_purchase_invoice_without_cost_center(self):
cost_center = "_Test Cost Center - _TC"
pi = make_purchase_invoice(credit_to="Creditors - _TC")
@@ -850,6 +860,42 @@ class TestPurchaseInvoice(unittest.TestCase):
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
def test_purchase_invoice_with_project_link(self):
project = make_project({
'project_name': 'Purchase Invoice Project',
'project_template_name': 'Test Project Template',
'start_date': '2020-01-01'
})
item_project = make_project({
'project_name': 'Purchase Invoice Item Project',
'project_template_name': 'Test Project Template',
'start_date': '2019-06-01'
})
pi = make_purchase_invoice(credit_to="Creditors - _TC" ,do_not_save=1)
pi.items[0].project = item_project.project_name
pi.project = project.project_name
pi.submit()
expected_values = {
"Creditors - _TC": {
"project": project.project_name
},
"_Test Account Cost for Goods Sold - _TC": {
"project": item_project.project_name
}
}
gl_entries = frappe.db.sql("""select account, cost_center, project, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
order by account asc""", pi.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["project"], gle.project)
def unlink_payment_on_cancel_of_invoice(enable=1):
accounts_settings = frappe.get_doc("Accounts Settings")

View File

@@ -1,5 +1,4 @@
{
"actions": [],
"autoname": "hash",
"creation": "2013-05-22 12:43:10",
"doctype": "DocType",
@@ -86,6 +85,7 @@
"item_tax_rate",
"bom",
"include_exploded_items",
"purchase_invoice_item",
"col_break6",
"purchase_order",
"po_detail",
@@ -764,12 +764,21 @@
"label": "Asset Category",
"options": "Asset Category",
"read_only": 1
},
{
"depends_on": "eval:parent.update_stock == 1",
"fieldname": "purchase_invoice_item",
"fieldtype": "Data",
"ignore_user_permissions": 1,
"label": "Purchase Invoice Item",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2020-04-07 18:34:35.104178",
"modified": "2020-06-30 16:48:01.398356",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",

View File

@@ -180,14 +180,16 @@ def get_items_list(pos_profile, company):
i.name, i.item_code, i.item_name, i.description, i.item_group, i.has_batch_no,
i.has_serial_no, i.is_stock_item, i.brand, i.stock_uom, i.image,
id.expense_account, id.selling_cost_center, id.default_warehouse,
i.sales_uom, c.conversion_factor
i.sales_uom, c.conversion_factor, it.item_tax_template, it.valid_from
from
`tabItem` i
left join `tabItem Default` id on id.parent = i.name and id.company = %s
left join `tabItem Tax` it on it.parent = i.name
left join `tabUOM Conversion Detail` c on i.name = c.parent and i.sales_uom = c.uom
where
i.disabled = 0 and i.has_variants = 0 and i.is_sales_item = 1
{cond}
group by i.item_code
""".format(cond=cond), tuple([company] + args_list), as_dict=1)

View File

@@ -25,18 +25,26 @@ frappe.ui.form.on("Sales Invoice", {
if(frm.doc.docstatus == 1 && !frm.is_dirty()
&& !frm.doc.is_return && !frm.doc.ewaybill) {
frm.add_custom_button('e-Way Bill JSON', () => {
var w = window.open(
frappe.urllib.get_full_url(
"/api/method/erpnext.regional.india.utils.generate_ewb_json?"
+ "dt=" + encodeURIComponent(frm.doc.doctype)
+ "&dn=" + encodeURIComponent(frm.doc.name)
)
);
if (!w) {
frappe.msgprint(__("Please enable pop-ups")); return;
}
}, __("Make"));
frm.add_custom_button('E-Way Bill JSON', () => {
frappe.call({
method: 'erpnext.regional.india.utils.generate_ewb_json',
args: {
'dt': frm.doc.doctype,
'dn': [frm.doc.name]
},
callback: function(r) {
if (r.message) {
const args = {
cmd: 'erpnext.regional.india.utils.download_ewb_json',
data: r.message,
docname: frm.doc.name
};
open_url_post(frappe.request.url, args);
}
}
});
}, __("Create"));
}
},

View File

@@ -16,17 +16,23 @@ frappe.listview_settings['Sales Invoice'].onload = function (doclist) {
}
}
var w = window.open(
frappe.urllib.get_full_url(
"/api/method/erpnext.regional.india.utils.generate_ewb_json?"
+ "dt=" + encodeURIComponent(doclist.doctype)
+ "&dn=" + encodeURIComponent(docnames)
)
);
if (!w) {
frappe.msgprint(__("Please enable pop-ups")); return;
}
frappe.call({
method: 'erpnext.regional.india.utils.generate_ewb_json',
args: {
'dt': doclist.doctype,
'dn': docnames
},
callback: function(r) {
if (r.message) {
const args = {
cmd: 'erpnext.regional.india.utils.download_ewb_json',
data: r.message,
docname: docnames
};
open_url_post(frappe.request.url, args);
}
}
});
};
doclist.page.add_actions_menu_item(__('Generate e-Way Bill JSON'), action, false);

View File

@@ -32,6 +32,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
me.frm.script_manager.trigger("is_pos");
me.frm.refresh_fields();
}
erpnext.queries.setup_warehouse_query(this.frm);
},
refresh: function(doc, dt, dn) {

View File

@@ -74,9 +74,9 @@
"base_total",
"base_net_total",
"column_break_32",
"total_net_weight",
"total",
"net_total",
"total_net_weight",
"taxes_section",
"taxes_and_charges",
"column_break_38",
@@ -148,9 +148,9 @@
"edit_printing_settings",
"letter_head",
"group_same_items",
"language",
"column_break_84",
"select_print_heading",
"column_break_84",
"language",
"more_information",
"inter_company_invoice_reference",
"customer_group",
@@ -396,7 +396,7 @@
{
"allow_on_submit": 1,
"fieldname": "po_no",
"fieldtype": "Data",
"fieldtype": "Small Text",
"label": "Customer's Purchase Order",
"no_copy": 1,
"print_hide": 1
@@ -1493,6 +1493,7 @@
"print_hide": 1
},
{
"collapsible": 1,
"fieldname": "subscription_section",
"fieldtype": "Section Break",
"label": "Subscription Section"
@@ -1568,7 +1569,7 @@
"icon": "fa fa-file-text",
"idx": 181,
"is_submittable": 1,
"modified": "2020-02-10 04:57:11.221180",
"modified": "2020-07-01 12:41:29.484813",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -552,6 +552,8 @@ class SalesInvoice(SellingController):
continue
for d in self.get('items'):
if not d.item_code: continue
is_stock_item = frappe.get_cached_value('Item', d.item_code, 'is_stock_item')
if (d.item_code and is_stock_item ==1 and not d.get(key.lower().replace(' ', '_')) and not self.get(value[1])):
msgprint(_("{0} is mandatory for Item {1}").format(key, d.item_code), raise_exception=1)
@@ -574,14 +576,14 @@ class SalesInvoice(SellingController):
def validate_item_code(self):
for d in self.get('items'):
if not d.item_code:
if not d.item_code and self.is_opening == "No":
msgprint(_("Item Code required at Row No {0}").format(d.idx), raise_exception=True)
def validate_warehouse(self):
super(SalesInvoice, self).validate_warehouse()
for d in self.get_item_list():
if not d.warehouse and frappe.get_cached_value("Item", d.item_code, "is_stock_item"):
if not d.warehouse and d.item_code and frappe.get_cached_value("Item", d.item_code, "is_stock_item"):
frappe.throw(_("Warehouse required for stock Item {0}").format(d.item_code))
def validate_delivery_note(self):
@@ -784,8 +786,9 @@ class SalesInvoice(SellingController):
if self.party_account_currency==self.company_currency else grand_total,
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency)
"cost_center": self.cost_center,
"project": self.project
}, self.party_account_currency, item=self)
)
def make_tax_gl_entries(self, gl_entries):
@@ -802,7 +805,7 @@ class SalesInvoice(SellingController):
tax.precision("base_tax_amount_after_discount_amount")) if account_currency==self.company_currency else
flt(tax.tax_amount_after_discount_amount, tax.precision("tax_amount_after_discount_amount"))),
"cost_center": tax.cost_center
}, account_currency)
}, account_currency, item=tax)
)
def make_item_gl_entries(self, gl_entries):
@@ -822,7 +825,7 @@ class SalesInvoice(SellingController):
for gle in fixed_asset_gl_entries:
gle["against"] = self.customer
gl_entries.append(self.get_gl_dict(gle))
gl_entries.append(self.get_gl_dict(gle, item=item))
asset.db_set("disposal_date", self.posting_date)
asset.set_status("Sold" if self.docstatus==1 else None)
@@ -839,7 +842,8 @@ class SalesInvoice(SellingController):
"credit_in_account_currency": (flt(item.base_net_amount, item.precision("base_net_amount"))
if account_currency==self.company_currency
else flt(item.net_amount, item.precision("net_amount"))),
"cost_center": item.cost_center
"cost_center": item.cost_center,
"project": item.project or self.project
}, account_currency, item=item)
)
@@ -860,7 +864,7 @@ class SalesInvoice(SellingController):
"against_voucher": self.return_against if cint(self.is_return) else self.name,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center
})
}, item=self)
)
gl_entries.append(
self.get_gl_dict({
@@ -869,7 +873,7 @@ class SalesInvoice(SellingController):
"against": self.customer,
"debit": self.loyalty_amount,
"remark": "Loyalty Points redeemed by the customer"
})
}, item=self)
)
def make_pos_gl_entries(self, gl_entries):
@@ -890,7 +894,7 @@ class SalesInvoice(SellingController):
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency)
}, self.party_account_currency, item=self)
)
payment_mode_account_currency = get_account_currency(payment_mode.account)
@@ -903,7 +907,7 @@ class SalesInvoice(SellingController):
if payment_mode_account_currency==self.company_currency \
else payment_mode.amount,
"cost_center": self.cost_center
}, payment_mode_account_currency)
}, payment_mode_account_currency, item=self)
)
def make_gle_for_change_amount(self, gl_entries):
@@ -920,8 +924,9 @@ class SalesInvoice(SellingController):
if self.party_account_currency==self.company_currency else flt(self.change_amount),
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency)
"cost_center": self.cost_center,
"project": self.project
}, self.party_account_currency, item=self)
)
gl_entries.append(
@@ -930,7 +935,7 @@ class SalesInvoice(SellingController):
"against": self.customer,
"credit": self.base_change_amount,
"cost_center": self.cost_center
})
}, item=self)
)
else:
frappe.throw(_("Select change amount account"), title="Mandatory Field")
@@ -953,8 +958,9 @@ class SalesInvoice(SellingController):
else flt(self.write_off_amount, self.precision("write_off_amount"))),
"against_voucher": self.return_against if cint(self.is_return) else self.name,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency)
"cost_center": self.cost_center,
"project": self.project
}, self.party_account_currency, item=self)
)
gl_entries.append(
self.get_gl_dict({
@@ -965,7 +971,7 @@ class SalesInvoice(SellingController):
self.precision("base_write_off_amount")) if write_off_account_currency==self.company_currency
else flt(self.write_off_amount, self.precision("write_off_amount"))),
"cost_center": self.cost_center or self.write_off_cost_center or default_cost_center
}, write_off_account_currency)
}, write_off_account_currency, item=self)
)
def make_gle_for_rounding_adjustment(self, gl_entries):
@@ -982,8 +988,7 @@ class SalesInvoice(SellingController):
"credit": flt(self.base_rounding_adjustment,
self.precision("base_rounding_adjustment")),
"cost_center": self.cost_center or round_off_cost_center,
}
))
}, item=self))
def update_billing_status_in_dn(self, update_modified=True):
updated_delivery_notes = []
@@ -1104,7 +1109,10 @@ class SalesInvoice(SellingController):
expiry_date=self.posting_date, include_expired_entry=True)
if lp_details and getdate(lp_details.from_date) <= getdate(self.posting_date) and \
(not lp_details.to_date or getdate(lp_details.to_date) >= getdate(self.posting_date)):
points_earned = cint(eligible_amount/lp_details.collection_factor)
collection_factor = lp_details.collection_factor if lp_details.collection_factor else 1.0
points_earned = cint(eligible_amount/collection_factor)
doc = frappe.get_doc({
"doctype": "Loyalty Point Entry",
"company": self.company,

View File

@@ -3,6 +3,7 @@
"company": "_Test Company",
"conversion_rate": 1.0,
"currency": "INR",
"cost_center": "_Test Cost Center - _TC",
"customer": "_Test Customer",
"customer_name": "_Test Customer",
"debit_to": "_Test Receivable - _TC",
@@ -37,7 +38,8 @@
"charge_type": "On Net Total",
"description": "VAT",
"doctype": "Sales Taxes and Charges",
"parentfield": "taxes",
"parentfield": "taxes",
"cost_center": "_Test Cost Center - _TC",
"rate": 6
},
{
@@ -45,7 +47,8 @@
"charge_type": "On Net Total",
"description": "Service Tax",
"doctype": "Sales Taxes and Charges",
"parentfield": "taxes",
"parentfield": "taxes",
"cost_center": "_Test Cost Center - _TC",
"rate": 6.36
}
],
@@ -76,6 +79,7 @@
"customer_name": "_Test Customer",
"debit_to": "_Test Receivable - _TC",
"doctype": "Sales Invoice",
"cost_center": "_Test Cost Center - _TC",
"items": [
{
"amount": 500.0,
@@ -107,7 +111,8 @@
"charge_type": "On Net Total",
"description": "VAT",
"doctype": "Sales Taxes and Charges",
"parentfield": "taxes",
"parentfield": "taxes",
"cost_center": "_Test Cost Center - _TC",
"rate": 16
},
{
@@ -115,7 +120,8 @@
"charge_type": "On Net Total",
"description": "Service Tax",
"doctype": "Sales Taxes and Charges",
"parentfield": "taxes",
"parentfield": "taxes",
"cost_center": "_Test Cost Center - _TC",
"rate": 10
}
],
@@ -132,6 +138,7 @@
"customer_name": "_Test Customer",
"debit_to": "_Test Receivable - _TC",
"doctype": "Sales Invoice",
"cost_center": "_Test Cost Center - _TC",
"items": [
{
"cost_center": "_Test Cost Center - _TC",
@@ -259,6 +266,7 @@
"customer_name": "_Test Customer",
"debit_to": "_Test Receivable - _TC",
"doctype": "Sales Invoice",
"cost_center": "_Test Cost Center - _TC",
"items": [
{
"cost_center": "_Test Cost Center - _TC",

View File

@@ -206,10 +206,19 @@ class TestSalesInvoice(unittest.TestCase):
"rate": 14,
'included_in_print_rate': 1
})
si.append("taxes", {
"charge_type": "On Item Quantity",
"account_head": "_Test Account Education Cess - _TC",
"cost_center": "_Test Cost Center - _TC",
"description": "CESS",
"rate": 5,
'included_in_print_rate': 1
})
si.insert()
# with inclusive tax
self.assertEqual(si.net_total, 4385.96)
self.assertEqual(si.items[0].net_amount, 3947.368421052631)
self.assertEqual(si.net_total, 3947.37)
self.assertEqual(si.grand_total, 5000)
si.reload()
@@ -222,8 +231,8 @@ class TestSalesInvoice(unittest.TestCase):
si.save()
# with inclusive tax and additional discount
self.assertEqual(si.net_total, 4285.96)
self.assertEqual(si.grand_total, 4885.99)
self.assertEqual(si.net_total, 3847.37)
self.assertEqual(si.grand_total, 4886)
si.reload()
@@ -235,7 +244,7 @@ class TestSalesInvoice(unittest.TestCase):
si.save()
# with inclusive tax and additional discount
self.assertEqual(si.net_total, 4298.25)
self.assertEqual(si.net_total, 3859.65)
self.assertEqual(si.grand_total, 4900.00)
def test_sales_invoice_discount_amount(self):
@@ -1575,11 +1584,8 @@ class TestSalesInvoice(unittest.TestCase):
si_doc = frappe.get_doc('Sales Invoice', si.name)
self.assertEqual(si_doc.outstanding_amount, 0)
def test_sales_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
def test_sales_invoice_with_cost_center(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
@@ -1604,14 +1610,47 @@ class TestSalesInvoice(unittest.TestCase):
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
def test_sales_invoice_with_project_link(self):
from erpnext.projects.doctype.project.test_project import make_project
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
project = make_project({
'project_name': 'Sales Invoice Project',
'project_template_name': 'Test Project Template',
'start_date': '2020-01-01'
})
item_project = make_project({
'project_name': 'Sales Invoice Item Project',
'project_template_name': 'Test Project Template',
'start_date': '2019-06-01'
})
def test_sales_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
sales_invoice = create_sales_invoice(do_not_save=1)
sales_invoice.items[0].project = item_project.project_name
sales_invoice.project = project.project_name
sales_invoice.submit()
expected_values = {
"Debtors - _TC": {
"project": project.project_name
},
"Sales - _TC": {
"project": item_project.project_name
}
}
gl_entries = frappe.db.sql("""select account, cost_center, project, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
order by account asc""", sales_invoice.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["project"], gle.project)
def test_sales_invoice_without_cost_center(self):
cost_center = "_Test Cost Center - _TC"
si = create_sales_invoice(debit_to="Debtors - _TC")
@@ -1634,9 +1673,6 @@ class TestSalesInvoice(unittest.TestCase):
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_deferred_revenue(self):
deferred_account = create_account(account_name="Deferred Revenue",
parent_account="Current Liabilities - _TC", company="_Test Company")
@@ -1834,7 +1870,7 @@ class TestSalesInvoice(unittest.TestCase):
si.submit()
data = get_ewb_data("Sales Invoice", si.name)
data = get_ewb_data("Sales Invoice", [si.name])
self.assertEqual(data['version'], '1.0.1118')
self.assertEqual(data['billLists'][0]['fromGstin'], '27AAECE4835E1ZR')

View File

@@ -1,5 +1,4 @@
{
"actions": [],
"autoname": "hash",
"creation": "2013-06-04 11:02:19",
"doctype": "DocType",
@@ -87,6 +86,7 @@
"edit_references",
"sales_order",
"so_detail",
"sales_invoice_item",
"column_break_74",
"delivery_note",
"dn_detail",
@@ -94,6 +94,7 @@
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
"project",
"section_break_54",
"page_break"
],
@@ -783,12 +784,28 @@
"fieldtype": "Link",
"label": "Finance Book",
"options": "Finance Book"
},
{
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
"options": "Project"
},
{
"depends_on": "eval:parent.update_stock == 1",
"fieldname": "sales_invoice_item",
"fieldtype": "Data",
"ignore_user_permissions": 1,
"label": "Sales Invoice Item",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2019-12-04 12:22:38.517710",
"modified": "2020-08-20 11:24:41.749986",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",

View File

@@ -1,314 +1,89 @@
{
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2016-05-08 23:49:38.842621",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"creation": "2016-05-08 23:49:38.842621",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"default",
"mode_of_payment",
"amount",
"column_break_3",
"account",
"type",
"base_amount",
"clearance_date"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:parent.doctype == 'POS Profile'",
"fetch_if_empty": 0,
"fieldname": "default",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Default",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"default": "0",
"depends_on": "eval:parent.doctype == 'POS Profile'",
"fieldname": "default",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Default"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "mode_of_payment",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Mode of Payment",
"length": 0,
"no_copy": 0,
"options": "Mode of Payment",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "mode_of_payment",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Mode of Payment",
"options": "Mode of Payment",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"depends_on": "eval:parent.doctype == 'Sales Invoice'",
"fetch_if_empty": 0,
"fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Amount",
"length": 0,
"no_copy": 0,
"options": "currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"default": "0",
"depends_on": "eval:parent.doctype == 'Sales Invoice'",
"fieldname": "amount",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Amount",
"options": "currency",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "column_break_3",
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Account",
"length": 0,
"no_copy": 0,
"options": "Account",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "account",
"fieldtype": "Link",
"label": "Account",
"options": "Account",
"print_hide": 1,
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "mode_of_payment.type",
"fetch_if_empty": 0,
"fieldname": "type",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Type",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fetch_from": "mode_of_payment.type",
"fieldname": "type",
"fieldtype": "Read Only",
"label": "Type"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Base Amount (Company Currency)",
"length": 0,
"no_copy": 1,
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "base_amount",
"fieldtype": "Currency",
"label": "Base Amount (Company Currency)",
"no_copy": 1,
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "clearance_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Clearance Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"fieldname": "clearance_date",
"fieldtype": "Date",
"label": "Clearance Date",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2019-03-19 14:54:56.524556",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Payment",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0,
"track_views": 0
],
"istable": 1,
"modified": "2020-08-03 13:07:49.260534",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Payment",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC"
}

View File

@@ -45,7 +45,9 @@ class ShippingRule(Document):
shipping_amount = 0.0
by_value = False
self.validate_countries(doc)
if doc.get_shipping_address():
# validate country only if there is address
self.validate_countries(doc)
if self.calculate_based_on == 'Net Total':
value = doc.base_net_total

View File

@@ -6,23 +6,42 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import flt
from frappe.utils import flt, getdate
from erpnext.accounts.utils import get_fiscal_year
class TaxWithholdingCategory(Document):
pass
def get_party_tax_withholding_details(ref_doc):
tax_withholding_category = frappe.db.get_value('Supplier', ref_doc.supplier, 'tax_withholding_category')
def get_party_tax_withholding_details(ref_doc, tax_withholding_category=None):
pan_no = ''
suppliers = []
if not tax_withholding_category:
tax_withholding_category, pan_no = frappe.db.get_value('Supplier', ref_doc.supplier, ['tax_withholding_category', 'pan'])
if not tax_withholding_category:
return
if not pan_no:
pan_no = frappe.db.get_value('Supplier', ref_doc.supplier, 'pan')
# Get others suppliers with the same PAN No
if pan_no:
suppliers = [d.name for d in frappe.get_all('Supplier', fields=['name'], filters={'pan': pan_no})]
if not suppliers:
suppliers.append(ref_doc.supplier)
fy = get_fiscal_year(ref_doc.posting_date, company=ref_doc.company)
tax_details = get_tax_withholding_details(tax_withholding_category, fy[0], ref_doc.company)
if not tax_details:
frappe.throw(_('Please set associated account in Tax Withholding Category {0} against Company {1}')
.format(tax_withholding_category, ref_doc.company))
tds_amount = get_tds_amount(ref_doc, tax_details, fy)
tds_amount = get_tds_amount(suppliers, ref_doc.net_total, ref_doc.company,
tax_details, fy, ref_doc.posting_date, pan_no)
tax_row = get_tax_row(tax_details, tds_amount)
return tax_row
@@ -39,7 +58,7 @@ def get_tax_withholding_details(tax_withholding_category, fiscal_year, company):
"rate": tax_rate_detail.tax_withholding_rate,
"threshold": tax_rate_detail.single_threshold,
"cumulative_threshold": tax_rate_detail.cumulative_threshold,
"description": tax_withholding.category_name
"description": tax_withholding.category_name if tax_withholding.category_name else tax_withholding_category
})
def get_tax_withholding_rates(tax_withholding, fiscal_year):
@@ -51,6 +70,7 @@ def get_tax_withholding_rates(tax_withholding, fiscal_year):
frappe.throw(_("No Tax Withholding data found for the current Fiscal Year."))
def get_tax_row(tax_details, tds_amount):
return {
"category": "Total",
"add_deduct_tax": "Deduct",
@@ -60,25 +80,36 @@ def get_tax_row(tax_details, tds_amount):
"tax_amount": tds_amount
}
def get_tds_amount(ref_doc, tax_details, fiscal_year_details):
def get_tds_amount(suppliers, net_total, company, tax_details, fiscal_year_details, posting_date, pan_no=None):
fiscal_year, year_start_date, year_end_date = fiscal_year_details
tds_amount = 0
tds_deducted = 0
def _get_tds(amount):
def _get_tds(amount, rate):
if amount <= 0:
return 0
return amount * tax_details.rate / 100
return amount * rate / 100
ldc_name = frappe.db.get_value('Lower Deduction Certificate',
{
'pan_no': pan_no,
'fiscal_year': fiscal_year
}, 'name')
ldc = ''
if ldc_name:
ldc = frappe.get_doc('Lower Deduction Certificate', ldc_name)
entries = frappe.db.sql("""
select voucher_no, credit
from `tabGL Entry`
where party=%s and fiscal_year=%s and credit > 0
""", (ref_doc.supplier, fiscal_year), as_dict=1)
where company = %s and
party in %s and fiscal_year=%s and credit > 0
""", (company, tuple(suppliers), fiscal_year), as_dict=1)
vouchers = [d.voucher_no for d in entries]
advance_vouchers = get_advance_vouchers(ref_doc.supplier, fiscal_year)
advance_vouchers = get_advance_vouchers(suppliers, fiscal_year=fiscal_year, company=company)
tds_vouchers = vouchers + advance_vouchers
@@ -93,7 +124,20 @@ def get_tds_amount(ref_doc, tax_details, fiscal_year_details):
tds_deducted = tds_deducted[0][0] if tds_deducted and tds_deducted[0][0] else 0
if tds_deducted:
tds_amount = _get_tds(ref_doc.net_total)
if ldc:
limit_consumed = frappe.db.get_value('Purchase Invoice',
{
'supplier': ('in', suppliers),
'apply_tds': 1,
'docstatus': 1
}, 'sum(net_total)')
if ldc and is_valid_certificate(ldc.valid_from, ldc.valid_upto, posting_date, limit_consumed, net_total,
ldc.certificate_limit):
tds_amount = get_ltds_amount(net_total, limit_consumed, ldc.certificate_limit, ldc.rate, tax_details)
else:
tds_amount = _get_tds(net_total, tax_details.rate)
else:
supplier_credit_amount = frappe.get_all('Purchase Invoice Item',
fields = ['sum(net_amount)'],
@@ -106,43 +150,79 @@ def get_tds_amount(ref_doc, tax_details, fiscal_year_details):
fields = ['sum(credit_in_account_currency)'],
filters = {
'parent': ('in', vouchers), 'docstatus': 1,
'party': ref_doc.supplier,
'party': ('in', suppliers),
'reference_type': ('not in', ['Purchase Invoice'])
}, as_list=1)
supplier_credit_amount += (jv_supplier_credit_amt[0][0]
if jv_supplier_credit_amt and jv_supplier_credit_amt[0][0] else 0)
supplier_credit_amount += ref_doc.net_total
supplier_credit_amount += net_total
debit_note_amount = get_debit_note_amount(ref_doc.supplier, year_start_date, year_end_date)
debit_note_amount = get_debit_note_amount(suppliers, year_start_date, year_end_date)
supplier_credit_amount -= debit_note_amount
if ((tax_details.get('threshold', 0) and supplier_credit_amount >= tax_details.threshold)
or (tax_details.get('cumulative_threshold', 0) and supplier_credit_amount >= tax_details.cumulative_threshold)):
tds_amount = _get_tds(supplier_credit_amount)
if ldc and is_valid_certificate(ldc.valid_from, ldc.valid_upto, posting_date, tds_deducted, net_total,
ldc.certificate_limit):
tds_amount = get_ltds_amount(supplier_credit_amount, 0, ldc.certificate_limit, ldc.rate,
tax_details)
else:
tds_amount = _get_tds(supplier_credit_amount, tax_details.rate)
return tds_amount
def get_advance_vouchers(supplier, fiscal_year=None, company=None, from_date=None, to_date=None):
def get_advance_vouchers(suppliers, fiscal_year=None, company=None, from_date=None, to_date=None):
condition = "fiscal_year=%s" % fiscal_year
if company:
condition += "and company =%s" % (company)
if from_date and to_date:
condition = "company=%s and posting_date between %s and %s" % (company, from_date, to_date)
condition += "and posting_date between %s and %s" % (from_date, to_date)
## Appending the same supplier again if length of suppliers list is 1
## since tuple of single element list contains None, For example ('Test Supplier 1', )
## and the below query fails
if len(suppliers) == 1:
suppliers.append(suppliers[0])
return frappe.db.sql_list("""
select distinct voucher_no
from `tabGL Entry`
where party=%s and %s and debit > 0
""", (supplier, condition)) or []
where party in %s and %s and debit > 0
""", (tuple(suppliers), condition)) or []
def get_debit_note_amount(supplier, year_start_date, year_end_date, company=None):
condition = ""
def get_debit_note_amount(suppliers, year_start_date, year_end_date, company=None):
condition = "and 1=1"
if company:
condition = " and company=%s " % company
if len(suppliers) == 1:
suppliers.append(suppliers[0])
return flt(frappe.db.sql("""
select abs(sum(net_total))
from `tabPurchase Invoice`
where supplier=%s %s and is_return=1 and docstatus=1
and posting_date between %s and %s
""", (supplier, condition, year_start_date, year_end_date)))
where supplier in %s and is_return=1 and docstatus=1
and posting_date between %s and %s %s
""", (tuple(suppliers), year_start_date, year_end_date, condition)))
def get_ltds_amount(current_amount, deducted_amount, certificate_limit, rate, tax_details):
if current_amount < (certificate_limit - deducted_amount):
return current_amount * rate/100
else:
ltds_amount = (certificate_limit - deducted_amount)
tds_amount = current_amount - ltds_amount
return ltds_amount * rate/100 + tds_amount * tax_details.rate/100
def is_valid_certificate(valid_from, valid_upto, posting_date, deducted_amount, current_amount, certificate_limit):
valid = False
if ((getdate(valid_from) <= getdate(posting_date) <= getdate(valid_upto)) and
certificate_limit > deducted_amount):
valid = True
return valid

View File

@@ -45,8 +45,8 @@ def validate_accounting_period(gl_map):
}, as_dict=1)
if accounting_periods:
frappe.throw(_("You can't create accounting entries in the closed accounting period {0}")
.format(accounting_periods[0].name), ClosedAccountingPeriod)
frappe.throw(_("You cannot create or cancel any accounting entries within in the closed Accounting Period {0}")
.format(frappe.bold(accounting_periods[0].name)), ClosedAccountingPeriod)
def process_gl_map(gl_map, merge_entries=True):
if merge_entries:
@@ -296,6 +296,7 @@ def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no), as_dict=True)
if gl_entries:
validate_accounting_period(gl_entries)
check_freezing_date(gl_entries[0]["posting_date"], adv_adj)
frappe.db.sql("""delete from `tabGL Entry` where voucher_type=%s and voucher_no=%s""",

View File

@@ -285,6 +285,8 @@ def get_matching_transactions_payments(description_matching):
else:
return []
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def payment_entry_query(doctype, txt, searchfield, start, page_len, filters):
account = frappe.db.get_value("Bank Account", filters.get("bank_account"), "account")
if not account:
@@ -313,6 +315,8 @@ def payment_entry_query(doctype, txt, searchfield, start, page_len, filters):
}
)
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def journal_entry_query(doctype, txt, searchfield, start, page_len, filters):
account = frappe.db.get_value("Bank Account", filters.get("bank_account"), "account")
@@ -348,6 +352,8 @@ def journal_entry_query(doctype, txt, searchfield, start, page_len, filters):
}
)
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def sales_invoices_query(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""
SELECT
@@ -373,4 +379,4 @@ def sales_invoices_query(doctype, txt, searchfield, start, page_len, filters):
'start': start,
'page_len': page_len
}
)
)

View File

@@ -1062,7 +1062,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}
if(index < me.page_len) {
$(frappe.render_template("pos_item", {
item_code: obj.name,
item_code: escape(obj.name),
item_price: item_price,
item_name: obj.name === obj.item_name ? "" : obj.item_name,
item_image: obj.image,
@@ -1098,7 +1098,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
get_items: function (item_code) {
// To search item as per the key enter
item_code = unescape(item_code);
item_code = item_code === "undefined" ? undefined : item_code;
var me = this;
this.item_serial_no = {};
this.item_batch_no = {};
@@ -1164,7 +1165,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
$(this).addClass('active');
me.numeric_val = "";
me.numeric_id = ""
me.item_code = $(this).attr("data-item-code");
me.item_code = unescape($(this).attr("data-item-code"));
me.render_selected_item()
me.bind_qty_event()
me.update_rate()
@@ -1176,33 +1177,33 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
var me = this;
$(this.wrapper).on("change", ".pos-item-qty", function () {
var item_code = $(this).parents(".pos-selected-item-action").attr("data-item-code");
var item_code = unescape($(this).parents(".pos-selected-item-action").attr("data-item-code"));
var qty = $(this).val();
me.update_qty(item_code, qty);
me.update_value();
})
$(this.wrapper).on("focusout", ".pos-item-qty", function () {
var item_code = $(this).parents(".pos-selected-item-action").attr("data-item-code");
var item_code = unescape($(this).parents(".pos-selected-item-action").attr("data-item-code"));
var qty = $(this).val();
me.update_qty(item_code, qty, true);
me.update_value();
})
$(this.wrapper).find("[data-action='increase-qty']").on("click", function () {
var item_code = $(this).parents(".pos-bill-item").attr("data-item-code");
var item_code = unescape($(this).parents(".pos-bill-item").attr("data-item-code"));
var qty = flt($(this).parents(".pos-bill-item").find('.pos-item-qty').val()) + 1;
me.update_qty(item_code, qty);
})
$(this.wrapper).find("[data-action='decrease-qty']").on("click", function () {
var item_code = $(this).parents(".pos-bill-item").attr("data-item-code");
var item_code = unescape($(this).parents(".pos-bill-item").attr("data-item-code"));
var qty = flt($(this).parents(".pos-bill-item").find('.pos-item-qty').val()) - 1;
me.update_qty(item_code, qty);
})
$(this.wrapper).on("change", ".pos-item-disc", function () {
var item_code = $(this).parents(".pos-selected-item-action").attr("data-item-code");
var item_code = unescape($(this).parents(".pos-selected-item-action").attr("data-item-code"));
var discount = $(this).val();
if(discount > 100){
discount = $(this).val('');
@@ -1253,7 +1254,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
update_rate: function () {
var me = this;
$(this.wrapper).on("change", ".pos-item-price", function () {
var item_code = $(this).parents(".pos-selected-item-action").attr("data-item-code");
var item_code = unescape($(this).parents(".pos-selected-item-action").attr("data-item-code"));
me.set_item_details(item_code, "rate", $(this).val());
me.update_value()
})
@@ -1282,9 +1283,17 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.child_doc = this.get_child_item(this.item_code);
$(this.wrapper).find('.selected-item').empty();
if(this.child_doc.length) {
this.child_doc[0]["allow_user_to_edit_rate"] = this.pos_profile_data["allow_user_to_edit_rate"] ? true : false,
this.child_doc[0]["allow_user_to_edit_discount"] = this.pos_profile_data["allow_user_to_edit_discount"] ? true : false;
this.selected_row = $(frappe.render_template("pos_selected_item", this.child_doc[0]))
this.selected_row = $(frappe.render_template("pos_selected_item", {
idx: this.child_doc[0].idx,
item_code: escape(this.child_doc[0].item_code),
qty: this.child_doc[0].qty,
price_list_rate: this.child_doc[0].price_list_rate,
allow_user_to_edit_rate: this.pos_profile_data["allow_user_to_edit_rate"] ? true : false,
allow_user_to_edit_discount: this.pos_profile_data["allow_user_to_edit_discount"] ? true : false,
discount_percentage: this.child_doc[0].discount_percentage,
rate: this.child_doc[0].rate,
amount: this.child_doc[0].amount
}))
$(this.wrapper).find('.selected-item').html(this.selected_row)
}
@@ -1458,7 +1467,40 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.child.batch_no = this.item_batch_no[this.child.item_code];
this.child.serial_no = (this.item_serial_no[this.child.item_code]
? this.item_serial_no[this.child.item_code][0] : '');
this.child.item_tax_rate = JSON.stringify(this.tax_data[this.child.item_code]);
const tax_template_is_valid = true;
if (this.items && this.items[0].valid_from) {
tax_template_is_valid = frappe.datetime.get_diff(frappe.datetime.now_date(),
this.items[0].valid_from) > 0;
}
this.child.item_tax_template = tax_template_is_valid ? this.items[0].item_tax_template : '';
this.child.item_tax_rate = JSON.stringify(this.tax_data[this.child.item_tax_template]);
if (this.child.item_tax_rate) {
this.add_taxes_from_item_tax_template(this.child.item_tax_rate);
}
},
add_taxes_from_item_tax_template: function(item_tax_map) {
let me = this;
if(item_tax_map && cint(frappe.defaults.get_default("add_taxes_from_item_tax_template"))) {
if(typeof (item_tax_map) == "string") {
item_tax_map = JSON.parse(item_tax_map);
}
$.each(item_tax_map, function(tax, rate) {
let found = (me.frm.doc.taxes || []).find(d => d.account_head === tax);
if(!found) {
let child = frappe.model.add_child(me.frm.doc, "taxes");
child.charge_type = "On Net Total";
child.account_head = tax;
child.description = String(tax);
child.rate = rate;
}
});
}
},
update_paid_amount_status: function (update_paid_amount) {
@@ -1502,7 +1544,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
$.each(this.frm.doc.items || [], function (i, d) {
$(frappe.render_template("pos_bill_item_new", {
item_code: d.item_code,
item_code: escape(d.item_code),
item_name: (d.item_name === d.item_code || !d.item_name) ? "" : ("<br>" + d.item_name),
qty: d.qty,
discount_percentage: d.discount_percentage || 0.0,

View File

@@ -163,7 +163,7 @@ def get_default_price_list(party):
def set_price_list(party_details, party, party_type, given_price_list, pos=None):
# price list
price_list = get_permitted_documents('Price List')
# if there is only one permitted document based on user permissions, set it
if price_list and len(price_list) == 1:
price_list = price_list[0]
@@ -468,23 +468,25 @@ def get_timeline_data(doctype, name):
from frappe.desk.form.load import get_communication_data
out = {}
fields = 'date(creation), count(name)'
fields = 'creation, count(*)'
after = add_years(None, -1).strftime('%Y-%m-%d')
group_by='group by date(creation)'
group_by='group by Date(creation)'
data = get_communication_data(doctype, name, after=after, group_by='group by date(creation)',
fields='date(C.creation) as creation, count(C.name)',as_dict=False)
data = get_communication_data(doctype, name, after=after, group_by='group by creation',
fields='C.creation as creation, count(C.name)',as_dict=False)
# fetch and append data from Activity Log
data += frappe.db.sql("""select {fields}
from `tabActivity Log`
where (reference_doctype="{doctype}" and reference_name="{name}")
or (timeline_doctype in ("{doctype}") and timeline_name="{name}")
or (reference_doctype in ("Quotation", "Opportunity") and timeline_name="{name}")
where (reference_doctype=%(doctype)s and reference_name=%(name)s)
or (timeline_doctype in (%(doctype)s) and timeline_name=%(name)s)
or (reference_doctype in ("Quotation", "Opportunity") and timeline_name=%(name)s)
and status!='Success' and creation > {after}
{group_by} order by creation desc
""".format(doctype=frappe.db.escape(doctype), name=frappe.db.escape(name), fields=fields,
group_by=group_by, after=after), as_dict=False)
""".format(fields=fields, group_by=group_by, after=after), {
"doctype": doctype,
"name": name
}, as_dict=False)
timeline_items = dict(data)
@@ -603,10 +605,16 @@ def get_party_shipping_address(doctype, name):
else:
return ''
def get_partywise_advanced_payment_amount(party_type, posting_date = None):
def get_partywise_advanced_payment_amount(party_type, posting_date = None, future_payment=0, company=None):
cond = "1=1"
if posting_date:
cond = "posting_date <= '{0}'".format(posting_date)
if future_payment:
cond = "posting_date <= '{0}' OR DATE(creation) <= '{0}' """.format(posting_date)
else:
cond = "posting_date <= '{0}'".format(posting_date)
if company:
cond += "and company = '{0}'".format(company)
data = frappe.db.sql(""" SELECT party, sum({0}) as amount
FROM `tabGL Entry`

View File

@@ -61,7 +61,7 @@ def make_sales_invoice():
debit_to = 'Debtors - _TC2',
income_account = 'Sales - _TC2',
expense_account = 'Cost of Goods Sold - _TC2',
cost_center = '_Test Company 2 - _TC2')
cost_center = 'Main - _TC2')

View File

@@ -135,12 +135,5 @@ frappe.query_reports["Accounts Payable"] = {
}
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["Accounts Payable"].filters.splice(9, 0 ,{
"fieldname": dimension["fieldname"],
"label": __(dimension["label"]),
"fieldtype": "Link",
"options": dimension["document_type"]
});
});
erpnext.utils.add_dimensions('Accounts Payable', 9);

View File

@@ -104,12 +104,5 @@ frappe.query_reports["Accounts Payable Summary"] = {
}
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["Accounts Payable Summary"].filters.splice(9, 0 ,{
"fieldname": dimension["fieldname"],
"label": __(dimension["label"]),
"fieldtype": "Link",
"options": dimension["document_type"]
});
});
erpnext.utils.add_dimensions('Accounts Payable Summary', 9);

View File

@@ -199,12 +199,5 @@ frappe.query_reports["Accounts Receivable"] = {
}
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["Accounts Receivable"].filters.splice(9, 0 ,{
"fieldname": dimension["fieldname"],
"label": __(dimension["label"]),
"fieldtype": "Link",
"options": dimension["document_type"]
});
});
erpnext.utils.add_dimensions('Accounts Receivable', 9);

View File

@@ -169,9 +169,11 @@ class ReceivablePayableReport(object):
def append_subtotal_row(self, party):
sub_total_row = self.total_row_map.get(party)
self.data.append(sub_total_row)
self.data.append({})
self.update_sub_total_row(sub_total_row, 'Total')
if sub_total_row:
self.data.append(sub_total_row)
self.data.append({})
self.update_sub_total_row(sub_total_row, 'Total')
def get_voucher_balance(self, gle):
if self.filters.get("sales_person"):
@@ -232,7 +234,8 @@ class ReceivablePayableReport(object):
if self.filters.get('group_by_party'):
self.append_subtotal_row(self.previous_party)
self.data.append(self.total_row_map.get('Total'))
if self.data:
self.data.append(self.total_row_map.get('Total'))
def append_row(self, row):
self.allocate_future_payments(row)
@@ -344,26 +347,28 @@ class ReceivablePayableReport(object):
def allocate_outstanding_based_on_payment_terms(self, row):
self.get_payment_terms(row)
for term in row.payment_terms:
term.outstanding = term.invoiced
# update "paid" and "oustanding" for this term
self.allocate_closing_to_term(row, term, 'paid')
if not term.paid:
self.allocate_closing_to_term(row, term, 'paid')
# update "credit_note" and "oustanding" for this term
if term.outstanding:
self.allocate_closing_to_term(row, term, 'credit_note')
row.payment_terms = sorted(row.payment_terms, key=lambda x: x['due_date'])
def get_payment_terms(self, row):
# build payment_terms for row
payment_terms_details = frappe.db.sql("""
select
si.name, si.party_account_currency, si.currency, si.conversion_rate,
ps.due_date, ps.payment_amount, ps.description
ps.due_date, ps.payment_amount, ps.description, ps.paid_amount
from `tab{0}` si, `tabPayment Schedule` ps
where
si.name = ps.parent and
si.name = %s
order by ps.due_date
order by ps.paid_amount desc, due_date
""".format(row.voucher_type), row.voucher_no, as_dict = 1)
@@ -389,11 +394,14 @@ class ReceivablePayableReport(object):
"invoiced": invoiced,
"invoice_grand_total": row.invoiced,
"payment_term": d.description,
"paid": 0.0,
"paid": d.paid_amount,
"credit_note": 0.0,
"outstanding": 0.0
"outstanding": invoiced - d.paid_amount
}))
if d.paid_amount:
row['paid'] -= d.paid_amount
def allocate_closing_to_term(self, row, term, key):
if row[key]:
if row[key] > term.outstanding:
@@ -529,7 +537,7 @@ class ReceivablePayableReport(object):
def get_ageing_data(self, entry_date, row):
# [0-30, 30-60, 60-90, 90-120, 120-above]
row.range1 = row.range2 = row.range3 = row.range4 = range5 = 0.0
row.range1 = row.range2 = row.range3 = row.range4 = row.range5 = 0.0
if not (self.age_as_on and entry_date):
return
@@ -554,6 +562,14 @@ class ReceivablePayableReport(object):
conditions, values = self.prepare_conditions()
order_by = self.get_order_by_condition()
if self.filters.show_future_payments:
values.insert(2, self.filters.report_date)
date_condition = """AND (posting_date <= %s
OR (against_voucher IS NULL AND DATE(creation) <= %s))"""
else:
date_condition = "AND posting_date <=%s"
if self.filters.get(scrub(self.party_type)):
select_fields = "debit_in_account_currency as debit, credit_in_account_currency as credit"
else:
@@ -569,9 +585,8 @@ class ReceivablePayableReport(object):
docstatus < 2
and party_type=%s
and (party is not null and party != '')
and posting_date <= %s
{1} {2}"""
.format(select_fields, conditions, order_by), values, as_dict=True)
{1} {2} {3}"""
.format(select_fields, date_condition, conditions, order_by), values, as_dict=True)
def get_sales_invoices_or_customers_based_on_sales_person(self):
if self.filters.get("sales_person"):
@@ -628,8 +643,10 @@ class ReceivablePayableReport(object):
account_type = "Receivable" if self.party_type == "Customer" else "Payable"
accounts = [d.name for d in frappe.get_all("Account",
filters={"account_type": account_type, "company": self.filters.company})]
conditions.append("account in (%s)" % ','.join(['%s'] *len(accounts)))
values += accounts
if accounts:
conditions.append("account in (%s)" % ','.join(['%s'] *len(accounts)))
values += accounts
def add_customer_filters(self, conditions, values):
if self.filters.get("customer_group"):

View File

@@ -63,7 +63,7 @@ def make_sales_invoice():
debit_to = 'Debtors - _TC2',
income_account = 'Sales - _TC2',
expense_account = 'Cost of Goods Sold - _TC2',
cost_center = '_Test Company 2 - _TC2',
cost_center = 'Main - _TC2',
do_not_save=1)
si.append('payment_schedule', dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30))
@@ -83,14 +83,14 @@ def make_payment(docname):
def make_credit_note(docname):
create_sales_invoice(company="_Test Company 2",
customer = '_Test Customer 2',
currency = 'EUR',
qty = -1,
warehouse = 'Finished Goods - _TC2',
debit_to = 'Debtors - _TC2',
income_account = 'Sales - _TC2',
expense_account = 'Cost of Goods Sold - _TC2',
cost_center = '_Test Company 2 - _TC2',
is_return = 1,
return_against = docname)
customer = '_Test Customer 2',
currency = 'EUR',
qty = -1,
warehouse = 'Finished Goods - _TC2',
debit_to = 'Debtors - _TC2',
income_account = 'Sales - _TC2',
expense_account = 'Cost of Goods Sold - _TC2',
cost_center = 'Main - _TC2',
is_return = 1,
return_against = docname)

View File

@@ -111,7 +111,12 @@ frappe.query_reports["Accounts Receivable Summary"] = {
"fieldname":"based_on_payment_terms",
"label": __("Based On Payment Terms"),
"fieldtype": "Check",
}
},
{
"fieldname":"show_future_payments",
"label": __("Show Future Payments"),
"fieldtype": "Check",
},
],
onload: function(report) {
@@ -122,11 +127,4 @@ frappe.query_reports["Accounts Receivable Summary"] = {
}
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["Accounts Receivable Summary"].filters.splice(9, 0 ,{
"fieldname": dimension["fieldname"],
"label": __(dimension["label"]),
"fieldtype": "Link",
"options": dimension["document_type"]
});
});
erpnext.utils.add_dimensions('Accounts Receivable Summary', 9);

View File

@@ -33,7 +33,7 @@ class AccountsReceivableSummary(ReceivablePayableReport):
self.get_party_total(args)
party_advance_amount = get_partywise_advanced_payment_amount(self.party_type,
self.filters.report_date) or {}
self.filters.report_date, self.filters.show_future_payments, self.filters.company) or {}
for party, party_dict in iteritems(self.party_total):
if party_dict.outstanding == 0:

View File

@@ -93,7 +93,7 @@ def get_assets(filters):
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
from (SELECT a.asset_category,
ifnull(sum(case when ds.schedule_date < %(from_date)s then
ifnull(sum(case when ds.schedule_date < %(from_date)s and (ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s) then
ds.depreciation_amount
else
0
@@ -111,13 +111,11 @@ def get_assets(filters):
0
end), 0) as depreciation_amount_during_the_period
from `tabAsset` a, `tabDepreciation Schedule` ds
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and a.name = ds.parent
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and a.name = ds.parent and ifnull(ds.journal_entry, '') != ''
group by a.asset_category
union
SELECT a.asset_category,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s)
then
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) then
0
else
a.opening_accumulated_depreciation

View File

@@ -4,6 +4,8 @@
frappe.require("assets/erpnext/js/financial_statements.js", function() {
frappe.query_reports["Balance Sheet"] = $.extend({}, erpnext.financial_statements);
erpnext.utils.add_dimensions('Balance Sheet', 10);
frappe.query_reports["Balance Sheet"]["filters"].push({
"fieldname": "accumulated_values",
"label": __("Accumulated Values"),

View File

@@ -2,16 +2,19 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import datetime
from six import iteritems
import frappe
from frappe import _
from frappe.utils import flt
from frappe.utils import formatdate
from frappe.utils import flt, formatdate
from erpnext.controllers.trends import get_period_date_ranges, get_period_month_ranges
from six import iteritems
from pprint import pprint
def execute(filters=None):
if not filters: filters = {}
if not filters:
filters = {}
columns = get_columns(filters)
if filters.get("budget_against_filter"):
@@ -43,20 +46,25 @@ def execute(filters=None):
period_data[0] += last_total
if(filters.get("show_cumulative")):
if filters.get("show_cumulative"):
last_total = period_data[0] - period_data[1]
period_data[2] = period_data[0] - period_data[1]
row += period_data
totals[2] = totals[0] - totals[1]
if filters["period"] != "Yearly" :
if filters["period"] != "Yearly":
row += totals
data.append(row)
return columns, data
def get_columns(filters):
columns = [_(filters.get("budget_against")) + ":Link/%s:150"%(filters.get("budget_against")), _("Account") + ":Link/Account:150"]
columns = [
_(filters.get("budget_against"))
+ ":Link/%s:150" % (filters.get("budget_against")),
_("Account") + ":Link/Account:150"
]
group_months = False if filters["period"] == "Monthly" else True
@@ -65,84 +73,181 @@ def get_columns(filters):
for year in fiscal_year:
for from_date, to_date in get_period_date_ranges(filters["period"], year[0]):
if filters["period"] == "Yearly":
labels = [_("Budget") + " " + str(year[0]), _("Actual ") + " " + str(year[0]), _("Variance ") + " " + str(year[0])]
labels = [
_("Budget") + " " + str(year[0]),
_("Actual ") + " " + str(year[0]),
_("Variance ") + " " + str(year[0])
]
for label in labels:
columns.append(label+":Float:150")
columns.append(label + ":Float:150")
else:
for label in [_("Budget") + " (%s)" + " " + str(year[0]), _("Actual") + " (%s)" + " " + str(year[0]), _("Variance") + " (%s)" + " " + str(year[0])]:
for label in [
_("Budget") + " (%s)" + " " + str(year[0]),
_("Actual") + " (%s)" + " " + str(year[0]),
_("Variance") + " (%s)" + " " + str(year[0])
]:
if group_months:
label = label % (formatdate(from_date, format_string="MMM") + "-" + formatdate(to_date, format_string="MMM"))
label = label % (
formatdate(from_date, format_string="MMM")
+ "-"
+ formatdate(to_date, format_string="MMM")
)
else:
label = label % formatdate(from_date, format_string="MMM")
columns.append(label+":Float:150")
columns.append(label + ":Float:150")
if filters["period"] != "Yearly" :
return columns + [_("Total Budget") + ":Float:150", _("Total Actual") + ":Float:150",
_("Total Variance") + ":Float:150"]
if filters["period"] != "Yearly":
return columns + [
_("Total Budget") + ":Float:150",
_("Total Actual") + ":Float:150",
_("Total Variance") + ":Float:150"
]
else:
return columns
def get_cost_centers(filters):
cond = "and 1=1"
order_by = ""
if filters.get("budget_against") == "Cost Center":
cond = "order by lft"
order_by = "order by lft"
if filters.get("budget_against") in ["Cost Center", "Project"]:
return frappe.db.sql_list("""select name from `tab{tab}` where company=%s
{cond}""".format(tab=filters.get("budget_against"), cond=cond), filters.get("company"))
return frappe.db.sql_list(
"""
select
name
from
`tab{tab}`
where
company = %s
{order_by}
""".format(tab=filters.get("budget_against"), order_by=order_by),
filters.get("company"))
else:
return frappe.db.sql_list("""select name from `tab{tab}`""".format(tab=filters.get("budget_against"))) #nosec
return frappe.db.sql_list(
"""
select
name
from
`tab{tab}`
""".format(tab=filters.get("budget_against"))) # nosec
#Get dimension & target details
# Get dimension & target details
def get_dimension_target_details(filters):
budget_against = frappe.scrub(filters.get("budget_against"))
cond = ""
if filters.get("budget_against_filter"):
cond += " and b.{budget_against} in (%s)".format(budget_against = \
frappe.scrub(filters.get('budget_against'))) % ', '.join(['%s']* len(filters.get('budget_against_filter')))
cond += """ and b.{budget_against} in (%s)""".format(
budget_against=budget_against) % ", ".join(["%s"] * len(filters.get("budget_against_filter")))
return frappe.db.sql("""
select b.{budget_against} as budget_against, b.monthly_distribution, ba.account, ba.budget_amount,b.fiscal_year
from `tabBudget` b, `tabBudget Account` ba
where b.name=ba.parent and b.docstatus = 1 and b.fiscal_year between %s and %s
and b.budget_against = %s and b.company=%s {cond} order by b.fiscal_year
""".format(budget_against=filters.get("budget_against").replace(" ", "_").lower(), cond=cond),
tuple([filters.from_fiscal_year,filters.to_fiscal_year,filters.budget_against, filters.company] + filters.get('budget_against_filter')),
as_dict=True)
return frappe.db.sql(
"""
select
b.{budget_against} as budget_against,
b.monthly_distribution,
ba.account,
ba.budget_amount,
b.fiscal_year
from
`tabBudget` b,
`tabBudget Account` ba
where
b.name = ba.parent
and b.docstatus = 1
and b.fiscal_year between %s and %s
and b.budget_against = %s
and b.company = %s
{cond}
order by
b.fiscal_year
""".format(
budget_against=budget_against,
cond=cond,
),
tuple(
[
filters.from_fiscal_year,
filters.to_fiscal_year,
filters.budget_against,
filters.company,
]
+ filters.get("budget_against_filter")
), as_dict=True)
#Get target distribution details of accounts of cost center
# Get target distribution details of accounts of cost center
def get_target_distribution_details(filters):
target_details = {}
for d in frappe.db.sql("""select md.name, mdp.month, mdp.percentage_allocation
from `tabMonthly Distribution Percentage` mdp, `tabMonthly Distribution` md
where mdp.parent=md.name and md.fiscal_year between %s and %s order by md.fiscal_year""",(filters.from_fiscal_year, filters.to_fiscal_year), as_dict=1):
target_details.setdefault(d.name, {}).setdefault(d.month, flt(d.percentage_allocation))
for d in frappe.db.sql(
"""
select
md.name,
mdp.month,
mdp.percentage_allocation
from
`tabMonthly Distribution Percentage` mdp,
`tabMonthly Distribution` md
where
mdp.parent = md.name
and md.fiscal_year between %s and %s
order by
md.fiscal_year
""",
(filters.from_fiscal_year, filters.to_fiscal_year), as_dict=1):
target_details.setdefault(d.name, {}).setdefault(
d.month, flt(d.percentage_allocation)
)
return target_details
#Get actual details from gl entry
# Get actual details from gl entry
def get_actual_details(name, filters):
cond = "1=1"
budget_against=filters.get("budget_against").replace(" ", "_").lower()
budget_against = frappe.scrub(filters.get("budget_against"))
cond = ""
if filters.get("budget_against") == "Cost Center":
cc_lft, cc_rgt = frappe.db.get_value("Cost Center", name, ["lft", "rgt"])
cond = "lft>='{lft}' and rgt<='{rgt}'".format(lft = cc_lft, rgt=cc_rgt)
cond = """
and lft >= "{lft}"
and rgt <= "{rgt}"
""".format(lft=cc_lft, rgt=cc_rgt)
ac_details = frappe.db.sql("""select gl.account, gl.debit, gl.credit,gl.fiscal_year,
MONTHNAME(gl.posting_date) as month_name, b.{budget_against} as budget_against
from `tabGL Entry` gl, `tabBudget Account` ba, `tabBudget` b
where
b.name = ba.parent
and b.docstatus = 1
and ba.account=gl.account
and b.{budget_against} = gl.{budget_against}
and gl.fiscal_year between %s and %s
and b.{budget_against}=%s
and exists(select name from `tab{tab}` where name=gl.{budget_against} and {cond}) group by gl.name order by gl.fiscal_year
""".format(tab = filters.budget_against, budget_against = budget_against, cond = cond,from_year=filters.from_fiscal_year,to_year=filters.to_fiscal_year),
(filters.from_fiscal_year, filters.to_fiscal_year, name), as_dict=1)
ac_details = frappe.db.sql(
"""
select
gl.account,
gl.debit,
gl.credit,
gl.fiscal_year,
MONTHNAME(gl.posting_date) as month_name,
b.{budget_against} as budget_against
from
`tabGL Entry` gl,
`tabBudget Account` ba,
`tabBudget` b
where
b.name = ba.parent
and b.docstatus = 1
and ba.account=gl.account
and b.{budget_against} = gl.{budget_against}
and gl.fiscal_year between %s and %s
and b.{budget_against} = %s
and exists(
select
name
from
`tab{tab}`
where
name = gl.{budget_against}
{cond}
)
group by
gl.name
order by gl.fiscal_year
""".format(tab=filters.budget_against, budget_against=budget_against, cond=cond),
(filters.from_fiscal_year, filters.to_fiscal_year, name), as_dict=1)
cc_actual_details = {}
for d in ac_details:
@@ -151,7 +256,6 @@ def get_actual_details(name, filters):
return cc_actual_details
def get_dimension_account_month_map(filters):
import datetime
dimension_target_details = get_dimension_target_details(filters)
tdd = get_target_distribution_details(filters)
@@ -161,28 +265,43 @@ def get_dimension_account_month_map(filters):
actual_details = get_actual_details(ccd.budget_against, filters)
for month_id in range(1, 13):
month = datetime.date(2013, month_id, 1).strftime('%B')
cam_map.setdefault(ccd.budget_against, {}).setdefault(ccd.account, {}).setdefault(ccd.fiscal_year,{})\
.setdefault(month, frappe._dict({
"target": 0.0, "actual": 0.0
}))
month = datetime.date(2013, month_id, 1).strftime("%B")
cam_map.setdefault(ccd.budget_against, {}).setdefault(
ccd.account, {}
).setdefault(ccd.fiscal_year, {}).setdefault(
month, frappe._dict({"target": 0.0, "actual": 0.0})
)
tav_dict = cam_map[ccd.budget_against][ccd.account][ccd.fiscal_year][month]
month_percentage = tdd.get(ccd.monthly_distribution, {}).get(month, 0) \
if ccd.monthly_distribution else 100.0/12
month_percentage = (
tdd.get(ccd.monthly_distribution, {}).get(month, 0)
if ccd.monthly_distribution
else 100.0 / 12
)
tav_dict.target = flt(ccd.budget_amount) * month_percentage / 100
for ad in actual_details.get(ccd.account, []):
if ad.month_name == month:
tav_dict.actual += flt(ad.debit) - flt(ad.credit)
if ad.month_name == month and ad.fiscal_year == ccd.fiscal_year:
tav_dict.actual += flt(ad.debit) - flt(ad.credit)
return cam_map
def get_fiscal_years(filters):
fiscal_year = frappe.db.sql("""select name from `tabFiscal Year` where
name between %(from_fiscal_year)s and %(to_fiscal_year)s""",
{'from_fiscal_year': filters["from_fiscal_year"], 'to_fiscal_year': filters["to_fiscal_year"]})
fiscal_year = frappe.db.sql(
"""
select
name
from
`tabFiscal Year`
where
name between %(from_fiscal_year)s and %(to_fiscal_year)s
""",
{
"from_fiscal_year": filters["from_fiscal_year"],
"to_fiscal_year": filters["to_fiscal_year"]
})
return fiscal_year

View File

@@ -5,6 +5,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
frappe.query_reports["Cash Flow"] = $.extend({},
erpnext.financial_statements);
erpnext.utils.add_dimensions('Cash Flow', 10);
// The last item in the array is the definition for Presentation Currency
// filter. It won't be used in cash flow for now so we pop it. Please take
// of this if you are working here.

View File

@@ -8,6 +8,7 @@ from __future__ import unicode_literals
import re
from past.builtins import cmp
import functools
import math
import frappe, erpnext
from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
@@ -42,7 +43,7 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_v
start_date = year_start_date
months = get_months(year_start_date, year_end_date)
for i in range(months // months_to_add):
for i in range(math.ceil(months / months_to_add)):
period = frappe._dict({
"from_date": start_date
})
@@ -50,9 +51,8 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_v
to_date = add_months(start_date, months_to_add)
start_date = to_date
if to_date == get_first_day(to_date):
# if to_date is the first day, get the last day of previous month
to_date = add_days(to_date, -1)
# Subtract one day from to_date, as it may be first day in next fiscal year or month
to_date = add_days(to_date, -1)
if to_date <= year_end_date:
# the normal case

View File

@@ -2,7 +2,7 @@
<h4 class="text-center">
{% if (filters.party_name) { %}
{%= filters.party_name %}
{% } else if (filters.party) { %}
{% } else if (filters.party && filters.party.length) { %}
{%= filters.party %}
{% } else if (filters.account) { %}
{%= filters.account %}

View File

@@ -160,12 +160,5 @@ frappe.query_reports["General Ledger"] = {
]
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["General Ledger"].filters.splice(15, 0 ,{
"fieldname": dimension["fieldname"],
"label": __(dimension["label"]),
"fieldtype": "Link",
"options": dimension["document_type"]
});
});
erpnext.utils.add_dimensions('General Ledger', 15)

View File

@@ -293,6 +293,9 @@ def get_accountwise_gle(filters, gl_entries, gle_map):
data[key].debit_in_account_currency += flt(gle.debit_in_account_currency)
data[key].credit_in_account_currency += flt(gle.credit_in_account_currency)
if data[key].against_voucher and gle.against_voucher:
data[key].against_voucher += ', ' + gle.against_voucher
from_date, to_date = getdate(filters.from_date), getdate(filters.to_date)
for gle in gl_entries:
if (gle.posting_date < from_date or

View File

@@ -8,7 +8,6 @@ from frappe.utils import flt
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
import copy
def execute(filters=None):
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
filters.periodicity, filters.accumulated_values, filters.company)
@@ -27,17 +26,26 @@ def execute(filters=None):
gross_income = get_revenue(income, period_list)
gross_expense = get_revenue(expense, period_list)
if(len(gross_income)==0 and len(gross_expense)== 0):
data.append({"account_name": "'" + _("Nothing is included in gross") + "'",
"account": "'" + _("Nothing is included in gross") + "'"})
data.append({
"account_name": "'" + _("Nothing is included in gross") + "'",
"account": "'" + _("Nothing is included in gross") + "'"
})
return columns, data
data.append({"account_name": "'" + _("Included in Gross Profit") + "'",
"account": "'" + _("Included in Gross Profit") + "'"})
# to avoid error eg: gross_income[0] : list index out of range
if not gross_income:
gross_income = [{}]
if not gross_expense:
gross_expense = [{}]
data.append({
"account_name": "'" + _("Included in Gross Profit") + "'",
"account": "'" + _("Included in Gross Profit") + "'"
})
data.append({})
data.extend(gross_income or [])
@@ -111,7 +119,6 @@ def set_total(node, value, complete_list, totals):
def get_profit(gross_income, gross_expense, period_list, company, profit_type, currency=None, consolidated=False):
profit_loss = {
"account_name": "'" + _(profit_type) + "'",
"account": "'" + _(profit_type) + "'",
@@ -123,7 +130,9 @@ def get_profit(gross_income, gross_expense, period_list, company, profit_type, c
for period in period_list:
key = period if consolidated else period.key
profit_loss[key] = flt(gross_income[0].get(key, 0)) - flt(gross_expense[0].get(key, 0))
gross_income_for_period = flt(gross_income[0].get(key, 0)) if gross_income else 0
gross_expense_for_period = flt(gross_expense[0].get(key, 0)) if gross_expense else 0
profit_loss[key] = gross_income_for_period - gross_expense_for_period
if profit_loss[key]:
has_value=True
@@ -143,12 +152,18 @@ def get_net_profit(non_gross_income, gross_income, gross_expense, non_gross_expe
for period in period_list:
key = period if consolidated else period.key
total_income = flt(gross_income[0].get(key, 0)) + flt(non_gross_income[0].get(key, 0))
total_expense = flt(gross_expense[0].get(key, 0)) + flt(non_gross_expense[0].get(key, 0))
gross_income_for_period = flt(gross_income[0].get(key, 0)) if gross_income else 0
non_gross_income_for_period = flt(non_gross_income[0].get(key, 0)) if non_gross_income else 0
gross_expense_for_period = flt(gross_expense[0].get(key, 0)) if gross_expense else 0
non_gross_expense_for_period = flt(non_gross_expense[0].get(key, 0)) if non_gross_expense else 0
total_income = gross_income_for_period + non_gross_income_for_period
total_expense = gross_expense_for_period + non_gross_expense_for_period
profit_loss[key] = flt(total_income) - flt(total_expense)
if profit_loss[key]:
has_value=True
if has_value:
return profit_loss
return profit_loss

View File

@@ -55,27 +55,27 @@ def get_columns(group_wise_columns, filters):
columns = []
column_map = frappe._dict({
"parent": _("Sales Invoice") + ":Link/Sales Invoice:120",
"posting_date": _("Posting Date") + ":Date",
"posting_time": _("Posting Time"),
"item_code": _("Item Code") + ":Link/Item",
"item_name": _("Item Name"),
"item_group": _("Item Group") + ":Link/Item Group",
"brand": _("Brand"),
"description": _("Description"),
"warehouse": _("Warehouse") + ":Link/Warehouse",
"qty": _("Qty") + ":Float",
"base_rate": _("Avg. Selling Rate") + ":Currency/currency",
"buying_rate": _("Valuation Rate") + ":Currency/currency",
"base_amount": _("Selling Amount") + ":Currency/currency",
"buying_amount": _("Buying Amount") + ":Currency/currency",
"gross_profit": _("Gross Profit") + ":Currency/currency",
"gross_profit_percent": _("Gross Profit %") + ":Percent",
"project": _("Project") + ":Link/Project",
"posting_date": _("Posting Date") + ":Date:100",
"posting_time": _("Posting Time") + ":Data:100",
"item_code": _("Item Code") + ":Link/Item:100",
"item_name": _("Item Name") + ":Data:100",
"item_group": _("Item Group") + ":Link/Item Group:100",
"brand": _("Brand") + ":Link/Brand:100",
"description": _("Description") +":Data:100",
"warehouse": _("Warehouse") + ":Link/Warehouse:100",
"qty": _("Qty") + ":Float:80",
"base_rate": _("Avg. Selling Rate") + ":Currency/currency:100",
"buying_rate": _("Valuation Rate") + ":Currency/currency:100",
"base_amount": _("Selling Amount") + ":Currency/currency:100",
"buying_amount": _("Buying Amount") + ":Currency/currency:100",
"gross_profit": _("Gross Profit") + ":Currency/currency:100",
"gross_profit_percent": _("Gross Profit %") + ":Percent:100",
"project": _("Project") + ":Link/Project:100",
"sales_person": _("Sales person"),
"allocated_amount": _("Allocated Amount") + ":Currency/currency",
"customer": _("Customer") + ":Link/Customer",
"customer_group": _("Customer Group") + ":Link/Customer Group",
"territory": _("Territory") + ":Link/Territory"
"allocated_amount": _("Allocated Amount") + ":Currency/currency:100",
"customer": _("Customer") + ":Link/Customer:100",
"customer_group": _("Customer Group") + ":Link/Customer Group:100",
"territory": _("Territory") + ":Link/Territory:100"
})
for col in group_wise_columns.get(scrub(filters.group_by)):
@@ -85,7 +85,8 @@ def get_columns(group_wise_columns, filters):
"fieldname": "currency",
"label" : _("Currency"),
"fieldtype": "Link",
"options": "Currency"
"options": "Currency",
"hidden": 1
})
return columns
@@ -277,7 +278,7 @@ class GrossProfitGenerator(object):
from `tabPurchase Invoice Item` a
where a.item_code = %s and a.docstatus=1
and modified <= %s
order by a.modified desc limit 1""", (item_code,self.filters.to_date))
order by a.modified desc limit 1""", (item_code, self.filters.to_date))
else:
last_purchase_rate = frappe.db.sql("""
select (a.base_rate / a.conversion_factor)

View File

@@ -102,7 +102,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
data.append(row)
if filters.get('group_by'):
if filters.get('group_by') and item_list:
total_row = total_row_map.get(prev_group_by_value or d.get('item_name'))
total_row['percent_gt'] = flt(total_row['total']/grand_total * 100)
data.append(total_row)

View File

@@ -111,7 +111,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
data.append(row)
if filters.get('group_by'):
if filters.get('group_by') and item_list:
total_row = total_row_map.get(prev_group_by_value or d.get('item_name'))
total_row['percent_gt'] = flt(total_row['total']/grand_total * 100)
data.append(total_row)

View File

@@ -6,6 +6,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
frappe.query_reports["Profit and Loss Statement"] = $.extend({},
erpnext.financial_statements);
erpnext.utils.add_dimensions('Profit and Loss Statement', 10);
frappe.query_reports["Profit and Loss Statement"]["filters"].push(
{
"fieldname": "project",

View File

@@ -56,11 +56,4 @@ frappe.query_reports["Purchase Register"] = {
]
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["Purchase Register"].filters.splice(7, 0 ,{
"fieldname": dimension["fieldname"],
"label": __(dimension["label"]),
"fieldtype": "Link",
"options": dimension["document_type"]
});
});
erpnext.utils.add_dimensions('Purchase Register', 7);

View File

@@ -68,12 +68,5 @@ frappe.query_reports["Sales Register"] = {
]
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["Sales Register"].filters.splice(7, 0 ,{
"fieldname": dimension["fieldname"],
"label": __(dimension["label"]),
"fieldtype": "Link",
"options": dimension["document_type"]
});
});
erpnext.utils.add_dimensions('Sales Register', 7);

View File

@@ -44,9 +44,14 @@ def get_result(filters):
out = []
for supplier in filters.supplier:
tds = frappe.get_doc("Tax Withholding Category", supplier.tax_withholding_category)
rate = [d.tax_withholding_rate for d in tds.rates if d.fiscal_year == filters.fiscal_year][0]
rate = [d.tax_withholding_rate for d in tds.rates if d.fiscal_year == filters.fiscal_year]
if rate:
rate = rate[0]
try:
account = [d.account for d in tds.accounts if d.company == filters.company][0]
except IndexError:
account = []
total_invoiced_amount, tds_deducted = get_invoice_and_tds_amount(supplier.name, account,
@@ -76,7 +81,7 @@ def get_invoice_and_tds_amount(supplier, account, company, from_date, to_date):
supplier_credit_amount = flt(sum([d.credit for d in entries]))
vouchers = [d.voucher_no for d in entries]
vouchers += get_advance_vouchers(supplier, company=company,
vouchers += get_advance_vouchers([supplier], company=company,
from_date=from_date, to_date=to_date)
tds_deducted = 0
@@ -89,7 +94,7 @@ def get_invoice_and_tds_amount(supplier, account, company, from_date, to_date):
""".format(', '.join(["'%s'" % d for d in vouchers])),
(account, from_date, to_date, company))[0][0])
debit_note_amount = get_debit_note_amount(supplier, from_date, to_date, company=company)
debit_note_amount = get_debit_note_amount([supplier], from_date, to_date, company=company)
total_invoiced_amount = supplier_credit_amount + tds_deducted - debit_note_amount

View File

@@ -46,7 +46,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"default": frappe.defaults.get_user_default("year_end_date"),
},
{
"fieldname":"cost_center",
"fieldname": "cost_center",
"label": __("Cost Center"),
"fieldtype": "Link",
"options": "Cost Center",
@@ -61,7 +61,13 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
}
},
{
"fieldname":"finance_book",
"fieldname": "project",
"label": __("Project"),
"fieldtype": "Link",
"options": "Project"
},
{
"fieldname": "finance_book",
"label": __("Finance Book"),
"fieldtype": "Link",
"options": "Finance Book",
@@ -96,14 +102,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"initial_depth": 3
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["Trial Balance"].filters.splice(5, 0 ,{
"fieldname": dimension["fieldname"],
"label": __(dimension["label"]),
"fieldtype": "Link",
"options": dimension["document_type"]
});
});
erpnext.utils.add_dimensions('Trial Balance', 6);
});

View File

@@ -69,6 +69,11 @@ def get_data(filters):
gl_entries_by_account = {}
opening_balances = get_opening_balances(filters)
#add filter inside list so that the query in financial_statements.py doesn't break
if filters.project:
filters.project = [filters.project]
set_gl_entries_by_account(filters.company, filters.from_date,
filters.to_date, min_lft, max_rgt, filters, gl_entries_by_account, ignore_closing_entries=not flt(filters.with_period_closing_entry))
@@ -102,6 +107,9 @@ def get_rootwise_opening_balances(filters, report_type):
additional_conditions += """ and cost_center in (select name from `tabCost Center`
where lft >= %s and rgt <= %s)""" % (lft, rgt)
if filters.project:
additional_conditions += " and project = %(project)s"
if filters.finance_book:
fb_conditions = " AND finance_book = %(finance_book)s"
if filters.include_default_book_entries:
@@ -116,6 +124,7 @@ def get_rootwise_opening_balances(filters, report_type):
"from_date": filters.from_date,
"report_type": report_type,
"year_start_date": filters.year_start_date,
"project": filters.project,
"finance_book": filters.finance_book,
"company_fb": frappe.db.get_value("Company", filters.company, 'default_finance_book')
}

View File

@@ -113,7 +113,7 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
acc = frappe.get_doc("Account", account)
try:
year_start_date = get_fiscal_year(date, verbose=0)[1]
year_start_date = get_fiscal_year(date, company=company, verbose=0)[1]
except FiscalYearError:
if getdate(date) > getdate(nowdate()):
# if fiscal year not found and the date is greater than today
@@ -124,14 +124,12 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
# hence, assuming balance as 0.0
return 0.0
allow_cost_center_in_entry_of_bs_account = get_allow_cost_center_in_entry_of_bs_account()
if account:
report_type = acc.report_type
else:
report_type = ""
if cost_center and (allow_cost_center_in_entry_of_bs_account or report_type =='Profit and Loss'):
if cost_center and report_type == 'Profit and Loss':
cc = frappe.get_doc("Cost Center", cost_center)
if cc.is_group:
cond.append(""" exists (
@@ -658,7 +656,8 @@ def get_outstanding_invoices(party_type, party, account, condition=None, filters
invoice_list = frappe.db.sql("""
select
voucher_no, voucher_type, posting_date, due_date,
ifnull(sum({dr_or_cr}), 0) as invoice_amount
ifnull(sum({dr_or_cr}), 0) as invoice_amount,
account_currency as currency
from
`tabGL Entry`
where
@@ -715,7 +714,8 @@ def get_outstanding_invoices(party_type, party, account, condition=None, filters
'invoice_amount': flt(d.invoice_amount),
'payment_amount': payment_amount,
'outstanding_amount': outstanding_amount,
'due_date': d.due_date
'due_date': d.due_date,
'currency': d.currency
})
)
@@ -767,10 +767,10 @@ def get_children(doctype, parent, company, is_root=False):
company_currency = frappe.get_cached_value('Company', company, "default_currency")
for each in acc:
each["company_currency"] = company_currency
each["balance"] = flt(get_balance_on(each.get("value"), in_account_currency=False))
each["balance"] = flt(get_balance_on(each.get("value"), in_account_currency=False, company=company))
if each.account_currency != company_currency:
each["balance_in_account_currency"] = flt(get_balance_on(each.get("value")))
each["balance_in_account_currency"] = flt(get_balance_on(each.get("value"), company=company))
return acc
@@ -817,48 +817,37 @@ def create_payment_gateway_account(gateway):
pass
@frappe.whitelist()
def update_number_field(doctype_name, name, field_name, number_value, company):
def update_cost_center(docname, cost_center_name, cost_center_number, company, merge):
'''
doctype_name = Name of the DocType
name = Docname being referred
field_name = Name of the field thats holding the 'number' attribute
number_value = Numeric value entered in field_name
Stores the number entered in the dialog to the DocType's field.
Renames the document by adding the number as a prefix to the current name and updates
all transaction where it was present.
'''
doc_title = frappe.db.get_value(doctype_name, name, frappe.scrub(doctype_name)+"_name")
validate_field_number("Cost Center", docname, cost_center_number, company, "cost_center_number")
validate_field_number(doctype_name, name, number_value, company, field_name)
if cost_center_number:
frappe.db.set_value("Cost Center", docname, "cost_center_number", cost_center_number.strip())
else:
frappe.db.set_value("Cost Center", docname, "cost_center_number", "")
frappe.db.set_value(doctype_name, name, field_name, number_value)
frappe.db.set_value("Cost Center", docname, "cost_center_name", cost_center_name.strip())
if doc_title[0].isdigit():
separator = " - " if " - " in doc_title else " "
doc_title = doc_title.split(separator, 1)[1]
frappe.db.set_value(doctype_name, name, frappe.scrub(doctype_name)+"_name", doc_title)
new_name = get_autoname_with_number(number_value, doc_title, name, company)
if name != new_name:
frappe.rename_doc(doctype_name, name, new_name)
new_name = get_autoname_with_number(cost_center_number, cost_center_name, docname, company)
if docname != new_name:
frappe.rename_doc("Cost Center", docname, new_name, force=1, merge=merge)
return new_name
def validate_field_number(doctype_name, name, number_value, company, field_name):
def validate_field_number(doctype_name, docname, number_value, company, field_name):
''' Validate if the number entered isn't already assigned to some other document. '''
if number_value:
filters = {field_name: number_value, "name": ["!=", docname]}
if company:
doctype_with_same_number = frappe.db.get_value(doctype_name,
{field_name: number_value, "company": company, "name": ["!=", name]})
else:
doctype_with_same_number = frappe.db.get_value(doctype_name,
{field_name: number_value, "name": ["!=", name]})
filters["company"] = company
doctype_with_same_number = frappe.db.get_value(doctype_name, filters)
if doctype_with_same_number:
frappe.throw(_("{0} Number {1} already used in account {2}")
.format(doctype_name, number_value, doctype_with_same_number))
frappe.throw(_("{0} Number {1} is already used in {2} {3}")
.format(doctype_name, number_value, doctype_name.lower(), doctype_with_same_number))
def get_autoname_with_number(number_value, doc_title, name, company):
''' append title with prefix as number and suffix as company's abbreviation separated by '-' '''
@@ -888,11 +877,6 @@ def get_coa(doctype, parent, is_root, chart=None):
return accounts
def get_allow_cost_center_in_entry_of_bs_account():
def generator():
return cint(frappe.db.get_value('Accounts Settings', None, 'allow_cost_center_in_entry_of_bs_account'))
return frappe.local_cache("get_allow_cost_center_in_entry_of_bs_account", (), generator, regenerate_if_none=True)
def get_stock_accounts(company):
return frappe.get_all("Account", filters = {
"account_type": "Stock",

View File

@@ -22,6 +22,7 @@ class Asset(AccountsController):
self.validate_item()
self.set_missing_values()
self.prepare_depreciation_data()
self.validate_gross_and_purchase_amount()
if self.get("schedules"):
self.validate_expected_value_after_useful_life()
@@ -31,7 +32,7 @@ class Asset(AccountsController):
self.validate_in_use_date()
self.set_status()
self.make_asset_movement()
if not self.booked_fixed_asset and is_cwip_accounting_enabled(self.asset_category):
if not self.booked_fixed_asset and self.validate_make_gl_entry():
self.make_gl_entries()
def before_cancel(self):
@@ -123,6 +124,14 @@ class Asset(AccountsController):
if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(self.purchase_date):
frappe.throw(_("Available-for-use Date should be after purchase date"))
def validate_gross_and_purchase_amount(self):
if self.is_existing_asset: return
if self.gross_purchase_amount and self.gross_purchase_amount != self.purchase_receipt_amount:
frappe.throw(_("Gross Purchase Amount should be {} to purchase amount of one single Asset. {}\
Please do not book expense of multiple assets against one single Asset.")
.format(frappe.bold("equal"), "<br>"), title=_("Invalid Gross Purchase Amount"))
def cancel_auto_gen_movement(self):
movements = frappe.db.sql(
@@ -398,6 +407,8 @@ class Asset(AccountsController):
row.expected_value_after_useful_life = asset_value_after_full_schedule
def validate_cancellation(self):
if self.status in ("In Maintenance", "Out of Order"):
frappe.throw(_("There are active maintenance or repairs against the asset. You must complete all of them before cancelling the asset."))
if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"):
frappe.throw(_("Asset cannot be cancelled, as it is already {0}").format(self.status))
@@ -447,18 +458,55 @@ class Asset(AccountsController):
for d in self.get('finance_books'):
if d.finance_book == self.default_finance_book:
return cint(d.idx) - 1
def validate_make_gl_entry(self):
purchase_document = self.get_purchase_document()
asset_bought_with_invoice = purchase_document == self.purchase_invoice
fixed_asset_account, cwip_account = self.get_asset_accounts()
cwip_enabled = is_cwip_accounting_enabled(self.asset_category)
# check if expense already has been booked in case of cwip was enabled after purchasing asset
expense_booked = False
cwip_booked = False
if asset_bought_with_invoice:
expense_booked = frappe.db.sql("""SELECT name FROM `tabGL Entry` WHERE voucher_no = %s and account = %s""",
(purchase_document, fixed_asset_account), as_dict=1)
else:
cwip_booked = frappe.db.sql("""SELECT name FROM `tabGL Entry` WHERE voucher_no = %s and account = %s""",
(purchase_document, cwip_account), as_dict=1)
if cwip_enabled and (expense_booked or not cwip_booked):
# if expense has already booked from invoice or cwip is booked from receipt
return False
elif not cwip_enabled and (not expense_booked or cwip_booked):
# if cwip is disabled but expense hasn't been booked yet
return True
elif cwip_enabled:
# default condition
return True
def get_purchase_document(self):
asset_bought_with_invoice = self.purchase_invoice and frappe.db.get_value('Purchase Invoice', self.purchase_invoice, 'update_stock')
purchase_document = self.purchase_invoice if asset_bought_with_invoice else self.purchase_receipt
return purchase_document
def get_asset_accounts(self):
fixed_asset_account = get_asset_category_account('fixed_asset_account', asset=self.name,
asset_category = self.asset_category, company = self.company)
cwip_account = get_asset_account("capital_work_in_progress_account",
self.name, self.asset_category, self.company)
return fixed_asset_account, cwip_account
def make_gl_entries(self):
gl_entries = []
if ((self.purchase_receipt \
or (self.purchase_invoice and frappe.db.get_value('Purchase Invoice', self.purchase_invoice, 'update_stock')))
and self.purchase_receipt_amount and self.available_for_use_date <= nowdate()):
fixed_asset_account = get_asset_category_account('fixed_asset_account', asset=self.name,
asset_category = self.asset_category, company = self.company)
purchase_document = self.get_purchase_document()
fixed_asset_account, cwip_account = self.get_asset_accounts()
cwip_account = get_asset_account("capital_work_in_progress_account",
self.name, self.asset_category, self.company)
if (purchase_document and self.purchase_receipt_amount and self.available_for_use_date <= nowdate()):
gl_entries.append(self.get_gl_dict({
"account": cwip_account,
@@ -468,7 +516,7 @@ class Asset(AccountsController):
"credit": self.purchase_receipt_amount,
"credit_in_account_currency": self.purchase_receipt_amount,
"cost_center": self.cost_center
}))
}, item=self))
gl_entries.append(self.get_gl_dict({
"account": fixed_asset_account,
@@ -478,7 +526,7 @@ class Asset(AccountsController):
"debit": self.purchase_receipt_amount,
"debit_in_account_currency": self.purchase_receipt_amount,
"cost_center": self.cost_center
}))
}, item=self))
if gl_entries:
from erpnext.accounts.general_ledger import make_gl_entries
@@ -611,7 +659,7 @@ def get_asset_account(account_name, asset=None, asset_category=None, company=Non
if asset:
account = get_asset_category_account(account_name, asset=asset,
asset_category = asset_category, company = company)
if not asset and not account:
account = get_asset_category_account(account_name, asset_category = asset_category, company = company)

View File

@@ -58,7 +58,8 @@ def make_depreciation_entry(asset_name, date=None):
"account": accumulated_depreciation_account,
"credit_in_account_currency": d.depreciation_amount,
"reference_type": "Asset",
"reference_name": asset.name
"reference_name": asset.name,
"cost_center": ""
}
debit_entry = {
@@ -196,12 +197,14 @@ def get_gl_entries_on_asset_disposal(asset, selling_amount=0, finance_book=None)
{
"account": fixed_asset_account,
"credit_in_account_currency": asset.gross_purchase_amount,
"credit": asset.gross_purchase_amount
"credit": asset.gross_purchase_amount,
"cost_center": depreciation_cost_center
},
{
"account": accumulated_depr_account,
"debit_in_account_currency": accumulated_depr_amount,
"debit": accumulated_depr_amount
"debit": accumulated_depr_amount,
"cost_center": depreciation_cost_center
}
]

View File

@@ -82,7 +82,6 @@ class TestAsset(unittest.TestCase):
doc.set_missing_values()
self.assertEquals(doc.items[0].is_fixed_asset, 1)
def test_schedule_for_straight_line_method(self):
pr = make_purchase_receipt(item_code="Macbook Pro",
qty=1, rate=100000.0, location="Test Location")
@@ -564,6 +563,81 @@ class TestAsset(unittest.TestCase):
self.assertEqual(gle, expected_gle)
def test_gle_with_cwip_toggling(self):
# TEST: purchase an asset with cwip enabled and then disable cwip and try submitting the asset
frappe.db.set_value("Asset Category", "Computers", "enable_cwip_accounting", 1)
pr = make_purchase_receipt(item_code="Macbook Pro",
qty=1, rate=5000, do_not_submit=True, location="Test Location")
pr.set('taxes', [{
'category': 'Total',
'add_deduct_tax': 'Add',
'charge_type': 'On Net Total',
'account_head': '_Test Account Service Tax - _TC',
'description': '_Test Account Service Tax',
'cost_center': 'Main - _TC',
'rate': 5.0
}, {
'category': 'Valuation and Total',
'add_deduct_tax': 'Add',
'charge_type': 'On Net Total',
'account_head': '_Test Account Shipping Charges - _TC',
'description': '_Test Account Shipping Charges',
'cost_center': 'Main - _TC',
'rate': 5.0
}])
pr.submit()
expected_gle = (
("Asset Received But Not Billed - _TC", 0.0, 5250.0),
("CWIP Account - _TC", 5250.0, 0.0)
)
pr_gle = frappe.db.sql("""select account, debit, credit from `tabGL Entry`
where voucher_type='Purchase Receipt' and voucher_no = %s
order by account""", pr.name)
self.assertEqual(pr_gle, expected_gle)
pi = make_invoice(pr.name)
pi.submit()
expected_gle = (
("_Test Account Service Tax - _TC", 250.0, 0.0),
("_Test Account Shipping Charges - _TC", 250.0, 0.0),
("Asset Received But Not Billed - _TC", 5250.0, 0.0),
("Creditors - _TC", 0.0, 5500.0),
("Expenses Included In Asset Valuation - _TC", 0.0, 250.0),
)
pi_gle = frappe.db.sql("""select account, debit, credit from `tabGL Entry`
where voucher_type='Purchase Invoice' and voucher_no = %s
order by account""", pi.name)
self.assertEqual(pi_gle, expected_gle)
asset = frappe.db.get_value('Asset', {'purchase_receipt': pr.name, 'docstatus': 0}, 'name')
asset_doc = frappe.get_doc('Asset', asset)
month_end_date = get_last_day(nowdate())
asset_doc.available_for_use_date = nowdate() if nowdate() != month_end_date else add_days(nowdate(), -15)
self.assertEqual(asset_doc.gross_purchase_amount, 5250.0)
asset_doc.append("finance_books", {
"expected_value_after_useful_life": 200,
"depreciation_method": "Straight Line",
"total_number_of_depreciations": 3,
"frequency_of_depreciation": 10,
"depreciation_start_date": month_end_date
})
# disable cwip and try submitting
frappe.db.set_value("Asset Category", "Computers", "enable_cwip_accounting", 0)
asset_doc.submit()
# asset should have gl entries even if cwip is disabled
expected_gle = (
("_Test Fixed Asset - _TC", 5250.0, 0.0),
("CWIP Account - _TC", 0.0, 5250.0)
)
gle = frappe.db.sql("""select account, debit, credit from `tabGL Entry`
where voucher_type='Asset' and voucher_no = %s
order by account""", asset_doc.name)
self.assertEqual(gle, expected_gle)
frappe.db.set_value("Asset Category", "Computers", "enable_cwip_accounting", 1)
def test_expense_head(self):
pr = make_purchase_receipt(item_code="Macbook Pro",
qty=2, rate=200000.0, location="Test Location")
@@ -599,6 +673,7 @@ def create_asset(**args):
"purchase_date": "2015-01-01",
"calculate_depreciation": 0,
"gross_purchase_amount": 100000,
"purchase_receipt_amount": 100000,
"expected_value_after_useful_life": 10000,
"warehouse": args.warehouse or "_Test Warehouse - _TC",
"available_for_use_date": "2020-06-06",

View File

@@ -11,12 +11,54 @@ from frappe.model.document import Document
class AssetCategory(Document):
def validate(self):
self.validate_finance_books()
self.validate_account_types()
self.validate_account_currency()
def validate_finance_books(self):
for d in self.finance_books:
for field in ("Total Number of Depreciations", "Frequency of Depreciation"):
if cint(d.get(frappe.scrub(field)))<1:
frappe.throw(_("Row {0}: {1} must be greater than 0").format(d.idx, field), frappe.MandatoryError)
def validate_account_currency(self):
account_types = [
'fixed_asset_account', 'accumulated_depreciation_account', 'depreciation_expense_account', 'capital_work_in_progress_account'
]
invalid_accounts = []
for d in self.accounts:
company_currency = frappe.get_value('Company', d.get('company_name'), 'default_currency')
for type_of_account in account_types:
if d.get(type_of_account):
account_currency = frappe.get_value("Account", d.get(type_of_account), "account_currency")
if account_currency != company_currency:
invalid_accounts.append(frappe._dict({ 'type': type_of_account, 'idx': d.idx, 'account': d.get(type_of_account) }))
for d in invalid_accounts:
frappe.throw(_("Row #{}: Currency of {} - {} doesn't matches company currency.")
.format(d.idx, frappe.bold(frappe.unscrub(d.type)), frappe.bold(d.account)),
title=_("Invalid Account"))
def validate_account_types(self):
account_type_map = {
'fixed_asset_account': { 'account_type': 'Fixed Asset' },
'accumulated_depreciation_account': { 'account_type': 'Accumulated Depreciation' },
'depreciation_expense_account': { 'root_type': 'Expense' },
'capital_work_in_progress_account': { 'account_type': 'Capital Work in Progress' }
}
for d in self.accounts:
for fieldname in account_type_map.keys():
if d.get(fieldname):
selected_account = d.get(fieldname)
key_to_match = next(iter(account_type_map.get(fieldname))) # acount_type or root_type
selected_key_type = frappe.db.get_value('Account', selected_account, key_to_match)
expected_key_type = account_type_map[fieldname][key_to_match]
if selected_key_type != expected_key_type:
frappe.throw(_("Row #{}: {} of {} should be {}. Please modify the account or select a different account.")
.format(d.idx, frappe.unscrub(key_to_match), frappe.bold(selected_account), frappe.bold(expected_key_type)),
title=_("Invalid Account"))
@frappe.whitelist()
def get_asset_category_account(fieldname, item=None, asset=None, account=None, asset_category = None, company = None):

View File

@@ -24,26 +24,6 @@ frappe.ui.form.on('Asset Maintenance', {
return indicator;
}
);
frm.set_query('select_serial_no', function(doc){
return {
asset: frm.doc.asset_name
}
})
},
select_serial_no: (frm) => {
let serial_nos = frm.doc.serial_no || frm.doc.select_serial_no;
if (serial_nos) {
serial_nos = serial_nos.split('\n');
serial_nos.push(frm.doc.select_serial_no);
const unique_sn = serial_nos.filter(function(elem, index, self) {
return index === self.indexOf(elem);
});
frm.set_value("serial_no", unique_sn.join('\n'));
}
},
refresh: (frm) => {
@@ -93,25 +73,6 @@ frappe.ui.form.on('Asset Maintenance Task', {
},
end_date: (frm, cdt, cdn) => {
get_next_due_date(frm, cdt, cdn);
},
assign_to: (frm, cdt, cdn) => {
var d = locals[cdt][cdn];
if (frm.doc.__islocal) {
frappe.model.set_value(cdt, cdn, "assign_to", "");
frappe.model.set_value(cdt, cdn, "assign_to_name", "");
frappe.throw(__("Please save before assigning task."));
}
if (d.assign_to) {
return frappe.call({
method: 'erpnext.assets.doctype.asset_maintenance.asset_maintenance.assign_tasks',
args: {
asset_maintenance_name: frm.doc.name,
assign_to_member: d.assign_to,
maintenance_task: d.maintenance_task,
next_due_date: d.next_due_date
}
});
}
}
});

View File

@@ -1,559 +1,140 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:asset_name",
"beta": 0,
"creation": "2017-10-19 16:50:22.879545",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"actions": [],
"autoname": "field:asset_name",
"creation": "2017-10-19 16:50:22.879545",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"asset_name",
"asset_category",
"company",
"column_break_3",
"item_code",
"item_name",
"section_break_6",
"maintenance_team",
"column_break_9",
"maintenance_manager",
"maintenance_manager_name",
"section_break_8",
"asset_maintenance_tasks"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "asset_name",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Asset Name",
"length": 0,
"no_copy": 0,
"options": "Asset",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "asset_name",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Asset Name",
"options": "Asset",
"reqd": 1,
"unique": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "asset_name.asset_category",
"fieldname": "asset_category",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Asset Category",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "asset_category",
"fieldtype": "Read Only",
"label": "Asset Category"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "asset_name.item_code",
"fieldname": "item_code",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Item Code",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "item_code",
"fieldtype": "Read Only",
"label": "Item Code"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "asset_name.item_name",
"fieldname": "item_name",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Item Name",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "item_name",
"fieldtype": "Read Only",
"label": "Item Name"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "column_break_3",
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Company",
"length": 0,
"no_copy": 0,
"options": "Company",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
"options": "Company",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "select_serial_no",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Select Serial No",
"length": 0,
"no_copy": 0,
"options": "Serial No",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "section_break_6",
"fieldtype": "Section Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "serial_no",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Serial No",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "maintenance_team",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Maintenance Team",
"options": "Asset Maintenance Team",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "column_break_9",
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "maintenance_team",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Maintenance Team",
"length": 0,
"no_copy": 0,
"options": "Asset Maintenance Team",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_9",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "maintenance_team.maintenance_manager",
"fieldname": "maintenance_manager",
"fieldtype": "Data",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Maintenance Manager",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "maintenance_manager",
"fieldtype": "Data",
"hidden": 1,
"label": "Maintenance Manager",
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "maintenance_team.maintenance_manager_name",
"fieldname": "maintenance_manager_name",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Maintenance Manager Name",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "maintenance_manager_name",
"fieldtype": "Read Only",
"label": "Maintenance Manager Name"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Tasks",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"label": "Tasks"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "asset_maintenance_tasks",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Maintenance Tasks",
"length": 0,
"no_copy": 0,
"options": "Asset Maintenance Task",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"fieldname": "asset_maintenance_tasks",
"fieldtype": "Table",
"label": "Maintenance Tasks",
"options": "Asset Maintenance Task",
"reqd": 1
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-05-22 17:20:54.711885",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Maintenance",
"name_case": "",
"owner": "Administrator",
],
"links": [],
"modified": "2020-05-28 20:28:32.993823",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Maintenance",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Quality Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Quality Manager",
"share": 1,
"write": 1
},
},
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Manufacturing User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Manufacturing User",
"share": 1,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

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