Compare commits

...

439 Commits

Author SHA1 Message Date
mbauskar
3f3ac5652f resolved merge conflicts 2017-07-07 13:42:54 +05:30
mbauskar
7b8d366e3a bumped to version 8.3.2 2017-07-07 14:11:45 +06:00
rohitwaghchaure
a29442d6bf [Fix] Setup wizard translation (#9693) 2017-07-07 13:40:13 +05:30
rohitwaghchaure
bbe16c80ff [Fix] Setup wizard translation issue (#9692) 2017-07-07 13:27:15 +05:30
Nabin Hait
4e21f11864 Merge pull request #9690 from rmehta/additional-discount-fix
[fix] reset flag after promise
2017-07-07 13:26:14 +05:30
Rushabh Mehta
19d52dc503 [fix] remove extra flag 2017-07-07 13:23:23 +05:30
Nabin Hait
701f7cccbf Merge pull request #9688 from nabinhait/pos_fixes
Fixed itemised tax calc to fix pos loading
2017-07-07 13:18:14 +05:30
Nabin Hait
8b486b0f28 Fixed state code of WB and allowed invoice_copy to edit after submit 2017-07-07 13:14:25 +05:30
Rushabh Mehta
6705ab3eaf [fix] discount setting multiple times 2017-07-07 13:14:08 +05:30
Rushabh Mehta
233a19a373 [fix] reset flag after promise 2017-07-07 13:06:29 +05:30
Nabin Hait
fbb5945ff3 Fixed itemised tax calc to fix pos loading 2017-07-07 12:58:22 +05:30
Nabin Hait
7773ee8960 Sales invoice dashboard, multiple letter head in report and email alert docs 2017-07-07 12:49:05 +05:30
Nabin Hait
8ad168ac67 Fixed merge conflict 2017-07-06 23:18:00 +05:30
Nabin Hait
3e9520b276 bumped to version 8.2.5 2017-07-06 23:46:40 +06:00
Nabin Hait
29b74b90c8 bumped to version 8.3.1 2017-07-06 23:45:28 +06:00
Nabin Hait
ad6cf4fa88 Merge branch 'develop' 2017-07-06 23:15:28 +05:30
Nabin Hait
e927b81292 Update production_order.js 2017-07-06 23:11:54 +05:30
Makarand Bauskar
88a37c17a6 [hotfix] commit after every 200 production orders (#9674) 2017-07-06 19:13:09 +05:30
Nabin Hait
5fe7f6c3fd Invoice copy is in the center in gst print format 2017-07-06 17:51:05 +05:30
Nabin Hait
d59819d9bb Date format issue fixed in setup wizard 2017-07-06 16:12:59 +05:30
mbauskar
afdd7a626c Merge branch 'develop' 2017-07-06 16:12:02 +05:30
mbauskar
7699b5e92a bumped to version 8.3.0 2017-07-06 16:42:02 +06:00
Nabin Hait
b5d765d19a Merge pull request #9669 from rohitwaghchaure/sales_invoice_serial_no_revert
Revert sales invoice serial no issues
2017-07-06 16:07:46 +05:30
Rohit Waghchaure
6d03790b44 Revert sales invoice serial no issues 2017-07-06 15:58:50 +05:30
Nabin Hait
3638250f5d Merge pull request #9641 from manassolanki/att-report
show inactive students in the monthly attendance report
2017-07-06 15:53:16 +05:30
Nabin Hait
7bf192e46a Merge pull request #9526 from manassolanki/validate-criteria
validate the duplicate assessment criteria
2017-07-06 15:47:10 +05:30
Nabin Hait
fa351f4bdf Merge pull request #9433 from tundebabzy/issue-9424
Errors due to a single quote in Supplier's name #9424
2017-07-06 15:22:16 +05:30
rohitwaghchaure
bedb486c55 [Fix] Multi letter head showing in the print (#9644) 2017-07-06 14:50:38 +05:30
Nabin Hait
f3f0dfef2a Invoice copy, state code in gst print format, hsn code in other sales/purchase docs (#9658)
* Invoice copy, state code in gst print format, hsn code in other sales/purchase docs

* Formatted Net Amount in item-tax-breakup

* GST print format fixes

* removed trailing whitespace

* removed trailing whitespace
2017-07-06 14:49:34 +05:30
rohitwaghchaure
5d5a81f375 Fixed patch create_warehouse_nestedset (#9656) 2017-07-06 13:03:11 +05:30
Nabin Hait
02c8607d04 Production Order Documentation for Required Items table (#9647) 2017-07-06 11:28:07 +05:30
Makarand Bauskar
ddd4845420 [hotfix] setup wizard, complete_setup fixes (#9654)
* [hotfix] setup wizard, complete_setup fixes

* Update utils.py

* Update utils.py
2017-07-06 11:09:34 +05:30
Rushabh Mehta
63b06420e1 [fix] setup wizard dates (#9646) 2017-07-05 17:56:04 +05:30
Makarand Bauskar
bf66d7e041 [minor] setup wizard dates to yyyy-mm-dd format (#9642) 2017-07-05 17:26:34 +05:30
Manas Solanki
fc85768685 show inactive students in the monthly attendance reoprt 2017-07-05 16:35:47 +05:30
Nabin Hait
37c784eb3a Updated modified in bom doctypes 2017-07-05 16:09:23 +05:30
Makarand Bauskar
a54eb7d022 [minor] added change log for v8.3.0 (#9629) 2017-07-05 15:36:38 +05:30
Makarand Bauskar
48af4289d3 Revert "[enhance] Provision to set the currency in the pricing rule for the price" (#9636) 2017-07-05 15:17:02 +05:30
Rushabh Mehta
03c30a7f92 [minor] throw name error if group matches with name, for setup wizard to nicely catch the exception 2017-07-05 15:12:07 +05:30
Nabin Hait
949a920022 Production Order Enhancements (#9432)
* Production Order Enhancements
  - Show required items child table
  - Source warehouse for each raw materials, in Pro Order Item and BOM Item table
  - Group warehouse allowed for source and wip warehouse
  - Patch to populate required items, to fix status and reserved qty for stopped pro order
  - Cleaned up existing codes
  - Test cases

* Set available qty in source and wip warehouse

* minor fix in bom query naming

* Minor Fixes

* Reload BOM doctypes in patch
2017-07-05 13:55:41 +05:30
Nabin Hait
852cb64e4f GST tax invoice print format and more (#9616)
* GST Tax Invoice print format and more. Fixes #9545 #9566 #9608

* Reload gst print format only for Indian users

* Fixes as Codacy
2017-07-05 12:58:19 +05:30
mbauskar
b66fb9a4c0 Merge branch 'master' into develop 2017-07-05 11:25:15 +05:30
mbauskar
9fbdf14e61 Merge branch 'hotfix' 2017-07-05 11:25:14 +05:30
mbauskar
4b7a30b527 bumped to version 8.2.4 2017-07-05 11:55:14 +06:00
Doridel Cahanap
5ad4a6e161 Total Stock Summary (#9465)
* Total Stock Summary

* indentation fixes and removed the for loop

* minor fixes in total stock summery report
2017-07-05 10:49:09 +05:30
rohitwaghchaure
10a4a13e5e Remove gst reports for non indian accounts (#9553)
* remove gst reports for non indian accounts

* [Fix] GSN code auto name
2017-07-04 16:45:29 +05:30
Frappe PR Bot
3ceab64bfa [translation] translation updates (#9611) 2017-07-04 16:08:14 +05:30
tundebabzy
6015f0f2ec Inspection required before delivery isn't working for item variants (#9362)
* makes `copy_attributes_to_variant` to not ignore "Table"

* fixes test cases - `test_auto_material_request` and `test_auto_material_request_for_variant`

* adds test case - tables in templates should be copied to variants

* [ci] use deprecated trusty build for now
2017-07-04 15:43:02 +05:30
rohitwaghchaure
e5ca48a76a [fix] Don't update the sales invoice number into the serial no if update stock is disabled in the invoice (#9593) 2017-07-04 10:54:23 +05:30
rohitwaghchaure
3e4bcfe2d8 [Fix] Opening Entry, Unknown column 'warehouse' in 'where clause' (#9585)
* [Fix] Opening Entry, Unknown column 'warehouse' in 'where clause'

* escaped company name in get_opening_accounts
2017-07-04 10:49:37 +05:30
Prateeksha Singh
5e4c8ecd62 Setup wizard refactor (#9441)
* cleaned up slides, yet to decide on master data

* remove item_count

* [fix] refresh slides on domain bug

* UI test

* set header image here in ERPNext

* [minor] lint checks

* [wiz] change autofilled fiscal year format

* [minor] fixed date format to dd-mm-yyyy if fiscal year is not available for country
2017-07-03 18:23:57 +05:30
Makarand Bauskar
11df066ed0 Merge pull request #9586 from Arundhatii/28June
Added help page for Global Search and updated old images #9241
2017-07-03 16:24:39 +05:30
Makarand Bauskar
87f2848aeb resolved conflicts 2017-07-03 16:24:01 +05:30
Makarand Bauskar
12450fa473 Merge pull request #9558 from mbauskar/domainify-school
[domainify] Domainification for the Education Domain
2017-07-03 16:17:21 +05:30
Frappe
67bbcf6932 Resolved conflicts in index.md 2017-07-03 16:00:07 +05:30
Frappe
79918c66c2 Deleted old Images and added Global Search Help page 2017-07-03 15:58:14 +05:30
Makarand Bauskar
960208bae0 Merge pull request #9426 from tundebabzy/issue-9096
Gross Profit Does not display Reversal of sales invoice #9096
2017-07-03 15:23:21 +05:30
Makarand Bauskar
1bad1fcc00 Merge pull request #9452 from faztp12/develop
Customer Query include Search fields
2017-07-03 15:20:23 +05:30
Rushabh Mehta
43ef4e9047 Added first UI tests (#9532)
* [wip]

* [tests] wip

* [ui-tests] first-cut

* [minor] remove old tests
2017-07-03 11:53:07 +05:30
Makarand Bauskar
65f6f2a05e Merge pull request #9568 from frappe/add-code-of-conduct-1
Create CODE_OF_CONDUCT.md
2017-07-03 10:48:16 +05:30
Rushabh Mehta
558fcc140f Create CODE_OF_CONDUCT.md 2017-07-01 21:35:10 +05:30
mbauskar
ea92682cfd Merge branch 'hotfix' 2017-07-01 14:16:46 +05:30
mbauskar
a06a600d0a Merge branch 'master' into develop 2017-07-01 14:16:46 +05:30
mbauskar
af9d3a4db6 bumped to version 8.2.3 2017-07-01 14:46:46 +06:00
Makarand Bauskar
f39a9f1c5b Merge pull request #9562 from mbauskar/gst-hsn-code
[minor] fix autoname for GST HSN Code (#9536)
2017-07-01 14:15:18 +05:30
Sagar Vora
067991ee30 [minor] fix autoname for GST HSN Code (#9536) 2017-07-01 14:14:14 +05:30
Makarand Bauskar
1589ada04d Merge pull request #9473 from rohitwaghchaure/pricing_rule_currency
[enhance] Provision to set the currency in the pricing rule for the price
2017-06-30 18:58:30 +05:30
mbauskar
ee368221cf [domainify] Domainification for schools doctype 2017-06-30 17:58:57 +05:30
rohitwaghchaure
6691856d08 Merge pull request #9554 from mbauskar/sales-register
[minor] fixed AttributeError: 'dict' object has no attribute 'company' in sales register
2017-06-30 16:48:10 +05:30
Charles-Henri Decultot
53de2f1b57 Translation correction in P&L report (#9436) 2017-06-30 16:45:11 +05:30
mbauskar
22aaf0cbd0 [minor] fixed AttributeError: 'dict' object has no attribute 'company' in sales register 2017-06-30 16:43:25 +05:30
Sagar Vora
8ebc0df65f [minor] fix autoname for GST HSN Code (#9536) 2017-06-30 16:42:26 +05:30
Makarand Bauskar
4095915bff Merge pull request #9489 from rohitwaghchaure/billed_amt_issue_in_pr
[fix] Billed Amt does not get updated in Purchase Receipt, if Invoice exists and item has been returned once before
2017-06-30 16:02:31 +05:30
Makarand Bauskar
abe8e2ecce Merge pull request #9533 from rohitwaghchaure/total_amount_issue
[minor] Total amount not showing value in bank reconcillation
2017-06-30 14:50:23 +05:30
Makarand Bauskar
b053674781 Merge pull request #9534 from manassolanki/report
Course wise assessment result tool
2017-06-30 14:47:46 +05:30
Manas Solanki
bb68f8ca01 cleanup for the assessment report and added chart 2017-06-30 12:22:51 +05:30
mbauskar
943637e06c Merge branch 'hotfix' 2017-06-30 12:00:23 +05:30
mbauskar
0407cb0d92 bumped to version 8.2.2 2017-06-30 12:30:22 +06:00
Makarand Bauskar
d192a420d1 Merge pull request #9549 from rohitwaghchaure/patch_fix_gst
[Fix] Options must be a valid DocType for field Customs Tariff Number
2017-06-30 11:59:47 +05:30
Rohit Waghchaure
3856d14ae6 [Fix] Options must be a valid DocType for field Customs Tariff Number 2017-06-30 11:57:41 +05:30
Manas Solanki
85480b3af7 Added report in config/schools.py 2017-06-30 11:36:57 +05:30
Manas Solanki
c4125b32ee Course wise assessment reports 2017-06-30 11:36:57 +05:30
mbauskar
4e08dfc72f Merge branch 'develop' 2017-06-29 21:58:08 +05:30
mbauskar
53e34f5c1c bumped to version 8.2.1 2017-06-29 22:28:08 +06:00
Makarand Bauskar
c6e1c3c048 Merge pull request #9537 from mbauskar/patch
[minor] fixed the report value for  deprecated report patch
2017-06-29 21:57:09 +05:30
mbauskar
0c2de6e07a [minor] fixed the report value for deprecated report patch 2017-06-29 21:47:14 +05:30
Rohit Waghchaure
b801357ecf [minor] Total amount not showing value in bank reconcillation 2017-06-29 18:40:01 +05:30
mbauskar
1508267fd6 Merge branch 'develop' 2017-06-29 15:07:26 +05:30
mbauskar
8f1f93603d bumped to version 8.2.0 2017-06-29 15:37:26 +06:00
Aditya Duggal
f1bd39c937 Allow NA values in GSTIN number (#9503)
-Reason for allowing NA value is that if a user wants to make GSTIN number mandatory then they can do the same easily
2017-06-29 14:25:19 +05:30
Manas Solanki
800c69eec3 validate the duplicate assessment criteria 2017-06-29 13:00:22 +05:30
mbauskar
ec252c806f resolved merge conflicts 2017-06-29 12:11:07 +05:30
mbauskar
2a903a0608 Merge branch 'hotfix' 2017-06-29 12:09:40 +05:30
mbauskar
71b4e48ea5 bumped to version 8.1.7 2017-06-29 12:39:39 +06:00
Makarand Bauskar
ae2d92ee76 Merge pull request #9523 from saurabh6790/setup_wiz_fix
[fix] translate domain
2017-06-29 12:07:19 +05:30
Saurabh
21cf1fd851 [fix] translate domain 2017-06-29 12:04:45 +05:30
Makarand Bauskar
02c281cc2f Merge pull request #9522 from rmehta/update-gstin-2
[fix] update-gstin
2017-06-29 12:01:20 +05:30
Makarand Bauskar
a938d3956a [minor] get doc using party_name instead of party 2017-06-29 11:58:50 +05:30
Rushabh Mehta
02b0ed4199 [fix] update-gstin 2017-06-29 11:56:14 +05:30
Vishal Dhayagude
76f93d05b7 display image in supplier's list view (#9500)
* [fix]display supplier image in desk

* Supplier image displayed in desk

* Show image in supplier desk page

* [minor] removed whitespaces
2017-06-29 11:23:13 +05:30
Makarand Bauskar
24ab20fe11 Merge pull request #9467 from rohitwaghchaure/support_hours_report
[enhance] Report for analysis of support hours count
2017-06-29 11:19:41 +05:30
Makarand Bauskar
1eb31db71f Merge pull request #9466 from manassolanki/validation
changes in student settings for validating the students in the student groups
2017-06-29 10:48:59 +05:30
Makarand Bauskar
ef95b4d6e3 Merge pull request #9468 from manassolanki/issue-11
in program enrollment filter out students which are already enrolled
2017-06-29 10:48:12 +05:30
Makarand Bauskar
514c0417dd Merge pull request #9483 from manassolanki/fix-student-fetch
fetch queries for the students in the student group
2017-06-29 10:47:05 +05:30
Makarand Bauskar
67f6ac848c Merge pull request #9497 from ashwinisave35/email_template_redesign
Adding ERPNext logo for email templates.
2017-06-29 10:46:44 +05:30
Makarand Bauskar
5d95ebec4e Merge pull request #9508 from rohitwaghchaure/contacts_module_error
[Fix] Module error during patch execution
2017-06-29 10:46:17 +05:30
Makarand Bauskar
bb7317d398 Merge pull request #9512 from mbauskar/patch-fix
[fixes] delete auto email report of deprecated reports and other minor fixes
2017-06-29 10:45:50 +05:30
Makarand Bauskar
550268eaf3 Merge pull request #9518 from sagarvora/gh-9516
[minor] fix supplier GSTIN portal not getting displayed
2017-06-29 10:43:53 +05:30
Makarand Bauskar
7f9af46da5 [minor] removed whitespace 2017-06-29 09:38:46 +05:30
Makarand Bauskar
e38eb83358 [minor] removed print statement 2017-06-29 09:35:11 +05:30
Makarand Bauskar
af00c9f70b [minor] removed whitespaces from get_students method 2017-06-29 09:25:19 +05:30
Makarand Bauskar
5c7545da0c [minor] passed index for string format 2017-06-29 09:07:59 +05:30
mbauskar
d6e8bb5452 [fixes] delete auto email report of deprecated reports and other minor fixes 2017-06-29 08:39:01 +05:30
Sagar Vora
435032f5bc [minor] fix typo 2017-06-28 23:59:47 +05:30
Sagar Vora
1ef50c89db [minor] use party_name instead of party and save GSTIN in uppercase 2017-06-28 23:52:22 +05:30
Rohit Waghchaure
2e4b4454b3 [Fix] Module error during patch execution 2017-06-28 17:31:59 +05:30
rohitwaghchaure
4b33b7e1c1 Merge pull request #9418 from nick9822/nick9822-patch-3
Removed "Asset" filter on payment account
2017-06-28 16:38:21 +05:30
rohitwaghchaure
69279229cc Merge pull request #8987 from bcornwellmott/bom_convert_uom
Added BOM UOM selection for items
2017-06-28 16:28:31 +05:30
Rohit Waghchaure
5b7028c7bb stock qty not changed if item change 2017-06-28 15:58:51 +05:30
mbauskar
0018db344c Merge branch 'develop' 2017-06-28 13:32:29 +05:30
mbauskar
e9a4f4e70d bumped to version 8.1.6 2017-06-28 14:02:29 +06:00
Saurabh
be03de3ad6 Merge pull request #9502 from mbauskar/patch-fix
[fix] delete/update desktop icon for deprecated report
2017-06-28 13:28:33 +05:30
Makarand Bauskar
d235325a95 Merge pull request #9501 from saurabh6790/gst_patch_fix
[fix] delete custom field tax_id if exists in transaction Sales Order, Sales Invoice and Delivery Note
2017-06-28 13:28:02 +05:30
mbauskar
6daa6e422e [fix] delete/update desktop icon for deprecated report 2017-06-28 13:26:50 +05:30
Saurabh
07913c3ff2 [fix] delete custom field tax_id if exists in trasaction Sales Order, Sales Invoice and Delivery Note 2017-06-28 13:16:50 +05:30
Makarand Bauskar
71ba7ea717 Merge pull request #9498 from mbauskar/develop
[minor] fixed broken image url in gst documentation
2017-06-28 12:30:56 +05:30
mbauskar
3b0e6cecd6 [minor] fixed broken image url in gst documentation 2017-06-28 12:29:19 +05:30
Ashwini Save
544de60d36 Adding ERPNext logo for email tempates. 2017-06-28 11:44:09 +05:30
Manas Solanki
d652221071 fetch queries for the students in the student group 2017-06-28 11:26:41 +05:30
mbauskar
4d5d3b7685 Merge branch 'develop' 2017-06-28 11:01:40 +05:30
mbauskar
3bf9071598 bumped to version 8.1.5 2017-06-28 11:31:40 +06:00
Saurabh
46af07cc09 Merge pull request #9494 from mbauskar/patch-fixes
[fix] handle email exception if email account is not configured
2017-06-28 11:00:00 +05:30
mbauskar
27692670b1 [fix] handle email exception if email account is not configured 2017-06-28 10:56:50 +05:30
Makarand Bauskar
3708df61bf Merge pull request #9493 from saurabh6790/gst_patch_fix
[fix] reload gst settings doctype in patch
2017-06-28 10:52:49 +05:30
Saurabh
3f2dd04b10 [fix] reload gst settings doctype in patch 2017-06-28 10:50:38 +05:30
mbauskar
fd598d8f3a Merge branch 'develop' 2017-06-28 10:40:07 +05:30
mbauskar
4e0999dda7 bumped to version 8.1.4 2017-06-28 11:10:07 +06:00
Makarand Bauskar
eef3f62ff7 Merge pull request #9488 from rmehta/gst-reminder
[regional] ability to send gst reminders to all parties
2017-06-27 19:33:05 +05:30
Makarand Bauskar
104eb8c6ad [minor] render GSTIN value as "" instead of None 2017-06-27 18:59:35 +05:30
Manas Solanki
3959c7c3c1 filter out students which are already enrolled in program enrollment 2017-06-27 18:22:05 +05:30
Makarand Bauskar
b43f4073db fixed TypeError: throw() got an unexpected keyword argument 'exception' 2017-06-27 18:15:52 +05:30
Rushabh Mehta
01659271be [minor] dont make fixtures again by patch 2017-06-27 18:05:54 +05:30
Rushabh Mehta
c616a4a527 [tests] codacy 2017-06-27 17:50:15 +05:30
Rohit Waghchaure
eb7eb43dfc [fix] Billed Amt does not get updated in Purchase Receipt, if Invoice exists and item has been returned once before 2017-06-27 17:34:44 +05:30
Rushabh Mehta
00ae424cac [regional] ability to send gst reminders to all parties 2017-06-27 17:31:41 +05:30
Makarand Bauskar
7b6e09b9a7 Merge pull request #9487 from rohitwaghchaure/currency_label_issue
[fix] Currency label not displaying in the total advance field
2017-06-27 16:16:22 +05:30
Makarand Bauskar
90a3e60de7 Merge pull request #9372 from pratu16x7/serial-batch-entry
Serial no/batch entry dialog
2017-06-27 16:12:30 +05:30
Rohit Waghchaure
f3e91e2b2b [minor] Currency label not displaying in the total advance field 2017-06-27 15:51:35 +05:30
pratu16x7
846f5d4bd8 [fix] cloning rows 2017-06-27 14:03:56 +05:30
Makarand Bauskar
51520f9de6 Merge pull request #9479 from frappe-pr-bot/translations-2017-06-27
[translation] translation update
2017-06-27 13:58:04 +05:30
Makarand Bauskar
9d457d3e34 Merge pull request #9485 from saurabh6790/gst_update_email
send email to system managers about gst update
2017-06-27 13:42:52 +05:30
frappe-pr-bot
8ddd946dea [translation] translation updates 2017-06-27 10:10:50 +02:00
Saurabh
c20abf6b2a send email to system managers about gst setup 2017-06-27 13:21:57 +05:30
Makarand Bauskar
68a48c9cfc Merge pull request #9484 from mbauskar/develop
revert customer-orders-invoices-and-shipping-status.md documentation
2017-06-27 12:51:32 +05:30
mbauskar
8c3f99f12e revert customer-orders-invoices-and-shipping-status.md documentation 2017-06-27 12:49:10 +05:30
Rushabh Mehta
9b09ff29d2 [fix] address creation for india/setup.py 2017-06-27 12:17:39 +05:30
Rushabh Mehta
f4e908bd91 [minor] general_ledger.js 2017-06-27 11:56:30 +05:30
Makarand Bauskar
5d8803b23e Merge pull request #9435 from rmehta/gst
GST (India) Setup and Invoices #8711
2017-06-27 11:44:33 +05:30
pratu16x7
f970ca4d35 Update docs 2017-06-27 10:12:58 +05:30
pratu16x7
29cebbb0cd use set_value() for setting rows 2017-06-27 09:48:28 +05:30
Rohit Waghchaure
0b078fb4cb [enhance] Provision to set the currency in the pricing rule for the price 2017-06-27 00:06:40 +05:30
pratu16x7
89d001caf3 [lint] fixes 2017-06-26 17:45:49 +05:30
tunde
6837e69187 Merge branch 'develop' into issue-9424 2017-06-26 13:05:27 +01:00
tunde
5824ae98d9 calls local to build frappe.form_dict in order to pass failing test 2017-06-26 12:42:11 +01:00
Rohit Waghchaure
67526f244e [enhance] Report for analysis of support hours count 2017-06-26 17:04:52 +05:30
tunde
67cbeb1bb0 Merge branch 'develop' into issue-9096 2017-06-26 12:11:07 +01:00
tunde
8859eb23a3 set form_dict correctly 2017-06-26 12:01:41 +01:00
pratu16x7
ae450fc23b async call to require, more validation 2017-06-26 15:31:46 +05:30
nick9822
82e816054e Added report_type to payment account filter 2017-06-26 15:29:44 +05:30
tunde
ea7768d3f3 fixes form_dict failure in travis test 2017-06-26 10:17:53 +01:00
Manas Solanki
cb650f836e validation of student in student attendance 2017-06-26 14:11:12 +05:30
Saurabh
f4fc30a72d Merge branch 'develop' 2017-06-26 13:55:59 +05:30
Saurabh
095701e86b bumped to version 8.1.3 2017-06-26 14:25:59 +06:00
Saurabh
dccceb44f9 Merge pull request #9463 from saurabh6790/v8_1_patch_fixes
[fix] patch fixes
2017-06-26 13:52:23 +05:30
pratu16x7
5f389c999a [fix] values update in items in invoices 2017-06-26 13:38:24 +05:30
Saurabh
29fa0a9a17 [fix] patch fixes 2017-06-26 13:28:45 +05:30
tunde
c1d22adb9f Merge branch 'develop' into issue-9424 2017-06-26 08:52:55 +01:00
tunde
bce13cd0e3 fixes failing test 2017-06-26 08:43:25 +01:00
Saurabh
81bb2c9f3c Merge branch 'develop' 2017-06-26 11:01:38 +05:30
Saurabh
3bf5a38c6f bumped to version 8.1.2 2017-06-26 11:31:37 +06:00
Makarand Bauskar
c93de0e803 [minor] removed global roles from company doctype field's depends on propery (#9450) 2017-06-24 10:39:30 +05:30
Rushabh Mehta
d03203966a [minor] fix old patch 2017-06-24 10:37:19 +05:30
Console Admin
8623166dca Customer Query include Searchfields
frappe/erpnext#8821
2017-06-23 20:32:52 +03:00
pratu16x7
577e4c4e28 Add in transaction.js, cleanups 2017-06-23 19:25:01 +05:30
Makarand Bauskar
ebaea08225 Merge pull request #9437 from Arundhatii/20Jun
Added help pages and deleted old images links to #9241
2017-06-23 18:54:45 +05:30
Makarand Bauskar
1a78a3244b removed conflicts 2017-06-23 18:37:08 +05:30
rohitwaghchaure
8f51a5e527 In POS on click of delete button, remove the selected item from the cart (#9428) 2017-06-23 18:17:04 +05:30
Makarand Bauskar
1d962dd3f7 removed conflicts 2017-06-23 18:11:58 +05:30
Makarand Bauskar
bbf81aa3a4 image title translation 2017-06-23 18:11:00 +05:30
Makarand Bauskar
862302f02d image title translation 2017-06-23 18:10:06 +05:30
Makarand Bauskar
408336e7ad image title translation 2017-06-23 18:08:45 +05:30
Makarand Bauskar
ab49c3100d corrected image title 2017-06-23 18:04:56 +05:30
Makarand Bauskar
ec27a30069 Merge pull request #9442 from creamdory/develop
BOM Stock Report to allow Multi Level Warehouse Setup
2017-06-23 17:59:56 +05:30
Makarand Bauskar
5e994ddf65 removed white spaces 2017-06-23 17:58:50 +05:30
Makarand Bauskar
4eced4acec Merge pull request #9445 from rohitwaghchaure/column_width_issue_bank_reco
[minor] Fix grid column of the Bank Reconciliation
2017-06-23 17:24:50 +05:30
Makarand Bauskar
6df26422f6 Merge pull request #9446 from rohitwaghchaure/delivery_required_issue_for_pos
Don't validate delivery note and sales order required for the POS invoice
2017-06-23 17:24:21 +05:30
Frappe
a951e56f9c Modified help pages 2017-06-23 16:49:35 +05:30
Frappe
1f8e5fbcb1 Edited help page 2017-06-23 16:48:46 +05:30
Frappe
ca6fed359b Added help pages for Subcontracting and deleted old images 2017-06-23 16:48:17 +05:30
creamdory
9961fb82d6 Bom Stock Report Change Requests 2017-06-23 15:57:52 +08:00
Rohit Waghchaure
8326028d33 Don't validate delivery note and sales order required for the POS invoice 2017-06-23 12:56:12 +05:30
Rohit Waghchaure
666d004b40 [minor] Fix grid column of the Bank Reconciliation 2017-06-23 12:10:21 +05:30
Frappe
9a8f33f855 Replaced screenshot in help pages, links to #9241 2017-06-23 11:30:26 +05:30
Frappe
8181a7463e added help page for Kanban Board, links to #9241 2017-06-23 11:30:26 +05:30
Frappe
ac08fbd438 added test documentation 2017-06-23 11:30:26 +05:30
Rushabh Mehta
210b6f8f7e [docs] 2017-06-22 22:32:08 +05:30
Rushabh Mehta
25366a22ad [minor] cleanup 2017-06-22 22:32:08 +05:30
Rushabh Mehta
919a74ad88 [gst] adde reports + docs 2017-06-22 22:32:08 +05:30
Rushabh Mehta
b3c8f44b3e [wip] GST for India. Pending reports 2017-06-22 22:31:32 +05:30
tunde
94500fd17b adds test case 2017-06-22 17:34:54 +01:00
tunde
dcd54209fc parameterises sql string 2017-06-22 14:03:19 +01:00
pratu16x7
759f669214 Add in delivery note 2017-06-22 18:14:29 +05:30
pratu16x7
70eca9462b make erpnext.SerialNoBatchSelector 2017-06-22 18:14:29 +05:30
pratu16x7
60d9446656 onchange in df 2017-06-22 18:14:29 +05:30
pratu16x7
934105bf34 fix modified by, blur serial field 2017-06-22 18:14:28 +05:30
pratu16x7
26b8f5c3ce [minor] 2017-06-22 18:14:16 +05:30
pratu16x7
36693e27be [fix] tests 2017-06-22 18:14:16 +05:30
pratu16x7
a5d5403bf3 specific change bubbling for grid fields 2017-06-22 18:13:56 +05:30
pratu16x7
0e35651e94 Add get_stock_qty test 2017-06-22 18:13:56 +05:30
pratu16x7
837ffbddbc [minor] 2017-06-22 18:13:55 +05:30
pratu16x7
ff25573558 cleanup 2017-06-22 18:13:55 +05:30
pratu16x7
82a199d6d7 [fix] availably qty reupdate 2017-06-22 18:13:55 +05:30
pratu16x7
d15a507567 add serial_no_check 2017-06-22 18:13:55 +05:30
pratu16x7
01e79f033e add warehouse selection and mapping 2017-06-22 18:13:55 +05:30
pratu16x7
9a6e675b41 wip 2017-06-22 18:13:55 +05:30
pratu16x7
7331f169fc [fix] warehouse required bug 2017-06-22 18:13:54 +05:30
pratu16x7
d09f35fa98 fire modal on item_code, events, validation 2017-06-22 18:13:54 +05:30
pratu16x7
52d703a232 [fix] test 2017-06-22 18:13:54 +05:30
pratu16x7
e4e00d2215 batch item distribution by oldest, serial no check 2017-06-22 18:13:54 +05:30
pratu16x7
60944e3397 get oldest batch in modal, insert batch items 2017-06-22 18:13:30 +05:30
pratu16x7
0b642cd414 set available qty 2017-06-22 18:13:30 +05:30
pratu16x7
b4de1c771b WIP 2017-06-22 18:13:30 +05:30
Rushabh Mehta
aedaac63ea [wip] batch, serial number selector 2017-06-22 18:13:30 +05:30
Saurabh
2cb598f644 Merge pull request #9430 from sagarvora/fix-travis
[ci] use deprecated trusty build for now
2017-06-22 17:28:10 +05:30
mbauskar
bbe9bccc1a Merge branch 'develop' 2017-06-22 17:00:25 +05:30
mbauskar
04c8bf0b21 bumped to version 8.1.1 2017-06-22 17:30:25 +06:00
Makarand Bauskar
0a9176a647 Merge pull request #9429 from mbauskar/delete-deprecated-reports
[minor] deleted deprecated reprots and changed the lead.json modified time
2017-06-22 16:58:50 +05:30
mbauskar
66e2a510b9 [minor] deleted deprecated reprots and changed the lead.json modified time 2017-06-22 16:57:46 +05:30
Sagar Vora
f070c548de [ci] use deprecated trusty build for now 2017-06-22 16:43:28 +05:30
tunde
96e629a635 adds credits notes to report since double entry for P or L affects sales 2017-06-22 10:04:33 +01:00
mbauskar
78aac9edb6 Merge branch 'develop' 2017-06-22 13:10:59 +05:30
mbauskar
ea77b63b4a bumped to version 8.1.0 2017-06-22 13:40:58 +06:00
Makarand Bauskar
79d36c7c43 Merge pull request #9423 from mbauskar/patch-fix
[minor] save the system settings document
2017-06-22 12:49:35 +05:30
mbauskar
4b299ba009 [minor] save the system settings document 2017-06-22 12:46:31 +05:30
Makarand Bauskar
e995371b08 Merge pull request #9355 from rohitwaghchaure/company_wise_manufacturing_settings
[Enhance] Company wise perpetual inventory settings
2017-06-22 12:35:41 +05:30
Rohit Waghchaure
2d9b3cd270 Fixed test cases 2017-06-22 12:23:15 +05:30
Ben Cornwell-Mott
ac3ad0810a Merge branch 'bom_convert_uom' of https://github.com/bcornwellmott/erpnext into bom_convert_uom 2017-06-21 10:17:39 -07:00
Ben Cornwell-Mott
1e96b7bbe5 Added conversion_factor update in patch 2017-06-21 10:16:50 -07:00
Makarand Bauskar
0ea5d941e6 Merge branch 'develop' into bom_convert_uom 2017-06-21 21:35:38 +05:30
nick9822
881491cd2b Removed "Asset" filter on payment account 2017-06-21 19:51:08 +05:30
Makarand Bauskar
1b6746e3bc Merge pull request #9388 from saurabh6790/dropbox_doc_fix
[update] dropbox documentation to show how to set redirect url to create access token
2017-06-21 19:10:45 +05:30
Makarand Bauskar
cdfccffc0d Merge pull request #9341 from manassolanki/training-event
send email on update and on update after submit
2017-06-21 19:09:21 +05:30
Makarand Bauskar
7a2a2dad35 Merge pull request #9381 from almeidapaulopt/so_proj
link sales order to new project
2017-06-21 18:48:30 +05:30
Makarand Bauskar
a3f7823304 Merge pull request #9412 from umairsy/21jun
Updated help pages and removed old images, links to #9262
2017-06-21 18:34:45 +05:30
Umair Sayyed
5057098a19 Updated help pages and removed old images, links to #9262 2017-06-21 17:54:39 +05:30
Makarand Bauskar
ce7087f08a Merge pull request #9408 from mbauskar/develop
merged hotfix branch to develop
2017-06-21 16:41:33 +05:30
Makarand Bauskar
b37eb10421 Merge pull request #9382 from nick9822/nick9822-patch-1
Resetting batch and serial nos checks
2017-06-21 16:34:32 +05:30
mbauskar
196f3b1fb8 resolved merge conflicts 2017-06-21 14:38:06 +05:30
mbauskar
654ccb84f4 Merge branch 'hotfix' 2017-06-21 13:17:12 +05:30
mbauskar
9b4690995e bumped to version 8.0.51 2017-06-21 13:47:12 +06:00
Makarand Bauskar
2c67b01335 Merge pull request #9404 from mbauskar/hotfix
make quotation against lead company name (#9188)
2017-06-21 12:57:08 +05:30
Manas Solanki
29ba4143f9 make quotation against lead company name (#9188) 2017-06-21 12:55:27 +05:30
Makarand Bauskar
9b5d1fc458 Merge pull request #9401 from sagarvora/so-calendar
[fix] get status in calendar view and show green background
2017-06-21 12:41:27 +05:30
Makarand Bauskar
a9a03ab723 Merge pull request #9403 from manassolanki/issue-10
Trigger assessment plan every time page loads, fixes #9402
2017-06-21 12:37:40 +05:30
Manas Solanki
7f64f623f0 Trigger assessment plan every time page loads 2017-06-21 12:08:23 +05:30
Sagar Vora
6371b53b7e [fix] get status in calendar view and show green background 2017-06-21 11:58:29 +05:30
Makarand Bauskar
c7cfa16f8c Merge pull request #9391 from saurabh6790/fix_make_variant_item_code
[minor][fix] pass template item name to make_variant_item_code
2017-06-21 11:58:07 +05:30
Saurabh
8d269beb45 [minor][fix] pass template item name to make_variant_item_code 2017-06-20 20:14:14 +05:30
Makarand Bauskar
cd5dd890aa Merge pull request #9384 from nick9822/nick9822-patch-2
Bug while fetching stock balance of new item.
2017-06-20 19:52:28 +05:30
Makarand Bauskar
eb08cce825 Merge pull request #9386 from umairsy/20Jun
Replaced old images with new, links to #9262
2017-06-20 19:40:46 +05:30
Saurabh
88b642637b update dropbox documentation to show how to set redirect url to create access token 2017-06-20 19:01:16 +05:30
Umair Sayyed
357cd6df90 added new images, links #9262 2017-06-20 18:19:50 +05:30
Umair Sayyed
3292e59dcd Replaced old images with new, links to #9262 2017-06-20 18:17:40 +05:30
nick9822
cc699a94fd Bug while fetching new item balance. 2017-06-20 17:13:29 +05:30
nick9822
43a48fd2bc Resetting batch and serial nos checks 2017-06-20 17:02:55 +05:30
Paulo Almeida
2d5e65ddcf link sales order to new project 2017-06-20 12:08:22 +01:00
Makarand Bauskar
d2301fc43d Merge pull request #9375 from frappe-pr-bot/translations-2017-06-20
[translation] translation update
2017-06-20 15:53:41 +05:30
frappe-pr-bot
db4bb720b8 [translation] translation updates 2017-06-20 11:22:36 +02:00
Makarand Bauskar
8fac4314aa Merge pull request #9373 from sagarvora/gh-9289
Check for align_labels_left before adding text-right class
2017-06-20 14:31:22 +05:30
Sagar Vora
89d60ca35e Check for align_labels_left before adding text-right class 2017-06-20 14:16:06 +05:30
Rushabh Mehta
17e6bb83eb [fix] typo, item group route to have parent only for non root 2017-06-20 14:07:33 +05:30
Makarand Bauskar
958b06b129 Merge pull request #9369 from sagarvora/gh-4559
[minor] calculate balance in company currency instead of account currency
2017-06-20 13:26:10 +05:30
Ayush Shukla
a111f78566 Leaderboard of customers, items, suppliers and sales partner (#9354)
* First commit leaderboard working

* Styling and added href

* Changed timeline string

* Changes in item

* Cleanup

* Fix

* made changes to currency column

* Code cleanup for codacy

* Sorting bug fixed and formatting done

* Changed type to isinstance
2017-06-20 13:04:45 +05:30
Vishal Dhayagude
310d4dc9e0 UOM column in Batch Wise Balance History Report (#9359)
* Training Events/Results link to employee dashbord

* [minor]Improve validation message for Buying / Selling Setting

* [minor]Added UOM cloumn in Batch Wise Balance History Report

* modified validation message for buying / selling setting
2017-06-20 13:02:35 +05:30
Britlog
faf75c4ddd Fix and improve shopping cart (#9348)
* Fix and improve shopping cart

* Update shopping_cart.js

* Update shopping_cart.js
2017-06-20 12:51:32 +05:30
Rushabh Mehta
c422874418 Update company.py 2017-06-20 12:19:36 +05:30
Rushabh Mehta
777526e3a8 Update __init__.py 2017-06-20 12:14:32 +05:30
Makarand Bauskar
22773a29f7 Merge pull request #9356 from tundebabzy/issue_6510
adds information about "Is Paid" and "Update Stock"
2017-06-20 12:04:16 +05:30
Sagar Vora
5b08d7acb3 [minor] calculate balance in company currency instead of account currency 2017-06-20 11:50:23 +05:30
Rohit Waghchaure
e9ff1914fc Added is_perpetual_inventory_enabled method 2017-06-20 11:26:37 +05:30
Rohit Waghchaure
65ccb42f95 fixed document 2017-06-20 10:21:34 +05:30
Rohit Waghchaure
6945d0dd8a fixed test cases 2017-06-20 10:21:33 +05:30
Rohit Waghchaure
a5f40941ae [Enhance] Companywise perpetual inventory setting 2017-06-20 10:21:33 +05:30
Rushabh Mehta
80ef298519 [fix] [tests] test_delivery_note 2017-06-20 10:07:28 +05:30
Rushabh Mehta
36311020de [minor] ux fixes 2017-06-20 09:31:06 +05:30
tunde
4961072b51 adds the corrected breadcrumbs trail 2017-06-19 13:51:27 +01:00
Makarand Bauskar
9a5c39d329 Merge pull request #9353 from mbauskar/develop
[minor] Allow on Submit for Sales Order Customer PO and Customer PO Date
2017-06-19 18:16:22 +05:30
tunde
46db749d62 adds information about "Is Paid" and "Update Stock" 2017-06-19 09:18:57 +01:00
mbauskar
de5a11e8fb [minor] Allow on Submit for Sales Order Customer PO and Customer PO Date 2017-06-19 13:07:51 +05:30
Sagar Vora
086b6a33ea Fixed BOM value not updating on changing item (#9350) 2017-06-19 12:25:14 +05:30
Sagar Vora
67fe1010c7 [minor] set_posting_time=1 only when imported data contains posting date. (#9349) 2017-06-19 12:12:22 +05:30
Rushabh Mehta
b7b49f6da7 [fixes] fix message and type conversion; 2017-06-19 09:59:09 +05:30
Charles-Henri Decultot
2305eda82e Addition of new fields for POS Profile in Sales Invoice and POS Profile User link modification (#9339) 2017-06-19 09:25:54 +05:30
Umair Sayed
ac2e32a511 replaced some old images with new, #9262 (#9335) 2017-06-19 09:23:04 +05:30
Ben Cornwell-Mott
2c77165fc6 Fixed small code issues (codecy) 2017-06-16 13:47:40 -07:00
Manas Solanki
9936100a6a send email on update and on update after submit fixes #8898 2017-06-16 22:18:20 +05:30
bcornwellmott
6561b8ade9 Merge branch 'develop' into bom_convert_uom 2017-06-16 08:29:00 -07:00
Makarand Bauskar
24173b9a12 Merge pull request #9337 from mbauskar/develop
[minor] use reload_doc instead of reload_doctype
2017-06-16 19:16:05 +05:30
mbauskar
3c1a53c325 [minor] use reload_doc instead of reload_doctype 2017-06-16 18:31:42 +05:30
Rushabh Mehta
73167eae60 [demo] make it faster, do not send user email 2017-06-16 16:55:32 +05:30
tundebabzy
9a3462031d [UX] Error in purchase transaction - Ignore instead of Prompt #7766 (#9329)
* sets tax category to "Total" if all items are non-stock items

* makes notification message translatable and removes multi-line string

* Update buying_controller.py
2017-06-16 15:30:14 +05:30
almeidapaulopt
31692a2595 Create a project from a Sales Order (#9111)
* init commit

* don't get tasks if project name is none

* cleanup

* Update sales_order.js
2017-06-16 15:29:41 +05:30
Makarand Bauskar
e159ce9a27 Merge pull request #9330 from mbauskar/develop
[minor] reload Domain doctype before executing patch
2017-06-16 14:36:22 +05:30
mbauskar
2ea55c7143 [minor] reload Domain doctype before executing patch 2017-06-16 14:33:59 +05:30
Makarand Bauskar
3d6697949c [minor] fixed the child table field name (#9328)
* [minor] exclude Other domain from Domains

* [minor] fixed the child table field name
2017-06-16 14:12:28 +05:30
Sagar Vora
b1c794a4f9 [hot] fix global name args is not defined (#9326) 2017-06-16 13:50:35 +05:30
Faris Ansari
1ee615c9ad Add .eslintrc for codacy (#9321) 2017-06-16 13:12:47 +05:30
rohitwaghchaure
fb45913b3b [fix] Patch for move account head from account to warehouse (#9325) 2017-06-16 13:12:37 +05:30
Makarand Bauskar
dd986f659e Merge branch 'pratu16x7-domainify' into domainify (#9324)
* bootstrap domains and set active_domain on setup

* [minor] Patch for domain docs

* [minor]

* Update create_domain_docs.py
2017-06-16 13:02:45 +05:30
Nabin Hait
84bc5601eb Total sales cost in Project should be updated based on base_grand_total (#9302)
* Total sales cost in Project should be updated based on base_grand_total

* Patch to update sales cost in Project in base currency
2017-06-16 12:13:51 +05:30
Vishal Dhayagude
2510d1c86a Training Events/Results link added to Employee (#9313) 2017-06-16 11:58:08 +05:30
Umair Sayed
5dadb0e19a created help page for email inbox, fixes #9262 (#9315) 2017-06-16 11:57:44 +05:30
Britlog
224eb90199 Fix get_parents context (#9296) 2017-06-16 11:51:06 +05:30
Sagar Vora
5f407907a2 fix logic of quantity validation (#9311) 2017-06-16 11:43:36 +05:30
Manas Solanki
b07535bb64 bug in training result module (#9314) 2017-06-16 11:20:42 +05:30
Rushabh Mehta
c8a0de5e59 Revert "sets tax category to "Total" if all items are non-stock items (#9295)" (#9320)
This reverts commit 476c4fec1d.
2017-06-16 11:18:23 +05:30
tundebabzy
476c4fec1d sets tax category to "Total" if all items are non-stock items (#9295) 2017-06-16 11:17:40 +05:30
Ben Cornwell-Mott
840c757b12 Merge branch 'bom_convert_uom' of https://github.com/bcornwellmott/erpnext into bom_convert_uom 2017-06-15 08:53:29 -07:00
Ben Cornwell-Mott
7055446508 Reload explosion and scrap items docs 2017-06-15 08:52:55 -07:00
Rushabh Mehta
e0434ad40e Merge branch 'develop' into bom_convert_uom 2017-06-15 17:32:27 +05:30
mbauskar
5da3ac63bf [minor] fixed merge conflicts 2017-06-15 16:09:42 +05:30
mbauskar
ac13627222 Merge branch 'hotfix' 2017-06-15 16:05:49 +05:30
mbauskar
489550ed59 bumped to version 8.0.50 2017-06-15 16:35:49 +06:00
Makarand Bauskar
950ad36352 Merge pull request #9306 from nabinhait/in_words_col_len
Change column length of in_words
2017-06-15 16:03:09 +05:30
Makarand Bauskar
a4af7cb7d3 removed extra quote from query 2017-06-15 16:02:44 +05:30
Nabin Hait
5aee7d1b70 Change column length of in_words 2017-06-15 15:35:08 +05:30
mbauskar
f9e2bf1ab4 fixed merge conflicts 2017-06-15 13:42:47 +05:30
Nabin Hait
6e9a146f2b Merge pull request #9193 from tundebabzy/issue_9180
Payment Entry - Latest Exchange Rate not fetched
2017-06-15 12:34:27 +05:30
Nabin Hait
2153399c39 Create journal_entry.py 2017-06-15 12:30:58 +05:30
Nabin Hait
6d7b0ce794 Warehouse Account Linking (#9292)
* [enhance] Added account in the warehouse

* documentation

* patch to move account head from account to warehouse

* fixed test cases

* Fixes in warehouse-account linking

* minor fix in test case
2017-06-15 11:09:27 +05:30
Umair Sayed
0b8e19b5d8 Added new help pages as per OKR - DO NOT MERGE (#9291)
* added help pages on Assessment, delete and restore documents and Document versioning, fixed #9262

* some fixes in help docs
2017-06-14 19:40:08 +05:30
tunde
3514332cd8 changes journal_entry.get_exchange_rate to return exchange rate at date not average exchange rate 2017-06-14 13:14:40 +01:00
Manas Solanki
67c4f1713b Minor changes in the UX and courses automatically fetched upon saving (#9264) 2017-06-14 17:34:36 +05:30
Manas Solanki
95ca531def make quotation against lead company name (#9188) 2017-06-14 16:13:23 +05:30
Sagar Vora
847444724b remove bracket (#9284) 2017-06-14 15:51:47 +05:30
Sagar Vora
d19c2e2e93 [minor] Check if item is stock item before validating Warehouse while Purchase Return (#9282)
* Check if item is stock item before validating Warehouse

* changed logic to decide warehouse_mandatory
2017-06-14 15:39:41 +05:30
KanchanChauhan
c849f647f7 Show Stock Level only if any value(actual, reserved, reserved for production or projected) exists (#9168) 2017-06-14 15:37:47 +05:30
Manas Solanki
40be3f4048 fix in the item for the function make_variant_item_code (#9280) 2017-06-14 15:06:07 +05:30
Manas Solanki
737482423b change in the absent student report (#9185) 2017-06-14 15:05:48 +05:30
Makarand Bauskar
0da5f23db6 [minor] fixed Cannot read property 'default_letter_head' of undefined (#9268) 2017-06-14 12:52:13 +05:30
Sagar Vora
99a2db80ab move bom based rate calculation to end (#9271) 2017-06-14 12:38:27 +05:30
bcornwellmott
d53dd7f4c9 Merge branch 'develop' into bom_convert_uom 2017-06-13 08:40:24 -07:00
Sagar Vora
489ab6d70d [minor] remove hardcoded flt precision and use system default (#9250)
* possible fix

* use system default precision for flt
2017-06-13 18:58:47 +05:30
tundebabzy
26a39610ca fixes #8941: Better error message for duplicate items (#8968)
* fixes #8941: Better error message for duplicate items

* gathers all non unique items instead of first encountered non unique item

* renders errored items with `br` instead of `li`
2017-06-13 17:40:56 +05:30
Ashwini Save
eed0cee186 Solve issue for while changing status of sales order page not reloading (#9204)
* Solve issue for while changing status of sales order page not reloading

* Close Sales order issue : code review Changes.
2017-06-13 17:14:06 +05:30
Makarand Bauskar
da15486624 Merge pull request #9260 from mbauskar/address-and-contacts
[hot] fixed ImportError: Module import failed for Company (erpnext.setup.doctype.company.company)
2017-06-13 17:08:56 +05:30
Makarand Bauskar
a7a7c835cc Merge pull request #9196 from msiddiq0/patch-2
Fix incorrect youtube link on Video Tutorials
2017-06-13 17:05:50 +05:30
Makarand Bauskar
f339f6d69f Merge pull request #9195 from msiddiq0/patch-1
Fixed wrong YouTube video link
2017-06-13 17:05:36 +05:30
Makarand Bauskar
65f5cf3fc1 Merge pull request #9197 from msiddiq0/patch-3
Fix incorrect YouTube link on Video Tutorials
2017-06-13 17:05:19 +05:30
mbauskar
96ce5821b8 [hot] fixed ImportError: Module import failed for Company (erpnext.setup.doctype.company.company) 2017-06-13 17:03:13 +05:30
Makarand Bauskar
0c5d732cd8 Merge pull request #9208 from mbauskar/docs
removed {next} from documentation and removed the globals from custom scripts
2017-06-13 16:32:26 +05:30
Makarand Bauskar
70ef313b0d Merge pull request #9245 from frappe-pr-bot/translations-2017-06-13
[translation] translation update
2017-06-13 16:23:22 +05:30
KanchanChauhan
1dc26b127b Salutation and Gender in Lead and Customer (#9199) 2017-06-13 15:26:35 +05:30
Saurabh
797f2030f8 Merge branch 'master' into develop 2017-06-13 15:20:13 +05:30
frappe-pr-bot
f7fe66cc48 [translation] translation updates 2017-06-13 11:17:57 +02:00
_JG_
aafe0c517f Update purchase_order_dashboard.py (#9149)
There are no links to projects
2017-06-13 13:00:47 +05:30
Makarand Bauskar
757e1bf846 Merge pull request #9213 from manassolanki/school-report
fix for student monthly attendance report
2017-06-13 12:30:37 +05:30
Nabin Hait
d0ac0bdc18 Merge branch 'master' into develop 2017-06-12 13:50:12 +05:30
Rushabh Mehta
4f8f9c1d9a [enhance] create demo with function bench --site sitename make-demo` (#9212) 2017-06-12 09:18:06 +05:30
tunde
5127da952e changes expected payment_account in test case according to the fact that exchange rate should return latest saved rate 2017-06-09 17:11:41 +01:00
bcornwellmott
fed9816213 Removed trailing whitespace 2017-06-09 07:37:27 -07:00
bcornwellmott
a35839aa47 Removing unused pprint 2017-06-09 07:36:15 -07:00
tunde
7bf4b121f3 Merge branch 'hotfix' into issue_9180 2017-06-09 13:58:22 +01:00
Manas Solanki
4458eb356b fix for student monthly attendance report 2017-06-09 18:20:21 +05:30
mbauskar
828804fab0 [minor] removed the {next} from the last articles 2017-06-09 17:30:36 +05:30
mbauskar
11f0ee3cac [docs] removed the globals from documentation 2017-06-09 17:23:06 +05:30
Faris Ansari
0626716f48 Merge pull request #9182 from pratu16x7/stock-entry-detail-global-fix
[fix] sys_defaults global in stock entry detail
2017-06-09 16:27:07 +05:30
tunde
0a5db528b1 makes sure latest test fixtures for currency exchange is retrieved before running test 2017-06-09 08:14:10 +01:00
msiddiq0
a05c168808 Fix incorrect YouTube link on Video Tutorials
The original YouTube video is private and not viewable by anyone. I linked the publicly viewable YouTube video for "Report Builder" now.
2017-06-08 21:02:45 -04:00
msiddiq0
a095d6e04b Fixing youtube link
Wrong youtube video linked here: "Managing Advance Payments". Linked to correct video now: "Bulk Update"
2017-06-08 20:51:50 -04:00
msiddiq0
03183332b4 Fixed wrong YouTube video link
The original link here led to video on "Bulk Update" not "Budgeting". I went and found the Budgeting video and linked it here now.
2017-06-08 20:10:18 -04:00
tunde
9b827e5b95 makes set_exchange_rate retrieve the latest exchange rate not average for "pay" and "internal transfer" payment entries 2017-06-08 20:54:01 +01:00
tunde
6148fe0909 adds test case to confirm that latest exchange rate is automatically selected 2017-06-08 20:50:11 +01:00
tunde
88f1d316d8 adds new tests that verify that get_exchange_rate returns the latest exchange rate 2017-06-08 19:44:26 +01:00
tunde
3eb5cb14d1 calls erpnext.setup.utils.get_exchange_rate instead of get_average_exchange_rate 2017-06-08 14:23:49 +01:00
pratu16x7
adb418d453 [fix] sys_defaults global in stock entry detail 2017-06-08 10:42:03 +05:30
Nabin Hait
2c808c578d Merge branch 'master' into develop 2017-06-08 10:34:45 +05:30
bcornwellmott
5491275b66 Merge branch 'develop' into bom_convert_uom 2017-06-07 08:42:54 -07:00
Javier Wong
b414f73931 [enhancement] Allow on Submit for Sales Order Customer PO and Customer PO Date (#9137) 2017-06-07 20:11:45 +05:30
ahmadRagheb
9017f3768b Fix labels to accept translation in selling doctype (#9135)
"label": _("Customer Addresses And Contacts"),
"label": _("Sales Partner Addresses And Contacts"),
now they can accept to be translated
2017-06-07 20:08:39 +05:30
Nabil Kadimi
41f6f4c200 Fix type (entrys) (#9131) 2017-06-07 20:08:11 +05:30
Umair Sayed
0dd5a20ca6 Help links added help_links.js (#9170)
* help links in help_links.js

* fixed in help_links.js
2017-06-07 20:05:35 +05:30
Makarand Bauskar
59a1540898 [minor] removed the deprecated inList method from eval (#9177) 2017-06-07 20:02:09 +05:30
Nabin Hait
a128b21baa Fixed merge conflict 2017-06-07 12:17:17 +05:30
Nabil Kadimi
347a79db5a Fix typo (#9133) 2017-06-07 12:06:05 +05:30
Frappe PR Bot
7c9010018d [translation] translation updates (#9156) 2017-06-07 12:05:29 +05:30
Faris Ansari
5f27c94100 Merge pull request #9078 from netchampfaris/remove-globals
Lint and fix JS files
2017-06-06 11:35:42 +05:30
Ben Cornwell-Mott
70fe968f02 Fixed some errors 2017-06-04 20:19:59 -07:00
Ben Cornwell-Mott
a3aa6a4449 Changed Explosion Item as well 2017-06-02 16:54:03 -07:00
Nabin Hait
5b8b4dcce1 Merge branch 'master' into develop 2017-06-02 14:05:54 +05:30
Nabin Hait
02d282f347 Merge branch 'master' into develop 2017-06-01 19:09:37 +05:30
Britlog
495a408db0 Fix contact form if email is both customer and lead (#9075) 2017-06-01 19:08:04 +05:30
Charles-Henri Decultot
5ade661a9a Weekly digest subject translation (#9003) 2017-06-01 19:06:32 +05:30
ahmadRagheb
c4d2bab5b3 Arabic language shows Errors onSubmit in maintenance_schedule (#9082)
* Arabic language shows Errors onSubmit  in maintenance_schedule

when trying to submit using arabic language error show up , 
i replace this way of formating arguments 
				description = frappe._("Reference: %s, Item Code: %s and Customer: %s") % \
					(self.name, d.item_code, self.customer)
to new one  :description = frappe._("Reference: %s, Item Code: %s and Customer: %s").format(self.name, d.item_code, self.customer)

and it solve the problem on my local

* Arabic language shows Errors onSubmit in maintenance_schedule

* Arabic language shows Errors onSubmit in maintenance_schedule
2017-06-01 19:06:00 +05:30
Frappe PR Bot
59ee45a1a5 [translation] translation updates (#9081) 2017-06-01 19:05:28 +05:30
Ashwini Save
2020dd37e8 Fixed issue : Payment Entry allocating amount more than invoice amount. (#9084)
* Fixed issue : Payment Entry allocating amount more than invoice amount.

* Added condition to solve issue when allocated amount is null

* Code review Changes for payment entry
2017-06-01 19:00:34 +05:30
Faris Ansari
9f6d024260 Set website route field as No Copy field (#9106)
* Set website route field as No Copy field

* minor
2017-06-01 18:58:07 +05:30
Manas Solanki
f60bd60012 Fix the demo for the schools (#8879)
* Fix the demo for the schools

* Fix for the demo

https://github.com/frappe/erpnext/issues/6347
2017-06-01 18:30:35 +05:30
Nabin Hait
fa16b849a0 Merge branch 'master' into develop 2017-05-30 22:52:39 +05:30
Nabin Hait
c9fa07b16d Merge branch 'master' into develop 2017-05-30 15:59:04 +05:30
Faris Ansari
ab74ca7fff Lint and fix JS files 2017-05-30 12:54:42 +05:30
Faris Ansari
dae7721384 Merge pull request #8975 from almeidapaulopt/milestones
Milestones in Project Gantt
2017-05-29 10:58:35 +05:30
Nabin Hait
6a541a6f7a Merge branch 'master' into develop 2017-05-26 21:35:42 +05:30
Francisco Roldán
44c1a610a1 Financial Statements Button translateabled (#9032) 2017-05-26 21:32:51 +05:30
Ashwini Save
d702cbfbfa Update code to fix issue #erpnext WN-SUP25349 : ValueError: max() arg is an empty sequence. (#9025) 2017-05-25 15:48:08 +05:30
Nabin Hait
45d337a016 Merge branch 'master' into develop 2017-05-25 14:19:51 +05:30
bcornwellmott
8fa1e03367 Merge branch 'develop' into bom_convert_uom 2017-05-24 12:35:12 -07:00
Ben Cornwell-Mott
0f0b121669 Added BOM UOM selection for items
Added patch for BOM Item UOM

Fixed scrap qty issue

Added Scrap Qty update to patch

Reverted test record for production order
2017-05-24 11:12:51 -07:00
Nabin Hait
c795386230 Fixed merge conflict 2017-05-24 18:39:16 +05:30
Makarand Bauskar
2f17e70793 [minor] removed the {next} for last page (#9002) 2017-05-24 18:35:35 +05:30
Ishan Loya
9bf4563b7a Change modified time 2017-05-24 17:47:42 +05:30
Ishan Loya
a70b41fbb8 Remove Role 'All' from BOM 2017-05-24 17:47:42 +05:30
nick9822
ca150cee8c Minor change: Alert to msgprint (#8966)
* Minor change: Alert to msgprint

* msgprint to frappe.msgprint
2017-05-24 17:22:26 +05:30
Charles-Henri Decultot
032374e76e Correction of the digest template (#8992) 2017-05-24 16:29:42 +05:30
Nabin Hait
8fac45a885 Merge branch 'master' into develop 2017-05-24 09:07:26 +05:30
Makarand Bauskar
3b9c2a4438 Added a reference of Sales Invoice in Serial No (#8855)
* [enhance] added Sales Invoice reference in Serial Number

* [patch] added test cases for Sales Invoice and added patch to copy sales invoice

* [minor] minor fixes in validate_serial_against_delivery_note

* [minor] fixes in sales invoice serial number validation
2017-05-23 18:45:34 +05:30
Nabin Hait
dce8dfc4fe Merge branch 'master' into develop 2017-05-23 17:48:43 +05:30
Nabin Hait
c9f5d84742 Merge branch 'master' into develop 2017-05-23 17:16:19 +05:30
Paulo Almeida
97ff6fea47 add milestone field 2017-05-23 11:55:37 +01:00
Nabin Hait
889e456dab Merge branch 'master' into develop 2017-05-23 12:04:06 +05:30
Rushabh Mehta
2b06633919 Merge branch 'master' into develop 2017-05-19 19:24:43 +05:30
Rushabh Mehta
612b31b626 Merge branch 'master' into develop 2017-05-19 18:33:55 +05:30
Rushabh Mehta
03fb6ff003 [rename] zh-tw -> zh-TW 2017-05-19 18:26:49 +05:30
Charles-Henri Decultot
2de1cd3529 View Attachments in portal (#8830)
* View Attachments in portal

* HTML beautify correction

* Move option to shopping cart settings

* new field in shopping cart settings for public attachments display in portal
2017-05-19 16:04:10 +05:30
Gaurav Naik
7f02714c26 Documentation for Allow Login using Mobile Number (#8918) 2017-05-19 16:03:05 +05:30
Charles-Henri Decultot
8bec0239b9 Prompt for mandatory batch number in POS (#8928)
* Prompt for mandatory batch number in POS

* Whitespaces correction
2017-05-19 16:02:30 +05:30
Manas Solanki
56549fd3d9 link the different doctype in the school module (#8844) 2017-05-19 15:16:50 +05:30
Abdulla P I
6cbc9b03f9 Update lead.py (#8789)
* Update lead.py

Import datetime to compare next contact date with now()

* Update lead.py

* Update lead.py

As per the suggestion from Nabin,instead of Datetime,getdate and nowdate from frappe.utils imported
2017-05-19 15:15:36 +05:30
KanchanChauhan
32cbbe5cc2 Website Specification Labls should not be capitalised by default (#8798) 2017-05-19 15:14:31 +05:30
880 changed files with 119612 additions and 59644 deletions

137
.eslintrc Normal file
View File

@@ -0,0 +1,137 @@
{
"env": {
"browser": true,
"node": true,
"es6": true
},
"extends": "eslint:recommended",
"rules": {
"indent": [
"error",
"tab",
{ "SwitchCase": 1 }
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"off"
],
"semi": [
"warn",
"always"
],
"camelcase": [
"off"
],
"no-unused-vars": [
"warn"
],
"no-redeclare": [
"warn"
],
"no-console": [
"warn"
],
"no-extra-boolean-cast": [
"off"
],
"no-control-regex": [
"off"
],
"spaced-comment": [
"warn"
],
"no-trailing-spaces": [
"warn"
]
},
"root": true,
"globals": {
"frappe": true,
"erpnext": true,
"schools": true,
"$": true,
"jQuery": true,
"moment": true,
"hljs": true,
"Awesomplete": true,
"CalHeatMap": true,
"Sortable": true,
"Showdown": true,
"Taggle": true,
"Gantt": true,
"Slick": true,
"PhotoSwipe": true,
"PhotoSwipeUI_Default": true,
"fluxify": true,
"io": true,
"c3": true,
"__": true,
"_p": true,
"_f": true,
"repl": true,
"Class": true,
"locals": true,
"cint": true,
"cstr": true,
"cur_frm": true,
"cur_dialog": true,
"cur_page": true,
"cur_list": true,
"cur_tree": true,
"msg_dialog": true,
"is_null": true,
"in_list": true,
"has_common": true,
"has_words": true,
"validate_email": true,
"get_number_format": true,
"format_number": true,
"format_currency": true,
"round_based_on_smallest_currency_fraction": true,
"roundNumber": true,
"comment_when": true,
"replace_newlines": true,
"open_url_post": true,
"toTitle": true,
"lstrip": true,
"strip": true,
"strip_html": true,
"replace_all": true,
"flt": true,
"precision": true,
"md5": true,
"CREATE": true,
"AMEND": true,
"CANCEL": true,
"copy_dict": true,
"get_number_format_info": true,
"print_table": true,
"Layout": true,
"web_form_settings": true,
"$c": true,
"$a": true,
"$i": true,
"$bg": true,
"$y": true,
"$c_obj": true,
"$c_obj_csv": true,
"refresh_many": true,
"refresh_field": true,
"toggle_field": true,
"get_field_obj": true,
"get_query_params": true,
"unhide_field": true,
"hide_field": true,
"set_field_options": true,
"getCookie": true,
"getCookies": true,
"get_url_arg": true,
"get_server_fields": true,
"set_multiple": true,
"QUnit": true
}
}

View File

@@ -1,5 +1,6 @@
language: python
dist: trusty
group: deprecated-2017Q2
python:
- "2.7"

46
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@frappe.io. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -2,8 +2,7 @@
from __future__ import unicode_literals
import frappe
__version__ = '8.0.49'
__version__ = '8.3.2'
def get_default_company(user=None):
'''Get default company for user'''
@@ -36,12 +35,13 @@ def get_company_currency(company):
frappe.flags.company_currency[company] = frappe.db.get_value('Company', company, 'default_currency')
return frappe.flags.company_currency[company]
def set_perpetual_inventory(enable=1, company=None):
if not company:
company = "_Test Company" if frappe.flags.in_test else get_default_company()
def set_perpetual_inventory(enable=1):
accounts_settings = frappe.get_doc("Accounts Settings")
accounts_settings.auto_accounting_for_stock = enable
accounts_settings.save()
company = frappe.get_doc("Company", company)
company.enable_perpetual_inventory = enable
company.save()
def encode_company_abbr(name, company):
'''Returns name encoded with company abbreviation'''
@@ -53,4 +53,15 @@ def encode_company_abbr(name, company):
return " - ".join(parts)
def is_perpetual_inventory_enabled(company):
if not company:
company = "_Test Company" if frappe.flags.in_test else get_default_company()
if not hasattr(frappe.local, 'enable_perpetual_inventory'):
frappe.local.enable_perpetual_inventory = {}
if not company in frappe.local.enable_perpetual_inventory:
frappe.local.enable_perpetual_inventory[company] = frappe.db.get_value("Company",
company, "enable_perpetual_inventory") or 0
return frappe.local.enable_perpetual_inventory[company]

View File

@@ -2,26 +2,26 @@
// License: GNU General Public License v3. See license.txt
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
if(doc.__islocal) {
msgprint(__("Please create new account from Chart of Accounts."));
cur_frm.cscript.refresh = function (doc, cdt, cdn) {
if (doc.__islocal) {
frappe.msgprint(__("Please create new account from Chart of Accounts."));
throw "cannot create";
}
cur_frm.toggle_display('account_name', doc.__islocal);
// hide fields if group
cur_frm.toggle_display(['account_type', 'tax_rate'], cint(doc.is_group)==0)
cur_frm.toggle_display(['account_type', 'tax_rate'], cint(doc.is_group) == 0)
// disable fields
cur_frm.toggle_enable(['account_name', 'is_group', 'company'], false);
if(cint(doc.is_group)==0) {
if (cint(doc.is_group) == 0) {
cur_frm.toggle_display('freeze_account', doc.__onload && doc.__onload.can_freeze_account);
}
// read-only for root accounts
if(!doc.parent_account) {
if (!doc.parent_account) {
cur_frm.set_read_only();
cur_frm.set_intro(__("This is a root account and cannot be edited."));
} else {
@@ -38,53 +38,53 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) {
cur_frm.add_fetch('parent_account', 'report_type', 'report_type');
cur_frm.add_fetch('parent_account', 'root_type', 'root_type');
cur_frm.cscript.account_type = function(doc, cdt, cdn) {
if(doc.is_group==0) {
cur_frm.cscript.account_type = function (doc, cdt, cdn) {
if (doc.is_group == 0) {
cur_frm.toggle_display(['tax_rate'], doc.account_type == 'Tax');
cur_frm.toggle_display('warehouse', doc.account_type=='Stock');
cur_frm.toggle_display('warehouse', doc.account_type == 'Stock');
}
}
cur_frm.cscript.add_toolbar_buttons = function(doc) {
cur_frm.cscript.add_toolbar_buttons = function (doc) {
cur_frm.add_custom_button(__('Chart of Accounts'),
function() { frappe.set_route("Tree", "Account"); });
function () { frappe.set_route("Tree", "Account"); });
if (doc.is_group == 1) {
cur_frm.add_custom_button(__('Group to Non-Group'),
function() { cur_frm.cscript.convert_to_ledger(); }, 'fa fa-retweet', 'btn-default');
function () { cur_frm.cscript.convert_to_ledger(); }, 'fa fa-retweet', 'btn-default');
} else if (cint(doc.is_group) == 0) {
cur_frm.add_custom_button(__('Ledger'), function() {
cur_frm.add_custom_button(__('Ledger'), function () {
frappe.route_options = {
"account": doc.name,
"from_date": sys_defaults.year_start_date,
"to_date": sys_defaults.year_end_date,
"from_date": frappe.sys_defaults.year_start_date,
"to_date": frappe.sys_defaults.year_end_date,
"company": doc.company
};
frappe.set_route("query-report", "General Ledger");
});
cur_frm.add_custom_button(__('Non-Group to Group'),
function() { cur_frm.cscript.convert_to_group(); }, 'fa fa-retweet', 'btn-default')
function () { cur_frm.cscript.convert_to_group(); }, 'fa fa-retweet', 'btn-default')
}
}
cur_frm.cscript.convert_to_ledger = function(doc, cdt, cdn) {
return $c_obj(cur_frm.doc,'convert_group_to_ledger','',function(r,rt) {
if(r.message == 1) {
cur_frm.refresh();
}
});
cur_frm.cscript.convert_to_ledger = function (doc, cdt, cdn) {
return $c_obj(cur_frm.doc, 'convert_group_to_ledger', '', function (r, rt) {
if (r.message == 1) {
cur_frm.refresh();
}
});
}
cur_frm.cscript.convert_to_group = function(doc, cdt, cdn) {
return $c_obj(cur_frm.doc,'convert_ledger_to_group','',function(r,rt) {
if(r.message == 1) {
cur_frm.refresh();
}
});
cur_frm.cscript.convert_to_group = function (doc, cdt, cdn) {
return $c_obj(cur_frm.doc, 'convert_ledger_to_group', '', function (r, rt) {
if (r.message == 1) {
cur_frm.refresh();
}
});
}
cur_frm.fields_dict['parent_account'].get_query = function(doc) {
cur_frm.fields_dict['parent_account'].get_query = function (doc) {
return {
filters: {
"is_group": 1,

View File

@@ -1,5 +1,6 @@
{
"allow_copy": 1,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"beta": 0,
@@ -402,35 +403,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "warehouse",
"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": "Warehouse",
"length": 0,
"no_copy": 0,
"options": "Warehouse",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@@ -545,18 +517,18 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-money",
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-02-17 16:22:49.249075",
"modified": "2017-04-21 17:22:41.150984",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Account",

View File

@@ -35,7 +35,6 @@ class Account(Document):
self.validate_group_or_ledger()
self.set_root_and_report_type()
self.validate_mandatory()
self.validate_warehouse_account()
self.validate_frozen_accounts_modifier()
self.validate_balance_must_be_debit_or_credit()
self.validate_account_currency()
@@ -162,46 +161,6 @@ class Account(Document):
if not self.report_type:
throw(_("Report Type is mandatory"))
def validate_warehouse_account(self):
'''If perpetual inventory is set, and warehouse is linked,
the account balance and stock balance as of now must always match.
'''
from erpnext.accounts.utils import get_balance_on
from erpnext.stock.utils import get_stock_value_on
if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
return
if self.account_type == "Stock":
if self.is_group == 0 and not self.warehouse:
frappe.throw(_("Warehouse is mandatory for non group Accounts of type Stock"))
if self.warehouse:
# company must be same
if frappe.get_value('Warehouse', self.warehouse, 'company') != self.company:
frappe.throw(_("Warehouse company must be same as Account company"))
# balance must be same
stock_balance = get_stock_value_on(self.warehouse)
if self.is_new():
account_balance = 0.0
else:
account_balance = get_balance_on(self.name)
if account_balance != stock_balance:
frappe.throw(_('Account balance ({0}) for {1} and stock value ({2}) for warehouse {3} must be same')
.format(fmt_money(account_balance, currency=self.account_currency), self.name,
fmt_money(stock_balance, currency=self.account_currency), self.warehouse))
elif self.warehouse:
self.warehouse = None
def validate_warehouse(self, warehouse):
lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
if lft and rgt:
if frappe.db.sql_list("""select sle.name from `tabStock Ledger Entry` sle where exists (select wh.name from
tabWarehouse wh where lft >= %s and rgt <= %s and sle.warehouse = wh.name)""", (lft, rgt)):
throw(_("Stock entries exist against Warehouse {0}, hence you cannot re-assign or modify it").format(warehouse))
def update_nsm_model(self):
"""update lft, rgt indices for nested set model"""

View File

@@ -37,16 +37,6 @@ frappe.treeview_settings["Account"] = {
},
{fieldtype:'Float', fieldname:'tax_rate', label:__('Tax Rate'),
depends_on: 'eval:doc.is_group==0&&doc.account_type=="Tax"'},
{fieldtype:'Link', fieldname:'warehouse', label:__('Warehouse'), options:"Warehouse",
depends_on: 'eval:(!doc.is_group&&doc.account_type=="Stock")',
get_query: function() {
return {
filters:{
"company": frappe.treeview_settings.filters["company"]
}
}
}
},
{fieldtype:'Link', fieldname:'account_currency', label:__('Currency'), options:"Currency",
description: __("Optional. Sets company's default currency, if not specified.")}
],
@@ -72,8 +62,8 @@ frappe.treeview_settings["Account"] = {
click: function(node, btn) {
frappe.route_options = {
"account": node.label,
"from_date": sys_defaults.year_start_date,
"to_date": sys_defaults.year_end_date,
"from_date": frappe.sys_defaults.year_start_date,
"to_date": frappe.sys_defaults.year_end_date,
"company": frappe.defaults.get_default('company') ? frappe.defaults.get_default('company'): ""
};
frappe.set_route("query-report", "General Ledger");

View File

@@ -117,7 +117,7 @@ def get_charts_for_country(country):
def get_account_tree_from_existing_company(existing_company):
all_accounts = frappe.get_all('Account',
filters={'company': existing_company, "warehouse": ""},
filters={'company': existing_company},
fields = ["name", "account_name", "parent_account", "account_type",
"is_group", "root_type", "tax_rate"],
order_by="lft, rgt")

View File

@@ -88,7 +88,6 @@
"Items Delivered to Customs on temprary Base": {}
},
"Stock in Hand": {
"is_group": 1,
"account_type": "Stock"
}
},

View File

@@ -65,8 +65,9 @@
"account_type": "Fixed Asset"
},
"Stock": {
"account_type": "Stock",
"is_group": 1
"Stock in Hand": {
"account_type": "Stock"
}
},
"root_type": "Asset"
},

View File

@@ -26,8 +26,9 @@
"Earnest Money": {}
},
"Stock Assets": {
"account_type": "Stock",
"is_group": 1
"Stock in Hand": {
"account_type": "Stock"
}
},
"Tax Assets": {
"is_group": 1

View File

@@ -40,8 +40,9 @@
"Rental Deposits": {}
},
"Stock Assets": {
"is_group": 1,
"account_type": "Stock"
"Stock in Hand": {
"account_type": "Stock"
}
},
"Tax Assets": {
"GST-Input": {}

View File

@@ -40,8 +40,9 @@
"Rental Deposits": {}
},
"Stock Assets": {
"account_type": "Stock",
"is_group": 1
"Stock in Hand": {
"account_type": "Stock"
}
},
"Tax Assets": {
"GST-Input": {}

View File

@@ -30,8 +30,10 @@ def get():
_("Earnest Money"): {}
},
_("Stock Assets"): {
_("Stock In Hand"): {
"account_type": "Stock"
},
"account_type": "Stock",
"is_group": 1
},
_("Tax Assets"): {
"is_group": 1

View File

@@ -3,6 +3,8 @@
from __future__ import unicode_literals
import frappe
from erpnext.stock import get_warehouse_account, get_company_default_inventory_account
def _make_test_records(verbose):
from frappe.test_runner import make_test_objects
@@ -63,3 +65,24 @@ def _make_test_records(verbose):
} for account_name, parent_account, is_group, account_type, currency in accounts])
return test_objects
def get_inventory_account(company, warehouse=None):
account = None
if warehouse:
account = get_warehouse_account(warehouse, company)
else:
account = get_company_default_inventory_account(company)
return account
def create_account(**kwargs):
account = frappe.get_doc(dict(
doctype = "Account",
account_name = kwargs.get('account_name'),
account_type = kwargs.get('account_type'),
parent_account = kwargs.get('parent_account'),
company = kwargs.get('company')
))
account.save()
return account.name

View File

@@ -14,6 +14,7 @@
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -22,7 +23,7 @@
"description": "If enabled, the system will post accounting entries for inventory automatically.",
"fieldname": "auto_accounting_for_stock",
"fieldtype": "Check",
"hidden": 0,
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
@@ -44,6 +45,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -73,6 +75,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -103,6 +106,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -131,6 +135,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -161,6 +166,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -190,6 +196,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -219,6 +226,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -249,6 +257,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -290,7 +299,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2017-04-18 13:35:59.166250",
"modified": "2017-06-16 17:39:50.614522",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",

View File

@@ -11,24 +11,4 @@ from frappe.model.document import Document
class AccountsSettings(Document):
def on_update(self):
frappe.db.set_default("auto_accounting_for_stock", self.auto_accounting_for_stock)
if cint(self.auto_accounting_for_stock):
# set default perpetual account in company
for company in frappe.db.sql("select name from tabCompany"):
company = frappe.get_doc("Company", company[0])
company.flags.ignore_permissions = True
company.save()
# Create account head for warehouses
warehouse_list = frappe.db.sql("""select name, company from tabWarehouse
where disabled=0""", as_dict=1)
warehouse_with_no_company = [d.name for d in warehouse_list if not d.company]
if warehouse_with_no_company:
frappe.throw(_("Company is missing in warehouses {0}")
.format(comma_and(warehouse_with_no_company)))
for wh in warehouse_list:
wh_doc = frappe.get_doc("Warehouse", wh.name)
wh_doc.flags.ignore_permissions = True
wh_doc.save()
pass

View File

@@ -14,7 +14,7 @@ frappe.ui.form.on('Asset', {
}
};
});
frm.set_query("warehouse", function() {
return {
"filters": {
@@ -24,12 +24,12 @@ frappe.ui.form.on('Asset', {
};
});
},
refresh: function(frm) {
frappe.ui.form.trigger("Asset", "is_existing_asset");
frm.toggle_display("next_depreciation_date", frm.doc.docstatus < 1);
frm.events.make_schedules_editable(frm);
if (frm.doc.docstatus==1) {
if (frm.doc.status=='Submitted' && !frm.doc.is_existing_asset && !frm.doc.purchase_invoice) {
frm.add_custom_button("Make Purchase Invoice", function() {
@@ -40,60 +40,60 @@ frappe.ui.form.on('Asset', {
frm.add_custom_button("Transfer Asset", function() {
erpnext.asset.transfer_asset(frm);
});
frm.add_custom_button("Scrap Asset", function() {
erpnext.asset.scrap_asset(frm);
});
frm.add_custom_button("Sell Asset", function() {
erpnext.asset.make_sales_invoice(frm);
});
} else if (frm.doc.status=='Scrapped') {
frm.add_custom_button("Restore Asset", function() {
erpnext.asset.restore_asset(frm);
});
}
frm.trigger("show_graph");
}
},
show_graph: function(frm) {
show_graph: function(frm) {
var x_intervals = ["x", frm.doc.purchase_date];
var asset_values = ["Asset Value", frm.doc.gross_purchase_amount];
var last_depreciation_date = frm.doc.purchase_date;
if(frm.doc.opening_accumulated_depreciation) {
last_depreciation_date = frappe.datetime.add_months(frm.doc.next_depreciation_date,
last_depreciation_date = frappe.datetime.add_months(frm.doc.next_depreciation_date,
-1*frm.doc.frequency_of_depreciation);
x_intervals.push(last_depreciation_date);
asset_values.push(flt(frm.doc.gross_purchase_amount) -
asset_values.push(flt(frm.doc.gross_purchase_amount) -
flt(frm.doc.opening_accumulated_depreciation));
}
$.each(frm.doc.schedules || [], function(i, v) {
x_intervals.push(v.schedule_date);
asset_value = flt(frm.doc.gross_purchase_amount) - flt(v.accumulated_depreciation_amount);
if(v.journal_entry) {
var asset_value = flt(frm.doc.gross_purchase_amount) - flt(v.accumulated_depreciation_amount);
if(v.journal_entry) {
last_depreciation_date = v.schedule_date;
asset_values.push(asset_value)
} else {
if (in_list(["Scrapped", "Sold"], frm.doc.status)) {
asset_values.push(null)
asset_values.push(null)
} else {
asset_values.push(asset_value)
}
}
})
if(in_list(["Scrapped", "Sold"], frm.doc.status)) {
x_intervals.push(frm.doc.disposal_date);
asset_values.push(0);
last_depreciation_date = frm.doc.disposal_date;
}
frm.dashboard.setup_chart({
data: {
x: 'x',
@@ -117,9 +117,9 @@ frappe.ui.form.on('Asset', {
padding: {bottom: 10}
}
}
});
});
},
item_code: function(frm) {
if(frm.doc.item_code) {
frappe.call({
@@ -137,27 +137,27 @@ frappe.ui.form.on('Asset', {
})
}
},
is_existing_asset: function(frm) {
frm.toggle_enable("supplier", frm.doc.is_existing_asset);
frm.toggle_reqd("next_depreciation_date", !frm.doc.is_existing_asset);
},
opening_accumulated_depreciation: function(frm) {
erpnext.asset.set_accululated_depreciation(frm);
},
depreciation_method: function(frm) {
frm.events.make_schedules_editable(frm);
},
make_schedules_editable: function(frm) {
var is_editable = frm.doc.depreciation_method==="Manual" ? true : false;
frm.toggle_enable("schedules", is_editable);
frm.fields_dict["schedules"].grid.toggle_enable("schedule_date", is_editable);
frm.fields_dict["schedules"].grid.toggle_enable("depreciation_amount", is_editable);
}
});
frappe.ui.form.on('Depreciation Schedule', {
@@ -177,7 +177,7 @@ frappe.ui.form.on('Depreciation Schedule', {
})
}
},
depreciation_amount: function(frm, cdt, cdn) {
erpnext.asset.set_accululated_depreciation(frm);
}
@@ -186,11 +186,11 @@ frappe.ui.form.on('Depreciation Schedule', {
erpnext.asset.set_accululated_depreciation = function(frm) {
if(frm.doc.depreciation_method != "Manual") return;
accumulated_depreciation = flt(frm.doc.opening_accumulated_depreciation);
var accumulated_depreciation = flt(frm.doc.opening_accumulated_depreciation);
$.each(frm.doc.schedules || [], function(i, row) {
accumulated_depreciation += flt(row.depreciation_amount);
frappe.model.set_value(row.doctype, row.name,
frappe.model.set_value(row.doctype, row.name,
"accumulated_depreciation_amount", accumulated_depreciation);
})
}
@@ -260,9 +260,9 @@ erpnext.asset.transfer_asset = function(frm) {
title: __("Transfer Asset"),
fields: [
{
"label": __("Target Warehouse"),
"label": __("Target Warehouse"),
"fieldname": "target_warehouse",
"fieldtype": "Link",
"fieldtype": "Link",
"options": "Warehouse",
"get_query": function () {
return {
@@ -271,13 +271,13 @@ erpnext.asset.transfer_asset = function(frm) {
["Warehouse", "is_group", "=", 0]
]
}
},
"reqd": 1
},
"reqd": 1
},
{
"label": __("Date"),
"label": __("Date"),
"fieldname": "transfer_date",
"fieldtype": "Datetime",
"fieldtype": "Datetime",
"reqd": 1,
"default": frappe.datetime.now_datetime()
}
@@ -285,7 +285,7 @@ erpnext.asset.transfer_asset = function(frm) {
});
dialog.set_primary_action(__("Transfer"), function() {
args = dialog.get_values();
var args = dialog.get_values();
if(!args) return;
dialog.hide();
return frappe.call({

View File

@@ -19,7 +19,8 @@ class Asset(Document):
self.validate_asset_values()
self.make_depreciation_schedule()
self.set_accumulated_depreciation()
self.validate_expected_value_after_useful_life()
if self.get("schedules"):
self.validate_expected_value_after_useful_life()
# Validate depreciation related accounts
get_depreciation_accounts(self)

View File

@@ -1,3 +1,3 @@
frappe.listview_settings['Asset'] = {
add_fields: ['image']
add_fields: ['image']
}

View File

@@ -4,7 +4,7 @@
frappe.ui.form.on('Asset Movement', {
onload: function(frm) {
frm.add_fetch("asset", "warehouse", "source_warehouse");
frm.set_query("target_warehouse", function() {
return {
filters: [

View File

@@ -20,11 +20,11 @@ frappe.ui.form.on('Bank Guarantee', {
});
},
start_date: function(frm) {
end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
var end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
cur_frm.set_value("end_date", end_date);
},
validity: function(frm) {
end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
var end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
cur_frm.set_value("end_date", end_date);
}
});

View File

@@ -62,13 +62,13 @@ class BankReconciliation(Document):
for d in entries:
row = self.append('payment_entries', {})
d.amount = fmt_money(d.debit if d.debit else d.credit, 2, d.account_currency) + " " + (_("Dr") if d.debit else _("Cr"))
amount = d.debit if d.debit else d.credit
d.amount = fmt_money(amount, 2, d.account_currency) + " " + (_("Dr") if d.debit else _("Cr"))
d.pop("credit")
d.pop("debit")
d.pop("account_currency")
row.update(d)
self.total_amount += flt(d.amount)
self.total_amount += flt(amount)
def update_clearance_date(self):
clearance_date_updated = False

View File

@@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
@@ -10,6 +11,7 @@
"editable_grid": 1,
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -20,7 +22,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payment Document",
"length": 0,
"no_copy": 0,
@@ -30,6 +34,7 @@
"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,
@@ -37,17 +42,20 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 1,
"columns": 2,
"fieldname": "payment_entry",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Payment Entry",
"length": 0,
"no_copy": 0,
@@ -58,6 +66,7 @@
"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,
@@ -66,6 +75,7 @@
"width": "50"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -76,7 +86,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Against Account",
"length": 0,
"no_copy": 0,
@@ -86,6 +98,7 @@
"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,
@@ -94,6 +107,7 @@
"width": "15"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -104,7 +118,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Amount",
"length": 0,
"no_copy": 0,
@@ -115,6 +131,7 @@
"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,
@@ -122,6 +139,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -132,7 +150,9 @@
"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,
@@ -140,6 +160,7 @@
"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,
@@ -148,6 +169,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -158,7 +180,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Posting Date",
"length": 0,
"no_copy": 0,
@@ -168,6 +192,7 @@
"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,
@@ -175,17 +200,20 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 1,
"columns": 2,
"fieldname": "cheque_number",
"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": "Cheque Number",
"length": 0,
"no_copy": 0,
@@ -195,6 +223,7 @@
"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,
@@ -202,6 +231,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -212,7 +242,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Cheque Date",
"length": 0,
"no_copy": 0,
@@ -222,6 +254,7 @@
"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,
@@ -229,6 +262,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -239,7 +273,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Clearance Date",
"length": 0,
"no_copy": 0,
@@ -249,6 +285,7 @@
"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,
@@ -256,18 +293,18 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
"modified": "2016-11-17 11:39:00.308624",
"modified": "2017-06-23 12:07:50.883515",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Reconciliation Detail",
@@ -276,6 +313,8 @@
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_order": "ASC",
"track_changes": 0,
"track_seen": 0
}

View File

@@ -43,7 +43,7 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) {
cur_frm.cscript.parent_cost_center = function(doc, cdt, cdn) {
if(!doc.company){
msgprint(__('Please enter company name first'));
frappe.msgprint(__('Please enter company name first'));
}
}

View File

@@ -13,7 +13,7 @@ $.extend(cur_frm.cscript, {
this.frm.toggle_enable('year_start_date', doc.__islocal)
this.frm.toggle_enable('year_end_date', doc.__islocal)
if (!doc.__islocal && (doc.name != sys_defaults.fiscal_year)) {
if (!doc.__islocal && (doc.name != frappe.sys_defaults.fiscal_year)) {
this.frm.add_custom_button(__("Default"),
this.frm.cscript.set_as_default, "fa fa-star");
this.frm.set_intro(__("To set this Fiscal Year as Default, click on 'Set as Default'"));
@@ -30,7 +30,7 @@ $.extend(cur_frm.cscript, {
year_start_date: function(doc, dt, dn) {
var me = this;
year_end_date =
var year_end_date =
frappe.datetime.add_days(frappe.datetime.add_months(this.frm.doc.year_start_date, 12), -1);
this.frm.set_value("year_end_date", year_end_date);
},

View File

@@ -62,11 +62,10 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
if(this.frm.doc.__islocal && this.frm.doc.company) {
frappe.model.set_default_values(this.frm.doc);
$.each(this.frm.doc.accounts || [], function(i, jvd) {
frappe.model.set_default_values(jvd);
}
);
frappe.model.set_default_values(jvd);
});
if(!this.frm.doc.amended_from) this.frm.doc.posting_date = this.frm.posting_date || get_today();
if(!this.frm.doc.amended_from) this.frm.doc.posting_date = this.frm.posting_date || frappe.datetime.get_today();
}
},
@@ -124,7 +123,7 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
// account filter
frappe.model.validate_missing(jvd, "account");
party_account_field = jvd.reference_type==="Sales Invoice" ? "debit_to": "credit_to";
var party_account_field = jvd.reference_type==="Sales Invoice" ? "debit_to": "credit_to";
out.filters.push([jvd.reference_type, party_account_field, "=", jvd.account]);
} else {
// party_type and party mandatory
@@ -243,7 +242,7 @@ cur_frm.cscript.update_totals = function(doc) {
cur_frm.cscript.get_balance = function(doc,dt,dn) {
cur_frm.cscript.update_totals(doc);
return $c_obj(cur_frm.doc, 'get_balance', '', function(r, rt){
cur_frm.refresh();
cur_frm.refresh();
});
}

View File

@@ -1311,7 +1311,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:inList([\"Credit Note\", \"Debit Note\"], doc.voucher_type)",
"depends_on": "eval:in_list([\"Credit Note\", \"Debit Note\"], doc.voucher_type)",
"fieldname": "stock_entry",
"fieldtype": "Link",
"hidden": 0,

View File

@@ -733,11 +733,10 @@ def get_opening_accounts(company):
accounts = frappe.db.sql_list("""select
name from tabAccount
where
is_group=0 and
report_type='Balance Sheet' and
ifnull(warehouse, '') = '' and
company=%s
order by name asc""", company)
is_group=0 and report_type='Balance Sheet' and company=%s and
name not in(select distinct account from tabWarehouse where
account is not null and account != '')
order by name asc""", frappe.db.escape(company))
return [{"account": a, "balance": get_balance_on(a)} for a in accounts]
@@ -871,14 +870,9 @@ def get_exchange_rate(posting_date, account=None, account_currency=None, company
if reference_type in ("Sales Invoice", "Purchase Invoice") and reference_name:
exchange_rate = frappe.db.get_value(reference_type, reference_name, "conversion_rate")
elif account_details and account_details.account_type == "Bank" and \
((account_details.root_type == "Asset" and flt(credit) > 0) or
(account_details.root_type == "Liability" and debit)):
exchange_rate = get_average_exchange_rate(account)
# The date used to retreive the exchange rate here is the date passed
# in as an argument to this function.
if not exchange_rate and account_currency and posting_date:
elif (not exchange_rate or exchange_rate==1) and account_currency and posting_date:
exchange_rate = get_exchange_rate(account_currency, company_currency, posting_date)
else:
exchange_rate = 1

View File

@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import unittest, frappe
from frappe.utils import flt
from erpnext.accounts.doctype.account.test_account import get_inventory_account
from erpnext.exceptions import InvalidAccountCurrency
@@ -83,7 +84,8 @@ class TestJournalEntry(unittest.TestCase):
jv = frappe.copy_doc(test_records[0])
jv.get("accounts")[0].update({
"account": "_Test Warehouse - _TC",
"account": get_inventory_account('_Test Company'),
"company": "_Test Company",
"party_type": None,
"party": None
})

View File

@@ -25,4 +25,5 @@ class ModeofPayment(Document):
for entry in self.accounts:
"""Error when Company of Ledger account doesn't match with Company Selected"""
if frappe.db.get_value("Account", entry.default_account, "company") != entry.company:
frappe.throw(_("Account does not match with Company"))
frappe.throw(_("Account {0} does not match with Company {1} in Mode of Account: {2}")
.format(entry.default_account, entry.company, self.name))

View File

@@ -2,13 +2,13 @@
// License: GNU General Public License v3. See license.txt
cur_frm.cscript.onload = function(doc,cdt,cdn){
if(doc.__islocal){
var callback1 = function(r,rt){
refresh_field('percentages');
}
if(doc.__islocal){
var callback1 = function(r,rt){
refresh_field('percentages');
}
return $c('runserverobj',args={'method':'get_months', 'docs':doc}, callback1);
}
return $c('runserverobj', {'method':'get_months', 'docs':doc}, callback1);
}
}
cur_frm.cscript.refresh = function(doc,cdt,cdn){

View File

@@ -36,7 +36,7 @@ frappe.ui.form.on('Payment Entry', {
frm.set_query("paid_to", function() {
var party_account_type = frm.doc.party_type=="Customer" ? "Receivable" : "Payable";
var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ?
["Bank", "Cash"] : party_account_type;
["Bank", "Cash"] : party_account_type;
return {
filters: {
@@ -196,8 +196,8 @@ frappe.ui.form.on('Payment Entry', {
if(frm.doc.payment_type == "Internal Transfer") {
$.each(["party", "party_balance", "paid_from", "paid_to",
"references", "total_allocated_amount"], function(i, field) {
frm.set_value(field, null);
})
frm.set_value(field, null);
});
} else {
if(!frm.doc.party)
frm.set_value("party_type", frm.doc.payment_type=="Receive" ? "Customer" : "Supplier");
@@ -214,9 +214,10 @@ frappe.ui.form.on('Payment Entry', {
$.each(["party", "party_balance", "paid_from", "paid_to",
"paid_from_account_currency", "paid_from_account_balance",
"paid_to_account_currency", "paid_to_account_balance",
"references", "total_allocated_amount"], function(i, field) {
"references", "total_allocated_amount"],
function(i, field) {
frm.set_value(field, null);
})
})
}
},
@@ -331,10 +332,12 @@ frappe.ui.form.on('Payment Entry', {
frm.set_value("source_exchange_rate", 1);
} else if (frm.doc.paid_from){
if (in_list(["Internal Transfer", "Pay"], frm.doc.payment_type)) {
var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
frappe.call({
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_average_exchange_rate",
method: "erpnext.setup.utils.get_exchange_rate",
args: {
account: frm.doc.paid_from
from_currency: frm.doc.paid_from_account_currency,
to_currency: company_currency
},
callback: function(r, rt) {
frm.set_value("source_exchange_rate", r.message);
@@ -501,13 +504,17 @@ frappe.ui.form.on('Payment Entry', {
}
});
if((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier")) {
if(total_positive_outstanding > total_negative_outstanding)
frm.set_value("paid_amount",
total_positive_outstanding - total_negative_outstanding);
} else if (total_negative_outstanding &&
(total_positive_outstanding < total_negative_outstanding)) {
if(
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier")
) {
if(total_positive_outstanding > total_negative_outstanding)
frm.set_value("paid_amount",
total_positive_outstanding - total_negative_outstanding);
} else if (
total_negative_outstanding &&
total_positive_outstanding < total_negative_outstanding
) {
frm.set_value("received_amount",
total_negative_outstanding - total_positive_outstanding);
}
@@ -575,9 +582,11 @@ frappe.ui.form.on('Payment Entry', {
row.allocated_amount = 0 //If allocate payment amount checkbox is unchecked, set zero to allocate amount
if(frm.doc.allocate_payment_amount){
if(row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
if(row.outstanding_amount >= allocated_positive_outstanding)
row.allocated_amount = allocated_positive_outstanding;
else row.allocated_amount = row.outstanding_amount;
if(row.outstanding_amount >= allocated_positive_outstanding) {
row.allocated_amount = allocated_positive_outstanding;
} else {
row.allocated_amount = row.outstanding_amount;
}
allocated_positive_outstanding -= flt(row.allocated_amount);
} else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
@@ -595,7 +604,8 @@ frappe.ui.form.on('Payment Entry', {
},
set_total_allocated_amount: function(frm) {
var total_allocated_amount = base_total_allocated_amount = 0.0;
var total_allocated_amount = 0.0;
var base_total_allocated_amount = 0.0;
$.each(frm.doc.references || [], function(i, row) {
if (row.allocated_amount) {
total_allocated_amount += flt(row.allocated_amount);
@@ -667,19 +677,21 @@ frappe.ui.form.on('Payment Entry', {
return;
}
if(frm.doc.party_type=="Customer"
&& !in_list(["Sales Order", "Sales Invoice", "Journal Entry"], row.reference_doctype)) {
frappe.model.set_value(row.doctype, row.name, "reference_doctype", null);
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Sales Order, Sales Invoice or Journal Entry", [row.idx]));
return false;
}
if(frm.doc.party_type=="Customer" &&
!in_list(["Sales Order", "Sales Invoice", "Journal Entry"], row.reference_doctype)
) {
frappe.model.set_value(row.doctype, row.name, "reference_doctype", null);
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Sales Order, Sales Invoice or Journal Entry", [row.idx]));
return false;
}
if(frm.doc.party_type=="Supplier" && !in_list(["Purchase Order",
"Purchase Invoice", "Journal Entry"], row.reference_doctype)) {
frappe.model.set_value(row.doctype, row.name, "against_voucher_type", null);
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Purchase Order, Purchase Invoice or Journal Entry", [row.idx]));
return false;
}
if(frm.doc.party_type=="Supplier" &&
!in_list(["Purchase Order", "Purchase Invoice", "Journal Entry"], row.reference_doctype)
) {
frappe.model.set_value(row.doctype, row.name, "against_voucher_type", null);
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Purchase Order, Purchase Invoice or Journal Entry", [row.idx]));
return false;
}
}
if (row) {

View File

@@ -48,6 +48,8 @@ class PaymentEntry(AccountsController):
self.validate_transaction_reference()
self.set_title()
self.set_remarks()
self.validate_duplicate_entry()
self.validate_allocated_amount()
def on_submit(self):
self.setup_party_account_field()
@@ -61,7 +63,22 @@ class PaymentEntry(AccountsController):
self.make_gl_entries(cancel=1)
self.update_advance_paid()
self.delink_advance_entry_references()
def validate_duplicate_entry(self):
reference_names = []
for d in self.get("references"):
if (d.reference_doctype, d.reference_name) in reference_names:
frappe.throw(_("Row #{0}: Duplicate entry in References {1} {2}").format(d.idx, d.reference_doctype, d.reference_name))
reference_names.append((d.reference_doctype, d.reference_name))
def validate_allocated_amount(self):
for d in self.get("references"):
if (flt(d.allocated_amount))> 0:
if flt(d.allocated_amount) > flt(d.outstanding_amount):
frappe.throw(_("Row #{0}: Allocated Amount cannot be greater than outstanding amount.").format(d.idx))
def delink_advance_entry_references(self):
for reference in self.references:
if reference.reference_doctype in ("Sales Invoice", "Purchase Invoice"):
@@ -149,8 +166,6 @@ class PaymentEntry(AccountsController):
if self.paid_from and not self.source_exchange_rate:
if self.paid_from_account_currency == self.company_currency:
self.source_exchange_rate = 1
elif self.payment_type in ("Pay", "Internal Transfer"):
self.source_exchange_rate = get_average_exchange_rate(self.paid_from)
else:
self.source_exchange_rate = get_exchange_rate(self.paid_from_account_currency,
self.company_currency, self.posting_date)

View File

@@ -112,6 +112,34 @@ class TestPaymentEntry(unittest.TestCase):
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 80)
def test_payment_entry_retrieves_last_exchange_rate(self):
from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records, save_new_records
test_records = test_records
save_new_records(test_records)
pe = frappe.new_doc("Payment Entry")
pe.payment_type = "Pay"
pe.company = "_Test Company"
pe.posting_date = "2016-01-10"
pe.paid_from = "_Test Bank USD - _TC"
pe.paid_to = "_Test Bank - _TC"
pe.paid_amount = 100
pe.reference_no = "3"
pe.reference_date = "2016-01-10"
pe.party_type = "Supplier"
pe.party = "_Test Supplier USD"
pe.setup_party_account_field()
pe.set_missing_values()
pe.set_exchange_rate()
pe.set_amounts()
self.assertEqual(
pe.source_exchange_rate, 65.1,
"{0} is not equal to {1}".format(pe.source_exchange_rate, 65.1)
)
def test_internal_transfer_usd_to_inr(self):
pe = frappe.new_doc("Payment Entry")

View File

@@ -14,7 +14,7 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext
this.frm.set_query('receivable_payable_account', function() {
if(!me.frm.doc.company || !me.frm.doc.party_type) {
msgprint(__("Please select Company and Party Type first"));
frappe.msgprint(__("Please select Company and Party Type first"));
} else {
return{
filters: {
@@ -29,7 +29,7 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext
this.frm.set_query('bank_cash_account', function() {
if(!me.frm.doc.company) {
msgprint(__("Please select Company first"));
frappe.msgprint(__("Please select Company first"));
} else {
return{
filters:[
@@ -96,10 +96,11 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext
},
set_invoice_options: function() {
var me = this;
var invoices = [];
$.each(me.frm.doc.invoices || [], function(i, row) {
if (row.invoice_number && !inList(invoices, row.invoice_number))
if (row.invoice_number && !in_list(invoices, row.invoice_number))
invoices.push(row.invoice_type + " | " + row.invoice_number);
});
@@ -108,7 +109,7 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext
me.frm.doc.name).options = "\n" + invoices.join("\n");
$.each(me.frm.doc.payments || [], function(i, p) {
if(!inList(invoices, cstr(p.invoice_number))) p.invoice_number = null;
if(!in_list(invoices, cstr(p.invoice_number))) p.invoice_number = null;
});
}

View File

@@ -87,8 +87,8 @@ class TestPaymentRequest(unittest.TestCase):
expected_gle = dict((d[0], d) for d in [
["_Test Receivable USD - _TC", 0, 5000, si_usd.name],
[pr.payment_account, 6000.0, 0, None],
["_Test Exchange Gain/Loss - _TC", 0, 1000, None]
[pr.payment_account, 6290.0, 0, None],
["_Test Exchange Gain/Loss - _TC", 0, 1290, None]
])
gl_entries = frappe.db.sql("""select account, debit, credit, against_voucher

View File

@@ -3,7 +3,7 @@
frappe.ui.form.on('Period Closing Voucher', {
onload: function(frm) {
if (!frm.doc.transaction_date) frm.doc.transaction_date = dateutil.obj_to_str(new Date());
if (!frm.doc.transaction_date) frm.doc.transaction_date = frappe.datetime.obj_to_str(new Date());
},
setup: function(frm) {

View File

@@ -26,6 +26,23 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) {
});
});
frappe.ui.form.on('POS Profile', {
refresh: function(frm) {
if(frm.doc.company) {
frm.trigger("toggle_display_account_head");
}
},
company: function(frm) {
frm.trigger("toggle_display_account_head");
},
toggle_display_account_head: function(frm) {
frm.toggle_display('expense_account',
erpnext.is_perpetual_inventory_enabled(frm.doc.company));
}
})
// Income Account
// --------------------------------
cur_frm.fields_dict['income_account'].get_query = function(doc,cdt,cdn) {
@@ -35,8 +52,8 @@ cur_frm.fields_dict['income_account'].get_query = function(doc,cdt,cdn) {
'company': doc.company,
'account_type': "Income Account"
}
}
}
};
};
// Cost Center
@@ -47,8 +64,8 @@ cur_frm.fields_dict['cost_center'].get_query = function(doc,cdt,cdn) {
'company': doc.company,
'is_group': 0
}
}
}
};
};
// Expense Account
@@ -60,8 +77,8 @@ cur_frm.fields_dict["expense_account"].get_query = function(doc) {
"company": doc.company,
"is_group": 0
}
}
}
};
};
// ------------------ Get Print Heading ------------------------------------
cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn) {
@@ -69,13 +86,13 @@ cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn)
filters:[
['Print Heading', 'docstatus', '!=', 2]
]
}
}
};
};
cur_frm.fields_dict.user.get_query = function(doc,cdt,cdn) {
return{ query:"frappe.core.doctype.user.user.user_query"}
}
return{ query:"frappe.core.doctype.user.user.user_query"};
};
cur_frm.fields_dict.write_off_account.get_query = function(doc) {
return{
@@ -84,16 +101,16 @@ cur_frm.fields_dict.write_off_account.get_query = function(doc) {
'is_group': 0,
'company': doc.company
}
}
}
};
};
// Write off cost center
//-----------------------
// -----------------------
cur_frm.fields_dict.write_off_cost_center.get_query = function(doc) {
return{
filters:{
'is_group': 0,
'company': doc.company
}
}
}
};
};

View File

@@ -40,7 +40,7 @@
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"set_only_once": 1,
"unique": 0
},
{
@@ -1132,7 +1132,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
"depends_on": "",
"fieldname": "expense_account",
"fieldtype": "Link",
"hidden": 0,
@@ -1201,7 +1201,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-13 14:29:06.317317",
"modified": "2017-06-16 17:04:33.165676",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",

View File

@@ -2,63 +2,65 @@
// License: GNU General Public License v3. See license.txt
frappe.ui.form.on("Pricing Rule", "refresh", function(frm) {
var help_content = ['<table class="table table-bordered" style="background-color: #f9f9f9;">',
'<tr><td>',
'<h4><i class="fa fa-hand-right"></i> ',
__('Notes'),
':</h4>',
'<ul>',
'<li>',
__("Pricing Rule is made to overwrite Price List / define discount percentage, based on some criteria."),
'</li>',
'<li>',
__("If selected Pricing Rule is made for 'Price', it will overwrite Price List. Pricing Rule price is the final price, so no further discount should be applied. Hence, in transactions like Sales Order, Purchase Order etc, it will be fetched in 'Rate' field, rather than 'Price List Rate' field."),
'</li>',
'<li>',
__('Discount Percentage can be applied either against a Price List or for all Price List.'),
'</li>',
'<li>',
__('To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled.'),
'</li>',
'</ul>',
'</td></tr>',
'<tr><td>',
'<h4><i class="fa fa-question-sign"></i> ',
__('How Pricing Rule is applied?'),
'</h4>',
'<ol>',
'<li>',
__("Pricing Rule is first selected based on 'Apply On' field, which can be Item, Item Group or Brand."),
'</li>',
'<li>',
__("Then Pricing Rules are filtered out based on Customer, Customer Group, Territory, Supplier, Supplier Type, Campaign, Sales Partner etc."),
'</li>',
'<li>',
__('Pricing Rules are further filtered based on quantity.'),
'</li>',
'<li>',
__('If two or more Pricing Rules are found based on the above conditions, Priority is applied. Priority is a number between 0 to 20 while default value is zero (blank). Higher number means it will take precedence if there are multiple Pricing Rules with same conditions.'),
'</li>',
'<li>',
__('Even if there are multiple Pricing Rules with highest priority, then following internal priorities are applied:'),
'<ul>',
'<li>',
__('Item Code > Item Group > Brand'),
'</li>',
'<li>',
__('Customer > Customer Group > Territory'),
'</li>',
'<li>',
__('Supplier > Supplier Type'),
'</li>',
'</ul>',
'</li>',
'<li>',
__('If multiple Pricing Rules continue to prevail, users are asked to set Priority manually to resolve conflict.'),
'</li>',
'</ol>',
'</td></tr>',
'</table>'].join("\n");
var help_content =
`<table class="table table-bordered" style="background-color: #f9f9f9;">
<tr><td>
<h4>
<i class="fa fa-hand-right"></i>
${__('Notes')}
</h4>
<ul>
<li>
${__("Pricing Rule is made to overwrite Price List / define discount percentage, based on some criteria.")}
</li>
<li>
${__("If selected Pricing Rule is made for 'Price', it will overwrite Price List. Pricing Rule price is the final price, so no further discount should be applied. Hence, in transactions like Sales Order, Purchase Order etc, it will be fetched in 'Rate' field, rather than 'Price List Rate' field.")}
</li>
<li>
${__('Discount Percentage can be applied either against a Price List or for all Price List.')}
</li>
<li>
${__('To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled.')}
</li>
</ul>
</td></tr>
<tr><td>
<h4><i class="fa fa-question-sign"></i>
${__('How Pricing Rule is applied?')}
</h4>
<ol>
<li>
${__("Pricing Rule is first selected based on 'Apply On' field, which can be Item, Item Group or Brand.")}
</li>
<li>
${__("Then Pricing Rules are filtered out based on Customer, Customer Group, Territory, Supplier, Supplier Type, Campaign, Sales Partner etc.")}
</li>
<li>
${__('Pricing Rules are further filtered based on quantity.')}
</li>
<li>
${__('If two or more Pricing Rules are found based on the above conditions, Priority is applied. Priority is a number between 0 to 20 while default value is zero (blank). Higher number means it will take precedence if there are multiple Pricing Rules with same conditions.')}
</li>
<li>
${__('Even if there are multiple Pricing Rules with highest priority, then following internal priorities are applied:')}
<ul>
<li>
${__('Item Code > Item Group > Brand')}
</li>
<li>
${__('Customer > Customer Group > Territory')}
</li>
<li>
${__('Supplier > Supplier Type')}
</li>
</ul>
</li>
<li>
${__('If multiple Pricing Rules continue to prevail, users are asked to set Priority manually to resolve conflict.')}
</li>
</ol>
</td></tr>
</table>`;
set_field_options("pricing_rule_help", help_content);

View File

@@ -101,8 +101,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
account: this.frm.doc.credit_to,
price_list: this.frm.doc.buying_price_list,
}, function() {
me.apply_pricing_rule();
})
me.apply_pricing_rule();
})
},
credit_to: function() {
@@ -130,7 +130,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
if(cint(this.frm.doc.is_paid)) {
if(!this.frm.doc.company) {
this.frm.set_value("is_paid", 0)
msgprint(__("Please specify Company to proceed"));
frappe.msgprint(__("Please specify Company to proceed"));
}
}
this.calculate_outstanding_amount();
@@ -195,19 +195,19 @@ cur_frm.script_manager.make(erpnext.accounts.PurchaseInvoice);
// Hide Fields
// ------------
function hide_fields(doc) {
parent_fields = ['due_date', 'is_opening', 'advances_section', 'from_date', 'to_date'];
var parent_fields = ['due_date', 'is_opening', 'advances_section', 'from_date', 'to_date'];
if(cint(doc.is_paid) == 1) {
hide_field(parent_fields);
} else {
for (i in parent_fields) {
for (var i in parent_fields) {
var docfield = frappe.meta.docfield_map[doc.doctype][parent_fields[i]];
if(!docfield.hidden) unhide_field(parent_fields[i]);
}
}
item_fields_stock = ['warehouse_section', 'received_qty', 'rejected_qty'];
var item_fields_stock = ['warehouse_section', 'received_qty', 'rejected_qty'];
cur_frm.fields_dict['items'].grid.set_column_disp(item_fields_stock,
(cint(doc.update_stock)==1 || cint(doc.is_return)==1 ? true : false));
@@ -224,9 +224,9 @@ cur_frm.fields_dict.cash_bank_account.get_query = function(doc) {
return {
filters: [
["Account", "account_type", "in", ["Cash", "Bank"]],
["Account", "root_type", "=", "Asset"],
["Account", "is_group", "=",0],
["Account", "company", "=", doc.company]
["Account", "company", "=", doc.company],
["Account", "report_type", "=", "Balance Sheet"]
]
}
}

View File

@@ -3238,7 +3238,7 @@
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"in_standard_filter": 1,
"label": "Status",
"length": 0,
"no_copy": 0,
@@ -3767,10 +3767,11 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-06-13 14:28:57.930167",
"modified": "2017-06-29 10:48:09.707735",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",
"name_case": "Title Case",
"owner": "Administrator",
"permissions": [
{

View File

@@ -11,7 +11,7 @@ from erpnext.controllers.buying_controller import BuyingController
from erpnext.accounts.party import get_party_account, get_due_date
from erpnext.accounts.utils import get_account_currency, get_fiscal_year
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import update_billed_amount_based_on_po
from erpnext.controllers.stock_controller import get_warehouse_account
from erpnext.stock import get_warehouse_account_map
from erpnext.accounts.general_ledger import make_gl_entries, merge_similar_entries, delete_gl_entries
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
from erpnext.buying.utils import check_for_closed_status
@@ -59,6 +59,7 @@ class PurchaseInvoice(BuyingController):
self.check_for_closed_status()
self.validate_with_previous_doc()
self.validate_uom_is_integer("uom", "qty")
self.validate_uom_is_integer("stock_uom", "stock_qty")
self.set_expense_account(for_validate=True)
self.set_against_expense_account()
self.validate_write_off_account()
@@ -163,7 +164,7 @@ class PurchaseInvoice(BuyingController):
frappe.msgprint(_("Item Code required at Row No {0}").format(d.idx), raise_exception=True)
def set_expense_account(self, for_validate=False):
auto_accounting_for_stock = cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
auto_accounting_for_stock = erpnext.is_perpetual_inventory_enabled(self.company)
if auto_accounting_for_stock:
stock_not_billed_account = self.get_company_default("stock_received_but_not_billed")
@@ -172,7 +173,7 @@ class PurchaseInvoice(BuyingController):
if self.update_stock:
self.validate_item_code()
self.validate_warehouse()
warehouse_account = get_warehouse_account()
warehouse_account = get_warehouse_account_map()
for item in self.get("items"):
# in case of auto inventory accounting,
@@ -185,7 +186,7 @@ class PurchaseInvoice(BuyingController):
not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")):
if self.update_stock:
item.expense_account = warehouse_account[item.warehouse]["name"]
item.expense_account = warehouse_account[item.warehouse]["account"]
else:
item.expense_account = stock_not_billed_account
@@ -204,14 +205,14 @@ class PurchaseInvoice(BuyingController):
if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes':
for d in self.get('items'):
if not d.purchase_order:
throw(_("Purchase Order number required for Item {0}").format(d.item_code))
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))
def pr_required(self):
stock_items = self.get_stock_items()
if frappe.db.get_value("Buying Settings", None, "pr_required") == 'Yes':
for d in self.get('items'):
if not d.purchase_receipt and d.item_code in stock_items:
throw(_("Purchase Receipt number required for Item {0}").format(d.item_code))
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))
def validate_write_off_account(self):
if self.write_off_amount and not self.write_off_account:
@@ -334,9 +335,7 @@ class PurchaseInvoice(BuyingController):
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
def get_gl_entries(self, warehouse_account=None):
self.auto_accounting_for_stock = \
cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
self.auto_accounting_for_stock = erpnext.is_perpetual_inventory_enabled(self.company)
self.stock_received_but_not_billed = self.get_company_default("stock_received_but_not_billed")
self.expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
self.negative_expense_to_be_booked = 0.0
@@ -377,7 +376,7 @@ class PurchaseInvoice(BuyingController):
# item gl entries
stock_items = self.get_stock_items()
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
warehouse_account = get_warehouse_account()
warehouse_account = get_warehouse_account_map()
for item in self.get("items"):
if flt(item.base_net_amount):

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import unittest
import frappe
import frappe, erpnext
import frappe.model
from frappe.utils import cint, flt, today, nowdate
import frappe.defaults
@@ -12,6 +12,7 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_per
test_records as pr_test_records
from erpnext.exceptions import InvalidCurrency
from erpnext.stock.doctype.stock_entry.test_stock_entry import get_qty_after_transaction
from erpnext.accounts.doctype.account.test_account import get_inventory_account
test_dependencies = ["Item", "Cost Center"]
test_ignore = ["Serial No"]
@@ -24,11 +25,10 @@ class TestPurchaseInvoice(unittest.TestCase):
def tearDown(self):
unlink_payment_on_cancel_of_invoice(0)
def test_gl_entries_without_auto_accounting_for_stock(self):
set_perpetual_inventory(0)
self.assertTrue(not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")))
def test_gl_entries_without_perpetual_inventory(self):
wrapper = frappe.copy_doc(test_records[0])
set_perpetual_inventory(0, wrapper.company)
self.assertTrue(not cint(erpnext.is_perpetual_inventory_enabled(wrapper.company)))
wrapper.insert()
wrapper.submit()
wrapper.load_from_db()
@@ -50,17 +50,16 @@ class TestPurchaseInvoice(unittest.TestCase):
for d in gl_entries:
self.assertEqual([d.debit, d.credit], expected_gl_entries.get(d.account))
def test_gl_entries_with_auto_accounting_for_stock(self):
set_perpetual_inventory(1)
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
def test_gl_entries_with_perpetual_inventory(self):
pi = frappe.copy_doc(test_records[1])
set_perpetual_inventory(1, pi.company)
self.assertTrue(cint(erpnext.is_perpetual_inventory_enabled(pi.company)), 1)
pi.insert()
pi.submit()
self.check_gle_for_pi(pi.name)
set_perpetual_inventory(0)
set_perpetual_inventory(0, pi.company)
def test_payment_entry_unlink_against_purchase_invoice(self):
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
@@ -83,11 +82,10 @@ class TestPurchaseInvoice(unittest.TestCase):
self.assertRaises(frappe.LinkExistsError, pi_doc.cancel)
def test_gl_entries_with_auto_accounting_for_stock_against_pr(self):
set_perpetual_inventory(1)
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
def test_gl_entries_with_perpetual_inventory_against_pr(self):
pr = frappe.copy_doc(pr_test_records[0])
set_perpetual_inventory(1, pr.company)
self.assertTrue(cint(erpnext.is_perpetual_inventory_enabled(pr.company)), 1)
pr.submit()
pi = frappe.copy_doc(test_records[1])
@@ -98,7 +96,7 @@ class TestPurchaseInvoice(unittest.TestCase):
self.check_gle_for_pi(pi.name)
set_perpetual_inventory(0)
set_perpetual_inventory(0, pr.company)
def check_gle_for_pi(self, pi):
gl_entries = frappe.db.sql("""select account, debit, credit
@@ -132,10 +130,9 @@ class TestPurchaseInvoice(unittest.TestCase):
self.assertRaises(frappe.CannotChangeConstantError, pi.save)
def test_gl_entries_with_aia_for_non_stock_items(self):
set_perpetual_inventory()
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
pi = frappe.copy_doc(test_records[1])
set_perpetual_inventory(1, pi.company)
self.assertTrue(cint(erpnext.is_perpetual_inventory_enabled(pi.company)), 1)
pi.get("items")[0].item_code = "_Test Non Stock Item"
pi.get("items")[0].expense_account = "_Test Account Cost for Goods Sold - _TC"
pi.get("taxes").pop(0)
@@ -158,7 +155,7 @@ class TestPurchaseInvoice(unittest.TestCase):
self.assertEquals(expected_values[i][0], gle.account)
self.assertEquals(expected_values[i][1], gle.debit)
self.assertEquals(expected_values[i][2], gle.credit)
set_perpetual_inventory(0)
set_perpetual_inventory(0, pi.company)
def test_purchase_invoice_calculation(self):
pi = frappe.copy_doc(test_records[0])
@@ -370,10 +367,11 @@ class TestPurchaseInvoice(unittest.TestCase):
order by account asc""", pi.name, as_dict=1)
self.assertTrue(gl_entries)
stock_in_hand_account = get_inventory_account(pi.company, pi.get("items")[0].warehouse)
expected_gl_entries = dict((d[0], d) for d in [
[pi.credit_to, 0.0, 250.0],
[pi.items[0].warehouse, 250.0, 0.0]
[stock_in_hand_account, 250.0, 0.0]
])
for i, gle in enumerate(gl_entries):
@@ -390,12 +388,13 @@ class TestPurchaseInvoice(unittest.TestCase):
sum(credit) as credit, debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
group by account, voucher_no order by account asc;""", pi.name, as_dict=1)
stock_in_hand_account = get_inventory_account(pi.company, pi.get("items")[0].warehouse)
self.assertTrue(gl_entries)
expected_gl_entries = dict((d[0], d) for d in [
[pi.credit_to, 250.0, 250.0],
[pi.items[0].warehouse, 250.0, 0.0],
[stock_in_hand_account, 250.0, 0.0],
["Cash - _TC", 0.0, 250.0]
])

View File

@@ -9,11 +9,11 @@ frappe.ui.form.on("Purchase Taxes and Charges", "add_deduct_tax", function(doc,
var d = locals[cdt][cdn];
if(!d.category && d.add_deduct_tax) {
msgprint(__("Please select Category first"));
frappe.msgprint(__("Please select Category first"));
d.add_deduct_tax = '';
}
else if(d.category != 'Total' && d.add_deduct_tax == 'Deduct') {
msgprint(__("Cannot deduct when category is for 'Valuation' or 'Valuation and Total'"));
frappe.msgprint(__("Cannot deduct when category is for 'Valuation' or 'Valuation and Total'"));
d.add_deduct_tax = '';
}
refresh_field('add_deduct_tax', d.name, 'taxes');
@@ -23,7 +23,7 @@ frappe.ui.form.on("Purchase Taxes and Charges", "category", function(doc, cdt, c
var d = locals[cdt][cdn];
if (d.category != 'Total' && d.add_deduct_tax == 'Deduct') {
msgprint(__("Cannot deduct when category is for 'Valuation' or 'Vaulation and Total'"));
frappe.msgprint(__("Cannot deduct when category is for 'Valuation' or 'Vaulation and Total'"));
d.add_deduct_tax = '';
}
refresh_field('add_deduct_tax', d.name, 'taxes');

View File

@@ -71,17 +71,19 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
});
if(!from_delivery_note && !is_delivered_by_supplier) {
cur_frm.add_custom_button(__('Delivery'), cur_frm.cscript['Make Delivery Note'],
__("Make"));
cur_frm.add_custom_button(__('Delivery'),
cur_frm.cscript['Make Delivery Note'], __("Make"));
}
}
if(doc.outstanding_amount!=0 && !cint(doc.is_return)) {
cur_frm.add_custom_button(__('Payment'), this.make_payment_entry, __("Make"));
cur_frm.add_custom_button(__('Payment'),
this.make_payment_entry, __("Make"));
}
if(doc.outstanding_amount>0 && !cint(doc.is_return)) {
cur_frm.add_custom_button(__('Payment Request'), this.make_payment_request, __("Make"));
cur_frm.add_custom_button(__('Payment Request'),
this.make_payment_request, __("Make"));
}
@@ -175,8 +177,8 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
account: this.frm.doc.debit_to,
price_list: this.frm.doc.selling_price_list,
}, function() {
me.apply_pricing_rule();
})
me.apply_pricing_rule();
})
},
debit_to: function() {
@@ -267,7 +269,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
if(this.frm.doc.is_pos) {
if(!this.frm.doc.company) {
this.frm.set_value("is_pos", 0);
msgprint(__("Please specify Company to proceed"));
frappe.msgprint(__("Please specify Company to proceed"));
} else {
var me = this;
return this.frm.call({
@@ -303,6 +305,23 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
}
this.frm.refresh_fields();
},
company_address: function() {
var me = this;
if(this.frm.doc.company_address) {
frappe.call({
method: "frappe.contacts.doctype.address.address.get_address_display",
args: {"address_dict": this.frm.doc.company_address },
callback: function(r) {
if(r.message) {
me.frm.set_value("company_address_display", r.message)
}
}
})
} else {
this.frm.set_value("company_address_display", "");
}
}
});
@@ -312,22 +331,25 @@ $.extend(cur_frm.cscript, new erpnext.accounts.SalesInvoiceController({frm: cur_
// Hide Fields
// ------------
cur_frm.cscript.hide_fields = function(doc) {
parent_fields = ['project', 'due_date', 'is_opening', 'source', 'total_advance', 'get_advances',
var parent_fields = ['project', 'due_date', 'is_opening', 'source', 'total_advance', 'get_advances',
'advances', 'sales_partner', 'commission_rate', 'total_commission', 'advances', 'from_date', 'to_date'];
if(cint(doc.is_pos) == 1) {
hide_field(parent_fields);
} else {
for (i in parent_fields) {
for (var i in parent_fields) {
var docfield = frappe.meta.docfield_map[doc.doctype][parent_fields[i]];
if(!docfield.hidden) unhide_field(parent_fields[i]);
}
}
item_fields_stock = ['serial_no', 'batch_no', 'actual_qty', 'expense_account', 'warehouse', 'expense_account', 'warehouse']
var item_fields_stock = ['batch_no', 'actual_batch_qty', 'actual_qty', 'expense_account',
'warehouse', 'expense_account', 'quality_inspection']
cur_frm.fields_dict['items'].grid.set_column_disp(item_fields_stock,
(cint(doc.update_stock)==1 || cint(doc.is_return)==1 ? true : false));
// India related fields
if (frappe.boot.sysdefaults.country == 'India') unhide_field(['c_form_applicable', 'c_form_no']);
else hide_field(['c_form_applicable', 'c_form_no']);
@@ -399,19 +421,6 @@ cur_frm.set_query("income_account", "items", function(doc) {
}
});
// expense account
if (sys_defaults.auto_accounting_for_stock) {
cur_frm.fields_dict['items'].grid.get_field('expense_account').get_query = function(doc) {
return {
filters: {
'report_type': 'Profit and Loss',
'company': doc.company,
"is_group": 0
}
}
}
}
// Cost Center in Details Table
// -----------------------------
@@ -442,11 +451,12 @@ cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
})
if(cur_frm.doc.is_pos) {
cur_frm.msgbox = frappe.msgprint(format('<a class="btn btn-primary" \
onclick="cur_frm.print_preview.printit(true)" style="margin-right: 5px;">{0}</a>\
<a class="btn btn-default" href="javascript:frappe.new_doc(cur_frm.doctype);">{1}</a>', [
__('Print'), __('New')
]));
cur_frm.msgbox = frappe.msgprint(
`<a class="btn btn-primary" onclick="cur_frm.print_preview.printit(true)" style="margin-right: 5px;">
${__('Print')}</a>
<a class="btn btn-default" href="javascript:frappe.new_doc(cur_frm.doctype);">
${__('New')}</a>`
);
} else if(cint(frappe.boot.notification_settings.sales_invoice)) {
cur_frm.email_doc(frappe.boot.notification_settings.sales_invoice_message);
@@ -492,7 +502,7 @@ frappe.ui.form.on('Sales Invoice', {
'Delivery Note': 'Delivery',
'Sales Invoice': 'Sales Return',
'Payment Request': 'Payment Request',
'Payment': 'Payment Entry'
'Payment Entry': 'Payment'
},
frm.fields_dict["timesheets"].grid.get_field("time_sheet").get_query = function(doc, cdt, cdn){
return{
@@ -500,6 +510,33 @@ frappe.ui.form.on('Sales Invoice', {
filters: {'project': doc.project}
}
}
// expense account
frm.fields_dict['items'].grid.get_field('expense_account').get_query = function(doc) {
if (erpnext.is_perpetual_inventory_enabled(doc.company)) {
return {
filters: {
'report_type': 'Profit and Loss',
'company': doc.company,
"is_group": 0
}
}
}
}
frm.set_query('company_address', function(doc) {
if(!doc.company) {
frappe.throw(_('Please set Company'));
}
return {
query: 'frappe.contacts.doctype.address.address.address_query',
filters: {
link_doctype: 'Company',
link_name: doc.company
}
};
});
},
project: function(frm){

View File

@@ -12,6 +12,7 @@
"doctype": "DocType",
"document_type": "",
"editable_grid": 0,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
@@ -190,7 +191,7 @@
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
@@ -200,37 +201,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "due_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payment Due Date",
"length": 0,
"no_copy": 1,
"oldfieldname": "due_date",
"oldfieldtype": "Date",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -253,7 +223,7 @@
"oldfieldtype": "Link",
"options": "Project",
"permlevel": 0,
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@@ -314,7 +284,7 @@
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
@@ -324,6 +294,37 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "pos_profile",
"fieldtype": "Link",
"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": "POS Profile",
"length": 0,
"no_copy": 0,
"options": "POS Profile",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -479,6 +480,37 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "due_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payment Due Date",
"length": 0,
"no_copy": 1,
"oldfieldname": "due_date",
"oldfieldtype": "Date",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -813,6 +845,37 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "territory",
"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": "Territory",
"length": 0,
"no_copy": 0,
"options": "Territory",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -909,21 +972,21 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "customer_group",
"fieldname": "company_address",
"fieldtype": "Link",
"hidden": 1,
"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": "Customer Group",
"label": "Company Address Name",
"length": 0,
"no_copy": 0,
"options": "Customer Group",
"options": "Address",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -940,24 +1003,23 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "territory",
"fieldtype": "Link",
"hidden": 0,
"fieldname": "company_address_display",
"fieldtype": "Small Text",
"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": "Territory",
"label": "Company Address",
"length": 0,
"no_copy": 0,
"options": "Territory",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -1448,7 +1510,7 @@
"options": "Sales Invoice Timesheet",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@@ -1851,6 +1913,36 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "sec_tax_breakup",
"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": "Tax Breakup",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -1858,7 +1950,7 @@
"collapsible": 0,
"columns": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "HTML",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -1868,12 +1960,12 @@
"in_standard_filter": 0,
"label": "Taxes and Charges Calculation",
"length": 0,
"no_copy": 0,
"no_copy": 1,
"oldfieldtype": "HTML",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -2480,7 +2572,7 @@
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"in_standard_filter": 0,
"label": "Outstanding Amount",
"length": 0,
"no_copy": 1,
@@ -2953,7 +3045,7 @@
"options": "Account",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@@ -3458,6 +3550,37 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "customer_group",
"fieldtype": "Link",
"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": "Customer Group",
"length": 0,
"no_copy": 0,
"options": "Customer Group",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -3535,7 +3658,7 @@
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"in_standard_filter": 1,
"label": "Status",
"length": 0,
"no_copy": 1,
@@ -4388,7 +4511,7 @@
"options": "Print Format",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@@ -4449,7 +4572,7 @@
"length": 0,
"no_copy": 1,
"permlevel": 0,
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@@ -4480,7 +4603,7 @@
"length": 0,
"no_copy": 1,
"permlevel": 0,
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@@ -4565,10 +4688,11 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-06-13 14:29:14.696232",
"modified": "2017-07-07 13:05:37.469682",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
"name_case": "Title Case",
"owner": "Administrator",
"permissions": [
{

View File

@@ -2,7 +2,7 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
import frappe, erpnext
import frappe.defaults
from frappe.utils import cint, flt
from frappe import _, msgprint, throw
@@ -54,10 +54,14 @@ class SalesInvoice(SellingController):
def validate(self):
super(SalesInvoice, self).validate()
self.validate_auto_set_posting_time()
self.so_dn_required()
if not self.is_pos:
self.so_dn_required()
self.validate_proj_cust()
self.validate_with_previous_doc()
self.validate_uom_is_integer("stock_uom", "qty")
self.validate_uom_is_integer("stock_uom", "stock_qty")
self.validate_uom_is_integer("uom", "qty")
self.check_close_sales_order("sales_order")
self.validate_debit_to_acc()
self.clear_unallocated_advances("Sales Invoice Advance", "advances")
@@ -88,6 +92,8 @@ class SalesInvoice(SellingController):
self.validate_c_form()
self.validate_time_sheets_are_submitted()
self.validate_multiple_billing("Delivery Note", "dn_detail", "amount", "items")
if not self.is_return:
self.validate_serial_numbers()
self.update_packing_list()
self.set_billing_hours_and_amount()
self.update_timesheet_billing_for_project()
@@ -126,6 +132,8 @@ class SalesInvoice(SellingController):
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
self.check_credit_limit()
self.update_serial_no()
if not cint(self.is_pos) == 1 and not self.is_return:
self.update_against_document_in_jv()
@@ -155,6 +163,7 @@ class SalesInvoice(SellingController):
if not self.is_return:
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
self.update_serial_no(in_cancel=True)
self.validate_c_form_on_cancel()
@@ -554,6 +563,8 @@ class SalesInvoice(SellingController):
throw(_("Delivery Note {0} is not submitted").format(d.delivery_note))
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
auto_accounting_for_stock = erpnext.is_perpetual_inventory_enabled(self.company)
if not self.grand_total:
return
@@ -575,11 +586,11 @@ class SalesInvoice(SellingController):
self.doctype, self.return_against if cint(self.is_return) else self.name)
if repost_future_gle and cint(self.update_stock) \
and cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
and cint(auto_accounting_for_stock):
items, warehouses = self.get_items_and_warehouses()
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items)
elif self.docstatus == 2 and cint(self.update_stock) \
and cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
and cint(auto_accounting_for_stock):
from erpnext.accounts.general_ledger import delete_gl_entries
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
@@ -667,8 +678,8 @@ class SalesInvoice(SellingController):
)
# expense account gl entries
if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) \
and cint(self.update_stock):
if cint(self.update_stock) and \
erpnext.is_perpetual_inventory_enabled(self.company):
gl_entries += super(SalesInvoice, self).get_gl_entries()
def make_pos_gl_entries(self, gl_entries):
@@ -781,6 +792,60 @@ class SalesInvoice(SellingController):
self.due_date = None
def update_serial_no(self, in_cancel=False):
""" update Sales Invoice refrence in Serial No """
invoice = None if (in_cancel or self.is_return) else self.name
if in_cancel and self.is_return:
invoice = self.return_against
for item in self.items:
if not item.serial_no:
continue
for serial_no in item.serial_no.split("\n"):
sno = frappe.get_doc('Serial No', serial_no)
sno.sales_invoice = invoice
sno.db_update()
def validate_serial_numbers(self):
"""
validate serial number agains Delivery Note and Sales Invoice
"""
self.validate_serial_against_delivery_note()
self.validate_serial_against_sales_invoice()
def validate_serial_against_delivery_note(self):
"""
validate if the serial numbers in Sales Invoice Items are same as in
Delivery Note Item
"""
for item in self.items:
if not item.delivery_note or not item.dn_detail:
continue
serial_nos = frappe.db.get_value("Delivery Note Item", item.dn_detail, "serial_no") or ""
dn_serial_nos = set(serial_nos.split("\n"))
serial_nos = item.serial_no or ""
si_serial_nos = set(serial_nos.split("\n"))
if si_serial_nos - dn_serial_nos:
frappe.throw(_("Serial Numbers in row {0} does not match with Delivery Note".format(item.idx)))
def validate_serial_against_sales_invoice(self):
""" check if serial number is already used in other sales invoice """
for item in self.items:
if not item.serial_no:
continue
for serial_no in item.serial_no.split("\n"):
sales_invoice = frappe.db.get_value("Serial No", serial_no, "sales_invoice")
if sales_invoice and self.name != sales_invoice:
frappe.throw(_("Serial Number: {0} is already referenced in Sales Invoice: {1}".format(
serial_no, sales_invoice
)))
def get_list_context(context=None):
from erpnext.controllers.website_list_for_contact import get_list_context
list_context = get_list_context(context)

View File

@@ -11,7 +11,8 @@ def get_data():
'Sales Invoice': 'return_against'
},
'internal_links': {
'Sales Order': ['items', 'sales_order']
'Sales Order': ['items', 'sales_order'],
'Delivery Note': ['items', 'delivery_note']
},
'transactions': [
{

View File

@@ -12,6 +12,7 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_per
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
from frappe.model.naming import make_autoname
from erpnext.accounts.doctype.account.test_account import get_inventory_account
class TestSalesInvoice(unittest.TestCase):
def make(self):
@@ -487,8 +488,8 @@ class TestSalesInvoice(unittest.TestCase):
self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 561.8)
def test_sales_invoice_gl_entry_without_perpetual_inventory(self):
set_perpetual_inventory(0)
si = frappe.copy_doc(test_records[1])
set_perpetual_inventory(0, si.company)
si.insert()
si.submit()
@@ -595,7 +596,7 @@ class TestSalesInvoice(unittest.TestCase):
order by account asc, debit asc""", si.name, as_dict=1)
self.assertTrue(gl_entries)
stock_in_hand = frappe.db.get_value("Account", {"warehouse": "_Test Warehouse - _TC"})
stock_in_hand = get_inventory_account('_Test Company')
expected_gl_entries = sorted([
[si.debit_to, 630.0, 0.0],
@@ -616,6 +617,7 @@ class TestSalesInvoice(unittest.TestCase):
self.assertEquals(expected_gl_entries[i][2], gle.credit)
si.cancel()
frappe.delete_doc('Sales Invoice', si.name)
gle = frappe.db.sql("""select * from `tabGL Entry`
where voucher_type='Sales Invoice' and voucher_no=%s""", si.name)
@@ -750,6 +752,12 @@ class TestSalesInvoice(unittest.TestCase):
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0], "warehouse"))
self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0],
"delivery_document_no"), si.name)
self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0], "sales_invoice"),
si.name)
# check if the serial number is already linked with any other Sales Invoice
_si = frappe.copy_doc(si.as_dict())
self.assertRaises(frappe.ValidationError, _si.insert)
return si
@@ -763,6 +771,7 @@ class TestSalesInvoice(unittest.TestCase):
self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0], "warehouse"), "_Test Warehouse - _TC")
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0],
"delivery_document_no"))
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0], "sales_invoice"))
def test_serialize_status(self):
serial_no = frappe.get_doc({
@@ -781,6 +790,27 @@ class TestSalesInvoice(unittest.TestCase):
self.assertRaises(SerialNoWarehouseError, si.submit)
def test_serial_numbers_against_delivery_note(self):
"""
check if the sales invoice item serial numbers and the delivery note items
serial numbers are same
"""
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
se = make_serialized_item()
serial_nos = get_serial_nos(se.get("items")[0].serial_no)
dn = create_delivery_note(item=se.get("items")[0].item_code, serial_no=serial_nos[0])
dn.submit()
si = make_sales_invoice(dn.name)
si.save()
self.assertEquals(si.get("items")[0].serial_no, dn.get("items")[0].serial_no)
def test_invoice_due_date_against_customers_credit_days(self):
# set customer's credit days
frappe.db.set_value("Customer", "_Test Customer", "credit_days_based_on", "Fixed Days")
@@ -822,11 +852,11 @@ class TestSalesInvoice(unittest.TestCase):
["incoming_rate", "stock_value_difference"])
self.assertEquals(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3)))
stock_in_hand_account = get_inventory_account('_Test Company', si1.items[0].warehouse)
# Check gl entry
gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
"voucher_no": si1.name, "account": "_Test Warehouse - _TC"}, "debit")
"voucher_no": si1.name, "account": stock_in_hand_account}, "debit")
self.assertEquals(gle_warehouse_amount, stock_value_difference)
@@ -1075,6 +1105,22 @@ class TestSalesInvoice(unittest.TestCase):
for i, k in enumerate(expected_values["keys"]):
self.assertEquals(d.get(k), expected_values[d.item_code][i])
def test_item_wise_tax_breakup(self):
si = create_sales_invoice(qty=100, rate=50, do_not_save=True)
si.append("taxes", {
"charge_type": "On Net Total",
"account_head": "_Test Account Service Tax - _TC",
"cost_center": "_Test Cost Center - _TC",
"description": "Service Tax",
"rate": 10
})
si.insert()
tax_breakup_html = '''\n<div class="tax-break-up" style="overflow-x: auto;">\n\t<table class="table table-bordered table-hover">\n\t\t<thead><tr><th class="text-left" style="min-width: 120px;">Item Name</th><th class="text-right" style="min-width: 80px;">Taxable Amount</th><th class="text-right" style="min-width: 80px;">_Test Account Service Tax - _TC</th></tr></thead>\n\t\t<tbody><tr><td>_Test Item</td><td class="text-right">\u20b9 5,000.00</td><td class="text-right">(10.0%) \u20b9 500.00</td></tr></tbody>\n\t</table>\n</div>'''
self.assertEqual(si.other_charges_calculation, tax_breakup_html)
def create_sales_invoice(**args):
si = frappe.new_doc("Sales Invoice")
args = frappe._dict(args)

View File

@@ -11,6 +11,7 @@
"doctype": "DocType",
"document_type": "Document",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
@@ -2165,7 +2166,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-05-10 17:14:42.681757",
"modified": "2017-07-06 17:54:03.347700",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",

View File

@@ -7,7 +7,7 @@ import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import cstr, cint
from frappe.geo.doctype.address.address import get_default_address
from frappe.contacts.doctype.address.address import get_default_address
class IncorrectCustomerGroup(frappe.ValidationError): pass
class IncorrectSupplierType(frappe.ValidationError): pass

View File

@@ -2,7 +2,7 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
import frappe, erpnext
from frappe.utils import flt, cstr, cint
from frappe import _
from frappe.model.meta import get_field_precision
@@ -80,7 +80,7 @@ def check_if_in_list(gle, gl_map):
def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
if not from_repost:
validate_account_for_auto_accounting_for_stock(gl_map)
validate_account_for_perpetual_inventory(gl_map)
round_off_debit_credit(gl_map)
@@ -100,11 +100,11 @@ def make_entry(args, adv_adj, update_outstanding, from_repost=False):
gle.run_method("on_update_with_args", adv_adj, update_outstanding, from_repost)
gle.submit()
def validate_account_for_auto_accounting_for_stock(gl_map):
if cint(frappe.db.get_single_value("Accounts Settings", "auto_accounting_for_stock")) \
def validate_account_for_perpetual_inventory(gl_map):
if cint(erpnext.is_perpetual_inventory_enabled(gl_map[0].company)) \
and gl_map[0].voucher_type=="Journal Entry":
aii_accounts = [d[0] for d in frappe.db.sql("""select name from tabAccount
where account_type = 'Stock' and (warehouse != '' and warehouse is not null) and is_group=0""")]
where account_type = 'Stock' and is_group=0""")]
for entry in gl_map:
if entry.account in aii_accounts:

View File

@@ -114,7 +114,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
email_prompt: function() {
var me = this;
fields = [{label:__("To"), fieldtype:"Data", reqd: 0, fieldname:"recipients",length:524288},
var fields = [{label:__("To"), fieldtype:"Data", reqd: 0, fieldname:"recipients",length:524288},
{fieldtype: "Section Break", collapsible: 1, label: "CC & Standard Reply"},
{fieldtype: "Section Break"},
{label:__("Subject"), fieldtype:"Data", reqd: 1,
@@ -399,7 +399,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.make_item_list();
this.make_discount_field()
},
make_control: function() {
this.frm = {}
this.frm.doc = this.doc
@@ -545,7 +545,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
me.toggle_totals_area();
});
},
bind_numeric_keypad: function() {
var me = this;
$(this.numeric_keypad).find('.pos-operation').on('click', function(){
@@ -574,15 +574,19 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
me.selected_field.closest('.pos-list-row').addClass('active');
}
})
$(this.numeric_keypad).find('.numeric-del').click(function(){
me.selected_field = $(me.wrapper).find('.selected-item').find('.' + me.numeric_id)
me.numeric_val = cstr(flt(me.selected_field.val())).slice(0, -1);
me.selected_field.val(me.numeric_val);
me.selected_field.trigger("change")
// me.render_selected_item()
if(me.numeric_id) {
me.selected_field = $(me.wrapper).find('.selected-item').find('.' + me.numeric_id)
me.numeric_val = cstr(flt(me.selected_field.val())).slice(0, -1);
me.selected_field.val(me.numeric_val);
me.selected_field.trigger("change")
} else {
//Remove an item from the cart, if focus is at selected item
me.remove_selected_item()
}
})
$(this.numeric_keypad).find('.pos-pay').click(function(){
me.validate();
me.update_paid_amount_status(true);
@@ -591,6 +595,14 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
})
},
remove_selected_item: function() {
this.remove_item = []
idx = $(this.wrapper).find(".pos-selected-item-action").attr("data-idx")
this.remove_item.push(idx)
this.remove_zero_qty_item()
this.update_paid_amount_status(false)
},
render_list_customers: function () {
var me = this;
@@ -604,7 +616,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
var html = "";
if(this.si_docs.length) {
this.si_docs.forEach(function (data, i) {
for (key in data) {
for (var key in data) {
html += frappe.render_template("pos_invoice_list", {
sr: i + 1,
name: key,
@@ -984,7 +996,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
make_item_list: function () {
var me = this;
if (!this.price_list) {
msgprint(__("Price List not found or disabled"));
frappe.msgprint(__("Price List not found or disabled"));
return;
}
@@ -1007,7 +1019,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
})).tooltip().appendTo($wrap);
}
});
$wrap.append(`
<div class="image-view-item btn-more text-muted text-center">
<div class="image-view-body">
@@ -1089,7 +1101,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
});
}
},
bind_items_event: function() {
var me = this;
$(this.wrapper).on('click', '.pos-bill-item', function() {
@@ -1126,7 +1138,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
var qty = flt($(this).parents(".pos-bill-item").find('.pos-item-qty').val()) - 1;
me.update_qty(item_code, qty)
})
$(this.wrapper).on("change", ".pos-item-disc", function () {
var item_code = $(this).parents(".pos-selected-item-action").attr("data-item-code");
var discount = $(this).val();
@@ -1252,7 +1264,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
remove_zero_qty_item: function () {
var me = this;
idx = 0
var idx = 0;
this.items = []
$.each(this.frm.doc["items"] || [], function (i, d) {
if (!in_list(me.remove_item, d.idx)) {
@@ -1270,7 +1282,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.wrapper.find('input.discount-percentage').on("change", function () {
me.frm.doc.additional_discount_percentage = flt($(this).val(), precision("additional_discount_percentage"));
total = me.frm.doc.grand_total
var total = me.frm.doc.grand_total
if (me.frm.doc.apply_discount_on == 'Net Total') {
total = me.frm.doc.net_total
@@ -1461,7 +1473,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
if (this.frm.doc.docstatus == 1) {
this.page.set_secondary_action(__("Print"), function () {
html = frappe.render(me.print_template_data, me.frm.doc)
var html = frappe.render(me.print_template_data, me.frm.doc)
me.print_document(html)
})
this.page.add_menu_item(__("Email"), function () {
@@ -1484,14 +1496,13 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
print_dialog: function () {
var me = this;
this.msgprint = frappe.msgprint(format('<a class="btn btn-primary print_doc" \
style="margin-right: 5px;">{0}</a>\
<a class="btn btn-default new_doc">{1}</a>', [
__('Print'), __('New')
]));
this.msgprint = frappe.msgprint(
`<a class="btn btn-primary print_doc"
style="margin-right: 5px;">${__('Print')}</a>
<a class="btn btn-default new_doc">${__('New')}</a>`);
$('.print_doc').click(function () {
html = frappe.render(me.print_template_data, me.frm.doc)
var html = frappe.render(me.print_template_data, me.frm.doc)
me.print_document(html)
})
@@ -1525,9 +1536,9 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
//Remove the sold serial no from the cache
$.each(this.frm.doc.items, function(index, data) {
sn = data.serial_no.split('\n')
var sn = data.serial_no.split('\n')
if(sn.length) {
serial_no_list = me.serial_no_data[data.item_code]
var serial_no_list = me.serial_no_data[data.item_code]
if(serial_no_list) {
$.each(sn, function(i, serial_no) {
if(in_list(Object.keys(serial_no_list), serial_no)) {
@@ -1550,7 +1561,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
toggle_input_field: function () {
var pointer_events = 'inherit'
disabled = this.frm.doc.docstatus == 1 ? true: false;
var disabled = this.frm.doc.docstatus == 1 ? true: false;
$(this.wrapper).find('input').attr("disabled", disabled);
$(this.wrapper).find('select').attr("disabled", disabled);
$(this.wrapper).find('input').attr("disabled", disabled);
@@ -1578,6 +1589,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.frm.doc.offline_pos_name = this.name;
this.frm.doc.posting_date = frappe.datetime.get_today();
this.frm.doc.posting_time = frappe.datetime.now_time();
this.frm.doc.pos_profile = this.pos_profile_data['name'];
invoice_data[this.name] = this.frm.doc
this.si_docs.push(invoice_data)
this.update_localstorage();
@@ -1590,7 +1602,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
var me = this;
this.si_docs = this.get_doc_from_localstorage();
$.each(this.si_docs, function (index, data) {
for (key in data) {
for (var key in data) {
if (key == me.name) {
me.si_docs[index][key] = me.frm.doc;
me.update_localstorage();
@@ -1661,10 +1673,10 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
get_submitted_invoice: function () {
var invoices = [];
var index = 1;
docs = this.get_doc_from_localstorage();
var docs = this.get_doc_from_localstorage();
if (docs) {
invoices = $.map(docs, function (data) {
for (key in data) {
for (var key in data) {
if (data[key].docstatus == 1 && index < 50) {
index++
data[key].docstatus = 0;
@@ -1683,7 +1695,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.new_si_docs = [];
if (this.removed_items) {
$.each(this.si_docs, function (index, data) {
for (key in data) {
for (var key in data) {
if (!in_list(me.removed_items, key)) {
me.new_si_docs.push(data);
}
@@ -1742,8 +1754,9 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
validate_serial_no: function () {
var me = this;
var item_code = serial_no = '';
for (key in this.item_serial_no) {
var item_code = ''
var serial_no = '';
for (var key in this.item_serial_no) {
item_code = key;
serial_no = me.item_serial_no[key][0];
}
@@ -1790,16 +1803,24 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
mandatory_batch_no: function () {
var me = this;
if (this.items[0].has_batch_no && !this.item_batch_no[this.items[0].item_code]) {
frappe.throw(__(repl("Error: Batch no is mandatory for item %(item)s", {
'item': this.items[0].item_code
})))
frappe.prompt([{
'fieldname': 'batch',
'fieldtype': 'Select',
'label': __('Batch No'),
'reqd': 1,
'options': this.batch_no_data[this.items[0].item_code]
}],
function(values){
me.item_batch_no[me.items[0].item_code] = values.batch;
},
__('Select Batch No'))
}
},
apply_pricing_rule: function () {
var me = this;
$.each(this.frm.doc["items"], function (n, item) {
pricing_rule = me.get_pricing_rule(item)
var pricing_rule = me.get_pricing_rule(item)
me.validate_pricing_rule(pricing_rule)
if (pricing_rule.length) {
item.pricing_rule = pricing_rule[0].name;
@@ -1815,7 +1836,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
item.pricing_rule = null;
me.apply_pricing_rule_on_item(item)
}
if(item.discount_percentage > 0) {
me.apply_pricing_rule_on_item(item)
}
@@ -1859,7 +1880,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
validate_condition: function (data) {
//This method check condition based on applicable for
condition = this.get_mapper_for_pricing_rule(data)[data.applicable_for]
var condition = this.get_mapper_for_pricing_rule(data)[data.applicable_for]
if (in_list(condition[1], condition[0])) {
return true
}
@@ -1892,7 +1913,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}
})
count = 0
var count = 0
$.each(priority_list, function (index, value) {
if (value == priority) {
count++

View File

@@ -7,11 +7,12 @@ import frappe
import datetime
from frappe import _, msgprint, scrub
from frappe.defaults import get_user_permissions
from frappe.model.utils import get_fetch_values
from frappe.utils import add_days, getdate, formatdate, get_first_day, date_diff, \
add_years, get_timestamp, nowdate, flt
from frappe.geo.doctype.address.address import get_address_display, get_default_address
from frappe.email.doctype.contact.contact import get_contact_details, get_default_contact
from erpnext.exceptions import PartyFrozen, InvalidCurrency, PartyDisabled, InvalidAccountCurrency
from frappe.contacts.doctype.address.address import get_address_display, get_default_address
from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
from erpnext.exceptions import PartyFrozen, PartyDisabled, InvalidAccountCurrency
from erpnext.accounts.utils import get_fiscal_year
from erpnext import get_default_currency
@@ -42,7 +43,7 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
party = frappe.get_doc(party_type, party)
set_address_details(out, party, party_type)
set_address_details(out, party, party_type, doctype, company)
set_contact_details(out, party, party_type)
set_other_values(out, party, party_type)
set_price_list(out, party, party_type, price_list)
@@ -60,10 +61,11 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
return out
def set_address_details(out, party, party_type):
def set_address_details(out, party, party_type, doctype=None, company=None):
billing_address_field = "customer_address" if party_type == "Lead" \
else party_type.lower() + "_address"
out[billing_address_field] = get_default_address(party_type, party.name)
out.update(get_fetch_values(doctype, billing_address_field, out[billing_address_field]))
# address display
out.address_display = get_address_display(out[billing_address_field])
@@ -72,6 +74,11 @@ def set_address_details(out, party, party_type):
if party_type in ["Customer", "Lead"]:
out.shipping_address_name = get_default_address(party_type, party.name, 'is_shipping_address')
out.shipping_address = get_address_display(out["shipping_address_name"])
out.update(get_fetch_values(doctype, 'shipping_address_name', out.shipping_address_name))
if doctype and doctype in ['Sales Invoice']:
out.company_address = get_default_address('Company', company)
out.update(get_fetch_values(doctype, 'company_address', out.company_address))
def set_contact_details(out, party, party_type):
out.contact_person = get_default_contact(party_type, party.name)
@@ -363,28 +370,28 @@ def get_timeline_data(doctype, name):
out.update({ timestamp: count })
return out
def get_dashboard_info(party_type, party):
current_fiscal_year = get_fiscal_year(nowdate(), as_dict=True)
company = frappe.db.get_default("company") or frappe.get_all("Company")[0].name
party_account_currency = get_party_account_currency(party_type, party, company)
company_default_currency = get_default_currency() \
or frappe.db.get_value('Company', company, 'default_currency')
if party_account_currency==company_default_currency:
total_field = "base_grand_total"
else:
total_field = "grand_total"
doctype = "Sales Invoice" if party_type=="Customer" else "Purchase Invoice"
billing_this_year = frappe.db.sql("""
select sum({0})
from `tab{1}`
where {2}=%s and docstatus=1 and posting_date between %s and %s
""".format(total_field, doctype, party_type.lower()),
""".format(total_field, doctype, party_type.lower()),
(party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date))
total_unpaid = frappe.db.sql("""
select sum(debit_in_account_currency) - sum(credit_in_account_currency)
from `tabGL Entry`
@@ -396,5 +403,5 @@ def get_dashboard_info(party_type, party):
info["total_unpaid"] = flt(total_unpaid[0][0]) if total_unpaid else 0
if party_type == "Supplier":
info["total_unpaid"] = -1 * info["total_unpaid"]
return info

View File

@@ -20,13 +20,13 @@ frappe.query_reports["Accounts Payable"] = {
"fieldname":"report_date",
"label": __("As on Date"),
"fieldtype": "Date",
"default": get_today()
"default": frappe.datetime.get_today()
},
{
"fieldname":"ageing_based_on",
"label": __("Ageing Based On"),
"fieldtype": "Select",
"options": 'Posting Date' + NEWLINE + 'Due Date',
"options": 'Posting Date\nDue Date',
"default": "Posting Date"
},
{

View File

@@ -20,13 +20,13 @@ frappe.query_reports["Accounts Payable Summary"] = {
"fieldname":"report_date",
"label": __("Date"),
"fieldtype": "Date",
"default": get_today()
"default": frappe.datetime.get_today()
},
{
"fieldname":"ageing_based_on",
"label": __("Ageing Based On"),
"fieldtype": "Select",
"options": 'Posting Date' + NEWLINE + 'Due Date',
"options": 'Posting Date\nDue Date',
"default": "Posting Date"
},
{

View File

@@ -1,9 +1,3 @@
{% var letterhead= filters.letter_head || frappe.get_doc(":Company", filters.company).default_letter_head || frappe.defaults.get_default("letter_head"); %}
{% if(letterhead) { %}
<div style="margin-bottom: 7px;" class="text-center">
{%= frappe.boot.letter_heads[letterhead].header %}
</div>
{% } %}
<h2 class="text-center">{%= __(report.report_name) %}</h2>
<h4 class="text-center">{%= filters.customer || filters.supplier %} </h4>
<h5 class="text-center">

View File

@@ -26,7 +26,7 @@ frappe.query_reports["Accounts Receivable"] = {
"fieldname":"credit_days_based_on",
"label": __("Credit Days Based On"),
"fieldtype": "Select",
"options": "" + NEWLINE + "Fixed Days" + NEWLINE + "Last Day of the Next Month"
"options": "\nFixed Days\nLast Day of the Next Month"
},
{
"fieldtype": "Break",
@@ -35,13 +35,13 @@ frappe.query_reports["Accounts Receivable"] = {
"fieldname":"report_date",
"label": __("As on Date"),
"fieldtype": "Date",
"default": get_today()
"default": frappe.datetime.get_today()
},
{
"fieldname":"ageing_based_on",
"label": __("Ageing Based On"),
"fieldtype": "Select",
"options": 'Posting Date' + NEWLINE + 'Due Date',
"options": 'Posting Date\nDue Date',
"default": "Posting Date"
},
{

View File

@@ -26,7 +26,7 @@ frappe.query_reports["Accounts Receivable Summary"] = {
"fieldname":"credit_days_based_on",
"label": __("Credit Days Based On"),
"fieldtype": "Select",
"options": "" + NEWLINE + "Fixed Days" + NEWLINE + "Last Day of the Next Month"
"options": "\nFixed Days\nLast Day of the Next Month"
},
{
"fieldtype": "Break",
@@ -35,13 +35,13 @@ frappe.query_reports["Accounts Receivable Summary"] = {
"fieldname":"report_date",
"label": __("Date"),
"fieldtype": "Date",
"default": get_today()
"default": frappe.datetime.get_today()
},
{
"fieldname":"ageing_based_on",
"label": __("Ageing Based On"),
"fieldtype": "Select",
"options": 'Posting Date' + NEWLINE + 'Due Date',
"options": 'Posting Date\nDue Date',
"default": "Posting Date"
},
{
@@ -70,7 +70,7 @@ frappe.query_reports["Accounts Receivable Summary"] = {
onload: function(report) {
report.page.add_inner_button(__("Accounts Receivable"), function() {
var filters = report.get_values();
frappe.set_route('query-report', 'Accounts Receivable', {company: filters.company});
frappe.set_route('query-report', 'Accounts Receivable', { company: filters.company });
});
}
}

View File

@@ -14,7 +14,7 @@ frappe.query_reports["Bank Clearance Summary"] = {
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"default": get_today()
"default": frappe.datetime.get_today()
},
{
"fieldname":"account",

View File

@@ -25,7 +25,7 @@ frappe.query_reports["Bank Reconciliation Statement"] = {
"fieldname":"report_date",
"label": __("Date"),
"fieldtype": "Date",
"default": get_today(),
"default": frappe.datetime.get_today(),
"reqd": 1
},
]

View File

@@ -8,7 +8,7 @@ frappe.query_reports["Budget Variance Report"] = {
label: __("Fiscal Year"),
fieldtype: "Link",
options: "Fiscal Year",
default: sys_defaults.fiscal_year,
default: frappe.sys_defaults.fiscal_year,
reqd: 1
},
{

View File

@@ -13,7 +13,7 @@
height: 37px;
}
</style>
{% var letterhead= filters.letter_head || frappe.get_doc(":Company", filters.company).default_letter_head || frappe.defaults.get_default("letter_head"); %}
{% var letterhead= filters.letter_head || (frappe.get_doc(":Company", filters.company) && frappe.get_doc(":Company", filters.company).default_letter_head) || frappe.defaults.get_default("letter_head"); %}
{% if(letterhead) { %}
<div style="margin-bottom: 7px;" class="text-center">
{%= frappe.boot.letter_heads[letterhead].header %}

View File

@@ -10,7 +10,7 @@ from frappe.utils import (flt, getdate, get_first_day, get_last_day, date_diff,
from erpnext.accounts.utils import get_fiscal_year
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
company=None, reset_period_on_fy_change=True):
"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
Periodicity can be (Yearly, Quarterly, Monthly)"""
@@ -85,8 +85,8 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_v
return period_list
def get_fiscal_year_data(from_fiscal_year, to_fiscal_year):
fiscal_year = frappe.db.sql("""select min(year_start_date) as year_start_date,
max(year_end_date) as year_end_date from `tabFiscal Year` where
fiscal_year = frappe.db.sql("""select min(year_start_date) as year_start_date,
max(year_end_date) as year_end_date from `tabFiscal Year` where
name between %(from_fiscal_year)s and %(to_fiscal_year)s""",
{'from_fiscal_year': from_fiscal_year, 'to_fiscal_year': to_fiscal_year}, as_dict=1)
@@ -110,7 +110,7 @@ def get_label(periodicity, from_date, to_date):
label = formatdate(from_date, "MMM YY") + "-" + formatdate(to_date, "MMM YY")
return label
def get_data(company, root_type, balance_must_be, period_list, filters=None,
accumulated_values=1, only_current_fiscal_year=True, ignore_closing_entries=False,
ignore_accumulated_values_for_fy=False):
@@ -119,16 +119,16 @@ def get_data(company, root_type, balance_must_be, period_list, filters=None,
return None
accounts, accounts_by_name, parent_children_map = filter_accounts(accounts)
company_currency = frappe.db.get_value("Company", company, "default_currency")
gl_entries_by_account = {}
for root in frappe.db.sql("""select lft, rgt from tabAccount
where root_type=%s and ifnull(parent_account, '') = ''""", root_type, as_dict=1):
set_gl_entries_by_account(company,
set_gl_entries_by_account(company,
period_list[0]["year_start_date"] if only_current_fiscal_year else None,
period_list[-1]["to_date"],
period_list[-1]["to_date"],
root.lft, root.rgt, filters,
gl_entries_by_account, ignore_closing_entries=ignore_closing_entries)
@@ -136,7 +136,7 @@ def get_data(company, root_type, balance_must_be, period_list, filters=None,
accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values)
out = prepare_data(accounts, balance_must_be, period_list, company_currency)
out = filter_out_zero_value_rows(out, parent_children_map)
if out:
add_total_row(out, root_type, balance_must_be, period_list, company_currency)
@@ -151,13 +151,13 @@ def calculate_values(accounts_by_name, gl_entries_by_account, period_list, accum
if entry.posting_date <= period.to_date:
if (accumulated_values or entry.posting_date >= period.from_date) and \
(not ignore_accumulated_values_for_fy or
(not ignore_accumulated_values_for_fy or
entry.fiscal_year == period.to_date_fiscal_year):
d[period.key] = d.get(period.key, 0.0) + flt(entry.debit) - flt(entry.credit)
if entry.posting_date < period_list[0].year_start_date:
d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values):
"""accumulate children's values in parent accounts"""
for d in reversed(accounts):
@@ -165,7 +165,7 @@ def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accu
for period in period_list:
accounts_by_name[d.parent_account][period.key] = \
accounts_by_name[d.parent_account].get(period.key, 0.0) + d.get(period.key, 0.0)
accounts_by_name[d.parent_account]["opening_balance"] = \
accounts_by_name[d.parent_account].get("opening_balance", 0.0) + d.get("opening_balance", 0.0)
@@ -173,15 +173,15 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
data = []
year_start_date = period_list[0]["year_start_date"].strftime("%Y-%m-%d")
year_end_date = period_list[-1]["year_end_date"].strftime("%Y-%m-%d")
for d in accounts:
# add to output
has_value = False
total = 0
row = frappe._dict({
"account_name": d.account_name,
"account": d.name,
"parent_account": d.parent_account,
"account_name": _(d.account_name),
"account": _(d.name),
"parent_account": _(d.parent_account),
"indent": flt(d.indent),
"year_start_date": year_start_date,
"year_end_date": year_end_date,
@@ -192,7 +192,7 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
if d.get(period.key) and balance_must_be=="Credit":
# change sign based on Debit or Credit, since calculation is done using (debit - credit)
d[period.key] *= -1
row[period.key] = flt(d.get(period.key, 0.0), 3)
if abs(row[period.key]) >= 0.005:
@@ -203,9 +203,9 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
row["has_value"] = has_value
row["total"] = total
data.append(row)
return data
def filter_out_zero_value_rows(data, parent_children_map, show_zero_values=False):
data_with_value = []
for d in data:
@@ -224,8 +224,8 @@ def filter_out_zero_value_rows(data, parent_children_map, show_zero_values=False
def add_total_row(out, root_type, balance_must_be, period_list, company_currency):
total_row = {
"account_name": "'" + _("Total {0} ({1})").format(root_type, balance_must_be) + "'",
"account": "'" + _("Total {0} ({1})").format(root_type, balance_must_be) + "'",
"account_name": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
"account": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
"currency": company_currency
}
@@ -235,11 +235,11 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency
total_row.setdefault(period.key, 0.0)
total_row[period.key] += row.get(period.key, 0.0)
row[period.key] = ""
total_row.setdefault("total", 0.0)
total_row["total"] += flt(row["total"])
row["total"] = ""
if total_row.has_key("total"):
out.append(total_row)

View File

@@ -1,9 +1,3 @@
{% var letterhead= filters.letter_head || frappe.get_doc(":Company", filters.company).default_letter_head || frappe.defaults.get_default("letter_head"); %}
{% if(letterhead) { %}
<div style="margin-bottom: 7px;" class="text-center">
{%= frappe.boot.letter_heads[letterhead].header %}
</div>
{% } %}
<h2 class="text-center">{%= __("Statement of Account") %}</h2>
<h4 class="text-center">
{% if (filters.party_name) { %}

View File

@@ -75,7 +75,7 @@ frappe.query_reports["General Ledger"] = {
}
return party_type;
},
change: function() {
on_change: function() {
var party_type = frappe.query_report_filters_by_name.party_type.get_value();
var party = frappe.query_report_filters_by_name.party.get_value();
if(!party_type || !party) {

View File

@@ -227,7 +227,7 @@ class GrossProfitGenerator(object):
if not average_buying_rate:
average_buying_rate = get_valuation_rate(item_code, row.warehouse,
row.parenttype, row.parent, allow_zero_rate=True,
currency=self.filters.currency)
currency=self.filters.currency, company=self.filters.company)
self.average_buying_rate[item_code] = flt(average_buying_rate)
@@ -278,7 +278,7 @@ class GrossProfitGenerator(object):
inner join `tabSales Invoice Item` on `tabSales Invoice Item`.parent = `tabSales Invoice`.name
{sales_team_table}
where
`tabSales Invoice`.docstatus = 1 and `tabSales Invoice`.is_return != 1 {conditions} {match_cond}
`tabSales Invoice`.docstatus = 1 {conditions} {match_cond}
order by
`tabSales Invoice`.posting_date desc, `tabSales Invoice`.posting_time desc"""
.format(conditions=conditions, sales_person_cols=sales_person_cols,

View File

@@ -14,7 +14,7 @@ frappe.query_reports["Item-wise Purchase Register"] = {
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"default": get_today()
"default": frappe.datetime.get_today()
},
{
"fieldname": "item_code",

View File

@@ -7,11 +7,14 @@ from frappe import _
from frappe.utils import flt
def execute(filters=None):
return _execute(filters)
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = {}
columns = get_columns()
columns = get_columns(additional_table_columns)
last_col = len(columns)
item_list = get_items(filters)
item_list = get_items(filters, additional_query_columns)
aii_account_map = get_aii_accounts()
if item_list:
item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
@@ -23,7 +26,7 @@ def execute(filters=None):
"width": 80
})
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
data = []
for d in item_list:
purchase_receipt = None
@@ -35,8 +38,16 @@ def execute(filters=None):
expense_account = d.expense_account or aii_account_map.get(d.company)
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.supplier,
d.supplier_name, d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
purchase_receipt, expense_account, d.qty, d.base_net_rate, d.base_net_amount]
d.supplier_name]
if additional_query_columns:
for col in additional_query_columns:
row.append(d.get(col))
row += [
d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
purchase_receipt, expense_account, d.qty, d.base_net_rate, d.base_net_amount
]
for tax in tax_accounts:
row.append(item_row_tax.get(d.name, {}).get(tax, 0))
@@ -49,17 +60,27 @@ def execute(filters=None):
return columns, data
def get_columns():
return [_("Item Code") + ":Link/Item:120", _("Item Name") + "::120",
def get_columns(additional_table_columns):
columns = [
_("Item Code") + ":Link/Item:120", _("Item Name") + "::120",
_("Item Group") + ":Link/Item Group:100", _("Invoice") + ":Link/Purchase Invoice:120",
_("Posting Date") + ":Date:80", _("Supplier") + ":Link/Supplier:120",
"Supplier Name::120", "Payable Account:Link/Account:120",
"Supplier Name::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",
_("Qty") + ":Float:120", _("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120"
]
return columns
def get_conditions(filters):
conditions = ""
@@ -74,21 +95,23 @@ def get_conditions(filters):
return conditions
def get_items(filters):
def get_items(filters, additional_query_columns):
conditions = get_conditions(filters)
match_conditions = frappe.build_match_conditions("Purchase Invoice")
if additional_query_columns:
additional_query_columns = ', ' + ', '.join(additional_query_columns)
return frappe.db.sql("""
select
select
pi_item.name, pi_item.parent, pi.posting_date, pi.credit_to, pi.company,
pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name,
pi_item.item_group, pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt,
pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.base_net_rate,
pi_item.base_net_amount, pi.supplier_name, pi.mode_of_payment
pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name,
pi_item.item_group, pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt,
pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.base_net_rate,
pi_item.base_net_amount, pi.supplier_name, pi.mode_of_payment {0}
from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item
where pi.name = pi_item.parent and pi.docstatus = 1 %s %s
order by pi.posting_date desc, pi_item.item_code desc
""" % (conditions, match_conditions), filters, as_dict=1)
""".format(additional_query_columns) % (conditions, match_conditions), filters, as_dict=1)
def get_aii_accounts():
return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))
@@ -104,11 +127,11 @@ def get_tax_accounts(item_list, columns):
item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
tax_details = frappe.db.sql("""
select
select
parent, account_head, item_wise_tax_detail, charge_type, base_tax_amount_after_discount_amount
from `tabPurchase Taxes and Charges`
where parenttype = 'Purchase Invoice' and docstatus = 1
and (account_head is not null and account_head != '')
from `tabPurchase Taxes and Charges`
where parenttype = 'Purchase Invoice' and docstatus = 1
and (account_head is not null and account_head != '')
and category in ('Total', 'Valuation and Total')
and parent in (%s)
""" % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
@@ -120,17 +143,17 @@ def get_tax_accounts(item_list, columns):
if item_wise_tax_detail:
try:
item_wise_tax_detail = json.loads(item_wise_tax_detail)
for item_code, tax_amount in item_wise_tax_detail.items():
tax_amount = flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
item_net_amount = sum([flt(d.base_net_amount)
item_net_amount = sum([flt(d.base_net_amount)
for d in item_row_map.get(parent, {}).get(item_code, [])])
for d in item_row_map.get(parent, {}).get(item_code, []):
item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) if item_net_amount else 0
item_row_tax.setdefault(d.name, {})[account_head] = item_tax_amount
except ValueError:
continue
elif charge_type == "Actual" and tax_amount:

View File

@@ -14,7 +14,7 @@ frappe.query_reports["Item-wise Sales Register"] = frappe.query_reports["Sales R
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"default": get_today()
"default": frappe.datetime.get_today()
},
{
"fieldname":"customer",

View File

@@ -8,11 +8,14 @@ from frappe.utils import flt
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
def execute(filters=None):
return _execute(filters)
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = {}
columns = get_columns()
columns = get_columns(additional_table_columns)
last_col = len(columns)
item_list = get_items(filters)
item_list = get_items(filters, additional_query_columns)
if item_list:
item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
columns.append({
@@ -21,7 +24,7 @@ def execute(filters=None):
"fieldtype": "Data",
"width": 80
})
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
company_currency = frappe.db.get_value("Company", filters.get("company"), "default_currency")
mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list]))
data = []
@@ -35,10 +38,17 @@ def execute(filters=None):
if not delivery_note and d.update_stock:
delivery_note = d.parent
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.customer, d.customer_name,
d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])),
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.customer, d.customer_name]
if additional_query_columns:
for col in additional_query_columns:
row.append(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.qty, d.base_net_rate, d.base_net_amount]
delivery_note, d.income_account, d.cost_center, d.qty, d.base_net_rate, d.base_net_amount
]
for tax in tax_accounts:
row.append(item_row_tax.get(d.name, {}).get(tax, 0))
@@ -50,12 +60,18 @@ def execute(filters=None):
return columns, data
def get_columns():
return [
def get_columns(additional_table_columns):
columns = [
_("Item Code") + ":Link/Item:120", _("Item Name") + "::120",
_("Item Group") + ":Link/Item Group:100", _("Invoice") + ":Link/Sales Invoice:120",
_("Posting Date") + ":Date:80", _("Customer") + ":Link/Customer:120",
_("Customer Name") + "::120", _("Customer Group") + ":Link/Customer Group:120",
_("Customer Name") + "::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",
@@ -66,6 +82,8 @@ def get_columns():
_("Amount") + ":Currency/currency:120"
]
return columns
def get_conditions(filters):
conditions = ""
@@ -76,15 +94,18 @@ def get_conditions(filters):
("to_date", " and si.posting_date<=%(to_date)s")):
if filters.get(opts[0]):
conditions += opts[1]
if filters.get("mode_of_payment"):
conditions += """ and exists(select name from `tabSales Invoice Payment`
where parent=si.name
where parent=si.name
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
return conditions
def get_items(filters):
def get_items(filters, additional_query_columns):
if additional_query_columns:
additional_query_columns = ', ' + ', '.join(additional_query_columns)
conditions = get_conditions(filters)
return frappe.db.sql("""
select
@@ -93,10 +114,11 @@ def get_items(filters):
si_item.item_code, si_item.item_name, si_item.item_group, si_item.sales_order,
si_item.delivery_note, si_item.income_account, si_item.cost_center, si_item.qty,
si_item.base_net_rate, si_item.base_net_amount, si.customer_name,
si.customer_group, si_item.so_detail, si.update_stock
si.customer_group, si_item.so_detail, si.update_stock {0}
from `tabSales Invoice` si, `tabSales Invoice Item` si_item
where si.name = si_item.parent and si.docstatus = 1 %s
order by si.posting_date desc, si_item.item_code desc""" % conditions, filters, as_dict=1)
order by si.posting_date desc, si_item.item_code desc
""".format(additional_query_columns or '') % conditions, filters, as_dict=1)
def get_tax_accounts(item_list, columns):
import json

View File

@@ -21,7 +21,7 @@ frappe.query_reports["Payment Period Based On Invoice Date"] = {
fieldname:"to_date",
label: __("To Date"),
fieldtype: "Date",
default: get_today()
default: frappe.datetime.get_today()
},
{
fieldname:"payment_type",

View File

@@ -3,6 +3,6 @@
frappe.require("assets/erpnext/js/purchase_trends_filters.js", function() {
frappe.query_reports["Purchase Invoice Trends"] = {
filters: get_filters()
filters: erpnext.get_purchase_trends_filters()
}
});

View File

@@ -14,7 +14,7 @@ frappe.query_reports["Purchase Register"] = {
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"default": get_today()
"default": frappe.datetime.get_today()
},
{
"fieldname":"supplier",

View File

@@ -7,10 +7,13 @@ from frappe.utils import flt
from frappe import msgprint, _
def execute(filters=None):
return _execute(filters)
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = {}
invoice_list = get_invoices(filters)
columns, expense_accounts, tax_accounts = get_columns(invoice_list)
invoice_list = get_invoices(filters, additional_query_columns)
columns, expense_accounts, tax_accounts = get_columns(invoice_list, additional_table_columns)
if not invoice_list:
msgprint(_("No record found"))
@@ -20,8 +23,9 @@ def execute(filters=None):
invoice_expense_map, invoice_tax_map = get_invoice_tax_map(invoice_list,
invoice_expense_map, expense_accounts)
invoice_po_pr_map = get_invoice_po_pr_map(invoice_list)
supplier_details = get_supplier_details(invoice_list)
suppliers = list(set([d.supplier for d in invoice_list]))
supplier_details = get_supplier_details(suppliers)
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
data = []
@@ -31,10 +35,18 @@ def execute(filters=None):
purchase_receipt = list(set(invoice_po_pr_map.get(inv.name, {}).get("purchase_receipt", [])))
project = list(set(invoice_po_pr_map.get(inv.name, {}).get("project", [])))
row = [inv.name, inv.posting_date, inv.supplier, inv.supplier_name,
supplier_details.get(inv.supplier),
inv.credit_to, inv.mode_of_payment, ", ".join(project), inv.bill_no, inv.bill_date, inv.remarks,
", ".join(purchase_order), ", ".join(purchase_receipt), company_currency]
row = [inv.name, inv.posting_date, inv.supplier, inv.supplier_name]
if additional_query_columns:
for col in additional_query_columns:
row.append(inv.get(col))
row += [
supplier_details.get(inv.supplier), # supplier_type
inv.credit_to, inv.mode_of_payment, ", ".join(project),
inv.bill_no, inv.bill_date, inv.remarks,
", ".join(purchase_order), ", ".join(purchase_receipt), company_currency
]
# map expense values
base_net_total = 0
@@ -61,15 +73,20 @@ def execute(filters=None):
return columns, data
def get_columns(invoice_list):
def get_columns(invoice_list, additional_table_columns):
"""return columns based on filters"""
columns = [
_("Invoice") + ":Link/Purchase Invoice:120", _("Posting Date") + ":Date:80",
_("Supplier Id") + "::120", _("Supplier Name") + "::120",
_("Supplier Type") + ":Link/Supplier Type:120", _("Payable Account") + ":Link/Account:120",
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
_("Invoice") + ":Link/Purchase Invoice:120", _("Posting Date") + ":Date:80",
_("Supplier Id") + "::120", _("Supplier Name") + "::120"]
if additional_table_columns:
columns += additional_table_columns
columns += [
_("Supplier Type") + ":Link/Supplier Type:120", _("Payable Account") + ":Link/Account:120",
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
_("Bill No") + "::120", _("Bill Date") + ":Date:80", _("Remarks") + "::150",
_("Purchase Order") + ":Link/Purchase Order:100",
_("Purchase Order") + ":Link/Purchase Order:100",
_("Purchase Receipt") + ":Link/Purchase Receipt:100",
{
"fieldname": "currency",
@@ -114,27 +131,31 @@ def get_conditions(filters):
if filters.get("from_date"): conditions += " and posting_date>=%(from_date)s"
if filters.get("to_date"): conditions += " and posting_date<=%(to_date)s"
if filters.get("mode_of_payment"): conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s"
return conditions
def get_invoices(filters):
def get_invoices(filters, additional_query_columns):
if additional_query_columns:
additional_query_columns = ', ' + ', '.join(additional_query_columns)
conditions = get_conditions(filters)
return frappe.db.sql("""
select
name, posting_date, credit_to, supplier, supplier_name, bill_no, bill_date, remarks,
base_net_total, base_grand_total, outstanding_amount, mode_of_payment
from `tabPurchase Invoice`
select
name, posting_date, credit_to, supplier, supplier_name, bill_no, bill_date,
remarks, base_net_total, base_grand_total, outstanding_amount,
mode_of_payment {0}
from `tabPurchase Invoice`
where docstatus = 1 %s
order by posting_date desc, name desc""" % conditions, filters, as_dict=1)
order by posting_date desc, name desc""".format(additional_query_columns or '') % conditions, filters, as_dict=1)
def get_invoice_expense_map(invoice_list):
expense_details = frappe.db.sql("""
select parent, expense_account, sum(base_net_amount) as amount
from `tabPurchase Invoice Item`
where parent in (%s)
from `tabPurchase Invoice Item`
where parent in (%s)
group by parent, expense_account
""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
@@ -149,7 +170,7 @@ def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts):
tax_details = frappe.db.sql("""
select parent, account_head, case add_deduct_tax when "Add" then sum(base_tax_amount_after_discount_amount)
else sum(base_tax_amount_after_discount_amount) * -1 end as tax_amount
from `tabPurchase Taxes and Charges`
from `tabPurchase Taxes and Charges`
where parent in (%s) and category in ('Total', 'Valuation and Total')
group by parent, account_head, add_deduct_tax
""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
@@ -169,8 +190,8 @@ def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts):
def get_invoice_po_pr_map(invoice_list):
pi_items = frappe.db.sql("""
select parent, purchase_order, purchase_receipt, po_detail, project
from `tabPurchase Invoice Item`
select parent, purchase_order, purchase_receipt, po_detail, project
from `tabPurchase Invoice Item`
where parent in (%s) and (ifnull(purchase_order, '') != '' or ifnull(purchase_receipt, '') != '')
""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
@@ -205,9 +226,8 @@ def get_account_details(invoice_list):
return account_map
def get_supplier_details(invoice_list):
def get_supplier_details(suppliers):
supplier_details = {}
suppliers = list(set([inv.supplier for inv in invoice_list]))
for supp in frappe.db.sql("""select name, supplier_type from `tabSupplier`
where name in (%s)""" % ", ".join(["%s"]*len(suppliers)), tuple(suppliers), as_dict=1):
supplier_details.setdefault(supp.name, supp.supplier_type)

View File

@@ -3,6 +3,6 @@
frappe.require("assets/erpnext/js/sales_trends_filters.js", function() {
frappe.query_reports["Sales Invoice Trends"] = {
filters: get_filters()
filters: erpnext.get_sales_trends_filters()
}
});

View File

@@ -14,7 +14,7 @@ frappe.query_reports["Sales Register"] = {
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"default": get_today()
"default": frappe.datetime.get_today()
},
{
"fieldname":"customer",

View File

@@ -7,10 +7,13 @@ from frappe.utils import flt
from frappe import msgprint, _
def execute(filters=None):
return _execute(filters)
def _execute(filters, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = frappe._dict({})
invoice_list = get_invoices(filters)
columns, income_accounts, tax_accounts = get_columns(invoice_list)
invoice_list = get_invoices(filters, additional_query_columns)
columns, income_accounts, tax_accounts = get_columns(invoice_list, additional_table_columns)
if not invoice_list:
msgprint(_("No record found"))
@@ -21,8 +24,9 @@ def execute(filters=None):
invoice_income_map, income_accounts)
invoice_so_dn_map = get_invoice_so_dn_map(invoice_list)
customer_map = get_customer_details(invoice_list)
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
customers = list(set([inv.customer for inv in invoice_list]))
customer_map = get_customer_details(customers)
company_currency = frappe.db.get_value("Company", filters.get("company"), "default_currency")
mode_of_payments = get_mode_of_payments([inv.name for inv in invoice_list])
data = []
@@ -31,12 +35,22 @@ def execute(filters=None):
sales_order = list(set(invoice_so_dn_map.get(inv.name, {}).get("sales_order", [])))
delivery_note = list(set(invoice_so_dn_map.get(inv.name, {}).get("delivery_note", [])))
row = [inv.name, inv.posting_date, inv.customer, inv.customer_name,
customer_map.get(inv.customer, {}).get("customer_group"),
customer_map.get(inv.customer, {}).get("territory"),
inv.debit_to, ", ".join(mode_of_payments.get(inv.name, [])), inv.project, inv.remarks,
", ".join(sales_order), ", ".join(delivery_note), company_currency]
customer_details = customer_map.get(inv.customer, {})
row = [
inv.name, inv.posting_date, inv.customer, inv.customer_name
]
if additional_query_columns:
for col in additional_query_columns:
row.append(inv.get(col))
row +=[
customer_details.get("customer_group"),
customer_details.get("territory"),
inv.debit_to, ", ".join(mode_of_payments.get(inv.name, [])),
inv.project, inv.remarks,
", ".join(sales_order), ", ".join(delivery_note), company_currency
]
# map income values
base_net_total = 0
for income_acc in income_accounts:
@@ -62,15 +76,20 @@ def execute(filters=None):
return columns, data
def get_columns(invoice_list):
def get_columns(invoice_list, additional_table_columns):
"""return columns based on filters"""
columns = [
_("Invoice") + ":Link/Sales Invoice:120", _("Posting Date") + ":Date:80",
_("Customer Id") + "::120", _("Customer Name") + "::120",
_("Customer Group") + ":Link/Customer Group:120", _("Territory") + ":Link/Territory:80",
_("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + "::120",
_("Project") +":Link/Project:80", _("Remarks") + "::150",
_("Invoice") + ":Link/Sales Invoice:120", _("Posting Date") + ":Date:80",
_("Customer") + ":Link/Customer:120", _("Customer Name") + "::120"
]
if additional_table_columns:
columns += additional_table_columns
columns +=[
_("Customer Group") + ":Link/Customer Group:120", _("Territory") + ":Link/Territory:80",
_("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + "::120",
_("Project") +":Link/Project:80", _("Remarks") + "::150",
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
{
"fieldname": "currency",
@@ -113,20 +132,23 @@ def get_conditions(filters):
if filters.get("from_date"): conditions += " and posting_date >= %(from_date)s"
if filters.get("to_date"): conditions += " and posting_date <= %(to_date)s"
if filters.get("mode_of_payment"):
conditions += """ and exists(select name from `tabSales Invoice Payment`
where parent=`tabSales Invoice`.name
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
return conditions
def get_invoices(filters):
def get_invoices(filters, additional_query_columns):
if additional_query_columns:
additional_query_columns = ', ' + ', '.join(additional_query_columns)
conditions = get_conditions(filters)
return frappe.db.sql("""select name, posting_date, debit_to, project, customer, customer_name, remarks,
base_net_total, base_grand_total, base_rounded_total, outstanding_amount
return frappe.db.sql("""select name, posting_date, debit_to, project, customer, customer_name, remarks,
base_net_total, base_grand_total, base_rounded_total, outstanding_amount {0}
from `tabSales Invoice`
where docstatus = 1 %s order by posting_date desc, name desc""" %
where docstatus = 1 %s order by posting_date desc, name desc""".format(additional_query_columns or '') %
conditions, filters, as_dict=1)
def get_invoice_income_map(invoice_list):
@@ -184,9 +206,8 @@ def get_invoice_so_dn_map(invoice_list):
return invoice_so_dn_map
def get_customer_details(invoice_list):
def get_customer_details(customers):
customer_map = {}
customers = list(set([inv.customer for inv in invoice_list]))
for cust in frappe.db.sql("""select name, territory, customer_group from `tabCustomer`
where name in (%s)""" % ", ".join(["%s"]*len(customers)), tuple(customers), as_dict=1):
customer_map.setdefault(cust.name, cust)

View File

@@ -216,7 +216,8 @@ def get_count_on(account, fieldname, date):
else:
dr_or_cr = "debit" if fieldname == "invoiced_amount" else "credit"
cr_or_dr = "credit" if fieldname == "invoiced_amount" else "debit"
select_fields = "ifnull(sum(credit-debit),0)" if fieldname == "invoiced_amount" else "ifnull(sum(debit-credit),0)"
select_fields = "ifnull(sum(credit-debit),0)" \
if fieldname == "invoiced_amount" else "ifnull(sum(debit-credit),0)"
if ((not gle.against_voucher) or (gle.against_voucher_type in ["Sales Order", "Purchase Order"]) or
(gle.against_voucher==gle.voucher_no and gle.get(dr_or_cr) > 0)):
@@ -224,8 +225,10 @@ def get_count_on(account, fieldname, date):
SELECT {0}
FROM `tabGL Entry` gle
WHERE docstatus < 2 and posting_date <= %(date)s and against_voucher = %(voucher_no)s
and party = %(party)s and name != %(name)s""".format(select_fields),
{"date": date, "voucher_no": gle.voucher_no, "party": gle.party, "name": gle.name})[0][0]
and party = %(party)s and name != %(name)s"""
.format(select_fields),
{"date": date, "voucher_no": gle.voucher_no,
"party": gle.party, "name": gle.name})[0][0]
outstanding_amount = flt(gle.get(dr_or_cr)) - flt(gle.get(cr_or_dr)) - payment_amount
currency_precision = get_currency_precision() or 2
@@ -519,20 +522,19 @@ def fix_total_debit_credit():
def get_stock_and_account_difference(account_list=None, posting_date=None):
from erpnext.stock.utils import get_stock_value_on
from erpnext.stock import get_warehouse_account_map
if not posting_date: posting_date = nowdate()
difference = {}
warehouse_account = get_warehouse_account_map()
account_warehouse = dict(frappe.db.sql("""select name, warehouse from tabAccount
where account_type = 'Stock' and (warehouse is not null and warehouse != '') and is_group=0
and name in (%s)""" % ', '.join(['%s']*len(account_list)), account_list))
for account, warehouse in account_warehouse.items():
account_balance = get_balance_on(account, posting_date, in_account_currency=False)
stock_value = get_stock_value_on(warehouse, posting_date)
if abs(flt(stock_value) - flt(account_balance)) > 0.005:
difference.setdefault(account, flt(stock_value) - flt(account_balance))
for warehouse, account_data in warehouse_account.items():
if account_data.get('account') in account_list:
account_balance = get_balance_on(account_data.get('account'), posting_date, in_account_currency=False)
stock_value = get_stock_value_on(warehouse, posting_date)
if abs(flt(stock_value) - flt(account_balance)) > 0.005:
difference.setdefault(account, flt(stock_value) - flt(account_balance))
return difference

View File

@@ -55,7 +55,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
if(is_drop_ship && doc.status!="Delivered"){
cur_frm.add_custom_button(__('Delivered'),
this.delivered_by_supplier, __("Status"));
this.delivered_by_supplier, __("Status"));
cur_frm.page.set_inner_btn_group_as_primary(__("Status"));
}

View File

@@ -43,7 +43,7 @@ class PurchaseOrder(BuyingController):
self.check_for_closed_status()
self.validate_uom_is_integer("uom", "qty")
self.validate_uom_is_integer("stock_uom", ["qty", "required_qty"])
self.validate_uom_is_integer("stock_uom", "stock_qty")
self.validate_with_previous_doc()
self.validate_for_subcontracting()
@@ -270,6 +270,9 @@ def make_purchase_receipt(source_name, target_doc=None):
doc = get_mapped_doc("Purchase Order", source_name, {
"Purchase Order": {
"doctype": "Purchase Receipt",
"field_map": {
"per_billed": "per_billed"
},
"validation": {
"docstatus": ["=", 1],
}
@@ -311,6 +314,9 @@ def make_purchase_invoice(source_name, target_doc=None):
doc = get_mapped_doc("Purchase Order", source_name, {
"Purchase Order": {
"doctype": "Purchase Invoice",
"field_map": {
"party_account_currency": "party_account_currency"
},
"validation": {
"docstatus": ["=", 1],
}

View File

@@ -10,7 +10,7 @@ def get_data():
'internal_links': {
'Material Request': ['items', 'material_request'],
'Supplier Quotation': ['items', 'supplier_quotation'],
'Project': ['project'],
'Project': ['items', 'project'],
},
'transactions': [
{
@@ -30,4 +30,4 @@ def get_data():
'items': ['Stock Entry']
}
]
}
}

View File

@@ -1,34 +1,34 @@
frappe.listview_settings['Purchase Order'] = {
add_fields: ["base_grand_total", "company", "currency", "supplier",
"supplier_name", "per_received", "per_billed", "status"],
get_indicator: function(doc) {
if(doc.status==="Closed"){
get_indicator: function (doc) {
if (doc.status === "Closed") {
return [__("Closed"), "green", "status,=,Closed"];
} else if (doc.status==="Delivered") {
} else if (doc.status === "Delivered") {
return [__("Delivered"), "green", "status,=,Closed"];
}else if(flt(doc.per_received, 2) < 100 && doc.status!=="Closed") {
if(flt(doc.per_billed, 2) < 100) {
} else if (flt(doc.per_received, 2) < 100 && doc.status !== "Closed") {
if (flt(doc.per_billed, 2) < 100) {
return [__("To Receive and Bill"), "orange",
"per_received,<,100|per_billed,<,100|status,!=,Closed"];
} else {
return [__("To Receive"), "orange",
"per_received,<,100|per_billed,=,100|status,!=,Closed"];
}
} else if(flt(doc.per_received, 2) == 100 && flt(doc.per_billed, 2) < 100 && doc.status!=="Closed") {
} else if (flt(doc.per_received, 2) == 100 && flt(doc.per_billed, 2) < 100 && doc.status !== "Closed") {
return [__("To Bill"), "orange", "per_received,=,100|per_billed,<,100|status,!=,Closed"];
} else if(flt(doc.per_received, 2) == 100 && flt(doc.per_billed, 2) == 100 && doc.status!=="Closed") {
} else if (flt(doc.per_received, 2) == 100 && flt(doc.per_billed, 2) == 100 && doc.status !== "Closed") {
return [__("Completed"), "green", "per_received,=,100|per_billed,=,100|status,!=,Closed"];
}
},
onload: function(listview) {
onload: function (listview) {
var method = "erpnext.buying.doctype.purchase_order.purchase_order.close_or_unclose_purchase_orders";
listview.page.add_menu_item(__("Close"), function() {
listview.call_for_selected_items(method, {"status": "Closed"});
listview.page.add_menu_item(__("Close"), function () {
listview.call_for_selected_items(method, { "status": "Closed" });
});
listview.page.add_menu_item(__("Re-open"), function() {
listview.call_for_selected_items(method, {"status": "Submitted"});
listview.page.add_menu_item(__("Re-open"), function () {
listview.call_for_selected_items(method, { "status": "Submitted" });
});
}
};

View File

@@ -56,17 +56,17 @@ frappe.ui.form.on("Request for Quotation",{
var dialog = new frappe.ui.Dialog({
title: __("For Supplier"),
fields: [
{"fieldtype": "Select", "label": __("Supplier"),
"fieldname": "supplier", "options":"Supplier",
"options": $.map(doc.suppliers,
function(d) { return d.supplier }), "reqd": 1 },
{"fieldtype": "Button", "label": __("Make Supplier Quotation"),
"fieldname": "make_supplier_quotation", "cssClass": "btn-primary"},
{ "fieldtype": "Select", "label": __("Supplier"),
"fieldname": "supplier",
"options": doc.suppliers.map(d => d.supplier),
"reqd": 1 },
{ "fieldtype": "Button", "label": __("Make Supplier Quotation"),
"fieldname": "make_supplier_quotation", "cssClass": "btn-primary" },
]
});
dialog.fields_dict.make_supplier_quotation.$input.click(function() {
args = dialog.get_values();
var args = dialog.get_values();
if(!args) return;
dialog.hide();
return frappe.call({
@@ -117,7 +117,7 @@ frappe.ui.form.on("Request for Quotation Supplier",{
+"&supplier_idx="+encodeURIComponent(child.idx)
+"&no_letterhead=0"));
if(!w) {
msgprint(__("Please enable pop-ups")); return;
frappe.msgprint(__("Please enable pop-ups")); return;
}
}
})
@@ -144,44 +144,44 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
}
})
}, __("Get items from"));
// Get items from open Material Requests based on supplier
this.frm.add_custom_button(__('Possible Supplier'), function() {
// Create a dialog window for the user to pick their supplier
var d = new frappe.ui.Dialog({
title: __('Select Possible Supplier'),
fields: [
{fieldname: 'supplier', fieldtype:'Link', options:'Supplier', label:'Supplier', reqd:1},
{fieldname: 'ok_button', fieldtype:'Button', label:'Get Items from Material Requests'},
]
});
// Get items from open Material Requests based on supplier
this.frm.add_custom_button(__('Possible Supplier'), function() {
// Create a dialog window for the user to pick their supplier
var d = new frappe.ui.Dialog({
title: __('Select Possible Supplier'),
fields: [
{fieldname: 'supplier', fieldtype:'Link', options:'Supplier', label:'Supplier', reqd:1},
{fieldname: 'ok_button', fieldtype:'Button', label:'Get Items from Material Requests'},
]
});
// On the user clicking the ok button
d.fields_dict.ok_button.input.onclick = function() {
var btn = d.fields_dict.ok_button.input;
var v = d.get_values();
if(v) {
$(btn).set_working();
// On the user clicking the ok button
d.fields_dict.ok_button.input.onclick = function() {
var btn = d.fields_dict.ok_button.input;
var v = d.get_values();
if(v) {
$(btn).set_working();
erpnext.utils.map_current_doc({
method: "erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_item_from_material_requests_based_on_supplier",
source_name: v.supplier,
target: me.frm,
setters: {
company: me.frm.doc.company
},
get_query_filters: {
material_request_type: "Purchase",
docstatus: 1,
status: ["!=", "Stopped"],
per_ordered: ["<", 99.99]
}
});
$(btn).done_working();
d.hide();
}
erpnext.utils.map_current_doc({
method: "erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_item_from_material_requests_based_on_supplier",
source_name: v.supplier,
target: me.frm,
setters: {
company: me.frm.doc.company
},
get_query_filters: {
material_request_type: "Purchase",
docstatus: 1,
status: ["!=", "Stopped"],
per_ordered: ["<", 99.99]
}
});
$(btn).done_working();
d.hide();
}
d.show();
}, __("Get items from"));
}
d.show();
}, __("Get items from"));
}
},

View File

@@ -3,8 +3,10 @@
# See license.txt
from __future__ import unicode_literals
import frappe
import unittest
import frappe
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
from frappe.utils import nowdate
class TestRequestforQuotation(unittest.TestCase):
@@ -28,6 +30,31 @@ class TestRequestforQuotation(unittest.TestCase):
self.assertEquals(sq1.get('items')[0].item_code, "_Test Item")
self.assertEquals(sq1.get('items')[0].qty, 5)
def test_make_supplier_quotation_with_special_characters(self):
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
frappe.delete_doc_if_exists("Supplier", "_Test Supplier '1", force=1)
supplier = frappe.new_doc("Supplier")
supplier.supplier_name = "_Test Supplier '1"
supplier.supplier_type = "_Test Supplier Type"
supplier.insert()
rfq = make_request_for_quotation(supplier_wt_appos)
sq = make_supplier_quotation(rfq.name, supplier_wt_appos[0].get("supplier"))
sq.submit()
frappe.form_dict = frappe.local("form_dict")
frappe.form_dict.name = rfq.name
self.assertEqual(
check_supplier_has_docname_access(supplier_wt_appos[0].get('supplier')),
True
)
# reset form_dict
frappe.form_dict.name = None
def test_make_supplier_quotation_from_portal(self):
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import create_supplier_quotation
rfq = make_request_for_quotation()
@@ -44,8 +71,11 @@ class TestRequestforQuotation(unittest.TestCase):
self.assertEquals(supplier_quotation_doc.get('items')[0].amount, 500)
def make_request_for_quotation():
supplier_data = get_supplier_data()
def make_request_for_quotation(supplier_data=None):
"""
:param supplier_data: List containing supplier data
"""
supplier_data = supplier_data if supplier_data else get_supplier_data()
rfq = frappe.new_doc('Request for Quotation')
rfq.transaction_date = nowdate()
rfq.status = 'Draft'
@@ -77,3 +107,8 @@ def get_supplier_data():
"supplier": "_Test Supplier 1",
"supplier_name": "_Test Supplier 1"
}]
supplier_wt_appos = [{
"supplier": "_Test Supplier '1",
"supplier_name": "_Test Supplier '1",
}]

View File

@@ -0,0 +1,3 @@
{% include "erpnext/regional/india/party.js" %}
erpnext.setup_gst_reminder_button('Supplier');

View File

@@ -2,10 +2,10 @@
// License: GNU General Public License v3. See license.txt
frappe.ui.form.on("Supplier", {
setup: function(frm) {
frm.set_query('default_price_list', { 'buying': 1});
frm.set_query('account', 'accounts', function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
setup: function (frm) {
frm.set_query('default_price_list', { 'buying': 1 });
frm.set_query('account', 'accounts', function (doc, cdt, cdn) {
var d = locals[cdt][cdn];
return {
filters: {
'account_type': 'Payable',
@@ -15,30 +15,30 @@ frappe.ui.form.on("Supplier", {
}
});
},
refresh: function(frm) {
frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Supplier'}
refresh: function (frm) {
frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Supplier' }
if(frappe.defaults.get_default("supp_master_name")!="Naming Series") {
if (frappe.defaults.get_default("supp_master_name") != "Naming Series") {
frm.toggle_display("naming_series", false);
} else {
erpnext.toggle_naming_series();
}
if(frm.doc.__islocal){
hide_field(['address_html','contact_html']);
frappe.geo.clear_address_and_contact(frm);
if (frm.doc.__islocal) {
hide_field(['address_html','contact_html']);
frappe.contacts.clear_address_and_contact(frm);
}
else {
unhide_field(['address_html','contact_html']);
frappe.geo.render_address_and_contact(frm);
unhide_field(['address_html','contact_html']);
frappe.contacts.render_address_and_contact(frm);
// custom buttons
frm.add_custom_button(__('Accounting Ledger'), function() {
frm.add_custom_button(__('Accounting Ledger'), function () {
frappe.set_route('query-report', 'General Ledger',
{party_type:'Supplier', party:frm.doc.name});
{ party_type: 'Supplier', party: frm.doc.name });
});
frm.add_custom_button(__('Accounts Payable'), function() {
frappe.set_route('query-report', 'Accounts Payable', {supplier:frm.doc.name});
frm.add_custom_button(__('Accounts Payable'), function () {
frappe.set_route('query-report', 'Accounts Payable', { supplier: frm.doc.name });
});
// indicators

View File

@@ -6,7 +6,7 @@ import frappe
import frappe.defaults
from frappe import msgprint, _
from frappe.model.naming import make_autoname
from frappe.geo.address_and_contact import load_address_and_contact, delete_contact_and_address
from frappe.contacts.address_and_contact import load_address_and_contact, delete_contact_and_address
from erpnext.utilities.transaction_base import TransactionBase
from erpnext.accounts.party import validate_party_accounts, get_dashboard_info, get_timeline_data # keep this

View File

@@ -1,3 +1,3 @@
frappe.listview_settings['Supplier'] = {
add_fields: ["supplier_name", "supplier_type"],
add_fields: ["supplier_name", "supplier_type", "image"],
};

View File

@@ -5,7 +5,7 @@
{% include 'erpnext/public/js/controllers/buying.js' %};
frappe.ui.form.on('Suppier Quotation', {
setup: function() {
setup: function(frm) {
frm.custom_make_buttons = {
'Purchase Order': 'Purchase Order'
}

View File

@@ -10,7 +10,6 @@ frappe.pages['purchase-analytics'].on_page_load = function(wrapper) {
new erpnext.PurchaseAnalytics(wrapper);
frappe.breadcrumbs.add("Buying");
}
@@ -18,7 +17,6 @@ erpnext.PurchaseAnalytics = frappe.views.TreeGridReport.extend({
init: function(wrapper) {
this._super({
title: __("Purchase Analytics"),
page: wrapper,
parent: $(wrapper).find('.layout-main'),
page: wrapper.page,
doctypes: ["Item", "Item Group", "Supplier", "Supplier Type", "Company", "Fiscal Year",
@@ -193,13 +191,13 @@ erpnext.PurchaseAnalytics = frappe.views.TreeGridReport.extend({
},
prepare_balances: function() {
var me = this;
var from_date = dateutil.str_to_obj(this.from_date);
var to_date = dateutil.str_to_obj(this.to_date);
var from_date = frappe.datetime.str_to_obj(this.from_date);
var to_date = frappe.datetime.str_to_obj(this.to_date);
var is_val = this.value_or_qty == 'Value';
$.each(this.tl[this.based_on], function(i, tl) {
if (me.is_default('company') ? true : tl.company === me.company) {
var posting_date = dateutil.str_to_obj(tl.posting_date);
var posting_date = frappe.datetime.str_to_obj(tl.posting_date);
if (posting_date >= from_date && posting_date <= to_date) {
var item = me.item_by_name[tl[me.tree_grid.item_key]] ||
me.item_by_name['Not Set'];

View File

@@ -3,6 +3,6 @@
frappe.require("assets/erpnext/js/purchase_trends_filters.js", function() {
frappe.query_reports["Purchase Order Trends"] = {
filters: get_filters()
filters: erpnext.get_purchase_trends_filters()
}
});

View File

@@ -3,30 +3,26 @@
frappe.query_reports["Quoted Item Comparison"] = {
"filters": [
{
"fieldname":"supplier_quotation",
"label": __("Supplier Quotation"),
"fieldtype": "Link",
"options": "Supplier Quotation",
"default": "",
"get_query": function() {
return {
filters: {"docstatus": ["<",2]}
}
{
"fieldname": "supplier_quotation",
"label": __("Supplier Quotation"),
"fieldtype": "Link",
"options": "Supplier Quotation",
"default": "",
"get_query": function () {
return { filters: { "docstatus": ["<", 2] } }
}
},{
"fieldname":"item",
"label": __("Item"),
"fieldtype": "Link",
"options": "Item",
"default": "",
"reqd": 1,
"get_query": function() {
},
{
"fieldname": "item",
"label": __("Item"),
"fieldtype": "Link",
"options": "Item",
"default": "",
"reqd": 1,
"get_query": function () {
var quote = frappe.query_report_filters_by_name.supplier_quotation.get_value();
if (quote != "")
{
if (quote != "") {
return {
query: "erpnext.buying.doctype.quality_inspection.quality_inspection.item_query",
filters: {
@@ -35,79 +31,74 @@ frappe.query_reports["Quoted Item Comparison"] = {
}
}
}
else{
return{
filters: {"disabled":0}
else {
return {
filters: { "disabled": 0 }
}
}
}
}
}
],
onload: function(report) {
//Create a button for setting the default supplier
report.page.add_inner_button(__("Select Default Supplier"), function() {
onload: function (report) {
// Create a button for setting the default supplier
report.page.add_inner_button(__("Select Default Supplier"), function () {
var reporter = frappe.query_reports["Quoted Item Comparison"];
//Always make a new one so that the latest values get updated
reporter.make_default_supplier_dialog(report);
report.dialog.show();
setTimeout(function() { report.dialog.input.focus(); }, 1000);
setTimeout(function () { report.dialog.input.focus(); }, 1000);
}, 'Tools');
},
"make_default_supplier_dialog": function (report) {
//Get the name of the item to change
// Get the name of the item to change
var filters = report.get_values();
var item_code = filters.item;
//Get a list of the suppliers (with a blank as well) for the user to select
// Get a list of the suppliers (with a blank as well) for the user to select
var select_options = "";
for (let supplier of report.data)
{
select_options += supplier.supplier_name+ '\n'
for (let supplier of report.data) {
select_options += supplier.supplier_name + '\n'
}
//Create a dialog window for the user to pick their supplier
// Create a dialog window for the user to pick their supplier
var d = new frappe.ui.Dialog({
title: __('Select Default Supplier'),
fields: [
{fieldname: 'supplier', fieldtype:'Select', label:'Supplier', reqd:1,options:select_options},
{fieldname: 'ok_button', fieldtype:'Button', label:'Set Default Supplier'},
{ fieldname: 'supplier', fieldtype: 'Select', label: 'Supplier', reqd: 1, options: select_options },
{ fieldname: 'ok_button', fieldtype: 'Button', label: 'Set Default Supplier' },
]
});
//On the user clicking the ok button
d.fields_dict.ok_button.input.onclick = function() {
// On the user clicking the ok button
d.fields_dict.ok_button.input.onclick = function () {
var btn = d.fields_dict.ok_button.input;
var v = report.dialog.get_values();
if(v) {
if (v) {
$(btn).set_working();
//Set the default_supplier field of the appropriate Item to the selected supplier
// Set the default_supplier field of the appropriate Item to the selected supplier
frappe.call({
method: "frappe.client.set_value",
args: {
doctype: "Item",
doctype: "Item",
name: item_code,
fieldname: "default_supplier",
value: v.supplier,
value: v.supplier,
},
callback: function (r){
callback: function (r) {
$(btn).done_working();
msgprint("Successfully Set Supplier");
frappe.msgprint("Successfully Set Supplier");
report.dialog.hide();
}
});
}
}
report.dialog = d;
}
}

View File

@@ -0,0 +1,8 @@
### Production Order Enahancement
- Show required items child table.
- Source warehouse for each Raw Materials, in Production Order Item and BOM Item table.
- Group warehouse allowed for Source and WIP warehouse.
### GST Tax Invoice Print Format
- Added print format to show tax(GST) breakup.
- Total Stock Summary report.
- Include Search Fields in Customer Query.

View File

@@ -0,0 +1,49 @@
# Copyright (c) 2015, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals, absolute_import, print_function
import click
import frappe
from frappe.commands import pass_context, get_site
def call_command(cmd, context):
return click.Context(cmd, obj=context).forward(cmd)
@click.command('make-demo')
@click.option('--site', help='site name')
@click.option('--domain', default='Manufacturing')
@click.option('--days', default=100,
help='Run the demo for so many days. Default 100')
@click.option('--resume', default=False, is_flag=True,
help='Continue running the demo for given days')
@click.option('--reinstall', default=False, is_flag=True,
help='Reinstall site before demo')
@pass_context
def make_demo(context, site, domain='Manufacturing', days=100,
resume=False, reinstall=False):
"Reinstall site and setup demo"
from frappe.commands.site import _reinstall
from frappe.installer import install_app
site = get_site(context)
if resume:
with frappe.init_site(site):
frappe.connect()
from erpnext.demo import demo
demo.simulate(days=days)
else:
if reinstall:
_reinstall(site, yes=True)
with frappe.init_site(site=site):
frappe.connect()
if not 'erpnext' in frappe.get_installed_apps():
install_app('erpnext')
# import needs site
from erpnext.demo import demo
demo.make(domain, days)
commands = [
make_demo
]

View File

@@ -35,7 +35,7 @@ def get_data():
{
"type": "report",
"name": "Accounts Receivable",
"doctype": "Sales Invoice",
"doctype": "Sales Invoice",
"is_query_report": True
},
{
@@ -198,6 +198,39 @@ def get_data():
},
]
},
{
"label": _("Goods and Services Tax (GST India)"),
"items": [
{
"type": "doctype",
"name": "GST Settings",
},
{
"type": "doctype",
"name": "GST HSN Code",
},
{
"type": "report",
"name": "GST Sales Register",
"is_query_report": True
},
{
"type": "report",
"name": "GST Purchase Register",
"is_query_report": True
},
{
"type": "report",
"name": "GST Itemised Sales Register",
"is_query_report": True
},
{
"type": "report",
"name": "GST Itemised Purchase Register",
"is_query_report": True
},
]
},
{
"label": _("Budget and Cost Center"),
"items": [

View File

@@ -137,7 +137,14 @@ def get_data():
{
"type": "doctype",
"name": "Assessment Result Tool"
}
},
{
"type": "report",
"is_query_report": True,
"name": "Course wise Assessment Report",
"doctype": "Assessment Result"
},
]
},
{

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