Compare commits

...

464 Commits

Author SHA1 Message Date
Sahil Khan
d959463cbc Merge branch 'v12-pre-release' into version-12 2020-04-17 11:27:54 +05:30
Sahil Khan
e6d02ecd7f bumped to version 12.7.0 2020-04-17 11:47:54 +05:50
Nabin Hait
4770626bbd fix: requested qty for customer provided item and rate for sales (#21301)
* 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:18 +05:30
rohitwaghchaure
df045e9f6d Merge pull request #21308 from rohitwaghchaure/fixed_job_card_time_issue_pre_release
fix: job card timer issue
2020-04-17 00:56:16 +05:30
Rohit Waghchaure
c10c920914 fix: job card time issue 2020-04-17 00:48:08 +05:30
rohitwaghchaure
fd99cc8494 Merge pull request #21294 from nabinhait/b12-7-pre-release-1
fix: requested qty calculation and some other small fixes
2020-04-16 19:18:54 +05:30
Nabin Hait
9ea9ed4256 Merge branch 'v12-pre-release' into b12-7-pre-release-1 2020-04-16 19:07:45 +05:30
Saqib
65eea97e0c fix: serial and batch selection from delivery note bug fix (#21293) 2020-04-16 16:22:16 +05:30
Nabin Hait
bd57cbda03 fix: requested qty calculation fix for UOM 2020-04-16 14:27:25 +05:30
Nabin Hait
31c8f8e795 chore: added change log v12.7.0 (#21289) 2020-04-16 12:46:42 +05:30
Nabin Hait
ccfc005932 fix: Made received qty readonly and no-copy 2020-04-16 11:25:15 +05:30
Nabin Hait
b4dfc8e1bf fix: Made release date mandatory 2020-04-16 11:24:43 +05:30
Marica
3635b17f22 Merge pull request #21287 from nextchamp-saqib/warehouse-fix-pre-release
fix: warehouse unset when cannot find item warehouse
2020-04-15 23:56:39 +05:30
Saqib Ansari
5d3e211531 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:10:00 +05:30
Saqib Ansari
bde676ef74 fix: pos not accessible without default customer 2020-04-15 22:09:50 +05:30
rohitwaghchaure
18a04a24b3 Merge pull request #21278 from marination/default-item-manufacturer-pre-release
feat: Provision to set Default Item Manufacturer
2020-04-15 16:47:47 +05:30
marination
64f053d583 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-15 16:43:41 +05:30
Nabin Hait
1fc8de32f1 fix: merge conflict 2020-04-14 20:31:50 +05:30
rohitwaghchaure
09f6199b36 fix: pick list test (#21267) 2020-04-14 19:43:26 +05:30
Rohan
b0f000b1c8 fix: order_type validation restriction (#18096) (#21264)
Co-authored-by: Don-Leopardo <46027152+Don-Leopardo@users.noreply.github.com>
2020-04-14 19:42:21 +05:30
Nabin Hait
49b653b444 fix: merge conflict 2020-04-14 19:34:48 +05:30
Nabin Hait
107229de04 fix: Fixed expense claim payment status 2020-04-14 19:33:05 +05:30
Deepesh Garg
1112bd0f23 Merge pull request #21260 from Alchez/v12-stock-available-order-desk
fix: [minor] show stock UOM in POS (v12)
2020-04-14 17:00:49 +05:30
rohitwaghchaure
8c931e4185 Merge pull request #21263 from rohitwaghchaure/fixed_stock_reco_test_case
fix: stock reco test case
2020-04-14 14:50:49 +05:30
Rohit Waghchaure
5771aabc49 fix: stock reco test case 2020-04-14 14:49:47 +05:30
Rohan Bansal
954c6540fd fix: show stock UOM in POS 2020-04-14 14:22:10 +05:30
rohitwaghchaure
4eea8bd2c0 fix: on changing qty free item not removed (#21250) 2020-04-14 12:49:38 +05:30
Marica
335d35a988 fix: Lead Contact with blank first name via Customer (#21248) 2020-04-14 11:53:00 +05:30
Faris Ansari
2833db559e fix: Set Price List in case of User Permissions (#21238)
Frontport of #18968
2020-04-14 11:50:54 +05:30
rohitwaghchaure
3d667bfe55 fix: minor issues (#21203) 2020-04-14 11:48:56 +05:30
Marica
7841653a03 fix: Project Update Email Error (#21209)
* fix: Project Update Email Error

* fix: Removed mandatory depends on

Co-authored-by: Himanshu <himanshuwarekar@yahoo.com>
2020-04-14 11:47:22 +05:30
Saqib
02a9b5a8a5 chore: hide redundant base received amount (#21229)
* fix: formatting

* chore: hide redundant base received amount
2020-04-14 11:45:56 +05:30
Vishal Dhayagude
4b1d0d19fb fix: str object not callable (#21228) 2020-04-14 11:42:22 +05:30
Mangesh-Khairnar
8b31e3ec2a fix: consider revereted expired leaves entry (#21256) 2020-04-14 09:33:53 +05:30
Marica
b2ba5dbd6a Merge pull request #21214 from vishdha/batch_message
fix(UX): batch error message improved
2020-04-13 15:38:59 +05:30
Marica
b2a9413c06 Merge branch 'version-12-hotfix' into batch_message 2020-04-13 13:20:43 +05:30
vishdha
1b15734bd8 fix: batch message ux improved 2020-04-13 12:36:54 +05:30
Deepesh Garg
725d6b235f Merge pull request #21241 from mujeerhashmi/v12_gstr_3b_report_fix
fix: GSTR 3B Report tax amount calculation
2020-04-13 11:05:24 +05:30
Syed Mujeer Hashmi
87c6b6d12f fix: GSTR 3B Report tax amount calculation
The tax amount after discount amount should be considered for tax
calculation.

Fixes #21231

Signed-off-by: Syed Mujeer Hashmi <mujeerhashmi@4csolutions.in>
(cherry picked from commit 58a16f1a3b)
2020-04-11 22:56:00 +05:30
Deepesh Garg
703e20df79 Merge pull request #21178 from nextchamp-saqib/purchase-register-filters-v12
feat: (minor) purchase register filters
2020-04-11 18:12:20 +05:30
Deepesh Garg
9d0af22b88 Merge pull request #21202 from marination/serial-no-status-hotfix
fix: Added Status field in Serial No for filter and report builder
2020-04-10 20:48:45 +05:30
Deepesh Garg
073d1c4c13 fix: SQL ssyntax error 2020-04-10 20:33:03 +05:30
Deepesh Garg
c4115c19e4 Merge branch 'version-12-hotfix' of https://github.com/frappe/erpnext into purchase-register-filters-v12 2020-04-10 20:32:30 +05:30
rohitwaghchaure
38896efd6d Merge pull request #21157 from marination/mr-customer-provided-to-stock-entry-hotfix
fix: Mapping Customer Provided Material Request to Stock Entry
2020-04-09 13:19:41 +05:30
Marica
b225ffa003 fix: Error on any new doc from Shipping Rule. (#21207) 2020-04-09 12:01:29 +05:30
vishdha
c3bb5a97f8 fix: item_name added for message 2020-04-09 11:25:02 +05:30
marination
cdd589a58a fix: Status field in Serial No for filter and report builder 2020-04-08 16:08:09 +05:30
Mangesh-Khairnar
bf5c7fc4d3 fix(MWS): add new regions to marketplace (#21195)
* fix(MWS): add marketplace region for uae

* fix: rename the fields for mws integrations

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-04-08 12:56:22 +05:30
Saqib
27eba1fc61 fix: cannot find accounting module while rendering breadcrumb (#21191) 2020-04-08 11:49:34 +05:30
Nabin Hait
95b6e8afda fix: Replace newlines with spaces before evaluation of condition and formula (#21166) 2020-04-08 09:34:39 +05:30
Saqib
7c1f2ce4eb fix: [ux] enforce 'get references from' in payment order (#21176) 2020-04-08 09:20:41 +05:30
rohitwaghchaure
af64300c18 Merge pull request #21066 from marination/bin-requested-qty-hotfix
fix: Updated Bin Requested Qty logic
2020-04-07 18:06:07 +05:30
rohitwaghchaure
6668544b4c Merge pull request #21169 from rohitwaghchaure/get_serial_nos_based_on_posting_date_and_time
fix: get serial nos based on posting date and time
2020-04-07 18:02:34 +05:30
Deepesh Garg
5e841b40f3 Merge pull request #21189 from deepeshgarg007/dimension_filter_fix_v12
fix: Use separate condition for tree and normal doctype
2020-04-07 15:23:25 +05:30
Deepesh Garg
5e79f763b5 fix: Use separate condition for tree and normal doctype 2020-04-07 15:19:21 +05:30
Rohit Waghchaure
aebf0e47f3 fix: get serial nos based on posting date and time 2020-04-07 14:41:24 +05:30
rohitwaghchaure
645ef9db87 Merge pull request #21182 from marination/purchase-receipt-scan-barcode-hotfix
feat: Scan Barcode in Purchase Receipt
2020-04-07 14:37:17 +05:30
Marica
d76ecb960e fix: Validate Serial/Batch No naming series in Item itself (#21168)
* fix: Validate Serial/Batch No naming series in Item itself

* fix: Consider '#' too
2020-04-07 14:15:48 +05:30
Vishal Dhayagude
d2da8bd6e2 fix(shopping cart): UX Improvements (#21035)
* fix: nontype error for resolved and moved place order button at bottom left

* fix: removed inline style

* fix: Request for quotation move to lower right

* fix: move buttons

Co-authored-by: Naren <patilnarendra3@gmail.com>
Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2020-04-07 12:19:40 +05:30
Saqib
a5fb07e475 fix(shopping-cart): address is made mandatory to place order (#20922)
fix(shopping-cart): address is made mandatory to place order
2020-04-07 12:09:28 +05:30
rohitwaghchaure
bcf1897e60 Merge pull request #21173 from rohitwaghchaure/material_request_incorrect_filter_issue
fix: material request type manufacture shows items with Is Purchase I…
2020-04-07 12:06:04 +05:30
Vishal Dhayagude
044abbace8 fix: Make Sales Invoice paid when it create from shopping cart (#20878)
Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2020-04-07 12:05:18 +05:30
Deepesh Garg
36a763bdc5 Merge pull request #21106 from nextchamp-saqib/payment-req-status-fix-v12
fix: payment request status fixes
2020-04-07 10:13:29 +05:30
marination
2dd488f878 feat: Scan Barcode in Purchase Receipt 2020-04-06 23:16:57 +05:30
Saqib Ansari
34288b0f38 feat: (minor) purchase register filters 2020-04-06 18:26:03 +05:30
Rohit Waghchaure
d7389b1920 fix: material request type manufacture shows items with Is Purchase Item enabled 2020-04-06 17:49:49 +05:30
Marica
42eddbf89b Merge branch 'version-12-hotfix' into bin-requested-qty-hotfix 2020-04-06 16:38:06 +05:30
Saqib
8e206f55be Merge branch 'version-12-hotfix' into cart-address-update-hotfix 2020-04-06 14:22:06 +05:30
Saqib Ansari
4ea7df69b4 fix: change request status on payment entry cancel 2020-04-06 12:35:54 +05:30
Marica
da6ef63bc4 Merge pull request #20865 from deepeshgarg007/po_supplier_skip_v12
feat: Allow PI creation without PO
2020-04-06 12:16:02 +05:30
Nabin Hait
5da9663ae4 Merge branch 'version-12-hotfix' into expense-claim-fix-v12 2020-04-06 12:14:27 +05:30
Nabin Hait
322660c644 fix: Merge conflict 2020-04-06 11:16:31 +05:30
Nabin Hait
2378572e1b fix: update attendace from leave application (#21154) 2020-04-06 10:15:50 +05:30
Deepesh Garg
ab436d4147 Merge pull request #21164 from deepeshgarg007/gst_3b_user_perm_v12
fix: User permissions in GSTR 3B report
2020-04-04 21:48:31 +05:30
Deepesh Garg
18cd3a029d fix: User permissions in GSTR 3B report 2020-04-04 20:07:44 +05:30
Saqib
dba4bd6f26 fix: [ux] credit to & debit to error message (#21133)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-04-03 19:36:00 +05:30
Marica
7bc70758fb Merge branch 'version-12-hotfix' into po_supplier_skip_v12 2020-04-03 18:35:29 +05:30
Deepesh Garg
69e0700101 Merge pull request #21158 from scmmishra/coa_importer
fix: TypeError for _ in coa importer
2020-04-03 18:34:44 +05:30
marination
dfe4d36e8d fix: Test Cases and block expense on outward entry
- Throw error if rate present against Customer Provided Item in DN and SI
- Added test cases for Sales Invoice and Delivery Note
- Allow SI and DN with 0 rate in Test
2020-04-03 18:29:30 +05:30
Shivam Mishra
55ded1379e Merge branch 'version-12-hotfix' into coa_importer 2020-04-03 17:21:42 +05:30
Shivam Mishra
64ed25abfb fix: TypeError for _ 2020-04-03 17:17:04 +05:30
marination
7b70679bf0 fix: Mapping Customer Provided Material Request to Stock Entry
- Fixed inability to map Material Request to Stock Entry
- Commonified Customer Provided Item validation
2020-04-03 15:57:32 +05:30
Deepesh Garg
31fbafe16f Merge pull request #21151 from scmmishra/fix-patch-dashboard-12
fix (tests): module import error for Dashboard Chart Field
2020-04-03 11:05:11 +05:30
Shivam Mishra
878e4cb3ce fix: lms quiz type error (#21153) 2020-04-03 10:07:44 +05:30
Marica
73bc29c011 fix: Update Received Qty in Material Request as per Stock UOM (#21055)
* fix: Update Received Qty in Material Request as per Stock UOM

* fix: Process each PR only once

* fix: minor suggested changes

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-04-03 10:06:39 +05:30
Saqib
44dbd98d90 fix: cannot set warehouse on deleting all so items and updating them (#21079)
* fix: cannot set warehouse on deleting all so items and updating them

* fix: travis

* fix: travis

* fix: docname is editable in update items dialog

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2020-04-03 10:01:14 +05:30
Marica
8b5693b77f Merge branch 'version-12-hotfix' into po_supplier_skip_v12 2020-04-02 21:14:19 +05:30
Deepesh Garg
76d2bd9633 Merge branch 'version-12-hotfix' into fix-patch-dashboard-12 2020-04-02 20:24:10 +05:30
Deepesh Garg
83c7561a84 Merge pull request #21149 from deepeshgarg007/travis_company_fixture_v12
fix: Travis(v12)
2020-04-02 20:22:53 +05:30
Shivam Mishra
f8cb81c9f9 fix (tests): reload doctype 2020-04-02 19:59:47 +05:30
marination
4a59b1d3b5 fix: Fixed Test Cases for Material Request
- Reduce quantity on Material Transfer/Issue
- No effect on Customer Provided Material Request
2020-04-02 19:38:38 +05:30
Deepesh Garg
763aab3301 fix: Travis 2020-04-02 19:12:36 +05:30
rohitwaghchaure
0bbc78cdbd Merge pull request #21145 from anupamvs/year-sum-hotfix
Sum of years not needed.
2020-04-02 12:00:55 +05:30
Anupam K
29fc063764 Sum of years not needed. 2020-04-02 11:34:42 +05:30
Anupam K
a66da0ddf4 Sum of years not needed. 2020-04-02 01:06:30 +05:30
Deepesh Garg
4fd447a31d Merge pull request #21136 from marination/stock-ledger-typo-hotfix
fix: Typo in stock level validation in Stock Ledger
2020-04-01 11:20:55 +05:30
marination
122049a9b4 fix: Typo in stock level validation in Stock Ledger 2020-04-01 11:07:46 +05:30
Marica
6a49ea5262 Merge pull request #21097 from rohitwaghchaure/item_code_showing_as_mandatory_issue_hotfix
fix: item code showing as mandatory even if the 'Item Naming By' is set as Naming Series in stock settings
2020-04-01 10:56:14 +05:30
Marica
9f709aa64c Merge branch 'version-12-hotfix' into item_code_showing_as_mandatory_issue_hotfix 2020-04-01 10:46:55 +05:30
Deepesh Garg
702e0ac29e Merge pull request #21117 from nextchamp-saqib/customer-group-price-list-in-pos-v12
fix: customer group price list not fetched in pos
2020-04-01 09:41:04 +05:30
Saqib Ansari
954276ff0e fix: check if selling price exists then set it 2020-03-31 18:49:28 +05:30
Saqib Ansari
0541b2ee27 fix: travis 2020-03-31 18:44:38 +05:30
Marica
dc6a3ae99c Merge pull request #21071 from pipech/v12_fix_pos-display-stock-item
fix(pos): fix pos not display only in-stock item
2020-03-31 18:13:44 +05:30
Marica
2512435a7b Merge branch 'version-12-hotfix' into v12_fix_pos-display-stock-item 2020-03-31 18:08:10 +05:30
Deepesh Garg
7d8d351668 Merge pull request #21064 from P-Froggy/fix-add-bank-account-reference-in-supplier-dashboard-hotfix
fix: Add missing bank accounts reference in supplier dashboard
2020-03-31 16:33:19 +05:30
Deepesh Garg
0126ef78c8 Merge pull request #21093 from scmmishra/multiple-option-fix-12
fix: use setup from Supplier Quotation Controller
2020-03-31 16:29:10 +05:30
rohitwaghchaure
489a5d203f Merge pull request #21016 from marination/so-mr-mapping-uom-hotfix
fix: UOM fixes in Sales Order,Material Request & Production Plan
2020-03-31 16:11:57 +05:30
Deepesh Garg
4716fc5eb8 Merge branch 'version-12-hotfix' into fix-add-bank-account-reference-in-supplier-dashboard-hotfix 2020-03-31 16:04:21 +05:30
rohitwaghchaure
437689371d Merge pull request #21002 from Alchez/v12-stock-entry-fg-validation
fix: allow target warehouses to be changed for work order stock entries (v12)
2020-03-31 15:43:28 +05:30
Saqib
798d532a11 fix: warehouse_account_map not getting reset for diff company transac… (#20997)
* fix: warehouse_account_map not getting reset for diff company transaction

* fix: potential key errors while fetching warehouse_account_map

* fix: travis

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-31 15:30:53 +05:30
rohitwaghchaure
c5a3bcca70 fix: make for quantity as non mandatory in job card (#21080) 2020-03-31 15:28:15 +05:30
rohitwaghchaure
e4cb523181 fix: serial no scan not adding the serial nos in stock entry (#21082) 2020-03-31 15:26:24 +05:30
Rucha Mahabal
b80213d65d fix: Healthcare Domain Issues (#21112)
* fix (Lab Test): None TypeError in Patient Medical Record

* fix: Lab Test Template data import failing in Lab Test Item creation

* fix: disabled Procedure Template shown as enabled in List View

* fix: change item_code from Link to Data to avoid item not found error

* fix: disabled patient shown as enabled

* fix: disabled practitioner schedule shown as enabled in list view

* fix: appointment reminders not working

* fix: Batch not getting fetched in Clinical Procedure Item
2020-03-31 10:52:51 +05:30
Anupam Kumar
d13e7d00b0 fix: email_to, party_type and party are not set in payment request (#21085)
* fix: email_to, party_type and party are not set in payment request when order made from portal

* fix: email_to, party_type and party are not set in payment request when order made from portal

Co-authored-by: Anupam K <anupam@Anupams-MacBook-Air.local>
2020-03-31 10:50:53 +05:30
Saqib
f492ba1e2d fix: auto created asset message (#21109)
* fix: auto created asset message

* Update erpnext/controllers/buying_controller.py

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-31 10:48:57 +05:30
Deepesh Garg
83111a4a2a fix: Expense account currency validation in Landed Cost voucher (#21074)
* fix: Expense account currency validation in Landed Cost voucher

* fix: Remove unused imports
2020-03-31 10:45:37 +05:30
Deepesh Garg
5a482a6685 Merge pull request #21068 from Alchez/v12-add-issue-status-filter
feat: add status filter in issue web form (v12)
2020-03-30 12:24:34 +05:30
Deepesh Garg
bda11e628b Merge pull request #21118 from rohitwaghchaure/fixed_parent_account_error_while_adding_equity_account
fix: not able to add equity account in the chart of accounts
2020-03-30 12:14:32 +05:30
Deepesh Garg
b8be73caea Merge pull request #21111 from nextchamp-saqib/cancel-error-hyperlink-v12
chore: hyperlinks in cannot cancel message
2020-03-29 21:54:09 +05:30
Deepesh Garg
df151ad6fa Merge pull request #21116 from nextchamp-saqib/course-report-perm-fix-v12
fix: cannot view report for course doctype - permission problem
2020-03-29 21:52:02 +05:30
Rohit Waghchaure
7e7787c298 fix: not able to add equity account in the chart of accounts 2020-03-29 16:33:30 +05:30
Saqib Ansari
1dd0c8f54c fix: customer group price list not fetched in pos 2020-03-29 12:58:30 +05:30
Saqib Ansari
dc04cbf9a9 fix: cannot view report for course doctype - permission problem 2020-03-29 12:52:43 +05:30
Deepesh Garg
77673f33db Merge pull request #21090 from scmmishra/print-format-fix-12
fix: total currency formatting in Acc Receivable and Payable
2020-03-28 21:28:20 +05:30
Deepesh Garg
f4e7de3cef Merge pull request #21104 from nextchamp-saqib/stock-ledger-warehouse-filter-v12
chore: [ux] filter warehouse based on company
2020-03-28 21:10:01 +05:30
Deepesh Garg
9b4ef1059c Merge pull request #21107 from nextchamp-saqib/gl-entry-currency-fix-v12
fix: currency formatting in gl entry dr cr field
2020-03-28 21:09:29 +05:30
Saqib Ansari
8ba661b8ed chore: hyperlinks in cannot cancel message 2020-03-28 20:11:59 +05:30
Saqib Ansari
1125ed8830 fix: currency formatting in gl entry dr cr field 2020-03-28 19:32:27 +05:30
Saqib Ansari
58351de797 fix: payment request status fixes 2020-03-28 19:30:03 +05:30
Saqib Ansari
f9ce7c2e18 chore: [ux] filter warehouse based on company 2020-03-28 19:16:00 +05:30
rohitwaghchaure
221189ab6e Merge pull request #21095 from anupamvs/item-wise-sales-history-billed-amount-bug-hotfix
bug: Item-wise Sales History - Billed amount
2020-03-28 15:00:46 +05:30
Rohit Waghchaure
8f854c7d93 fix: item code showing as mandatory even if the 'Item Naming By' is set as Naming Series in stock settings 2020-03-28 14:56:45 +05:30
Anupam K
728edacfd4 bug: Item-wise Sales History - Billed amount 2020-03-28 13:48:42 +05:30
Deepesh Garg
9aa8cabf93 Merge pull request #21088 from nabinhait/item_defaults_fix
fix: Add item defaults based on global settings only if default company and warehouse is mentioned
2020-03-27 21:50:19 +05:30
Shivam Mishra
cf2ab9b129 fix: use setup from Supplier Quotation Controller 2020-03-27 21:21:38 +05:30
Shivam Mishra
2313d2d80a fix: total currency formatting 2020-03-27 19:37:26 +05:30
Nabin Hait
b03d1327a5 fix: Add item defaults based on global settings only if default company and warehouse is mentioned 2020-03-27 19:24:17 +05:30
rohitwaghchaure
8110edbc62 Merge pull request #21076 from rohitwaghchaure/default_item_is_not_coming_while_making_new_bom
fix: item not showing in popup while making batch
2020-03-27 13:49:07 +05:30
Rohit Waghchaure
d90f658163 fix: item not showing in popup while making batch 2020-03-27 12:54:01 +05:30
Poranut Chollavorn
0b8191d566 fix(pos): fix pos display item instock 2020-03-26 13:46:36 +00:00
Rohan Bansal
27f0d13bdd feat: add status filter in issue web form 2020-03-26 16:06:07 +05:30
marination
c944676bb5 fix: Updated Bin Requested Qty logic 2020-03-26 15:44:52 +05:30
Nabin Hait
ff49a2f0b6 fix: Ignored user permission for parent_company and existing_company field in Company (#21010) 2020-03-26 13:36:21 +05:30
Deepesh Garg
8a5587749b fix: Added hidden GL column in general ledger (#21022)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-26 13:29:36 +05:30
Marica
3c378aaac7 fix: Make shelf life mandatory in Batched Item if it has expiry date (#21045) 2020-03-26 13:28:42 +05:30
Raffael Meyer
72430e91b2 fix: account groups (#21046) 2020-03-26 13:25:14 +05:30
Marica
6b038bda0d fix: Project field in Stock Entry Detail should be editable (#21000) 2020-03-26 13:23:54 +05:30
Saqib
01f80b239d fix: wrong calculation of depreciation eliminated for a period (#21032) 2020-03-26 13:23:06 +05:30
Saqib
b9f81d913b fix: currency not fetched on quotation creation (#20998) 2020-03-26 13:20:27 +05:30
Saqib
750985dc23 feat: auto set batch no on serial no selection (#20758)
* feat: auto set batch no on serial no selection

* fix: dialog not shown if set warehouse selected

* fix: typo

* fix: merge conflict

* fix: callback no getting called after serial no selected

* fix: callback no getting called after serial no selected

* fix: available batch qty not fetched without set_warehouse selected

* fix: item batch not synced with dialog batch table
2020-03-26 13:18:36 +05:30
P-Froggy
bcb9c28597 Fix: Add missing bank accounts reference in supplier dashboard 2020-03-26 02:35:09 +01:00
Deepesh Garg
23891a918d Merge pull request #21058 from deepeshgarg007/gstr_1_pos_validation_v12
fix: Place of supply validation in GSTR-1 report
2020-03-25 17:02:19 +05:30
Deepesh Garg
4f1a3876ec fix: Remove debug 2020-03-25 16:56:09 +05:30
Deepesh Garg
43806f3e68 fix: Place of supply validation in GSTR-1 report 2020-03-25 16:55:59 +05:30
Deepesh Garg
f4405246ed Merge pull request #21012 from Thunderbottom/log_error-fix-v12
chore: pass traceback and error message as kwargs
2020-03-24 20:19:42 +05:30
rohitwaghchaure
8cc507af53 Merge pull request #21039 from rohitwaghchaure/manufacturing_ux_fixes_hotfix
fix: Manufacturing UX, added calendar view for job card
2020-03-24 16:33:34 +05:30
rohitwaghchaure
6c8bbf9a1c Merge pull request #21029 from rohitwaghchaure/import_supplier_invoices
feat: import supplier invoices
2020-03-24 16:33:00 +05:30
rohitwaghchaure
ea470609fd Merge pull request #21036 from rohitwaghchaure/fixed_batch_selector_popup
fix: batch selection popup not coming for stock entry
2020-03-24 16:31:56 +05:30
Deepesh Garg
ad44f52a26 Merge pull request #21042 from deepeshgarg007/default_dimension_clean_up_v12
fix: Default dimension set code cleanup
2020-03-24 15:48:01 +05:30
Deepesh Garg
1e7cba9dd3 fix: Default dimension set code cleanup 2020-03-24 15:45:22 +05:30
Rohit Waghchaure
87b3dbb214 fix: Manufacturing UX, added calendar view for job card 2020-03-24 14:06:56 +05:30
Rohit Waghchaure
243283eec8 fix: batch selection popup not coming for stock entry 2020-03-24 11:34:44 +05:30
Rohit Waghchaure
b05922026d feat: import supplier invoices 2020-03-23 16:31:39 +05:30
Rohan
ed8e44b467 Merge branch 'version-12-hotfix' into v12-stock-entry-fg-validation 2020-03-23 14:49:59 +05:30
Deepesh Garg
76e163a889 Merge pull request #21026 from deepeshgarg007/dimension_perm_v12
fix: Remove quick entry from accounting dimensions
2020-03-22 21:56:47 +05:30
Deepesh Garg
20ab2c1e20 fix: Remove quick entry from accouting dimensions 2020-03-22 21:53:50 +05:30
Deepesh Garg
3f7ea072c3 Merge pull request #21004 from rohitwaghchaure/qty_must_be_positive_for_stock_entry
fix: stock entry qty must be positive
2020-03-21 20:45:50 +05:30
Deepesh Garg
601db77801 Merge pull request #21014 from surajshetty3416/fix-opportunity-listview-version-12-hotfix
fix: Add currency in options of Opportunity Amount
2020-03-20 20:22:46 +05:30
marination
93e72fdd21 fix: UOM fixes in Sales Order,Material Request & Production Plan 2020-03-20 18:06:25 +05:30
Suraj Shetty
e2bb2593db fix: Add currency in options of Opportunity Amount - To show currect symbol in list view 2020-03-20 15:13:07 +05:30
Chinmay D. Pai
e53e96f01b chore: pass traceback and error message as kwargs
fixes issue where the system tries to generate an error log but fails
with the following error:

Traceback (most recent call last):
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/setup/doctype/company/company.py", line 421, in install_country_fixtures
    frappe.get_attr(module_name)(company_doc, False)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 17, in setup
    make_fixtures(company)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 523, in make_fixtures
    set_tax_withholding_category(company)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 543, in set_tax_withholding_category
    fiscal_year = get_fiscal_year(today(), company=company)[0]
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/accounts/utils.py", line 24, in get_fiscal_year
    return get_fiscal_years(date, fiscal_year, label, verbose, company, as_dict=as_dict)[0]
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/accounts/utils.py", line 80, in get_fiscal_years
    raise FiscalYearError(error_msg)
erpnext.accounts.utils.FiscalYearError: Date 20-03-2020 not in any active Fiscal Year.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/app.py", line 62, in application
    response = frappe.api.handle()
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/api.py", line 55, in handle
    return frappe.handler.handle()
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/handler.py", line 22, in handle
    data = execute_cmd(cmd)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/handler.py", line 61, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/__init__.py", line 1054, in call
    return fn(*args, **newargs)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/desk/form/save.py", line 22, in savedocs
    doc.save()
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 273, in save
    return self._save(*args, **kwargs)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 296, in _save
    self.insert()
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 260, in insert
    self.run_post_save_methods()
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 926, in run_post_save_methods
    self.run_method("on_update")
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 794, in run_method
    out = Document.hook(fn)(self, *args, **kwargs)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 1065, in composer
    return composed(self, method, *args, **kwargs)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 1048, in runner
    add_to_return_value(self, fn(self, *args, **kwargs))
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 788, in <lambda>
    fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/setup/doctype/company/company.py", line 107, in on_update
    install_country_fixtures(self.name)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/setup/doctype/company/company.py", line 423, in install_country_fixtures
    frappe.log_error(str(e), frappe.get_traceback())
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/__init__.py", line 1524, in log_error
    method=title)).insert(ignore_permissions=True)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 231, in insert
    self._validate()
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 463, in _validate
    self._validate_length()
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/base_document.py", line 583, in _validate_length
    self.throw_length_exceeded_error(df, max_length, value)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/base_document.py", line 599, in throw_length_exceeded_error
    .format(reference, _(df.label), max_length, value), frappe.CharacterLengthExceededError, title=_('Value too big'))
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/__init__.py", line 377, in throw
    msgprint(msg, raise_exception=exc, title=title, indicator='red', is_minimizable=is_minimizable)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/__init__.py", line 356, in msgprint
    _raise_exception()
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/__init__.py", line 316, in _raise_exception
    raise raise_exception(msg)
frappe.exceptions.CharacterLengthExceededError: Error Log f2cbb8c0f2: 'Title' (Traceback (most recent call last):
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/setup/doctype/company/company.py", line 421, in install_country_fixtures
    frappe.get_attr(module_name)(company_doc, False)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 17, in setup
    make_fixtures(company)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 523, in make_fixtures
    set_tax_withholding_category(company)
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 543, in set_tax_withholding_category
    fiscal_year = get_fiscal_year(today(), company=company)[0]
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/accounts/utils.py", line 24, in get_fiscal_year
    return get_fiscal_years(date, fiscal_year, label, verbose, company, as_dict=as_dict)[0]
  File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/accounts/utils.py", line 80, in get_fiscal_years
    raise FiscalYearError(error_msg)
erpnext.accounts.utils.FiscalYearError: Date 20-03-2020 not in any active Fiscal Year.
) will get truncated, as max characters allowed is 140

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2020-03-20 13:57:30 +05:30
Rohit Waghchaure
794064db9f fix: stock entry qty must be positive 2020-03-19 14:44:16 +05:30
Rohan
4c4a1aa56d fix: allow target warehouses to be changed for work order stock entries 2020-03-19 13:19:08 +05:30
Sahil Khan
84a5e34319 Merge branch 'v12-pre-release' into version-12 2020-03-19 12:44:10 +05:30
Sahil Khan
d1bbda6d71 bumped to version 12.6.0 2020-03-19 13:04:10 +05:50
Deepesh Garg
8c56f8595e fix: Unable to submit landed cost voucher (#20978) 2020-03-19 11:03:14 +05:30
Deepesh Garg
c2f6782658 fix: Unable to submit landed cost voucher (#20979) 2020-03-19 11:02:34 +05:30
Deepesh Garg
7c0398c8e3 fix: Update is_tree field in Tree doctypes (#20983) 2020-03-19 11:01:40 +05:30
Deepesh Garg
71e9f23d77 fix: Update is_tree field in Tree doctypes (#20982) 2020-03-19 11:00:55 +05:30
Nabin Hait
7b45ae1f2d fix: Multiple fixes during pre-release testing (#20985) 2020-03-19 10:58:41 +05:30
Nabin Hait
bf0f9c5cb4 fix: Multiple fixes during pre-release testing (#20986) 2020-03-19 10:58:07 +05:30
Deepesh Garg
3f1682a4f3 Merge pull request #20993 from rohitwaghchaure/fixed_bom_comparision_issue_pre_release
fix: bom comparison issue
2020-03-19 10:54:51 +05:30
Deepesh Garg
4dd8f390e2 Merge pull request #20992 from rohitwaghchaure/fixed_bom_comparision_issue_hotfix
fix: bom comparison issue
2020-03-19 10:54:29 +05:30
Rohit Waghchaure
82661aa042 fix: bom comparison issue 2020-03-19 10:06:55 +05:30
Rohit Waghchaure
210a718a04 fix: bom comparison issue 2020-03-19 10:03:06 +05:30
Deepesh Garg
1d94f6c848 Merge pull request #20989 from rohitwaghchaure/fixed_shortage_qty_in_stock_projected_qty_report_pre_release
fix: shortage qty in stock projected qty report
2020-03-19 09:32:50 +05:30
Rohit Waghchaure
d21a9fa917 fix: shortage qty in stock projected qty report 2020-03-19 09:25:15 +05:30
Deepesh Garg
51cbfa6aa6 Merge pull request #20972 from rohitwaghchaure/fixed_shortage_qty_in_stock_projected_qty_report
fix: shortage qty in stock projected qty report
2020-03-19 09:04:30 +05:30
Rohit Waghchaure
1ed5993ff6 fix: shortage qty in stock projected qty report 2020-03-18 13:33:55 +05:30
Marica
e655648b18 fix: Missing if condition in Customer Default Bank Account Validation. (#20971) 2020-03-18 11:35:43 +05:30
Marica
da7c6b0d99 fix: Missing if condition in Customer Default Bank Account Validation. (#20970) 2020-03-18 11:29:02 +05:30
Nabin Hait
a5b836d3d4 core: Added change log 2020-03-17 21:02:22 +05:30
Nabin Hait
8a7ecebc03 fix: merge conflict 2020-03-17 19:49:25 +05:30
Anurag Mishra
7cf245895e refactor: Report BOM Sock Calculated (#19431) 2020-03-17 19:45:33 +05:30
Priyanka Gangar
738517c6e8 Label changes in account settings hotfix (#20964)
* fix: Account setting words switches to US Terminology

* created united_states.js

* Remove Unwanted Spaces

* Remove all changes

* Add spaces between arguments

Co-authored-by: PriyankaGangar <pinka0925@gmail.com>
2020-03-17 19:39:06 +05:30
rohitwaghchaure
a6cd666b10 fix: reserved qty for production issue for partial completion of work order (#20900) 2020-03-17 17:00:41 +05:30
Saqib
bc8a881e64 fix: purchase return are allowed even when assets are not cancelled (#20798)
* fix: purchase return are allowed even when assets are not cancelled

* chore: test case

* fix: error message

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-17 17:00:24 +05:30
Deepesh Garg
224059e7ba fix: Party Name not visible in statement of accounts (#20914)
* fix: Party name in Statement Of Accounts

* Update general_ledger.html

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-17 16:59:09 +05:30
Sun Howwrongbum
6f454dce20 fix: null fields being set in Integration Request (#20894)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-17 12:13:01 +05:30
Deepesh Garg
3528149329 fix: Add check to skip PR in supplier master 2020-03-17 11:48:11 +05:30
Deepesh Garg
6c148ef314 fix: Add check to skip SO and DN in customer master 2020-03-17 11:47:23 +05:30
Anurag Mishra
7f58f6af39 fix: leave based on multiple holiday list (#20849)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-17 10:58:17 +05:30
Marica
3ddcc2e5c7 fix: Item alternative must have similar fields as orignal item (#20799)
* fix: Item alternative must have similar fields as orignal item

* fix: Using db.get_values and meta instead of get_value and get_doc

* fix: Made code more DRY

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-17 10:56:13 +05:30
Deepesh Garg
756f47af04 feat: Nested set filtering for accounting dimension (#20866)
* feat: Nested set filtering for accounting dimension

* fix: Remove print statement
2020-03-17 10:52:56 +05:30
Anurag Mishra
b9e1d9ad7d Deduction based on earnins/gross pay (#20935)
* fix: deductions calculation based on gross pay

* test: salary structure deduction based on gross pay

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-16 22:44:17 +05:30
Deepesh Garg
169ba6f9b2 Merge pull request #20959 from deepeshgarg007/mode_of_payment_fix_v12
fix: Mode of payment not fetcched in Item wise purchase register
2020-03-16 22:43:24 +05:30
nmimsnikhil
7c0e89d785 fix: added a Reason for Rejection field for each items (#20828)
* fix: added a Reason for Rejection field for each items

* Update delivery_note_item.json

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-16 22:41:23 +05:30
Deepesh Garg
dd8059a3aa fix: Mode of payment not fetcched in Item wise purchase register 2020-03-16 22:39:32 +05:30
Don-Leopardo
0dcd5a0f34 fix: sql injection (#20817) 2020-03-16 22:35:01 +05:30
rohitwaghchaure
d2a2837034 fix: bom replace tool issue (#20841)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-16 21:42:51 +05:30
Anurag Mishra
22a069d4b0 fix: Wrong status 2020-03-16 19:15:33 +05:30
Rohan
281a9fdf07 fix: handle error handling (#20814) 2020-03-16 17:57:15 +05:30
Saqib
e7a6a4b009 fix: is_pos gets reset on making s_inv from s_ord (#20887)
* s_inv has is_pos default set as 1
2020-03-16 17:48:21 +05:30
Nabin Hait
5c760175d1 fix: deletion of auto-created batch (#20953) 2020-03-16 17:26:02 +05:30
Deepesh Garg
11fb93d022 fix: Add bank transaction in module view (#20823) 2020-03-16 16:54:34 +05:30
Saqib
43a0011987 fix: serial_no_selector showing for non serialized batched item (#20852) 2020-03-16 16:28:54 +05:30
Vishal Dhayagude
37886a72ef fix(HR): Leave application company field made read-only and filter in Monthly attendance sheet (#20911)
* fix(HR): Leave application company field made Readonly

* fix: in monthly report attandance employee filter based on company

* fix: minor typo
2020-03-16 15:57:42 +05:30
Deepesh Garg
98573fb868 Merge pull request #20921 from deepeshgarg007/c_from_fix_v12
fix: Get invoice details only if invoice is selected
2020-03-16 15:56:19 +05:30
Deepesh Garg
4d954f1a5f Merge pull request #20836 from Thunderbottom/welcome-email-fix-v12
fix: use ERPNext in welcome email when default company is not set
2020-03-16 15:54:09 +05:30
Prssanna Desai
46053f6c8f fix: fix options of currency fieldtype in Expense Taxes and Charges (#20910) 2020-03-16 15:52:00 +05:30
Chinmay Pai
6f3941c9cc fix: remove make_purchase_invoice from demo script (#20906)
currently demo fails with the following error:

frappe@bf54a9834cfe:/workspace/development/frappe-bench$ bench --site test1.localhost execute erpnext.demo.demo.make
Traceback (most recent call last):
  File "/usr/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/workspace/development/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 97, in <module>
    main()
  File "/workspace/development/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 18, in main
    click.Group(commands=commands)(prog_name='bench')
  File "/workspace/development/frappe-bench/env/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/workspace/development/frappe-bench/env/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/workspace/development/frappe-bench/env/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/workspace/development/frappe-bench/env/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/workspace/development/frappe-bench/env/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/workspace/development/frappe-bench/env/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/workspace/development/frappe-bench/env/lib/python3.7/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/workspace/development/frappe-bench/apps/frappe/frappe/commands/__init__.py", line 25, in _func
    ret = f(frappe._dict(ctx.obj), *args, **kwargs)
  File "/workspace/development/frappe-bench/apps/frappe/frappe/commands/utils.py", line 145, in execute
    ret = frappe.get_attr(method)(*args, **kwargs)
  File "/workspace/development/frappe-bench/apps/frappe/frappe/__init__.py", line 1042, in get_attr
    return getattr(get_module(modulename), methodname)
  File "/workspace/development/frappe-bench/apps/frappe/frappe/__init__.py", line 823, in get_module
    return importlib.import_module(modulename)
  File "/workspace/development/frappe-bench/env/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/workspace/development/frappe-bench/apps/erpnext/erpnext/demo/demo.py", line 6, in <module>
    from erpnext.demo.user import hr, sales, purchase, manufacturing, stock, accounts, projects, fixed_asset
  File "/workspace/development/frappe-bench/apps/erpnext/erpnext/demo/user/fixed_asset.py", line 9, in <module>
    from erpnext.assets.doctype.asset.asset import make_purchase_invoice, make_sales_invoice
ImportError: cannot import name 'make_purchase_invoice' from 'erpnext.assets.doctype.asset.asset' (/workspace/development/frappe-bench/apps/erpnext/erpnext/assets/doctype/asset/asset.py)

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2020-03-16 15:49:50 +05:30
Raffael Meyer
cd71114c15 fix(accounts): add account_type and tax_rate to some VAT accounts (#20941)
* Add account_type and tax rate to some VAT accounts

* fix indentation
2020-03-16 15:44:32 +05:30
Nabin Hait
e2a31f221a fix: Multiple fixes for travis (#20950) 2020-03-16 15:36:10 +05:30
Anurag Mishra
97dfe2ac32 fix: local variable 'benefit_amount' referenced before assignment (#20948) 2020-03-16 13:47:47 +05:30
Myuddin khatri
9c63b1d2c9 fix(shopping-cart): setting billing and shipping address
setting billing and shipping address
2020-03-12 16:15:05 +05:30
Myuddin khatri
0f807bf7ee fix(shopping-cart): address is made mandatory to place order 2020-03-12 14:40:34 +05:30
Deepesh Garg
ee003495f6 fix: Get invoice details only if invoice is selected 2020-03-12 13:25:06 +05:30
Deepesh Garg
08f0e9d6f3 Merge pull request #20891 from deepeshgarg007/itemised_purchase_register_v12
fix: HSN code not visible in GST Itemised Purchase register
2020-03-10 10:05:21 +05:30
Deepesh Garg
4d6fb59bfb Merge pull request #20885 from deepeshgarg007/first_row_dimension_v12
fix: Acccounting Dimension disappearing in first row after refresh
2020-03-09 22:47:46 +05:30
Deepesh Garg
0317576434 fix: HSN code not visible in GST Itemised Purchase register 2020-03-09 22:42:21 +05:30
Saqib
b607963fba fix: [pos] customer group filter resets on syncing offline invoices (#20874) 2020-03-09 18:30:42 +05:30
Marica
d08cff9efc fix: Validate Serial No/Batch No against unserialized Item in Stock Reconciliation (#20859) 2020-03-09 18:13:38 +05:30
Marica
2f2cef6c5f fix: ModuleNotFoundError on Turkey Company setup (#20854) 2020-03-09 18:07:55 +05:30
Deepesh Garg
875e0f5fb2 fix: Acccounting Dimension disappearing in first row after refresh 2020-03-09 18:05:35 +05:30
Deepesh Garg
d9ab412032 feat: Allow PI creation without PO 2020-03-06 19:04:41 +05:30
Saqib
6c4cddccf6 fix: show uom in print formats instead of stock uom (#20844)
Co-authored-by: Saqib Ansari <saqibansari@Saqibs-MacBook-Pro.local>
2020-03-06 11:06:41 +05:30
Marica
69d3c4ff25 fix: update_child_qty_rate() missing argument (#20839) 2020-03-06 10:57:43 +05:30
Nabin Hait
1f80c8dffe perf: improve gl entry submission (#20802)
* perf: improve gl entry submission

* perf: add indexes

* fix: replace **kwargs with *args

* fix: syntax error

* fix: travis

* chore: remove purchase invoice from status updater

* fix: set_staus args

Co-Authored-By: Nabin Hait <nabinhait@gmail.com>

* fix: only update status for invoices & fees

* [bug][fix]: set status to object instead of variable (#20790)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
Co-authored-by: Saurabh <saurabh6790@gmail.com>
2020-03-05 13:04:53 +05:30
Chinmay D. Pai
12cdf0fb52 fix: use ERPNext in welcome email when default company is not set
Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2020-03-05 10:11:55 +05:30
Deepesh Garg
b6a3a06c4b Merge pull request #20821 from deepeshgarg007/gst_itemised_v12
fix: HSN code no visible in GST itemised sales register
2020-03-04 10:41:55 +05:30
Deepesh Garg
2728590471 fix: HSN code no visible in GST itemised sales register 2020-03-04 10:26:25 +05:30
Priyanka Gangar
7766530afc fix: fetch sales person name (#20801)
* fix: fetch sales person name

* Update sales_person.js

Co-authored-by: pinka0925 <44537026+pinka0925@users.noreply.github.com>
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-02 19:24:14 +05:30
Deepesh Garg
d7839eb8ac fix: Total amount not displayed in Journal Entry (#20795)
* fix: Total amount not displayed in Journal Entry

* fix: Update paid_to_received field

* fix: set total amount

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-03-02 18:09:24 +05:30
Prssanna Desai
6a734ecd34 fix: use get all instead of get list to fetch item attributes (#20793) 2020-03-02 18:06:21 +05:30
Mangesh-Khairnar
acd93b3bd1 fix: use system language to translate strings (#20792) 2020-03-02 18:05:59 +05:30
Marica
94200b1179 chore: Item Price and Product Bundle Form cleanup (#20773)
* chore: Item Price and Product Bundle Form cleanup

* fix: Trailing comma
2020-03-02 15:51:22 +05:30
Saqib
a6bf96322b chore: control reposting of future gl entries with flags (#20775) 2020-03-02 15:19:28 +05:30
Saqib
27163e60bb feat: link serial no to batch no (#20779)
* feat: link serial no to batch no

* fix: test cases
2020-03-02 15:03:18 +05:30
Saqib
1041516e8e fix: reconciled entries showing in bank reco (#20788) 2020-03-02 15:00:42 +05:30
Deepesh Garg
b7bbd827fd Merge pull request #20769 from marination/buying-dashboard-hotfix
chore: Rearranged Buying Module Dashboard
2020-02-29 17:34:35 +05:30
Sahil Khan
fda7cbeca4 Merge branch 'v12-pre-release' into version-12 2020-02-28 15:06:03 +05:30
Sahil Khan
2fc58b3327 bumped to version 12.5.2 2020-02-28 15:26:03 +05:50
marination
3fcd575f53 chore: Rearranged Buying Module Dashboard 2020-02-28 13:08:38 +05:30
Deepesh Garg
0cee807dfb Merge pull request #20766 from deepeshgarg007/bank_reco_release
fix: Journal Entry not being fetched in Bank Reconciliation
2020-02-28 12:35:06 +05:30
Deepesh Garg
a51c56c4b3 fix: Remove debug statement 2020-02-28 12:32:18 +05:30
Deepesh Garg
d2f26e57d2 fix: Journal Entry not being fetched in Bank Reconciliation 2020-02-28 12:32:05 +05:30
Deepesh Garg
b7790c0394 fix: Item Wise report query fix (#20765) 2020-02-28 12:30:29 +05:30
Deepesh Garg
d17e0b5aca fix: Item Wise report query fix (#20761) 2020-02-28 12:29:11 +05:30
Shivam Mishra
f08b5e4866 feat: ignore permission when deleting linked emails (#20753) 2020-02-27 19:07:39 +05:30
Deepesh Garg
78ae5e7721 Merge pull request #20749 from deepeshgarg007/bank_reco_jv_v12
fix: Journal Entry not being fetched in Bank Reconciliation
2020-02-27 16:19:01 +05:30
Deepesh Garg
5fb66a3953 fix: Remove debug statement 2020-02-27 16:15:43 +05:30
Deepesh Garg
d952e71d97 fix: Journal Entry not being fetched in Bank Reconciliation 2020-02-27 16:15:16 +05:30
rohitwaghchaure
fe337dfb66 fix: serial no material transfer performance issue (#20722) 2020-02-27 14:27:43 +05:30
Saqib
45329232b3 fix: only update items if rate or qty changed (#20743) 2020-02-27 12:51:23 +05:30
Rohan
30ad21b7d8 fix: sort Issues chronologically (#20740) 2020-02-26 18:53:48 +05:30
Marica
4e3ad9c3f2 fix: Lock stock ledger entries that are being reposted. (#20739)
- If stock ledger entries are being reposted, don't let any other transaction apply itself on the same.
2020-02-26 18:51:35 +05:30
Sahil Khan
2a1e9b542e Merge branch 'v12-pre-release' into version-12 2020-02-26 18:20:16 +05:30
Sahil Khan
8f458feafc bumped to version 12.5.1 2020-02-26 18:40:16 +05:50
Deepesh Garg
e116d8f819 Merge pull request #20738 from deepeshgarg007/bank_reco_fix_v12_pre
fix: Mandatory bank account error fix
2020-02-26 17:42:14 +05:30
Deepesh Garg
f3674ccc6c fix: SQL condition 2020-02-26 17:40:13 +05:30
Deepesh Garg
6f35a63f2d fix: Mandatory bank account error fix 2020-02-26 17:40:04 +05:30
Deepesh Garg
acbc4f648d fix: Mandatory bank account error fix (#20734)
* fix: Mandatory bank account error fix

* fix: SQL condition
2020-02-26 17:17:06 +05:30
Anurag Mishra
5475b5f562 fix: validated leave allocation (#20635)
* fix: validated leave allocation

* fix: changes requested

* Update erpnext/hr/doctype/leave_encashment/leave_encashment.py

Co-Authored-By: Nabin Hait <nabinhait@gmail.com>

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-02-26 14:50:52 +05:30
rohitwaghchaure
39861c270c fix: same free item not working for pricing rule (#20713) 2020-02-26 12:51:53 +05:30
RJPvT
6eaa542709 fix: smaller then instead of bigger then :-( dumb mistake v12 #20693 (#20701) 2020-02-26 11:59:06 +05:30
Saqib
2a8981929a perf: search for customer's return invoices then filter out gl_entries (#20710) 2020-02-26 11:36:38 +05:30
rohitwaghchaure
0aa7aa5996 fix: rate and amount in material request copying from sales order (#20718) 2020-02-26 11:27:49 +05:30
rohitwaghchaure
a20bd89c20 fix: reorder material request not created if doctype has custom mandatory field (#20720) 2020-02-26 11:25:30 +05:30
Deepesh Garg
aa7af30382 Merge pull request #20715 from rohitwaghchaure/account_dashboard_not_working_hotfix
fix: account dashboard not working
2020-02-26 10:18:27 +05:30
Rohit Waghchaure
9921d28ea7 fix: account dashboard not working 2020-02-25 12:17:25 +05:30
Sahil Khan
b26fd04843 Merge branch 'v12-pre-release' into version-12 2020-02-20 18:26:58 +05:30
Sahil Khan
1b78d20d3c bumped to version 12.5.0 2020-02-20 18:46:57 +05:50
sahil28297
b203406d4c fix: proper release note version 2020-02-20 18:20:33 +05:30
Mangesh-Khairnar
5a0017c61a Merge pull request #20686 from Anurag810/additional_salary_fixes
fix: Additional salary can be created only for active employee
2020-02-20 16:21:55 +05:30
Anurag Mishra
df15c758f6 fix: Additional salary can be created only for active employee 2020-02-20 15:29:09 +05:30
Mangesh-Khairnar
588a89f957 fix: return null for attribute (#20684) 2020-02-20 13:41:00 +05:30
Mangesh-Khairnar
c74343531f fix: skip earned leaves check for max leaves set to zero or less (#20536)
* fix: skip earned leaves check for max leaves set to zero or less

* test: earned leaves creation
2020-02-20 13:25:45 +05:30
Deepesh Garg
a257189c77 Merge pull request #20451 from Anurag810/fleet-management_v12
fix: odometer value was not syncing properly
2020-02-20 13:20:21 +05:30
Rohan
355051bf75 fix: apply url encoding to project names (#20641) 2020-02-20 12:59:21 +05:30
Anurag Mishra
ab8aa43ffb fix: changed field type which was affecting filters (#20670) 2020-02-20 12:52:37 +05:30
Mathieu Brunot
a6f56bbc3e chore(ci-coverage): Pin coverage 4.5.4 #20646 (#20648)
* chore(ci-coverage): Pin coveralls 4.5.4 #20646

Signed-off-by: mathieu.brunot <mathieu.brunot@monogramm.io>

* chore: Pin coverage

Signed-off-by: mathieu.brunot <mathieu.brunot@monogramm.io>
2020-02-20 12:50:09 +05:30
gavin
4e2b9395b9 chore: drop cypress requirement (#20675) 2020-02-20 12:48:32 +05:30
Saqib
ae9159fbd8 fix: mandatory on hold comment for purchase invoice (#20667) 2020-02-20 12:33:07 +05:30
Saqib
8e80c17602 chore: SINV set_status remove redundant function calls (#20661) 2020-02-20 12:32:09 +05:30
Saqib
8903258362 fix: mandatory on hold comment for purchase invoice (#20668)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-02-20 12:30:35 +05:30
Saqib
1beeb28908 fix: check for available stock in product bundle's website warehouse (#20680) 2020-02-20 12:22:33 +05:30
Saqib
2d2aa7d664 fix: check for available stock in product bundle's website warehouse (#20679)
* fix: check for available stock in product bundle's website warehouse

* test: earned leaves creation

* fix: minor change

Co-authored-by: Mangesh-Khairnar <mkhairnar10@gmail.com>
2020-02-20 12:22:01 +05:30
Nabin Hait
cd6b60df70 core: Added change log 2020-02-20 12:18:21 +05:30
Nabin Hait
b18790f5c2 Merge branch 'version-12-hotfix' into v12-pre-release 2020-02-19 19:19:36 +05:30
Mangesh-Khairnar
f6d7090f07 fix: earned leaves creation for zero maximum leaves (#20677) 2020-02-19 19:16:40 +05:30
Deepesh Garg
017d280877 Merge pull request #20664 from marination/stock-settings-query-v12-hotfix
fix: Set Query on warehouse fields in Stock Settings
2020-02-19 18:58:46 +05:30
Anurag Mishra
031d4092d0 test: syncing of odometer value 2020-02-19 16:49:13 +05:30
marination
0119d15adb fix: Server side validation for Warehouses 2020-02-19 11:21:55 +05:30
Deepesh Garg
df6cb3c43b Merge pull request #20633 from scmmishra/tree-fix-qms
fix: filters for quality_procedure tree
2020-02-19 09:40:52 +05:30
marination
1ed737cf64 fix: Set Query on warehouse fields in Stock Settings 2020-02-18 21:45:52 +05:30
Deepesh Garg
c64e46fe67 Merge pull request #20483 from racitup/plaid-20343-fix
fix: Plaid fixes and enhancements
2020-02-18 18:03:16 +05:30
Nabin Hait
f579b0e3de fix: merge conflict 2020-02-18 17:49:20 +05:30
Deepesh Garg
b63c041aa4 feat: Group by AR/AP report (#20574)
* feat: Group by AR/AP report

* fix: Do not consider total row in charts

* fix: Subtotal row for last party
2020-02-18 16:09:37 +05:30
rohitwaghchaure
22f9a5f09f Merge pull request #20639 from nextchamp-saqib/pos-mode-of-pay-fix-v12
fix: disabled mode of payments fetches in sales invoices
2020-02-18 12:38:14 +05:30
rohitwaghchaure
e47875340e Merge pull request #20655 from marination/precision-mr-item-hotfix
fix: Stock Quantity not calculated on client side in Material Request…
2020-02-18 12:34:27 +05:30
marination
6f28383531 fix: Stock Quantity not calculated on client side in Material Request Items. 2020-02-18 11:08:16 +05:30
Deepesh Garg
95050702f1 Merge branch veersion-12-hotfix into plaid-20343-fix 2020-02-17 22:11:14 +05:30
Deepesh Garg
ae8f717fe5 Merge pull request #20640 from gavindsouza/updated-requirements
chore(requirements): Pin requirements
2020-02-17 22:05:26 +05:30
Gavin D'souza
f95ac99baa fix(travis): add lib cups for updated frappe requirements 2020-02-17 16:52:27 +05:30
Shivam Mishra
660b4d1e2f feat: show numeric values in item configurator (#20430) 2020-02-17 15:58:31 +05:30
thefalconx33
5bfebaf1c0 fix: disabled mode of payments fetches in sales invoices 2020-02-17 14:16:49 +05:30
Deepesh Garg
980e54c5f4 Merge pull request #20570 from Er-Naren719/hotfix-user-table-columns-updated
feat: columns under user table updated
2020-02-17 11:19:23 +05:30
Shivam Mishra
efbfeb2d89 fix: filters for quality_procedure tree 2020-02-17 10:50:05 +05:30
rohitwaghchaure
0676ed08b1 Merge pull request #20540 from rohitwaghchaure/fixed_purchase_receipt_time_out_error
fix: time out error while submitting the purchase receipt
2020-02-11 19:55:04 +05:30
rohitwaghchaure
e9946672e0 Merge branch 'version-12-hotfix' into fixed_purchase_receipt_time_out_error 2020-02-11 19:54:54 +05:30
rohitwaghchaure
6124f83e6e Merge pull request #20556 from ashish-greycube/patch-3
fix: backflush raw material based on - Material Transferred for Manufacture
2020-02-11 19:50:09 +05:30
Deepesh Garg
2b83debc72 Merge pull request #20564 from govindsmenokee/patch-4
fix: get_students not respecting the program
2020-02-11 17:03:24 +05:30
Er-Naren719
fc4cc9ab42 feat: column width increased for view attachments field (#314) 2020-02-11 10:17:34 +00:00
Deepesh Garg
cd19974d7a Merge pull request #20566 from vishdha/filter_serial_based_on_batch_v12
fix: filter serial no based on batch no
2020-02-11 13:44:54 +05:30
vishal
cde48a44cf fix: filter serial no based on batch no 2020-02-11 12:39:49 +05:30
Govind S Menokee
57d33f9ce6 fix: get_students not respecting the program
The get_students function is not taking into account the program for which the fee needs to be created. If a student is enrolled for multiple programs then the fee schedule pull up the wrong count of students.
2020-02-11 11:23:16 +05:30
Deepesh Garg
90a46acc0d Merge pull request #20557 from rohitwaghchaure/added_indexing_on_columns_to_fix_performance_issue
fix: added indexing on columns to fix performace issue
2020-02-11 10:13:24 +05:30
Deepesh Garg
60634cc829 Merge pull request #20252 from deepeshgarg007/group_by_sales_v12
feat: Group by item wise sales register
2020-02-10 22:20:21 +05:30
Rohit Waghchaure
a7c27596bb fix: added indexing on columns to fix performace issue 2020-02-10 15:30:22 +05:30
Deepesh Garg
b4e3146665 Merge pull request #20550 from nextchamp-saqib/so-update-items-warehouse-fix-v12
fix: mandatory warehouse wrror while updating items after submission
2020-02-10 12:09:38 +05:30
Ashish Shah
495ab6c7f2 fix: backflush raw material based on - Material Transferred for Manufacture
Hi @nabinhait ,
 
Issue : Manufacturing setting > Backflush Raw Material Based on “Material Transferred for Manufacture” doesn't fetch the actual raw material transferred qty. It fetches qty based on "BOM"

The issue is because @creamdory in PR #https://github.com/frappe/erpnext/pull/13384
commit : https://github.com/frappe/erpnext/pull/13384/files#diff-91f0ed661ef4b6e1f167fc7961b1a79b

```
changed from: if trans_qty and manufacturing_qty >= (produced_qty + flt(self.fg_completed_qty)):
to : if trans_qty and manufacturing_qty > (produced_qty + flt(self.fg_completed_qty)):
```
**'='** was added by her in the condition, which was not there before her commit.
Kindly except the fix for the issue.


https://github.com/frappe/erpnext/blob/develop/erpnext/stock/doctype/stock_entry/stock_entry.py#L1057

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

https://github.com/frappe/erpnext/pull/13384/files#diff-91f0ed661ef4b6e1f167fc7961b1a79b

**before fix gif** :  Stock Entry = Manufacture shows raw material quantity as per BOM.

![FetchTransQtyError](https://user-images.githubusercontent.com/29812965/74123824-ffdd8600-4bf5-11ea-8873-95de24a7ef09.gif)

**after fix gi**f :  Stock Entry = "Manufacture" shows raw material quantity as per "Material Transfer for Manufacture".

![FetchTransQtyFix](https://user-images.githubusercontent.com/29812965/74123836-0c61de80-4bf6-11ea-86fb-d9619fd9b02b.gif)
2020-02-10 11:13:27 +05:30
Deepesh Garg
0e396a62b1 Merge pull request #20554 from ruchamahabal/fix_regional_data_v12
fix: patch for creating irs_1099 custom field (United States)
2020-02-10 09:08:55 +05:30
Rucha Mahabal
1343a4b755 fix: patch for creating irs_1099 custom field (United States) 2020-02-10 00:31:44 +05:30
rohitwaghchaure
ec45c096a0 fix: pricing rule not working on item groups (#20546) 2020-02-09 19:45:42 +05:30
thefalconx33
c7e523cee4 fix: mandatory warehouse wrror while updating items after submission 2020-02-09 12:21:01 +05:30
rohitwaghchaure
9e436336e2 Merge pull request #20542 from rohitwaghchaure/fixed_incorrect_material_request_warehouse_in_production_plan
fix: incorrect warehouse for material request in production plan
2020-02-07 17:43:32 +05:30
Rohit Waghchaure
a9205adfbd fix: test cases 2020-02-07 15:38:56 +05:30
Deepesh Garg
f5bff5f15d fix: Styling and minor fixes 2020-02-07 15:25:43 +05:30
Rohit Waghchaure
bbeacb9acf fix: incorrect warehouse for material request in production plan 2020-02-07 15:04:37 +05:30
Rohit Waghchaure
7027584391 fix: time out error while submitting the purchase receipt which has more than 100 serial nos 2020-02-07 14:41:00 +05:30
Deepesh Garg
372d4e2e05 Merge branch 'group_by_sales_v12' of github.com:deepeshgarg007/erpnext into group_by_sales_v12 2020-02-07 11:10:10 +05:30
Deepesh Garg
bdfa2ff33a fix: Do not calculate total for rate 2020-02-07 11:09:43 +05:30
Deepesh Garg
787b31674a Merge pull request #20534 from rohitwaghchaure/procurement_tracker_not_working_for_special_char_company_name_v12_hotfix
fix: Procurement Tracker report not working
2020-02-07 10:44:13 +05:30
Rohit Waghchaure
0eb9f7408e fix: Procurement Tracker report not working 2020-02-06 14:38:51 +05:30
Deepesh Garg
5c96415eb5 Merge pull request #20530 from nextchamp-saqib/mv-fix-v12
fix: typo; serial no doesn't have amc start date
2020-02-06 13:58:29 +05:30
thefalconx33
d9f8347fc8 fix: typo; serial no doesn't have amc start date 2020-02-06 12:58:48 +05:30
Deepesh Garg
2a48fe6ce6 Merge pull request #20524 from deepeshgarg007/bank_account_label__v12
Bank account label  v12
2020-02-05 18:04:12 +05:30
deepeshgarg007
3ed574532d fix: filter 2020-02-05 18:02:31 +05:30
deepeshgarg007
9f58e59a2c fix: Label and UX fixes while creating payment entry against customer 2020-02-05 18:02:19 +05:30
Deepesh Garg
23c6d6cf16 Merge pull request #20522 from rohitwaghchaure/picklist_nonetype_error
fix: unsupported operand type(s) for += 'int' and 'NoneType'
2020-02-05 17:44:46 +05:30
Rohit Waghchaure
8e0a9e8748 fix: unsupported operand type(s) for += 'int' and 'NoneType' 2020-02-05 16:17:16 +05:30
Deepesh Garg
67dbeee7b2 fix: Add total row 2020-02-05 15:34:08 +05:30
Parth J. Kharwar
b4a0c773ae fix: half day leave date value reset (#20488)
* fix: full day leaves not tagged as half day in attendance

* chore: code cleanup for half day date value set
2020-02-05 15:00:58 +05:30
Anurag Mishra
ce598530db fix: requested changes 2020-02-05 12:49:11 +05:30
Deepesh Garg
694f57fbb4 Merge pull request #20521 from deepeshgarg007/fixnancial_query_fix_v12
fix: SQL query in financial statements
2020-02-05 12:33:06 +05:30
Deepesh Garg
0f90b870fb fix: SQL query in financial statements 2020-02-05 12:30:15 +05:30
Nabin Hait
bd5b37dbb7 Merge branch 'v12-pre-release' into version-12 2020-02-03 19:00:36 +05:30
Nabin Hait
7e93e87244 bumped to version 12.4.3 2020-02-03 19:20:36 +05:50
Deepesh Garg
02f4aa6db6 fix: Unable to submit landed cost voucher (#20494)
* fix: Unable to submit landed cost voucher

* fix: Test case for multiple landed cost voucher against a Purchase receipt

* fix: Test Case
2020-02-03 18:56:43 +05:30
Deepesh Garg
ade2c36123 fix: Unable to submit landed cost voucher (#20494)
* fix: Unable to submit landed cost voucher

* fix: Test case for multiple landed cost voucher against a Purchase receipt

* fix: Test Case
2020-02-03 18:54:35 +05:30
Pranav Nachnekar
3ef80f2d2e fix: disallow quick entry for doctypes with tree view (#20453)
* fix: imporer escaping

* fix: disallow quick entry for doctypes with tree view
2020-02-03 17:05:30 +05:30
Himanshu
85c6480b41 fix(Report): Quality Review report sql fix (#20425)
* fix: report fix

* fix: add QM permission

* fix: add QM permission
2020-02-03 16:16:42 +05:30
Saqib
f3c94315c3 feat: add tax category in pos profile (#20414)
* feat: add tax category in pos profile

* fix: review fixes
2020-02-03 15:53:22 +05:30
Saqib
a4219f1cfe fix: gst permission for gst settings & hsn code (#20501)
* fix: gst permission for gst settings & hsn code

* Fix: Typo

Co-authored-by: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com>
2020-02-03 15:40:53 +05:30
Deepesh Garg
831a7ddd6f fix: Minor fixes 2020-02-01 23:15:21 +05:30
Parth J. Kharwar
43886ca016 fix: employee checkin doctype time permissions (#20473) 2020-01-31 14:37:56 +05:30
rohitwaghchaure
61b4244837 Merge pull request #20479 from deepeshgarg007/finance-book-filter-new-v12
fix: Do not show any finance book record if no finance book filter is applied
2020-01-31 13:19:49 +05:30
Deepesh Garg
6871979acc Merge pull request #20470 from alyf-de/version-12-hotfix
fix(regional): byte strings in DATEV Report
2020-01-31 11:20:51 +05:30
Deepesh Garg
bb7cf81d52 fix: Cash flow filter fix 2020-01-31 11:18:26 +05:30
Deepesh Garg
9826291c52 fix: Filtering fixes in financial statement 2020-01-31 11:18:13 +05:30
racitup
08661250d2 Ignore codacy SQL injection warning (internal code only) and add copyright notice 2020-01-30 15:22:34 +00:00
racitup
814001a90f fix: attempt at pymysql InternalError 1054 about clearance_date in field list when removing payments from bank transactions 2020-01-30 15:22:34 +00:00
racitup
eef73a0d92 manually added patch for bank reconciliation fields since develop branch was in a different place #20380 2020-01-30 15:22:34 +00:00
racitup
a1e3202054 fix: Bank Reconciliation Bank Account and Bank Account No field names 2020-01-30 15:22:34 +00:00
racitup
bee017e17c fix: Plaid transaction import order, transaction_id duplicate check, added transaction category tags 2020-01-30 15:22:34 +00:00
racitup
a054508211 fix: Plaid automatic_synchronization TypeError on filter & add info log message #20343 2020-01-30 15:22:34 +00:00
racitup
feaa82a8ea fix: KeyError about bank_account_no due to non-existent field: #20343 2020-01-30 15:22:34 +00:00
racitup
a175e06149 fix: pymysql.err.InternalError about t2.bank_account_no due to removal of field from Journal Entry Account table: #20343 2020-01-30 15:22:34 +00:00
Deepesh Garg
ba4d9469ff fix: Do not show any finance book record if no finance book filter is applied 2020-01-30 15:41:44 +05:30
Deepesh Garg
54c6f91dde Merge pull request #20474 from ParthKharwar/hotfix-brand-breadcrumb
fix: rename breadcrumb for Brand DocType from Selling to Stock
2020-01-30 13:14:21 +05:30
Parth Kharwar
e552e958de fix: rename breadcrumb for Brand DocType from Selling to Stock 2020-01-30 12:35:02 +05:30
Raffael Meyer
7524ecbc59 fix #20469 2020-01-30 00:08:25 +01:00
Deepesh Garg
be2ca5f8cc Merge pull request #20460 from 0Pranav/fix-supplier-quotation-button-v12
fix: missing plus button in request for quotaion for supplier quotation
2020-01-29 10:45:32 +05:30
0Pranav
d4d641a07e fix: missing plus button in request for quotaion for supplier quotation 2020-01-29 09:36:48 +05:30
rohitwaghchaure
8e5b812a97 fix: incorrect work order qty for sub assembly items (#20448) 2020-01-28 14:34:54 +05:30
Nabin Hait
df94f0565e fix: cannot complete task if dependent task are not completed / cancelled (#20434) 2020-01-28 14:08:48 +05:30
Anurag Mishra
637915f295 fix: odometer value was not syncing properly 2020-01-28 13:15:26 +05:30
Pranav Nachnekar
f2838c4a13 fix: discounting not applied on sales invoice created by subscriptions (#20432)
* fix: imporer escaping

* fix: discounting not applied on sales invoice created by subscriptions
2020-01-28 12:52:42 +05:30
Marica
fe56c7ce39 fix: Column 'project' in where clause is ambiguous (#20439)
* fix: Column 'project' in where clause is ambiguous

* fix: Fixed alias in query
2020-01-28 12:44:03 +05:30
Deepesh Garg
29ecbde445 Merge pull request #20446 from Alchez/v12-driver-address-fetch
fix: only fetch driver address if not set (v12)
2020-01-28 09:20:53 +05:30
Deepesh Garg
611f212aa4 Merge pull request #20443 from fproldan/fix_sqlinjection_hotfix_v12
fix: SQL Injection in get_product_list_for_group method
2020-01-28 09:18:11 +05:30
Rohan Bansal
6fbafa1924 fix: only fetch driver address if not set 2020-01-27 18:04:33 +05:30
NahuelOperto
875bac8bb9 Fix sql injection 2020-01-27 08:58:01 -03:00
Saqib
b4b410f1d2 refac: filters and columns of fixed asset register report (#20420) 2020-01-27 16:06:15 +05:30
deepeshgarg007
eec0ee83e2 fix: Changes in total row display 2020-01-27 15:51:20 +05:30
Deepesh Garg
148951e6f3 fix: Finance book filtering in financial statements (#20411)
* fix: Finance book filtering in financial statements

* fix: Use IS NULL instead of ifnull
2020-01-27 15:18:45 +05:30
Saqib
612e3b77fd fix: incorrect status for fraction of outstanding amount (#20370) 2020-01-27 14:23:05 +05:30
Deepesh Garg
a60849f6ab Merge pull request #20415 from hrwX/customer_primary_addr_v12
fix(Customer): Change `primary_address` fieldtype to Text
2020-01-27 12:33:38 +05:30
deepeshgarg007
6f27e97980 fix: Add group by functionality to purchase register 2020-01-27 08:49:52 +05:30
deepeshgarg007
8d9145aaac fix: Code cleanup and commonification 2020-01-27 08:49:42 +05:30
Himanshu Warekar
25a7330db0 fix: change primary addr fieldtype to Text 2020-01-24 17:36:59 +05:30
Saqib
92c999afcb fix: wrong outstanding invoices fetched against employee (#20374) 2020-01-24 16:23:05 +05:30
Anurag Mishra
9e3dc25b1c fix: Duplicate Attendance Due Wrong Date format (#20389) 2020-01-24 16:14:38 +05:30
Rucha Mahabal
2a3cd7d601 fix(Healthcare): disabled Lab Test Template shown as Enabled in List View (#20379)
* fix (Healthcare): disabled Lab Test Template shown as enabled in List View

* fix: remove custom disabled button and unhide disabled field
2020-01-24 16:11:16 +05:30
Marica
3ca67ceebb fix: Product Page non-stock item status (#20384) 2020-01-24 15:52:12 +05:30
Rucha Mahabal
245fc49089 fix: healthcare settings registration fee NoneType error (#20396) 2020-01-24 15:50:40 +05:30
rohitwaghchaure
78199dbf0a Merge pull request #20399 from rohitwaghchaure/fixed_serial_no_button_not_working_v12_hotfix
fix: add serial no button not working
2020-01-24 13:49:25 +05:30
Deepesh Garg
2ac33c9ce9 Merge pull request #20402 from deepeshgarg007/general_ledger_sort_v12
fix: Order GL entries by creation time in General ledger
2020-01-24 13:19:56 +05:30
Deepesh Garg
34cd035d8c Merge pull request #20392 from rohitwaghchaure/unlink_reference_name_from_batch_on_cancel_of_stock_transactions
fix: unlink references from batch on cancellation of stock transactions
2020-01-23 22:41:21 +05:30
deepeshgarg007
ba4f565ca3 fix: Order GL entries by creation time in General ledger 2020-01-23 17:48:41 +05:30
Rohit Waghchaure
5860427bc5 delete the auto created batch 2020-01-23 17:43:30 +05:30
Rohit Waghchaure
89f42eef49 fix: add serial no button not working 2020-01-23 15:53:45 +05:30
Deepesh Garg
eacbfa15c0 Merge pull request #20385 from rohitwaghchaure/fixed_lead_date_comparision_issue
fix: lead date comparison issue
2020-01-23 15:23:28 +05:30
Deepesh Garg
5d45c2c184 Merge pull request #20387 from rohitwaghchaure/lead_showing_two_times_in_the_report
fix: lead details duplicate entries
2020-01-23 15:21:11 +05:30
Deepesh Garg
b24b0378ea Merge pull request #20382 from nextchamp-saqib/small-fix-asset-v12
fix: tuple index out of range error
2020-01-23 15:02:29 +05:30
Rohit Waghchaure
144012a5de fix: unlink references from batch on cacnellation of stock transactions 2020-01-23 12:42:42 +05:30
rohitwaghchaure
5fb4027375 Merge pull request #20376 from rohitwaghchaure/zero_division_qty_error_while_completing_fg_entry_v12_pre_release
fix: Zero division error while making finished good entry against the…
2020-01-22 17:01:21 +05:30
rohitwaghchaure
3fa65f1363 Merge pull request #20375 from rohitwaghchaure/zero_division_qty_error_while_completing_fg_entry
fix: Zero division error while making finished good entry against the…
2020-01-22 17:00:44 +05:30
Rohit Waghchaure
79f630661a fix: lead details duplicate entries 2020-01-22 16:53:30 +05:30
Rohit Waghchaure
61b9fe6a81 fix: lead date comparison issue 2020-01-22 14:43:37 +05:30
thefalconx33
f38d9d8f0d fix: tuple index out of range error 2020-01-22 12:24:03 +05:30
Rohit Waghchaure
3a67daa1fd fix: Zero division error while making finished good entry against the work order 2020-01-21 19:25:27 +05:30
Rohit Waghchaure
813726b415 fix: Zero division error while making finished good entry against the work order 2020-01-21 19:22:27 +05:30
rohitwaghchaure
87fe2143be fix: not able to import chart of account if parent account is missing (#20367) 2020-01-21 15:32:12 +05:30
Saqib
c759b06f16 fix: account not added to child company (#20364)
* fix: account not added to child company

* fix: removed print

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2020-01-21 15:26:46 +05:30
Chinmay Pai
c32249a72f fix: Set Quotation expired if not Ordered or Lost (#20365)
Co-authored-by: Chinmay Pai <chinmaydpai@gmail.com>

Co-authored-by: KanchanChauhan <angel143.dr@gmail.com>
2020-01-21 14:12:49 +05:30
Nabin Hait
05f4be69f4 fix: Don't fetch price list rate on change of qty (#20362) 2020-01-21 13:04:26 +05:30
Mangesh-Khairnar
541881162a fix: calculate remaining leave balance (#20342)
* fix: calculate remaining leave balance

* fix: nonetype issue in the total leaves calculation
2020-01-20 19:42:49 +05:30
rohitwaghchaure
19c5e031a9 fix: incorrect number of gl entries issue (#20350) 2020-01-20 17:52:53 +05:30
Nabin Hait
45be9fe416 fix: deprecated fetching item price based on min_qty (#20346) 2020-01-20 15:44:48 +05:30
Nabin Hait
1596352585 fix: close_opportunity_after_days field is in selling settings (#20334) 2020-01-17 15:59:02 +05:30
Nabin Hait
4b893b1d51 fix: Plaid TypeError in add_bank_accounts (#20336) 2020-01-17 15:57:43 +05:30
Parth J. Kharwar
d85e144944 chore: changed employee contact field name (#20227) 2020-01-17 11:47:49 +05:30
Rohan
4dfff5a271 fix: handle default value for batch size in BOM operation (#20327) 2020-01-17 11:46:00 +05:30
Pranav Nachnekar
c2b9598966 fix: imporer escaping (#20329) 2020-01-17 11:45:03 +05:30
Vishal Dhayagude
d16e7c096b fix: salary structure assignment filter employee based on company (#20319)
* fix: pick company from employee salary structure

* fix: Salary structure assignment fetch company from enmployee

* Revert "fix: Salary structure assignment fetch company from enmployee"

This reverts commit ab2da691c79646d6d095f347ea3e273f466ee34f.

* fix: Salary structure assignment fetch company from enmployee

* fix: filter on company for salary structure assignment

* fix: minor changes

* fix: minor changes

* fix: added company to salary strucutre assignment
2020-01-17 11:44:20 +05:30
Himanshu
5511912251 fix: don't hide primary_address_and_contact_detail (#20321) 2020-01-16 13:39:03 +05:30
Saqib
514d3c37b9 fix: hide total amount field from journal entry PF (#20325) 2020-01-16 13:38:21 +05:30
Nabin Hait
7721954bbb fix: Multiple fixes based on testing on pre-release branch (#20303)
* fix: Multiple fixes based on testing on pre-release branch

* fix: reload hr settings
2020-01-16 13:37:20 +05:30
Marica
0a50088a0e fix: Applied query on PO Supplier popup field in Material Request. (#20232) 2020-01-15 19:24:10 +05:30
Marica
6ba6ba27bd fix: Missing argument in status updater (#20284) 2020-01-15 19:22:21 +05:30
Saqib
611e23c149 fix: make jv depreciations only if calculate depr is checked (#20283) 2020-01-15 19:05:42 +05:30
sahil28297
89affd8d09 fix(patch): reload tax category (#20307) 2020-01-15 18:58:09 +05:30
sahil28297
8dfd5535f1 fix(patch): do not append taxes to template if account name is not set (#20311) 2020-01-15 18:57:20 +05:30
Saqib
8c45ae73b3 fix: get existing payment req amount only from unpaid req (#20290) 2020-01-15 16:36:19 +05:30
rohitwaghchaure
fed9e2861c fix: incorrect number of GL Entries error in stock entry (#20297) 2020-01-15 16:35:02 +05:30
Pranav Nachnekar
6e115638a1 fix: remove debugger statement (#20295)
backport of https://github.com/frappe/erpnext/pull/20294
2020-01-15 14:49:28 +05:30
rohitwaghchaure
437be1162e Merge pull request #20277 from rohitwaghchaure/fixed_report_stock_and_account_value_comparison_v12_hotfix
fix: filter issue for the stock and account value comparision report
2020-01-14 12:18:50 +05:30
Rohit Waghchaure
e3b6a14ab1 fix: filter issue for the stock and account value comparision report 2020-01-14 12:15:06 +05:30
Saqib
eb7893768b fix: payment entry can be created against on hold PI (#20271) 2020-01-14 12:07:30 +05:30
Saqib
6e1ef4f5c2 fix: gl not generated on manual asset creation (#20266) 2020-01-14 11:38:00 +05:30
Deepesh Garg
7d7027f47c fix: Remove patch to set automatic tax fetching from item tax template (#20235)
* fix: Remove patch to set automatic tax fetching from item tax template

* fix: Remove duplicate patch
2020-01-13 15:09:21 +05:30
Deepesh Garg
7086ecb3b0 Merge pull request #20246 from nextchamp-saqib/asset-cancel-fix-v12
fix: auto cancel if movement exists
2020-01-13 15:07:57 +05:30
Deepesh Garg
8508ace50e Merge pull request #20258 from nextchamp-saqib/revery-hv-v12
fix: remove default customer as party type
2020-01-13 13:49:20 +05:30
thefalconx33
c52ef56875 fix: remove default customer as party type 2020-01-13 12:45:08 +05:30
deepeshgarg007
4dfe8ab483 fix: Remove debug param 2020-01-12 22:15:25 +05:30
deepeshgarg007
ea5e0a9d5b fix: Grand total query fix 2020-01-12 21:56:31 +05:30
deepeshgarg007
30111e6403 fix: Remove group-by item 2020-01-12 21:56:22 +05:30
deepeshgarg007
e5a572a4a8 fix: Group by sales register report 2020-01-12 21:56:12 +05:30
thefalconx33
83ed7df8cd fix: auto cancel if movement exists 2020-01-11 14:20:18 +05:30
Deepesh Garg
97e93c6257 Merge pull request #20238 from deepeshgarg007/hsn_template_v12
fix: Item tax template fetching from HSN Code
2020-01-10 21:45:22 +05:30
Gavin D'souza
73089470b1 chore: pinned backwards compatible dependencies 2019-11-15 17:38:32 +05:30
Gavin D'souza
3798f8bd25 style(requirements): alphabetically sorted requirements 2019-11-15 13:59:15 +05:30
Gavin D'souza
f805a76e79 chore: pinned requirements 2019-11-13 17:27:16 +05:30
339 changed files with 9720 additions and 21819 deletions

View File

@@ -63,6 +63,7 @@ install:
- tar -xf /tmp/wkhtmltox.tar.xz -C /tmp
- sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf
- sudo chmod o+x /usr/local/bin/wkhtmltopdf
- sudo apt-get install libcups2-dev
- cd ~/frappe-bench
@@ -76,5 +77,6 @@ install:
- bench --site test_site reinstall --yes
after_script:
- pip install coverage==4.5.4
- pip install python-coveralls
- coveralls -b apps/erpnext -d ../../sites/.coverage

View File

@@ -1,3 +0,0 @@
{
"baseUrl": "http://test_site_ui:8000"
}

View File

@@ -1,5 +0,0 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@@ -1,31 +0,0 @@
context('Form', () => {
before(() => {
cy.login('Administrator', 'qwe');
cy.visit('/desk');
});
it('create a new opportunity', () => {
cy.visit('/desk#Form/Opportunity/New Opportunity 1');
cy.get('.page-title').should('contain', 'Not Saved');
cy.fill_field('opportunity_from', 'Customer', 'Select');
cy.fill_field('party_name', 'Test Customer', 'Link').blur();
cy.get('.primary-action').click();
cy.get('.page-title').should('contain', 'Open');
cy.get('.form-inner-toolbar button:contains("Lost")').click({ force: true });
cy.get('.modal input[data-fieldname="lost_reason"]').as('input');
cy.get('@input').focus().type('Higher', { delay: 200 });
cy.get('.modal .awesomplete ul')
.should('be.visible')
.get('li:contains("Higher Price")')
.click({ force: true });
cy.get('@input').focus().type('No Followup', { delay: 200 });
cy.get('.modal .awesomplete ul')
.should('be.visible')
.get('li:contains("No Followup")')
.click();
cy.fill_field('detailed_reason', 'Test Detailed Reason', 'Text');
cy.get('.modal button:contains("Declare Lost")').click({ force: true });
cy.get('.page-title').should('contain', 'Lost');
});
});

View File

@@ -1,17 +0,0 @@
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
// module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
// }

View File

@@ -1,25 +0,0 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })

View File

@@ -1,22 +0,0 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// import frappe commands
import '../../../frappe/cypress/support/index';
// Import commands.js using ES2015 syntax:
import './commands';
// Alternatively you can use CommonJS syntax:
// require('./commands')

View File

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

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe, json
from frappe import _
from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day, formatdate
from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day, formatdate, get_link_to_form
from erpnext.accounts.report.general_ledger.general_ledger import execute
from frappe.core.page.dashboard.dashboard import cache_source, get_from_date_from_timespan
from frappe.desk.doctype.dashboard_chart.dashboard_chart import get_period_ending
@@ -30,8 +30,13 @@ def get(chart_name = None, chart = None, no_cache = None, from_date = None, to_d
account = filters.get("account")
company = filters.get("company")
if not account and chart:
frappe.throw(_("Account is not set for the dashboard chart {0}").format(chart))
if not account and chart_name:
frappe.throw(_("Account is not set for the dashboard chart {0}")
.format(get_link_to_form("Dashboard Chart", chart_name)))
if not frappe.db.exists("Account", account) and chart_name:
frappe.throw(_("Account {0} does not exists in the dashboard chart {1}")
.format(account, get_link_to_form("Dashboard Chart", chart_name)))
if not to_date:
to_date = nowdate()

View File

@@ -1,4 +1,5 @@
{
"actions": [],
"allow_copy": 1,
"allow_import": 1,
"creation": "2013-01-30 12:49:46",
@@ -196,10 +197,13 @@
],
"icon": "fa fa-money",
"idx": 1,
"modified": "2019-10-10 19:10:02.967554",
"is_tree": 1,
"links": [],
"modified": "2020-03-18 18:26:03.992861",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Account",
"nsm_parent_field": "parent_account",
"owner": "Administrator",
"permissions": [
{

View File

@@ -95,29 +95,29 @@ class Account(NestedSet):
# ignore validation while creating new compnay or while syncing to child companies
if frappe.local.flags.ignore_root_company_validation or self.flags.ignore_root_company_validation:
return
ancestors = get_root_company(self.company)
if ancestors:
if frappe.get_value("Company", self.company, "allow_account_creation_against_child_company"):
return
if not frappe.db.get_value("Account",
{'account_name': self.account_name, 'company': ancestors[0]}, 'name'):
frappe.throw(_("Please add the account to root level Company - %s" % ancestors[0]))
else:
elif self.parent_account:
descendants = get_descendants_of('Company', self.company)
if not descendants: return
parent_acc_name_map = {}
parent_acc_name, parent_acc_number = frappe.db.get_value('Account', self.parent_account, \
["account_name", "account_number"])
for d in frappe.db.get_values('Account',
{ "company": ["in", descendants], "account_name": parent_acc_name,
"account_number": parent_acc_number },
["company", "name"], as_dict=True):
filters = {
"company": ["in", descendants],
"account_name": parent_acc_name,
}
if parent_acc_number:
filters["account_number"] = parent_acc_number
for d in frappe.db.get_values('Account', filters=filters, fieldname=["company", "name"], as_dict=True):
parent_acc_name_map[d["company"]] = d["name"]
if not parent_acc_name_map: return
self.create_account_for_child_company(parent_acc_name_map, descendants, parent_acc_name)
def validate_group_or_ledger(self):
@@ -175,7 +175,6 @@ class Account(NestedSet):
filters["account_number"] = self.account_number
child_account = frappe.db.get_value("Account", filters, 'name')
if not child_account:
doc = frappe.copy_doc(self)
doc.flags.ignore_root_company_validation = True

View File

@@ -1,7 +1,7 @@
frappe.provide("frappe.treeview_settings")
frappe.treeview_settings["Account"] = {
breadcrumbs: "Accounts",
breadcrumb: "Accounts",
title: __("Chart Of Accounts"),
get_tree_root: false,
filters: [

View File

@@ -406,11 +406,11 @@
"is_group": 1,
"Bewertungskorrektur zu Forderungen aus Lieferungen und Leistungen": {
"account_number": "9960"
},
"Debitoren": {
"is_group": 1,
"account_number": "10000"
},
},
"Debitoren": {
"is_group": 1,
"account_number": "10000"
},
"Forderungen aus Lieferungen und Leistungen": {
"account_number": "1200",
"account_type": "Receivable"
@@ -663,16 +663,22 @@
"account_number": "1400"
},
"Abziehbare Vorsteuer 7 %": {
"account_number": "1401"
"account_number": "1401",
"account_type": "Tax",
"tax_rate": 7.0
},
"Abziehbare Vorsteuer aus innergem. Erwerb": {
"account_number": "1402"
},
"Abziehbare Vorsteuer aus innergem. Erwerb 19%": {
"account_number": "1404"
"account_number": "1404",
"account_type": "Tax",
"tax_rate": 19.0
},
"Abziehbare Vorsteuer 19 %": {
"account_number": "1406"
"account_number": "1406",
"account_type": "Tax",
"tax_rate": 19.0
},
"Abziehbare Vorsteuer nach \u00a7 13b UStG 19 %": {
"account_number": "1407"
@@ -1197,15 +1203,15 @@
"is_group": 1,
"Bewertungskorrektur zu Verb. aus Lieferungen und Leistungen": {
"account_number": "9964"
},
"Kreditoren": {
"account_number": "70000",
"is_group": 1,
"Wareneingangs-­Verrechnungskonto" : {
"account_number": "70001",
"account_type": "Stock Received But Not Billed"
}
},
},
"Kreditoren": {
"account_number": "70000",
"is_group": 1,
"Wareneingangs-­Verrechnungskonto" : {
"account_number": "70001",
"account_type": "Stock Received But Not Billed"
}
},
"Verb. aus Lieferungen und Leistungen": {
"account_number": "3300",
"account_type": "Payable"
@@ -1488,17 +1494,21 @@
},
"Umsatzsteuer 7 %": {
"account_number": "3801",
"account_type": "Tax"
"account_type": "Tax",
"tax_rate": 7.0
},
"Umsatzsteuer aus innergem. Erwerb": {
"account_number": "3802"
},
"Umsatzsteuer aus innergem. Erwerb 19 %": {
"account_number": "3804"
"account_number": "3804",
"account_type": "Tax",
"tax_rate": 19.0
},
"Umsatzsteuer 19 %": {
"account_number": "3806",
"account_type": "Tax"
"account_type": "Tax",
"tax_rate": 19.0
},
"Umsatzsteuer aus im Inland steuerpfl. EU-Lieferungen": {
"account_number": "3807"
@@ -2295,49 +2305,49 @@
},
"6 - sonstige betriebliche Ertr\u00e4ge": {
"root_type": "Income",
"is_group": 1,
"Erhaltene Boni (Gruppe)": {
"is_group": 1,
"Erhaltene Boni 7 % Vorsteuer": {
"account_number": "5750"
},
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
"account_number": "5753"
},
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
"account_number": "5754"
},
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
"account_number": "5755"
},
"Erhaltene Boni 19 % Vorsteuer": {
"account_number": "5760"
},
"Erhaltene Boni": {
"account_number": "5769"
}
},
"Erhaltene Rabatte (Gruppe)": {
"is_group": 1,
"Erhaltene Rabatte": {
"account_number": "5770"
},
"Erhaltene Rabatte 7 % Vorsteuer": {
"account_number": "5780"
},
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
"account_number": "5783"
},
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
"account_number": "5784"
},
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
"account_number": "5785"
},
"Erhaltene Rabatte 19 % Vorsteuer": {
"account_number": "5790"
}
},
"is_group": 1,
"Erhaltene Boni (Gruppe)": {
"is_group": 1,
"Erhaltene Boni 7 % Vorsteuer": {
"account_number": "5750"
},
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
"account_number": "5753"
},
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
"account_number": "5754"
},
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
"account_number": "5755"
},
"Erhaltene Boni 19 % Vorsteuer": {
"account_number": "5760"
},
"Erhaltene Boni": {
"account_number": "5769"
}
},
"Erhaltene Rabatte (Gruppe)": {
"is_group": 1,
"Erhaltene Rabatte": {
"account_number": "5770"
},
"Erhaltene Rabatte 7 % Vorsteuer": {
"account_number": "5780"
},
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
"account_number": "5783"
},
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
"account_number": "5784"
},
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
"account_number": "5785"
},
"Erhaltene Rabatte 19 % Vorsteuer": {
"account_number": "5790"
}
},
"Andere aktivierte Eigenleistungen": {
"account_number": "4820"
},
@@ -2407,29 +2417,26 @@
"Erl\u00f6se aus Verk\u00e4ufen Sachanlageverm\u00f6gen (bei Buchgewinn)": {
"account_number": "4849"
},
"Erl\u00f6se aus Verk\u00e4ufen immaterieller VG (bei Buchgewinn) (Gruppe)": {
"is_group": 1,
"Erl\u00f6se aus Verk\u00e4ufen immaterieller VG (bei Buchgewinn)": {
"account_number": "4850"
},
"Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (bei Buchgewinn)": {
"account_number": "4851"
},
"Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (inl\u00e4ndische Kap.Ges., bei Buchgewinn)": {
"account_number": "4852"
},
"Anlagenabg\u00e4nge Sachanlagen (Restbuchwert bei Buchvergewinn)": {
"account_number": "4855"
},
"Anlagenabg\u00e4nge immaterielle VG (Restbuchwert bei Buchgewinn)": {
"account_number": "4856"
},
"Anlagenabg\u00e4nge Finanzanlagen (Restbuchwert bei Buchgewinn)": {
"account_number": "4857"
},
"Anlagenabg\u00e4nge Finanzanlagen (inl\u00e4ndische Kap.Ges., Restbuchwert bei Buchgewinn)": {
"account_number": "4858"
}
"Erl\u00f6se aus Verk\u00e4ufen immaterieller VG (bei Buchgewinn)": {
"account_number": "4850"
},
"Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (bei Buchgewinn)": {
"account_number": "4851"
},
"Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (inl\u00e4ndische Kap.Ges., bei Buchgewinn)": {
"account_number": "4852"
},
"Anlagenabg\u00e4nge Sachanlagen (Restbuchwert bei Buchvergewinn)": {
"account_number": "4855"
},
"Anlagenabg\u00e4nge immaterielle VG (Restbuchwert bei Buchgewinn)": {
"account_number": "4856"
},
"Anlagenabg\u00e4nge Finanzanlagen (Restbuchwert bei Buchgewinn)": {
"account_number": "4857"
},
"Anlagenabg\u00e4nge Finanzanlagen (inl\u00e4ndische Kap.Ges., Restbuchwert bei Buchgewinn)": {
"account_number": "4858"
},
"Ertr\u00e4ge aus Zuschreibungen des Sachanlageverm\u00f6gens": {
"account_number": "4910",
@@ -2552,20 +2559,17 @@
"Entnahme von Gegenst\u00e4nden ohne USt": {
"account_number": "4605"
},
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 7 % USt (Gruppe)": {
"is_group": 1,
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 7 % USt": {
"account_number": "4630"
},
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt": {
"account_number": "4637"
},
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternnehmens ohne USt (Telefon-Nutzung)": {
"account_number": "4638"
},
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt (Kfz-Nutzung)": {
"account_number": "4639"
}
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 7 % USt": {
"account_number": "4630"
},
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt": {
"account_number": "4637"
},
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternnehmens ohne USt (Telefon-Nutzung)": {
"account_number": "4638"
},
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt (Kfz-Nutzung)": {
"account_number": "4639"
},
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 19 % USt (Gruppe)": {
"is_group": 1,
@@ -2603,14 +2607,11 @@
"Unentgeltliche Zuwendung von Gegenst\u00e4nden ohne USt": {
"account_number": "4689"
},
"Nicht steuerbare Ums\u00e4tze (Innenums\u00e4tze) (Gruppe)": {
"is_group": 1,
"Nicht steuerbare Ums\u00e4tze (Innenums\u00e4tze)": {
"account_number": "4690"
},
"Umsatzsteuerverg\u00fctungen, z.B. nach \u00a7 24 UStG": {
"account_number": "4695"
}
"Nicht steuerbare Ums\u00e4tze (Innenums\u00e4tze)": {
"account_number": "4690"
},
"Umsatzsteuerverg\u00fctungen, z.B. nach \u00a7 24 UStG": {
"account_number": "4695"
},
"Au\u00dferordentliche Ertr\u00e4ge (Gruppe)": {
"is_group": 1,
@@ -2620,48 +2621,42 @@
"Au\u00dferordentliche Ertr\u00e4ge finanzwirksam": {
"account_number": "7401"
},
"Au\u00dferordentliche Ertr\u00e4ge nicht finanzwirksam (Gruppe)": {
"is_group": 1,
"Au\u00dferordentliche Ertr\u00e4ge nicht finanzwirksam": {
"account_number": "7450"
},
"Ertr\u00e4ge durch Verschmelzung und Umwandlung": {
"account_number": "7451"
},
"Ertr\u00e4ge durch den Verkauf von bedeutenden Beteiligungen": {
"account_number": "7452"
},
"Ert\u00e4ge durch den Verkauf von bedeutenden Grundst\u00fccken": {
"account_number": "7453"
},
"Gewinn aus der Ver\u00e4u\u00dferung oder der Aufgabe von Gesch\u00e4ftsaktivit\u00e4ten nach Steuern": {
"account_number": "7454"
}
"Au\u00dferordentliche Ertr\u00e4ge nicht finanzwirksam": {
"account_number": "7450"
},
"Au\u00dferordentliche Ertr\u00e4ge aus der Anwendung von \u00dcbergangsvorschriften (Gruppe)": {
"is_group": 1,
"Au\u00dferordentliche Ertr\u00e4ge aus der Anwendung von \u00dcbergangsvorschriften": {
"account_number": "7460"
},
"Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Sachanlageverm\u00f6gen": {
"account_number": "7461"
},
"Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Finanzanlageverm\u00f6gen": {
"account_number": "7462"
},
"Au\u00dferordentliche Ertr\u00e4ge: Wertpapiere im Umlaufverm\u00f6gen": {
"account_number": "7463"
},
"Au\u00dferordentliche Ertr\u00e4ge: latente Steuern": {
"account_number": "7464"
}
"Ertr\u00e4ge durch Verschmelzung und Umwandlung": {
"account_number": "7451"
},
"Ertr\u00e4ge durch den Verkauf von bedeutenden Beteiligungen": {
"account_number": "7452"
},
"Ert\u00e4ge durch den Verkauf von bedeutenden Grundst\u00fccken": {
"account_number": "7453"
},
"Gewinn aus der Ver\u00e4u\u00dferung oder der Aufgabe von Gesch\u00e4ftsaktivit\u00e4ten nach Steuern": {
"account_number": "7454"
},
"Au\u00dferordentliche Ertr\u00e4ge aus der Anwendung von \u00dcbergangsvorschriften": {
"account_number": "7460"
},
"Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Sachanlageverm\u00f6gen": {
"account_number": "7461"
},
"Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Finanzanlageverm\u00f6gen": {
"account_number": "7462"
},
"Au\u00dferordentliche Ertr\u00e4ge: Wertpapiere im Umlaufverm\u00f6gen": {
"account_number": "7463"
},
"Au\u00dferordentliche Ertr\u00e4ge: latente Steuern": {
"account_number": "7464"
}
}
},
"7 - sonstige betriebliche Aufwendungen": {
"root_type": "Expense",
"is_group": 1,
"Erl\u00f6sschm\u00e4lerungen (Gruppe)": {
"is_group": 1,
"Erl\u00f6sschm\u00e4lerungen (Gruppe)": {
"is_group": 1,
"Erl\u00f6sschm\u00e4lerungen": {
"account_number": "4700"
@@ -2692,40 +2687,43 @@
},
"Erl\u00f6sschm\u00e4lerungen aus im Inland steuerpfl. EU-Lieferungen 16 % USt": {
"account_number": "4729"
}
},
"Gew\u00e4hrte Skonti (Gruppe)": {
"is_group": 1,
"Gew. Skonti": {
"account_number": "4730"
},
"Gew\u00e4hrte Skonti (Gruppe)": {
"is_group": 1,
"Gew. Skonti": {
"account_number": "4730"
},
"Gew. Skonti 7 % USt": {
"account_number": "4731"
},
"Gew. Skonti 19 % USt": {
"account_number": "4736"
},
"Gew. Skonti aus Lieferungen von Mobilfunkger./Schaltkr., f. die der Leistungsempf. die Ust. schuldet": {
"account_number": "4738"
},
"Gew. Skonti aus Leistungen, f. die der Leistungsempf. die Umsatzsteuer nach \u00a7 13b UStG schuldet": {
"account_number": "4741"
},
"Gew. Skonti aus Erl\u00f6sen aus im anderen EU-Land steuerpfl. Leistungen, f. die der Leistungsempf. die Ust. schuldet": {
"account_number": "4742"
},
"Gew. Skonti aus steuerfreien innergem. Lieferungen \u00a7 4 Nr. 1b UStG": {
"account_number": "4743"
},
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen": {
"account_number": "4745"
},
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 7% USt": {
"account_number": "4746"
},
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 19% USt": {
"account_number": "4748"
}
"Gew. Skonti 7 % USt": {
"account_number": "4731"
},
"Gew. Skonti 19 % USt": {
"account_number": "4736"
},
"Gew. Skonti aus Lieferungen von Mobilfunkger./Schaltkr., f. die der Leistungsempf. die Ust. schuldet": {
"account_number": "4738"
},
"Gew. Skonti aus Leistungen, f. die der Leistungsempf. die Umsatzsteuer nach \u00a7 13b UStG schuldet": {
"account_number": "4741"
},
"Gew. Skonti aus Erl\u00f6sen aus im anderen EU-Land steuerpfl. Leistungen, f. die der Leistungsempf. die Ust. schuldet": {
"account_number": "4742"
},
"Gew. Skonti aus steuerfreien innergem. Lieferungen \u00a7 4 Nr. 1b UStG": {
"account_number": "4743"
},
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen": {
"account_number": "4745"
},
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 7% USt": {
"account_number": "4746"
},
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 19% USt": {
"account_number": "4748"
}
},
"Gew\u00e4hrte Boni (Gruppe)": {
"is_group": 1,
"Gew\u00e4hrte Boni 7 % USt": {
"account_number": "4750"
},
@@ -2744,7 +2742,7 @@
"Gew\u00e4hrte Rabatte 19 % USt": {
"account_number": "4790"
}
},
},
"Sonstige betriebliche Aufwendungen": {
"account_number": "6300"
},
@@ -2838,103 +2836,79 @@
"account_number": "6398"
}
},
"Versicherungen (Gruppe)": {
"is_group": 1,
"Versicherungen": {
"account_number": "6400"
},
"Versicherungen f. Geb\u00e4ude, die zum Betriebsverm\u00f6gen geh\u00f6ren": {
"account_number": "6405"
},
"Netto-Pr\u00e4mie f. R\u00fcckdeckung k\u00fcnftiger Versorgungsleistungen": {
"account_number": "6410"
},
"Beitr\u00e4ge": {
"account_number": "6420"
},
"Sonstige Abgaben": {
"account_number": "6430"
},
"Steuerlich abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": {
"account_number": "6436"
},
"Steuerlich nicht abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": {
"account_number": "6437"
},
"Ausgleichsabgabe i. S. d. Schwerbehindertengesetzes": {
"account_number": "6440"
},
"Reparaturen und Instandhaltung von Bauten": {
"account_number": "6450"
},
"Reparaturen und Instandhaltung von technischenAnlagen und Maschinen": {
"account_number": "6460"
},
"Reparaturen und Instandhaltung von anderen Anlagen und Betriebs- und Gesch\u00e4ftsausstattung": {
"account_number": "6470"
},
"Zuf\u00fchrung zu Aufwandsr\u00fcckstellungen": {
"account_number": "6475"
},
"Reparaturen und Instandhaltung von anderen Anlagen": {
"account_number": "6485"
},
"Sonstige Reparaturen und Instandhaltungen": {
"account_number": "6490"
},
"Wartungskosten f. Hard- und Software": {
"account_number": "6495"
},
"Mietleasing (bewegliche Wirtschaftsg\u00fcter)": {
"account_number": "6498"
}
"Versicherungen": {
"account_number": "6400"
},
"Versicherungen f. Geb\u00e4ude, die zum Betriebsverm\u00f6gen geh\u00f6ren": {
"account_number": "6405"
},
"Netto-Pr\u00e4mie f. R\u00fcckdeckung k\u00fcnftiger Versorgungsleistungen": {
"account_number": "6410"
},
"Beitr\u00e4ge": {
"account_number": "6420"
},
"Sonstige Abgaben": {
"account_number": "6430"
},
"Steuerlich abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": {
"account_number": "6436"
},
"Steuerlich nicht abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": {
"account_number": "6437"
},
"Ausgleichsabgabe i. S. d. Schwerbehindertengesetzes": {
"account_number": "6440"
},
"Reparaturen und Instandhaltung von Bauten": {
"account_number": "6450"
},
"Reparaturen und Instandhaltung von technischenAnlagen und Maschinen": {
"account_number": "6460"
},
"Reparaturen und Instandhaltung von anderen Anlagen und Betriebs- und Gesch\u00e4ftsausstattung": {
"account_number": "6470"
},
"Zuf\u00fchrung zu Aufwandsr\u00fcckstellungen": {
"account_number": "6475"
},
"Reparaturen und Instandhaltung von anderen Anlagen": {
"account_number": "6485"
},
"Sonstige Reparaturen und Instandhaltungen": {
"account_number": "6490"
},
"Wartungskosten f. Hard- und Software": {
"account_number": "6495"
},
"Mietleasing (bewegliche Wirtschaftsg\u00fcter)": {
"account_number": "6498"
},
"Fahrzeugkosten (Gruppe)": {
"is_group": 1,
"Fahrzeugkosten": {
"account_number": "6500"
},
"Kfz-Versicherungen (Gruppe)": {
"is_group": 1,
"Kfz-Versicherungen": {
"account_number": "6520"
}
"Kfz-Versicherungen": {
"account_number": "6520"
},
"Laufende Kfz-Betriebskosten (Gruppe)": {
"is_group": 1,
"Laufende Kfz-Betriebskosten": {
"account_number": "6530"
}
"Laufende Kfz-Betriebskosten": {
"account_number": "6530"
},
"Kfz-Reparaturen (Gruppe)": {
"is_group": 1,
"Kfz-Reparaturen": {
"account_number": "6540"
}
"Kfz-Reparaturen": {
"account_number": "6540"
},
"Garagenmiete (Gruppe)": {
"is_group": 1,
"Garagenmiete": {
"account_number": "6550"
}
"Garagenmiete": {
"account_number": "6550"
},
"Mietleasing Kfz (Gruppe)": {
"is_group": 1,
"Mietleasing Kfz": {
"account_number": "6560"
}
"Mietleasing Kfz": {
"account_number": "6560"
},
"Sonstige Kfz-Kosten (Gruppe)": {
"is_group": 1,
"Sonstige Kfz-Kosten": {
"account_number": "6570"
}
"Sonstige Kfz-Kosten": {
"account_number": "6570"
},
"Mautgeb\u00fchren (Gruppe)": {
"is_group": 1,
"Mautgeb\u00fchren": {
"account_number": "6580"
}
"Mautgeb\u00fchren": {
"account_number": "6580"
},
"Kfz-Kosten f. betrieblich genutzte zum Privatverm\u00f6gen geh\u00f6rende Kraftfahrzeuge": {
"account_number": "6590"
@@ -2996,20 +2970,23 @@
"Nicht abzugsf\u00e4hige Betriebsausgaben aus Werbe- und Repr\u00e4sentationskosten": {
"account_number": "6645"
},
"Reisekosten Arbeitnehmer": {
"account_number": "6650"
},
"Reisekosten Arbeitnehmer \u00dcbernachtungsaufwand": {
"account_number": "6660"
},
"Reisekosten Arbeitnehmer Fahrtkosten": {
"account_number": "6663"
},
"Reisekosten Arbeitnehmer Verpflegungsmehraufwand": {
"account_number": "6664"
},
"Kilometergelderstattung Arbeitnehmer": {
"account_number": "6668"
"Reisekosten Arbeitnehmer (Gruppe)": {
"is_group": 1,
"Reisekosten Arbeitnehmer": {
"account_number": "6650"
},
"Reisekosten Arbeitnehmer \u00dcbernachtungsaufwand": {
"account_number": "6660"
},
"Reisekosten Arbeitnehmer Fahrtkosten": {
"account_number": "6663"
},
"Reisekosten Arbeitnehmer Verpflegungsmehraufwand": {
"account_number": "6664"
},
"Kilometergelderstattung Arbeitnehmer": {
"account_number": "6668"
}
},
"Reisekosten Unternehmer (Gruppe)": {
"is_group": 1,

View File

@@ -48,12 +48,6 @@ frappe.ui.form.on('Accounting Dimension', {
frm.set_value('label', frm.doc.document_type);
frm.set_value('fieldname', frappe.model.scrub(frm.doc.document_type));
if (frm.is_new()){
let row = frappe.model.add_child(frm.doc, "Accounting Dimension Detail", "dimension_defaults");
row.reference_document = frm.doc.document_type;
frm.refresh_fields("dimension_defaults");
}
frappe.db.get_value('Accounting Dimension', {'document_type': frm.doc.document_type}, 'document_type', (r) => {
if (r && r.document_type) {
frm.set_df_property('document_type', 'description', "Document type is already set as dimension");

View File

@@ -1,4 +1,5 @@
{
"actions": [],
"autoname": "field:label",
"creation": "2019-05-04 18:13:37.002352",
"doctype": "DocType",
@@ -46,7 +47,8 @@
"options": "Accounting Dimension Detail"
}
],
"modified": "2019-07-17 16:49:31.134385",
"links": [],
"modified": "2020-03-22 20:34:39.805728",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounting Dimension",
@@ -63,9 +65,20 @@
"role": "System Manager",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"share": 1,
"write": 1
}
],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "ASC",
"track_changes": 1

View File

@@ -172,7 +172,7 @@ def get_doctypes_with_dimensions():
return doclist
def get_accounting_dimensions(as_list=True):
accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "disabled"])
accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "disabled", "document_type"])
if as_list:
return [d.fieldname for d in accounting_dimensions]
@@ -186,6 +186,18 @@ def get_checks_for_pl_and_bs_accounts():
return dimensions
def get_dimension_with_children(doctype, dimension):
if isinstance(dimension, list):
dimension = dimension[0]
all_dimensions = []
lft, rgt = frappe.db.get_value(doctype, dimension, ["lft", "rgt"])
children = frappe.get_all(doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]}, order_by="lft")
all_dimensions += [c.name for c in children]
return all_dimensions
@frappe.whitelist()
def get_dimension_filters():
dimension_filters = frappe.db.sql("""

View File

@@ -0,0 +1,8 @@
frappe.ui.form.on('Accounts Settings', {
refresh: function(frm) {
frm.set_df_property("acc_frozen_upto", "label", "Books Closed Through");
frm.set_df_property("frozen_accounts_modifier", "label", "Role Allowed to Close Books & Make Changes to Closed Periods");
frm.set_df_property("credit_controller", "label", "Credit Manager");
}
});

View File

@@ -1,4 +1,5 @@
{
"actions": [],
"allow_import": 1,
"allow_rename": 1,
"creation": "2017-05-29 21:35:13.136357",
@@ -82,7 +83,7 @@
"default": "0",
"fieldname": "is_default",
"fieldtype": "Check",
"label": "Is the Default Account"
"label": "Is Default Account"
},
{
"default": "0",
@@ -211,7 +212,8 @@
"read_only": 1
}
],
"modified": "2019-10-02 01:34:12.417601",
"links": [],
"modified": "2020-01-29 20:42:26.458316",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Account",

View File

@@ -6,6 +6,7 @@ from __future__ import unicode_literals
import frappe, json
from frappe.model.document import Document
from frappe import _
from frappe.desk.search import sanitize_searchfield
class BankGuarantee(Document):
def validate(self):
@@ -22,5 +23,8 @@ class BankGuarantee(Document):
@frappe.whitelist()
def get_vouchar_detials(column_list, doctype, docname):
column_list = json.loads(column_list)
for col in column_list:
sanitize_searchfield(col)
return frappe.db.sql(''' select {columns} from `tab{doctype}` where name=%s'''
.format(columns=", ".join(json.loads(column_list)), doctype=doctype), docname, as_dict=1)[0]

View File

@@ -3,16 +3,16 @@
frappe.ui.form.on("Bank Reconciliation", {
setup: function(frm) {
frm.add_fetch("bank_account", "account_currency", "account_currency");
frm.add_fetch("account", "account_currency", "account_currency");
},
onload: function(frm) {
let default_bank_account = frappe.defaults.get_user_default("Company")?
locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"]: "";
frm.set_value("bank_account", default_bank_account);
frm.set_value("account", default_bank_account);
frm.set_query("bank_account", function() {
frm.set_query("account", function() {
return {
"filters": {
"account_type": ["in",["Bank","Cash"]],

View File

@@ -19,10 +19,9 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Select account head of the bank where cheque was deposited.",
"fetch_from": "bank_account_no.account",
"fetch_from": "bank_account.account",
"fetch_if_empty": 1,
"fieldname": "bank_account",
"fieldname": "account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -31,7 +30,7 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Bank Account",
"label": "Account",
"length": 0,
"no_copy": 0,
"options": "Account",
@@ -164,7 +163,6 @@
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -183,8 +181,9 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Select the Bank Account to reconcile.",
"fetch_if_empty": 0,
"fieldname": "bank_account_no",
"fieldname": "bank_account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -193,12 +192,11 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Bank Account No",
"label": "Bank Account",
"length": 0,
"no_copy": 0,
"options": "Bank Account",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -450,7 +448,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2019-04-09 18:41:06.110453",
"modified": "2020-01-22 00:00:00.000000",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Reconciliation",
@@ -483,4 +481,4 @@
"track_changes": 0,
"track_seen": 0,
"track_views": 0
}
}

View File

@@ -13,17 +13,15 @@ form_grid_templates = {
class BankReconciliation(Document):
def get_payment_entries(self):
if not (self.bank_account and self.from_date and self.to_date):
msgprint(_("Bank Account, From Date and To Date are Mandatory"))
return
if not (self.from_date and self.to_date):
frappe.throw(_("From Date and To Date are Mandatory"))
if not self.account:
frappe.throw(_("Account is mandatory to get payment entries"))
condition = ""
if not self.include_reconciled_entries:
condition = " and (clearance_date is null or clearance_date='0000-00-00')"
account_cond = ""
if self.bank_account_no:
account_cond = " and t2.bank_account_no = {0}".format(frappe.db.escape(self.bank_account_no))
condition = "and (clearance_date IS NULL or clearance_date='0000-00-00')"
journal_entries = frappe.db.sql("""
select
@@ -34,15 +32,15 @@ class BankReconciliation(Document):
from
`tabJournal Entry` t1, `tabJournal Entry Account` t2
where
t2.parent = t1.name and t2.account = %s and t1.docstatus=1
and t1.posting_date >= %s and t1.posting_date <= %s
and ifnull(t1.is_opening, 'No') = 'No' {0} {1}
t2.parent = t1.name and t2.account = %(account)s and t1.docstatus=1
and t1.posting_date >= %(from)s and t1.posting_date <= %(to)s
and ifnull(t1.is_opening, 'No') = 'No' {condition}
group by t2.account, t1.name
order by t1.posting_date ASC, t1.name DESC
""".format(condition, account_cond), (self.bank_account, self.from_date, self.to_date), as_dict=1)
""".format(condition=condition), {"account": self.account, "from": self.from_date, "to": self.to_date}, as_dict=1)
if self.bank_account_no:
condition = " and bank_account = %(bank_account_no)s"
if self.bank_account:
condition += 'and bank_account = %(bank_account)s'
payment_entries = frappe.db.sql("""
select
@@ -55,12 +53,12 @@ class BankReconciliation(Document):
from `tabPayment Entry`
where
(paid_from=%(account)s or paid_to=%(account)s) and docstatus=1
and posting_date >= %(from)s and posting_date <= %(to)s {0}
and posting_date >= %(from)s and posting_date <= %(to)s
{condition}
order by
posting_date ASC, name DESC
""".format(condition),
{"account":self.bank_account, "from":self.from_date,
"to":self.to_date, "bank_account_no": self.bank_account_no}, as_dict=1)
""".format(condition=condition), {"account": self.account, "from":self.from_date,
"to": self.to_date, "bank_account": self.bank_account}, as_dict=1)
pos_entries = []
if self.include_pos_transactions:
@@ -72,11 +70,10 @@ class BankReconciliation(Document):
from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account
where
sip.account=%(account)s and si.docstatus=1 and sip.parent = si.name
and account.name = sip.account and si.posting_date >= %(from)s and si.posting_date <= %(to)s {0}
and account.name = sip.account and si.posting_date >= %(from)s and si.posting_date <= %(to)s
order by
si.posting_date ASC, si.name DESC
""".format(condition),
{"account":self.bank_account, "from":self.from_date, "to":self.to_date}, as_dict=1)
""", {"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)),
key=lambda k: k['posting_date'] or getdate(nowdate()))

View File

@@ -110,6 +110,15 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"depends_on": "eval:doc.docstatus==1",
"fieldname": "clearance_date",
"fieldtype": "Date",
"label": "Clearance Date",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
}
],
"has_web_view": 0,
@@ -122,7 +131,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2018-12-06 10:57:02.635141",
"modified": "2020-01-22 00:00:00.000000",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Transaction Payments",
@@ -138,4 +147,4 @@
"track_changes": 1,
"track_seen": 0,
"track_views": 0
}
}

View File

@@ -210,10 +210,10 @@ def get_requested_amount(args, budget):
item_code = args.get('item_code')
condition = get_other_condition(args, budget, 'Material Request')
data = frappe.db.sql(""" select ifnull((sum(mri.stock_qty - mri.ordered_qty) * rate), 0) as amount
from `tabMaterial Request Item` mri, `tabMaterial Request` mr where mr.name = mri.parent and
mri.item_code = %s and mr.docstatus = 1 and mri.stock_qty > mri.ordered_qty and {0} and
mr.material_request_type = 'Purchase' and mr.status != 'Stopped'""".format(condition), item_code, as_list=1)
data = frappe.db.sql(""" select ifnull((sum(child.stock_qty - child.ordered_qty) * rate), 0) as amount
from `tabMaterial Request Item` child, `tabMaterial Request` parent where parent.name = child.parent and
child.item_code = %s and parent.docstatus = 1 and child.stock_qty > child.ordered_qty and {0} and
parent.material_request_type = 'Purchase' and parent.status != 'Stopped'""".format(condition), item_code, as_list=1)
return data[0][0] if data else 0
@@ -221,10 +221,10 @@ def get_ordered_amount(args, budget):
item_code = args.get('item_code')
condition = get_other_condition(args, budget, 'Purchase Order')
data = frappe.db.sql(""" select ifnull(sum(poi.amount - poi.billed_amt), 0) as amount
from `tabPurchase Order Item` poi, `tabPurchase Order` po where
po.name = poi.parent and poi.item_code = %s and po.docstatus = 1 and poi.amount > poi.billed_amt
and po.status != 'Closed' and {0}""".format(condition), item_code, as_list=1)
data = frappe.db.sql(""" select ifnull(sum(child.amount - child.billed_amt), 0) as amount
from `tabPurchase Order Item` child, `tabPurchase Order` parent where
parent.name = child.parent and child.item_code = %s and parent.docstatus = 1 and child.amount > child.billed_amt
and parent.status != 'Closed' and {0}""".format(condition), item_code, as_list=1)
return data[0][0] if data else 0
@@ -233,16 +233,15 @@ def get_other_condition(args, budget, for_doc):
budget_against_field = frappe.scrub(args.get("budget_against_field"))
if budget_against_field and args.get(budget_against_field):
condition += " and %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'
start_date, end_date = frappe.db.get_value('Fiscal Year', args.get('fiscal_year'),
['year_start_date', 'year_end_date'])
alias = 'mr' if for_doc == 'Material Request' else 'po'
condition += """ and %s.%s
between '%s' and '%s' """ %(alias, date_field, start_date, end_date)
condition += """ and parent.%s
between '%s' and '%s' """ %(date_field, start_date, end_date)
return condition

View File

@@ -32,10 +32,12 @@ frappe.ui.form.on('C-Form Invoice Detail', {
invoice_no(frm, cdt, cdn) {
let d = frappe.get_doc(cdt, cdn);
frm.call('get_invoice_details', {
invoice_no: d.invoice_no
}).then(r => {
frappe.model.set_value(cdt, cdn, r.message);
});
if (d.invoice_no) {
frm.call('get_invoice_details', {
invoice_no: d.invoice_no
}).then(r => {
frappe.model.set_value(cdt, cdn, r.message);
});
}
}
});

View File

@@ -96,7 +96,11 @@ def build_forest(data):
if parent_account == account_name == child:
return [parent_account]
elif account_name == child:
return [child] + return_parent(data, parent_account)
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))
return [child] + parent_account_list
charts_map, paths = {}, []
@@ -104,7 +108,7 @@ def build_forest(data):
error_messages = []
for i in data:
account_name, _, account_number, is_group, account_type, root_type = i
account_name, dummy, account_number, is_group, account_type, root_type = i
if not account_name:
error_messages.append("Row {0}: Please enter Account Name".format(line_no))

View File

@@ -1,4 +1,5 @@
{
"actions": [],
"allow_copy": 1,
"allow_import": 1,
"allow_rename": 1,
@@ -123,10 +124,13 @@
],
"icon": "fa fa-money",
"idx": 1,
"modified": "2019-09-16 14:44:17.103548",
"is_tree": 1,
"links": [],
"modified": "2020-03-18 18:26:01.540170",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Cost Center",
"nsm_parent_field": "parent_cost_center",
"owner": "Administrator",
"permissions": [
{
@@ -162,7 +166,6 @@
"role": "Purchase User"
}
],
"quick_entry": 1,
"search_fields": "parent_cost_center, is_group",
"show_name_in_global_search": 1,
"sort_field": "modified",

View File

@@ -1,5 +1,5 @@
frappe.treeview_settings["Cost Center"] = {
breadcrumbs: "Accounts",
breadcrumb: "Accounts",
get_tree_root: false,
filters: [{
fieldname: "company",

View File

@@ -18,7 +18,8 @@
"in_list_view": 1,
"label": "Invoice",
"options": "Sales Invoice",
"reqd": 1
"reqd": 1,
"search_index": 1
},
{
"fetch_from": "sales_invoice.customer",
@@ -60,7 +61,7 @@
}
],
"istable": 1,
"modified": "2019-09-26 11:05:36.016772",
"modified": "2020-02-20 16:16:20.724620",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Discounted Invoice",

View File

@@ -7,4 +7,4 @@ from __future__ import unicode_literals
from frappe.model.document import Document
class DiscountedInvoice(Document):
pass
pass

File diff suppressed because it is too large Load Diff

View File

@@ -232,10 +232,13 @@ def update_outstanding_amt(account, party_type, party, against_voucher_type, aga
if bal < 0 and not on_cancel:
frappe.throw(_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal)))
# Update outstanding amt on against voucher
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
ref_doc = frappe.get_doc(against_voucher_type, against_voucher)
ref_doc.db_set('outstanding_amount', bal)
# Didn't use db_set for optimisation purpose
ref_doc.outstanding_amount = bal
frappe.db.set_value(against_voucher_type, against_voucher, 'outstanding_amount', bal)
ref_doc.set_status(update=True)
def validate_frozen_account(account, adv_adj=None):
@@ -274,6 +277,9 @@ def update_against_account(voucher_type, voucher_no):
if d.against != new_against:
frappe.db.set_value("GL Entry", d.name, "against", new_against)
def on_doctype_update():
frappe.db.add_index("GL Entry", ["against_voucher_type", "against_voucher"])
frappe.db.add_index("GL Entry", ["voucher_type", "voucher_no"])
def rename_gle_sle_docs():
for doctype in ["GL Entry", "Stock Ledger Entry"]:

File diff suppressed because it is too large Load Diff

View File

@@ -456,11 +456,12 @@ class JournalEntry(AccountsController):
def set_print_format_fields(self):
bank_amount = party_amount = total_amount = 0.0
currency = bank_account_currency = party_account_currency = pay_to_recd_from= None
party_type = None
for d in self.get('accounts'):
if d.party_type in ['Customer', 'Supplier'] and d.party:
party_type = d.party_type
if not pay_to_recd_from:
pay_to_recd_from = frappe.db.get_value(d.party_type, d.party,
"customer_name" if d.party_type=="Customer" else "supplier_name")
pay_to_recd_from = d.party
if pay_to_recd_from and pay_to_recd_from == d.party:
party_amount += (d.debit_in_account_currency or d.credit_in_account_currency)
@@ -470,8 +471,9 @@ class JournalEntry(AccountsController):
bank_amount += (d.debit_in_account_currency or d.credit_in_account_currency)
bank_account_currency = d.account_currency
if pay_to_recd_from:
self.pay_to_recd_from = pay_to_recd_from
if party_type and pay_to_recd_from:
self.pay_to_recd_from = frappe.db.get_value(party_type, pay_to_recd_from,
"customer_name" if party_type=="Customer" else "supplier_name")
if bank_amount:
total_amount = bank_amount
currency = bank_account_currency

View File

@@ -11,6 +11,7 @@ class ModeofPayment(Document):
def validate(self):
self.validate_accounts()
self.validate_repeating_companies()
self.validate_pos_mode_of_payment()
def validate_repeating_companies(self):
"""Error when Same Company is entered multiple times in accounts"""
@@ -27,3 +28,15 @@ class ModeofPayment(Document):
if frappe.db.get_value("Account", entry.default_account, "company") != entry.company:
frappe.throw(_("Account {0} does not match with Company {1} in Mode of Account: {2}")
.format(entry.default_account, entry.company, self.name))
def validate_pos_mode_of_payment(self):
if not self.enabled:
pos_profiles = frappe.db.sql("""SELECT sip.parent FROM `tabSales Invoice Payment` sip
WHERE sip.parenttype = 'POS Profile' and sip.mode_of_payment = %s""", (self.name))
pos_profiles = list(map(lambda x: x[0], pos_profiles))
if pos_profiles:
message = "POS Profile " + frappe.bold(", ".join(pos_profiles)) + " contains \
Mode of Payment " + frappe.bold(str(self.name)) + ". Please remove them to disable this mode."
frappe.throw(_(message), title="Not Allowed")

View File

@@ -154,8 +154,11 @@ frappe.ui.form.on('Payment Entry', {
frm.toggle_display("base_paid_amount", frm.doc.paid_from_account_currency != company_currency);
frm.toggle_display("base_received_amount", (frm.doc.paid_to_account_currency != company_currency &&
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
frm.toggle_display("base_received_amount", (
frm.doc.paid_to_account_currency != company_currency &&
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency
&& frm.doc.base_paid_amount != frm.doc.base_received_amount
));
frm.toggle_display("received_amount", (frm.doc.payment_type=="Internal Transfer" ||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency))
@@ -486,6 +489,7 @@ frappe.ui.form.on('Payment Entry', {
paid_amount: function(frm) {
frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
frm.trigger("reset_received_amount");
frm.events.hide_unhide_fields(frm);
},
received_amount: function(frm) {
@@ -509,6 +513,7 @@ frappe.ui.form.on('Payment Entry', {
frm.events.set_unallocated_amount(frm);
frm.set_paid_amount_based_on_received_amount = false;
frm.events.hide_unhide_fields(frm);
},
reset_received_amount: function(frm) {

View File

@@ -81,7 +81,12 @@ class PaymentEntry(AccountsController):
self.update_advance_paid()
self.update_expense_claim()
self.delink_advance_entry_references()
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)
def update_outstanding_amounts(self):
self.set_missing_ref_details(force=True)
@@ -102,7 +107,9 @@ class PaymentEntry(AccountsController):
self.bank = bank_data.bank
self.bank_account_no = bank_data.bank_account_no
self.set(field, bank_data.account)
if not self.get(field):
self.set(field, bank_data.account)
def validate_allocated_amount(self):
for d in self.get("references"):

View File

@@ -149,6 +149,49 @@ 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_against_sales_invoice_to_check_status(self):
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
currency="USD", conversion_rate=50)
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
pe.reference_no = "1"
pe.reference_date = "2016-01-01"
pe.target_exchange_rate = 50
pe.insert()
pe.submit()
outstanding_amount, status = frappe.db.get_value("Sales Invoice", si.name, ["outstanding_amount", "status"])
self.assertEqual(flt(outstanding_amount), 0)
self.assertEqual(status, 'Paid')
pe.cancel()
outstanding_amount, status = frappe.db.get_value("Sales Invoice", si.name, ["outstanding_amount", "status"])
self.assertEqual(flt(outstanding_amount), 100)
self.assertEqual(status, 'Unpaid')
def test_payment_against_purchase_invoice_to_check_status(self):
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
currency="USD", conversion_rate=50)
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank USD - _TC")
pe.reference_no = "1"
pe.reference_date = "2016-01-01"
pe.source_exchange_rate = 50
pe.insert()
pe.submit()
outstanding_amount, status = frappe.db.get_value("Purchase Invoice", pi.name, ["outstanding_amount", "status"])
self.assertEqual(flt(outstanding_amount), 0)
self.assertEqual(status, 'Paid')
pe.cancel()
outstanding_amount, status = frappe.db.get_value("Purchase Invoice", pi.name, ["outstanding_amount", "status"])
self.assertEqual(flt(outstanding_amount), 250)
self.assertEqual(status, 'Unpaid')
def test_payment_entry_against_ec(self):
payable = frappe.get_cached_value('Company', "_Test Company", 'default_payable_account')
@@ -566,4 +609,4 @@ class TestPaymentEntry(unittest.TestCase):
self.assertEqual(expected_party_account_balance, party_account_balance)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
accounts_settings.save()

View File

@@ -15,11 +15,11 @@ frappe.ui.form.on('Payment Order', {
if (frm.doc.docstatus == 0) {
frm.add_custom_button(__('Payment Request'), function() {
frm.trigger("get_from_payment_request");
}, __("Get from"));
}, __("Get Payments from"));
frm.add_custom_button(__('Payment Entry'), function() {
frm.trigger("get_from_payment_entry");
}, __("Get from"));
}, __("Get Payments from"));
frm.trigger('remove_button');
}

View File

@@ -59,7 +59,6 @@
"fieldtype": "Section Break"
},
{
"allow_bulk_edit": 1,
"fieldname": "references",
"fieldtype": "Table",
"label": "Payment Order Reference",
@@ -108,7 +107,7 @@
}
],
"is_submittable": 1,
"modified": "2019-05-14 17:12:24.912666",
"modified": "2020-04-06 18:00:56.022642",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Order",

View File

@@ -92,6 +92,7 @@ class PaymentReconciliation(Document):
FROM `tab{doc}`, `tabGL Entry`
WHERE
(`tab{doc}`.name = `tabGL Entry`.against_voucher or `tab{doc}`.name = `tabGL Entry`.voucher_no)
and `tab{doc}`.{party_type_field} = %(party)s
and `tab{doc}`.is_return = 1 and `tab{doc}`.return_against IS NULL
and `tabGL Entry`.against_voucher_type = %(voucher_type)s
and `tab{doc}`.docstatus = 1 and `tabGL Entry`.party = %(party)s
@@ -99,12 +100,17 @@ class PaymentReconciliation(Document):
GROUP BY `tab{doc}`.name
Having
amount > 0
""".format(doc=voucher_type, dr_or_cr=dr_or_cr, reconciled_dr_or_cr=reconciled_dr_or_cr), {
'party': self.party,
'party_type': self.party_type,
'voucher_type': voucher_type,
'account': self.receivable_payable_account
}, as_dict=1)
""".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)),
{
'party': self.party,
'party_type': self.party_type,
'voucher_type': voucher_type,
'account': self.receivable_payable_account
}, as_dict=1)
def add_payment_entries(self, entries):
self.set('payments', [])

File diff suppressed because it is too large Load Diff

View File

@@ -66,6 +66,8 @@ class PaymentRequest(Document):
if self.payment_request_type == 'Outward':
self.db_set('status', 'Initiated')
return
elif self.payment_request_type == 'Inward':
self.db_set('status', 'Requested')
send_mail = self.payment_gateway_validation()
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
@@ -88,6 +90,7 @@ class PaymentRequest(Document):
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"):
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
si = make_sales_invoice(self.reference_name, ignore_permissions=True)
si.allocate_advances_automatically = True
si = si.insert(ignore_permissions=True)
si.submit()
@@ -126,12 +129,12 @@ class PaymentRequest(Document):
return controller.get_payment_url(**{
"amount": flt(self.grand_total, self.precision("grand_total")),
"title": data.company.encode("utf-8"),
"description": self.subject.encode("utf-8"),
"title": frappe.as_unicode(data.company),
"description": frappe.as_unicode(self.subject),
"reference_doctype": "Payment Request",
"reference_docname": self.name,
"payer_email": self.email_to or frappe.session.user,
"payer_name": frappe.safe_encode(data.customer_name),
"payer_name": frappe.as_unicode(data.customer_name),
"order_id": self.name,
"currency": self.currency
})
@@ -317,13 +320,13 @@ def make_payment_request(**args):
"payment_request_type": args.get("payment_request_type"),
"currency": ref_doc.currency,
"grand_total": grand_total,
"email_to": args.recipient_id or "",
"email_to": args.recipient_id or ref_doc.owner,
"subject": _("Payment Request for {0}").format(args.dn),
"message": gateway_account.get("message") or get_dummy_message(ref_doc),
"reference_doctype": args.dt,
"reference_name": args.dn,
"party_type": args.get("party_type"),
"party": args.get("party"),
"party_type": args.get("party_type") or "Customer",
"party": args.get("party") or ref_doc.customer,
"bank_account": bank_account
})
@@ -373,6 +376,7 @@ def get_existing_payment_request_amount(ref_dt, ref_dn):
reference_doctype = %s
and reference_name = %s
and docstatus = 1
and status != 'Paid'
""", (ref_dt, ref_dn))
return flt(existing_payment_request_amount[0][0]) if existing_payment_request_amount else 0
@@ -414,17 +418,31 @@ def make_payment_entry(docname):
doc = frappe.get_doc("Payment Request", docname)
return doc.create_payment_entry(submit=False).as_dict()
def make_status_as_paid(doc, method):
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,
"docstatus": 1})
if payment_request_name:
doc = frappe.get_doc("Payment Request", payment_request_name)
if doc.status != "Paid":
doc.db_set('status', 'Paid')
frappe.db.commit()
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:
status = 'Partially Paid'
elif ref_details.outstanding_amount == ref_details.total_amount:
if pay_req_doc.payment_request_type == 'Outward':
status = 'Initiated'
elif pay_req_doc.payment_request_type == 'Inward':
status = 'Requested'
pay_req_doc.db_set('status', status)
frappe.db.commit()
def get_dummy_message(doc):
return frappe.render_template("""{% if doc.contact_person -%}
@@ -474,4 +492,4 @@ def make_payment_order(source_name, target_doc=None):
}
}, target_doc, set_missing_values)
return doclist
return doclist

View File

@@ -4,14 +4,20 @@ frappe.listview_settings['Payment Request'] = {
if(doc.status == "Draft") {
return [__("Draft"), "darkgrey", "status,=,Draft"];
}
if(doc.status == "Requested") {
return [__("Requested"), "green", "status,=,Requested"];
}
else if(doc.status == "Initiated") {
return [__("Initiated"), "green", "status,=,Initiated"];
}
else if(doc.status == "Partially Paid") {
return [__("Partially Paid"), "orange", "status,=,Partially Paid"];
}
else if(doc.status == "Paid") {
return [__("Paid"), "blue", "status,=,Paid"];
}
else if(doc.status == "Cancelled") {
return [__("Cancelled"), "orange", "status,=,Cancelled"];
return [__("Cancelled"), "red", "status,=,Cancelled"];
}
}
}

View File

@@ -101,6 +101,23 @@ class TestPaymentRequest(unittest.TestCase):
self.assertEqual(expected_gle[gle.account][2], gle.credit)
self.assertEqual(expected_gle[gle.account][3], gle.against_voucher)
def test_status(self):
si_usd = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
currency="USD", conversion_rate=50)
pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com",
mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1, return_doc=1)
pe = pr.create_payment_entry()
pr.load_from_db()
self.assertEqual(pr.status, 'Paid')
pe.cancel()
pr.load_from_db()
self.assertEqual(pr.status, 'Requested')
def test_multiple_payment_entries_against_sales_order(self):
# Make Sales Order, grand_total = 1000
so = make_sales_order()

View File

@@ -3,6 +3,7 @@
"autoname": "Prompt",
"creation": "2013-05-24 12:15:51",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"disabled",
"section_break_2",
@@ -50,6 +51,7 @@
"income_account",
"expense_account",
"taxes_and_charges",
"tax_category",
"apply_discount_on",
"accounting_dimensions_section",
"cost_center",
@@ -381,11 +383,17 @@
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
},
{
"fieldname": "tax_category",
"fieldtype": "Link",
"label": "Tax Category",
"options": "Tax Category"
}
],
"icon": "icon-cog",
"idx": 1,
"modified": "2019-05-25 22:56:30.352693",
"modified": "2020-01-24 15:52:03.797701",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",

View File

@@ -252,7 +252,7 @@ def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=Fa
if pricing_rule.price_or_product_discount == "Price":
apply_price_discount_rule(pricing_rule, item_details, args)
else:
get_product_discount_rule(pricing_rule, item_details, doc)
get_product_discount_rule(pricing_rule, item_details, args, doc)
item_details.has_pricing_rule = 1

View File

@@ -9,6 +9,8 @@ from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_orde
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.stock.get_item_details import get_item_details
from frappe import MandatoryError
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.healthcare.doctype.lab_test_template.lab_test_template import make_item_price
class TestPricingRule(unittest.TestCase):
def setUp(self):
@@ -145,6 +147,52 @@ class TestPricingRule(unittest.TestCase):
self.assertEquals(details.get("margin_type"), "Percentage")
self.assertEquals(details.get("margin_rate_or_amount"), 10)
def test_mixed_conditions_for_item_group(self):
for item in ["Mixed Cond Item 1", "Mixed Cond Item 2"]:
make_item(item, {"item_group": "Products"})
make_item_price(item, "_Test Price List", 100)
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule for Item Group",
"apply_on": "Item Group",
"item_groups": [
{
"item_group": "Products",
},
{
"item_group": "Seed",
},
],
"selling": 1,
"mixed_conditions": 1,
"currency": "USD",
"rate_or_discount": "Discount Percentage",
"discount_percentage": 10,
"applicable_for": "Customer Group",
"customer_group": "All Customer Groups",
"company": "_Test Company"
}
frappe.get_doc(test_record.copy()).insert()
args = frappe._dict({
"item_code": "Mixed Cond Item 1",
"item_group": "Products",
"company": "_Test Company",
"price_list": "_Test Price List",
"currency": "_Test Currency",
"doctype": "Sales Order",
"conversion_rate": 1,
"price_list_currency": "_Test Currency",
"plc_conversion_rate": 1,
"order_type": "Sales",
"customer": "_Test Customer",
"customer_group": "_Test Customer Group",
"name": None
})
details = get_item_details(args)
self.assertEquals(details.get("discount_percentage"), 10)
def test_pricing_rule_for_variants(self):
from erpnext.stock.get_item_details import get_item_details
from frappe import MandatoryError
@@ -278,6 +326,66 @@ class TestPricingRule(unittest.TestCase):
self.assertEquals(item.discount_amount, 110)
self.assertEquals(item.rate, 990)
def test_pricing_rule_for_product_discount_on_same_item(self):
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule",
"apply_on": "Item Code",
"currency": "USD",
"items": [{
"item_code": "_Test Item",
}],
"selling": 1,
"rate_or_discount": "Discount Percentage",
"rate": 0,
"min_qty": 0,
"max_qty": 7,
"discount_percentage": 17.5,
"price_or_product_discount": "Product",
"same_item": 1,
"free_qty": 1,
"company": "_Test Company"
}
frappe.get_doc(test_record.copy()).insert()
# With pricing rule
so = make_sales_order(item_code="_Test Item", qty=1)
so.load_from_db()
self.assertEqual(so.items[1].is_free_item, 1)
self.assertEqual(so.items[1].item_code, "_Test Item")
def test_pricing_rule_for_product_discount_on_different_item(self):
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule",
"apply_on": "Item Code",
"currency": "USD",
"items": [{
"item_code": "_Test Item",
}],
"selling": 1,
"rate_or_discount": "Discount Percentage",
"rate": 0,
"min_qty": 0,
"max_qty": 7,
"discount_percentage": 17.5,
"price_or_product_discount": "Product",
"same_item": 0,
"free_item": "_Test Item 2",
"free_qty": 1,
"company": "_Test Company"
}
frappe.get_doc(test_record.copy()).insert()
# With pricing rule
so = make_sales_order(item_code="_Test Item", qty=1)
so.load_from_db()
self.assertEqual(so.items[1].is_free_item, 1)
self.assertEqual(so.items[1].item_code, "_Test Item 2")
def make_pricing_rule(**args):
args = frappe._dict(args)

View File

@@ -178,7 +178,8 @@ def filter_pricing_rules(args, pricing_rules, doc=None):
if pricing_rules[0].mixed_conditions and doc:
stock_qty, amount, items = get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args)
pricing_rules[0].apply_rule_on_other_items = items
for pricing_rule_args in pricing_rules:
pricing_rule_args.apply_rule_on_other_items = items
elif pricing_rules[0].is_cumulative:
items = [args.get(frappe.scrub(pr_doc.get('apply_on')))]
@@ -245,7 +246,7 @@ def filter_pricing_rules(args, pricing_rules, doc=None):
def validate_quantity_and_amount_for_suggestion(args, qty, amount, item_code, transaction_type):
fieldname, msg = '', ''
type_of_transaction = 'purcahse' if transaction_type == "buying" else "sale"
type_of_transaction = 'purchase' if transaction_type == 'buying' else 'sale'
for field, value in {'min_qty': qty, 'min_amt': amount}.items():
if (args.get(field) and value < args.get(field)
@@ -329,9 +330,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")
amt = row.get('qty') * (row.get("price_list_rate") or args.get("rate"))
sum_qty += row.get("stock_qty") or args.get("stock_qty")
sum_qty += row.get("stock_qty") or args.get("stock_qty") or args.get("qty")
sum_amt += amt
if pr_doc.is_cumulative:
@@ -435,7 +436,7 @@ def apply_pricing_rule_on_transaction(doc):
doc.calculate_taxes_and_totals()
elif d.price_or_product_discount == 'Product':
item_details = frappe._dict({'parenttype': doc.doctype})
get_product_discount_rule(d, item_details, doc)
get_product_discount_rule(d, item_details, doc=doc)
apply_pricing_rule_for_free_items(doc, item_details.free_item_data)
doc.set_missing_values()
@@ -443,9 +444,10 @@ def get_applied_pricing_rules(item_row):
return (item_row.get("pricing_rules").split(',')
if item_row.get("pricing_rules") else [])
def get_product_discount_rule(pricing_rule, item_details, doc=None):
free_item = (pricing_rule.free_item
if not pricing_rule.same_item or pricing_rule.apply_on == 'Transaction' else item_details.item_code)
def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None):
free_item = pricing_rule.free_item
if pricing_rule.same_item:
free_item = item_details.item_code or args.item_code
if not free_item:
frappe.throw(_("Free item not set in the pricing rule {0}")
@@ -464,7 +466,7 @@ def get_product_discount_rule(pricing_rule, item_details, doc=None):
item_details.free_item_data.update(item_data)
item_details.free_item_data['uom'] = pricing_rule.free_item_uom or item_data.stock_uom
item_details.free_item_data['conversion_factor'] = get_conversion_factor(free_item,
item_details.free_item_data['conversion_factor'] = get_conversion_factor(free_item,
item_details.free_item_data['uom']).get("conversion_factor", 1)
if item_details.get("parenttype") == 'Purchase Order':
@@ -489,7 +491,7 @@ def get_pricing_rule_items(pr_doc):
for d in pr_doc.get(pricing_rule_apply_on):
if apply_on == 'item_group':
get_child_item_groups(d.get(apply_on))
apply_on_data.extend(get_child_item_groups(d.get(apply_on)))
else:
apply_on_data.append(d.get(apply_on))
@@ -507,7 +509,7 @@ def validate_coupon_code(coupon_name):
frappe.throw(_("Sorry,coupon code validity has not started"))
elif coupon.valid_upto:
if coupon.valid_upto < getdate(today()) :
frappe.throw(_("Sorry,coupon code validity has expired"))
frappe.throw(_("Sorry,coupon code validity has expired"))
elif coupon.used>=coupon.maximum_use:
frappe.throw(_("Sorry,coupon code are exhausted"))
else:

View File

@@ -167,8 +167,16 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
make_comment_dialog_and_block_invoice: function(){
const me = this;
const title = __('Add Comment');
const title = __('Block Invoice');
const fields = [
{
fieldname: 'release_date',
read_only: 0,
fieldtype:'Date',
label: __('Release Date'),
default: me.frm.doc.release_date,
reqd: 1
},
{
fieldname: 'hold_comment',
read_only: 0,
@@ -187,7 +195,11 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
const dialog_data = me.dialog.get_values();
frappe.call({
'method': 'erpnext.accounts.doctype.purchase_invoice.purchase_invoice.block_invoice',
'args': {'name': me.frm.doc.name, 'hold_comment': dialog_data.hold_comment},
'args': {
'name': me.frm.doc.name,
'hold_comment': dialog_data.hold_comment,
'release_date': dialog_data.release_date
},
'callback': (r) => me.frm.reload_doc()
});
me.dialog.hide();

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe, erpnext
from frappe.utils import cint, cstr, formatdate, flt, getdate, nowdate
from frappe.utils import cint, cstr, formatdate, flt, getdate, nowdate, get_link_to_form
from frappe import _, throw
import frappe.defaults
@@ -146,10 +146,14 @@ class PurchaseInvoice(BuyingController):
["account_type", "report_type", "account_currency"], as_dict=True)
if account.report_type != "Balance Sheet":
frappe.throw(_("Credit To account must be a Balance Sheet account"))
frappe.throw(_("Please ensure {} account is a Balance Sheet account. \
You can change the parent account to a Balance Sheet account or select a different account.")
.format(frappe.bold("Credit To")), title=_("Invalid Account"))
if self.supplier and account.account_type != "Payable":
frappe.throw(_("Credit To account must be a Payable account"))
frappe.throw(_("Please ensure {} account is a Payable account. \
Change the account type to Payable or select a different account.")
.format(frappe.bold("Credit To")), title=_("Invalid Account"))
self.party_account_currency = account.account_currency
@@ -255,16 +259,30 @@ class PurchaseInvoice(BuyingController):
def po_required(self):
if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes':
if frappe.get_value('Supplier', self.supplier, 'allow_purchase_invoice_creation_without_purchase_order'):
return
for d in self.get('items'):
if not d.purchase_order:
throw(_("As per the Buying Settings if Purchase Order Required == 'YES', then for creating Purchase Invoice, user need to create Purchase Order first for item {0}").format(d.item_code))
throw(_("""Purchase Order Required for item {0}
To submit the invoice without purchase order please set
{1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold(_('Purchase Order Required')),
frappe.bold('No'), get_link_to_form('Buying Settings', 'Buying Settings', 'Buying Settings')))
def pr_required(self):
stock_items = self.get_stock_items()
if frappe.db.get_value("Buying Settings", None, "pr_required") == 'Yes':
if frappe.get_value('Supplier', self.supplier, 'allow_purchase_invoice_creation_without_purchase_receipt'):
return
for d in self.get('items'):
if not d.purchase_receipt and d.item_code in stock_items:
throw(_("As per the Buying Settings if Purchase Reciept Required == 'YES', then for creating Purchase Invoice, user need to create Purchase Receipt first for item {0}").format(d.item_code))
throw(_("""Purchase Receipt Required for item {0}
To submit the invoice without purchase receipt please set
{1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold(_('Purchase Receipt Required')),
frappe.bold('No'), get_link_to_form('Buying Settings', 'Buying Settings', 'Buying Settings')))
def validate_write_off_account(self):
if self.write_off_amount and not self.write_off_account:
@@ -368,7 +386,7 @@ class PurchaseInvoice(BuyingController):
update_outstanding_amt(self.credit_to, "Supplier", self.supplier,
self.doctype, self.return_against if cint(self.is_return) and self.return_against else self.name)
if repost_future_gle and cint(self.update_stock) and self.auto_accounting_for_stock:
if (repost_future_gle or self.flags.repost_future_gle) and cint(self.update_stock) and self.auto_accounting_for_stock:
from erpnext.controllers.stock_controller import update_gl_entries_after
items, warehouses = self.get_items_and_warehouses()
update_gl_entries_after(self.posting_date, self.posting_time,
@@ -866,6 +884,7 @@ class PurchaseInvoice(BuyingController):
# because updating ordered qty in bin depends upon updated ordered qty in PO
if self.update_stock == 1:
self.update_stock_ledger()
self.delete_auto_created_batches()
self.make_gl_entries_on_cancel()
self.update_project()
@@ -927,9 +946,10 @@ class PurchaseInvoice(BuyingController):
def on_recurring(self, reference_doc, auto_repeat_doc):
self.due_date = None
def block_invoice(self, hold_comment=None):
def block_invoice(self, hold_comment=None, release_date=None):
self.db_set('on_hold', 1)
self.db_set('hold_comment', cstr(hold_comment))
self.db_set('release_date', release_date)
def unblock_invoice(self):
self.db_set('on_hold', 0)
@@ -1013,12 +1033,15 @@ def unblock_invoice(name):
@frappe.whitelist()
def block_invoice(name, hold_comment):
def block_invoice(name, release_date, hold_comment=None):
if frappe.db.exists('Purchase Invoice', name):
pi = frappe.get_doc('Purchase Invoice', name)
pi.block_invoice(hold_comment)
pi.block_invoice(hold_comment, release_date)
@frappe.whitelist()
def make_inter_company_sales_invoice(source_name, target_doc=None):
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
return make_inter_company_transaction("Purchase Invoice", source_name, target_doc)
def on_doctype_update():
frappe.db.add_index("Purchase Invoice", ["supplier", "is_return", "return_against"])

View File

@@ -198,7 +198,6 @@
"fieldtype": "Link",
"label": "UOM",
"options": "UOM",
"print_hide": 1,
"reqd": 1
},
{
@@ -754,14 +753,13 @@
{
"fieldname": "manufacturer_part_no",
"fieldtype": "Data",
"label": "Manufacturer Part Number",
"read_only": 1
"label": "Manufacturer Part Number"
},
{
"depends_on": "is_fixed_asset",
"fetch_from": "item_code.asset_category",
"fieldname": "asset_category",
"fieldtype": "Data",
"fieldtype": "Link",
"in_preview": 1,
"label": "Asset Category",
"options": "Asset Category",
@@ -771,7 +769,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2019-12-04 12:23:17.046413",
"modified": "2020-04-07 18:34:35.104178",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",

View File

@@ -152,8 +152,11 @@ def update_multi_mode_option(doc, pos_profile):
def get_mode_of_payment(doc):
return frappe.db.sql(""" select mpa.default_account, mpa.parent, mp.type as type from `tabMode of Payment Account` mpa, \
`tabMode of Payment` mp where mpa.parent = mp.name and mpa.company = %(company)s""", {'company': doc.company}, as_dict=1)
return frappe.db.sql("""
select mpa.default_account, mpa.parent, mp.type as type
from `tabMode of Payment Account` mpa,`tabMode of Payment` mp
where mpa.parent = mp.name and mpa.company = %(company)s and mp.enabled = 1""",
{'company': doc.company}, as_dict=1)
def update_tax_table(doc):
@@ -204,7 +207,7 @@ def get_customers_list(pos_profile={}):
if pos_profile.get('customer_groups'):
# Get customers based on the customer groups defined in the POS profile
for d in pos_profile.get('customer_groups'):
customer_groups.extend([d.name for d in get_child_nodes('Customer Group', d.customer_group)])
customer_groups.extend([d.get('name') for d in get_child_nodes('Customer Group', d.get('customer_group'))])
cond = "customer_group in (%s)" % (', '.join(['%s'] * len(customer_groups)))
return frappe.db.sql(""" select name, customer_name, customer_group,
@@ -384,7 +387,9 @@ def get_pricing_rule_data(doc):
@frappe.whitelist()
def make_invoice(doc_list={}, email_queue_list={}, customers_list={}):
def make_invoice(pos_profile, doc_list={}, email_queue_list={}, customers_list={}):
import json
if isinstance(doc_list, string_types):
doc_list = json.loads(doc_list)
@@ -418,7 +423,11 @@ def make_invoice(doc_list={}, email_queue_list={}, customers_list={}):
name_list.append(name)
email_queue = make_email_queue(email_queue_list)
customers = get_customers_list()
if isinstance(pos_profile, string_types):
pos_profile = json.loads(pos_profile)
customers = get_customers_list(pos_profile)
return {
'invoice': name_list,
'email_queue': email_queue,

View File

@@ -1,5 +1,4 @@
{
"actions": [],
"allow_import": 1,
"autoname": "naming_series:",
"creation": "2013-05-24 19:29:05",
@@ -373,7 +372,8 @@
"no_copy": 1,
"options": "Sales Invoice",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"search_index": 1
},
{
"fieldname": "column_break_21",
@@ -1568,8 +1568,7 @@
"icon": "fa fa-file-text",
"idx": 181,
"is_submittable": 1,
"links": [],
"modified": "2019-12-30 19:15:59.580414",
"modified": "2020-02-10 04:57:11.221180",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -413,6 +413,9 @@ class SalesInvoice(SellingController):
if pos:
self.allow_print_before_pay = pos.allow_print_before_pay
if not for_validate:
self.tax_category = pos.get("tax_category")
if not for_validate and not self.customer:
self.customer = pos.customer
@@ -426,13 +429,18 @@ class SalesInvoice(SellingController):
if (not for_validate) or (for_validate and not self.get(fieldname)):
self.set(fieldname, pos.get(fieldname))
customer_price_list = frappe.get_value("Customer", self.customer, 'default_price_list')
if pos.get("company_address"):
self.company_address = pos.get("company_address")
if not customer_price_list:
self.set('selling_price_list', pos.get('selling_price_list'))
if self.customer:
customer_price_list, customer_group = frappe.get_value("Customer", self.customer, ['default_price_list', 'customer_group'])
customer_group_price_list = frappe.get_value("Customer Group", customer_group, 'default_price_list')
selling_price_list = customer_price_list or customer_group_price_list or pos.get('selling_price_list')
else:
selling_price_list = pos.get('selling_price_list')
if selling_price_list:
self.set('selling_price_list', selling_price_list)
if not for_validate:
self.update_stock = cint(pos.get("update_stock"))
@@ -463,13 +471,17 @@ class SalesInvoice(SellingController):
["account_type", "report_type", "account_currency"], as_dict=True)
if not account:
frappe.throw(_("Debit To is required"))
frappe.throw(_("Debit To is required"), title=_("Account Missing"))
if account.report_type != "Balance Sheet":
frappe.throw(_("Debit To account must be a Balance Sheet account"))
frappe.throw(_("Please ensure {} account is a Balance Sheet account. \
You can change the parent account to a Balance Sheet account or select a different account.")
.format(frappe.bold("Debit To")), title=_("Invalid Account"))
if self.customer and account.account_type != "Receivable":
frappe.throw(_("Debit To account must be a Receivable account"))
frappe.throw(_("Please ensure {} account is a Receivable account. \
Change the account type to Receivable or select a different account.")
.format(frappe.bold("Debit To")), title=_("Invalid Account"))
self.party_account_currency = account.account_currency
@@ -531,14 +543,18 @@ class SalesInvoice(SellingController):
"""check in manage account if sales order / delivery note required or not."""
if self.is_return:
return
dic = {'Sales Order':['so_required', 'is_pos'],'Delivery Note':['dn_required', 'update_stock']}
for i in dic:
if frappe.db.get_single_value('Selling Settings', dic[i][0]) == 'Yes':
prev_doc_field_map = {'Sales Order': ['so_required', 'is_pos'],'Delivery Note': ['dn_required', 'update_stock']}
for key, value in iteritems(prev_doc_field_map):
if frappe.db.get_single_value('Selling Settings', value[0]) == 'Yes':
if frappe.get_value('Customer', self.customer, value[0]):
continue
for d in self.get('items'):
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(i.lower().replace(' ','_')) and not self.get(dic[i][1])):
msgprint(_("{0} is mandatory for Item {1}").format(i,d.item_code), raise_exception=1)
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)
def validate_proj_cust(self):
@@ -714,7 +730,7 @@ class SalesInvoice(SellingController):
update_outstanding_amt(self.debit_to, "Customer", self.customer,
self.doctype, self.return_against if cint(self.is_return) and self.return_against else self.name)
if repost_future_gle and cint(self.update_stock) \
if (repost_future_gle or self.flags.repost_future_gle) and cint(self.update_stock) \
and cint(auto_accounting_for_stock):
items, warehouses = self.get_items_and_warehouses()
update_gl_entries_after(self.posting_date, self.posting_time,
@@ -1208,48 +1224,39 @@ class SalesInvoice(SellingController):
self.set_missing_values(for_validate = True)
def get_discounting_status(self):
status = None
if self.is_discounted:
invoice_discounting_list = frappe.db.sql("""
select status
from `tabInvoice Discounting` id, `tabDiscounted Invoice` d
where
id.name = d.parent
and d.sales_invoice=%s
and id.docstatus=1
and status in ('Disbursed', 'Settled')
""", self.name)
for d in invoice_discounting_list:
status = d[0]
if status == "Disbursed":
break
return status
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()
discounting_status = None
if self.is_discounted:
discountng_status = get_discounting_status(self.name)
if not status:
if self.docstatus == 2:
status = "Cancelled"
elif self.docstatus == 1:
if flt(self.outstanding_amount) > 0 and getdate(self.due_date) < getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed':
if outstanding_amount > 0 and due_date < nowdate and self.is_discounted and discountng_status=='Disbursed':
self.status = "Overdue and Discounted"
elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) < getdate(nowdate()):
elif outstanding_amount > 0 and due_date < nowdate:
self.status = "Overdue"
elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed':
elif outstanding_amount > 0 and due_date >= nowdate and self.is_discounted and discountng_status=='Disbursed':
self.status = "Unpaid and Discounted"
elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) >= getdate(nowdate()):
elif outstanding_amount > 0 and due_date >= nowdate:
self.status = "Unpaid"
#Check if outstanding amount is 0 due to credit note issued against invoice
elif flt(self.outstanding_amount) <= 0 and self.is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
elif outstanding_amount <= 0 and self.is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
self.status = "Credit Note Issued"
elif self.is_return == 1:
self.status = "Return"
elif flt(self.outstanding_amount)<=0:
elif outstanding_amount<=0:
self.status = "Paid"
else:
self.status = "Submitted"
@@ -1259,6 +1266,26 @@ class SalesInvoice(SellingController):
if update:
self.db_set('status', self.status, update_modified = update_modified)
def get_discounting_status(sales_invoice):
status = None
invoice_discounting_list = frappe.db.sql("""
select status
from `tabInvoice Discounting` id, `tabDiscounted Invoice` d
where
id.name = d.parent
and d.sales_invoice=%s
and id.docstatus=1
and status in ('Disbursed', 'Settled')
""", sales_invoice)
for d in invoice_discounting_list:
status = d[0]
if status == "Disbursed":
break
return status
def validate_inter_company_party(doctype, party, company, inter_company_reference):
if not party:
return
@@ -1426,6 +1453,21 @@ def get_inter_company_details(doc, doctype):
"company": company
}
def get_internal_party(parties, link_doctype, doc):
if len(parties) == 1:
party = parties[0].name
else:
# If more than one Internal Supplier/Customer, get supplier/customer on basis of address
if doc.get('company_address') or doc.get('shipping_address'):
party = frappe.db.get_value("Dynamic Link", {"parent": doc.get('company_address') or doc.get('shipping_address'),
"parenttype": "Address", "link_doctype": link_doctype}, "link_name")
if not party:
party = parties[0].name
else:
party = parties[0].name
return party
def validate_inter_company_transaction(doc, doctype):
@@ -1514,6 +1556,9 @@ def get_loyalty_programs(customer):
else:
return lp_details
def on_doctype_update():
frappe.db.add_index("Sales Invoice", ["customer", "is_return", "return_against"])
@frappe.whitelist()
def create_invoice_discounting(source_name, target_doc=None):
invoice = frappe.get_doc("Sales Invoice", source_name)

View File

@@ -728,7 +728,7 @@ class TestSalesInvoice(unittest.TestCase):
def test_make_pos_invoice(self):
from erpnext.accounts.doctype.sales_invoice.pos import make_invoice
make_pos_profile()
pos_profile = make_pos_profile()
pr = make_purchase_receipt(company= "_Test Company with perpetual inventory",supplier_warehouse= "Work In Progress - TCP1", item_code= "_Test FG Item",warehouse= "Stores - TCP1",cost_center= "Main - TCP1")
pos = create_sales_invoice(company= "_Test Company with perpetual inventory", debit_to="Debtors - TCP1", item_code= "_Test FG Item", warehouse="Stores - TCP1", income_account = "Sales - TCP1", expense_account = "Cost of Goods Sold - TCP1", cost_center = "Main - TCP1", do_not_save=True)
@@ -744,7 +744,7 @@ class TestSalesInvoice(unittest.TestCase):
pos.append("taxes", tax)
invoice_data = [{'09052016142': pos}]
si = make_invoice(invoice_data).get('invoice')
si = make_invoice(pos_profile, invoice_data).get('invoice')
self.assertEqual(si[0], '09052016142')
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': '09052016142', 'docstatus': 1})
@@ -762,7 +762,7 @@ class TestSalesInvoice(unittest.TestCase):
if allow_negative_stock:
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 0)
make_pos_profile()
pos_profile = make_pos_profile()
timestamp = cint(time.time())
item = make_item("_Test POS Item")
@@ -776,7 +776,7 @@ class TestSalesInvoice(unittest.TestCase):
{'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 330}]
invoice_data = [{timestamp: pos}]
si = make_invoice(invoice_data).get('invoice')
si = make_invoice(pos_profile, invoice_data).get('invoice')
self.assertEqual(si[0], timestamp)
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
@@ -785,7 +785,7 @@ class TestSalesInvoice(unittest.TestCase):
timestamp = cint(time.time())
pos["offline_pos_name"] = timestamp
invoice_data = [{timestamp: pos}]
si1 = make_invoice(invoice_data).get('invoice')
si1 = make_invoice(pos_profile, invoice_data).get('invoice')
self.assertEqual(si1[0], timestamp)
sales_invoice1 = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
@@ -1890,7 +1890,7 @@ def create_sales_invoice(**args):
"gst_hsn_code": "999800",
"warehouse": args.warehouse or "_Test Warehouse - _TC",
"qty": args.qty or 1,
"rate": args.rate or 100,
"rate": args.rate if args.get("rate") is not None else 100,
"income_account": args.income_account or "Sales - _TC",
"expense_account": args.expense_account or "Cost of Goods Sold - _TC",
"cost_center": args.cost_center or "_Test Cost Center - _TC",

View File

@@ -82,7 +82,7 @@ class ShippingRule(Document):
if not shipping_country:
frappe.throw(_('Shipping Address does not have country, which is required for this Shipping Rule'))
if shipping_country not in [d.country for d in self.countries]:
frappe.throw(_('Shipping rule not applicable for country {0}'.format(shipping_country)))
frappe.throw(_('Shipping rule not applicable for country {0} in Shipping Address').format(shipping_country))
def add_shipping_rule_to_tax_table(self, doc, shipping_amount):
shipping_charge = {

View File

@@ -1,4 +1,5 @@
{
"actions": [],
"autoname": "ACC-SUB-.YYYY.-.#####",
"creation": "2017-07-18 17:50:43.967266",
"doctype": "DocType",
@@ -155,7 +156,7 @@
"fieldname": "apply_additional_discount",
"fieldtype": "Select",
"label": "Apply Additional Discount On",
"options": "\nGrand Total\nNet total"
"options": "\nGrand Total\nNet Total"
},
{
"fieldname": "cb_2",
@@ -196,7 +197,8 @@
"fieldtype": "Column Break"
}
],
"modified": "2019-07-25 18:45:38.579579",
"links": [],
"modified": "2020-01-27 14:37:32.845173",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Subscription",

View File

@@ -280,7 +280,7 @@ class Subscription(Document):
if self.additional_discount_percentage or self.additional_discount_amount:
discount_on = self.apply_additional_discount
invoice.apply_additional_discount = discount_on if discount_on else 'Grand Total'
invoice.apply_discount_on = discount_on if discount_on else 'Grand Total'
# Subscription period
invoice.from_date = self.current_invoice_start

View File

@@ -57,7 +57,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2020-01-15 17:14:28.951793",
"modified": "2020-01-15 17:14:28.951793",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Tax Category",

View File

@@ -136,12 +136,14 @@ def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
def make_entry(args, adv_adj, update_outstanding, from_repost=False):
args.update({"doctype": "GL Entry"})
gle = frappe.get_doc(args)
gle = frappe.new_doc("GL Entry")
gle.update(args)
gle.flags.ignore_permissions = 1
gle.flags.from_repost = from_repost
gle.insert()
gle.validate()
gle.db_insert()
gle.run_method("on_update_with_args", adv_adj, update_outstanding, from_repost)
gle.flags.ignore_validate = True
gle.submit()
def validate_account_for_perpetual_inventory(gl_map):

View File

@@ -1769,6 +1769,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
freeze: true,
args: {
pos_profile: me.pos_profile_data,
doc_list: me.si_docs,
email_queue_list: me.email_queue_list,
customers_list: me.customers_list

View File

@@ -163,8 +163,9 @@ 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 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]
elif pos and party_type == 'Customer':
customer_price_list = frappe.get_value('Customer', party.name, 'default_price_list')

View File

@@ -100,6 +100,11 @@ frappe.query_reports["Accounts Payable"] = {
"fieldtype": "Link",
"options": "Supplier Group"
},
{
"fieldname": "group_by_party",
"label": __("Group By Supplier"),
"fieldtype": "Check"
},
{
"fieldname":"based_on_payment_terms",
"label": __("Based On Payment Terms"),
@@ -112,6 +117,16 @@ frappe.query_reports["Accounts Payable"] = {
"hidden": 1
}
],
"formatter": function(value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
if (data && data.bold) {
value = value.bold();
}
return value;
},
onload: function(report) {
report.page.add_inner_button(__("Accounts Payable Summary"), function() {
var filters = report.get_values();

View File

@@ -218,15 +218,15 @@
<td></td>
<td style="text-align: right"><b>{%= __("Total") %}</b></td>
<td style="text-align: right">
{%= format_currency(data[i]["invoiced"], data[i]["currency"] ) %}</td>
{%= format_currency(data[i]["invoiced"], data[0]["currency"] ) %}</td>
{% if(!filters.show_future_payments) { %}
<td style="text-align: right">
{%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} </td>
{%= format_currency(data[i]["paid"], data[0]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[0]["currency"]) %} </td>
{% } %}
<td style="text-align: right">
{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td>
{%= format_currency(data[i]["outstanding"], data[0]["currency"]) %}</td>
{% if(filters.show_future_payments) { %}
{% if(report.report_name === "Accounts Receivable") { %}
@@ -234,8 +234,8 @@
{%= data[i]["po_no"] %}</td>
{% } %}
<td style="text-align: right">{%= data[i]["future_ref"] %}</td>
<td style="text-align: right">{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["future_amount"], data[0]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["remaining_balance"], data[0]["currency"]) %}</td>
{% } %}
{% } %}
{% } else { %}
@@ -256,10 +256,10 @@
{% } else { %}
<td><b>{%= __("Total") %}</b></td>
{% } %}
<td style="text-align: right">{%= format_currency(data[i]["invoiced"], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["invoiced"], data[0]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["paid"], data[0]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[0]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["outstanding"], data[0]["currency"]) %}</td>
{% } %}
{% } %}
</tr>

View File

@@ -87,7 +87,7 @@ frappe.query_reports["Accounts Receivable"] = {
frappe.query_report.set_filter_value('payment_terms', value["payment_terms"]);
});
frappe.db.get_value('Customer Credit Limit', {'parent': customer, 'company': company},
frappe.db.get_value('Customer Credit Limit', {'parent': customer, 'company': company},
["credit_limit"], function(value) {
if (value) {
frappe.query_report.set_filter_value('credit_limit', value["credit_limit"]);
@@ -131,6 +131,11 @@ frappe.query_reports["Accounts Receivable"] = {
"fieldtype": "Link",
"options": "Sales Person"
},
{
"fieldname": "group_by_party",
"label": __("Group By Customer"),
"fieldtype": "Check"
},
{
"fieldname":"based_on_payment_terms",
"label": __("Based On Payment Terms"),
@@ -177,6 +182,15 @@ frappe.query_reports["Accounts Receivable"] = {
}
],
"formatter": function(value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
if (data && data.bold) {
value = value.bold();
}
return value;
},
onload: function(report) {
report.page.add_inner_button(__("Accounts Receivable Summary"), function() {
var filters = report.get_values();

View File

@@ -7,7 +7,7 @@ from frappe import _, scrub
from frappe.utils import getdate, nowdate, flt, cint, formatdate, cstr, now, time_diff_in_seconds
from collections import OrderedDict
from erpnext.accounts.utils import get_currency_precision
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
# This report gives a summary of all Outstanding Invoices considering the following
@@ -46,7 +46,7 @@ class ReceivablePayableReport(object):
self.get_columns()
self.get_data()
self.get_chart_data()
return self.columns, self.data, None, self.chart
return self.columns, self.data, None, self.chart, None, self.skip_total_row
def set_defaults(self):
if not self.filters.get("company"):
@@ -57,6 +57,12 @@ class ReceivablePayableReport(object):
self.party_type = self.filters.party_type
self.party_details = {}
self.invoices = set()
self.skip_total_row = 0
if self.filters.get('group_by_party'):
self.previous_party=''
self.total_row_map = {}
self.skip_total_row = 1
def get_data(self):
self.get_gl_entries()
@@ -102,6 +108,12 @@ class ReceivablePayableReport(object):
)
self.get_invoices(gle)
if self.filters.get('group_by_party'):
self.init_subtotal_row(gle.party)
if self.filters.get('group_by_party'):
self.init_subtotal_row('Total')
def get_invoices(self, gle):
if gle.voucher_type in ('Sales Invoice', 'Purchase Invoice'):
if self.filters.get("sales_person"):
@@ -111,6 +123,20 @@ class ReceivablePayableReport(object):
else:
self.invoices.add(gle.voucher_no)
def init_subtotal_row(self, party):
if not self.total_row_map.get(party):
self.total_row_map.setdefault(party, {
'party': party,
'bold': 1
})
for field in self.get_currency_fields():
self.total_row_map[party][field] = 0.0
def get_currency_fields(self):
return ['invoiced', 'paid', 'credit_note', 'outstanding', 'range1',
'range2', 'range3', 'range4', 'range5']
def update_voucher_balance(self, gle):
# get the row where this balance needs to be updated
# if its a payment, it will return the linked invoice or will be considered as advance
@@ -135,6 +161,18 @@ class ReceivablePayableReport(object):
# advance / unlinked payment or other adjustment
row.paid -= gle_balance
def update_sub_total_row(self, row, party):
total_row = self.total_row_map.get(party)
for field in self.get_currency_fields():
total_row[field] += row.get(field, 0.0)
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')
def get_voucher_balance(self, gle):
if self.filters.get("sales_person"):
against_voucher = gle.against_voucher or gle.voucher_no
@@ -192,11 +230,22 @@ class ReceivablePayableReport(object):
else:
self.append_row(row)
if self.filters.get('group_by_party'):
self.append_subtotal_row(self.previous_party)
self.data.append(self.total_row_map.get('Total'))
def append_row(self, row):
self.allocate_future_payments(row)
self.set_invoice_details(row)
self.set_party_details(row)
self.set_ageing(row)
if self.filters.get('group_by_party'):
self.update_sub_total_row(row, row.party)
if self.previous_party and (self.previous_party != row.party):
self.append_subtotal_row(self.previous_party)
self.previous_party = row.party
self.data.append(row)
def set_invoice_details(self, row):
@@ -503,6 +552,7 @@ class ReceivablePayableReport(object):
# get all the GL entries filtered by the given filters
conditions, values = self.prepare_conditions()
order_by = self.get_order_by_condition()
if self.filters.get(scrub(self.party_type)):
select_fields = "debit_in_account_currency as debit, credit_in_account_currency as credit"
@@ -520,9 +570,8 @@ class ReceivablePayableReport(object):
and party_type=%s
and (party is not null and party != '')
and posting_date <= %s
{1}
order by posting_date, party"""
.format(select_fields, conditions), values, as_dict=True)
{1} {2}"""
.format(select_fields, conditions, order_by), values, as_dict=True)
def get_sales_invoices_or_customers_based_on_sales_person(self):
if self.filters.get("sales_person"):
@@ -554,9 +603,14 @@ class ReceivablePayableReport(object):
self.add_supplier_filters(conditions, values)
self.add_accounting_dimensions_filters(conditions, values)
return " and ".join(conditions), values
def get_order_by_condition(self):
if self.filters.get('group_by_party'):
return "order by party, posting_date"
else:
return "order by posting_date, party"
def add_common_filters(self, conditions, values, party_type_field):
if self.filters.company:
conditions.append("company=%s")
@@ -611,13 +665,16 @@ class ReceivablePayableReport(object):
doctype=doctype, lft=lft, rgt=rgt, key=key)
def add_accounting_dimensions_filters(self, conditions, values):
accounting_dimensions = get_accounting_dimensions()
accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions:
for dimension in accounting_dimensions:
if self.filters.get(dimension):
conditions.append("{0} = %s".format(dimension))
values.append(self.filters.get(dimension))
if self.filters.get(dimension.fieldname):
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
self.filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
self.filters.get(dimension.fieldname))
conditions.append("{0} in %s".format(dimension.fieldname))
values.append(tuple(self.filters.get(dimension.fieldname)))
def get_gle_balance(self, gle):
# get the balance of the GL (debit - credit) or reverse balance based on report type
@@ -736,11 +793,13 @@ class ReceivablePayableReport(object):
def get_chart_data(self):
rows = []
for row in self.data:
values = [row.range1, row.range2, row.range3, row.range4, row.range5]
precision = cint(frappe.db.get_default("float_precision")) or 2
rows.append({
'values': [flt(val, precision) for val in values]
})
row = frappe._dict(row)
if not cint(row.bold):
values = [row.range1, row.range2, row.range3, row.range4, row.range5]
precision = cint(frappe.db.get_default("float_precision")) or 2
rows.append({
'values': [flt(val, precision) for val in values]
})
self.chart = {
"data": {

View File

@@ -4,126 +4,137 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import formatdate, getdate, flt, add_days
from frappe.utils import formatdate, flt, add_days
def execute(filters=None):
filters.day_before_from_date = add_days(filters.from_date, -1)
columns, data = get_columns(filters), get_data(filters)
return columns, data
def get_data(filters):
data = []
asset_categories = get_asset_categories(filters)
assets = get_assets(filters)
asset_costs = get_asset_costs(assets, filters)
asset_depreciations = get_accumulated_depreciations(assets, filters)
for asset_category in asset_categories:
row = frappe._dict()
row.asset_category = asset_category
row.update(asset_costs.get(asset_category))
# row.asset_category = asset_category
row.update(asset_category)
row.cost_as_on_to_date = (flt(row.cost_as_on_from_date) + flt(row.cost_of_new_purchase) -
flt(row.cost_of_sold_asset) - flt(row.cost_of_scrapped_asset))
row.update(next(asset for asset in assets if asset["asset_category"] == asset_category.get("asset_category", "")))
row.accumulated_depreciation_as_on_to_date = (flt(row.accumulated_depreciation_as_on_from_date) +
flt(row.depreciation_amount_during_the_period) - flt(row.depreciation_eliminated_during_the_period))
row.net_asset_value_as_on_from_date = (flt(row.cost_as_on_from_date) -
flt(row.accumulated_depreciation_as_on_from_date))
row.net_asset_value_as_on_to_date = (flt(row.cost_as_on_to_date) -
flt(row.accumulated_depreciation_as_on_to_date))
row.cost_as_on_to_date = (flt(row.cost_as_on_from_date) + flt(row.cost_of_new_purchase)
- flt(row.cost_of_sold_asset) - flt(row.cost_of_scrapped_asset))
row.update(asset_depreciations.get(asset_category))
row.accumulated_depreciation_as_on_to_date = (flt(row.accumulated_depreciation_as_on_from_date) +
flt(row.depreciation_amount_during_the_period) - flt(row.depreciation_eliminated))
row.net_asset_value_as_on_from_date = (flt(row.cost_as_on_from_date) -
flt(row.accumulated_depreciation_as_on_from_date))
row.net_asset_value_as_on_to_date = (flt(row.cost_as_on_to_date) -
flt(row.accumulated_depreciation_as_on_to_date))
data.append(row)
return data
def get_asset_categories(filters):
return frappe.db.sql_list("""
select distinct asset_category from `tabAsset`
where docstatus=1 and company=%s and purchase_date <= %s
""", (filters.company, filters.to_date))
return frappe.db.sql("""
SELECT asset_category,
ifnull(sum(case when purchase_date < %(from_date)s then
case when ifnull(disposal_date, 0) = 0 or disposal_date >= %(from_date)s then
gross_purchase_amount
else
0
end
else
0
end), 0) as cost_as_on_from_date,
ifnull(sum(case when purchase_date >= %(from_date)s then
gross_purchase_amount
else
0
end), 0) as cost_of_new_purchase,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Sold" then
gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_sold_asset,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Scrapped" then
gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_scrapped_asset
from `tabAsset`
where docstatus=1 and company=%(company)s and purchase_date <= %(to_date)s
group by asset_category
""", {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1)
def get_assets(filters):
return frappe.db.sql("""
select name, asset_category, purchase_date, gross_purchase_amount, disposal_date, status
from `tabAsset`
where docstatus=1 and company=%s and purchase_date <= %s""",
(filters.company, filters.to_date), as_dict=1)
def get_asset_costs(assets, filters):
asset_costs = frappe._dict()
for d in assets:
asset_costs.setdefault(d.asset_category, frappe._dict({
"cost_as_on_from_date": 0,
"cost_of_new_purchase": 0,
"cost_of_sold_asset": 0,
"cost_of_scrapped_asset": 0
}))
costs = asset_costs[d.asset_category]
if getdate(d.purchase_date) < getdate(filters.from_date):
if not d.disposal_date or getdate(d.disposal_date) >= getdate(filters.from_date):
costs.cost_as_on_from_date += flt(d.gross_purchase_amount)
else:
costs.cost_of_new_purchase += flt(d.gross_purchase_amount)
if d.disposal_date and getdate(d.disposal_date) >= getdate(filters.from_date) \
and getdate(d.disposal_date) <= getdate(filters.to_date):
if d.status == "Sold":
costs.cost_of_sold_asset += flt(d.gross_purchase_amount)
elif d.status == "Scrapped":
costs.cost_of_scrapped_asset += flt(d.gross_purchase_amount)
return asset_costs
def get_accumulated_depreciations(assets, filters):
asset_depreciations = frappe._dict()
for d in assets:
asset = frappe.get_doc("Asset", d.name)
if d.asset_category in asset_depreciations:
asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] += asset.opening_accumulated_depreciation
else:
asset_depreciations.setdefault(d.asset_category, frappe._dict({
"accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
"depreciation_amount_during_the_period": 0,
"depreciation_eliminated_during_the_period": 0
}))
SELECT results.asset_category,
sum(results.accumulated_depreciation_as_on_from_date) as accumulated_depreciation_as_on_from_date,
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
ds.depreciation_amount
else
0
end), 0) as accumulated_depreciation_as_on_from_date,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s and ds.schedule_date <= a.disposal_date then
ds.depreciation_amount
else
0
end), 0) as depreciation_eliminated_during_the_period,
ifnull(sum(case when ds.schedule_date >= %(from_date)s and ds.schedule_date <= %(to_date)s
and (ifnull(a.disposal_date, 0) = 0 or ds.schedule_date <= a.disposal_date) then
ds.depreciation_amount
else
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
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
0
else
a.opening_accumulated_depreciation
end), 0) as accumulated_depreciation_as_on_from_date,
ifnull(sum(case when a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then
a.opening_accumulated_depreciation
else
0
end), 0) as depreciation_eliminated_during_the_period,
0 as depreciation_amount_during_the_period
from `tabAsset` a
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s
group by a.asset_category) as results
group by results.asset_category
""", {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1)
depr = asset_depreciations[d.asset_category]
if not asset.schedules: # if no schedule,
if asset.disposal_date:
# and disposal is NOT within the period, then opening accumulated depreciation not included
if getdate(asset.disposal_date) < getdate(filters.from_date) or getdate(asset.disposal_date) > getdate(filters.to_date):
asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] = 0
# if no schedule, and disposal is within period, accumulated dep is the amount eliminated
if getdate(asset.disposal_date) >= getdate(filters.from_date) and getdate(asset.disposal_date) <= getdate(filters.to_date):
depr.depreciation_eliminated_during_the_period += asset.opening_accumulated_depreciation
for schedule in asset.get("schedules"):
if getdate(schedule.schedule_date) < getdate(filters.from_date):
if not asset.disposal_date or getdate(asset.disposal_date) >= getdate(filters.from_date):
depr.accumulated_depreciation_as_on_from_date += flt(schedule.depreciation_amount)
elif getdate(schedule.schedule_date) <= getdate(filters.to_date):
if not asset.disposal_date:
depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)
else:
if getdate(schedule.schedule_date) <= getdate(asset.disposal_date):
depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)
if asset.disposal_date and getdate(asset.disposal_date) >= getdate(filters.from_date) and getdate(asset.disposal_date) <= getdate(filters.to_date):
if getdate(schedule.schedule_date) <= getdate(asset.disposal_date):
depr.depreciation_eliminated_during_the_period += flt(schedule.depreciation_amount)
return asset_depreciations
def get_columns(filters):
return [
{

View File

@@ -14,6 +14,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
frappe.query_reports["Balance Sheet"]["filters"].push({
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check"
"fieldtype": "Check",
"default": 1
});
});

View File

@@ -20,7 +20,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check"
"fieldtype": "Check",
"default": 1
}
);
});

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import cint
from frappe.utils import cint, cstr
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import get_net_profit_loss
from erpnext.accounts.utils import get_fiscal_year
@@ -129,13 +129,13 @@ def get_account_type_based_gl_data(company, start_date, end_date, account_type,
cond = ""
filters = frappe._dict(filters)
if filters.finance_book:
cond = " and finance_book = %s" %(frappe.db.escape(filters.finance_book))
if filters.include_default_book_entries:
company_fb = frappe.db.get_value("Company", company, 'default_finance_book')
if filters.include_default_book_entries:
company_fb = frappe.db.get_value("Company", company, 'default_finance_book')
cond = """ AND (finance_book in (%s, %s, '') OR finance_book IS NULL)
""" %(frappe.db.escape(filters.finance_book), frappe.db.escape(company_fb))
else:
cond = " AND (finance_book in (%s, '') OR finance_book IS NULL)" %(frappe.db.escape(cstr(filters.finance_book)))
cond = """ and finance_book in (%s, %s)
""" %(frappe.db.escape(filters.finance_book), frappe.db.escape(company_fb))
gl_sum = frappe.db.sql_list("""
select sum(credit) - sum(debit)

View File

@@ -58,7 +58,8 @@ frappe.query_reports["Consolidated Financial Statement"] = {
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check"
"fieldtype": "Check",
"default": 1
}
]
}

View File

@@ -387,11 +387,10 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
if from_date:
additional_conditions.append("gl.posting_date >= %(from_date)s")
if filters.get("finance_book"):
if filters.get("include_default_book_entries"):
additional_conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
else:
additional_conditions.append("finance_book in (%(finance_book)s)")
if filters.get("include_default_book_entries"):
additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)")
else:
additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)")
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""

View File

@@ -13,10 +13,10 @@ import frappe, erpnext
from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
from erpnext.accounts.utils import get_fiscal_year
from frappe import _
from frappe.utils import (flt, getdate, get_first_day, add_months, add_days, formatdate)
from frappe.utils import (flt, getdate, get_first_day, add_months, add_days, formatdate, cstr)
from six import itervalues
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
company=None, reset_period_on_fy_change=True):
@@ -348,46 +348,48 @@ def set_gl_entries_by_account(
additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters)
accounts = frappe.db.sql_list("""select name from `tabAccount`
where lft >= %s and rgt <= %s""", (root_lft, root_rgt))
additional_conditions += " and account in ({})"\
.format(", ".join([frappe.db.escape(d) for d in accounts]))
where lft >= %s and rgt <= %s and company = %s""", (root_lft, root_rgt, company))
gl_filters = {
"company": company,
"from_date": from_date,
"to_date": to_date,
"finance_book": filters.get("finance_book")
}
if accounts:
additional_conditions += " and account in ({})"\
.format(", ".join([frappe.db.escape(d) for d in accounts]))
if filters.get("include_default_book_entries"):
gl_filters["company_fb"] = frappe.db.get_value("Company",
company, 'default_finance_book')
gl_filters = {
"company": company,
"from_date": from_date,
"to_date": to_date,
"finance_book": cstr(filters.get("finance_book"))
}
for key, value in filters.items():
if value:
gl_filters.update({
key: value
})
if filters.get("include_default_book_entries"):
gl_filters["company_fb"] = frappe.db.get_value("Company",
company, 'default_finance_book')
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year, debit_in_account_currency, credit_in_account_currency, account_currency from `tabGL Entry`
where company=%(company)s
{additional_conditions}
and posting_date <= %(to_date)s
order by account, posting_date""".format(additional_conditions=additional_conditions), gl_filters, as_dict=True) #nosec
for key, value in filters.items():
if value:
gl_filters.update({
key: value
})
if filters and filters.get('presentation_currency'):
convert_to_presentation_currency(gl_entries, get_currency(filters))
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year, debit_in_account_currency, credit_in_account_currency, account_currency from `tabGL Entry`
where company=%(company)s
{additional_conditions}
and posting_date <= %(to_date)s
order by account, posting_date""".format(additional_conditions=additional_conditions), gl_filters, as_dict=True) #nosec
for entry in gl_entries:
gl_entries_by_account.setdefault(entry.account, []).append(entry)
if filters and filters.get('presentation_currency'):
convert_to_presentation_currency(gl_entries, get_currency(filters))
return gl_entries_by_account
for entry in gl_entries:
gl_entries_by_account.setdefault(entry.account, []).append(entry)
return gl_entries_by_account
def get_additional_conditions(from_date, ignore_closing_entries, filters):
additional_conditions = []
accounting_dimensions = get_accounting_dimensions()
accounting_dimensions = get_accounting_dimensions(as_list=False)
if ignore_closing_entries:
additional_conditions.append("ifnull(voucher_type, '')!='Period Closing Voucher'")
@@ -406,16 +408,20 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
filters.cost_center = get_cost_centers_with_children(filters.cost_center)
additional_conditions.append("cost_center in %(cost_center)s")
if filters.get("finance_book"):
if filters.get("include_default_book_entries"):
additional_conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
else:
additional_conditions.append("finance_book in (%(finance_book)s)")
if filters.get("include_default_book_entries"):
additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)")
else:
additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)")
if accounting_dimensions:
for dimension in accounting_dimensions:
if filters.get(dimension):
additional_conditions.append("{0} in (%({0})s)".format(dimension))
if filters.get(dimension.fieldname):
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
additional_conditions.append("{0} in %({0})s".format(dimension.fieldname))
else:
additional_conditions.append("{0} in (%({0})s)".format(dimension.fieldname))
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""

View File

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

View File

@@ -154,7 +154,8 @@ frappe.query_reports["General Ledger"] = {
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check"
"fieldtype": "Check",
"default": 1
}
]
}

View File

@@ -10,7 +10,7 @@ from frappe import _, _dict
from erpnext.accounts.utils import get_account_currency
from erpnext.accounts.report.financial_statements import get_cost_centers_with_children
from six import iteritems
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
from collections import OrderedDict
def execute(filters=None):
@@ -119,7 +119,7 @@ def get_gl_entries(filters):
select_fields = """, debit, credit, debit_in_account_currency,
credit_in_account_currency """
order_by_statement = "order by posting_date, account"
order_by_statement = "order by posting_date, account, creation"
if filters.get("group_by") == _("Group by Voucher"):
order_by_statement = "order by posting_date, voucher_type, voucher_no"
@@ -131,7 +131,7 @@ def get_gl_entries(filters):
gl_entries = frappe.db.sql(
"""
select
posting_date, account, party_type, party,
name as gl_entry, posting_date, account, party_type, party,
voucher_type, voucher_no, cost_center, project,
against_voucher_type, against_voucher, account_currency,
remarks, against, is_opening {select_fields}
@@ -184,7 +184,7 @@ def get_conditions(filters):
if filters.get("finance_book"):
if filters.get("include_default_book_entries"):
conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)")
else:
conditions.append("finance_book in (%(finance_book)s)")
@@ -194,12 +194,17 @@ def get_conditions(filters):
if match_conditions:
conditions.append(match_conditions)
accounting_dimensions = get_accounting_dimensions()
accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions:
for dimension in accounting_dimensions:
if filters.get(dimension):
conditions.append("{0} in (%({0})s)".format(dimension))
if filters.get(dimension.fieldname):
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
conditions.append("{0} in %({0})s".format(dimension.fieldname))
else:
conditions.append("{0} in (%({0})s)".format(dimension.fieldname))
return "and {}".format(" and ".join(conditions)) if conditions else ""
@@ -359,6 +364,12 @@ def get_columns(filters):
currency = get_company_currency(company)
columns = [
{
"fieldname": "gl_entry",
"fieldtype": "Link",
"options": "GL Entry",
"hidden": 1
},
{
"label": _("Posting Date"),
"fieldname": "posting_date",

View File

@@ -34,6 +34,20 @@ frappe.query_reports["Item-wise Purchase Register"] = {
"label": __("Mode of Payment"),
"fieldtype": "Link",
"options": "Mode of Payment"
},
{
"label": __("Group By"),
"fieldname": "group_by",
"fieldtype": "Select",
"options": ["Supplier", "Item Group", "Item", "Invoice"]
}
]
],
"formatter": function(value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
if (data && data.bold) {
value = value.bold();
}
return value;
}
}

View File

@@ -5,7 +5,9 @@ from __future__ import unicode_literals
import frappe, erpnext
from frappe import _
from frappe.utils import flt
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import get_tax_accounts
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import (get_tax_accounts,
get_grand_total, add_total_row, get_display_value, get_group_by_and_display_fields, add_sub_total_row,
get_group_by_conditions)
def execute(filters=None):
return _execute(filters)
@@ -13,7 +15,7 @@ def execute(filters=None):
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = {}
filters.update({"from_date": filters.get("date_range")[0], "to_date": filters.get("date_range")[1]})
columns = get_columns(additional_table_columns)
columns = get_columns(additional_table_columns, filters)
company_currency = erpnext.get_company_currency(filters.company)
@@ -23,16 +25,16 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency,
doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges")
columns.append({
"fieldname": "currency",
"label": _("Currency"),
"fieldtype": "Data",
"width": 80
})
po_pr_map = get_purchase_receipts_against_purchase_order(item_list)
data = []
total_row_map = {}
skip_total_row = 0
prev_group_by_value = ''
if filters.get('group_by'):
grand_total = get_grand_total(filters, 'Purchase Invoice')
for d in item_list:
if not d.stock_qty:
continue
@@ -44,51 +46,244 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, []))
expense_account = d.expense_account or aii_account_map.get(d.company)
row = [d.item_code, d.item_name, d.item_group, d.description, d.parent, d.posting_date, d.supplier,
d.supplier_name]
row = {
'item_code': d.item_code,
'item_name': d.item_name,
'item_group': d.item_group,
'description': d.description,
'invoice': d.parent,
'posting_date': d.posting_date,
'supplier': d.supplier,
'supplier_name': d.supplier_name
}
if additional_query_columns:
for col in additional_query_columns:
row.append(d.get(col))
row.update({
col: d.get(col)
})
row += [
d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_amount / d.stock_qty, d.base_net_amount
]
row.update({
'credit_to': d.credit_to,
'mode_of_payment': d.mode_of_payment,
'project': d.project,
'company': d.company,
'purchase_order': d.purchase_order,
'purchase_receipt': d.purchase_receipt,
'expense_account': expense_account,
'stock_qty': d.stock_qty,
'stock_uom': d.stock_uom,
'rate': d.base_net_amount / d.stock_qty,
'amount': d.base_net_amount
})
total_tax = 0
for tax in tax_columns:
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
row.update({
frappe.scrub(tax + ' Rate'): item_tax.get("tax_rate", 0),
frappe.scrub(tax + ' Amount'): item_tax.get("tax_amount", 0),
})
total_tax += flt(item_tax.get("tax_amount"))
row += [total_tax, d.base_net_amount + total_tax, company_currency]
row.update({
'total_tax': total_tax,
'total': d.base_net_amount + total_tax,
'currency': company_currency
})
if filters.get('group_by'):
row.update({'percent_gt': flt(row['total']/grand_total) * 100})
group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters)
data, prev_group_by_value = add_total_row(data, filters, prev_group_by_value, d, total_row_map,
group_by_field, subtotal_display_field, grand_total, tax_columns)
add_sub_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns)
data.append(row)
return columns, data
if filters.get('group_by'):
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)
data.append({})
add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns)
data.append(total_row_map.get('total_row'))
skip_total_row = 1
return columns, data, None, None, None, skip_total_row
def get_columns(additional_table_columns):
columns = [
_("Item Code") + ":Link/Item:120", _("Item Name") + "::120",
_("Item Group") + ":Link/Item Group:100", "Description::150", _("Invoice") + ":Link/Purchase Invoice:120",
_("Posting Date") + ":Date:80", _("Supplier") + ":Link/Supplier:120",
"Supplier Name::120"
]
def get_columns(additional_table_columns, filters):
columns = []
if filters.get('group_by') != ('Item'):
columns.extend(
[
{
'label': _('Item Code'),
'fieldname': 'item_code',
'fieldtype': 'Link',
'options': 'Item',
'width': 120
},
{
'label': _('Item Name'),
'fieldname': 'item_name',
'fieldtype': 'Data',
'width': 120
}
]
)
if filters.get('group_by') not in ('Item', 'Item Group'):
columns.extend([
{
'label': _('Item Group'),
'fieldname': 'item_group',
'fieldtype': 'Link',
'options': 'Item Group',
'width': 120
}
])
columns.extend([
{
'label': _('Description'),
'fieldname': 'description',
'fieldtype': 'Data',
'width': 150
},
{
'label': _('Invoice'),
'fieldname': 'invoice',
'fieldtype': 'Link',
'options': 'Purchase Invoice',
'width': 120
},
{
'label': _('Posting Date'),
'fieldname': 'posting_date',
'fieldtype': 'Date',
'width': 120
}
])
if filters.get('group_by') != 'Supplier':
columns.extend([
{
'label': _('Supplier'),
'fieldname': 'supplier',
'fieldtype': 'Link',
'options': 'Supplier',
'width': 120
},
{
'label': _('Supplier Name'),
'fieldname': 'supplier_name',
'fieldtype': 'Data',
'width': 120
}
])
if additional_table_columns:
columns += additional_table_columns
columns += [
"Payable Account:Link/Account:120",
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
_("Company") + ":Link/Company:100", _("Purchase Order") + ":Link/Purchase Order:100",
_("Purchase Receipt") + ":Link/Purchase Receipt:100", _("Expense Account") + ":Link/Account:140",
_("Stock Qty") + ":Float:120", _("Stock UOM") + "::100",
_("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120"
{
'label': _('Payable Account'),
'fieldname': 'credit_to',
'fieldtype': 'Link',
'options': 'Account',
'width': 80
},
{
'label': _('Mode Of Payment'),
'fieldname': 'mode_of_payment',
'fieldtype': 'Link',
'options': 'Mode of Payment',
'width': 120
},
{
'label': _('Project'),
'fieldname': 'project',
'fieldtype': 'Link',
'options': 'Project',
'width': 80
},
{
'label': _('Company'),
'fieldname': 'company',
'fieldtype': 'Link',
'options': 'Company',
'width': 80
},
{
'label': _('Purchase Order'),
'fieldname': 'purchase_order',
'fieldtype': 'Link',
'options': 'Purchase Order',
'width': 100
},
{
'label': _("Purchase Receipt"),
'fieldname': 'Purchase Receipt',
'fieldtype': 'Link',
'options': 'Purchase Receipt',
'width': 100
},
{
'label': _('Expense Account'),
'fieldname': 'expense_account',
'fieldtype': 'Link',
'options': 'Account',
'width': 100
},
{
'label': _('Stock Qty'),
'fieldname': 'stock_qty',
'fieldtype': 'Float',
'width': 100
},
{
'label': _('Stock UOM'),
'fieldname': 'stock_uom',
'fieldtype': 'Link',
'options': 'UOM',
'width': 100
},
{
'label': _('Rate'),
'fieldname': 'rate',
'fieldtype': 'Float',
'options': 'currency',
'width': 100
},
{
'label': _('Amount'),
'fieldname': 'amount',
'fieldtype': 'Currency',
'options': 'currency',
'width': 100
},
{
'fieldname': 'currency',
'label': _('Currency'),
'fieldtype': 'Currency',
'width': 80,
'hidden': 1
}
]
if filters.get('group_by'):
columns.append({
'label': _('% Of Grand Total'),
'fieldname': 'percent_gt',
'fieldtype': 'Float',
'width': 80
})
return columns
def get_conditions(filters):
@@ -103,17 +298,20 @@ def get_conditions(filters):
if filters.get(opts[0]):
conditions += opts[1]
if not filters.get("group_by"):
conditions += "ORDER BY `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc"
else:
conditions += get_group_by_conditions(filters, 'Purchase Invoice')
return conditions
def get_items(filters, additional_query_columns):
conditions = get_conditions(filters)
match_conditions = frappe.build_match_conditions("Purchase Invoice")
if match_conditions:
match_conditions = " and {0} ".format(match_conditions)
if additional_query_columns:
additional_query_columns = ', ' + ', '.join(additional_query_columns)
else:
additional_query_columns = ''
return frappe.db.sql("""
select
@@ -125,12 +323,11 @@ def get_items(filters, additional_query_columns):
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
`tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`,
`tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_amount`,
`tabPurchase Invoice`.supplier_name, `tabPurchase Invoice`.mode_of_payment {0}
`tabPurchase Invoice`.`supplier_name`, `tabPurchase Invoice`.`mode_of_payment` {0}
from `tabPurchase Invoice`, `tabPurchase Invoice Item`
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and
`tabPurchase Invoice`.docstatus = 1 %s %s
order by `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc
""".format(additional_query_columns) % (conditions, match_conditions), filters, as_dict=1)
`tabPurchase Invoice`.docstatus = 1 %s
""".format(additional_query_columns) % (conditions), filters, as_dict=1)
def get_aii_accounts():
return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))

View File

@@ -4,48 +4,62 @@
frappe.query_reports["Item-wise Sales Register"] = {
"filters": [
{
"fieldname":"date_range",
"fieldname": "date_range",
"label": __("Date Range"),
"fieldtype": "DateRange",
"default": [frappe.datetime.add_months(frappe.datetime.get_today(),-1), frappe.datetime.get_today()],
"reqd": 1
},
{
"fieldname":"customer",
"fieldname": "customer",
"label": __("Customer"),
"fieldtype": "Link",
"options": "Customer"
},
{
"fieldname":"company",
"fieldname": "company",
"label": __("Company"),
"fieldtype": "Link",
"options": "Company",
"default": frappe.defaults.get_user_default("Company")
},
{
"fieldname":"mode_of_payment",
"fieldname": "mode_of_payment",
"label": __("Mode of Payment"),
"fieldtype": "Link",
"options": "Mode of Payment"
},
{
"fieldname":"warehouse",
"fieldname": "warehouse",
"label": __("Warehouse"),
"fieldtype": "Link",
"options": "Warehouse"
},
{
"fieldname":"brand",
"fieldname": "brand",
"label": __("Brand"),
"fieldtype": "Link",
"options": "Brand"
},
{
"fieldname":"item_group",
"fieldname": "item_group",
"label": __("Item Group"),
"fieldtype": "Link",
"options": "Item Group"
},
{
"label": __("Group By"),
"fieldname": "group_by",
"fieldtype": "Select",
"options": ["Customer Group", "Customer", "Item Group", "Item", "Territory", "Invoice"]
}
]
],
"formatter": function(value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
if (data && data.bold) {
value = value.bold();
}
return value;
}
}

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe, erpnext
from frappe import _
from frappe.utils import flt
from frappe.utils import flt, cstr
from frappe.model.meta import get_field_precision
from frappe.utils.xlsxutils import handle_html
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
@@ -15,23 +15,25 @@ def execute(filters=None):
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = {}
filters.update({"from_date": filters.get("date_range") and filters.get("date_range")[0], "to_date": filters.get("date_range") and filters.get("date_range")[1]})
columns = get_columns(additional_table_columns)
columns = get_columns(additional_table_columns, filters)
company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency")
item_list = get_items(filters, additional_query_columns)
if item_list:
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
columns.append({
"fieldname": "currency",
"label": _("Currency"),
"fieldtype": "Data",
"width": 80
})
mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list]))
so_dn_map = get_delivery_notes_against_sales_order(item_list)
data = []
total_row_map = {}
skip_total_row = 0
prev_group_by_value = ''
if filters.get('group_by'):
grand_total = get_grand_total(filters, 'Sales Invoice')
for d in item_list:
delivery_note = None
if d.delivery_note:
@@ -42,57 +44,285 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
if not delivery_note and d.update_stock:
delivery_note = d.parent
row = [d.item_code, d.item_name, d.item_group, d.description, d.parent, d.posting_date, d.customer, d.customer_name]
row = {
'item_code': d.item_code,
'item_name': d.item_name,
'item_group': d.item_group,
'description': d.description,
'invoice': d.parent,
'posting_date': d.posting_date,
'customer': d.customer,
'customer_name': d.customer_name,
'customer_group': d.customer_group,
}
if additional_query_columns:
for col in additional_query_columns:
row.append(d.get(col))
row.update({
col: d.get(col)
})
row += [
d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])),
d.territory, d.project, d.company, d.sales_order,
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom
]
row.update({
'debit_to': d.debit_to,
'mode_of_payment': ", ".join(mode_of_payments.get(d.parent, [])),
'territory': d.territory,
'project': d.project,
'company': d.company,
'sales_order': d.sales_order,
'delivery_note': d.delivery_note,
'income_account': d.income_account,
'cost_center': d.cost_center,
'stock_qty': d.stock_qty,
'stock_uom': d.stock_uom
})
if d.stock_uom != d.uom and d.stock_qty:
row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount]
row.update({
'rate': (d.base_net_rate * d.qty)/d.stock_qty,
'amount': d.base_net_amount
})
else:
row += [d.base_net_rate, d.base_net_amount]
row.update({
'rate': d.base_net_rate,
'amount': d.base_net_amount
})
total_tax = 0
for tax in tax_columns:
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
row.update({
frappe.scrub(tax + ' Rate'): item_tax.get("tax_rate", 0),
frappe.scrub(tax + ' Amount'): item_tax.get("tax_amount", 0),
})
total_tax += flt(item_tax.get("tax_amount"))
row += [total_tax, d.base_net_amount + total_tax, company_currency]
row.update({
'total_tax': total_tax,
'total': d.base_net_amount + total_tax,
'currency': company_currency
})
if filters.get('group_by'):
row.update({'percent_gt': flt(row['total']/grand_total) * 100})
group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters)
data, prev_group_by_value = add_total_row(data, filters, prev_group_by_value, d, total_row_map,
group_by_field, subtotal_display_field, grand_total, tax_columns)
add_sub_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns)
data.append(row)
return columns, data
if filters.get('group_by'):
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)
data.append({})
add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns)
data.append(total_row_map.get('total_row'))
skip_total_row = 1
def get_columns(additional_table_columns):
columns = [
_("Item Code") + ":Link/Item:120", _("Item Name") + "::120",
_("Item Group") + ":Link/Item Group:100", "Description::150", _("Invoice") + ":Link/Sales Invoice:120",
_("Posting Date") + ":Date:80", _("Customer") + ":Link/Customer:120",
_("Customer Name") + "::120"]
return columns, data, None, None, None, skip_total_row
def get_columns(additional_table_columns, filters):
columns = []
if filters.get('group_by') != ('Item'):
columns.extend(
[
{
'label': _('Item Code'),
'fieldname': 'item_code',
'fieldtype': 'Link',
'options': 'Item',
'width': 120
},
{
'label': _('Item Name'),
'fieldname': 'item_name',
'fieldtype': 'Data',
'width': 120
}
]
)
if filters.get('group_by') not in ('Item', 'Item Group'):
columns.extend([
{
'label': _('Item Group'),
'fieldname': 'item_group',
'fieldtype': 'Link',
'options': 'Item Group',
'width': 120
}
])
columns.extend([
{
'label': _('Description'),
'fieldname': 'description',
'fieldtype': 'Data',
'width': 150
},
{
'label': _('Invoice'),
'fieldname': 'invoice',
'fieldtype': 'Link',
'options': 'Sales Invoice',
'width': 120
},
{
'label': _('Posting Date'),
'fieldname': 'posting_date',
'fieldtype': 'Date',
'width': 120
}
])
if filters.get('group_by') != 'Customer':
columns.extend([
{
'label': _('Customer Group'),
'fieldname': 'customer_group',
'fieldtype': 'Link',
'options': 'Customer Group',
'width': 120
}
])
if filters.get('group_by') not in ('Customer', 'Customer Group'):
columns.extend([
{
'label': _('Customer'),
'fieldname': 'customer',
'fieldtype': 'Link',
'options': 'Customer',
'width': 120
},
{
'label': _('Customer Name'),
'fieldname': 'customer_name',
'fieldtype': 'Data',
'width': 120
}
])
if additional_table_columns:
columns += additional_table_columns
columns += [
_("Customer Group") + ":Link/Customer Group:120",
_("Receivable Account") + ":Link/Account:120",
_("Mode of Payment") + "::120", _("Territory") + ":Link/Territory:80",
_("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100",
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
_("Income Account") + ":Link/Account:140", _("Cost Center") + ":Link/Cost Center:140",
_("Stock Qty") + ":Float:120", _("Stock UOM") + "::100",
_("Rate") + ":Currency/currency:120",
_("Amount") + ":Currency/currency:120"
{
'label': _('Receivable Account'),
'fieldname': 'debit_to',
'fieldtype': 'Link',
'options': 'Account',
'width': 80
},
{
'label': _('Mode Of Payment'),
'fieldname': 'mode_of_payment',
'fieldtype': 'Data',
'width': 120
}
]
if filters.get('group_by') != 'Terriotory':
columns.extend([
{
'label': _("Territory"),
'fieldname': 'territory',
'fieldtype': 'Link',
'options': 'Territory',
'width': 80
}
])
columns += [
{
'label': _('Project'),
'fieldname': 'project',
'fieldtype': 'Link',
'options': 'Project',
'width': 80
},
{
'label': _('Company'),
'fieldname': 'company',
'fieldtype': 'Link',
'options': 'Company',
'width': 80
},
{
'label': _('Sales Order'),
'fieldname': 'sales_order',
'fieldtype': 'Link',
'options': 'Sales Order',
'width': 100
},
{
'label': _("Delivery Note"),
'fieldname': 'delivery_note',
'fieldtype': 'Link',
'options': 'Delivery Note',
'width': 100
},
{
'label': _('Income Account'),
'fieldname': 'income_account',
'fieldtype': 'Link',
'options': 'Account',
'width': 100
},
{
'label': _("Cost Center"),
'fieldname': 'cost_center',
'fieldtype': 'Link',
'options': 'Cost Center',
'width': 100
},
{
'label': _('Stock Qty'),
'fieldname': 'stock_qty',
'fieldtype': 'Float',
'width': 100
},
{
'label': _('Stock UOM'),
'fieldname': 'stock_uom',
'fieldtype': 'Link',
'options': 'UOM',
'width': 100
},
{
'label': _('Rate'),
'fieldname': 'rate',
'fieldtype': 'Float',
'options': 'currency',
'width': 100
},
{
'label': _('Amount'),
'fieldname': 'amount',
'fieldtype': 'Currency',
'options': 'currency',
'width': 100
},
{
'fieldname': 'currency',
'label': _('Currency'),
'fieldtype': 'Currency',
'width': 80,
'hidden': 1
}
]
if filters.get('group_by'):
columns.append({
'label': _('% Of Grand Total'),
'fieldname': 'percent_gt',
'fieldtype': 'Float',
'width': 80
})
return columns
def get_conditions(filters):
@@ -112,33 +342,39 @@ def get_conditions(filters):
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
if filters.get("warehouse"):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s)"""
conditions += """and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s"""
if filters.get("brand"):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s)"""
conditions += """and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s"""
if filters.get("item_group"):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)"""
conditions += """and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s"""
if not filters.get("group_by"):
conditions += "ORDER BY `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_group desc"
else:
conditions += get_group_by_conditions(filters, 'Sales Invoice')
return conditions
def get_group_by_conditions(filters, doctype):
if filters.get("group_by") == 'Invoice':
return "ORDER BY `tab{0} Item`.parent desc".format(doctype)
elif filters.get("group_by") == 'Item':
return "ORDER BY `tab{0} Item`.`item_code`".format(doctype)
elif filters.get("group_by") == 'Item Group':
return "ORDER BY `tab{0} Item`.{1}".format(doctype, frappe.scrub(filters.get('group_by')))
elif filters.get("group_by") in ('Customer', 'Customer Group', 'Territory', 'Supplier'):
return "ORDER BY `tab{0}`.{1}".format(doctype, frappe.scrub(filters.get('group_by')))
def get_items(filters, additional_query_columns):
conditions = get_conditions(filters)
match_conditions = frappe.build_match_conditions("Sales Invoice")
if match_conditions:
match_conditions = " and {0} ".format(match_conditions)
if additional_query_columns:
additional_query_columns = ', ' + ', '.join(additional_query_columns)
else:
additional_query_columns = ''
return frappe.db.sql("""
select
@@ -156,9 +392,8 @@ def get_items(filters, additional_query_columns):
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0}
from `tabSales Invoice`, `tabSales Invoice Item`
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
and `tabSales Invoice`.docstatus = 1 %s %s
order by `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_code desc
""".format(additional_query_columns or '') % (conditions, match_conditions), filters, as_dict=1)
and `tabSales Invoice`.docstatus = 1 {1}
""".format(additional_query_columns or '', conditions), filters, as_dict=1) #nosec
def get_delivery_notes_against_sales_order(item_list):
so_dn_map = frappe._dict()
@@ -177,6 +412,15 @@ def get_delivery_notes_against_sales_order(item_list):
return so_dn_map
def get_grand_total(filters, doctype):
return frappe.db.sql(""" SELECT
SUM(`tab{0}`.base_grand_total)
FROM `tab{0}`
WHERE `tab{0}`.docstatus = 1
and posting_date between %s and %s
""".format(doctype), (filters.get('from_date'), filters.get('to_date')))[0][0] #nosec
def get_deducted_taxes():
return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'")
@@ -264,9 +508,117 @@ def get_tax_accounts(item_list, columns, company_currency,
tax_columns.sort()
for desc in tax_columns:
columns.append(desc + " Rate:Data:80")
columns.append(desc + " Amount:Currency/currency:100")
columns.append({
'label': _(desc + ' Rate'),
'fieldname': frappe.scrub(desc + ' Rate'),
'fieldtype': 'Float',
'width': 100
})
columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:100"]
columns.append({
'label': _(desc + ' Amount'),
'fieldname': frappe.scrub(desc + ' Amount'),
'fieldtype': 'Currency',
'options': 'currency',
'width': 100
})
columns += [
{
'label': _('Total Tax'),
'fieldname': 'total_tax',
'fieldtype': 'Currency',
'options': 'currency',
'width': 100
},
{
'label': _('Total'),
'fieldname': 'total',
'fieldtype': 'Currency',
'options': 'currency',
'width': 100
}
]
return itemised_tax, tax_columns
def add_total_row(data, filters, prev_group_by_value, item, total_row_map,
group_by_field, subtotal_display_field, grand_total, tax_columns):
if prev_group_by_value != item.get(group_by_field, ''):
if prev_group_by_value:
total_row = total_row_map.get(prev_group_by_value)
data.append(total_row)
data.append({})
add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns)
prev_group_by_value = item.get(group_by_field, '')
total_row_map.setdefault(item.get(group_by_field, ''), {
subtotal_display_field: get_display_value(filters, group_by_field, item),
'stock_qty': 0.0,
'amount': 0.0,
'bold': 1,
'total_tax': 0.0,
'total': 0.0,
'percent_gt': 0.0
})
total_row_map.setdefault('total_row', {
subtotal_display_field: "Total",
'stock_qty': 0.0,
'amount': 0.0,
'bold': 1,
'total_tax': 0.0,
'total': 0.0,
'percent_gt': 0.0
})
return data, prev_group_by_value
def get_display_value(filters, group_by_field, item):
if filters.get('group_by') == 'Item':
if item.get('item_code') != item.get('item_name'):
value = cstr(item.get('item_code')) + "<br><br>" + \
"<span style='font-weight: normal'>" + cstr(item.get('item_name')) + "</span>"
else:
value = item.get('item_code', '')
elif filters.get('group_by') in ('Customer', 'Supplier'):
party = frappe.scrub(filters.get('group_by'))
if item.get(party) != item.get(party+'_name'):
value = item.get(party) + "<br><br>" + \
"<span style='font-weight: normal'>" + item.get(party+'_name') + "</span>"
else:
value = item.get(party)
else:
value = item.get(group_by_field)
return value
def get_group_by_and_display_fields(filters):
if filters.get('group_by') == 'Item':
group_by_field = 'item_code'
subtotal_display_field = 'invoice'
elif filters.get('group_by') == 'Invoice':
group_by_field = 'parent'
subtotal_display_field = 'item_code'
else:
group_by_field = frappe.scrub(filters.get('group_by'))
subtotal_display_field = 'item_code'
return group_by_field, subtotal_display_field
def add_sub_total_row(item, total_row_map, group_by_value, tax_columns):
total_row = total_row_map.get(group_by_value)
total_row['stock_qty'] += item['stock_qty']
total_row['amount'] += item['amount']
total_row['total_tax'] += item['total_tax']
total_row['total'] += item['total']
total_row['percent_gt'] += item['percent_gt']
for tax in tax_columns:
total_row.setdefault(frappe.scrub(tax + ' Amount'), 0.0)
total_row[frappe.scrub(tax + ' Amount')] += flt(item[frappe.scrub(tax + ' Amount')])

View File

@@ -23,7 +23,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check"
"fieldtype": "Check",
"default": 1
}
);
});

View File

@@ -34,6 +34,33 @@ frappe.query_reports["Purchase Register"] = {
"label": __("Mode of Payment"),
"fieldtype": "Link",
"options": "Mode of Payment"
},
{
"fieldname":"cost_center",
"label": __("Cost Center"),
"fieldtype": "Link",
"options": "Cost Center"
},
{
"fieldname":"warehouse",
"label": __("Warehouse"),
"fieldtype": "Link",
"options": "Warehouse"
},
{
"fieldname":"item_group",
"label": __("Item Group"),
"fieldtype": "Link",
"options": "Item Group"
}
]
}
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"]
});
});

View File

@@ -5,6 +5,7 @@ from __future__ import unicode_literals
import frappe
from frappe.utils import flt
from frappe import msgprint, _
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
def execute(filters=None):
return _execute(filters)
@@ -66,7 +67,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
total_tax += tax_amount
row.append(tax_amount)
# total tax, grand total, rounded total & outstanding amount
# total tax, grand total, rounded total & outstanding amount
row += [total_tax, inv.base_grand_total, flt(inv.base_grand_total, 0), inv.outstanding_amount]
data.append(row)
@@ -134,6 +135,38 @@ def get_conditions(filters):
if filters.get("mode_of_payment"): conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s"
if filters.get("cost_center"):
conditions += """ and exists(select name from `tabPurchase Invoice Item`
where parent=`tabPurchase Invoice`.name
and ifnull(`tabPurchase Invoice Item`.cost_center, '') = %(cost_center)s)"""
if filters.get("warehouse"):
conditions += """ and exists(select name from `tabPurchase Invoice Item`
where parent=`tabPurchase Invoice`.name
and ifnull(`tabPurchase Invoice Item`.warehouse, '') = %(warehouse)s)"""
if filters.get("item_group"):
conditions += """ and exists(select name from `tabPurchase Invoice Item`
where parent=`tabPurchase Invoice`.name
and ifnull(`tabPurchase Invoice Item`.item_group, '') = %(item_group)s)"""
accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions:
common_condition = """
and exists(select name from `tabPurchase Invoice Item`
where parent=`tabPurchase Invoice`.name
"""
for dimension in accounting_dimensions:
if filters.get(dimension.fieldname):
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
conditions += common_condition + "and ifnull(`tabPurchase Invoice Item`.{0}, '') in %({0})s)".format(dimension.fieldname)
else:
conditions += common_condition + "and ifnull(`tabPurchase Invoice Item`.{0}, '') in (%({0})s))".format(dimension.fieldname)
return conditions
def get_invoices(filters, additional_query_columns):

View File

@@ -6,7 +6,7 @@ import frappe
from frappe.utils import flt
from frappe import msgprint, _
from frappe.model.meta import get_field_precision
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
def execute(filters=None):
return _execute(filters)
@@ -139,7 +139,7 @@ def get_columns(invoice_list, additional_table_columns):
columns +=[
{
'label': _("Custmer Group"),
'label': _("Customer Group"),
'fieldname': 'customer_group',
'fieldtype': 'Link',
'options': 'Customer Group',
@@ -175,7 +175,7 @@ def get_columns(invoice_list, additional_table_columns):
'label': _("Project"),
'fieldname': 'project',
'fieldtype': 'Link',
'options': 'project',
'options': 'Project',
'width': 80
},
{
@@ -341,15 +341,22 @@ def get_conditions(filters):
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)"""
accounting_dimensions = get_accounting_dimensions()
accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions:
common_condition = """
and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
"""
for dimension in accounting_dimensions:
if filters.get(dimension):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.{0}, '') = %({0})s)""".format(dimension)
if filters.get(dimension.fieldname):
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
conditions += common_condition + "and ifnull(`tabSales Invoice Item`.{0}, '') in %({0})s)".format(dimension.fieldname)
else:
conditions += common_condition + "and ifnull(`tabSales Invoice Item`.{0}, '') in (%({0})s))".format(dimension.fieldname)
return conditions

View File

@@ -85,7 +85,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check"
"fieldtype": "Check",
"default": 1
}
],
"formatter": erpnext.financial_statements.formatter,

View File

@@ -7,7 +7,7 @@ from frappe import _
from frappe.utils import flt, getdate, formatdate, cstr
from erpnext.accounts.report.financial_statements \
import filter_accounts, set_gl_entries_by_account, filter_out_zero_value_rows
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
value_fields = ("opening_debit", "opening_credit", "debit", "credit", "closing_debit", "closing_credit")
@@ -103,13 +103,13 @@ def get_rootwise_opening_balances(filters, report_type):
where lft >= %s and rgt <= %s)""" % (lft, rgt)
if filters.finance_book:
fb_conditions = " and finance_book = %(finance_book)s"
fb_conditions = " AND finance_book = %(finance_book)s"
if filters.include_default_book_entries:
fb_conditions = " and (finance_book in (%(finance_book)s, %(company_fb)s))"
fb_conditions = " AND (finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)"
additional_conditions += fb_conditions
accounting_dimensions = get_accounting_dimensions()
accounting_dimensions = get_accounting_dimensions(as_list=False)
query_filters = {
"company": filters.company,
@@ -122,11 +122,16 @@ def get_rootwise_opening_balances(filters, report_type):
if accounting_dimensions:
for dimension in accounting_dimensions:
if filters.get(dimension):
additional_conditions += """ and {0} in (%({0})s) """.format(dimension)
if filters.get(dimension.fieldname):
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
additional_conditions += "and {0} in %({0})s".format(dimension.fieldname)
else:
additional_conditions += "and {0} in (%({0})s)".format(dimension.fieldname)
query_filters.update({
dimension: filters.get(dimension)
dimension.fieldname: filters.get(dimension.fieldname)
})
gle = frappe.db.sql("""

View File

@@ -640,8 +640,9 @@ def get_outstanding_invoices(party_type, party, account, condition=None, filters
precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
if account:
root_type = frappe.get_cached_value("Account", account, "root_type")
root_type, account_type = frappe.get_cached_value("Account", account, ["root_type", "account_type"])
party_account_type = "Receivable" if root_type == "Asset" else "Payable"
party_account_type = account_type or party_account_type
else:
party_account_type = erpnext.get_party_account_type(party_type)

View File

@@ -620,7 +620,7 @@ def get_asset_account(account_name, asset=None, asset_category=None, company=Non
if not account:
if not asset_category:
frappe.throw(_("Set {0} in company {2}").format(account_name.replace('_', ' ').title(), company))
frappe.throw(_("Set {0} in company {1}").format(account_name.replace('_', ' ').title(), company))
else:
frappe.throw(_("Set {0} in asset category {1} or company {2}")
.format(account_name.replace('_', ' ').title(), asset_category, company))

View File

@@ -22,7 +22,7 @@ def post_depreciation_entries(date=None):
def get_depreciable_assets(date):
return frappe.db.sql_list("""select a.name
from tabAsset a, `tabDepreciation Schedule` ds
where a.name = ds.parent and a.docstatus=1 and ds.schedule_date<=%s
where a.name = ds.parent and a.docstatus=1 and ds.schedule_date<=%s and a.calculate_depreciation = 1
and a.status in ('Submitted', 'Partially Depreciated')
and ifnull(ds.journal_entry, '')=''""", date)

View File

@@ -1,708 +1,227 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"actions": [],
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:location_name",
"beta": 0,
"creation": "2018-05-07 12:49:22.595974",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"location_name",
"parent_location",
"cb_details",
"is_container",
"is_group",
"sb_location_details",
"latitude",
"longitude",
"cb_latlong",
"area",
"area_uom",
"sb_geolocation",
"location",
"tree_details",
"lft",
"rgt",
"old_parent"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "location_name",
"fieldtype": "Data",
"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": "Location Name",
"length": 0,
"no_copy": 1,
"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": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "parent_location",
"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": "Parent Location",
"length": 0,
"no_copy": 0,
"options": "Location",
"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": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"search_index": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cb_details",
"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": 0,
"default": "0",
"description": "Check if it is a hydroponic unit",
"fieldname": "is_container",
"fieldtype": "Check",
"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": "Is Container",
"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": "Is Container"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "is_group",
"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": "Is Group",
"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": "Is Group"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sb_location_details",
"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": "Location Details",
"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": "Location Details"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "parent_location.latitude",
"fieldname": "latitude",
"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": "Latitude",
"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": "Latitude"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "parent_location.longitude",
"fieldname": "longitude",
"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": "Longitude",
"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": "Longitude"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cb_latlong",
"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,
"label": "",
"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": 0,
"fieldname": "area",
"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": "Area",
"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": "eval:doc.area",
"fieldname": "area_uom",
"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": "Area UOM",
"length": 0,
"no_copy": 0,
"options": "UOM",
"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
"options": "UOM"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sb_geolocation",
"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
"fieldtype": "Section Break"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "location",
"fieldtype": "Geolocation",
"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": "Location",
"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": "Location"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "tree_details",
"fieldtype": "Section Break",
"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": "Tree Details",
"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": "Tree Details"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "lft",
"fieldtype": "Int",
"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": "lft",
"length": 0,
"no_copy": 1,
"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": 0,
"fieldname": "rgt",
"fieldtype": "Int",
"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": "rgt",
"length": 0,
"no_copy": 1,
"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": 0,
"fieldname": "old_parent",
"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": "Old Parent",
"length": 0,
"no_copy": 1,
"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
}
],
"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-07-11 13:36:30.999405",
"is_tree": 1,
"links": [],
"modified": "2020-03-18 18:25:59.283057",
"modified_by": "Administrator",
"module": "Assets",
"name": "Location",
"name_case": "Title Case",
"nsm_parent_field": "parent_location",
"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": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"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": "Stock User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"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": "Accounts User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"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": "Stock Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"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": "Agriculture Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Agriculture User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0,
"track_views": 0
"track_changes": 1
}

View File

@@ -20,6 +20,16 @@ frappe.query_reports["Fixed Asset Register"] = {
default: 'In Location',
reqd: 1
},
{
fieldname:"purchase_date",
label: __("Purchase Date"),
fieldtype: "Date"
},
{
fieldname:"available_for_use_date",
label: __("Available For Use Date"),
fieldtype: "Date"
},
{
fieldname:"finance_book",
label: __("Finance Book"),
@@ -27,10 +37,15 @@ frappe.query_reports["Fixed Asset Register"] = {
options: "Finance Book"
},
{
fieldname:"date",
label: __("Date"),
fieldtype: "Date",
default: frappe.datetime.get_today()
fieldname:"asset_category",
label: __("Asset Category"),
fieldtype: "Link",
options: "Asset Category"
},
{
fieldname:"is_existing_asset",
label: __("Is Existing Asset"),
fieldtype: "Check"
},
]
};

View File

@@ -40,6 +40,42 @@ def get_columns(filters):
"fieldname": "status",
"width": 90
},
{
"label": _("Purchase Date"),
"fieldtype": "Date",
"fieldname": "purchase_date",
"width": 90
},
{
"label": _("Available For Use Date"),
"fieldtype": "Date",
"fieldname": "available_for_use_date",
"width": 90
},
{
"label": _("Gross Purchase Amount"),
"fieldname": "gross_purchase_amount",
"options": "Currency",
"width": 90
},
{
"label": _("Asset Value"),
"fieldname": "asset_value",
"options": "Currency",
"width": 90
},
{
"label": _("Opening Accumulated Depreciation"),
"fieldname": "opening_accumulated_depreciation",
"options": "Currency",
"width": 90
},
{
"label": _("Depreciated Amount"),
"fieldname": "depreciated_amount",
"options": "Currency",
"width": 90
},
{
"label": _("Cost Center"),
"fieldtype": "Link",
@@ -54,25 +90,6 @@ def get_columns(filters):
"options": "Department",
"width": 100
},
{
"label": _("Location"),
"fieldtype": "Link",
"fieldname": "location",
"options": "Location",
"width": 100
},
{
"label": _("Purchase Date"),
"fieldtype": "Date",
"fieldname": "purchase_date",
"width": 90
},
{
"label": _("Gross Purchase Amount"),
"fieldname": "gross_purchase_amount",
"options": "Currency",
"width": 90
},
{
"label": _("Vendor Name"),
"fieldtype": "Data",
@@ -80,25 +97,29 @@ def get_columns(filters):
"width": 100
},
{
"label": _("Available For Use Date"),
"fieldtype": "Date",
"fieldname": "available_for_use_date",
"width": 90
},
{
"label": _("Asset Value"),
"fieldname": "asset_value",
"options": "Currency",
"width": 90
"label": _("Location"),
"fieldtype": "Link",
"fieldname": "location",
"options": "Location",
"width": 100
},
]
def get_conditions(filters):
conditions = {'docstatus': 1}
conditions = { 'docstatus': 1 }
status = filters.status
date = filters.date
if filters.company:
if filters.get('company'):
conditions["company"] = filters.company
if filters.get('purchase_date'):
conditions["purchase_date"] = ('<=', filters.get('purchase_date'))
if filters.get('available_for_use_date'):
conditions["available_for_use_date"] = ('<=', filters.get('available_for_use_date'))
if filters.get('is_existing_asset'):
conditions["is_existing_asset"] = filters.get('is_existing_asset')
if filters.get('asset_category'):
conditions["asset_category"] = filters.get('asset_category')
# In Store assets are those that are not sold or scrapped
operand = 'not in'
@@ -114,7 +135,7 @@ def get_data(filters):
data = []
conditions = get_conditions(filters)
depreciation_amount_map = get_finance_book_value_map(filters.date, filters.finance_book)
depreciation_amount_map = get_finance_book_value_map(filters)
pr_supplier_map = get_purchase_receipt_supplier_map()
pi_supplier_map = get_purchase_invoice_supplier_map()
@@ -136,6 +157,8 @@ def get_data(filters):
"cost_center": asset.cost_center,
"vendor_name": pr_supplier_map.get(asset.purchase_receipt) or pi_supplier_map.get(asset.purchase_invoice),
"gross_purchase_amount": asset.gross_purchase_amount,
"opening_accumulated_depreciation": asset.opening_accumulated_depreciation,
"depreciated_amount": depreciation_amount_map.get(asset.name) or 0.0,
"available_for_use_date": asset.available_for_use_date,
"location": asset.location,
"asset_category": asset.asset_category,
@@ -146,9 +169,9 @@ def get_data(filters):
return data
def get_finance_book_value_map(date, finance_book=''):
if not date:
date = today()
def get_finance_book_value_map(filters):
date = filters.get('purchase_date') or filters.get('available_for_use_date') or today()
return frappe._dict(frappe.db.sql(''' Select
parent, SUM(depreciation_amount)
FROM `tabDepreciation Schedule`
@@ -157,7 +180,7 @@ def get_finance_book_value_map(date, finance_book=''):
AND schedule_date<=%s
AND journal_entry IS NOT NULL
AND ifnull(finance_book, '')=%s
GROUP BY parent''', (date, cstr(finance_book))))
GROUP BY parent''', (date, cstr(filters.finance_book or ''))))
def get_purchase_receipt_supplier_map():
return frappe._dict(frappe.db.sql(''' Select

View File

@@ -698,8 +698,7 @@
{
"fieldname": "manufacturer_part_no",
"fieldtype": "Data",
"label": "Manufacturer Part Number",
"read_only": 1
"label": "Manufacturer Part Number"
},
{
"default": "0",
@@ -712,7 +711,7 @@
],
"idx": 1,
"istable": 1,
"modified": "2019-11-07 17:19:12.090355",
"modified": "2020-04-07 18:35:17.558928",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",

View File

@@ -9,7 +9,7 @@ cur_frm.add_fetch('contact', 'email_id', 'email_id')
frappe.ui.form.on("Request for Quotation",{
setup: function(frm) {
frm.custom_make_buttons = {
'Supplier Quotation': 'Supplier Quotation'
'Supplier Quotation': 'Create'
}
frm.fields_dict["suppliers"].grid.get_field("contact").get_query = function(doc, cdt, cdn) {

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,8 @@ def get_data():
'heatmap_message': _('This is based on transactions against this Supplier. See timeline below for details'),
'fieldname': 'supplier',
'non_standard_fieldnames': {
'Payment Entry': 'party_name'
'Payment Entry': 'party_name',
'Bank Account': 'party'
},
'transactions': [
{
@@ -24,6 +25,10 @@ def get_data():
'label': _('Payments'),
'items': ['Payment Entry']
},
{
'label': _('Bank'),
'items': ['Bank Account']
},
{
'label': _('Pricing'),
'items': ['Pricing Rule']

View File

@@ -4,15 +4,17 @@
// attach required files
{% include 'erpnext/public/js/controllers/buying.js' %};
frappe.ui.form.on('Suppier Quotation', {
setup: function(frm) {
frm.custom_make_buttons = {
'Purchase Order': 'Purchase Order'
}
}
});
erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.extend({
setup: function() {
this.frm.custom_make_buttons = {
'Purchase Order': 'Purchase Order',
'Quotation': 'Quotation',
'Subscription': 'Subscription'
}
this._super();
},
refresh: function() {
var me = this;
this._super();

View File

@@ -1,4 +1,5 @@
{
"actions": [],
"autoname": "hash",
"creation": "2013-05-22 12:43:10",
"doctype": "DocType",
@@ -522,8 +523,7 @@
{
"fieldname": "manufacturer_part_no",
"fieldtype": "Data",
"label": "Manufacturer Part Number",
"read_only": 1
"label": "Manufacturer Part Number"
},
{
"fieldname": "column_break_15",
@@ -532,7 +532,8 @@
],
"idx": 1,
"istable": 1,
"modified": "2019-06-02 05:32:46.019237",
"links": [],
"modified": "2020-04-07 18:35:51.175947",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation Item",

View File

@@ -141,13 +141,13 @@ def get_conditions(filters):
conditions = ""
if filters.get("company"):
conditions += " AND company='%s'"% filters.get('company')
conditions += " AND company=%s"% frappe.db.escape(filters.get('company'))
if filters.get("cost_center") or filters.get("project"):
conditions += """
AND (cost_center='%s'
OR project='%s')
"""% (filters.get('cost_center'), filters.get('project'))
AND (cost_center=%s
OR project=%s)
"""% (frappe.db.escape(filters.get('cost_center')), frappe.db.escape(filters.get('project')))
if filters.get("from_date"):
conditions += " AND transaction_date>=%s"% filters.get('from_date')

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