Compare commits

...

331 Commits

Author SHA1 Message Date
mbauskar
4f939b82b6 Merge branch 'hotfix' 2017-08-31 15:31:47 +05:30
mbauskar
2a4328b4f5 bumped to version 8.10.1 2017-08-31 16:01:47 +06:00
tundebabzy
7f8a259beb Fixer Always Fetches Latest Exchange Rate Even When Date is Specified (#10596) (#10597)
* test that confirms the bug. Same test should pass after fix

* make use of correct api url
2017-08-31 14:30:15 +05:30
rohitwaghchaure
56e31d05e9 [Fix] POS customer field is hang while searching customer, make error log if sync has failed (#10607) 2017-08-31 14:19:58 +05:30
krnkris
3c635e219e Rename fr_plan_comptable_général.json to fr_plan_comptable_general.json (#10601) 2017-08-31 14:17:46 +05:30
Makarand Bauskar
de278635a3 [hotfix] fixes for UnicodeDecodeError (#10620) 2017-08-31 13:36:56 +05:30
mbauskar
5096c45dec Merge branch 'master' into hotfix 2017-08-29 20:42:06 +05:30
mbauskar
fd6b371dac Merge branch 'staging' 2017-08-29 20:38:21 +05:30
mbauskar
c0f34f454b bumped to version 8.10.0 2017-08-29 21:08:21 +06:00
tundebabzy
1a947dbf6a Item Name not loaded in Material Request via BOM (#10535) (#10555)
* adds item_name to child table

* adds two new functions to utils:
- first_row_is_empty: to check if first row in child table is empty
- remove_empty_first_row: to remove the empty first row in a child table

* removes empty first row after getting from BOM

* ui test
2017-08-29 18:18:27 +05:30
Faris Ansari
847f9f80c1 Merge pull request #10559 from mntechnique/pos_scanner_hotfix
[Fix] POS Scanner
2017-08-28 16:54:01 +05:30
Faris Ansari
8fbc08f91f Decrease timeout to 400 2017-08-28 16:52:20 +05:30
mbauskar
5d0c4361ab resolved merged conflicts 2017-08-28 11:58:44 +05:30
mbauskar
95e13ea629 Merge branch 'hotfix' 2017-08-28 11:56:17 +05:30
mbauskar
d44af40de8 bumped to version 8.9.2 2017-08-28 12:26:17 +06:00
Nabin Hait
2df0788c11 Validate for negative outstanding reference only if party is Customer or Supplier (#10568) 2017-08-28 11:23:33 +05:30
Revant Nandgaonkar
2558daf6b7 Allow search without keypress enter 2017-08-26 15:52:35 +05:30
Revant Nandgaonkar
2f7cb82ca0 [Fix] POS Scanner
Search item based on key press instead of 1sec wait
Fast Scanning needs this to avoid 1sec delay
2017-08-26 09:58:15 +05:30
Nabin Hait
caab582943 Tax breakup for actual amount and fixes in itemised purchase register (#10515)
* Tax breakup for actual amount and fixes in itemised pur register

* Rounding of itemised tax breakup amount
2017-08-24 16:22:28 +05:30
Rushabh Mehta
6b651d734e [fix] status in purchase_receipt.py (#10534) 2017-08-24 15:47:49 +05:30
Rushabh Mehta
7e506af0b9 [fix] warehouse query fixes https://github.com/frappe/erpnext/issues/10537 (#10538) 2017-08-24 15:23:33 +05:30
mbauskar
dc9744f353 Merge branch 'develop' into staging 2017-08-23 13:19:48 +05:30
Makarand Bauskar
dd8c0febd5 [minor] changed the modified date for bom for rename_bom_update_tool patch (#10509) 2017-08-23 13:17:37 +05:30
mbauskar
2d2b12c800 Merge branch 'hotfix' 2017-08-23 13:06:43 +05:30
mbauskar
06f5ae0e78 Merge branch 'master' into develop 2017-08-23 13:06:43 +05:30
mbauskar
918f029d98 bumped to version 8.9.1 2017-08-23 13:36:43 +06:00
Nabin Hait
cb40bd86f8 Supplier bill no in GST itemised purchase register (#10513) 2017-08-23 13:04:50 +05:30
Saurabh
b903c86076 Merge pull request #10506 from nabinhait/hotfix677
Minor fix in itemised sales register
2017-08-23 11:13:31 +05:30
Nabin Hait
fcb2462902 Minor fix in itemised sales register 2017-08-23 09:44:33 +05:30
mbauskar
1669404f06 Merge branch 'staging' 2017-08-22 20:22:24 +05:30
mbauskar
b69ec059fe Merge branch 'master' into develop 2017-08-22 20:22:24 +05:30
mbauskar
d46a9572af bumped to version 8.9.0 2017-08-22 20:52:24 +06:00
rohitwaghchaure
7379e4e5de Merge pull request #10195 from nabinhait/auto_update_bom_cost
Update BOM cost in all BOMs based on latest rm rate
2017-08-22 19:14:53 +05:30
Nabin Hait
bb326f2bbd Chart of accounts for Taiwan (#10435) 2017-08-22 19:07:42 +05:30
Nabin Hait
34c218b2de Minor improvements based on skip_transfer (#10457) 2017-08-22 19:07:16 +05:30
Nabin Hait
382f5eb1b1 Run sales/purchase register for one month by default (#10493) 2017-08-22 19:06:21 +05:30
Doridel Cahanap
a6a93cbe06 [Fix] Request for Quotation Portal Title (#10489) 2017-08-22 18:39:38 +05:30
Vishal Dhayagude
a1637d8343 [UI Test] UI test for Sales Invoice with Payment Entry (#10483)
* [UI Test] UI test for Sales Invoice with Payment Entry

* Update test_purchase_order_receipt.js
2017-08-22 18:33:17 +05:30
Utkarsh Goswami
5cf3bdd593 Travis fix for purchase order receipt (#10498) 2017-08-22 17:39:06 +05:30
mbauskar
081ff80882 Merge branch 'hotfix' 2017-08-22 15:42:10 +05:30
mbauskar
4396a0e9a8 Merge branch 'master' into staging 2017-08-22 15:42:10 +05:30
mbauskar
3b3ab4d574 Merge branch 'master' into develop 2017-08-22 15:42:10 +05:30
mbauskar
974cfd2895 bumped to version 8.8.6 2017-08-22 16:12:09 +06:00
rohitwaghchaure
187cea3602 [Fix] Accepting duplicate serial no is purchase receipt (#10469)
* [Fix] Accepting duplicate serial no is purchase receipt

* Fixed test cases
2017-08-22 15:38:32 +05:30
Nabin Hait
28d8557905 [fix] Taxes in itemised purchase register (#10494) 2017-08-22 15:30:45 +05:30
mbauskar
8f4e1712ba Merge branch 'hotfix' 2017-08-22 12:03:47 +05:30
mbauskar
7716a08b5d Merge branch 'master' into staging 2017-08-22 12:03:47 +05:30
mbauskar
7d9452f4e4 Merge branch 'master' into develop 2017-08-22 12:03:47 +05:30
mbauskar
4cbd43cb40 bumped to version 8.8.5 2017-08-22 12:33:46 +06:00
Makarand Bauskar
11224eaf06 [hotfix] fixes for TypeError: 'NoneType' object is not iterable (#10484) 2017-08-22 12:03:02 +05:30
rohitwaghchaure
02bad86037 Merge pull request #10473 from rohitwaghchaure/item_group_issue_in_pos
[Fix] Pricing rule applying only on item groups defined in POS profile
2017-08-22 11:34:49 +05:30
Nabin Hait
6c6e45157b Fixed test case for replace bom 2017-08-22 10:49:58 +05:30
Nabin Hait
52cc08dd2d Test case added for replacing BOM 2017-08-22 10:49:57 +05:30
Nabin Hait
adbf8adfb9 Update BOM cost in all BOMs based on latest rm rate 2017-08-22 10:49:57 +05:30
Makarand Bauskar
a591d1df5f [minor] ingore user permission for old_parent fields (#10471) 2017-08-21 19:04:49 +05:30
Rohit Waghchaure
33326fe90e [Fix] Pricing rule applying only on item groups defined in POS profile 2017-08-21 16:30:21 +05:30
Ameya Shenoy
c87c1dbbbf converted production tests to INR from USD (#10472) 2017-08-21 14:10:04 +05:30
Rushabh Mehta
575ab3ab70 [docs] for print style (#10452) 2017-08-21 12:24:28 +05:30
mbauskar
5088ad11ee Merge branch 'master' into staging 2017-08-21 08:58:52 +05:30
mbauskar
62f0722325 resolved merge conflicts 2017-08-21 08:58:42 +05:30
mbauskar
9d6900bd3b Merge branch 'hotfix' 2017-08-21 08:57:32 +05:30
mbauskar
ddb26d02e5 bumped to version 8.8.4 2017-08-21 09:27:32 +06:00
Nabin Hait
879e162cce Additional GST related fields in Invoice and Sales/Purchase Register reort (#10405) 2017-08-21 08:28:55 +05:30
Zarrar
196b491ac4 [ui test ] Travis failing fix (#10468)
* Value in assertion was wrong

* Update test_purchase_order_receipt.js
2017-08-21 08:07:42 +05:30
Nabin Hait
1f49f511aa Tax rate in Itemised sales/purchase register and cleanups (#10439) 2017-08-21 08:05:12 +05:30
rohitwaghchaure
0d9ab86496 [Fix] Making of production order from so, system not fetched the items from the sales order item if packing list has items and vice versa (#10453) 2017-08-21 07:52:49 +05:30
rohitwaghchaure
6b1624cfee [Fix] Tax rule is not working for the parent customer groups (#10458) 2017-08-21 07:38:37 +05:30
Makarand Bauskar
222e86bb13 [hotfix] fixed the mysql syntax error issue on stock ledger report (#10442) 2017-08-21 07:35:16 +05:30
Makarand Bauskar
80d06da978 [hotfix] fixed mysql syntax error in Student and Guardian Contact Details report (#10450) 2017-08-21 07:34:45 +05:30
KanchanChauhan
dd351c585a [Minor] Title added to rfq web view (#10454) 2017-08-20 11:00:43 +05:30
Vishal Dhayagude
8fd5b325e0 [UI Test] travis.yml modified for fresh UI Test (#10446)
* [UI Test] travis.yml modified for fresh UI Test

* [fix] travis

* Update test_production_order.js

* Update test_production_order.js

* Update test_purchase_order_receipt.js

* Update tests.txt

* Update test_purchase_order_receipt.js
2017-08-20 10:59:48 +05:30
Vishal Dhayagude
592e8c2e77 [UI Test] UI Test added for Stock Reconciliation (#10432)
* [UI Test] UI Test added for Stock Reconciliation

* [fix] Codacy
2017-08-18 15:01:20 +05:30
Utkarsh Goswami
5a27aead06 Test for Process Payroll (#10447) 2017-08-18 13:12:53 +05:30
Utkarsh Goswami
ca63cc6439 [UI Test Recruitment] To test Recruitment in HR module (#10441)
* Tests for Recruitment

* Codacy fix
2017-08-18 11:57:01 +05:30
Vishal Dhayagude
2890fa74a2 [UI Test] UI Test for Purchase Receipt Added (#10434) 2017-08-18 11:55:14 +05:30
Zarrar
780f11ec16 path to test updated (#10438) 2017-08-17 18:36:33 +05:30
Makarand Bauskar
fe43ecb5ee [hotfix] fixed type in gst_state_code_data.json file (#10437) 2017-08-17 17:34:25 +05:30
rohitwaghchaure
fff56530c4 [Fix] Due date not fetching on the payment entry against the invoices (#10419) 2017-08-17 14:47:25 +05:30
Nabin Hait
5b266eff89 Update patches.txt 2017-08-17 14:42:50 +05:30
Makarand Bauskar
446c2b0e91 [hotfix] fixes for https://github.com/frappe/erpnext/issues/9782 calculate leave without pay before subtracting holidays (#10355) 2017-08-17 12:39:35 +05:30
Nabin Hait
0650d8e155 Merge branch 'bcornwellmott-no_quote' into develop 2017-08-17 12:03:01 +05:30
Ben Cornwell-Mott
ee9f9863ff MORE CODACY 2017-08-17 11:29:11 +05:30
Ben Cornwell-Mott
9727a3fe50 More codacy issues 2017-08-17 11:27:31 +05:30
Rohit Waghchaure
df83191ea0 Set write permission to sales manger for permlevel 1 in Quotation doctype 2017-08-17 11:27:30 +05:30
Ben Cornwell-Mott
13218f7d76 Fixed codacy issues 2017-08-17 11:25:12 +05:30
Ben Cornwell-Mott
bea7d9f919 Added tests 2017-08-17 11:25:12 +05:30
Ben Cornwell-Mott
1b43515160 Codacy fixes 2017-08-17 11:18:49 +05:30
Ben Cornwell-Mott
48058a88e5 Minor cleanup 2017-08-17 11:18:49 +05:30
Ben Cornwell-Mott
f7e42211b9 Added Quote Status to RFQ Suppliers with No Quote 2017-08-17 11:18:49 +05:30
Zarrar
abd3419632 made test less dependent on python test data (#10424) 2017-08-17 11:04:16 +05:30
Shreya Shah
b5ed6823d6 [UI Test] Buying - Create Purchase receipt (#10421)
* Create purchase receipt after submitting the purchase order

* Checks quantity and rate in stock ledger
2017-08-17 11:03:43 +05:30
Vishal Dhayagude
f37eacdee5 [UI Test] Purchase Invoice (#10422)
* [UI Test] Purchase Invoice

* [fix] Travis failed
2017-08-17 11:01:59 +05:30
Nabin Hait
64c32dcd59 [fix] Update monthly sales value on Company (#10417)
* [fix] Update monthly sales value on cancellation of invoice, also update modified datestamp

* Company monthly sales: patches and test cases
2017-08-16 15:04:18 +05:30
Zarrar
9eb8680ec9 travis failing issue fix (#10420) 2017-08-16 13:25:31 +05:30
tundebabzy
f35710db15 remove empty first row if needed (#10378)
refactor code: move global functions to callback scope
2017-08-16 13:25:18 +05:30
tundebabzy
258faab761 Transaction Forms (Payment Entry, Sales Invoice, Purchase Invoice) can forget company currency (#10409) (#10410)
* properly keep track of document currency and company currency

* Update taxes_and_totals.js
2017-08-16 13:16:46 +05:30
tundebabzy
5fc5b68a49 update multi currency accounting documentation to remove incorrect info (#10404) 2017-08-16 11:41:56 +05:30
Manas Solanki
0371d5a326 new item group filter in the stock ledger report (#10400) 2017-08-16 11:35:04 +05:30
Utkarsh Goswami
44b088c6b3 [UI Test Salary] To test the salary structure and the salary slip (#10407)
* Test for salary structure and salary slip

* Test for salary structure and salary slip

* Test for salary structure and salary slip

* Travis CI fixes

* Updated

* Updated

* travis fixes

* Travis fixes
2017-08-16 11:32:04 +05:30
Shreya Shah
289400d944 [UI Test] Buying module - Multiple tests for Purchase orders (#10414)
* Extended timeout to avoid rare failures

* Get purchase orders with discount on grand total

* Get purchase orders with discount on individual items

* Get purchase orders and calculate taxes

* Added paths
2017-08-16 11:31:34 +05:30
Shreya Shah
f6544e95d4 [UI Tests] Buying Module - Supplier quotations and Purchase orders (#10397)
* Get Supplier Quotation with item wise discount

* Get purchase orders

* Added paths

* Codacy fix
2017-08-14 17:29:09 +05:30
Makarand Bauskar
0973161ae5 [docs] Translate the Schools Assessment section documentation to Spanish (#10398)
* [docs] Translate the Schools app documentation to Spanish

* [docs] Translate the Schools Student section documentation to Spanish

* [docs] Translate the Schools SETUP section documentation to Spanish

* [docs] Translate the Schools ADMISSION section documentation to Spanish

* [docs] Translate the Schools FEES section documentation to Spanish

* [docs] Translate the Schools SCHEDULE section documentation to Spanish

* [docs] Translate the Schools Assessment section documentation to Spanish
2017-08-14 14:55:48 +05:30
mbauskar
40377e87de Merge branch 'master' into staging 2017-08-14 12:33:56 +05:30
mbauskar
7b7a77a551 Merge branch 'hotfix' 2017-08-14 12:33:55 +05:30
mbauskar
4ca3e8f70a Merge branch 'master' into develop 2017-08-14 12:33:55 +05:30
mbauskar
e0cc7c64a1 bumped to version 8.8.3 2017-08-14 13:03:55 +06:00
Makarand Bauskar
e5ae4d3bd3 send email via the background jobs (#10374) (#10393)
* send the email via the background worker in the payment request (#10350)

* send email via the background jobs (#10374)
2017-08-14 12:22:50 +05:30
Vishal Dhayagude
7186131d65 [UI Test] sales invoice (#10394)
* [UI Test] Sales Invoice

* [UI Test] Sales Invoice
2017-08-14 12:22:04 +05:30
Manas Solanki
a5cb9ae8bd send email via the background jobs (#10374) 2017-08-14 09:50:15 +05:30
mbauskar
f03afe0878 Merge branch 'master' into staging 2017-08-14 09:31:01 +05:30
mbauskar
2fa8af3b02 Merge branch 'master' into develop 2017-08-14 09:31:01 +05:30
mbauskar
41d77e8d86 Merge branch 'hotfix' 2017-08-14 09:31:00 +05:30
mbauskar
b2f160eef0 bumped to version 8.8.2 2017-08-14 10:01:00 +06:00
Shreya Shah
67e2ef30c4 [UI test] Buying module - Get Supplier Quotations (#10375)
* Get quotations for Suppliers

* Calculate taxes and charges for Supplier quotations

* Added paths for tests

* Codacy fix

* Improvised the page route function
2017-08-14 09:17:00 +05:30
tundebabzy
041b9c3c32 make item name read only and add hide if not saved (#10382) 2017-08-14 09:16:07 +05:30
Vishal Dhayagude
22baba2cff [UI TEST] Test added for Delivery Note (#10376) 2017-08-11 17:17:30 +05:30
Faris Ansari
7273cb7f54 Track changes in Account doctype (#10373) 2017-08-11 16:19:28 +05:30
Vishal Dhayagude
4157b64776 [UI Test] Multiple UI Test for Stock Entry added (#10354) 2017-08-11 12:06:16 +05:30
Shreya Shah
9e30969243 Fetching items from material requests doctype (#10363) 2017-08-11 12:02:35 +05:30
Rushabh Mehta
dbb5154f37 Fixes in Order / Quotation (#10361)
* Additions in Order Page for Sidebar Menu with "Order" page route

* Adjust Columns in order_taxes.html to avoid number breaks for more precisions

* Fields additions in transaction_row.html

* [fix] style for order pages, indicator for quotation etc

* [fix] style for order pages, indicator for quotation etc

* [test] add timeout
2017-08-10 21:06:09 +05:30
Shreya Shah
5ae39ae79a Get Quotation requests and send emails to suppliers (#10356) 2017-08-10 16:20:47 +05:30
rohitwaghchaure
2e8232e7aa [Fix] Getting an error cost center is not defined in the purchase receipt, even if it's defined in the company (#10320) 2017-08-10 11:32:59 +05:30
Makarand Bauskar
aac8349391 [hotfix] remove the white spaces from condition and formula fields (#10331)
* [hotfix] remove the white spaces from condition and formula fields

* [tests] added tests cases for whitespaces in formula and condition fields
2017-08-10 11:25:49 +05:30
Manas Solanki
a854ea00a5 mark holiday in the employee monthly attendance sheet (#10349) 2017-08-10 11:20:58 +05:30
Manas Solanki
e97f587411 send the email via the background worker in the payment request (#10350) 2017-08-10 11:17:38 +05:30
rohitwaghchaure
35438b6fc0 [Fix] Opportunity status has not changed after making of quotation against it if items has not added in the opportunity (#10351) 2017-08-10 11:15:50 +05:30
Rushabh Mehta
17e5f4132c [tests] less verbose logs 2017-08-10 11:03:26 +05:30
mbauskar
08c3f4758e Merge branch 'develop' into staging 2017-08-10 10:58:17 +05:30
mbauskar
5039d6de6f Merge branch 'develop' into staging 2017-08-10 10:56:33 +05:30
Zarrar
14468e79a3 [ui test] Student assessment and result (#10353)
* updated to test more thoroughly

* backbone set to generate result

* rebased with develop
2017-08-10 10:56:22 +05:30
Shreya Shah
243f091b30 Get supplier details (#10352) 2017-08-10 10:51:47 +05:30
Vishal Dhayagude
e05c2e5d95 [UI Test] for Stock Entery (#10346) 2017-08-09 17:36:04 +05:30
rohitwaghchaure
5999ade43a [Fix] Auto batch creation not working for purchase invoice is update stock is enabled (#10348) 2017-08-09 17:24:13 +05:30
Vishal Dhayagude
bde05e96a6 [UI TEST] Multiple test for Materail request (#10347) 2017-08-09 16:56:14 +05:30
Vishal Dhayagude
da30a69ee7 [UI Test] test added for Material Request (#10338)
* [UI Test] test added for Material Request

* [mod] date in material request
2017-08-09 13:08:38 +05:30
mbauskar
353956a864 Merge branch 'hotfix' 2017-08-09 11:17:55 +05:30
mbauskar
42251da131 Merge branch 'master' into develop 2017-08-09 11:17:55 +05:30
mbauskar
3e29a28cee bumped to version 8.8.1 2017-08-09 11:47:55 +06:00
Makarand Bauskar
60fcf47f6a [hotfix] changed the modified date for quotation (#10337) 2017-08-09 11:15:18 +05:30
Rushabh Mehta
dfd8f9b0ce [docs] move calculate-incentive-for-sales-team.md 2017-08-09 10:49:59 +05:30
Rushabh Mehta
c957ce161f [fix] titles 2017-08-09 10:46:17 +05:30
Rushabh Mehta
67884cb7cf [fix] remove 2fa from wizard docs 2017-08-09 10:46:17 +05:30
Zarrar
17e35e6ac7 [ui tests] Student attendance and leave application (#10326)
* spelling error rectified

* setting up leave application

* marking attendance and checking

* typo error fixed
2017-08-08 18:24:15 +05:30
Vishal Dhayagude
135560e170 [UI Test] Multiple UI Test for Quotation (#10330) 2017-08-08 18:22:53 +05:30
rohitwaghchaure
468fb97c81 [Fix] Lead address not able to select on the quotation (#10328) 2017-08-08 17:27:58 +05:30
Doridel Cahanap
96e52be5f1 [Enhancement] Allow Sidebar Menu record search using text from Item Name of a record (#10324)
* Search Record in Sidebar Menu Using Item Name for Order Page

* Test Case to create 2 Quotations with different Items
2017-08-08 17:12:50 +05:30
mbauskar
53f0f62f1c Merge branch 'master' into develop 2017-08-08 16:07:57 +05:30
mbauskar
39ec7dc658 Merge branch 'staging' 2017-08-08 16:07:56 +05:30
mbauskar
e77102ea47 bumped to version 8.8.0 2017-08-08 16:37:56 +06:00
Nabin Hait
7f476b4528 The series added for Asset Depreciation Entry (#10268) 2017-08-08 15:01:02 +05:30
Makarand Bauskar
b985ad2a8e [minor] fixes for pos_profile in make-demo (#10289) 2017-08-08 15:00:30 +05:30
ckosiegbu
1ac6bcba23 Removal of SMS Settings and SMS Parameters from ERPNext (#10033)
* Removal of SMS Settings and SMS Parameter from ERPNext.

* [DOCS]Documentation for Two Factor Authentication

* [Patch]Point SMS module to frappe core

* Rearrange doc help index.txt to fit

* [DOCS]Update Documentation for Two Factor Authentication
2017-08-08 14:55:30 +05:30
Nabin Hait
32992d555d Added chart of accounts for Argentina, France, Brazil and Hungary (#10312) 2017-08-08 14:42:04 +05:30
KanchanChauhan
71088aa2bd Supplier Part No in Purchase Receipt since it exits in Purchase Order (#10314) 2017-08-08 14:41:35 +05:30
mbauskar
1065679720 Merge branch 'master' into staging 2017-08-08 12:54:12 +05:30
mbauskar
6b0b7912c4 Merge branch 'master' into develop 2017-08-08 12:54:12 +05:30
mbauskar
35167be0d9 Merge branch 'hotfix' 2017-08-08 12:54:11 +05:30
mbauskar
1846d0fa2f bumped to version 8.7.3 2017-08-08 13:24:11 +06:00
Rushabh Mehta
09d1eaa87b [minor] standard filters 2017-08-08 12:00:04 +05:30
Zarrar
40343da1b0 Student group creation (#10308)
* auto-fills groups with students

* improvised and rectified tests

* increased timer to avoid rare failures

* removed duplicate code

* requested changes implemented

* changes implemented
2017-08-08 11:43:28 +05:30
Saurabh
3a4b6c2cba [fix] redirect to payment url if paying via web portal (#10265)
* [fix] redirect to payment url if paying via web portal

* [fix] test case fix

* [fix] test case fixes
2017-08-08 11:29:11 +05:30
KanchanChauhan
255c5f4407 Supplier Delivery Note field added to Purchase Receipt, good to have for future references (#10309) 2017-08-08 11:23:45 +05:30
rohitwaghchaure
9ef1d0f5a5 [Fix] Balance sheet not working (#10311) 2017-08-08 11:23:25 +05:30
Nabin Hait
738d8c2e0f Changed patch order to reload domain 2017-08-08 11:15:13 +05:30
Manas Solanki
c0fb428075 print format for the assessment report (#10227)
* print format for the assessment report

* fix for the comma in assessment plan
2017-08-07 13:54:39 +05:30
Nabin Hait
632f7673d5 Added total row in GST reports (#10292) 2017-08-07 13:50:16 +05:30
Nabin Hait
79005e83d7 Merge pull request #10293 from ashwinisave35/knowledge_base_button
Changed Text of Knowledge base button to Help Article
2017-08-07 13:50:02 +05:30
Nabin Hait
19128134a8 Merge pull request #10295 from tundebabzy/issue-10099-2
BOM Currency symbol issue (#10099) - Stock Ledger report
2017-08-07 13:49:22 +05:30
tunde
80a9f37272 add options in get_columns 2017-08-04 12:08:09 +01:00
Ashwini Save
cbef770ed7 Changed Text of Knowledge base button to Help Article 2017-08-04 16:14:38 +05:30
Nabin Hait
51b4167cdd Merge pull request #10269 from tundebabzy/currency-issues
BOM - Currency symbol issue (#10099)
2017-08-04 15:36:35 +05:30
Zarrar
82d2828be6 [ui test] Student Group - manually and using creation tool (#10283)
* fixing issues in original files

* creating a student log

* student group - manually and using creation tool
2017-08-04 15:33:27 +05:30
mbauskar
4ef1e2046b Merge branch 'master' into staging 2017-08-04 14:08:57 +05:30
mbauskar
e770824568 Merge branch 'master' into develop 2017-08-04 14:08:57 +05:30
mbauskar
320fb13b37 Merge branch 'hotfix' 2017-08-04 14:08:56 +05:30
mbauskar
4796e8e317 bumped to version 8.7.2 2017-08-04 14:38:56 +06:00
rohitwaghchaure
87b6498e02 Merge pull request #10287 from rohitwaghchaure/fixed_test_case
Fixed test cases for dynamic link order
2017-08-04 14:00:41 +05:30
Rohit Waghchaure
499144fd86 Fixed test cases for dynamic link order 2017-08-04 13:30:59 +05:30
Makarand Bauskar
b96e239cc0 [hotfix] ignore if project type is None (#10284) 2017-08-04 11:40:23 +05:30
mbauskar
cce79255fe resolved merge conflicts 2017-08-04 11:07:49 +05:30
mbauskar
f3be738b68 resolved merge conflicts 2017-08-04 11:07:07 +05:30
mbauskar
139db5ffe7 Merge branch 'hotfix' 2017-08-04 11:05:01 +05:30
mbauskar
8cf951b574 bumped to version 8.7.1 2017-08-04 11:35:01 +06:00
rohitwaghchaure
0c1d441aa3 Test case for dynamic link order (#10276) 2017-08-04 10:55:46 +05:30
rohitwaghchaure
5906ddf804 [Fix] View ledger button not disaplying in the head of an account (#10254)
* [Fix] View ledger button not disaplying in the head of an account

* Show view ledger button in account if user has permission to read GL Entry data
2017-08-04 10:52:01 +05:30
Zarrar
326acc3ecb [ui test] fixed tests that used fees in any way (#10279)
* course table dependency on fee structure bypassed

* testing related to fees removed

* added more students data

* codacy fix
2017-08-04 10:51:26 +05:30
Vishal Dhayagude
592add9f0a [UI Test] Sales Order with Shipping Rule and Pricing Rule Added (#10270)
* [UI Test] Sales Order with Shipping Rule Added

* [UI Test] Sales Order with Pricing Rule Added
2017-08-04 10:51:08 +05:30
Rushabh Mehta
1696294847 [fix] remove property setter for project type (#10277)
* [fix] remove property setter for project type

* [patch] project type
2017-08-04 10:50:56 +05:30
Ameya Shenoy
4331067e57 [ui-test] completed tests for manufacturing (#10218)
* modified test_item to include child table assertions

* minor travis fixes

* removed css selectors and used cur_frm
2017-08-04 10:50:32 +05:30
rohitwaghchaure
046e1a6e28 [Fix] Patch broken if serial no has single quote (#10262) 2017-08-03 17:38:03 +05:30
Nabin Hait
ee5ff805e9 Book expense included in valuation only if perpetual inventory enabled (#10271) 2017-08-03 17:37:23 +05:30
mbauskar
329aae2458 Merge branch 'develop' into staging 2017-08-03 16:17:24 +05:30
Saurabh
33aaebac2b [fix] encode title and description in payment request (#10240) 2017-08-03 11:47:05 +05:30
Nabin Hait
af01f5154b Merge pull request #10251 from rohitwaghchaure/permlevel_1_write_permission
Set write permission to sales manger for permlevel 1 in Quotation doctype
2017-08-03 10:45:17 +05:30
Nabin Hait
b554f9077c Update set_write_permission_for_quotation_for_sales_manager.py 2017-08-03 10:44:55 +05:30
Nabin Hait
f7c1c2c812 Merge pull request #10260 from KanchanChauhan/field-name-change
[Minor] Changed country field name from "data_6" to "country"
2017-08-03 10:21:42 +05:30
Nabin Hait
bfb3de771b Merge pull request #10255 from tundebabzy/issue-10215
Error when creating Bank Entry from Process Payroll (#10215)
2017-08-03 10:20:31 +05:30
Nabin Hait
21045c456e Update process_payroll.py 2017-08-03 10:20:10 +05:30
Nabin Hait
5ebb9a0fc7 Merge pull request #10259 from pratu16x7/hotfix
[hotfix] website stock not shown due to discount not set
2017-08-03 10:19:13 +05:30
Kanchan Chauhan
1fd17a9a67 [Minor] Country field name should be country 2017-08-03 10:18:43 +05:30
tunde
7663bbadb9 edit Doctypes to use company currency 2017-08-03 00:05:56 +01:00
tunde
4a263c714d get_party_detail should use default currency of party 2017-08-02 22:26:39 +01:00
pratu16x7
7587b19d1b [fix] website stock not shown due to discount not set 2017-08-02 22:14:51 +05:30
tunde
919c9db1b0 indicator should be red 2017-08-02 15:19:24 +01:00
Nabin Hait
f5dee777dd minor fix in applying pricing rule 2017-08-02 19:08:39 +05:30
tunde
3b8b3fe766 Merge branch 'hotfix' into issue-10215 2017-08-02 14:27:56 +01:00
tunde
85adbd7eae show message if there's no submitted salary slip 2017-08-02 14:20:24 +01:00
tunde
c697526382 except in python 3 compatible style 2017-08-02 14:20:23 +01:00
mbauskar
2dd57acdef removed merge conflicts 2017-08-02 18:39:04 +05:30
mbauskar
99350db5e1 Merge branch 'staging' 2017-08-02 18:35:51 +05:30
mbauskar
478ffb9ae3 bumped to version 8.7.0 2017-08-02 19:05:51 +06:00
mbauskar
73dc35ddbf resolved merge conflicts 2017-08-02 18:24:03 +05:30
Rohit Waghchaure
250e964205 Set write permission to sales manger for permlevel 1 in Quotation doctype 2017-08-02 18:23:39 +05:30
mbauskar
ee090a9a3c Merge branch 'master' into develop 2017-08-02 18:18:14 +05:30
mbauskar
22a5e79b9a Merge branch 'hotfix' 2017-08-02 18:18:14 +05:30
mbauskar
4d49a7f6d1 bumped to version 8.6.6 2017-08-02 18:48:14 +06:00
Makarand Bauskar
ce436b7698 [minor] set description to '' if template description is not available (#10244) 2017-08-02 18:16:53 +05:30
rohitwaghchaure
ec9430dae7 [Fix] Default selling settings not fetched on customer quick entry form (#10243) 2017-08-02 18:16:13 +05:30
Faris Ansari
578624db1f Fix column width in GST Tax Breakup (#10230) 2017-08-02 17:44:32 +05:30
Vishal Dhayagude
ed0b107a9f [UI Test] UI test added for Pricing Rule (#10237)
* [UI Test] UI test added for Pricing Rule

* [mod]minor chages in pricing rule test

* [fix] codacy fixed
2017-08-02 17:31:20 +05:30
Vishal Dhayagude
f9e4893d9d [UI Test] Test added for Shipping Rule (#10229)
* [UI Test] Test added for Shipping Rule

* [fix]Travis Failed
2017-08-02 17:16:46 +05:30
Vishal Dhayagude
f1f1b60a62 [UI Test ] Sales Order with tax and discount (#10225)
* [new] UI Test for Sales Order

* [fix] Codacy fixed

* Update test_sales_order_with_discount_on_grand_total.js

* Update test_sales_order_with_taxes_and_charges.js
2017-08-02 17:15:47 +05:30
Zarrar
78c6e34106 [ui test] student applicant and various actions that can be taken (#10221)
* msgprint error fixed

* student applicant, various actions and its dependencies
2017-08-02 11:25:49 +05:30
Nabin Hait
9641d5b1f4 Make payment entry button in expense claim and some minor cleanup 2017-08-01 17:38:48 +05:30
Nabin Hait
edba79e8f0 Update utils.py 2017-08-01 17:38:48 +05:30
Ben Cornwell-Mott
38d4be8325 Update manuals. Fix codacy issues 2017-08-01 17:38:47 +05:30
Ben Cornwell-Mott
118ceda46f Add Payment Entry for Expenses 2017-08-01 17:35:50 +05:30
Vishal Dhayagude
316477b422 [UI Tests] All sales order test in tests folders (#10211)
* [new] Sales order with_discount, multi_uom, delivery_date added

* [fix] All sales order test in tests folder
2017-08-01 17:16:21 +05:30
Nabin Hait
564e8b74dc Minor fixing in setting cumulative tax amount 2017-08-01 16:35:22 +05:30
Nabin Hait
4ada637b17 Update taxes_and_totals.js 2017-08-01 16:20:59 +05:30
Nabin Hait
3a512af0e2 Merge pull request #10202 from nabinhait/hotfix
Minor fix in bom_stock_qty patch
2017-08-01 16:05:44 +05:30
Nabin Hait
1012bcdde5 Merge pull request #10210 from KanchanChauhan/this-is-me
[URGENT] "this" is "me"
2017-08-01 16:03:54 +05:30
Kanchan Chauhan
d0c5b3eb07 [URGENT] this is me 2017-08-01 16:02:01 +05:30
Nabin Hait
9b2b42dfc1 Minor fix in bom_stock_qty patch 2017-08-01 11:10:29 +05:30
Makarand Bauskar
317888211a merged hotfix branch into staging (#10191)
* [Fix] Error in sales invoice and POS if customer group not defined in the customer (#10148)

* Revert "[Fix] Error in sales invoice and POS if customer group not defined in the customer (#10148)" (#10159)

This reverts commit 4d2e782e42.

* [Fix] Unable to save asset because of float error issue (#10157)

* bumped to version 8.6.4

* [Fix] Error in sales invoice and POS if customer group not defined in the customer (#10160)

* Set billing hours to 0 in timesheet #9535 (#10139)

* `update_billing_hours` to use flt not cint

* if not billable, reset billable hours

* if not billable, reset time rates

* test

* [Fix] Timesheet Company Issue

* Added delivery date in SO parent form. Fixes #10104 (#10155)

* Added delivery date in SO parent form. Fixes #10104

* UI tests for sales order delivery date

* bumped to version 8.6.5
2017-08-01 11:06:41 +05:30
Nabin Hait
cd95134267 Rounding issue in tax calculation (#10135)
* Adjust rounding loss of discount in the last item row. Fixes #8952

* Fixed rounding issue in tax calculation. Fixes #8953, #8952, #8893, #6954, #8910

* Rounding related fixes for purchase cycle
2017-07-31 18:07:45 +05:30
Rushabh Mehta
1fb4abc322 [docs] cleanup 2017-07-31 17:40:17 +05:30
Vishal Dhayagude
95dfe27bf7 [UI Test] Sales Order with multi currency and tax (#10189)
* [UI Test] Sales Order with multi currency and tax

* [fix]Codacy fixed

* [fix] tests.txt
2017-07-31 17:29:25 +05:30
Rushabh Mehta
4920d73adb [docs] remove {{docs_base_url}} 2017-07-31 16:41:35 +05:30
Rushabh Mehta
95349fe360 [docs] add headings 2017-07-31 16:21:12 +05:30
Faris Ansari
40d3ad2bb4 Add erpnext-grey.png, add logo in footer (#10101)
* Add erpnext-grey.png, footer html

* Sent via ERPNext
2017-07-31 16:16:22 +05:30
Makarand Bauskar
98b52a7245 resolved merge conflicts on develop (#10185)
* resolved merge conflicts on develop

* [minor] removed the validate_activity
2017-07-31 15:09:52 +05:30
mbauskar
8b6f7914b0 resolved merge conflicts 2017-07-31 12:30:53 +05:30
mbauskar
4d185f3541 Merge branch 'hotfix' 2017-07-31 12:21:35 +05:30
mbauskar
892cd615f8 bumped to version 8.6.5 2017-07-31 12:51:35 +06:00
Nabin Hait
495ef67caa Added delivery date in SO parent form. Fixes #10104 (#10155)
* Added delivery date in SO parent form. Fixes #10104

* UI tests for sales order delivery date
2017-07-31 11:25:51 +05:30
Zarrar
35d3190822 [ui test] Setting up school course+program and their dependencies (#10142)
* setting up course and its dependencies

* rebasing with develop branch

* codacy fix

* added test for Program

* updated test-dada to maintain consistency with future tests
2017-07-31 11:05:52 +05:30
Ameya Shenoy
4e91f28ce5 [ui-testing] added test for production order (#10138)
* temporary commit for switching branches

* [ui-tests] added bill_of_materials test

* added warehouses required for production order

* [ui-test] added production order test

* debugging travis failure
2017-07-31 11:02:28 +05:30
Nabin Hait
3beb1ba667 Merge pull request #10165 from rohitwaghchaure/production_order_company_issue
[Fix] Timesheet Company Issue
2017-07-29 18:20:12 +05:30
Rohit Waghchaure
33977827c4 [Fix] Timesheet Company Issue 2017-07-29 14:15:50 +05:30
Nabin Hait
e09b507b6c Merge pull request #10062 from rohitwaghchaure/set_defualt_mode_payment
[enhance] Provision to set default mode of payment for the POS in POS profile
2017-07-28 21:10:05 +05:30
Nabin Hait
1fcd2b0676 Merge branch 'develop' into set_defualt_mode_payment 2017-07-28 21:09:42 +05:30
tundebabzy
41c954b8b3 Set billing hours to 0 in timesheet #9535 (#10139)
* `update_billing_hours` to use flt not cint

* if not billable, reset billable hours

* if not billable, reset time rates

* test
2017-07-28 21:05:15 +05:30
Faris Ansari
482331b987 [fix] Default Warehouse not obeying form value (#10153) 2017-07-28 20:58:39 +05:30
rohitwaghchaure
e2176b852e [Fix] Error in sales invoice and POS if customer group not defined in the customer (#10160) 2017-07-28 20:52:02 +05:30
Utkarsh Yadav
8990af458b [ui test] leave application in HR (#10151)
* added test for leave application

* minor changes and path added

* travis fixes

* minor changes
2017-07-28 19:37:15 +05:30
Vishal Dhayagude
569011fb21 [UI Test] Test for Product Bundle added (#10158) 2017-07-28 19:36:50 +05:30
Britlog
4c7709efbd Portal breadcrumbs (#10095) 2017-07-28 18:54:22 +05:30
Rushabh Mehta
11a3d51774 [test] test_sales_order.py 2017-07-28 17:11:11 +05:30
mbauskar
9d5b1b0e8f Merge branch 'hotfix' 2017-07-28 16:03:52 +05:30
mbauskar
3b27382013 Merge branch 'master' into develop 2017-07-28 16:03:52 +05:30
mbauskar
2b420f7038 bumped to version 8.6.4 2017-07-28 16:33:52 +06:00
rohitwaghchaure
353af64197 [Fix] Unable to save asset because of float error issue (#10157) 2017-07-28 15:55:46 +05:30
Rushabh Mehta
be4fd1100d [fix] test 2017-07-28 15:54:07 +05:30
Makarand Bauskar
8bccaed35a Revert "[Fix] Error in sales invoice and POS if customer group not defined in the customer (#10148)" (#10159)
This reverts commit 4d2e782e42.
2017-07-28 15:43:23 +05:30
Rushabh Mehta
8af33a513b [fix] test 2017-07-28 15:34:20 +05:30
rohitwaghchaure
4d2e782e42 [Fix] Error in sales invoice and POS if customer group not defined in the customer (#10148) 2017-07-28 15:21:22 +05:30
Rushabh Mehta
e16ec0c891 [minor] change docs_base_url 2017-07-28 14:56:59 +05:30
Makarand Bauskar
20f4d7f559 Merge branch 'develop' into set_defualt_mode_payment 2017-07-28 14:41:48 +05:30
Rushabh Mehta
0fcf44e1a2 User Permissions Redesign (#10006)
* [fixes] for user permission

* [docs] updated docs for user permissions

* [docs] updated docs for user permissions

* [docs] updated docs for user permissions
2017-07-28 14:33:15 +05:30
bcornwellmott
bab0c5a8a5 Add disable check for Activity Type (#10120)
* Add disable check for Activity Type

* Add check for disabled in Timesheet

* Codacy fixes

* Fixed bugs

* Restore permissions
2017-07-28 14:32:45 +05:30
Rushabh Mehta
bead70b43a Docs in website (#10149)
* [docs] move to erpnext.org

* [docs]

* [minor] add title
2017-07-28 11:44:08 +05:30
Utkarsh Yadav
1c8d8a9720 [ui test] leave type,leave control panel and leave allocation in HR (#10136)
* changes in attendance

* added test for leave type

* added test for leave control panel

* added test for leave allocation

* codacy fixes
2017-07-28 11:40:29 +05:30
Rushabh Mehta
d50da78f28 [fixes] errors caught on flake8 (#10126) 2017-07-28 11:39:01 +05:30
Rushabh Mehta
2653825d25 [fix] flake8 verison 2017-07-28 11:37:45 +05:30
Rohit Waghchaure
120b6c0b3c UI test cases and documentation 2017-07-28 01:52:10 +05:30
Rohit Waghchaure
5296e3c321 [enhance] Provision to set default mode of payment for the POS in POS profile 2017-07-27 19:17:05 +05:30
Saurabh
c07741d36f Merge branch 'master' into staging 2017-07-27 17:50:28 +05:30
Saurabh
734e635ef6 Merge branch 'hotfix' 2017-07-27 17:50:27 +05:30
Saurabh
8907f1d2c3 Merge branch 'master' into develop 2017-07-27 17:50:27 +05:30
Saurabh
6f9ef5b890 bumped to version 8.6.3 2017-07-27 18:20:27 +06:00
Zarrar
c54510660e [ui test] Minor files (#10133)
* added permissions for Administrator user

* updated files

* minor files for future tests

* added entry for all tests
2017-07-27 17:19:06 +05:30
Makarand Bauskar
145393b12f [hotfix] set the account name in GL entry instead of warehouse (#10134) 2017-07-27 16:46:40 +05:30
Makarand Bauskar
9c6e2c3637 [hotfix] included the get_purchase_trends_filters instead of get_sales_trends_filters in Purchase Receipts trends (#10127) 2017-07-27 16:23:57 +05:30
mbauskar
cfc2693b2e Merge branch 'hotfix' 2017-07-27 12:18:15 +05:30
mbauskar
7b764d03c2 Merge branch 'master' into develop 2017-07-27 12:18:15 +05:30
mbauskar
448d919cc1 bumped to version 8.6.2 2017-07-27 12:48:15 +06:00
Vishal Dhayagude
b528411ed1 [ui test]sales and taxes charges template (#10116) 2017-07-27 12:15:06 +05:30
Utkarsh Yadav
b8b01928d3 [ui test] employee attendance tool and attendance in HR (#10112)
* added test for attendance tool

* added test for attendance

* minor changes

* minor changes

* path added in tests.txt

* codacy fixes
2017-07-27 11:49:10 +05:30
tundebabzy
296603a861 auto populate all rows (#10090) 2017-07-27 11:47:56 +05:30
tundebabzy
84227a6c54 Employee Loan Should Be Limited To Employee Company (#10039) (#10093)
* filter employee drop down by company name

* codacy fix
2017-07-27 11:47:03 +05:30
tundebabzy
9281013d51 add transaction date call to get_exchange_rate (#10109) 2017-07-27 11:43:32 +05:30
tundebabzy
87ec6a12ef adds options to currency fields (#10118) 2017-07-27 11:38:17 +05:30
rohitwaghchaure
059f99e621 [Fix] Wrong avg. buying rate in the Gross Profit report (#10110) 2017-07-27 11:37:30 +05:30
rohitwaghchaure
8579dd1d78 [minor] If customer has removed getting an error (#10107) 2017-07-27 11:21:54 +05:30
cclauss
6848708377 old style exception, raise --> new style for Python 3 (#10082)
* old style raise --> raise() for Python 3

* old style exception --> new style for Python 3

* old style exception --> new style for Python 3

* old style exception --> new style for Python 3

* old style exception --> new style for Python 3

* old style exception --> new style for Python 3

* old style exception --> new style for Python 3

* old style exception --> new style for Python 3

* old style exception --> new style for Python 3

* old style exception --> new style for Python 3

* old style raise --> raise() for Python 3

* old style raise --> raise() for Python 3

* old style exception, raise --> new style for Python 3
2017-07-27 10:38:35 +05:30
Vishal Dhayagude
c67bf5026e [UI Test] Create tax account in Charts of account (#10105)
* [new]tax creation added

* [new]path added test.txt
2017-07-27 09:11:08 +05:30
Faris Ansari
fbec103ae7 Remove inline styling, add css classes (#10077) 2017-07-26 18:46:13 +05:30
Makarand Bauskar
1d9fd9aa52 [minor][wiz] fix company image alignment (#10114) (#10117) 2017-07-26 18:19:41 +05:30
KanchanChauhan
58c9934452 [fix] company graph based on base currency (#9950) 2017-07-26 18:17:11 +05:30
Prateeksha Singh
83535811ad [minor][wiz] fix company image alignment (#10114) 2017-07-26 18:11:37 +05:30
mbauskar
930dd5e54e Merge branch 'develop' into staging 2017-07-26 18:02:32 +05:30
KanchanChauhan
7800bd89dc Added Project Type new doctype to be added as link field for Project Type field in project instead of select field (#9929) 2017-07-26 17:55:25 +05:30
Utkarsh Yadav
53b877bd8f [ui test] Employee in HR (#10103)
* added test for employee

* names changed

* path added in tests.txt
2017-07-26 16:32:16 +05:30
Utkarsh Goswami
40937083bf [UI-Test Project] To check a billing cost of a project with multiple tasks (#10084)
* Updated test for Project Timesheet with multiple tasks

* Updated test for Project Timesheet with multiple tasks

* Updated test for Project Timesheet with multiple tasks

* updated:

* Updated

* Updated
2017-07-26 16:31:08 +05:30
Makarand Bauskar
d0109a6fc0 [minor] enable all roles and domain before running tests cases (#10108)
* [minor] enable all roles and domain before running tests cases

* Update utils.py
2017-07-26 16:29:22 +05:30
Utkarsh Yadav
b8a4a584e6 [ui test] test for department, designation, company and leave block list (#10085)
* added test for required items

* minor fixes for travis

* name changed

* added test for employment type

* travis fixes
2017-07-26 13:14:34 +05:30
Prateeksha Singh
cda6206c1f [minor][wiz] remove header brand image (#10016) 2017-07-26 13:05:48 +05:30
Saurabh
7bdc45eceb Merge branch 'master' into develop 2017-07-25 18:02:58 +05:30
Saurabh
dc6e369172 Merge branch 'master' into develop 2017-07-25 16:42:28 +05:30
Saurabh
fb4f320df4 Merge branch 'master' into develop 2017-07-25 16:15:50 +05:30
Ameya Shenoy
08450878f1 [ui-test] added test for bill_of_materials (#10063)
* temporary commit for switching branches

* [ui-tests] added bill_of_materials test

* fixed minor codacy problems

* added minor requested changes
2017-07-25 15:23:58 +05:30
Ashwini Save
2ffe878999 Timeline Title for small resolution Add to knowledge base button. (#9926)
* Add to Knowledge Base button class updated to hide for mobile view.

* Updated code to avoid multiple occurance of Knowledge Base button while updating comment.
2017-07-25 14:16:48 +05:30
rohitwaghchaure
49a6b4a4fa [Fix] RFQ list showing to all supplier in the portal (#10023) 2017-07-25 14:12:58 +05:30
bcornwellmott
05e51d6c83 Add Get Suppliers dialog (#10025)
* Add Get Suppliers dialog

* Commonize code, use depends_on

* Update request_for_quotation.js
2017-07-25 14:10:23 +05:30
rohitwaghchaure
4cccdbdbf9 [Fix] Validating price list currency even if price list is not defined (#10056) 2017-07-25 14:05:01 +05:30
KanchanChauhan
4b888b95d0 [Minor] Added filter condition to Customer Query (#10057) 2017-07-25 14:03:01 +05:30
Zarrar
b5ec8381a6 [UI Tests] School Academic Term test (#10050) 2017-07-25 11:46:34 +05:30
Zarrar
1c6828e5d6 [UI Tests] School Academic Year test (#10049) 2017-07-25 11:45:39 +05:30
KanchanChauhan
d65b4b4238 Patch was faling, reload doc was missing (#10072) 2017-07-25 11:39:46 +05:30
ci2014
13abada526 Update email-account.md (#10066)
* Update email-account.md

Add information to conditional import

* Add files via upload
2017-07-25 11:06:03 +05:30
tundebabzy
de54f3019f use api to get default cost center for chosen company (#10067) 2017-07-25 11:05:07 +05:30
bcornwellmott
d023d9a0bd Add RFQ email sent check (#10068)
* Add RFQ email sent check

* remove blankspace

* Removed debugger
2017-07-25 11:03:12 +05:30
Vishal Dhayagude
edb2749dfd Timesheet web (#10037)
* [new]Timesheet added

* [new] Customer wise timesheet on webportal added
2017-07-25 10:53:12 +05:30
Makarand Bauskar
fcaf313c0f [minor] make-demo fixes for manufacturing domain (#10029) 2017-07-25 10:49:35 +05:30
bcornwellmott
96381da547 Supplier Scorecard (#9294)
* Initial start of scorecard docs

* Got basic functionality working

* Fixed doc names and added key functions

* Basic functional version minus Actions

* Hide scorecard docs until functional

* Created supplier scorecard documentation

* Added default variables and standings. Added restrictions for PO + RFQ

* Automatic daily scorecard creation + on save

* Added warning for PO nd RFQs

* Minor fixes for codepy, automatically add variables for criteria, fix hooks.py typo

* Added tests, fixed codacy formatting, small improvements

* Fixed test bug w/ criteria. Codacy cleanup

* Fixed codacy issues. Fixed sticky criteria

* Fixed bug with period search. Remove blank variable child.

* Updated docs, automatically add criteria and standings, clean up period create message

* Uncommented test, set docs to beta

* Fix for nabinhait review

* Fix codacy issue. Fix dict assignment for records
2017-07-24 22:42:30 +05:30
Ameya Shenoy
91b2833708 [ui-tests] added workstation and operation (#10044)
* [ui-test] workstation and operation testing added

* [ui-tests] removed unnecessary assertions and used logical names for operations and workstations
2017-07-24 14:34:30 +05:30
Utkarsh Yadav
20a862a6b9 [ui test] holiday list and branch in HR (#10045)
* added test for holiday list

* codacy fixes

* added check for all days in list

* added test for branch

* codacy fixe

* minor fixes
2017-07-24 14:33:42 +05:30
tundebabzy
65656ec2df hide salution and gender if company type is Company (#10040) 2017-07-24 11:32:26 +05:30
Makarand Bauskar
9306aff1bb [minor] moved the patch to v8_5 and other minor fixes (#10012)
* Quotation and Supplier Quotation Route and Permission Edits

* [minor] moved the patch to v8_5 and other minor fixes
2017-07-21 15:19:47 +05:30
Ameya Shenoy
73f969fd7f [ui-test] manufacturing item creation testing (#10009) 2017-07-21 14:22:08 +05:30
1068 changed files with 24428 additions and 8523 deletions

View File

@@ -15,6 +15,8 @@ services:
- mysql
install:
- pip install flake8==3.3.0
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
- sudo rm /etc/apt/sources.list.d/docker.list
- sudo apt-get purge -y mysql-common mysql-server mysql-client
- nvm install v7.10.0
@@ -51,6 +53,9 @@ before_script:
script:
- set -e
- bench --verbose run-tests
- bench run-tests
- sleep 5
- bench --verbose run-ui-tests --app erpnext
- bench reinstall --yes
- bench execute erpnext.setup.setup_wizard.utils.complete
- bench execute erpnext.setup.utils.enable_all_roles_and_domains
- bench run-ui-tests --app erpnext

View File

@@ -6,10 +6,9 @@
Includes: Accounting, Inventory, Manufacturing, CRM, Sales, Purchase, Project Management, HRMS. Requires MariaDB.
ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a full-stack web app framework in Python & JavaScript.
ERPNext is built on the [Frappé](https://github.com/frappe/frappe) Framework, a full-stack web app framework in Python & JavaScript.
- [User Guide](https://frappe.github.io/erpnext/)
- [Getting Help](http://erpnext.org/getting-help.html)
- [User Guide](https://erpnext.org/docs/user)
- [Discussion Forum](https://discuss.erpnext.com/)
---
@@ -34,7 +33,7 @@ System and user credentials are listed on the download page.
GNU/General Public License (see LICENSE.txt)
The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappe Technologies Pvt Ltd (Frappe) and Contributors.
The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappé Technologies Pvt Ltd (Frappé) and Contributors.
---
@@ -49,19 +48,19 @@ The ERPNext code is licensed as GNU General Public License (v3) and the Document
## Logo and Trademark
The brand name ERPNext and the logo are trademarks of Frappe Technologies Pvt. Ltd.
The brand name ERPNext and the logo are trademarks of Frappé Technologies Pvt. Ltd.
### Introduction
Frappe Technologies Pvt. Ltd. (Frappe) owns and oversees the trademarks for the ERPNext name and logos. We have developed this trademark usage policy with the following goals in mind:
Frappé Technologies Pvt. Ltd. (Frappé) owns and oversees the trademarks for the ERPNext name and logos. We have developed this trademark usage policy with the following goals in mind:
- Wed like to make it easy for anyone to use the ERPNext name or logo for community-oriented efforts that help spread and improve ERPNext.
- Wed like to make it clear how ERPNext-related businesses and projects can (and cannot) use the ERPNext name and logo.
- Wed like to make it hard for anyone to use the ERPNext name and logo to unfairly profit from, trick or confuse people who are looking for official ERPNext resources.
### Frappe Trademark Usage Policy
### Frappé Trademark Usage Policy
Permission from Frappe is required to use the ERPNext name or logo as part of any project, product, service, domain or company name.
Permission from Frappé is required to use the ERPNext name or logo as part of any project, product, service, domain or company name.
We will grant permission to use the ERPNext name and logo for projects that meet the following criteria:
@@ -72,7 +71,7 @@ Your project neither promotes nor is associated with entities that currently fai
Use of the ERPNext name and logo is additionally allowed in the following situations:
All other ERPNext-related businesses or projects can use the ERPNext name and logo to refer to and explain their services, but they cannot use them as part of a product, project, service, domain, or company name and they cannot use them in any way that suggests an affiliation with or endorsement by ERPNext or Frappe Technologies or the ERPNext open source project. For example, a consulting company can describe its business as “123 Web Services, offering ERPNext consulting for small businesses,” but cannot call its business “The ERPNext Consulting Company.”
All other ERPNext-related businesses or projects can use the ERPNext name and logo to refer to and explain their services, but they cannot use them as part of a product, project, service, domain, or company name and they cannot use them in any way that suggests an affiliation with or endorsement by ERPNext or Frappé Technologies or the ERPNext open source project. For example, a consulting company can describe its business as “123 Web Services, offering ERPNext consulting for small businesses,” but cannot call its business “The ERPNext Consulting Company.”
Similarly, its OK to use the ERPNext logo as part of a page that describes your products or services, but it is not OK to use it as part of your company or product logo or branding itself. Under no circumstances is it permitted to use ERPNext as part of a top-level domain name.
@@ -80,6 +79,6 @@ We do not allow the use of the trademark in advertising, including AdSense/AdWor
Please note that it is not the goal of this policy to limit commercial activity around ERPNext. We encourage ERPNext-based businesses, and we would love to see hundreds of them.
When in doubt about your use of the ERPNext name or logo, please contact Frappe Technologies for clarification.
When in doubt about your use of the ERPNext name or logo, please contact Frappé Technologies for clarification.
(inspired by WordPress)

View File

@@ -1,6 +1,6 @@
## ERPNext includes these public works
For Frappe Framework, please see attributions.md at https://github.com/frappe/frappe/
For Frappé Framework, please see attributions.md at https://github.com/frappe/frappe/
#### Images

View File

@@ -4,7 +4,7 @@ import inspect
import frappe
from erpnext.hooks import regional_overrides
__version__ = '8.6.1'
__version__ = '8.10.1'
def get_default_company(user=None):
'''Get default company for user'''
@@ -28,6 +28,16 @@ def get_default_currency():
if company:
return frappe.db.get_value('Company', company, 'default_currency')
def get_default_cost_center(company):
'''Returns the default cost center of the company'''
if not company:
return None
if not frappe.flags.company_cost_center:
frappe.flags.company_cost_center = {}
if not company in frappe.flags.company_cost_center:
frappe.flags.company_cost_center[company] = frappe.db.get_value('Company', company, 'cost_center')
return frappe.flags.company_cost_center[company]
def get_company_currency(company):
'''Returns the default company currency'''

View File

@@ -68,7 +68,8 @@ frappe.ui.form.on('Account', {
}
});
});
} else if (cint(frm.doc.is_group) == 0) {
} else if (cint(frm.doc.is_group) == 0
&& frappe.boot.user.can_read.indexOf("GL Entry") !== -1) {
cur_frm.add_custom_button(__('Ledger'), function () {
frappe.route_options = {
"account": frm.doc.name,

View File

@@ -13,6 +13,7 @@
"editable_grid": 0,
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -42,6 +43,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -70,6 +72,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -100,6 +103,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -130,6 +134,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,
@@ -250,6 +258,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -278,6 +287,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -309,6 +319,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -341,6 +352,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -372,6 +384,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -404,6 +417,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -433,6 +447,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -461,6 +476,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -489,6 +505,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -528,7 +545,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-04-21 17:22:41.150984",
"modified": "2017-08-11 15:28:35.855809",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Account",
@@ -641,6 +658,6 @@
"search_fields": "",
"show_name_in_global_search": 1,
"sort_order": "ASC",
"track_changes": 0,
"track_changes": 1,
"track_seen": 0
}

View File

@@ -78,6 +78,7 @@ def get_chart(chart_template, existing_company=None):
for folder in folders:
path = os.path.join(os.path.dirname(__file__), folder)
for fname in os.listdir(path):
fname = frappe.as_unicode(fname)
if fname.endswith(".json"):
with open(os.path.join(path, fname), "r") as f:
chart = f.read()
@@ -105,6 +106,7 @@ def get_charts_for_country(country):
path = os.path.join(os.path.dirname(__file__), folder)
for fname in os.listdir(path):
fname = frappe.as_unicode(fname)
if (fname.startswith(country_code) or fname.startswith(country)) and fname.endswith(".json"):
with open(os.path.join(path, fname), "r") as f:
_get_chart_name(f.read())

View File

@@ -84,7 +84,7 @@ def get_csv_contents(files_path):
try:
csv_content.setdefault(file_type, [])\
.append(read_csv_content(csvfile.read()))
except Exception, e:
except Exception as e:
continue
return csv_content

View File

@@ -0,0 +1,419 @@
{
"country_code": "ar",
"name": "Argentina - Chart of Accounts",
"tree": {
"1.0.0.00.00 - ACTIVO": {
"1.1.0.00.00 - ACTIVO CORRIENTE": {
"1.1.1.00.00 - CAJA Y BANCOS": {
"1.1.1.01.00 - CAJAS": {
"1.1.1.01.01 - Caja": {},
"1.1.1.01.02 - Caja chica": {},
"1.1.1.01.03 - Caja en Moneda Extranjera": {},
"1.1.1.01.04 - Valores a depositar": {},
"1.1.1.01.05 - Tarjetas - Cupones": {},
"account_type": "Cash"
},
"1.1.1.02.00 - BANCOS": {
"1.1.1.02.01 - Banco de la Nacio\u0301n Argentina(ejemplo) c/c en": {},
"1.1.1.02.03 - Banco del exterior": {},
"account_type": "Bank"
}
},
"1.1.2.00.00 - INVERSIONES TEMPORARIAS": {
"1.1.2.01.00 - INVERSIONES EN ACCIONES": {
"1.1.2.01.01 - Acciones": {
"account_type": "Receivable"
}
},
"1.1.2.02.00 - DEPO\u0301SITOS A PLAZO FIJO": {
"1.1.2.02.01 - Depo\u0301sitos a Plazo Fijo en pesos": {
"account_type": "Receivable"
},
"1.1.2.02.02 - Depo\u0301sitos a Plazo Fijo en moneda": {
"account_type": "Receivable"
}
}
},
"1.1.3.00.00 - CRE\u0301DITOS POR VENTAS DE SERVICIOS": {
"1.1.3.01.00 - DEUDORES EN CTA. CTE": {
"1.1.3.01.01 - Deudores locales": {
"account_type": "Receivable"
},
"1.1.3.01.02 - Deudores del exterior": {
"account_type": "Receivable"
},
"1.1.3.01.03 - Deudores Morosos": {
"account_type": "Chargeable"
},
"1.1.3.01.04 - Deudores en Gestio\u0301n Judicial": {}
},
"1.1.3.02.00 - Documentos a cobrar por Vas. de Servicios": {
"account_type": "Receivable"
},
"1.1.3.03.00 - Previsio\u0301n para deudores incobrables": {}
},
"1.1.4.00.00 - OTROS CRE\u0301DITOS CORRIENTES": {
"1.1.4.01.00 - CRE\u0301DITOS IMPOSITIVOS CORRIENTES": {
"1.1.4.01.01 - Anticipos Impuesto a las Ganancias": {},
"1.1.4.01.02 - Anticipos Impuesto a los Ingresos Brutos": {},
"1.1.4.01.03 - Percepciones y Retenciones Impto. a las Ganancias": {},
"1.1.4.01.04 - Percepciones y Retenciones Impto. a los": {},
"1.1.4.01.05 - IVA Cre\u0301dito Fiscal": {},
"1.1.4.01.06 - IVA Cre\u0301dito Fiscal Exportacio\u0301n": {},
"1.1.4.01.07 - IVA Saldo a Favor Te\u0301cnico": {},
"1.1.4.01.08 - IVA Saldo a Favor Te\u0301cnico": {},
"1.1.4.01.09 - IVA Saldo a Favor de Libre": {},
"1.1.4.01.10 - Percepciones y Retenciones de IVA": {},
"1.1.4.01.11 - Cre\u0301ditos por quebrantos impositivos no": {},
"1.1.4.01.12 - Activos por Impuesto Diferido (Ctes.)": {}
},
"1.1.4.02.00 - CRE\u0301DITOS DIVERSOS CORRIENTES": {
"1.1.4.02.01 - Cuentas Particulares Directores": {},
"1.1.4.02.02 - Cuentas Particulares Socios/Accionistas": {},
"1.1.4.02.03 - Anticipos a Proveedores (No cong.": {
"account_type": "Receivable"
},
"1.1.4.02.04 - Anticipos de Sueldos": {},
"1.1.4.02.05 - Pre\u0301stamos al personal": {},
"1.1.4.02.06 - Depo\u0301sitos pendientes de acreditacio\u0301n": {},
"1.1.4.02.07 - Arrendamiento pagado por adelantado": {}
}
},
"1.1.5.00.00 - OTROS ACTIVOS CORRIENTES": {
"is_group": 1
},
"1.1.6.00.00 - INVENTARIOS": {
"account_type": "Stock",
"is_group": 1
}
},
"1.2.0.00.00 - ACTIVO NO CORRIENTE": {
"1.2.1.00.00 - INVERSIONES PERMANENTES": {
"1.2.1.01.00 - BONOS DE DEUDA": {
"1.2.1.01.01 - Ti\u0301tulos Deuda Pu\u0301blica (Pesos)": {
"is_group": 1
},
"1.2.1.01.02 - Bonex": {}
},
"1.2.1.02.00 - DEPO\u0301SITOS A PLAZO FIJO NO": {
"1.2.1.02.01 - Depo\u0301sitos a plazo fijo en pesos (no cte.)": {},
"1.2.1.02.02 - Depo\u0301sitos a plazo fijo en moneda": {}
},
"1.2.1.03.00 - INVERSIONES EN BIENES DEPRECIABLES": {
"1.2.1.03.01 - Inversiones en Inmuebles Valores": {},
"1.2.1.03.02 - Inversiones en Inmuebles": {},
"1.2.1.03.03 - Amortizaciones Acumuladas Inversiones": {}
}
},
"1.2.2.00.00 - BIENES DE USO": {
"1.2.2.01.00 - INMUEBLES": {
"1.2.2.01.01 - Inmuebles Valores originales": {
"account_type": "Fixed Asset"
},
"1.2.2.01.02 - Inmuebles Actualizaciones": {},
"1.2.2.01.03 - Amortizaciones Acumuladas Inmuebles": {
"account_type": "Depreciation"
}
},
"1.2.2.02.00 - MAQUINARIAS Y EQUIPOS": {
"1.2.2.02.01 - Maquinarias y Equipos Valores de origen": {
"account_type": "Fixed Asset"
},
"1.2.2.02.02 - Maquinarias y Equipos Actualizaciones": {},
"1.2.2.02.03 - Amortizaciones Acumuladas Maquinarias": {
"account_type": "Depreciation"
}
},
"1.2.2.03.00 - MUEBLES Y U\u0301TILES": {
"1.2.2.03.01 - Muebles y U\u0301tiles Valores de Origen": {
"account_type": "Fixed Asset"
},
"1.2.2.03.02 - Muebles y U\u0301tiles Actualizaciones": {},
"1.2.2.03.03 - Amortizaciones Acumuladas Muebles y": {
"account_type": "Depreciation"
}
},
"1.2.2.04.00 - RODADOS": {
"1.2.2.04.01 - Rodados Valores Originales": {
"account_type": "Fixed Asset"
},
"1.2.2.04.02 - Rodados Actualizaciones": {},
"1.2.2.04.03 - Amortizaciones Acumuladas Rodados": {
"account_type": "Depreciation"
}
},
"1.2.2.07.00 - TERRENOS": {
"1.2.2.07.01 - Terrenos Valores Originales": {
"account_type": "Fixed Asset"
},
"1.2.2.07.02 - Terrenos Actualizaciones": {}
},
"1.2.2.08.00 - INSTALACIONES": {
"1.2.2.08.01 - Instalaciones Valores Originales": {
"account_type": "Fixed Asset"
},
"1.2.2.08.02 - Instalaciones Ajuste": {},
"1.2.2.08.03 - Amortizaciones Acumuladas": {
"account_type": "Depreciation"
}
},
"1.2.2.09.00 - HERRAMIENTAS": {
"1.2.2.09.01 - Herramientas Valores Originales": {
"account_type": "Fixed Asset"
},
"1.2.2.09.02 - Herramientas Ajuste": {},
"1.2.2.09.03 - Amortizaciones Acumuladas": {
"account_type": "Depreciation"
}
}
},
"1.2.3.00.00 - ACTIVOS INTANGIBLES": {
"1.2.3.01.00 - MARCAS Y PATENTES": {
"1.2.3.01.01 - Marcas y Patentes Valores Originales": {},
"1.2.3.01.02 - Marcas y Patentes Actualizaciones": {},
"1.2.3.01.03 - Amortizaciones Acumuladas Marcas y": {}
}
},
"1.2.4.00.00 - CRE\u0301DITOS POR VENTA DE SERVICIOS": {
"1.2.4.01.00 - DEUDORES NO CORRIENTES": {
"1.2.4.01.01 - Deudores Locales (No Ctes.)": {}
},
"1.2.4.02.00 - Documentos a cobrar por Vtas. de Servicios": {}
},
"1.2.5.00.00 - OTROS CRE\u0301DITOS NO CORRIENTES": {
"1.2.5.01.00 - CRE\u0301DITOS IMPOSITIVOS NO CORRIENTES": {
"1.2.5.01.01 - Activos por Impto. Diferido (No Ctes.)": {},
"1.2.5.01.02 - Cre\u0301ditos por Quebrantos Impositivos no": {}
},
"1.2.5.02.00 - CRE\u0301DITOS DIVERSOS NO CORRIENTES": {
"1.2.5.02.01 - Cuentas Particulares Directores (No": {},
"1.2.5.02.02 - Cuentas Particulares Socios/Accionistas": {}
}
},
"1.2.6.00.00 - OTROS ACTIVOS NO CORRIENTES": {
"1.2.6.01.00 - Llave de Negocio": {}
}
},
"root_type": "Asset"
},
"2.0.0.00.00 - PASIVO": {
"2.1.0.00.00 - PASIVO CORRIENTE": {
"2.1.1.00.00 - DEUDAS COMERCIALES CORRIENTES": {
"2.1.1.02.00 - ACREEDORES": {
"2.1.1.02.01 - Acreedores Locales (Ctes.)": {
"account_type": "Payable"
}
}
},
"2.1.2.00.00 - REMUNERACIONES Y CAGAS SOCIALES": {
"2.1.2.02.00 - DEUDAS PREVISIONALES": {
"2.1.2.02.01 - Jubilaciones a pagar": {},
"2.1.2.02.02 - ART a pagar": {},
"2.1.2.02.03 - Obra Social a pagar": {},
"2.1.2.02.04 - SAC a pagar": {},
"2.1.2.02.05 - Vacaciones a pagar": {}
},
"2.1.2.03.00 - Sueldos y Jornales a pagar": {
"account_type": "Chargeable"
}
},
"2.1.3.00.00 - CARGAS FISCALES": {
"2.1.3.01.00 - IMPUESTO AL VALOR AGREGADO": {
"2.1.3.01.01 - IVA De\u0301bito Fiscal": {},
"2.1.3.01.02 - IVA De\u0301bito Fiscal Sobretasa": {},
"2.1.3.01.03 - Percepciones y Retenciones efectuadas": {},
"2.1.3.01.04 - IVA a Pagar": {}
},
"2.1.3.02.00 - INGRESOS BRUTOS": {
"2.1.3.02.01 - Impuesto a los Ingresos Brutos a Pagar": {},
"2.1.3.02.02 - Percepciones efectuadas Ingresos": {}
},
"2.1.3.03.00 - IMPUESTO A LAS GANANCIAS": {
"2.1.3.03.01 - Impuesto Ganancia Mi\u0301nima Presunta a": {},
"2.1.3.03.02 - Impuesto a las Ganancias a Pagar": {},
"2.1.3.03.03 - Pasivo por Impuesto Diferido": {},
"2.1.3.03.04 - Percepciones y Retenciones efectuadas": {}
}
},
"2.1.4.00.00 - DEUDAS FINANCIERAS": {
"2.1.4.01.00 - Pre\u0301stamo Banco de la Nacio\u0301n Argentina (Cte.)": {},
"2.1.4.02.00 - Pre\u0301stamo Banco de la Provincia de Bs. As.": {}
},
"2.1.5.00.00 - OTRAS DEUDAS CORRIENTES": {
"2.1.5.01.00 - Dividendos a pagar (Ctes.)": {},
"2.1.5.02.00 - Honorarios Directores a Pagar (Ctes.)": {}
},
"2.1.6.00.00 - PROVISIONES": {
"2.1.6.01.00 - Provisio\u0301n para despidos": {},
"2.1.6.02.00 - Provisio\u0301n para SAC": {}
},
"2.1.7.00.00 - INVENTARIOS POR PAGAR": {
"2.1.7.01.00 - Inventario entrante no facturado": {
"account_type": "Stock Received But Not Billed"
}
}
},
"2.2.0.00.00 - PASIVO NO CORRIENTE": {
"2.2.1.00.00 - DEUDAS FINANCIERAS NO CORRIENTES": {
"2.2.1.01.00 - Pre\u0301stamo Banco de la Nacio\u0301n Argentina(ejemplo) (No": {}
},
"2.2.2.00.00 - CARGAS FISCALES NO CORRIENTES": {
"2.2.2.01.00 - Moratoria": {}
},
"2.2.3.00.00 - DEUDAS COMERCIALES": {
"2.2.3.01.00 - ACREEDORES": {
"2.2.3.01.01 - Acreedores Locales (No Ctes.)": {}
}
},
"2.2.4.00.00 - OTRAS DEUDAS NO CORRIENTES": {
"is_group": 1
}
},
"root_type": "Liability"
},
"3.0.0.00.00 - PATRIMONIO NETO": {
"3.1.0.00.00 - APORTE DE LOS PROPIETARIOS": {
"3.1.1.00.00 - CAPITAL SOCIAL": {
"3.1.1.01.00 - Acciones en Circulacio\u0301n": {},
"3.1.1.02.00 - Aportes Irrevocables": {},
"3.1.1.03.00 - Acciones a distribuir": {},
"3.1.1.04.00 - Capital": {},
"3.1.1.05.00 - Ajuste del Capital": {}
}
},
"3.3.0.00.00 - RESERVAS": {
"3.3.1.00.00 - Reserva Legal": {},
"3.3.2.00.00 - Reserva Facultativa": {},
"3.3.3.00.00 - Reserva Estatutaria": {},
"3.3.4.00.00 - Ajuste Reserva Legal": {}
},
"3.4.0.00.00 - RESULTADOS ACUMULADOS": {
"3.4.1.00.00 - Resultado del Ejercicio": {},
"3.4.2.00.00 - Resultado Ejercicios Anteriores": {},
"3.4.3.00.00 - A.R.E.A (P)": {},
"3.4.4.00.00 - A.R.E.A (G)": {}
},
"root_type": "Equity"
},
"4.1.0.00.00 - INGRESOS": {
"4.1.0.00.00 - INGRESOS ORDINARIOS": {
"4.1.1.00.00 - INGRESOS POR SERVICIOS PRESTADOS": {
"4.1.1.01.00 - Ventas de Servicios": {},
"4.1.1.02.00 - Ingresos de fuente extranjera": {}
},
"4.1.3.00.00 - RESULTADOS FINANCIEROS Y POR": {
"4.1.3.01.00 - Intereses Ganados": {},
"4.1.3.02.00 - Resultado por Tenencia de acciones": {},
"4.1.3.03.00 - Diferencia tipo de cambio": {},
"4.1.3.04.00 - Resultado por tenencia (positivo)": {}
},
"4.1.4.00.00 - OTROS INGRESOS ORDINARIOS": {
"is_group": 1
}
},
"4.2.0.00.00 - INGRESOS EXTRAORDINARIOS": {
"4.2.1.00.00 - Utilidad Venta Bienes de Uso": {},
"4.2.2.00.00 - Reintegro de Seguros": {},
"4.2.3.00.00 - Otros ingresos extraordinarios": {}
},
"root_type": "Income"
},
"5.0.0.00.00 - EGRESOS": {
"5.1.0.00.00 - EGRESOS ORDINARIOS": {
"5.1.2.00.00 - GASTOS DE EXPLOTACIO\u0301N": {
"5.1.2.01.00 - Sueldos y Jornales - Explotacio\u0301n": {},
"5.1.2.02.00 - Cargas Sociales - Explotacio\u0301n": {},
"5.1.2.03.00 - Energi\u0301a - Explotacio\u0301n": {},
"5.1.2.04.00 - Honorarios Profesionales - Explotacio\u0301n": {},
"5.1.2.05.00 - Ropa de trabajo - Explotacio\u0301n": {},
"5.1.2.06.00 - Seguros - Explotacio\u0301n": {},
"5.1.2.07.00 - Despidos - Explotacio\u0301n": {},
"5.1.2.08.00 - Comida del personal - Explotacio\u0301n": {},
"5.1.2.09.00 - Cuota me\u0301dica a cargo del empleador": {},
"5.1.2.10.00 - Amortizaciones - Explotacio\u0301n": {},
"5.1.2.11.00 - Repuestos y Reparaciones - Explotacio\u0301n": {},
"5.1.2.12.00 - Gastos de limpieza - Explotacio\u0301n": {},
"5.1.2.13.00 - Mantenimiento - Explotacio\u0301n": {},
"5.1.2.14.00 - Combustibles y Lubricantes - Explotacio\u0301n": {},
"5.1.2.15.00 - Insumos diversos - Explotacio\u0301n": {},
"5.1.2.16.00 - Fletes - Explotacio\u0301n": {}
},
"5.1.3.00.00 - GASTOS DE ADMINISTRACIO\u0301N": {
"5.1.3.01.00 - Sueldos - Administracio\u0301n": {},
"5.1.3.02.00 - Cargas Sociales - Administracio\u0301n": {},
"5.1.3.03.00 - Honorarios - Administracio\u0301n": {},
"5.1.3.04.00 - Amortizaciones - Administracio\u0301n": {},
"5.1.3.05.00 - Via\u0301ticos - Administracio\u0301n": {},
"5.1.3.06.00 - Libreri\u0301a y Papeleri\u0301a - Administracio\u0301n": {},
"5.1.3.07.00 - Certificaciones y Sellados": {},
"5.1.3.08.00 - Gastos Bancarios - Administracio\u0301n": {},
"5.1.3.09.00 - Gastos Varios - Administracio\u0301n": {},
"5.1.3.10.00 - Insumos Computacio\u0301n - Administracio\u0301n": {},
"5.1.3.11.00 - Correspondencia - Administracio\u0301n": {},
"5.1.3.12.00 - Mantenimiento - Administracio\u0301n": {},
"5.1.3.13.00 - Energi\u0301a - Administracio\u0301n": {},
"5.1.3.14.00 - Seguros - Administracio\u0301n": {},
"5.1.3.15.00 - Costo sobre ventas": {
"account_type": "Cost of Goods Sold"
},
"5.1.3.16.00 - Gastos de Valoracion": {
"account_type": "Expenses Included In Valuation"
}
},
"5.1.4.00.00 - GASTOS DE COMERCIALIZACIO\u0301N": {
"5.1.4.01.00 - Sueldos - Comercializacio\u0301n": {},
"5.1.4.02.00 - Cargas Sociales - Comercializacio\u0301n": {},
"5.1.4.03.00 - Publicidad - Comercializacio\u0301n": {},
"5.1.4.04.00 - Amortizaciones - Comercializacio\u0301n": {},
"5.1.4.05.00 - Seguros - Comercializacio\u0301n": {},
"5.1.4.06.00 - Honorarios - Comercializacio\u0301n": {},
"5.1.4.07.00 - Gastos Varios - Comercializacio\u0301n": {},
"5.1.4.08.00 - Fletes - Comercializacio\u0301n": {},
"5.1.4.09.00 - IVA no computable - Comercializacio\u0301n": {},
"5.1.4.10.00 - Descuentos otorgados a clientes": {},
"5.1.4.11.00 - Comisiones de terceros": {},
"5.1.4.12.00 - Quebrantos por deudores": {},
"5.1.4.13.00 - Via\u0301ticos - Comercializacio\u0301n": {}
},
"5.1.5.00.00 - GASTOS FINANCIEROS": {
"5.1.5.01.00 - Intereses y Gastos bancarios": {},
"5.1.5.02.00 - Intereses a Proveedores": {},
"5.1.5.03.00 - Intereses y recargos impositivos": {},
"5.1.5.04.00 - Diferencia de Cambio": {},
"5.1.5.05.00 - Diferencia de Cambio Balance en": {},
"5.1.5.06.00 - Resultado por tenencia (negativo)": {},
"5.1.5.08.00 - Amortizaciones Inversiones en bienes": {},
"5.1.5.09.00 - R.E.C.P.A.M": {},
"5.1.5.10.00 - Resultado por tenencia negativo de": {}
},
"5.1.7.00.00 - IMPUESTOS": {
"5.1.7.01.00 - Impuesto a las Ganancias": {},
"5.1.7.02.00 - Impuesto a las Ganancia Mi\u0301nima": {},
"5.1.7.03.00 - Impuesto a los Ingresos Brutos": {},
"5.1.7.04.00 - Tasa municipal": {},
"5.1.7.05.00 - Impuestos Territoriales": {},
"5.1.7.06.00 - Impuesto s/ los De\u0301bitos y Cre\u0301ditos": {},
"5.1.7.07.00 - Impuestos internos y varios": {}
},
"5.1.8.00.00 - GASTOS SOBRE EXISTENCIAS": {
"5.1.8.01.00 - Costo sobre ventas": {
"account_type": "Cost of Goods Sold"
},
"5.1.8.02.00 - Gastos de Valoracion": {
"account_type": "Expenses Included In Valuation"
},
"5.1.8.03.00 - Ajuste de Existencia": {
"account_type": "Stock Adjustment"
}
}
},
"5.2.0.00.00 - EGRESOS EXTRAORDINARIOS": {
"5.2.1.00.00 - Pe\u0301rdida por venta bienes de uso": {},
"5.2.2.00.00 - Amortizaciones extraordinarias": {},
"5.2.3.00.00 - Ajuste del valor de los bienes": {},
"5.2.4.00.00 - Ajuste de Amortizaciones acumuladas de": {}
},
"root_type": "Expense"
}
}
}

View File

@@ -49,6 +49,10 @@
"is_group": 1
},
"ESTOQUES": {
"All Warehouses": {
"account_type": "Stock",
"is_group": 1
},
"Constru\u00e7\u00f5es em Andamento de Im\u00f3veis Destinados \u00e0 Venda": {},
"Estoques Destinados \u00e0 Doa\u00e7\u00e3o": {},
"Im\u00f3veis Destinados \u00e0 Venda": {},

View File

@@ -1,100 +0,0 @@
{
"country_code": "fr",
"name": "France - Chart of Accounts",
"tree": {
"Frais": {
"601 achats stock\u00e9s, mat premi\u00e8res": {
"account_type": "Cost of Goods Sold"
},
"6031 variation des stock\u00e9s mat premi\u00e8res": {
"account_type": "Stock Adjustment"
},
"6081 frais accessoires d'achats mat premi\u00e8res": {
"account_type": "Expenses Included In Valuation"
},
"Dotations aux amortissements, d\u00e9pr\u00e9ciations": {
"account_type": "Depreciation"
},
"root_type": "Expense"
},
"le revenu": {
"701 ventes de produits finis": {},
"root_type": "Income"
},
"les atouts": {
"Amortissements des immobilisations corporelles ": {
"Autres immobilisations corporelles (m\u00eame ventilation que celle du compte 218)": {
"account_type": "Accumulated Depreciation"
},
"Constructions (m\u00eame ventilation que celle du compte 213) ": {
"account_type": "Accumulated Depreciation"
},
"Installations mat\u00e9riel et outillage industriels (m\u00eame ventilation que celle du compte 215)": {
"account_type": "Accumulated Depreciation"
},
"account_type": "Accumulated Depreciation"
},
"Banques": {
"51201 Soci\u00e9t\u00e9 g\u00e9n\u00e9rale": {
"account_type": "Bank"
},
"account_type": "Bank"
},
"Caisse": {
"5301 Caisse si\u00e8ge social": {
"account_type": "Cash"
},
"account_type": "Cash"
},
"Clients et comptes rattach\u00e9s": {
"41119 Autres Clients": {
"account_type": "Receivable"
},
"account_type": "Receivable"
},
"Immobilisations corporelles en cours": {
"Autres immobilisations corporelles": {
"account_type": "Fixed Asset"
},
"Constructions": {
"account_type": "Fixed Asset"
},
"Installations techniques mat\u00e9riel et outillage industriels ": {
"account_type": "Fixed Asset"
},
"account_type": "Fixed Asset"
},
"Stock": {
"Stock in Hand": {
"account_type": "Stock"
}
},
"root_type": "Asset"
},
"passifs": {
"Fournisseurs - Factures non parvenues ": {
"4081 Fournisseurs - Factures non parvenues ": {
"account_type": "Stock Received But Not Billed"
},
"account_type": "Stock Received But Not Billed"
},
"Fournisseurs et comptes rattach\u00e9s": {
"4011 Fournisseurs - Achats de biens et prestations de services": {
"account_type": "Payable"
},
"account_type": "Payable"
},
"root_type": "Liability",
"\u00c9tat - Taxes sur le chiffre d'affaires": {
"TVA collect\u00e9e (Taux Normal)": {
"account_type": "Tax"
},
"account_type": "Tax"
}
},
"\u00c9quit\u00e9": {
"is_group": 1,
"root_type": "Equity"
}
}
}

View File

@@ -0,0 +1,856 @@
{
"country_code": "hu",
"name": "Hungary - Chart of Accounts",
"tree": {
"1. SZ\u00c1MLAOSZT\u00c1LY BEFEKTETETT ESZK\u00d6Z\u00d6K": {
"11. IMMATERI\u00c1LIS JAVAK": {
"111. Alap\u00edt\u00e1s-\u00e1tszervez\u00e9s aktiv\u00e1lt \u00e9rt\u00e9ke": {},
"112. K\u00eds\u00e9rleti fejleszt\u00e9s aktiv\u00e1lt \u00e9rt\u00e9ke": {},
"113. Vagyoni \u00e9rt\u00e9k\u0171 jogok": {},
"114. Szellemi term\u00e9kek": {},
"115. \u00dczleti vagy c\u00e9g\u00e9rt\u00e9k": {},
"117. Immateri\u00e1lis javak \u00e9rt\u00e9khelyesb\u00edt\u00e9se": {}
},
"12-16. T\u00c1RGYI ESZK\u00d6Z\u00d6K": {
"12. INGATLANOK \u00c9S KAPCSOL\u00d3D\u00d3 VAGYONI \u00c9RT\u00c9K\u00db JOGOK": {
"121. Telkek, f\u00f6ldter\u00fclet ": {
"1211. Telkek, f\u00f6ldter\u00fcletek brutt\u00f3 \u00e9rt\u00e9ke": {
"account_type": "Fixed Asset"
},
"1218. Telkek, f\u00f6ldter\u00fcletek terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
"1219. Telkek, f\u00f6ldter\u00fcletek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
},
"122. Ingatlanokhoz kapcsol\u00f3d\u00f3 vagyoni \u00e9rt\u00e9k\u0171 jogok": {
"1221. Ingatlanokhoz kapcsol\u00f3d\u00f3 vagyoni \u00e9rt\u00e9k\u0171 jogok brutt\u00f3 \u00e9rt\u00e9ke": {
"account_type": "Fixed Asset"
},
"1228. Ingatlanokhoz kapcsol\u00f3d\u00f3 vagyoni \u00e9rt\u00e9k\u0171 jogok terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
"1229. Ingatlanokhoz kapcsol\u00f3d\u00f3 vagyoni \u00e9rt\u00e9k\u0171 jogok terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
},
"123. \u00c9p\u00fcletek, \u00e9p\u00fcletr\u00e9szek, tulajdoni h\u00e1nyadok ": {
"account_type": "Fixed Asset",
"is_group": 1
},
"124. Egy\u00e9b ingatlanok": {
"is_group": 1
},
"125. \u00dczemk\u00f6r\u00f6n k\u00edv\u00fcli ingatlanok, \u00e9p\u00fcletek ": {
"is_group": 1
},
"126. Ingatlanokhoz kapcsol\u00f3d\u00f3 vagyoni \u00e9rt\u00e9k\u0171 jogok": {
"is_group": 1
},
"127. Ingatlanok \u00e9rt\u00e9khelyesb\u00edt\u00e9se": {},
"129. Kis \u00e9rt\u00e9k\u0171 ingatlanok": {}
},
"13. M\u00dbSZAKI BERENDEZ\u00c9SEK, G\u00c9PEK, J\u00c1RM\u00dbVEK": {
"131. Termel\u0151 g\u00e9pek, berendez\u00e9sek, szersz\u00e1mok, gy\u00e1rt\u00f3eszk\u00f6z\u00f6k": {
"1311. Termel\u0151 g\u00e9pek, berendez\u00e9sek brutt\u00f3 \u00e9rt\u00e9ke": {
"account_type": "Fixed Asset"
},
"1318. Termel\u0151 g\u00e9pek, berendez\u00e9sek terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
"1319. Termel\u0151 g\u00e9pek, berendez\u00e9sek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
},
"132. M\u0171szaki j\u00e1rm\u0171vek": {},
"133. Ki nem emelt m\u0171szaki berendez\u00e9sek, g\u00e9pek, j\u00e1rm\u0171vek": {},
"139. Kis \u00e9rt\u00e9k\u0171 m\u0171szaki berendez\u00e9sek, g\u00e9pek, j\u00e1rm\u0171vek": {}
},
"14. EGY\u00c9B BERENDEZ\u00c9SEK, FELSZEREL\u00c9SEK, J\u00c1RM\u00dbVEK": {
"141. Egy\u00e9b (\u00fczemi \u2013 \u00fczleti), berendez\u00e9sek, felszerel\u00e9sek": {
"1411. Egy\u00e9b (\u00fczemi \u2013 \u00fczleti), berendez\u00e9sek, felszerel\u00e9sek brutt\u00f3 \u00e9rt\u00e9ke": {
"account_type": "Fixed Asset"
},
"1418. Egy\u00e9b (\u00fczemi \u2013 \u00fczleti), berendez\u00e9sek, felszerel\u00e9sek terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
"1419. Egy\u00e9b (\u00fczemi \u2013 \u00fczleti), berendez\u00e9sek, felszerel\u00e9sek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
},
"142. Egy\u00e9b j\u00e1rm\u0171vek": {
"1421. Egy\u00e9b j\u00e1rm\u0171vek brutt\u00f3 \u00e9rt\u00e9ke": {
"account_type": "Fixed Asset"
},
"1428. Egy\u00e9b j\u00e1rm\u0171vek terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
"1429. Egy\u00e9b j\u00e1rm\u0171vek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
},
"143. Irodai, igazgat\u00e1si berendez\u00e9sek \u00e9s felszerel\u00e9sek": {
"1431. Irodai, igazgat\u00e1si berendez\u00e9sek \u00e9s felszerel\u00e9sek brutt\u00f3 \u00e9rt\u00e9ke": {
"account_type": "Fixed Asset"
},
"1438. Irodai, igazgat\u00e1si berendez\u00e9sek \u00e9s felszerel\u00e9sek terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
"1439. Irodai, igazgat\u00e1si berendez\u00e9sek \u00e9s felszerel\u00e9sek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
},
"144. Ki nem emelt egy\u00e9b berendez\u00e9sek, felszerel\u00e9sek": {
"account_type": "Fixed Asset"
},
"145. J\u00f3l\u00e9ti berendez\u00e9sek, felszerel\u00e9si t\u00e1rgyak \u00e9s k\u00e9pz\u0151m\u0171v\u00e9szeti alkot\u00e1sok": {
"account_type": "Fixed Asset"
},
"147. Egy\u00e9b berendez\u00e9sek, felszerel\u00e9sek, j\u00e1rm\u0171vek \u00e9rt\u00e9khelyesb\u00edt\u00e9se": {
"account_type": "Fixed Asset"
},
"149. Kis \u00e9rt\u00e9k\u0171 egy\u00e9b berendez\u00e9sek, felszerel\u00e9sek, j\u00e1rm\u0171vek": {
"account_type": "Fixed Asset"
}
},
"15. TENY\u00c9SZ\u00c1LLATOK": {
"151. Teny\u00e9sz\u00e1llatok": {}
},
"16. BERUH\u00c1Z\u00c1SOK, FEL\u00daJ\u00cdT\u00c1SOK": {
"161. Befejezetlen beruh\u00e1z\u00e1sok ": {},
"162. Fel\u00faj\u00edt\u00e1sok": {},
"168. Beruh\u00e1z\u00e1sok terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
},
"17-19. BEFEKTETETT P\u00c9NZ\u00dcGYI ESZK\u00d6Z\u00d6K": {
"17. TULAJDONI R\u00c9SZESED\u00c9ST JELENT\u00d5 BEFEKTET\u00c9SEK (R\u00c9SZESED\u00c9SEK)": {
"171. Tart\u00f3s r\u00e9szesed\u00e9s kapcsolt v\u00e1llalkoz\u00e1sban": {},
"172. Egy\u00e9b tart\u00f3s r\u00e9szesed\u00e9s": {},
"177. R\u00e9szesed\u00e9sek \u00e9rt\u00e9khelyesb\u00edt\u00e9se": {},
"179. R\u00e9szesed\u00e9sek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
},
"18. HITELVISZONYT MEGTESTES\u00cdT\u00d5 \u00c9RT\u00c9KPAP\u00cdROK": {
"181. \u00c1llamk\u00f6tv\u00e9nyek": {},
"182. Kapcsolt v\u00e1llalkoz\u00e1sok \u00e9rt\u00e9kpap\u00edrjai": {},
"183. Egy\u00e9b v\u00e1llalkoz\u00e1sok \u00e9rt\u00e9kpap\u00edrjai": {},
"184. Tart\u00f3s diszkont \u00e9rt\u00e9kpap\u00edrok": {},
"189. \u00c9rt\u00e9kpap\u00edrok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
},
"19. TART\u00d3SAN ADOTT K\u00d6LCS\u00d6N\u00d6K (tart\u00f3s bankbet\u00e9tek)": {
"191. Tart\u00f3san adott k\u00f6lcs\u00f6n\u00f6k kapcsolt v\u00e1llalkoz\u00e1sban": {},
"192. Tart\u00f3s bankbet\u00e9tek": {},
"193. Egy\u00e9b tart\u00f3san adott k\u00f6lcs\u00f6n\u00f6k": {},
"194. Tart\u00f3s bankbet\u00e9tek kapcsolt v\u00e1llalkoz\u00e1sban": {},
"195. Tart\u00f3s bankbet\u00e9tek egy\u00e9b r\u00e9szesed\u00e9si viszonyban \u00e1ll\u00f3 v\u00e1llalkoz\u00e1sban": {},
"196. Egy\u00e9b tart\u00f3s bankbet\u00e9tek": {},
"197. P\u00e9nz\u00fcgyi l\u00edzing miatti tart\u00f3s k\u00f6vetel\u00e9s": {},
"199. Tart\u00f3san adott k\u00f6lcs\u00f6n\u00f6k (\u00e9s bankbet\u00e9tek) \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
}
}
},
"root_type": "Asset"
},
"2. SZ\u00c1MLAOSZT\u00c1LY K\u00c9SZLETEK": {
"21-22. ANYAGOK": {
"211 - 219. Nyers- \u00e9s alapanyagok ": {},
"221. Seg\u00e9danyagok": {},
"222. \u00dczem- \u00e9s f\u0171t\u0151anyagok ": {},
"223. Fenntart\u00e1si anyagok ": {},
"224. \u00c9p\u00edt\u00e9si anyagok": {},
"225. Egy \u00e9ven bel\u00fcl elhaszn\u00e1l\u00f3d\u00f3 anyagi eszk\u00f6z\u00f6k ": {},
"226. T\u00e1rgyi eszk\u00f6z\u00f6k k\u00f6z\u00fcl \u00e1tsorolt anyagok": {},
"227. Egy\u00e9b anyagok": {},
"228. Anyagok \u00e1rk\u00fcl\u00f6nb\u00f6zete": {},
"229. Anyagok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
},
"23. BEFEJEZETLEN TERMEL\u00c9S \u00c9S F\u00c9LK\u00c9SZ TERM\u00c9KEK": {
"231 - 234. Befejezetlen termel\u00e9s ": {
"231. Befejezetlen termel\u00e9s": {},
"232. F\u00e9lk\u00e9sz term\u00e9kek": {}
},
"238. F\u00e9lk\u00e9sz term\u00e9kek k\u00e9szlet\u00e9rt\u00e9k-k\u00fcl\u00f6nb\u00f6zete": {},
"239. Befejezetlen termel\u00e9s \u00e9s f\u00e9lk\u00e9sz term\u00e9kek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
},
"24. N\u00d6VEND\u00c9K-, H\u00cdZ\u00d3- \u00c9S EGY\u00c9B \u00c1LLATOK": {
"is_group": 1
},
"25. K\u00c9SZTERM\u00c9KEK": {
"251-257. K\u00e9szterm\u00e9kek": {},
"258. K\u00e9szterm\u00e9kek k\u00e9szlet\u00e9rt\u00e9k-k\u00fcl\u00f6nb\u00f6zete": {},
"259. K\u00e9szterm\u00e9kek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
},
"26-28. \u00c1RUK ": {
"261. Kereskedelmi \u00e1ruk": {
"account_type": "Stock",
"is_group": 0
},
"262. Idegen helyen t\u00e1rolt, bizom\u00e1nyba \u00e1tadott \u00e1ruk": {
"account_type": "Stock",
"is_group": 0
},
"263. T\u00e1rgyi eszk\u00f6z\u00f6k k\u00f6z\u00fcl \u00e1tsorolt \u00e1ruk": {
"account_type": "Stock",
"is_group": 0
},
"264. Bels\u0151 (egys\u00e9gek, tev\u00e9kenys\u00e9gek k\u00f6z\u00f6tti) \u00e1tad\u00e1s-\u00e1tv\u00e9tel \u00fctk\u00f6z\u0151sz\u00e1mla": {
"account_type": "Stock",
"is_group": 0
},
"269. Kereskedelmi \u00e1ruk \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {
"account_type": "Stock",
"is_group": 0
},
"account_type": "Stock"
},
"27. K\u00d6ZVET\u00cdTETT SZOLG\u00c1LTAT\u00c1SOK ": {
"271. K\u00f6zvet\u00edtett szolg\u00e1ltat\u00e1sok": {},
"279. K\u00f6zvet\u00edtett szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
},
"28. BET\u00c9TD\u00cdJAS G\u00d6NGY\u00d6LEGEK": {
"is_group": 1
},
"root_type": "Asset"
},
"3. SZ\u00c1MLAOSZT\u00c1LY K\u00d6VETEL\u00c9SEK, P\u00c9NZ\u00dcGYI ESZK\u00d6Z\u00d6K \u00c9S AKT\u00cdV ID\u00d5BELI ELHAT\u00c1ROL\u00c1SOK": {
"31. K\u00d6VETEL\u00c9SEK \u00c1RUSZ\u00c1LL\u00cdT\u00c1SB\u00d3L \u00c9S SZOLG\u00c1LTAT\u00c1SB\u00d3L (VEV\u00d5K) ": {
"311. Belf\u00f6ldi k\u00f6vetel\u00e9sek (forintban)": {
"account_type": "Receivable"
},
"312. Belf\u00f6ldi k\u00f6vetel\u00e9sek (deviz\u00e1ban)": {
"account_type": "Receivable"
},
"315. Belf\u00f6ldi k\u00f6vetel\u00e9sek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa ": {},
"316. K\u00fclf\u00f6ldi k\u00f6vetel\u00e9sek (forintban)": {
"account_type": "Receivable"
},
"317. K\u00fclf\u00f6ldi k\u00f6vetel\u00e9sek (deviz\u00e1ban)": {
"account_type": "Receivable"
},
"319. K\u00fclf\u00f6ldi k\u00f6vetel\u00e9sek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
},
"32. K\u00d6VETEL\u00c9SEK KAPCSOLT V\u00c1LLALKOZ\u00c1SSAL SZEMBEN": {
"is_group": 1
},
"33. K\u00d6VETEL\u00c9SEK EGY\u00c9B R\u00c9SZESED\u00c9SI VISZONYBAN L\u00c9V\u00d5 V\u00c1LLALKOZ\u00c1SSAL SZEMBEN ": {
"is_group": 1
},
"34. V\u00c1LT\u00d3K\u00d6VETEL\u00c9SEK": {
"is_group": 1
},
"35. ADOTT EL\u00d5LEGEK": {
"351. Immateri\u00e1lis javakra adott el\u0151legek": {},
"352. Beruh\u00e1z\u00e1sokra adott el\u0151legek": {},
"353. K\u00e9szletekre adott el\u0151legek": {},
"358. Jegyzett, de m\u00e9g be nem fizetett t\u0151ke r\u00e9szesed\u00e9si viszonyban nem l\u00e9v\u0151 v\u00e1llalkoz\u00e1st\u00f3l": {},
"359. Adott el\u0151legek \u00e9rt\u00e9kveszt\u00e9se \u00e9s vissza\u00edr\u00e1sa": {}
},
"36. EGY\u00c9B K\u00d6VETEL\u00c9SEK": {
"361. Munkav\u00e1llal\u00f3kkal szembeni k\u00f6vetel\u00e9sek": {
"3611. Munkav\u00e1llal\u00f3knak foly\u00f3s\u00edtott el\u0151legek": {},
"3612. El\u0151\u00edrt tartoz\u00e1sok": {},
"3613. Egy\u00e9b elsz\u00e1mol\u00e1sok a munkav\u00e1llal\u00f3kkal": {}
},
"362. K\u00f6lts\u00e9gvet\u00e9ssel szembeni k\u00f6vetel\u00e9sek": {
"is_group": 1
},
"363. R\u00f6vid lej\u00e1ratra k\u00f6lcs\u00f6nadott p\u00e9nzeszk\u00f6z\u00f6k": {
"is_group": 1
},
"364. R\u00e9szesed\u00e9sekkel, \u00e9rt\u00e9kpap\u00edrokkal kapcsolatos k\u00f6vetel\u00e9sek": {
"3641. R\u00f6vid lej\u00e1rat\u00fa k\u00f6lcs\u00f6n\u00f6k": {},
"3642. Tart\u00f3san adott k\u00f6lcs\u00f6n\u00f6kb\u0151l \u00e1tsorolt k\u00f6vetel\u00e9sek": {}
},
"365. V\u00e1s\u00e1rolt \u00e9s kapott k\u00f6vetel\u00e9sek ": {
"is_group": 1
},
"366. R\u00e9szesed\u00e9sekkel, \u00e9rt\u00e9kpap\u00edrokkal kapcsolatos k\u00f6vetel\u00e9sek": {},
"367. Hat\u00e1rid\u0151s, opci\u00f3s \u00e9s swap \u00fcgyletekkel kapcsolatos k\u00f6vetel\u00e9sek": {},
"368. K\u00fcl\u00f6nf\u00e9le egy\u00e9b k\u00f6vetel\u00e9sek ": {
"3681. Bizom\u00e1nyosi \u00fcgylettel kapcsolatos elsz\u00e1mol\u00e1sok": {},
"3682. \u00c9rt\u00e9kpap\u00edr-elsz\u00e1mol\u00e1si sz\u00e1mla": {},
"3683. Import beszerz\u00e9sek \u00e1f\u00e1ja": {},
"3684. Ad\u00f3sok": {},
"3685. Biztos\u00edt\u00f3int\u00e9zettel szembeni k\u00f6vetel\u00e9sek": {},
"3686. Barter \u00fcgylet elsz\u00e1mol\u00e1si sz\u00e1mla": {},
"3687. \u00c1rfolyam k\u00fcl\u00f6nb\u00f6zetek elsz\u00e1mol\u00e1si sz\u00e1mla": {},
"3688. Ki nem emelt egy\u00e9b k\u00f6vetel\u00e9sek": {}
},
"369. Egy\u00e9b k\u00f6vetel\u00e9sek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
},
"37. \u00c9RT\u00c9KPAP\u00cdROK": {
"371. R\u00e9szesed\u00e9sek": {
"3711. R\u00e9szesed\u00e9s anyav\u00e1llalatban": {},
"3712. R\u00e9szesed\u00e9s le\u00e1nyv\u00e1llalatban": {},
"3713. R\u00e9szesed\u00e9s k\u00f6z\u00f6s vezet\u00e9s\u0171 v\u00e1llalkoz\u00e1sban": {},
"3714. R\u00e9szesed\u00e9s t\u00e1rsult v\u00e1llalkoz\u00e1sban": {},
"3719. Kapcsolt v\u00e1llalkoz\u00e1sban l\u00e9v\u0151 r\u00e9szesed\u00e9sek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
},
"372. Saj\u00e1t r\u00e9szv\u00e9nyek, saj\u00e1t \u00fczletr\u00e9szek": {
"3721. Elad\u00e1sra v\u00e1s\u00e1rolt egy\u00e9b r\u00e9szesed\u00e9sek": {}
},
"373. Forgat\u00e1si c\u00e9l\u00fa hitelviszonyt megtestes\u00edt\u0151 \u00e9rt\u00e9kpap\u00edrok ": {
"3741. Elad\u00e1sra v\u00e1s\u00e1rolt hitelviszonyt megtestes\u00edt\u0151 \u00e9rt\u00e9kpap\u00edrok": {},
"3742. Elad\u00e1sra v\u00e1s\u00e1rolt diszkont \u00e9rt\u00e9kpap\u00edrok": {},
"3749. Forgat\u00e1si c\u00e9l\u00fa hitelviszonyt megtestes\u00edt\u0151 \u00e9rt\u00e9kpap\u00edrok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
},
"378. \u00c9rt\u00e9kpap\u00edrok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
"379. \u00c9rt\u00e9kpap\u00edr elsz\u00e1mol\u00e1si sz\u00e1mla": {}
},
"38. P\u00c9NZESZK\u00d6Z\u00d6K": {
"381. P\u00e9nzt\u00e1r ": {
"3811. P\u00e9nzt\u00e1r-sz\u00e1mla": {},
"3812. Elektronikus p\u00e9nzeszk\u00f6z\u00f6k ": {},
"account_type": "Cash"
},
"382. Valutap\u00e9nzt\u00e1r ": {
"3821. Valutap\u00e9nzt\u00e1r-sz\u00e1mla": {},
"3829. Valuta \u00e1rfolyamk\u00fcl\u00f6nb\u00f6zeti sz\u00e1mla ": {}
},
"383. Csekkek": {},
"384. Elsz\u00e1mol\u00e1si bet\u00e9tsz\u00e1mla ": {
"account_type": "Bank",
"is_group": 1
},
"385. Elk\u00fcl\u00f6n\u00edtett bet\u00e9tsz\u00e1ml\u00e1k ": {
"3851. Kamatoz\u00f3 bet\u00e9tsz\u00e1ml\u00e1k": {},
"3852. Elk\u00fcl\u00f6n\u00edtett p\u00e9nzeszk\u00f6z\u00f6k k\u00f6tv\u00e9nykibocs\u00e1t\u00e1sb\u00f3l ": {},
"3853. Beruh\u00e1z\u00e1sra elk\u00fcl\u00f6n\u00edtett p\u00e9nzeszk\u00f6z\u00f6k": {},
"3854. Fejleszt\u00e9si c\u00e9lra elk\u00fcl\u00f6n\u00edtett p\u00e9nzeszk\u00f6z\u00f6k ": {},
"3855. Egy\u00e9b c\u00e9lra elk\u00fcl\u00f6n\u00edtett p\u00e9nzeszk\u00f6z\u00f6k": {},
"3856. Lak\u00e1s\u00e9p\u00edt\u00e9si bet\u00e9tsz\u00e1mla": {},
"3857. Elk\u00fcl\u00f6n\u00edtett lak\u00e1s\u00e9p\u00edt\u00e9si c\u00e9l\u00fa p\u00e9nzeszk\u00f6z\u00f6k ": {},
"3858. Lak\u00e1s\u00e9p\u00edt\u00e9s \u00faton l\u00e9v\u0151 p\u00e9nzeszk\u00f6zei": {}
},
"386. Devizabet\u00e9t-sz\u00e1mla ": {
"3861. Devizabet\u00e9t-sz\u00e1mla": {},
"3862. K\u00fclf\u00f6ld\u00f6n vezetett devizabet\u00e9t-sz\u00e1mla ": {},
"3863. Devizat\u00f6rzsbet\u00e9t-sz\u00e1mla": {},
"3868. Egy\u00e9b devizabet\u00e9t-sz\u00e1mla": {},
"3869. Devizabet\u00e9t \u00e1rfolyamk\u00fcl\u00f6nb\u00f6zeti sz\u00e1mla ": {}
},
"387. Elektronikus p\u00e9nz": {},
"389. \u00c1tvezet\u00e9si sz\u00e1mla": {}
},
"39. AKT\u00cdV ID\u00d5BELI ELHAT\u00c1ROL\u00c1SOK": {
"391. Bev\u00e9telek akt\u00edv id\u0151beli elhat\u00e1rol\u00e1sa ": {
"3911. Diszkont \u00e9rt\u00e9kpap\u00edrok id\u0151ar\u00e1nyos kamat\u00e1nak elhat\u00e1rol\u00e1sa": {},
"3912. \u00c9rt\u00e9kpap\u00edrok beszerz\u00e9s\u00e9hez kapcsol\u00f3d\u00f3 k\u00fcl\u00f6nb\u00f6zetb\u0151l az id\u0151ar\u00e1nyos \u00e1rfolyamnyeres\u00e9g elhat\u00e1rol\u00e1sa": {},
"3913. \u00c1rbev\u00e9tel, egy\u00e9b kamatbev\u00e9tel, egy\u00e9b bev\u00e9tel elhat\u00e1rol\u00e1sa": {}
},
"392. K\u00f6lts\u00e9gek, r\u00e1ford\u00edt\u00e1sok akt\u00edv id\u0151beli elhat\u00e1rol\u00e1sa ": {
"3921. \u00c9rt\u00e9kpap\u00edrok, r\u00e9szesed\u00e9sek beszerz\u00e9s\u00e9hez kapcsol\u00f3d\u00f3 bizom\u00e1nyi d\u00edj, v\u00e1s\u00e1rolt v\u00e9teli opci\u00f3 d\u00edj\u00e1nak elhat\u00e1rol\u00e1sa": {},
"3922. T\u00f6bbletk\u00f6telezetts\u00e9gek elhat\u00e1rol\u00e1sa": {},
"3923. K\u00f6lts\u00e9gek, egy\u00e9b fizetett kamatok, egy\u00e9b r\u00e1ford\u00edt\u00e1sok elhat\u00e1rol\u00e1sa": {}
},
"393. Halasztott r\u00e1ford\u00edt\u00e1sok ": {
"3931. Tartoz\u00e1s\u00e1tv\u00e1llal\u00e1sok miatti r\u00e1ford\u00edt\u00e1sok elhat\u00e1rol\u00e1sa": {},
"3932. Devizak\u00f6telezetts\u00e9gek \u00e1rfolyamvesztes\u00e9g\u00e9nek elhat\u00e1rol\u00e1sa ": {}
},
"399. A k\u00f6vetel\u00e9s-jelleg\u0171 akt\u00edv id\u0151beli elhat\u00e1rol\u00e1sok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
},
"root_type": "Asset"
},
"4. SZ\u00c1MLAOSZT\u00c1LY FORR\u00c1SOK": {
"41. SAJ\u00c1T T\u00d5KE": {
"411. Jegyzett\u0151ke ": {},
"412. T\u0151ketartal\u00e9k": {},
"413. Eredm\u00e9nytartal\u00e9k": {},
"414. Lek\u00f6t\u00f6tt tartal\u00e9k ": {
"4141. Lek\u00f6t\u00f6tt tartal\u00e9k t\u0151ketartal\u00e9kb\u00f3l": {},
"4142. Lek\u00f6t\u00f6tt tartal\u00e9k eredm\u00e9nytartal\u00e9kb\u00f3l": {},
"4143. Lek\u00f6t\u00f6tt tartal\u00e9k p\u00f3tbefizet\u00e9sb\u0151l ": {}
},
"417. \u00c9rt\u00e9kel\u00e9si tartal\u00e9k": {},
"418. El\u0151z\u0151 \u00e9vek helyesb\u00edt\u00e9s\u00e9b\u0151l sz\u00e1rmaz\u00f3 m\u00e9rleg szerinti eredm\u00e9ny": {},
"419. Ad\u00f3zott eredm\u00e9ny": {}
},
"42. C\u00c9LTARTAL\u00c9KOK": {
"421. C\u00e9ltartal\u00e9k a v\u00e1rhat\u00f3 k\u00f6telezetts\u00e9gekre ": {},
"422. C\u00e9ltartal\u00e9k a j\u00f6v\u0151beni k\u00f6lts\u00e9gekre": {},
"424. \u00c1rfolyamvesztes\u00e9g id\u0151beli elhat\u00e1rol\u00e1sa alapj\u00e1n k\u00e9pzett c\u00e9ltartal\u00e9k ": {},
"429. Egy\u00e9b c\u00e9ltartal\u00e9k": {}
},
"43-47. K\u00d6TELEZETTS\u00c9GEK": {
"43. H\u00c1TRASOROLT K\u00d6TELEZETTS\u00c9GEK": {
"431. H\u00e1trasorolt k\u00f6telezetts\u00e9gek kapcsolt v\u00e1llalkoz\u00e1ssal szemben ": {
"4311. H\u00e1trasorolt k\u00f6telezetts\u00e9gek anyav\u00e1llalattal szemben ": {},
"4312. H\u00e1trasorolt k\u00f6telezetts\u00e9gek le\u00e1nyv\u00e1llalattal szemben": {},
"4313. H\u00e1trasorolt k\u00f6telezetts\u00e9gek k\u00f6z\u00f6s vezet\u00e9s\u0171 v\u00e1llalkoz\u00e1ssal szemben ": {},
"4314. H\u00e1trasorolt k\u00f6telezetts\u00e9gek t\u00e1rsult v\u00e1llalkoz\u00e1ssal szemben ": {}
},
"432. H\u00e1trasorolt k\u00f6telezetts\u00e9gek egy\u00e9b r\u00e9szesed\u00e9si viszonyban l\u00e9v\u0151 v\u00e1llalkoz\u00e1ssal szemben": {},
"433. H\u00e1trasorolt k\u00f6telezetts\u00e9gek egy\u00e9b gazd\u00e1lkod\u00f3val szemben": {}
},
"44. HOSSZ\u00da LEJ\u00c1RAT\u00da K\u00d6TELEZETTS\u00c9GEK": {
"441. Hossz\u00fa lej\u00e1ratra kapott k\u00f6lcs\u00f6n\u00f6k": {},
"442. \u00c1tv\u00e1ltoztathat\u00f3 k\u00f6tv\u00e9nyek ": {},
"443. Tartoz\u00e1sok k\u00f6tv\u00e9nykibocs\u00e1t\u00e1sb\u00f3l ": {
"4431. Tartoz\u00e1sok k\u00f6tv\u00e9nykibocs\u00e1t\u00e1sb\u00f3l forintban ": {},
"4432. Tartoz\u00e1sok k\u00f6tv\u00e9nykibocs\u00e1t\u00e1sb\u00f3l deviz\u00e1ban": {}
},
"444. Beruh\u00e1z\u00e1si \u00e9s fejleszt\u00e9si hitelek ": {
"4441. Beruh\u00e1z\u00e1si \u00e9s fejleszt\u00e9si hitelek forintban ": {},
"4442. Beruh\u00e1z\u00e1si \u00e9s fejleszt\u00e9si hitelek deviz\u00e1ban ": {}
},
"445. Egy\u00e9b hossz\u00fa lej\u00e1rat\u00fa hitelek ": {
"4451. Egy\u00e9b hossz\u00fa lej\u00e1rat\u00fa hitelek forintban ": {},
"4452. Egy\u00e9b hossz\u00fa lej\u00e1rat\u00fa hitelek deviz\u00e1ban": {}
},
"446. Tart\u00f3s k\u00f6telezetts\u00e9gek kapcsolt v\u00e1llalkoz\u00e1ssal szemben ": {
"is_group": 1
},
"447. Tart\u00f3s k\u00f6telezetts\u00e9gek egy\u00e9b r\u00e9szesed\u00e9si viszonyban l\u00e9v\u0151 v\u00e1llalkoz\u00e1ssal szemben": {},
"448. P\u00e9nz\u00fcgyi l\u00edzing miatti k\u00f6telezetts\u00e9gek ": {},
"449. Egy\u00e9b hossz\u00fa lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek ": {
"4491. Kincst\u00e1ri vagyon r\u00e9sz\u00e9t k\u00e9pez\u0151 eszk\u00f6z\u00f6k kezel\u00e9sbe v\u00e9tel\u00e9hez kapcsol\u00f3d\u00f3 k\u00f6telezetts\u00e9g": {},
"4492. Alap\u00edt\u00f3kkal szembeni hossz\u00fa lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek ": {}
},
"4499. Hossz\u00fa lej\u00e1rat\u00fa egy\u00e9b k\u00f6telezetts\u00e9gek": {}
},
"45-47. R\u00d6VID LEJ\u00c1RAT\u00da K\u00d6TELEZETTS\u00c9GEK": {
"451. R\u00f6vid lej\u00e1rat\u00fa k\u00f6lcs\u00f6n\u00f6k ": {
"4511. R\u00f6vid lej\u00e1rat\u00fa \u00e1tv\u00e1ltoztathat\u00f3 k\u00f6tv\u00e9nyek ": {},
"4512. Egy\u00e9b r\u00f6vid lej\u00e1rat\u00fa k\u00f6lcs\u00f6n\u00f6k": {}
},
"452. R\u00f6vid lej\u00e1rat\u00fa hitelek ": {
"4521. R\u00f6vid lej\u00e1rat\u00fa hitelek forintban ": {},
"4522. R\u00f6vid lej\u00e1rat\u00fa hitelek deviz\u00e1ban ": {}
},
"453. Vev\u0151kt\u0151l kapott el\u0151legek": {},
"454-456. K\u00f6telezetts\u00e9gek \u00e1rusz\u00e1ll\u00edt\u00e1sb\u00f3l \u00e9s szolg\u00e1ltat\u00e1sb\u00f3l (sz\u00e1ll\u00edt\u00f3k)": {
"454. Sz\u00e1ll\u00edt\u00f3k ": {
"4541. Belf\u00f6ldi anyag- \u00e9s \u00e1rusz\u00e1ll\u00edt\u00f3k ": {
"account_type": "Payable"
},
"4542. K\u00fclf\u00f6ldi anyag- \u00e9s \u00e1rusz\u00e1ll\u00edt\u00f3k ": {
"account_type": "Payable"
},
"4543. Belf\u00f6ldi szolg\u00e1ltat\u00f3k": {},
"4544. K\u00fclf\u00f6ldi szolg\u00e1ltat\u00f3k": {},
"4549. Nem sz\u00e1ml\u00e1zott sz\u00e1ll\u00edt\u00e1sok, szolg\u00e1ltat\u00e1sok ": {
"account_type": "Stock Received But Not Billed"
}
},
"455. Beruh\u00e1z\u00e1si sz\u00e1ll\u00edt\u00f3k ": {
"4551. Belf\u00f6ldi beruh\u00e1z\u00e1si sz\u00e1ll\u00edt\u00f3k ": {},
"4552. K\u00fclf\u00f6ldi beruh\u00e1z\u00e1si sz\u00e1ll\u00edt\u00f3k": {},
"4559. Nem sz\u00e1ml\u00e1zott beruh\u00e1z\u00e1si sz\u00e1ll\u00edt\u00f3k ": {}
},
"456. Nem sz\u00e1ml\u00e1zott sz\u00e1ll\u00edt\u00f3k": {}
},
"457. V\u00e1lt\u00f3tartoz\u00e1sok": {},
"458. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek kapcsolt v\u00e1llalkoz\u00e1ssal szemben ": {
"4581. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek anyav\u00e1llalattal szemben ": {},
"4582. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek le\u00e1nyv\u00e1llalattal szemben": {},
"4583. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek k\u00f6z\u00f6s vezet\u00e9s\u0171 v\u00e1llalkoz\u00e1ssal szemben": {},
"4584. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek t\u00e1rsult v\u00e1llalkoz\u00e1ssal szemben": {}
},
"459. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek egy\u00e9b r\u00e9szesed\u00e9si viszonyban l\u00e9v\u0151 v\u00e1llalkoz\u00e1ssal szemben": {},
"461-479. Egy\u00e9b r\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek": {
"461. Eredm\u00e9nyt terhel\u0151 ad\u00f3k elsz\u00e1mol\u00e1sa": {
"4611. T\u00e1rsas\u00e1gi ad\u00f3 elsz\u00e1mol\u00e1sa ": {},
"4612. K\u00fcl\u00f6nad\u00f3 elsz\u00e1mol\u00e1sa ": {},
"4613. Egyszer\u0171s\u00edtett v\u00e1llalkoz\u00f3i ad\u00f3 elsz\u00e1mol\u00e1sa ": {}
},
"462. Szem\u00e9lyi j\u00f6vedelemad\u00f3 elsz\u00e1mol\u00e1sa ": {
"4612. Mag\u00e1nszem\u00e9lyekt\u0151l levont szem\u00e9lyi j\u00f6vedelem ad\u00f3 elsz\u00e1mol\u00e1sa ": {},
"4621. Kifizet\u0151t terhel\u0151 szem\u00e9lyi j\u00f6vedelem ad\u00f3 elsz\u00e1mol\u00e1sa ": {}
},
"463. K\u00f6lts\u00e9gvet\u00e9si befizet\u00e9si k\u00f6telezetts\u00e9gek ": {
"463-1. Nyugd\u00edjj\u00e1rul\u00e9k ": {},
"463-10. Innov\u00e1ci\u00f3s j\u00e1rul\u00e9k ": {},
"463-11. \u00d6nellen\u0151rz\u00e9si p\u00f3tl\u00e9k ": {},
"463-12. Mulaszt\u00e1si b\u00edrs\u00e1g, ad\u00f3b\u00edrs\u00e1g ": {},
"463-13. K\u00e9sedelmi p\u00f3tl\u00e9k ": {},
"463-14. Egy\u00e9b k\u00f6lts\u00e9gvet\u00e9si befizet\u00e9si k\u00f6telezetts\u00e9gek ": {},
"463-2. Eg\u00e9szs\u00e9gbiztos\u00edt\u00e1si- \u00e9s munkaer\u0151 piaci j\u00e1rul\u00e9k ": {},
"463-3. Rehabilit\u00e1ci\u00f3s hozz\u00e1j\u00e1rul\u00e1s ": {},
"463-4. Szoci\u00e1lis hozz\u00e1j\u00e1rul\u00e1si ad\u00f3 ": {},
"463-5. Eg\u00e9szs\u00e9g\u00fcgyi szolg\u00e1ltat\u00e1si j\u00e1rul\u00e9k ": {},
"463-6. Szakk\u00e9pz\u00e9si hozz\u00e1j\u00e1rul\u00e1s ": {},
"463-7. Eg\u00e9szs\u00e9g\u00fcgyi hozz\u00e1j\u00e1rul\u00e1s ": {},
"463-8. Egyszer\u0171s\u00edtett foglalkoztat\u00e1s k\u00f6zterhe ": {},
"463-9. C\u00e9gaut\u00f3ad\u00f3 ": {}
},
"464. G\u00e9pj\u00e1rm\u0171 ad\u00f3 (c\u00e9gaut\u00f3ad\u00f3) elsz\u00e1mol\u00e1sa": {
"is_group": 1
},
"465. V\u00e1m- \u00e9s p\u00e9nz\u00fcgy\u0151rs\u00e9g elsz\u00e1mol\u00e1si sz\u00e1mla ": {
"4651. V\u00e1mk\u00f6lts\u00e9gek \u00e9s egy\u00e9b v\u00e1mterhek elsz\u00e1mol\u00e1si sz\u00e1mla": {},
"4652. Importbeszerz\u00e9s ut\u00e1n fizetend\u0151 \u00e1ltal\u00e1nos forgalmi ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla": {},
"4653. V\u00e1m- \u00e9s p\u00e9nz\u00fcgy\u0151rs\u00e9ggel kapcsolatos egy\u00e9b elsz\u00e1mol\u00e1sok ": {}
},
"466. El\u0151zetesen felsz\u00e1m\u00edtott \u00e1ltal\u00e1nos forgalmi ad\u00f3 ": {
"4661. Beszerz\u00e9sek el\u0151zetesen felsz\u00e1m\u00edtott \u00e1ltal\u00e1nos forgalmi ad\u00f3ja ": {},
"4662. Ar\u00e1nyos\u00edt\u00e1ssal megosztand\u00f3 el\u0151zetesen felsz\u00e1m\u00edtott \u00e1ltal\u00e1nos forgalmi ad\u00f3": {}
},
"467. Fizetend\u0151 \u00e1ltal\u00e1nos forgalmi ad\u00f3": {},
"468. \u00c1ltal\u00e1nos forgalmi ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
"469. Helyi ad\u00f3k elsz\u00e1mol\u00e1si sz\u00e1mla ": {
"4691. \u00c9p\u00edtm\u00e9nyad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
"4692. Telekad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla": {},
"4693. Kommun\u00e1lis ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
"4694. Idegenforgalmi ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
"4695. Helyi ipar\u0171z\u00e9si ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
"4696. G\u00e9pj\u00e1rm\u0171ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla": {},
"4697. K\u00fclf\u00f6ldi g\u00e9pj\u00e1rm\u0171ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
"4699. Egy\u00e9b helyi ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla": {}
},
"471. J\u00f6vedelemelsz\u00e1mol\u00e1si sz\u00e1mla ": {
"4711. Keresetelsz\u00e1mol\u00e1si sz\u00e1mla ": {},
"4712. T\u00e1rsadalombiztos\u00edt\u00e1si ell\u00e1t\u00e1s ": {},
"4713. Egy\u00e9b kifizet\u00e9sek elsz\u00e1mol\u00e1sa": {}
},
"472. Fel nem vett j\u00e1rand\u00f3s\u00e1gok": {},
"473. Elsz\u00e1mol\u00e1s a t\u00e1rsadalombiztos\u00edt\u00e1ssal ": {},
"474. Szakk\u00e9pz\u00e9si hozz\u00e1j\u00e1rul\u00e1s": {
"4741. K\u00f6zponti m\u0171szaki fejleszt\u00e9si hozz\u00e1j\u00e1rul\u00e1s": {},
"4742. Elsz\u00e1mol\u00e1sra kapott p\u00e9nzeszk\u00f6z\u00f6k": {},
"4743. K\u00f6rnyezetv\u00e9delmi term\u00e9k d\u00edjfizet\u00e9si k\u00f6telezetts\u00e9g ": {},
"4749. Egy\u00e9b befizet\u00e9sek az elk\u00fcl\u00f6n\u00edtett alapokba": {}
},
"475. Eg\u00e9szs\u00e9g\u00fcgyi hozz\u00e1j\u00e1rul\u00e1s (EHO) elsz\u00e1mol\u00e1sa": {},
"476. Egy\u00e9b \u00e1llami ad\u00f3hat\u00f3s\u00e1ggal szembeni k\u00f6telezetts\u00e9g elsz\u00e1mol\u00e1sa": {
"4761. K\u00e1rt\u00e9r\u00edt\u00e9s": {},
"4762. B\u00edr\u00f3i letilt\u00e1s": {},
"4763. Banki-elsz\u00e1mol\u00e1s": {},
"4764. Levont szakszervezeti d\u00edj": {},
"4765. Mag\u00e1n nyugd\u00edjp\u00e9nzt\u00e1ri befizet\u00e9si k\u00f6telezetts\u00e9gek": {}
},
"477. R\u00f6vid lej\u00e1rat\u00fa egy\u00e9b k\u00f6telezetts\u00e9gek munkav\u00e1llal\u00f3kkal \u00e9s tulajdonosokkal szemben": {},
"478. R\u00e9szesed\u00e9sekkel, \u00e9rt\u00e9kpap\u00edrokkal kapcsolatos k\u00f6telezetts\u00e9gek ": {},
"479. K\u00fcl\u00f6nf\u00e9le r\u00f6vid lej\u00e1rat\u00fa egy\u00e9b befizet\u00e9si k\u00f6telezetts\u00e9gek ": {
"4791. Biztos\u00edt\u00f3 int\u00e9zetekkel szembeni k\u00f6telezetts\u00e9gek": {},
"4792. Hitelez\u0151k": {},
"4793. \u00c1tv\u00e1llalt k\u00f6telezetts\u00e9gek": {},
"4794. Beszerz\u00e9si \u00e1rba beletartoz\u00f3 el\u0151\u00edrt egy\u00e9b k\u00f6telezetts\u00e9gek ": {},
"4795. Egy\u00e9b r\u00f6vid lej\u00e1rat\u00fa el\u0151\u00edrt k\u00f6telezetts\u00e9gek": {}
}
}
}
},
"48. PASSZ\u00cdV ID\u00d5BELI ELHAT\u00c1ROL\u00c1SOK": {
"481. Bev\u00e9telek passz\u00edv id\u0151beli elhat\u00e1rol\u00e1sa ": {
"4811. Befolyt, elsz\u00e1molt bev\u00e9telek elhat\u00e1rol\u00e1sa": {},
"4812. K\u00f6lts\u00e9gek ellent\u00e9telez\u00e9s\u00e9re kapott t\u00e1mogat\u00e1sok elhat\u00e1rol\u00e1sa": {},
"4813. Devizaeszk\u00f6z\u00f6k \u00e9s devizak\u00f6telezetts\u00e9gek m\u00e9rlegfordul\u00f3napi \u00e9rt\u00e9kel\u00e9se \u00e1rfolyamnyeres\u00e9g\u00e9nek elhat\u00e1rol\u00e1sa": {}
},
"482. K\u00f6lts\u00e9gek, r\u00e1ford\u00edt\u00e1sok passz\u00edv id\u0151beli elhat\u00e1rol\u00e1sa ": {
"4821. M\u00e9rlegfordul\u00f3nap el\u0151tti id\u0151szakot terhel\u0151 k\u00f6lts\u00e9gek, r\u00e1ford\u00edt\u00e1sok elhat\u00e1rol\u00e1sa": {},
"4822. \u00c9rt\u00e9kpap\u00edrok beszerz\u00e9s\u00e9hez kapcsol\u00f3d\u00f3 k\u00fcl\u00f6nb\u00f6zetb\u0151l az id\u0151ar\u00e1nyos \u00e1rfolyam\u008fvesztes\u00e9g elhat\u00e1rol\u00e1sa": {},
"4823. Fizetend\u0151 kamatok elhat\u00e1rol\u00e1sa ": {}
},
"483. Halasztott bev\u00e9telek ": {}
},
"49. \u00c9VI M\u00c9RLEGSZ\u00c1ML\u00c1K": {
"491. Nyit\u00f3m\u00e9rleg sz\u00e1mla ": {},
"492. Z\u00e1r\u00f3m\u00e9rleg sz\u00e1mla": {},
"493. Ad\u00f3zott eredm\u00e9ny elsz\u00e1mol\u00e1si sz\u00e1mla": {},
"494. El\u0151z\u0151 \u00e9vi ad\u00f3zott eredm\u00e9ny elsz\u00e1mol\u00e1sa": {}
},
"root_type": "Liability"
},
"5. SZ\u00c1MLAOSZT\u00c1LY K\u00d6LTS\u00c9GNEMEK": {
"51 - 53 ANYAGJELLEG\u00db R\u00c1FORD\u00cdT\u00c1SOK ": {
"51. ANYAGK\u00d6LTS\u00c9G": {
"511. V\u00e1s\u00e1rolt anyagok k\u00f6lts\u00e9gei ": {
"5111. Alapanyag k\u00f6lts\u00e9gek": {},
"5112. Seg\u00e9danyag k\u00f6lts\u00e9gek": {},
"5113. \u00dczemanyag k\u00f6lts\u00e9gek": {},
"5114. Egy \u00e9ven bel\u00fcl elhaszn\u00e1l\u00f3d\u00f3 gy\u00e1rt\u00f3eszk\u00f6z\u00f6k, berendez\u00e9sek, felszerel\u00e9sek \u00e9s egy\u00e9b eszk\u00f6z\u00f6k k\u00f6lts\u00e9gei": {},
"5115. Egy \u00e9ven bel\u00fcl elhaszn\u00e1l\u00f3d\u00f3 munkaruha, v\u00e9d\u0151ruha felhaszn\u00e1l\u00e1s k\u00f6lts\u00e9gei": {},
"5116. Nyomtatv\u00e1nyok, irodaszerek k\u00f6lts\u00e9gei": {},
"5117. F\u0171t\u0151anyag k\u00f6lts\u00e9gek": {},
"5118. Villamosenergia felhaszn\u00e1l\u00e1s \u00e9s v\u00edzfelhaszn\u00e1l\u00e1s k\u00f6lts\u00e9gei": {},
"5119. Egy\u00e9b anyagfelhaszn\u00e1l\u00e1s k\u00f6lts\u00e9gei": {},
"512. Egy \u00e9ven bel\u00fcl elhaszn\u00e1l\u00f3d\u00f3 anyagi eszk\u00f6z\u00f6k k\u00f6lts\u00e9gei ": {},
"5121. V\u00e1s\u00e1rolt n\u00f6vend\u00e9k\u00e1llatok k\u00f6lts\u00e9gei": {},
"5122. V\u00e1s\u00e1rolt h\u00edz\u00f3\u00e1llatok k\u00f6lts\u00e9gei": {},
"5123. V\u00e1s\u00e1rolt egy\u00e9b \u00e1llatok k\u00f6lts\u00e9gei": {},
"513. Egy\u00e9b anyagk\u00f6lts\u00e9g": {},
"519. Anyagk\u00f6lts\u00e9g megt\u00e9r\u00fcl\u00e9s": {}
}
},
"52. IG\u00c9NYBE VETT SZOLG\u00c1LTAT\u00c1SOK K\u00d6LTS\u00c9GEI": {
"521. Sz\u00e1ll\u00edt\u00e1s-rakod\u00e1s, rakt\u00e1roz\u00e1s k\u00f6lts\u00e9gei": {},
"522. B\u00e9rleti d\u00edjak": {},
"523. Karbantart\u00e1si k\u00f6lts\u00e9gek": {},
"524. Hirdet\u00e9s, rekl\u00e1m, propaganda k\u00f6lts\u00e9gek": {},
"525. Oktat\u00e1s \u00e9s tov\u00e1bbk\u00e9pz\u00e9s k\u00f6lts\u00e9gei": {},
"526. Utaz\u00e1si \u00e9s kik\u00fcldet\u00e9si k\u00f6lts\u00e9gek (napid\u00edj n\u00e9lk\u00fcl)": {},
"529. Ig\u00e9nybe vett egy\u00e9b szolg\u00e1ltat\u00e1sok k\u00f6lts\u00e9gei": {}
},
"53. EGY\u00c9B SZOLG\u00c1LTAT\u00c1SOK K\u00d6LTS\u00c9GEI": {
"531. Hat\u00f3s\u00e1gi igazgat\u00e1si, szolg\u00e1ltat\u00e1si d\u00edjak, illet\u00e9kek": {},
"532. P\u00e9nz\u00fcgyi, befektet\u00e9si szolg\u00e1ltat\u00e1si d\u00edjak": {},
"533. Biztos\u00edt\u00e1si d\u00edj ": {},
"534. K\u00f6lts\u00e9gk\u00e9nt elsz\u00e1moland\u00f3 ad\u00f3k, j\u00e1rul\u00e9kok, term\u00e9kd\u00edjak": {},
"539. K\u00fcl\u00f6nf\u00e9le egy\u00e9b szolg\u00e1ltat\u00e1sok k\u00f6lts\u00e9gei": {}
}
},
"54 - 56. SZEM\u00c9LYI JELLEG\u00db R\u00c1FORD\u00cdT\u00c1SOK": {
"54. B\u00c9RK\u00d6LTS\u00c9G ": {
"541. B\u00e9rk\u00f6lts\u00e9g": {},
"542. Tulajdonos szem\u00e9lyes k\u00f6zrem\u0171k\u00f6d\u00e9s\u00e9nek ellen\u00e9rt\u00e9ke": {},
"543. Sz\u00f6vetkezeti tagok munkad\u00edja": {}
},
"55. SZEM\u00c9LYI JELLEG\u00db EGY\u00c9B KIFIZET\u00c9SEK": {
"551. Munkav\u00e1llal\u00f3knak, tagoknak fizetett szem\u00e9lyi jelleg\u0171 kifizet\u00e9sek ": {
"5511. Betegszabads\u00e1g d\u00edja, munk\u00e1ltat\u00f3t terhel\u0151 t\u00e1pp\u00e9nz, t\u00e1pp\u00e9nz kieg\u00e9sz\u00edt\u00e9s": {},
"5512. V\u00e9gkiel\u00e9g\u00edt\u00e9s": {},
"5513. Munk\u00e1baj\u00e1r\u00e1ssal kapcsolatos egy\u00e9b k\u00f6lts\u00e9gek t\u00e9r\u00edt\u00e9se": {},
"5514. Kik\u00fcldet\u00e9s napid\u00edja": {},
"5515. Megv\u00e1ltozott munkak\u00e9pess\u00e9g\u0171 munkav\u00e1llal\u00f3k keresetkieg\u00e9sz\u00edt\u00e9se, fizetett seg\u00e9lyek": {},
"5516. \u00dcd\u00fcl\u00e9si hozz\u00e1j\u00e1rul\u00e1s": {},
"5517. Lak\u00e1s\u00e9p\u00edt\u00e9sre ny\u00fajtott t\u00e1mogat\u00e1s, alb\u00e9rleti hozz\u00e1j\u00e1rul\u00e1s": {},
"5518. Jubileumi jutalom, t\u00e1rgyjutalom": {},
"5519. Sorkatonai vagy polg\u00e1ri szolg\u00e1lat teljes\u00edt\u00e9s\u00e9t k\u00f6vet\u0151en fizetett szem\u00e9lyi alapb\u00e9r": {}
},
"552. J\u00f3l\u00e9ti \u00e9s kultur\u00e1lis k\u00f6lts\u00e9gek": {},
"559. Egy\u00e9b szem\u00e9lyi jelleg\u0171 kifizet\u00e9sek ": {
"5591. Munk\u00e1ltat\u00f3 \u00e1ltal fizetett baleset-, \u00e9let- \u00e9s nyugd\u00edjbiztos\u00edt\u00e1s d\u00edja": {},
"5592. Munk\u00e1ltat\u00f3 \u00e1ltal \u00f6nk\u00e9ntes p\u00e9nzt\u00e1rba befizetett munk\u00e1ltat\u00f3i tagd\u00edj hozz\u00e1j\u00e1rul\u00e1s": {},
"5593. Munk\u00e1ltat\u00f3t terhel\u0151 szem\u00e9lyi j\u00f6vedelemad\u00f3": {},
"5594. Munk\u00e1ltat\u00f3i hozz\u00e1j\u00e1rul\u00e1s a korengedm\u00e9nyes nyugd\u00edj ig\u00e9nybev\u00e9tel\u00e9hez": {},
"5595. Tal\u00e1lm\u00e1nyi d\u00edj, szabadalom v\u00e9tel\u00e1ra \u00e9s hasznos\u00edt\u00e1si d\u00edja, az \u00faj\u00edt\u00e1si d\u00edj \u00e9s ezekkel kapcsolatos k\u00f6zrem\u0171k\u00f6d\u00e9si d\u00edjak": {},
"5596. Fizetett szerz\u0151i, \u00edr\u00f3i \u00e9s m\u00e1s jogv\u00e9delmet \u00e9lvez\u0151 munk\u00e1k d\u00edjai \u00e9s ezekkel kapcsolatos k\u00f6zrem\u0171k\u00f6d\u0151i d\u00edjak": {},
"5597. Fizetett \u00f6szt\u00f6nd\u00edjak": {},
"5598. Reprezent\u00e1ci\u00f3s k\u00f6lts\u00e9gek, \u00e9tkez\u00e9si hozz\u00e1j\u00e1rul\u00e1s": {},
"5599. Munk\u00e1ltat\u00f3 \u00e1ltal fizetett mag\u00e1nnyugd\u00edj-p\u00e9nzt\u00e1ri tagd\u00edj kieg\u00e9sz\u00edt\u00e9s, munkav\u00e1llal\u00f3kkal kapcsolatos biztos\u00edt\u00e1si d\u00edjak": {}
}
},
"56. B\u00c9RJ\u00c1RUL\u00c9KOK": {
"561. Nyugd\u00edjbiztos\u00edt\u00e1si \u00e9s eg\u00e9szs\u00e9gbiztos\u00edt\u00e1si j\u00e1rul\u00e9k ": {},
"562. Eg\u00e9szs\u00e9g\u00fcgyi hozz\u00e1j\u00e1rul\u00e1s": {},
"563. Munkaad\u00f3i j\u00e1rul\u00e9k": {},
"564. Szakk\u00e9pz\u00e9si hozz\u00e1j\u00e1rul\u00e1s ": {},
"569. Egy\u00e9b hozz\u00e1j\u00e1rul\u00e1s ": {}
}
},
"57. \u00c9RT\u00c9KCS\u00d6KKEN\u00c9SI LE\u00cdR\u00c1S": {
"571. Terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1s ": {
"5711. Terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1s ": {
"account_type": "Depreciation"
},
"5712. Kiemelt, kis \u00e9rt\u00e9k\u0171 (50 eFt egyedi beszerz\u00e9si \u00e9rt\u00e9k alatti) eszk\u00f6z\u00f6k terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1sa": {},
"57121. Kis \u00e9rt\u00e9k\u0171 (50 eFt egyedi beszerz\u00e9si \u00e9rt\u00e9k alatti) vagyoni \u00e9rt\u00e9k\u0171 jogok terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1sa": {},
"57122. Kis \u00e9rt\u00e9k\u0171 (50 eFt egyedi beszerz\u00e9si \u00e9rt\u00e9k alatti) szellemi term\u00e9kek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1sa": {},
"57123. Kis \u00e9rt\u00e9k\u0171 (50 eFt egyedi beszerz\u00e9si \u00e9rt\u00e9k alatti) t\u00e1rgyi eszk\u00f6z\u00f6k terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1sa": {}
}
},
"58. AKTIV\u00c1LT SAJ\u00c1T TELJES\u00cdTM\u00c9NYEK \u00c9RT\u00c9KE": {
"581. Saj\u00e1t termel\u00e9s\u0171 k\u00e9szletek \u00e1llom\u00e1nyv\u00e1ltoz\u00e1sa ": {},
"582. Saj\u00e1t el\u0151\u00e1ll\u00edt\u00e1s\u00fa eszk\u00f6z\u00f6k aktiv\u00e1lt \u00e9rt\u00e9ke": {},
"589. Aktiv\u00e1lt saj\u00e1t teljes\u00edtm\u00e9nyek \u00e1tvezet\u00e9si sz\u00e1mla": {}
},
"59. K\u00d6LTS\u00c9GNEM ELLENSZ\u00c1MLA (els\u0151dleges k\u00f6lts\u00e9ghely-k\u00f6lts\u00e9gvisel\u0151 elsz\u00e1mol\u00f3s eset\u00e9n) ": {
"is_group": 1
},
"59. K\u00d6LTS\u00c9GNEM \u00c1TVEZET\u00c9SI SZ\u00c1MLA (els\u0151dleges k\u00f6lts\u00e9gnem-elsz\u00e1mol\u00e1s eset\u00e9n)": {
"is_group": 1
},
"59. K\u00d6LTS\u00c9GNEM \u00c1TVEZET\u00c9SI SZ\u00c1MLA (els\u0151dleges k\u00f6lts\u00e9gnem-elsz\u00e1mol\u00e1s eset\u00e9n, kiz\u00e1r\u00f3lag \u00f6sszk\u00f6lts\u00e9g elj\u00e1r\u00e1ssal)": {
"59/51. Anyagk\u00f6lts\u00e9g \u00e1tvezet\u00e9si sz\u00e1mla": {},
"59/52. Ig\u00e9nybe vett szolg\u00e1ltat\u00e1sok k\u00f6lts\u00e9gei \u00e1tvezet\u00e9si sz\u00e1mla ": {},
"59/53. Egy\u00e9b szolg\u00e1ltat\u00e1sok k\u00f6lts\u00e9gei \u00e1tvezet\u00e9si sz\u00e1mla ": {},
"59/54. B\u00e9rk\u00f6lts\u00e9g \u00e1tvezet\u00e9si sz\u00e1mla": {},
"59/55. Szem\u00e9lyi jelleg\u0171 egy\u00e9b kifizet\u00e9sek \u00e1tvezet\u00e9si sz\u00e1mla ": {},
"59/56. B\u00e9rj\u00e1rul\u00e9kok \u00e1tvezet\u00e9si sz\u00e1mla": {},
"59/57. \u00c9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1s \u00e1tvezet\u00e9si sz\u00e1mla ": {}
},
"59. K\u00d6LTS\u00c9GNEM \u00c1TVEZET\u00c9SI SZ\u00c1MLA (kiz\u00e1r\u00f3lag k\u00f6lts\u00e9gnem-elsz\u00e1mol\u00e1s \u00e9s forgalmi k\u00f6lts\u00e9g elj\u00e1r\u00e1ssal)": {
"is_group": 1
},
"root_type": "Expense"
},
"6. SZ\u00c1MLAOSZT\u00c1LY K\u00d6LTS\u00c9GHELYEK, \u00c1LTAL\u00c1NOS K\u00d6LTS\u00c9GEK": {
"61. JAV\u00cdT\u00d3-KARBANTART\u00d3 \u00dcZEMEK K\u00d6LTS\u00c9GEI": {},
"62. SZOLG\u00c1LTAT\u00c1ST V\u00c9GZ\u00d5 \u00dcZEMEK (EGYS\u00c9GEK) K\u00d6LTS\u00c9GEI": {},
"63. G\u00c9PK\u00d6LTS\u00c9G": {},
"64-65. \u00dcZEMI IR\u00c1NY\u00cdT\u00c1S \u00c1LTAL\u00c1NOS K\u00d6LTS\u00c9GEI": {},
"66. K\u00d6ZPONTI IR\u00c1NY\u00cdT\u00c1S \u00c1LTL\u00c1NOS K\u00d6LTS\u00c9GEI": {},
"67. \u00c9RT\u00c9KES\u00cdT\u00c9SI, FORGALMAZ\u00c1SI K\u00d6LTS\u00c9GEK": {},
"68. ELK\u00dcL\u00d6N\u00cdTETT EGY\u00c9B \u00c1LTL\u00c1NOS K\u00d6LTS\u00c9GEK": {
"681. Alap\u00edt\u00e1s-\u00e1tszervez\u00e9s k\u00f6lts\u00e9gei": {},
"682. Alap- \u00e9s alkalmazott kutat\u00e1s saj\u00e1t k\u00f6lts\u00e9gei": {},
"683. V\u00e1llalkoz\u00e1sban adott alap- \u00e9s alkalmazott kutat\u00e1s k\u00f6lts\u00e9gei": {},
"684. K\u00eds\u00e9rleti fejleszt\u00e9s saj\u00e1t k\u00f6lts\u00e9gei": {},
"685. V\u00e1llalkoz\u00e1sba adott k\u00eds\u00e9rleti fejleszt\u00e9s k\u00f6lts\u00e9gei": {},
"686. Kutat\u00e1s-k\u00eds\u00e9rleti fejleszt\u00e9s \u00e1ltal\u00e1nos \u00e9s k\u00f6zvetett k\u00f6lts\u00e9gei": {},
"687. Kutat\u00e1s-k\u00eds\u00e9rleti fejleszt\u00e9s elsz\u00e1molt \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {},
"688. Garanci\u00e1lis jav\u00edt\u00e1s k\u00f6lts\u00e9gei": {},
"689. Egy\u00e9b elk\u00fcl\u00f6n\u00edtett k\u00f6lts\u00e9gek": {}
},
"69. K\u00d6LTS\u00c9GHELYEK K\u00d6LTS\u00c9GNEMEK \u00c1TVEZET\u00c9SE": {
"691. K\u00f6lts\u00e9ghelyek k\u00f6lts\u00e9geinek \u00e1tvezet\u00e9se": {}
},
"root_type": "Expense"
},
"7. SZ\u00c1MLAOSZT\u00c1LY TEV\u00c9KENYS\u00c9GEKK\u00d6LTS\u00c9GEI": {
"is_group": 1,
"root_type": "Expense"
},
"8. SZ\u00c1MLAOSZT\u00c1LY \u00c9RT\u00c9KES\u00cdT\u00c9S ELSZ\u00c1MOLT \u00d6NK\u00d6LTS\u00c9GE \u00c9S R\u00c1FORD\u00cdT\u00c1SOK": {
"81-83. SZ\u00c1MLACSOPORTOK (az \u00f6sszk\u00f6lts\u00e9g elj\u00e1r\u00e1ssal k\u00e9sz\u00fcl\u0151 eredm\u00e9ny-kimutat\u00e1shoz)": {
"81. ANYAGJELLEG\u00db R\u00c1FORD\u00cdT\u00c1SOK": {
"811. Anyagk\u00f6lts\u00e9g ": {},
"812. Ig\u00e9nybe vett szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9ke": {},
"813. Egy\u00e9b szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9ke": {},
"814. Eladott \u00e1ruk beszerz\u00e9si \u00e9rt\u00e9ke": {},
"815. Eladott (k\u00f6zvet\u00edtett) szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9ke": {}
},
"82. SZEM\u00c9LYI JELLEG\u00db R\u00c1FORD\u00cdT\u00c1SOK": {
"821. B\u00e9rk\u00f6lts\u00e9g": {},
"822. Szem\u00e9lyi jelleg\u0171 egy\u00e9b kifizet\u00e9sek": {},
"823. B\u00e9rj\u00e1rul\u00e9kok": {}
},
"83. \u00c9RT\u00c9KCS\u00d6KKEN\u00c9SI LE\u00cdR\u00c1S": {
"831. \u00c9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1s ": {}
}
},
"81-85. SZ\u00c1MLACSOPORTOK (a forgalmi k\u00f6lts\u00e9g elj\u00e1r\u00e1ssal k\u00e9sz\u00fcl\u0151 eredm\u00e9nykimutat\u00e1shoz)": {
"81-82. BELF\u00d6LDI \u00c9RT\u00c9KES\u00cdT\u00c9S K\u00d6ZVETLEN K\u00d6LTS\u00c9GEI": {
"811. Belf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9s elsz\u00e1molt k\u00f6zvetlen \u00f6nk\u00f6lts\u00e9ge": {
"account_type": "Cost of Goods Sold"
},
"812. Belf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9s eladott \u00e1ruk beszerz\u00e9si \u00e9rt\u00e9ke": {
"account_type": "Stock Adjustment"
},
"813. Belf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9s eladott (k\u00f6zvet\u00edtett) szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9ke": {
"account_type": "Expenses Included In Valuation"
}
},
"83-84. EXPORT\u00c9RT\u00c9KES\u00cdT\u00c9S K\u00d6ZVETLEN K\u00d6LTS\u00c9GEI": {
"831. Export\u00e9rt\u00e9kes\u00edt\u00e9s elsz\u00e1molt k\u00f6zvetlen \u00f6nk\u00f6lts\u00e9ge": {},
"832. Export\u00e9rt\u00e9kes\u00edt\u00e9s eladott \u00e1ruk beszerz\u00e9si \u00e9rt\u00e9ke": {},
"833. Export\u00e9rt\u00e9kes\u00edt\u00e9s eladott (k\u00f6zvet\u00edtett) szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9ke": {}
},
"85. \u00c9RT\u00c9KES\u00cdT\u00c9S K\u00d6ZVETETT K\u00d6LTS\u00c9GEI": {
"851. \u00c9rt\u00e9kes\u00edt\u00e9si, forgalmaz\u00e1si k\u00f6lts\u00e9gek": {},
"852. Igazgat\u00e1si k\u00f6lts\u00e9gek": {},
"853. Egy\u00e9b \u00e1ltal\u00e1nos k\u00f6lts\u00e9gek": {}
}
},
"86. EGY\u00c9B R\u00c1FORD\u00cdT\u00c1SOK": {
"861. Egy\u00e9b r\u00e1ford\u00edt\u00e1snak min\u0151s\u00fcl\u0151 \u00e9rt\u00e9kes\u00edt\u00e9sek": {
"8611. \u00c9rt\u00e9kes\u00edtett immateri\u00e1lis javak, t\u00e1rgyi eszk\u00f6z\u00f6k k\u00f6nyv szerinti \u00e9rt\u00e9ke": {},
"8612. \u00c9rt\u00e9kes\u00edtett, \u00e1truh\u00e1zott (engedm\u00e9nyezett) k\u00f6vetel\u00e9sek k\u00f6nyv szerinti \u00e9rt\u00e9ke": {}
},
"862. Egy\u00e9b r\u00e1ford\u00edt\u00e1snak min\u0151s\u00fcl\u0151 eszk\u00f6z kivezet\u00e9sek": {
"8621. Hi\u00e1nyz\u00f3, megsemmis\u00fclt, kiselejtezett immateri\u00e1lis javak, t\u00e1rgyi eszk\u00f6z\u00f6k nett\u00f3 \u00e9rt\u00e9ke": {},
"8622. Hi\u00e1nyz\u00f3, megsemmis\u00fclt, \u00e1llom\u00e1nyb\u00f3l kivezetett k\u00e9szletek k\u00f6nyv szerinti \u00e9rt\u00e9ke": {}
},
"863. Behajthatatlan k\u00f6vetel\u00e9sek le\u00edrt \u00f6sszege": {},
"864. C\u00e9ltartal\u00e9k k\u00e9pz\u00e9s": {
"8641. C\u00e9ltartal\u00e9k-k\u00e9pz\u00e9s a v\u00e1rhat\u00f3 k\u00f6telezetts\u00e9gekre": {},
"8642. C\u00e9ltartal\u00e9k-k\u00e9pz\u00e9s a j\u00f6v\u0151beni k\u00f6lts\u00e9gekre": {},
"8643. C\u00e9ltartal\u00e9k-k\u00e9pz\u00e9s egy\u00e9b c\u00edmen": {}
},
"865. Ut\u00f3lag adott, nem sz\u00e1ml\u00e1zott engedm\u00e9ny": {},
"866. Egy\u00e9b r\u00e1ford\u00edt\u00e1sk\u00e9nt elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {
"8661. K\u00f6zponti k\u00f6lts\u00e9gvet\u00e9ssel elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {},
"8662. Helyi \u00f6nkorm\u00e1nyzatokkal elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {},
"8663. Elk\u00fcl\u00f6n\u00edtett \u00e1llami p\u00e9nzalapokkal elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {},
"8664. T\u00e1rsadalombiztos\u00edt\u00e1ssal elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {},
"8665. EU p\u00e9nz\u00fcgyi alapokkal elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {},
"8666. R\u00e1ford\u00edt\u00e1sk\u00e9nt elsz\u00e1molt egy\u00e9b ad\u00f3k \u00e9s ad\u00f3jelleg\u0171 t\u00e9telek": {}
},
"867. Egy\u00e9b r\u00e1ford\u00edt\u00e1sk\u00e9nt elsz\u00e1molt, ad\u00f3nak nem min\u0151s\u00fcl\u0151 kifizet\u00e9sek": {
"8671. K\u00e1resem\u00e9nnyel kapcsolatos fizetett, fizetend\u0151 \u00f6sszegek": {},
"8672. K\u00f6lts\u00e9gek (r\u00e1ford\u00edt\u00e1sok) ellent\u00e9telez\u00e9s\u00e9re visszafizet\u00e9si k\u00f6telezetts\u00e9g n\u00e9lk\u00fcl adott t\u00e1mogat\u00e1s, juttat\u00e1": {},
"8673. Fejleszt\u00e9si c\u00e9lra, visszafizet\u00e9si k\u00f6telezetts\u00e9g n\u00e9lk\u00fcl adott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
"8674. Fejleszt\u00e9si c\u00e9lra kapott t\u00e1mogat\u00e1s visszafizetend\u0151 \u00f6sszege": {},
"8675. Tao \u00e1ltal elismert b\u00edrs\u00e1gok, k\u00f6tb\u00e9rek, k\u00e9sedelmi kamatok, p\u00f3tl\u00e9kok, k\u00e1rt\u00e9r\u00edt\u00e9sek, s\u00e9relemd\u00edjak": {},
"8676. Tao \u00e1ltal el nem ismert b\u00edrs\u00e1gok, k\u00f6tb\u00e9rek, k\u00e9sedelmi kamatok, p\u00f3tl\u00e9kok, k\u00e1rt\u00e9r\u00edt\u00e9sek, s\u00e9relemd\u00edjak": {}
},
"868. Terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9sek, \u00e9rt\u00e9kveszt\u00e9sek": {
"8681. Immateri\u00e1lis javak terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {},
"8682. T\u00e1rgyi eszk\u00f6z\u00f6k terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {},
"8683. K\u00e9szletek \u00e9rt\u00e9kveszt\u00e9se": {},
"8684. K\u00f6vetel\u00e9sek \u00e9rt\u00e9kveszt\u00e9se": {}
},
"869. K\u00fcl\u00f6nf\u00e9le egy\u00e9b r\u00e1ford\u00edt\u00e1sok": {
"8691. T\u00e1rsas\u00e1gba bevitt, \u00e9rt\u00e9kpap\u00edrnak vagy r\u00e9szesed\u00e9snek nem min\u0151s\u00fcl\u0151 vagyont. k\u00f6nyv szerinti \u00e9s l\u00e9t. okir. meghat. veszt. k\u00fcl\u00f6nb\u00f6zet": {},
"8692. Ellent\u00e9telez\u00e9s n\u00e9lk\u00fcl \u00e1tv\u00e1llalt k\u00f6telezetts\u00e9g szerz\u0151d\u00e9s szerinti \u00f6sszege": {},
"8693. T\u00e9r\u00edt\u00e9s n\u00e9lk\u00fcl \u00e1tadott, r\u00e9szesed\u00e9snek vagy \u00e9rt\u00e9kpap\u00edrnak nem min\u0151s\u00fcl\u0151 eszk\u00f6z\u00f6k nyilv\u00e1ntart\u00e1s szerinti \u00e9rt\u00e9ke": {},
"8694. T\u00e9r\u00edt\u00e9s n\u00e9lk\u00fcl ny\u00fajtott szolg\u00e1ltat\u00e1sok beker\u00fcl\u00e9si \u00e9rt\u00e9ke": {},
"8695. Elengedett k\u00f6vetel\u00e9sek k\u00f6nyv szerinti \u00e9rt\u00e9ke": {},
"8696. Egy\u00e9b, vagyoncs\u00f6kken\u00e9ssel j\u00e1r\u00f3 r\u00e1ford\u00edt\u00e1sok": {}
}
},
"87. P\u00c9NZ\u00dcGYI M\u0170VELETEK R\u00c1FORD\u00cdT\u00c1SAI": {
"871. R\u00e9szesed\u00e9sekb\u0151l sz\u00e1rmaz\u00f3 r\u00e1ford\u00edt\u00e1sok, \u00e1rfolyamvesztes\u00e9gek": {},
"872. Befektetett p\u00e9nz\u00fcgyi eszk\u00f6z\u00f6kb\u0151l (\u00e9rt\u00e9kpap\u00edrokb\u00f3l, k\u00f6lcs\u00f6n\u00f6kb\u0151l) sz\u00e1rmaz\u00f3 r\u00e1ford\u00edt\u00e1sok \u00e1rfolyamvesztes\u00e9gek": {},
"873. Hitelint\u00e9zetnek fizetend\u0151 kamatok \u00e9s kamatjelleg\u0171 r\u00e1ford\u00edt\u00e1sok": {},
"874. Nem hitelint\u00e9zetnek fizetend\u0151 kamatok \u00e9s kamatjelleg\u0171 r\u00e1ford\u00edt\u00e1sok": {},
"875. R\u00e9szesed\u00e9sek, \u00e9rt\u00e9kpap\u00edrok, bankbet\u00e9tek \u00e9rt\u00e9kveszt\u00e9se \u00e9s vissza\u00edr\u00e1sa": {
"8751. R\u00e9szesed\u00e9sek, \u00e9rt\u00e9kpap\u00edrok, bankbet\u00e9tek \u00e9rt\u00e9kveszt\u00e9se": {},
"8752. R\u00e9szesed\u00e9sek, \u00e9rt\u00e9kpap\u00edrok, bankbet\u00e9tek \u00e9rt\u00e9kveszt\u00e9s\u00e9nek vissza\u00edr\u00e1sa": {}
},
"876. K\u00fclf\u00f6ldi p\u00e9nz\u00e9rt\u00e9kre sz\u00f3l\u00f3 eszk\u00f6z\u00f6k \u00e9s k\u00f6telezetts\u00e9gek \u00e1rfolyamvesztes\u00e9gei": {
"8761. Deviza- \u00e9s valutak\u00e9szletek forintra \u00e1tv\u00e1lt\u00e1s\u00e1nak \u00e1rfolyamvesztes\u00e9ge": {},
"8762. K\u00fclf\u00f6ldi p\u00e9nz\u00e9rt\u00e9kre sz\u00f3l\u00f3 eszk\u00f6z\u00f6k \u00e9s k\u00f6telezetts\u00e9gek p\u00e9nz\u00fcgyileg rendezett \u00e1rfolyamvesztes\u00e9ge": {}
},
"877. P\u00e9nz\u00fcgyi m\u0171veletek egy\u00e9b r\u00e1ford\u00edt\u00e1sai": {},
"878. P\u00e9nz\u00fcgyi rendez\u00e9shez kapcsol\u00f3d\u00f3an adott engedm\u00e9ny": {},
"879. Egy\u00e9b vagyoncs\u00f6kken\u00e9ssel j\u00e1r\u00f3 p\u00e9nz\u00fcgyi r\u00e1ford\u00edt\u00e1sok": {}
},
"88. RENDK\u00cdV\u00dcLI R\u00c1FORD\u00cdT\u00c1SOK": {
"881. T\u00e1rsas\u00e1gba bevitt eszk\u00f6z\u00f6k nyilv\u00e1ntart\u00e1s szerinti \u00e9rt\u00e9ke": {}
},
"89. EREDM\u00c9NYT TERHEL\u0150 AD\u00d3K": {
"891. T\u00e1rsas\u00e1gi ad\u00f3": {},
"892. Egyszer\u0171s\u00edtett v\u00e1llalkoz\u00f3i ad\u00f3": {},
"893. Kisv\u00e1llalati ad\u00f3": {},
"899. Eredm\u00e9nyt terhel\u0151 egy\u00e9b ad\u00f3k": {}
},
"root_type": "Expense"
},
"9. SZ\u00c1MLAOSZT\u00c1LY BEV\u00c9TELEK": {
"91. BELF\u00d6LDI \u00c9RT\u00c9KES\u00cdT\u00c9S \u00c1RBEV\u00c9TELE": {
"911. Belf\u00f6ldinek \u00e9rt\u00e9kes\u00edtett saj\u00e1t termel\u00e9s\u0171 k\u00e9szletek \u00e1rbev\u00e9tele": {},
"912. Belf\u00f6ldinek \u00e9rt\u00e9kes\u00edtett v\u00e1s\u00e1rolt k\u00e9szletek \u00e1rbev\u00e9tele": {},
"913. Belf\u00f6ldinek ny\u00fajtott szolg\u00e1ltat\u00e1sok \u00e1rbev\u00e9tele": {},
"918. Belf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9ssel kapcsolatos \u00e1rt\u00e1mogat\u00e1s": {},
"919. Egy\u00e9b belf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9s \u00e1rbev\u00e9tele": {}
},
"92. EXPORT\u00c9RT\u00c9KES\u00cdT\u00c9S \u00c1RBEV\u00c9TELE": {
"921. K\u00fclf\u00f6ldinek \u00e9rt\u00e9kes\u00edtett saj\u00e1t termel\u00e9s\u0171 k\u00e9szletek \u00e1rbev\u00e9tele": {},
"922. K\u00fclf\u00f6ldinek \u00e9rt\u00e9kes\u00edtett v\u00e1s\u00e1rolt k\u00e9szletek \u00e1rbev\u00e9tele": {},
"923. K\u00fclf\u00f6ldinek ny\u00fajtott szolg\u00e1ltat\u00e1sok \u00e1rbev\u00e9tele": {},
"928. K\u00fclf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9ssel kapcsolatos \u00e1rt\u00e1mogat\u00e1s": {},
"929. Egy\u00e9b k\u00fclf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9s \u00e1rbev\u00e9tele": {}
},
"96. EGY\u00c9B BEV\u00c9TELEK": {
"961. Egy\u00e9b bev\u00e9telnek min\u0151s\u00fcl\u0151 \u00e9rt\u00e9kes\u00edt\u00e9sek": {
"9611. \u00c9rt\u00e9kes\u00edtett immateri\u00e1lis javak, t\u00e1rgyi eszk\u00f6z\u00f6k ellen\u00e9rt\u00e9ke": {},
"9612. \u00c9rt\u00e9kes\u00edtett, \u00e1truh\u00e1zott (engedm\u00e9nyezett) k\u00f6vetel\u00e9sek ellen\u00e9rt\u00e9ke": {}
},
"963. K\u00f6vetel\u00e9s k\u00f6nyv szerinti \u00e9rt\u00e9k\u00e9t meghalad\u00f3an realiz\u00e1lt \u00f6sszeg": {},
"964. C\u00e9ltartal\u00e9k felold\u00e1s": {
"9651. V\u00e1rhat\u00f3 k\u00f6telezetts\u00e9gek fedezet\u00e9re k\u00e9pzett c\u00e9ltartal\u00e9k felhaszn\u00e1l\u00e1sa ": {},
"9652. J\u00f6v\u0151beni k\u00f6lts\u00e9gekre k\u00e9pzett c\u00e9ltartal\u00e9k felhaszn\u00e1l\u00e1sa ": {},
"9653. Egy\u00e9b c\u00edmen k\u00e9pzett c\u00e9ltartal\u00e9k felhaszn\u00e1l\u00e1sa ": {}
},
"965. Ut\u00f3lag kapott, nem sz\u00e1ml\u00e1zott engedm\u00e9ny": {},
"966. Ut\u00f3lag kapott, nem sz\u00e1ml\u00e1zott engedm\u00e9ny": {
"9661. K\u00f6zponti k\u00f6lts\u00e9gvet\u00e9sb\u0151l kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
"9662. Helyi \u00f6nkorm\u00e1nyzatokt\u00f3l kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
"9663. Eur\u00f3pai Uni\u00f3t\u00f3l kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
"9664. Egy\u00e9b forr\u00e1sb\u00f3l kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {}
},
"967. Egy\u00e9b bev\u00e9telk\u00e9nt elsz\u00e1molt p\u00e9nzbev\u00e9telek": {
"9671. K\u00e1resem\u00e9nnyel kapcsolatos t\u00e9r\u00edt\u00e9sek": {},
"9672. K\u00f6lts\u00e9gek (r\u00e1ford\u00edt\u00e1sok) ellent\u00e9telez\u00e9s\u00e9re kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
"9673. Fejleszt\u00e9si c\u00e9lra kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
"9674. Kapott b\u00edrs\u00e1gok, k\u00f6tb\u00e9rek, fekb\u00e9rek, k\u00e9sedelmi kamatok, k\u00e1rt\u00e9r\u00edt\u00e9sek": {}
},
"968. Terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9sek, \u00e9rt\u00e9kveszt\u00e9sek vissza\u00edr\u00e1sa": {
"9681. Immateri\u00e1lis javak terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9s\u00e9nek vissza\u00edr\u00e1sa": {},
"9682. T\u00e1rgyi eszk\u00f6z\u00f6k terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9s\u00e9nek vissza\u00edr\u00e1sa": {},
"9683. K\u00e9szletek \u00e9rt\u00e9kveszt\u00e9s\u00e9nek vissza\u00edr\u00e1sa": {},
"9684. R\u00e9szesed\u00e9sek \u00e9rt\u00e9kveszt\u00e9s\u00e9nek vissza\u00edr\u00e1sa": {}
},
"969. K\u00fcl\u00f6nf\u00e9le egy\u00e9b bev\u00e9telek": {
"9691. Gazdas\u00e1gi t\u00e1rsas\u00e1gba bevitt, \u00e9rt\u00e9kp. vagy r\u00e9szesed\u00e9snek nem min\u0151s\u00fcl\u0151 vagyont. \u00e9rt\u00e9ke \u00e9s l\u00e9tes\u00edt\u0151 okir. \u00e9rt. nyer. jell . k\u00fcl\u00f6nb.": {},
"9692. El\u00e9v\u00fclt k\u00f6telezetts\u00e9g k\u00f6nyv szerinti \u00e9rt\u00e9ke": {},
"9693. T\u00e9r\u00edt\u00e9s n\u00e9lk\u00fcl \u00e1tvett, aj\u00e1nd\u00e9kk\u00e9nt, hagyat\u00e9kk\u00e9nt kapott, fellelt eszk\u00f6z\u00f6k piaci vagy jogszab\u00e1ly szerinti \u00e9rt\u00e9ke": {},
"9694. T\u00e9r\u00edt\u00e9s n\u00e9lk\u00fcl kapott szolg\u00e1ltat\u00e1sok piaci vagy jogszab\u00e1ly szerinti \u00e9rt\u00e9ke": {},
"9695. Elengedett \u00e9s ellent\u00e9telez\u00e9s n\u00e9lk\u00fcl \u00e1tv\u00e1llalt k\u00f6telezetts\u00e9g \u00e9rt\u00e9ke": {},
"9696. Egy\u00e9b, vagyonn\u00f6veked\u00e9ssel j\u00e1r\u00f3 bev\u00e9telek": {}
}
},
"97. P\u00c9NZ\u00dcGYI M\u0170VELETEK BEV\u00c9TELEI": {
"971. R\u00e9szesed\u00e9sekb\u0151l sz\u00e1rmaz\u00f3 bev\u00e9telek, \u00e1rfolyamnyeres\u00e9gek": {},
"972. Befektetett p\u00e9nz\u00fcgyi eszk\u00f6z\u00f6kb\u0151l (\u00e9rt\u00e9kpap\u00edrokb\u00f3l, k\u00f6lcs\u00f6n\u00f6kb\u0151l) sz\u00e1rmaz\u00f3 bev\u00e9telek, \u00e1rfolyamnyeres\u00e9gek": {},
"973. Hitelint\u00e9zett\u0151l kapott kamatok \u00e9s kamatjelleg\u0171 bev\u00e9telek": {},
"974. Nem hitelint\u00e9zett\u0151l kapott kamatok \u00e9s kamatjelleg\u0171 bev\u00e9telek": {},
"975. Kapott (j\u00e1r\u00f3) osztal\u00e9k \u00e9s r\u00e9szesed\u00e9s": {},
"976. K\u00fclf\u00f6ldi p\u00e9nz\u00e9rt\u00e9kre sz\u00f3l\u00f3 eszk\u00f6z\u00f6k \u00e9s k\u00f6telezetts\u00e9gek \u00e1rfolyamnyeres\u00e9gei": {
"9761. Deviza- \u00e9s valutak\u00e9szletek forintra \u00e1tv\u00e1lt\u00e1s\u00e1nak \u00e1rfolyamnyeres\u00e9ge": {},
"9762. K\u00fclf\u00f6ldi p\u00e9nz\u00e9rt\u00e9kre sz\u00f3l\u00f3 eszk\u00f6z\u00f6k \u00e9s k\u00f6telezetts\u00e9gek p\u00e9nz\u00fcgyileg rendezett \u00e1rfolyamnyeres\u00e9ge": {}
},
"977. P\u00e9nz\u00fcgyi m\u0171veletek egy\u00e9b bev\u00e9telei": {},
"978. P\u00e9nz\u00fcgyi rendez\u00e9shez kapcsol\u00f3d\u00f3an kapott engedm\u00e9ny": {},
"979. Egy\u00e9b vagyonn\u00f6veked\u00e9ssel j\u00e1r\u00f3 p\u00e9nz\u00fcgyi bev\u00e9telek": {}
},
"root_type": "Income"
}
}
}

View File

@@ -0,0 +1,722 @@
{
"country_code": "tw",
"name": "Taiwan - Chart of Accounts",
"tree": {
"1-\u8cc7\u7522": {
"11~12-\u6d41\u52d5\u8cc7\u7522": {
"111-\u73fe\u91d1\u53ca\u7d04\u7576\u73fe\u91d1": {
"1111-\u5eab\u5b58\u73fe\u91d1": {
"account_type": "Cash"
},
"1112-\u96f6\u7528\u91d1/\u9031\u8f49\u91d1": {
"account_type": "Cash"
},
"1113-\u9280\u884c\u5b58\u6b3e": {
"account_type": "Bank",
"\u4e2d\u570b\u4fe1\u8a17": {
"account_type": "Bank"
},
"\u53f0\u5317\u5bcc\u90a6": {
"account_type": "Bank"
}
},
"1116-\u5728\u9014\u73fe\u91d1": {
"account_type": "Cash"
},
"1117-\u7d04\u7576\u73fe\u91d1": {
"account_type": "Cash"
},
"1118-\u5176\u4ed6\u73fe\u91d1\u53ca\u7d04\u7576\u73fe\u91d1": {
"account_type": "Cash"
},
"account_type": "Cash"
},
"112-\u77ed\u671f\u6295\u8cc7": {
"1121-\u77ed\u671f\u6295\u8cc7 \u2014\u80a1\u7968": {}
},
"113-\u61c9\u6536\u7968\u64da": {
"1131-\u61c9\u6536\u7968\u64da": {
"account_type": "Receivable"
},
"1132-\u61c9\u6536\u7968\u64da\u8cbc\u73fe ": {
"account_type": "Receivable"
},
"1138-\u5176\u4ed6\u61c9\u6536\u7968\u64da ": {
"account_type": "Receivable"
},
"1139-\u5099\u62b5\u5446\u5e33 \uff0d\u61c9\u6536\u7968\u64da ": {
"account_type": "Receivable"
},
"account_type": "Receivable"
},
"114-\u61c9\u6536\u5e33\u6b3e": {
"1141-\u61c9\u6536\u5e33\u6b3e ": {
"account_type": "Receivable"
},
"1142-\u61c9\u6536\u5206\u671f\u5e33\u6b3e ": {
"account_type": "Receivable"
},
"1149-\u5099\u62b5\u5446\u5e33 \uff0d\u61c9\u6536\u5e33\u6b3e ": {
"account_type": "Receivable"
},
"account_type": "Receivable"
},
"118-\u5176\u4ed6\u61c9\u6536\u6b3e": {
"1184-\u61c9\u6536\u6536\u76ca": {
"account_type": "Receivable"
},
"1185-\u61c9\u6536\u9000\u7a05\u6b3e": {
"account_type": "Receivable"
},
"1189-\u5099\u62b5\u5446\u5e33 \u2014 \u5176\u4ed6\u61c9\u6536\u6b3e ": {
"account_type": "Receivable"
},
"account_type": "Receivable"
},
"121~122-\u5b58\u8ca8": {
"1219-\u5099\u62b5\u5b58\u8ca8\u8dcc\u50f9\u640d\u5931": {},
"1229-\u5099\u62b5\u5b58\u8ca8\u8dcc\u50f9\u640d\u5931": {},
"account_type": "Stock",
"is_group": 1
},
"125-\u9810\u4ed8\u8cbb\u7528": {
"1251-\u9810\u4ed8\u85aa\u8cc7": {},
"1252-\u9810\u4ed8\u79df\u91d1": {},
"1253-\u9810\u4ed8\u4fdd\u96aa\u8cbb": {},
"1254-\u7528\u54c1\u76e4\u5b58": {},
"1255-\u9810\u4ed8\u6240\u5f97\u7a05": {},
"1258-\u5176\u4ed6\u9810\u4ed8\u8cbb\u7528": {}
},
"126-\u9810\u4ed8\u6b3e\u9805": {
"1261-\u9810\u4ed8\u8ca8\u6b3e": {},
"1268-\u5176\u4ed6\u9810\u4ed8\u6b3e\u9805": {}
},
"128~129-\u5176\u4ed6\u6d41\u52d5\u8cc7\u7522": {
"1281-\u9032\u9805\u7a05\u984d": {},
"1282-\u7559\u62b5\u7a05\u984d": {},
"1283-\u66ab\u4ed8\u6b3e": {},
"1284-\u4ee3\u4ed8\u6b3e": {},
"1285-\u54e1\u5de5\u501f\u652f": {}
}
},
"13-\u57fa\u91d1\u53ca\u9577\u671f\u6295\u8cc7": {
"131-\u57fa\u91d1": {
"1311-\u511f\u50b5\u57fa\u91d1": {},
"1313-\u610f\u5916\u640d\u5931\u6e96\u5099\u57fa\u91d1": {},
"1314-\u9000\u4f11\u57fa\u91d1": {},
"1318-\u5176\u4ed6\u57fa\u91d1": {}
},
"132-\u9577\u671f\u6295\u8cc7": {
"1321-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7": {},
"1322-\u9577\u671f\u50b5\u5238\u6295\u8cc7": {},
"1323-\u9577\u671f\u4e0d\u52d5\u7522\u6295\u8cc7": {},
"1328-\u5176\u4ed6\u9577\u671f\u6295\u8cc7": {}
}
},
"14~15-\u56fa\u5b9a\u8cc7\u7522": {
"141-\u571f\u5730": {
"1411-\u571f\u5730": {
"account_type": "Fixed Asset"
},
"account_type": "Fixed Asset"
},
"142-\u571f\u5730\u6539\u826f\u7269": {
"1421-\u571f\u5730\u6539\u826f\u7269": {
"account_type": "Fixed Asset"
},
"account_type": "Fixed Asset"
},
"143-\u623f\u5c4b\u53ca\u5efa\u7269": {
"1431-\u623f\u5c4b\u53ca\u5efa\u7269": {
"account_type": "Fixed Asset"
},
"account_type": "Fixed Asset"
},
"144~146-\u6a5f(\u5668)\u5177\u53ca\u8a2d\u5099": {
"1441-\u6a5f(\u5668)\u5177": {
"account_type": "Fixed Asset"
},
"account_type": "Fixed Asset"
},
"151-\u79df\u8cc3\u8cc7\u7522": {
"1511-\u79df\u8cc3\u8cc7\u7522": {
"account_type": "Fixed Asset"
},
"account_type": "Fixed Asset"
},
"152-\u79df\u8cc3\u6b0a\u76ca\u6539\u826f": {
"1521-\u79df\u8cc3\u6b0a\u76ca\u6539\u826f": {
"account_type": "Fixed Asset"
},
"account_type": "Fixed Asset"
},
"156-\u672a\u5b8c\u5de5\u7a0b\u53ca\u9810\u4ed8\u8cfc\u7f6e\u8a2d\u5099\u6b3e": {
"1561-\u672a\u5b8c\u5de5\u7a0b": {
"account_type": "Fixed Asset"
},
"account_type": "Fixed Asset"
},
"158-\u96dc\u9805\u56fa\u5b9a\u8cc7\u7522": {
"1581-\u96dc\u9805\u56fa\u5b9a\u8cc7\u7522": {
"account_type": "Fixed Asset"
},
"account_type": "Fixed Asset"
},
"account_type": "Fixed Asset"
},
"16-\u905e\u8017\u8cc7\u7522": {
"161-\u905e\u8017\u8cc7\u7522": {
"is_group": 1
}
},
"17-\u7121\u5f62\u8cc7\u7522": {
"171-\u5546\u6a19\u6b0a": {
"1711-\u5546\u6a19\u6b0a": {}
},
"172-\u5c08\u5229\u6b0a": {
"1721-\u5c08\u5229\u6b0a": {}
},
"176-\u5546\u8b7d": {
"1761-\u5546\u8b7d": {}
},
"177-\u958b\u8fa6\u8cbb": {
"1771-\u958b\u8fa6\u8cbb": {}
},
"178-\u5176\u4ed6\u7121\u5f62\u8cc7\u7522": {
"1781-\u905e\u5ef6\u9000\u4f11\u91d1\u6210\u672c": {}
}
},
"18-\u5176\u4ed6\u8cc7\u7522": {
"181-\u905e\u5ef6\u8cc7\u7522": {
"1811-\u50b5\u5238\u767c\u884c\u6210\u672c": {},
"1812-\u9577\u671f\u9810\u4ed8\u79df\u91d1": {},
"1813-\u9577\u671f\u9810\u4ed8\u4fdd\u96aa\u8cbb": {},
"1814-\u905e\u5ef6\u6240\u5f97\u7a05\u8cc7\u7522": {},
"1815-\u9810\u4ed8\u9000\u4f11\u91d1": {},
"1818-\u5176\u4ed6\u905e\u5ef6\u8cc7\u7522": {}
},
"182-\u9592\u7f6e\u8cc7\u7522": {
"1821-\u9592\u7f6e\u8cc7\u7522": {}
},
"184-\u9577\u671f\u61c9\u6536\u7968\u64da\u53ca\u6b3e\u9805\u8207\u50ac\u6536\u5e33\u6b3e": {
"1841-\u9577\u671f\u61c9\u6536\u7968\u64da": {
"account_type": "Receivable"
},
"1842-\u9577\u671f\u61c9\u6536\u5e33\u6b3e": {
"account_type": "Receivable"
},
"1843-\u50ac\u6536\u5e33\u6b3e": {
"account_type": "Receivable"
},
"1848-\u5176\u4ed6\u9577\u671f\u61c9\u6536\u6b3e\u9805": {
"account_type": "Receivable"
},
"1849-\u5099\u62b5\u5446\u5e33\u2014\u9577\u671f\u61c9\u6536\u7968\u64da\u53ca\u6b3e\u9805\u8207\u50ac\u6536\u5e33\u6b3e": {
"account_type": "Receivable"
},
"account_type": "Receivable"
},
"185-\u51fa\u79df\u8cc7\u7522": {
"1851-\u51fa\u79df\u8cc7\u7522": {},
"1858-\u51fa\u79df\u8cc7\u7522 \u2014\u91cd\u4f30\u589e\u503c": {},
"1859-\u7d2f\u7a4d\u6298\u820a \u2014\u51fa\u79df\u8cc7\u7522": {
"account_type": "Accumulated Depreciation"
}
},
"186-\u5b58\u51fa\u4fdd\u8b49\u91d1": {
"1861-\u5b58\u51fa\u4fdd\u8b49\u91d1": {}
},
"188-\u96dc\u9805\u8cc7\u7522": {
"1881-\u53d7\u9650\u5236\u5b58\u6b3e": {},
"1888-\u96dc\u9805\u8cc7\u7522 \u2014\u5176\u4ed6": {}
}
},
"Temporary Accounts": {
"Temporary Opening": {
"account_type": "Temporary"
},
"account_type": "Temporary"
},
"root_type": "Asset"
},
"2-\u8ca0\u50b5": {
"21~22-\u6d41\u52d5\u8ca0\u50b5": {
"211-\u77ed\u671f\u501f\u6b3e": {
"2111-\u9280\u884c\u900f\u652f": {},
"2112-\u9280\u884c\u501f\u6b3e": {}
},
"212-\u61c9\u4ed8\u77ed\u671f\u7968\u5238": {
"2121-\u61c9\u4ed8\u5546\u696d\u672c\u7968": {
"account_type": "Payable"
},
"2122-\u9280\u884c\u627f\u514c\u532f\u7968": {
"account_type": "Payable"
},
"account_type": "Payable"
},
"213-\u61c9\u4ed8\u7968\u64da": {
"2131-\u61c9\u4ed8\u7968\u64da": {
"account_type": "Payable"
},
"account_type": "Payable"
},
"214-\u61c9\u4ed8\u5e33\u6b3e": {
"2141-\u61c9\u4ed8\u5e33\u6b3e": {
"account_type": "Payable"
},
"account_type": "Payable"
},
"216-\u61c9\u4ed8\u6240\u5f97\u7a05": {
"2161-\u61c9\u4ed8\u6240\u5f97\u7a05": {
"account_type": "Tax",
"tax_rate": 5.0
},
"account_type": "Tax",
"tax_rate": 5.0
},
"217-\u61c9\u4ed8\u8cbb\u7528": {
"2171-\u61c9\u4ed8\u85aa\u5de5": {},
"2172-\u61c9\u4ed8\u79df\u91d1": {},
"2173-\u61c9\u4ed8\u5229\u606f": {},
"2174-\u61c9\u4ed8\u71df\u696d\u7a05": {},
"2175-\u61c9\u4ed8\u7a05\u6350 \u2014\u5176\u4ed6": {
"account_type": "Tax",
"tax_rate": 5.0
},
"2178-\u5176\u4ed6\u61c9\u4ed8\u8cbb\u7528": {}
},
"218~219-\u5176\u4ed6\u61c9\u4ed8\u6b3e": {
"2184-\u61c9\u4ed8\u571f\u5730\u623f\u5c4b\u6b3e": {},
"2185-\u61c9\u4ed8\u8a2d\u5099\u6b3e": {},
"2192-\u61c9\u4ed8\u80a1\u5229": {}
},
"226-\u9810\u6536\u6b3e\u9805": {
"2261-\u9810\u6536\u8ca8\u6b3e": {},
"2262-\u9810\u6536\u6536\u5165": {},
"2268-\u5176\u4ed6\u9810\u6536\u6b3e": {}
},
"227-\u4e00\u5e74\u6216\u4e00\u71df\u696d\u9031\u671f\u5167\u5230\u671f\u9577\u671f\u8ca0\u50b5": {
"is_group": 1
},
"228~229-\u5176\u4ed6\u6d41\u52d5\u8ca0\u50b5": {
"2281-\u92b7\u9805\u7a05\u984d": {},
"2283-\u66ab\u6536\u6b3e ": {},
"2284-\u4ee3\u6536\u6b3e": {},
"2285-\u4f30\u8a08\u552e\u5f8c\u670d\u52d9/\u4fdd\u56fa\u8ca0\u50b5": {},
"2291-\u905e\u5ef6\u6240\u5f97\u7a05\u8ca0\u50b5": {},
"2292-\u905e\u5ef6\u514c\u63db\u5229\u76ca": {}
}
},
"23-\u9577\u671f\u8ca0\u50b5": {
"231-\u61c9\u4ed8\u516c\u53f8\u50b5": {
"2311-\u61c9\u4ed8\u516c\u53f8\u50b5": {},
"2319-\u61c9\u4ed8\u516c\u53f8\u50b5\u6ea2(\u6298)\u50f9": {}
},
"232-\u9577\u671f\u501f\u6b3e": {
"2321-\u9577\u671f\u9280\u884c\u501f\u6b3e": {},
"2324-\u9577\u671f\u501f\u6b3e \u2014\u696d\u4e3b": {},
"2325-\u9577\u671f\u501f\u6b3e \u2014\u54e1\u5de5": {},
"2327-\u9577\u671f\u501f\u6b3e \u2014\u95dc\u4fc2\u4eba": {},
"2328-\u9577\u671f\u501f\u6b3e \u2014\u5176\u4ed6": {}
},
"233-\u9577\u671f\u61c9\u4ed8\u7968\u64da\u53ca\u6b3e\u9805": {
"2331-\u9577\u671f\u61c9\u4ed8\u7968\u64da": {
"account_type": "Payable"
},
"2332-\u9577\u671f\u61c9\u4ed8\u5e33\u6b3e": {
"account_type": "Payable"
},
"2333-\u9577\u671f\u61c9\u4ed8\u79df\u8cc3\u8ca0\u50b5": {
"account_type": "Payable"
},
"account_type": "Payable"
},
"234-\u4f30\u8a08\u61c9\u4ed8\u571f\u5730\u589e\u503c\u7a05": {
"2341-\u4f30\u8a08\u61c9\u4ed8\u571f\u5730\u589e\u503c\u7a05": {}
},
"235-\u61c9\u8a08\u9000\u4f11\u91d1\u8ca0\u50b5": {
"2351-\u61c9\u8a08\u9000\u4f11\u91d1\u8ca0\u50b5": {}
},
"238-\u5176\u4ed6\u9577\u671f\u8ca0\u50b5": {
"2388-\u5176\u4ed6\u9577\u671f\u8ca0\u50b5\u2014\u5176\u4ed6": {}
}
},
"28-\u5176\u4ed6\u8ca0\u50b5": {
"281-\u905e\u5ef6\u8ca0\u50b5": {
"2811-\u905e\u5ef6\u6536\u5165": {},
"2814-\u905e\u5ef6\u6240\u5f97\u7a05\u8ca0\u50b5": {},
"2818-\u5176\u4ed6\u905e\u5ef6\u8ca0\u50b5": {}
},
"286-\u5b58\u5165\u4fdd\u8b49\u91d1": {
"2861-\u5b58\u5165\u4fdd\u8b49\u91d1": {}
},
"288-\u96dc\u9805\u8ca0\u50b5": {
"2888-\u96dc\u9805\u8ca0\u50b5 \u2014\u5176\u4ed6": {}
}
},
"Stock Received But Not Billed": {
"account_type": "Stock Received But Not Billed"
},
"root_type": "Liability"
},
"3-\u696d\u4e3b\u6b0a\u76ca": {
"31-\u8cc7\u672c": {
"311-\u8cc7\u672c\uff08\u80a1\u672c\uff09 ": {
"3111-\u666e\u901a\u80a1\u80a1\u672c": {},
"3112-\u7279\u5225\u80a1\u80a1\u672c": {},
"3113-\u9810\u6536\u80a1\u672c": {},
"3114-\u5f85\u5206\u914d\u80a1\u7968\u80a1\u5229": {},
"3115-\u8cc7\u672c": {}
}
},
"32-\u8cc7\u672c\u516c\u7a4d": {
"321-\u80a1\u7968\u6ea2\u50f9": {
"3211-\u666e\u901a\u80a1\u80a1\u7968\u6ea2\u50f9": {},
"3212-\u7279\u5225\u80a1\u80a1\u7968\u6ea2\u50f9": {}
},
"323-\u8cc7\u7522\u91cd\u4f30\u589e\u503c\u6e96\u5099": {
"3231-\u8cc7\u7522\u91cd\u4f30\u589e\u503c\u6e96\u5099": {}
},
"324-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u516c\u7a4d": {
"3241-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u516c\u7a4d": {}
},
"325-\u5408\u4f75\u516c\u7a4d": {
"3251-\u5408\u4f75\u516c\u7a4d": {}
},
"326-\u53d7\u8d08\u516c\u7a4d": {
"3261-\u53d7\u8d08\u516c\u7a4d": {}
},
"328-\u5176\u4ed6\u8cc7\u672c\u516c\u7a4d": {
"3281-\u6b0a\u76ca\u6cd5\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u8cc7\u672c\u516c\u7a4d": {},
"3282-\u8cc7\u672c\u516c\u7a4d\u2014 \u5eab\u85cf\u80a1\u7968\u4ea4\u6613": {}
}
},
"33-\u4fdd\u7559\u76c8\u9918(\u7d2f\u7a4d\u8667\u640d)": {
"331-\u6cd5\u5b9a\u76c8\u9918\u516c\u7a4d": {
"3311-\u6cd5\u5b9a\u76c8\u9918\u516c\u7a4d": {}
},
"332-\u7279\u5225\u76c8\u9918\u516c\u7a4d": {
"3321-\u610f\u5916\u640d\u5931\u6e96\u5099": {},
"3322-\u6539\u826f\u64f4\u5145\u6e96\u5099": {},
"3323-\u511f\u50b5\u6e96\u5099": {},
"3328-\u5176\u4ed6\u7279\u5225\u76c8\u9918\u516c\u7a4d": {}
},
"335-\u672a\u5206\u914d\u76c8\u9918(\u7d2f\u7a4d\u8667\u640d) ": {
"is_group": 1
}
},
"34-\u6b0a\u76ca\u8abf\u6574": {
"341-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {
"3411-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {}
},
"342-\u7d2f\u7a4d\u63db\u7b97\u8abf\u6574\u6578": {
"3421-\u7d2f\u7a4d\u63db\u7b97\u8abf\u6574\u6578": {}
},
"343-\u672a\u8a8d\u5217\u70ba\u9000\u4f11\u91d1\u6210\u672c\u4e4b\u6de8\u640d\u5931": {
"3431-\u672a\u8a8d\u5217\u70ba\u9000\u4f11\u91d1\u6210\u672c\u4e4b\u6de8\u640d\u5931": {}
}
},
"35-\u5eab\u85cf\u80a1": {
"351-\u5eab\u85cf\u80a1": {
"3511-\u5eab\u85cf\u80a1": {}
}
},
"36-\u5c11\u6578\u80a1\u6b0a": {
"361-\u5c11\u6578\u80a1\u6b0a": {
"3611-\u5c11\u6578\u80a1\u6b0a": {}
}
},
"root_type": "Equity"
},
"4-\u71df\u696d\u6536\u5165": {
"41-\u92b7\u8ca8\u6536\u5165": {
"411-\u92b7\u8ca8\u6536\u5165": {
"4111-\u92b7\u8ca8\u6536\u5165": {},
"4112-\u5206\u671f\u4ed8\u6b3e\u92b7\u8ca8\u6536\u5165": {}
},
"417-\u92b7\u8ca8\u9000\u56de": {
"4171-\u92b7\u8ca8\u9000\u56de": {}
},
"419-\u92b7\u8ca8\u6298\u8b93": {
"4191-\u92b7\u8ca8\u6298\u8b93": {}
}
},
"46-\u52de\u52d9\u6536\u5165": {
"461-\u52de\u52d9\u6536\u5165": {
"4611-\u52de\u52d9\u6536\u5165": {}
}
},
"47-\u696d\u52d9\u6536\u5165": {
"471-\u696d\u52d9\u6536\u5165": {
"4711-\u696d\u52d9\u6536\u5165": {}
}
},
"48-\u5176\u4ed6\u71df\u696d\u6536\u5165": {
"488-\u5176\u4ed6\u71df\u696d\u6536\u5165\u2014\u5176\u4ed6": {
"4888-\u5176\u4ed6\u71df\u696d\u6536\u5165\u2014\u5176\u4ed6": {}
}
},
"root_type": "Income"
},
"5-\u71df\u696d\u6210\u672c": {
"51-\u92b7\u8ca8\u6210\u672c": {
"511-\u92b7\u8ca8\u6210\u672c": {
"5111-\u92b7\u8ca8\u6210\u672c": {
"account_type": "Cost of Goods Sold"
},
"5112-\u5206\u671f\u4ed8\u6b3e\u92b7\u8ca8\u6210\u672c": {
"account_type": "Cost of Goods Sold"
},
"account_type": "Cost of Goods Sold"
},
"512-\u9032\u8ca8": {
"5121-\u9032\u8ca8": {},
"5122-\u9032\u8ca8\u8cbb\u7528": {},
"5123-\u9032\u8ca8\u9000\u51fa": {},
"5124-\u9032\u8ca8\u6298\u8b93": {}
},
"513-\u9032\u6599": {
"5131-\u9032\u6599": {},
"5132-\u9032\u6599\u8cbb\u7528": {},
"5133-\u9032\u6599\u9000\u51fa": {},
"5134-\u9032\u6599\u6298\u8b93": {}
},
"514-\u76f4\u63a5\u4eba\u5de5": {
"5141-\u76f4\u63a5\u4eba\u5de5": {}
},
"515~518-\u88fd\u9020\u8cbb\u7528": {
"5151-\u9593\u63a5\u4eba\u5de5": {},
"5152-\u79df\u91d1\u652f\u51fa": {},
"5153-\u6587\u5177\u7528\u54c1": {},
"5154-\u65c5\u8cbb": {},
"5155-\u904b\u8cbb": {},
"5156-\u90f5\u96fb\u8cbb": {},
"5157-\u4fee\u7e55\u8cbb": {},
"5158-\u5305\u88dd\u8cbb": {},
"5161-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
"5162-\u4fdd\u96aa\u8cbb": {},
"5163-\u52a0\u5de5\u8cbb": {},
"5166-\u7a05\u6350": {
"account_type": "Tax",
"tax_rate": 5.0
},
"5168-\u6298\u820a ": {
"account_type": "Depreciation"
},
"5169-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
"5172-\u4f19\u98df\u8cbb": {},
"5173-\u8077\u5de5\u798f\u5229": {},
"5176-\u8a13\u7df4\u8cbb": {},
"5177-\u9593\u63a5\u6750\u6599": {},
"5188-\u5176\u4ed6\u88fd\u9020\u8cbb\u7528": {}
},
"Expenses Included In Valuation": {
"account_type": "Expenses Included In Valuation"
},
"account_type": "Cost of Goods Sold"
},
"56-\u52de\u52d9\u6210\u672c\u88fd": {
"561-\u52de\u52d9\u6210\u672c": {
"5611-\u52de\u52d9\u6210\u672c": {}
}
},
"57-\u696d\u52d9\u6210\u672c": {
"571-\u696d\u52d9\u6210\u672c": {
"5711-\u696d\u52d9\u6210\u672c": {}
}
},
"58-\u5176\u4ed6\u71df\u696d\u6210\u672c": {
"588-\u5176\u4ed6\u71df\u696d\u6210\u672c\u2014\u5176\u4ed6 ": {
"5888-\u5176\u4ed6\u71df\u696d\u6210\u672c\u2014\u5176\u4ed6": {}
}
},
"Stock Adjustment": {
"account_type": "Stock Adjustment"
},
"root_type": "Expense"
},
"6-\u71df\u696d\u8cbb\u7528": {
"61-\u63a8\u92b7\u8cbb\u7528": {
"615~618-\u63a8\u92b7\u8cbb\u7528": {
"6151-\u85aa\u8cc7\u652f\u51fa": {},
"6152-\u79df\u91d1\u652f\u51fa": {},
"6153-\u6587\u5177\u7528\u54c1": {},
"6154-\u65c5\u8cbb": {},
"6155-\u904b\u8cbb": {},
"6156-\u90f5\u96fb\u8cbb": {},
"6157-\u4fee\u7e55\u8cbb": {},
"6159-\u5ee3\u544a\u8cbb": {},
"6161-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
"6162-\u4fdd\u96aa\u8cbb": {},
"6164-\u4ea4\u969b\u8cbb": {},
"6165-\u6350\u8d08": {},
"6166-\u7a05\u6350": {
"account_type": "Tax",
"tax_rate": 5.0
},
"6167-\u5446\u5e33\u640d\u5931": {},
"6168-\u6298\u820a ": {
"account_type": "Depreciation"
},
"6169-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
"6172-\u4f19\u98df\u8cbb": {},
"6173-\u8077\u5de5\u798f\u5229": {},
"6175-\u4f63\u91d1\u652f\u51fa": {},
"6176-\u8a13\u7df4\u8cbb": {},
"6188-\u5176\u4ed6\u63a8\u92b7\u8cbb\u7528": {}
}
},
"62-\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {
"625~628-\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {
"6251-\u85aa\u8cc7\u652f\u51fa": {},
"6252-\u79df\u91d1\u652f\u51fa": {},
"6253-\u6587\u5177\u7528\u54c1": {},
"6254-\u65c5\u8cbb": {},
"6255-\u904b\u8cbb": {},
"6256-\u90f5\u96fb\u8cbb": {},
"6257-\u4fee\u7e55\u8cbb": {},
"6259-\u5ee3\u544a\u8cbb": {},
"6261-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
"6262-\u4fdd\u96aa\u8cbb": {},
"6264-\u4ea4\u969b\u8cbb": {},
"6265-\u6350\u8d08": {},
"6266-\u7a05\u6350": {
"account_type": "Tax",
"tax_rate": 5.0
},
"6267-\u5446\u5e33\u640d\u5931": {},
"6268-\u6298\u820a": {
"account_type": "Depreciation"
},
"6269-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
"6271-\u5916\u92b7\u640d\u5931": {},
"6272-\u4f19\u98df\u8cbb": {},
"6273-\u8077\u5de5\u798f\u5229": {},
"6274-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {},
"6275-\u4f63\u91d1\u652f\u51fa": {},
"6276-\u8a13\u7df4\u8cbb": {},
"6278-\u52de\u52d9\u8cbb": {},
"6288-\u5176\u4ed6\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {}
}
},
"63-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {
"635~638-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {
"6351-\u85aa\u8cc7\u652f\u51fa": {},
"6352-\u79df\u91d1\u652f\u51fa": {},
"6353-\u6587\u5177\u7528\u54c1": {},
"6354-\u65c5\u8cbb": {},
"6355-\u904b\u8cbb": {},
"6356-\u90f5\u96fb\u8cbb": {},
"6357-\u4fee\u7e55\u8cbb": {},
"6361-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
"6362-\u4fdd\u96aa\u8cbb": {},
"6364-\u4ea4\u969b\u8cbb": {},
"6366-\u7a05\u6350": {
"account_type": "Tax",
"tax_rate": 5.0
},
"6368-\u6298\u820a": {
"account_type": "Depreciation"
},
"6369-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
"6372-\u4f19\u98df\u8cbb": {},
"6373-\u8077\u5de5\u798f\u5229": {},
"6376-\u8a13\u7df4\u8cbb": {},
"6378-\u5176\u4ed6\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {}
}
},
"root_type": "Expense"
},
"7-\u71df\u696d\u5916\u6536\u5165\u53ca\u8cbb\u7528": {
"71~74-\u71df\u696d\u5916\u6536\u5165": {
"711-\u5229\u606f\u6536\u5165": {
"7111-\u5229\u606f\u6536\u5165": {}
},
"712-\u6295\u8cc7\u6536\u76ca": {
"7121-\u6b0a\u76ca\u6cd5\u8a8d\u5217\u4e4b\u6295\u8cc7\u6536\u76ca": {},
"7122-\u80a1\u5229\u6536\u5165": {},
"7123-\u77ed\u671f\u6295\u8cc7\u5e02\u50f9\u56de\u5347\u5229\u76ca": {}
},
"713-\u514c\u63db\u5229\u76ca": {
"7131-\u514c\u63db\u5229\u76ca": {}
},
"714-\u8655\u5206\u6295\u8cc7\u6536\u76ca": {
"7141-\u8655\u5206\u6295\u8cc7\u6536\u76ca": {}
},
"715-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u6536\u5165": {
"7151-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u6536\u5165": {}
},
"748-\u5176\u4ed6\u71df\u696d\u5916\u6536\u5165": {
"7481-\u6350\u8d08\u6536\u5165": {},
"7482-\u79df\u91d1\u6536\u5165": {},
"7483-\u4f63\u91d1\u6536\u5165": {},
"7484-\u51fa\u552e\u4e0b\u8173\u53ca\u5ee2\u6599\u6536\u5165": {},
"7485-\u5b58\u8ca8\u76e4\u76c8": {},
"7486-\u5b58\u8ca8\u8dcc\u50f9\u56de\u5347\u5229\u76ca": {},
"7487-\u58de\u5e33\u8f49\u56de\u5229\u76ca": {},
"7488-\u5176\u4ed6\u71df\u696d\u5916\u6536\u5165\u2014\u5176\u4ed6": {}
}
},
"75~78-\u71df\u696d\u5916\u8cbb\u7528": {
"751-\u5229\u606f\u8cbb\u7528": {
"7511-\u5229\u606f\u8cbb\u7528": {}
},
"752-\u6295\u8cc7\u640d\u5931": {
"7521-\u6b0a\u76ca\u6cd5\u8a8d\u5217\u4e4b\u6295\u8cc7\u640d\u5931": {},
"7523-\u77ed\u671f\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {}
},
"753-\u514c\u63db\u640d\u5931": {
"7531-\u514c\u63db\u640d\u5931": {}
},
"754-\u8655\u5206\u6295\u8cc7\u640d\u5931": {
"7541-\u8655\u5206\u6295\u8cc7\u640d\u5931": {}
},
"755-\u8655\u5206\u8cc7\u7522\u640d\u5931": {
"7551-\u8655\u5206\u8cc7\u7522\u640d\u5931 ": {}
},
"788-\u5176\u4ed6\u71df\u696d\u5916\u8cbb\u7528": {
"7881-\u505c\u5de5\u640d\u5931": {},
"7882-\u707d\u5bb3\u640d\u5931": {},
"7885-\u5b58\u8ca8\u76e4\u640d": {},
"7886-\u5b58\u8ca8\u8dcc\u50f9\u53ca\u5446\u6eef\u640d\u5931": {},
"7888-\u5176\u4ed6\u71df\u696d\u5916\u8cbb\u7528\u2014\u5176\u4ed6": {}
}
},
"root_type": "Income"
},
"8-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca)": {
"81-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca)": {
"811-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca) ": {
"8111-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca) ": {}
}
},
"root_type": "Expense"
},
"9-\u975e\u7d93\u5e38\u71df\u696d\u640d\u76ca": {
"91-\u505c\u696d\u90e8\u9580\u640d\u76ca": {
"911-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u505c\u696d\u524d\u71df\u696d\u640d\u76ca": {
"9111-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u505c\u696d\u524d\u71df\u696d\u640d\u76ca": {}
},
"912-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u8655\u5206\u640d\u76ca": {
"9121-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u8655\u5206\u640d\u76ca": {}
}
},
"92-\u975e\u5e38\u640d\u76ca": {
"921-\u975e\u5e38\u640d\u76ca": {
"9211-\u975e\u5e38\u640d\u76ca": {}
}
},
"93-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {
"931-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {
"9311-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {}
}
},
"94-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {
"941-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {
"9411-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {}
}
},
"root_type": "Expense"
}
}
}

View File

@@ -0,0 +1,46 @@
QUnit.module('accounts');
QUnit.test("test account", assert => {
assert.expect(3);
let done = assert.async();
frappe.run_serially([
() => frappe.set_route('Tree', 'Account'),
() => frappe.click_button('Expand All'),
() => frappe.click_link('Duties and Taxes - '+ frappe.get_abbr(frappe.defaults.get_default("Company"))),
() => {
if($('a:contains("CGST"):visible').length == 0){
return frappe.map_tax.make('CGST', 9);
}
},
() => {
if($('a:contains("SGST"):visible').length == 0){
return frappe.map_tax.make('SGST', 9);
}
},
() => {
if($('a:contains("IGST"):visible').length == 0){
return frappe.map_tax.make('IGST', 18);
}
},
() => {
assert.ok($('a:contains("CGST"):visible').length!=0, "CGST Checked");
assert.ok($('a:contains("SGST"):visible').length!=0, "SGST Checked");
assert.ok($('a:contains("IGST"):visible').length!=0, "IGST Checked");
},
() => done()
]);
});
frappe.map_tax = {
make:function(text,rate){
return frappe.run_serially([
() => frappe.click_button('Add Child'),
() => frappe.timeout(0.2),
() => cur_dialog.set_value('account_name',text),
() => cur_dialog.set_value('account_type','Tax'),
() => cur_dialog.set_value('tax_rate',rate),
() => cur_dialog.set_value('account_currency','INR'),
() => frappe.click_button('Create New'),
]);
}
};

View File

@@ -147,8 +147,9 @@ class Asset(Document):
accumulated_depreciation_after_full_schedule = \
max([d.accumulated_depreciation_amount for d in self.get("schedules")])
asset_value_after_full_schedule = (flt(self.gross_purchase_amount) -
flt(accumulated_depreciation_after_full_schedule))
asset_value_after_full_schedule = flt(flt(self.gross_purchase_amount) -
flt(accumulated_depreciation_after_full_schedule),
self.precision('expected_value_after_useful_life'))
if self.expected_value_after_useful_life < asset_value_after_full_schedule:
frappe.throw(_("Expected value after useful life must be greater than or equal to {0}")

View File

@@ -36,12 +36,15 @@ def make_depreciation_entry(asset_name, date=None):
fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
get_depreciation_accounts(asset)
depreciation_cost_center = frappe.db.get_value("Company", asset.company, "depreciation_cost_center")
depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
["depreciation_cost_center", "series_for_depreciation_entry"])
for d in asset.get("schedules"):
if not d.journal_entry and getdate(d.schedule_date) <= getdate(date):
je = frappe.new_doc("Journal Entry")
je.voucher_type = "Depreciation Entry"
je.naming_series = depreciation_series
je.posting_date = d.schedule_date
je.company = asset.company
je.remark = "Depreciation Entry against {0} worth {1}".format(asset_name, d.depreciation_amount)
@@ -109,8 +112,11 @@ def scrap_asset(asset_name):
elif asset.status in ("Cancelled", "Sold", "Scrapped"):
frappe.throw(_("Asset {0} cannot be scrapped, as it is already {1}").format(asset.name, asset.status))
depreciation_series = frappe.db.get_value("Company", asset.company, "series_for_depreciation_entry")
je = frappe.new_doc("Journal Entry")
je.voucher_type = "Journal Entry"
je.naming_series = depreciation_series
je.posting_date = today()
je.company = asset.company
je.remark = "Scrap Entry for asset {0}".format(asset_name)

View File

@@ -150,11 +150,16 @@ class TestAsset(unittest.TestCase):
asset.load_from_db()
self.assertEqual(asset.status, "Submitted")
frappe.db.set_value("Company", "_Test Company", "series_for_depreciation_entry", "DEPR-")
post_depreciation_entries(date="2021-01-01")
asset.load_from_db()
self.assertEqual(asset.status, "Partially Depreciated")
# check depreciation entry series
self.assertEqual(asset.get("schedules")[0].journal_entry[:4], "DEPR")
expected_gle = (
("_Test Accumulated Depreciations - _TC", 0.0, 30000.0),
("_Test Depreciations - _TC", 30000.0, 0.0)

View File

@@ -718,7 +718,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-04-27 13:18:06.617940",
"modified": "2017-08-03 12:40:09.611951",
"modified_by": "Administrator",
"module": "Accounts",
"name": "GL Entry",
@@ -786,7 +786,7 @@
}
],
"quick_entry": 1,
"read_only": 1,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "voucher_no,account,posting_date,against_voucher",
"show_name_in_global_search": 0,

View File

@@ -0,0 +1,23 @@
/* eslint-disable */
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
QUnit.test("test: GL Entry", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially('GL Entry', [
// insert a new GL Entry
() => frappe.tests.make([
// values to be set
{key: 'value'}
]),
() => {
assert.equal(cur_frm.doc.key, 'value');
},
() => done()
]);
});

View File

@@ -43,8 +43,26 @@ frappe.ui.form.on("Journal Entry", {
$.each(frm.doc.accounts || [], function(i, row) {
erpnext.journal_entry.set_exchange_rate(frm, row.doctype, row.name);
})
},
company: function(frm) {
frappe.call({
method: "frappe.client.get_value",
args: {
doctype: "Company",
filters: {"name": frm.doc.company},
fieldname: "cost_center"
},
callback: function(r){
if(r.message){
$.each(frm.doc.accounts || [], function(i, jvd) {
frappe.model.set_value(jvd.doctype, jvd.name, "cost_center", r.message.cost_center);
});
}
}
});
}
})
});
erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
onload: function() {

View File

@@ -28,7 +28,7 @@ frappe.ui.form.on('Payment Entry', {
frm.set_query("party_type", function() {
return{
"filters": {
"name": ["in",["Customer","Supplier"]],
"name": ["in",["Customer","Supplier", "Employee"]],
}
}
});
@@ -70,6 +70,8 @@ frappe.ui.form.on('Payment Entry', {
var doctypes = ["Sales Order", "Sales Invoice", "Journal Entry"];
} else if (frm.doc.party_type=="Supplier") {
var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"];
} else if (frm.doc.party_type=="Employee") {
var doctypes = ["Expense Claim", "Journal Entry"];
} else {
var doctypes = ["Journal Entry"];
}
@@ -82,12 +84,18 @@ frappe.ui.form.on('Payment Entry', {
frm.set_query("reference_name", "references", function(doc, cdt, cdn) {
child = locals[cdt][cdn];
filters = {"docstatus": 1, "company": doc.company};
party_type_doctypes = ['Sales Invoice', 'Sales Order', 'Purchase Invoice', 'Purchase Order'];
party_type_doctypes = ['Sales Invoice', 'Sales Order', 'Purchase Invoice',
'Purchase Order', 'Expense Claim'];
if (in_list(party_type_doctypes, child.reference_doctype)) {
filters[doc.party_type.toLowerCase()] = doc.party;
}
if(child.reference_doctype == "Expense Claim") {
filters["status"] = "Approved";
filters["is_paid"] = 0;
}
return {
filters: filters
};
@@ -200,9 +208,15 @@ frappe.ui.form.on('Payment Entry', {
});
} else {
if(!frm.doc.party)
frm.set_value("party_type", frm.doc.payment_type=="Receive" ? "Customer" : "Supplier");
{
if (frm.doc.payment_type=="Receive"){
frm.set_value("party_type", "Customer");
}
}
else
{
frm.events.party(frm);
}
if(frm.doc.mode_of_payment)
frm.events.mode_of_payment(frm);
@@ -339,7 +353,8 @@ frappe.ui.form.on('Payment Entry', {
method: "erpnext.setup.utils.get_exchange_rate",
args: {
from_currency: frm.doc.paid_from_account_currency,
to_currency: company_currency
to_currency: company_currency,
transaction_date: frm.doc.posting_date
},
callback: function(r, rt) {
frm.set_value("source_exchange_rate", r.message);
@@ -484,9 +499,10 @@ frappe.ui.form.on('Payment Entry', {
var c = frm.add_child("references");
c.reference_doctype = d.voucher_type;
c.reference_name = d.voucher_no;
c.due_date = d.due_date
c.total_amount = d.invoice_amount;
c.outstanding_amount = d.outstanding_amount;
if(!in_list(["Sales Order", "Purchase Order"], d.voucher_type)) {
if(!in_list(["Sales Order", "Purchase Order", "Expense Claim"], d.voucher_type)) {
if(flt(d.outstanding_amount) > 0)
total_positive_outstanding += flt(d.outstanding_amount);
else
@@ -501,14 +517,15 @@ frappe.ui.form.on('Payment Entry', {
} else {
c.exchange_rate = 1;
}
if (in_list(['Sales Invoice', 'Purchase Invoice'], d.reference_doctype)){
if (in_list(['Sales Invoice', 'Purchase Invoice', "Expense Claim"], d.reference_doctype)){
c.due_date = d.due_date;
}
});
if(
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier")
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee")
) {
if(total_positive_outstanding > total_negative_outstanding)
frm.set_value("paid_amount",
@@ -552,8 +569,9 @@ frappe.ui.form.on('Payment Entry', {
})
var allocated_negative_outstanding = 0;
if((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier")) {
if ((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee")) {
if(total_positive_outstanding_including_order > paid_amount) {
var remaining_outstanding = total_positive_outstanding_including_order - paid_amount;
allocated_negative_outstanding = total_negative_outstanding < remaining_outstanding ?
@@ -561,7 +579,7 @@ frappe.ui.form.on('Payment Entry', {
}
var allocated_positive_outstanding = paid_amount + allocated_negative_outstanding;
} else {
} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
if(paid_amount > total_negative_outstanding) {
if(total_negative_outstanding == 0) {
frappe.msgprint(__("Cannot {0} {1} {2} without any negative outstanding invoice",
@@ -694,6 +712,14 @@ frappe.ui.form.on('Payment Entry', {
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=="Employee" &&
!in_list(["Expense Claim", "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 Expense Claim or Journal Entry", [row.idx]));
return false;
}
}
if (row) {

View File

@@ -12,27 +12,27 @@ from erpnext.accounts.doctype.journal_entry.journal_entry \
import get_average_exchange_rate, get_default_bank_cash_account
from erpnext.setup.utils import get_exchange_rate
from erpnext.accounts.general_ledger import make_gl_entries
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
from erpnext.controllers.accounts_controller import AccountsController
class InvalidPaymentEntry(ValidationError): pass
class PaymentEntry(AccountsController):
def setup_party_account_field(self):
def setup_party_account_field(self):
self.party_account_field = None
self.party_account = None
self.party_account_currency = None
if self.payment_type == "Receive":
self.party_account_field = "paid_from"
self.party_account = self.paid_from
self.party_account_currency = self.paid_from_account_currency
elif self.payment_type == "Pay":
self.party_account_field = "paid_to"
self.party_account = self.paid_to
self.party_account_currency = self.paid_to_account_currency
def validate(self):
self.setup_party_account_field()
self.set_missing_values()
@@ -50,18 +50,20 @@ class PaymentEntry(AccountsController):
self.set_remarks()
self.validate_duplicate_entry()
self.validate_allocated_amount()
def on_submit(self):
self.setup_party_account_field()
if self.difference_amount:
frappe.throw(_("Difference Amount must be zero"))
self.make_gl_entries()
self.update_advance_paid()
self.update_expense_claim()
def on_cancel(self):
self.setup_party_account_field()
self.make_gl_entries(cancel=1)
self.update_advance_paid()
self.update_expense_claim()
self.delink_advance_entry_references()
def validate_duplicate_entry(self):
@@ -70,8 +72,8 @@ class PaymentEntry(AccountsController):
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:
@@ -87,111 +89,113 @@ class PaymentEntry(AccountsController):
def set_missing_values(self):
if self.payment_type == "Internal Transfer":
for field in ("party", "party_balance", "total_allocated_amount",
for field in ("party", "party_balance", "total_allocated_amount",
"base_total_allocated_amount", "unallocated_amount"):
self.set(field, None)
self.references = []
else:
if not self.party_type:
frappe.throw(_("Party Type is mandatory"))
if not self.party:
frappe.throw(_("Party is mandatory"))
self.party_name = frappe.db.get_value(self.party_type, self.party,
self.party_name = frappe.db.get_value(self.party_type, self.party,
self.party_type.lower() + "_name")
if self.party:
if not self.party_balance:
self.party_balance = get_balance_on(party_type=self.party_type,
party=self.party, date=self.posting_date, company=self.company)
if not self.party_account:
party_account = get_party_account(self.party_type, self.party, self.company)
self.set(self.party_account_field, party_account)
self.party_account = party_account
if self.paid_from and not (self.paid_from_account_currency or self.paid_from_account_balance):
acc = get_account_details(self.paid_from, self.posting_date)
self.paid_from_account_currency = acc.account_currency
self.paid_from_account_balance = acc.account_balance
if self.paid_to and not (self.paid_to_account_currency or self.paid_to_account_balance):
acc = get_account_details(self.paid_to, self.posting_date)
self.paid_to_account_currency = acc.account_currency
self.paid_to_account_balance = acc.account_balance
self.party_account_currency = self.paid_from_account_currency \
if self.payment_type=="Receive" else self.paid_to_account_currency
self.set_missing_ref_details()
def set_missing_ref_details(self):
for d in self.get("references"):
if d.allocated_amount:
ref_details = get_reference_details(d.reference_doctype,
ref_details = get_reference_details(d.reference_doctype,
d.reference_name, self.party_account_currency)
for field, value in ref_details.items():
if not d.get(field):
d.set(field, value)
def validate_payment_type(self):
if self.payment_type not in ("Receive", "Pay", "Internal Transfer"):
frappe.throw(_("Payment Type must be one of Receive, Pay and Internal Transfer"))
def validate_party_details(self):
if self.party:
if not frappe.db.exists(self.party_type, self.party):
frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party))
if self.party_account:
party_account_type = "Receivable" if self.party_type=="Customer" else "Payable"
self.validate_account_type(self.party_account, [party_account_type])
def validate_bank_accounts(self):
if self.payment_type in ("Pay", "Internal Transfer"):
self.validate_account_type(self.paid_from, ["Bank", "Cash"])
if self.payment_type in ("Receive", "Internal Transfer"):
self.validate_account_type(self.paid_to, ["Bank", "Cash"])
def validate_account_type(self, account, account_types):
account_type = frappe.db.get_value("Account", account, "account_type")
if account_type not in account_types:
frappe.throw(_("Account Type for {0} must be {1}").format(account, comma_or(account_types)))
def set_exchange_rate(self):
if self.paid_from and not self.source_exchange_rate:
if self.paid_from_account_currency == self.company_currency:
self.source_exchange_rate = 1
else:
self.source_exchange_rate = get_exchange_rate(self.paid_from_account_currency,
self.source_exchange_rate = get_exchange_rate(self.paid_from_account_currency,
self.company_currency, self.posting_date)
if self.paid_to and not self.target_exchange_rate:
self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency,
self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency,
self.company_currency, self.posting_date)
def validate_mandatory(self):
for field in ("paid_amount", "received_amount", "source_exchange_rate", "target_exchange_rate"):
if not self.get(field):
frappe.throw(_("{0} is mandatory").format(self.meta.get_label(field)))
def validate_reference_documents(self):
if self.party_type == "Customer":
valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry")
else:
elif self.party_type == "Supplier":
valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry")
elif self.party_type == "Employee":
valid_reference_doctypes = ("Expense Claim", "Journal Entry")
for d in self.get("references"):
if not d.allocated_amount:
continue
if d.reference_doctype not in valid_reference_doctypes:
frappe.throw(_("Reference Doctype must be one of {0}")
.format(comma_or(valid_reference_doctypes)))
elif d.reference_name:
if not frappe.db.exists(d.reference_doctype, d.reference_name):
frappe.throw(_("{0} {1} does not exist").format(d.reference_doctype, d.reference_name))
@@ -204,21 +208,26 @@ class PaymentEntry(AccountsController):
.format(d.reference_doctype, d.reference_name, self.party_type, self.party))
else:
self.validate_journal_entry()
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice"):
ref_party_account = ref_doc.debit_to \
if self.party_type=="Customer" else ref_doc.credit_to
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim"):
if self.party_type=="Customer":
ref_party_account = ref_doc.debit_to
elif self.party_type=="Supplier":
ref_party_account = ref_doc.credit_to
elif self.party_type=="Employee":
ref_party_account = ref_doc.payable_account
if ref_party_account != self.party_account:
frappe.throw(_("{0} {1} does not associated with Party Account {2}")
.format(d.reference_doctype, d.reference_name, self.party_account))
frappe.throw(_("{0} {1} is associated with {2}, but Party Account is {3}")
.format(d.reference_doctype, d.reference_name, ref_party_account, self.party_account))
if ref_doc.docstatus != 1:
frappe.throw(_("{0} {1} must be submitted")
.format(d.reference_doctype, d.reference_name))
def validate_journal_entry(self):
for d in self.get("references"):
if d.allocated_amount and d.reference_doctype == "Journal Entry":
if d.allocated_amount and d.reference_doctype == "Journal Entry":
je_accounts = frappe.db.sql("""select debit, credit from `tabJournal Entry Account`
where account = %s and party=%s and docstatus = 1 and parent = %s
and (reference_type is null or reference_type in ("", "Sales Order", "Purchase Order"))
@@ -236,7 +245,7 @@ class PaymentEntry(AccountsController):
if not valid:
frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry")
.format(d.reference_name, dr_or_cr))
def set_amounts(self):
self.set_amounts_in_company_currency()
self.set_total_allocated_amount()
@@ -246,111 +255,111 @@ class PaymentEntry(AccountsController):
def set_amounts_in_company_currency(self):
self.base_paid_amount, self.base_received_amount, self.difference_amount = 0, 0, 0
if self.paid_amount:
self.base_paid_amount = flt(flt(self.paid_amount) * flt(self.source_exchange_rate),
self.base_paid_amount = flt(flt(self.paid_amount) * flt(self.source_exchange_rate),
self.precision("base_paid_amount"))
if self.received_amount:
self.base_received_amount = flt(flt(self.received_amount) * flt(self.target_exchange_rate),
self.base_received_amount = flt(flt(self.received_amount) * flt(self.target_exchange_rate),
self.precision("base_received_amount"))
def set_total_allocated_amount(self):
if self.payment_type == "Internal Transfer":
return
total_allocated_amount, base_total_allocated_amount = 0, 0
for d in self.get("references"):
if d.allocated_amount:
if d.allocated_amount:
total_allocated_amount += flt(d.allocated_amount)
base_total_allocated_amount += flt(flt(d.allocated_amount) * flt(d.exchange_rate),
base_total_allocated_amount += flt(flt(d.allocated_amount) * flt(d.exchange_rate),
self.precision("base_paid_amount"))
self.total_allocated_amount = abs(total_allocated_amount)
self.base_total_allocated_amount = abs(base_total_allocated_amount)
def set_unallocated_amount(self):
self.unallocated_amount = 0;
if self.party:
party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
if self.total_allocated_amount < party_amount:
if self.payment_type == "Receive":
self.unallocated_amount = party_amount - (self.total_allocated_amount - total_deductions)
else:
self.unallocated_amount = party_amount - (self.total_allocated_amount + total_deductions)
def set_difference_amount(self):
base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate)
base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate)
if self.payment_type=="Receive" else flt(self.target_exchange_rate))
base_party_amount = flt(self.base_total_allocated_amount) + flt(base_unallocated_amount)
if self.payment_type == "Receive":
self.difference_amount = base_party_amount - self.base_received_amount
elif self.payment_type == "Pay":
self.difference_amount = self.base_paid_amount - base_party_amount
else:
self.difference_amount = self.base_paid_amount - flt(self.base_received_amount)
for d in self.get("deductions"):
if d.amount:
self.difference_amount -= flt(d.amount)
self.difference_amount = flt(self.difference_amount, self.precision("difference_amount"))
def clear_unallocated_reference_document_rows(self):
self.set("references", self.get("references", {"allocated_amount": ["not in", [0, None, ""]]}))
frappe.db.sql("""delete from `tabPayment Entry Reference`
frappe.db.sql("""delete from `tabPayment Entry Reference`
where parent = %s and allocated_amount = 0""", self.name)
def validate_payment_against_negative_invoice(self):
if ((self.payment_type=="Pay" and self.party_type=="Customer")
if ((self.payment_type=="Pay" and self.party_type=="Customer")
or (self.payment_type=="Receive" and self.party_type=="Supplier")):
total_negative_outstanding = sum([abs(flt(d.outstanding_amount))
total_negative_outstanding = sum([abs(flt(d.outstanding_amount))
for d in self.get("references") if flt(d.outstanding_amount) < 0])
party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
if not total_negative_outstanding:
frappe.throw(_("Cannot {0} {1} {2} without any negative outstanding invoice")
.format(self.payment_type, ("to" if self.party_type=="Customer" else "from"),
.format(self.payment_type, ("to" if self.party_type=="Customer" else "from"),
self.party_type), InvalidPaymentEntry)
elif party_amount > total_negative_outstanding:
frappe.throw(_("Paid Amount cannot be greater than total negative outstanding amount {0}")
.format(total_negative_outstanding), InvalidPaymentEntry)
def set_title(self):
if self.payment_type in ("Receive", "Pay"):
self.title = self.party
else:
self.title = self.paid_from + " - " + self.paid_to
def validate_transaction_reference(self):
bank_account = self.paid_to if self.payment_type == "Receive" else self.paid_from
bank_account_type = frappe.db.get_value("Account", bank_account, "account_type")
if bank_account_type == "Bank":
if not self.reference_no or not self.reference_date:
frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction"))
def set_remarks(self):
if self.remarks: return
if self.payment_type=="Internal Transfer":
remarks = [_("Amount {0} {1} transferred from {2} to {3}")
.format(self.paid_from_account_currency, self.paid_amount, self.paid_from, self.paid_to)]
else:
remarks = [_("Amount {0} {1} {2} {3}").format(
self.party_account_currency,
self.paid_amount if self.payment_type=="Receive" else self.received_amount,
_("received from") if self.payment_type=="Receive" else _("to"), self.party
)]
if self.reference_no:
remarks.append(_("Transaction reference no {0} dated {1}")
.format(self.reference_no, self.reference_date))
@@ -358,35 +367,35 @@ class PaymentEntry(AccountsController):
if self.payment_type in ["Receive", "Pay"]:
for d in self.get("references"):
if d.allocated_amount:
remarks.append(_("Amount {0} {1} against {2} {3}").format(self.party_account_currency,
remarks.append(_("Amount {0} {1} against {2} {3}").format(self.party_account_currency,
d.allocated_amount, d.reference_doctype, d.reference_name))
for d in self.get("deductions"):
if d.amount:
remarks.append(_("Amount {0} {1} deducted against {2}")
.format(self.company_currency, d.amount, d.account))
self.set("remarks", "\n".join(remarks))
def make_gl_entries(self, cancel=0, adv_adj=0):
if self.payment_type in ("Receive", "Pay") and not self.get("party_account_field"):
self.setup_party_account_field()
gl_entries = []
self.add_party_gl_entries(gl_entries)
self.add_bank_gl_entries(gl_entries)
self.add_deductions_gl_entries(gl_entries)
make_gl_entries(gl_entries, cancel=cancel, adv_adj=adv_adj)
def add_party_gl_entries(self, gl_entries):
if self.party_account:
if self.payment_type=="Receive":
against_account = self.paid_to
else:
against_account = self.paid_from
party_gl_dict = self.get_gl_dict({
"account": self.party_account,
"party_type": self.party_type,
@@ -394,39 +403,39 @@ class PaymentEntry(AccountsController):
"against": against_account,
"account_currency": self.party_account_currency
})
dr_or_cr = "credit" if self.party_type == "Customer" else "debit"
for d in self.get("references"):
gle = party_gl_dict.copy()
gle.update({
"against_voucher_type": d.reference_doctype,
"against_voucher": d.reference_name
})
allocated_amount_in_company_currency = flt(flt(d.allocated_amount) * flt(d.exchange_rate),
self.precision("paid_amount"))
allocated_amount_in_company_currency = flt(flt(d.allocated_amount) * flt(d.exchange_rate),
self.precision("paid_amount"))
gle.update({
dr_or_cr + "_in_account_currency": d.allocated_amount,
dr_or_cr: allocated_amount_in_company_currency
})
gl_entries.append(gle)
if self.unallocated_amount:
base_unallocated_amount = base_unallocated_amount = self.unallocated_amount * \
(self.source_exchange_rate if self.payment_type=="Receive" else self.target_exchange_rate)
gle = party_gl_dict.copy()
gle.update({
dr_or_cr + "_in_account_currency": self.unallocated_amount,
dr_or_cr: base_unallocated_amount
})
gl_entries.append(gle)
def add_bank_gl_entries(self, gl_entries):
if self.payment_type in ("Pay", "Internal Transfer"):
gl_entries.append(
@@ -448,14 +457,14 @@ class PaymentEntry(AccountsController):
"debit": self.base_received_amount
})
)
def add_deductions_gl_entries(self, gl_entries):
for d in self.get("deductions"):
if d.amount:
account_currency = get_account_currency(d.account)
if account_currency != self.company_currency:
frappe.throw(_("Currency for {0} must be {1}").format(d.account, self.company_currency))
gl_entries.append(
self.get_gl_dict({
"account": d.account,
@@ -466,34 +475,41 @@ class PaymentEntry(AccountsController):
"cost_center": d.cost_center
})
)
def update_advance_paid(self):
if self.payment_type in ("Receive", "Pay") and self.party:
for d in self.get("references"):
if d.allocated_amount and d.reference_doctype in ("Sales Order", "Purchase Order"):
frappe.get_doc(d.reference_doctype, d.reference_name).set_total_advance_paid()
def update_expense_claim(self):
if self.payment_type in ("Pay") and self.party:
for d in self.get("references"):
if d.reference_doctype=="Expense Claim" and d.reference_name:
doc = frappe.get_doc("Expense Claim", d.reference_name)
update_reimbursed_amount(doc)
@frappe.whitelist()
def get_outstanding_reference_documents(args):
args = json.loads(args)
party_account_currency = get_account_currency(args.get("party_account"))
company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency")
# Get negative outstanding sales /purchase invoices
total_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
args.get("party"), args.get("party_account"), total_field)
# Get positive outstanding sales /purchase invoices
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
args.get("party_account"))
for d in outstanding_invoices:
d["exchange_rate"] = 1
if party_account_currency != company_currency:
if d.voucher_type in ("Sales Invoice", "Purchase Invoice"):
if d.voucher_type in ("Sales Invoice", "Purchase Invoice", "Expense Claim"):
d["exchange_rate"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "conversion_rate")
elif d.voucher_type == "Journal Entry":
d["exchange_rate"] = get_exchange_rate(
@@ -501,79 +517,89 @@ def get_outstanding_reference_documents(args):
)
# Get all SO / PO which are not fully billed or aginst which full advance not paid
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"), args.get("party"),
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"), args.get("party"),
party_account_currency, company_currency)
return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency):
voucher_type = 'Sales Order' if party_type == "Customer" else 'Purchase Order'
if party_type == "Customer":
voucher_type = 'Sales Order'
elif party_type == "Supplier":
voucher_type = 'Purchase Order'
elif party_type == "Employee":
voucher_type = None
ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
orders = []
if voucher_type:
ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
orders = frappe.db.sql("""
select
name as voucher_no,
{ref_field} as invoice_amount,
({ref_field} - advance_paid) as outstanding_amount,
transaction_date as posting_date
from
`tab{voucher_type}`
where
{party_type} = %s
and docstatus = 1
and ifnull(status, "") != "Closed"
and {ref_field} > advance_paid
and abs(100 - per_billed) > 0.01
order by
transaction_date, name
""".format(**{
"ref_field": ref_field,
"voucher_type": voucher_type,
"party_type": scrub(party_type)
}), party, as_dict = True)
orders = frappe.db.sql("""
select
name as voucher_no,
{ref_field} as invoice_amount,
({ref_field} - advance_paid) as outstanding_amount,
transaction_date as posting_date
from
`tab{voucher_type}`
where
{party_type} = %s
and docstatus = 1
and ifnull(status, "") != "Closed"
and {ref_field} > advance_paid
and abs(100 - per_billed) > 0.01
order by
transaction_date, name
""".format(**{
"ref_field": ref_field,
"voucher_type": voucher_type,
"party_type": scrub(party_type)
}), party, as_dict = True)
order_list = []
for d in orders:
d["voucher_type"] = voucher_type
# This assumes that the exchange rate required is the one in the SO
d["exchange_rate"] = get_exchange_rate(party_account_currency,
d["exchange_rate"] = get_exchange_rate(party_account_currency,
company_currency, posting_date)
order_list.append(d)
return order_list
def get_negative_outstanding_invoices(party_type, party, party_account, total_field):
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
return frappe.db.sql("""
select
"{voucher_type}" as voucher_type, name as voucher_no,
{total_field} as invoice_amount, outstanding_amount, posting_date,
due_date, conversion_rate as exchange_rate
from
`tab{voucher_type}`
where
{party_type} = %s and {party_account} = %s and docstatus = 1 and outstanding_amount < 0
order by
posting_date, name
""".format(**{
"total_field": total_field,
"voucher_type": voucher_type,
"party_type": scrub(party_type),
"party_account": "debit_to" if party_type=="Customer" else "credit_to"
}), (party, party_account), as_dict = True)
if party_type != "Employee":
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
return frappe.db.sql("""
select
"{voucher_type}" as voucher_type, name as voucher_no,
{total_field} as invoice_amount, outstanding_amount, posting_date,
due_date, conversion_rate as exchange_rate
from
`tab{voucher_type}`
where
{party_type} = %s and {party_account} = %s and docstatus = 1 and outstanding_amount < 0
order by
posting_date, name
""".format(**{
"total_field": total_field,
"voucher_type": voucher_type,
"party_type": scrub(party_type),
"party_account": "debit_to" if party_type=="Customer" else "credit_to"
}), (party, party_account), as_dict = True)
else:
return []
@frappe.whitelist()
def get_party_details(company, party_type, party, date):
if not frappe.db.exists(party_type, party):
frappe.throw(_("Invalid {0}: {1}").format(party_type, party))
party_account = get_party_account(party_type, party, company)
account_currency = get_account_currency(party_account)
account_balance = get_balance_on(party_account, date)
party_balance = get_balance_on(party_type=party_type, party=party)
return {
"party_account": party_account,
"party_account_currency": account_currency,
@@ -581,7 +607,7 @@ def get_party_details(company, party_type, party, date):
"account_balance": account_balance
}
@frappe.whitelist()
@frappe.whitelist()
def get_account_details(account, date):
frappe.has_permission('Payment Entry', throw=True)
return frappe._dict({
@@ -589,59 +615,67 @@ def get_account_details(account, date):
"account_balance": get_balance_on(account, date),
"account_type": frappe.db.get_value("Account", account, "account_type")
})
@frappe.whitelist()
def get_company_defaults(company):
fields = ["write_off_account", "exchange_gain_loss_account", "cost_center"]
ret = frappe.db.get_value("Company", company, fields, as_dict=1)
for fieldname in fields:
if not ret[fieldname]:
frappe.throw(_("Please set default {0} in Company {1}")
.format(frappe.get_meta("Company").get_label(fieldname), company))
return ret
@frappe.whitelist()
def get_reference_details(reference_doctype, reference_name, party_account_currency):
total_amount = outstanding_amount = exchange_rate = None
ref_doc = frappe.get_doc(reference_doctype, reference_name)
if reference_doctype != "Journal Entry":
if party_account_currency == ref_doc.company_currency:
total_amount = ref_doc.base_grand_total
if ref_doc.doctype == "Expense Claim":
total_amount = ref_doc.total_sanctioned_amount
else:
total_amount = ref_doc.base_grand_total
exchange_rate = 1
else:
total_amount = ref_doc.grand_total
# Get the exchange rate from the original ref doc
# Get the exchange rate from the original ref doc
# or get it based on the posting date of the ref doc
exchange_rate = ref_doc.get("conversion_rate") or \
get_exchange_rate(party_account_currency, ref_doc.company_currency, ref_doc.posting_date)
outstanding_amount = ref_doc.get("outstanding_amount") \
if reference_doctype in ("Sales Invoice", "Purchase Invoice") \
else flt(total_amount) - flt(ref_doc.advance_paid)
if reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim") \
else flt(total_amount) - flt(ref_doc.advance_paid)
else:
# Get the exchange rate based on the posting date of the ref doc
exchange_rate = get_exchange_rate(party_account_currency,
exchange_rate = get_exchange_rate(party_account_currency,
ref_doc.company_currency, ref_doc.posting_date)
return frappe._dict({
"due_date": ref_doc.get("due_date"),
"total_amount": total_amount,
"outstanding_amount": outstanding_amount,
"exchange_rate": exchange_rate
})
@frappe.whitelist()
def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None):
doc = frappe.get_doc(dt, dn)
if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
frappe.throw(_("Can only make payment against unbilled {0}").format(dt))
party_type = "Customer" if dt in ("Sales Invoice", "Sales Order") else "Supplier"
if dt in ("Sales Invoice", "Sales Order"):
party_type = "Customer"
elif dt in ("Purchase Invoice", "Purchase Order"):
party_type = "Supplier"
elif dt in ("Expense Claim"):
party_type = "Employee"
# party account
if dt == "Sales Invoice":
@@ -650,16 +684,16 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
party_account = doc.credit_to
else:
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)
# payment type
if (dt == "Sales Order" or (dt=="Sales Invoice" and doc.outstanding_amount > 0)) \
or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
payment_type = "Receive"
else:
payment_type = "Pay"
# amounts
grand_total = outstanding_amount = 0
if party_amount:
@@ -667,15 +701,18 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
elif dt in ("Sales Invoice", "Purchase Invoice"):
grand_total = doc.base_grand_total if party_account_currency == doc.company_currency else doc.grand_total
outstanding_amount = doc.outstanding_amount
elif dt in ("Expense Claim"):
grand_total = doc.total_sanctioned_amount
outstanding_amount = doc.total_sanctioned_amount - doc.total_amount_reimbursed
else:
total_field = "base_grand_total" if party_account_currency == doc.company_currency else "grand_total"
grand_total = flt(doc.get(total_field))
outstanding_amount = grand_total - flt(doc.advance_paid)
# bank or cash
bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"),
bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"),
account=bank_account)
paid_amount = received_amount = 0
if party_account_currency == bank.account_currency:
paid_amount = received_amount = abs(outstanding_amount)
@@ -687,7 +724,7 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
received_amount = abs(outstanding_amount)
if bank_amount:
paid_amount = bank_amount
pe = frappe.new_doc("Payment Entry")
pe.payment_type = payment_type
pe.company = doc.company
@@ -704,7 +741,7 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
pe.received_amount = received_amount
pe.allocate_payment_amount = 1
pe.letter_head = doc.get("letter_head")
pe.append("references", {
"reference_doctype": dt,
"reference_name": dn,

View File

@@ -10,6 +10,7 @@ from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_orde
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, InvalidPaymentEntry
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
from erpnext.hr.doctype.expense_claim.test_expense_claim import make_expense_claim
test_dependencies = ["Item"]
@@ -20,80 +21,102 @@ class TestPaymentEntry(unittest.TestCase):
pe.paid_from = "Debtors - _TC"
pe.insert()
pe.submit()
expected_gle = dict((d[0], d) for d in [
["Debtors - _TC", 0, 1000, so.name],
["_Test Cash - _TC", 1000.0, 0, None]
])
self.validate_gl_entries(pe.name, expected_gle)
so_advance_paid = frappe.db.get_value("Sales Order", so.name, "advance_paid")
self.assertEqual(so_advance_paid, 1000)
pe.cancel()
self.assertFalse(self.get_gle(pe.name))
so_advance_paid = frappe.db.get_value("Sales Order", so.name, "advance_paid")
self.assertEqual(so_advance_paid, 0)
def test_payment_entry_against_si_usd_to_usd(self):
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
currency="USD", conversion_rate=50)
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
pe.reference_no = "1"
pe.reference_date = "2016-01-01"
pe.target_exchange_rate = 50
pe.target_exchange_rate = 50
pe.insert()
pe.submit()
expected_gle = dict((d[0], d) for d in [
["_Test Receivable USD - _TC", 0, 5000, si.name],
["_Test Bank USD - _TC", 5000.0, 0, None]
])
self.validate_gl_entries(pe.name, expected_gle)
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 0)
pe.cancel()
self.assertFalse(self.get_gle(pe.name))
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 100)
def test_payment_entry_against_pi(self):
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
currency="USD", conversion_rate=50)
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank USD - _TC")
pe.reference_no = "1"
pe.reference_date = "2016-01-01"
pe.source_exchange_rate = 50
pe.source_exchange_rate = 50
pe.insert()
pe.submit()
expected_gle = dict((d[0], d) for d in [
["_Test Payable USD - _TC", 12500, 0, pi.name],
["_Test Bank USD - _TC", 0, 12500, None]
])
self.validate_gl_entries(pe.name, expected_gle)
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", pi.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 0)
def test_payment_entry_against_ec(self):
payable = frappe.db.get_value('Company', "_Test Company", 'default_payable_account')
ec = make_expense_claim(payable, 300, 300, "_Test Company","Travel Expenses - _TC")
pe = get_payment_entry("Expense Claim", ec.name, bank_account="_Test Bank USD - _TC", bank_amount=300)
pe.reference_no = "1"
pe.reference_date = "2016-01-01"
pe.source_exchange_rate = 1
pe.insert()
pe.submit()
expected_gle = dict((d[0], d) for d in [
[payable, 300, 0, ec.name],
["_Test Bank USD - _TC", 0, 300, None]
])
self.validate_gl_entries(pe.name, expected_gle)
outstanding_amount = flt(frappe.db.get_value("Expense Claim", ec.name, "total_sanctioned_amount")) - \
flt(frappe.db.get_value("Expense Claim", ec.name, "total_amount_reimbursed"))
self.assertEqual(outstanding_amount, 0)
def test_payment_entry_against_si_usd_to_inr(self):
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
currency="USD", conversion_rate=50)
pe = get_payment_entry("Sales Invoice", si.name, party_amount=20,
pe = get_payment_entry("Sales Invoice", si.name, party_amount=20,
bank_account="_Test Bank - _TC", bank_amount=900)
pe.reference_no = "1"
pe.reference_date = "2016-01-01"
self.assertEqual(pe.difference_amount, 100)
pe.append("deductions", {
"account": "_Test Exchange Gain/Loss - _TC",
"cost_center": "_Test Cost Center - _TC",
@@ -101,15 +124,15 @@ class TestPaymentEntry(unittest.TestCase):
})
pe.insert()
pe.submit()
expected_gle = dict((d[0], d) for d in [
["_Test Receivable USD - _TC", 0, 1000, si.name],
["_Test Bank - _TC", 900, 0, None],
["_Test Exchange Gain/Loss - _TC", 100.0, 0, None],
])
self.validate_gl_entries(pe.name, expected_gle)
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 80)
@@ -140,7 +163,7 @@ class TestPaymentEntry(unittest.TestCase):
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")
pe.payment_type = "Internal Transfer"
@@ -152,31 +175,31 @@ class TestPaymentEntry(unittest.TestCase):
pe.received_amount = 4500
pe.reference_no = "2"
pe.reference_date = nowdate()
pe.setup_party_account_field()
pe.set_missing_values()
pe.set_exchange_rate()
pe.set_amounts()
self.assertEquals(pe.difference_amount, 500)
pe.append("deductions", {
"account": "_Test Exchange Gain/Loss - _TC",
"cost_center": "_Test Cost Center - _TC",
"amount": 500
})
pe.insert()
pe.submit()
expected_gle = dict((d[0], d) for d in [
["_Test Bank USD - _TC", 0, 5000, None],
["_Test Bank - _TC", 4500, 0, None],
["_Test Exchange Gain/Loss - _TC", 500.0, 0, None],
])
self.validate_gl_entries(pe.name, expected_gle)
def test_payment_against_negative_sales_invoice(self):
pe1 = frappe.new_doc("Payment Entry")
pe1.payment_type = "Pay"
@@ -186,33 +209,33 @@ class TestPaymentEntry(unittest.TestCase):
pe1.paid_from = "_Test Cash - _TC"
pe1.paid_amount = 100
pe1.received_amount = 100
self.assertRaises(InvalidPaymentEntry, pe1.validate)
si1 = create_sales_invoice()
# create full payment entry against si1
pe2 = get_payment_entry("Sales Invoice", si1.name, bank_account="_Test Cash - _TC")
pe2.insert()
pe2.submit()
# create return entry against si1
create_sales_invoice(is_return=1, return_against=si1.name, qty=-1)
si1_outstanding = frappe.db.get_value("Sales Invoice", si1.name, "outstanding_amount")
self.assertEqual(si1_outstanding, -100)
# pay more than outstanding against si1
pe3 = get_payment_entry("Sales Invoice", si1.name, bank_account="_Test Cash - _TC")
pe3.paid_amount = pe3.received_amount = 300
self.assertRaises(InvalidPaymentEntry, pe3.validate)
# pay negative outstanding against si1
pe3.paid_to = "Debtors - _TC"
pe3.paid_amount = pe3.received_amount = 100
pe3.insert()
pe3.submit()
expected_gle = dict((d[0], d) for d in [
["Debtors - _TC", 100, 0, si1.name],
["_Test Cash - _TC", 0, 100, None]
@@ -228,10 +251,10 @@ class TestPaymentEntry(unittest.TestCase):
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si1.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, -100)
def validate_gl_entries(self, voucher_no, expected_gle):
gl_entries = self.get_gle(voucher_no)
self.assertTrue(gl_entries)
for i, gle in enumerate(gl_entries):
@@ -239,7 +262,7 @@ class TestPaymentEntry(unittest.TestCase):
self.assertEquals(expected_gle[gle.account][1], gle.debit)
self.assertEquals(expected_gle[gle.account][2], gle.credit)
self.assertEquals(expected_gle[gle.account][3], gle.against_voucher)
def get_gle(self, voucher_no):
return frappe.db.sql("""select account, debit, credit, against_voucher
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s

View File

@@ -11,6 +11,7 @@ from erpnext.accounts.party import get_party_account
from erpnext.accounts.utils import get_account_currency
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, get_company_defaults
from frappe.integrations.utils import get_payment_gateway_controller
from frappe.utils.background_jobs import enqueue
class PaymentRequest(Document):
def validate(self):
@@ -37,10 +38,11 @@ class PaymentRequest(Document):
self.make_communication_entry()
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart") \
or self.flags.mute_email:
send_mail = False
if send_mail and not self.flags.mute_email:
if send_mail:
self.set_payment_request_url()
self.send_email()
@@ -50,7 +52,7 @@ class PaymentRequest(Document):
def make_invoice(self):
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"):
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
si = make_sales_invoice(self.reference_name, ignore_permissions=True)
si = si.insert(ignore_permissions=True)
@@ -75,8 +77,8 @@ class PaymentRequest(Document):
return controller.get_payment_url(**{
"amount": flt(self.grand_total, self.precision("grand_total")),
"title": data.company,
"description": self.subject,
"title": data.company.encode("utf-8"),
"description": self.subject.encode("utf-8"),
"reference_doctype": "Payment Request",
"reference_docname": self.name,
"payer_email": self.email_to or frappe.session.user,
@@ -142,9 +144,15 @@ class PaymentRequest(Document):
def send_email(self):
"""send email with payment link"""
frappe.sendmail(recipients=self.email_to, sender=None, subject=self.subject,
message=self.get_message(), attachments=[frappe.attach_print(self.reference_doctype,
self.reference_name, file_name=self.reference_name, print_format=self.print_format)])
email_args = {
"recipients": self.email_to,
"sender": None,
"subject": self.subject,
"message": self.get_message(),
"now": True,
"attachments": [frappe.attach_print(self.reference_doctype, self.reference_name,
file_name=self.reference_name, print_format=self.print_format)]}
enqueue(method=frappe.sendmail, queue='short', timeout=300, async=True, **email_args)
def get_message(self):
"""return message with payment gateway link"""
@@ -216,12 +224,9 @@ def make_payment_request(**args):
"""Make payment request"""
args = frappe._dict(args)
ref_doc = frappe.get_doc(args.dt, args.dn)
gateway_account = get_gateway_details(args) or frappe._dict()
grand_total = get_amount(ref_doc, args.dt)
gateway_account = get_gateway_details(args) or frappe._dict()
existing_payment_request = frappe.db.get_value("Payment Request",
{"reference_doctype": args.dt, "reference_name": args.dn, "docstatus": ["!=", 2]})
@@ -244,22 +249,19 @@ def make_payment_request(**args):
"reference_name": args.dn
})
if args.return_doc:
return pr
if args.mute_email:
if args.order_type == "Shopping Cart" or args.mute_email:
pr.flags.mute_email = True
if args.submit_doc:
pr.insert(ignore_permissions=True)
pr.submit()
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
if args.order_type == "Shopping Cart":
frappe.db.commit()
frappe.local.response["type"] = "redirect"
frappe.local.response["location"] = pr.get_payment_url()
if not args.cart:
if args.return_doc:
return pr
return pr.as_dict()

View File

@@ -70,7 +70,7 @@ class TestPaymentRequest(unittest.TestCase):
so_inr = make_sales_order(currency="INR")
pr = make_payment_request(dt="Sales Order", dn=so_inr.name, recipient_id="saurabh@erpnext.com",
mute_email=1, submit_doc=1)
mute_email=1, submit_doc=1, return_doc=1)
pe = pr.set_as_paid()
so_inr = frappe.get_doc("Sales Order", so_inr.name)
@@ -81,7 +81,7 @@ class TestPaymentRequest(unittest.TestCase):
currency="USD", conversion_rate=50)
pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com",
mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1)
mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1, return_doc=1)
pe = pr.set_as_paid()

View File

@@ -721,38 +721,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "tc_name",
"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": "Terms and Conditions",
"length": 0,
"no_copy": 0,
"oldfieldname": "tc_name",
"oldfieldtype": "Link",
"options": "Terms and Conditions",
"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,
@@ -782,39 +750,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "territory",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Territory",
"length": 0,
"no_copy": 0,
"oldfieldname": "territory",
"oldfieldtype": "Link",
"options": "Territory",
"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,
@@ -847,6 +782,38 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "tc_name",
"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": "Terms and Conditions",
"length": 0,
"no_copy": 0,
"oldfieldname": "tc_name",
"oldfieldtype": "Link",
"options": "Terms and Conditions",
"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,
@@ -910,6 +877,129 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "customer_details",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "New Customer Details",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "territory",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Territory",
"length": 0,
"no_copy": 0,
"oldfieldname": "territory",
"oldfieldtype": "Link",
"options": "Territory",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_31",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "customer_group",
"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": "Customer Group",
"length": 0,
"no_copy": 0,
"options": "Customer Group",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -1201,7 +1291,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-16 17:04:33.165676",
"modified": "2017-07-28 03:40:03.253088",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",

View File

@@ -14,6 +14,8 @@ class POSProfile(Document):
self.check_for_duplicate()
self.validate_all_link_fields()
self.validate_duplicate_groups()
self.check_default_payment()
self.validate_customer_territory_group()
def check_for_duplicate(self):
res = frappe.db.sql("""select name, user from `tabPOS Profile`
@@ -48,6 +50,21 @@ class POSProfile(Document):
if len(customer_groups) != len(set(customer_groups)):
frappe.throw(_("Duplicate customer group found in the cutomer group table"), title = "Duplicate Customer Group")
def check_default_payment(self):
if self.payments:
default_mode_of_payment = [d.default for d in self.payments if d.default]
if not default_mode_of_payment:
frappe.throw(_("Set default mode of payment"))
if len(default_mode_of_payment) > 1:
frappe.throw(_("Multiple default mode of payment is not allowed"))
def validate_customer_territory_group(self):
if not self.territory:
frappe.throw(_("Territory is Required in POS Profile"), title="Mandatory Field")
if not self.customer_group:
frappe.throw(_("Customer Group is Required in POS Profile"), title="Mandatory Field")
def before_save(self):
set_account_for_mode_of_payment(self)

View File

@@ -0,0 +1,23 @@
/* eslint-disable */
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
QUnit.test("test: POS Profile", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially('POS Profile', [
// insert a new POS Profile
() => frappe.tests.make([
// values to be set
{key: 'value'}
]),
() => {
assert.equal(cur_frm.doc.key, 'value');
},
() => done()
]);
});

View File

@@ -31,6 +31,8 @@ class TestPOSProfile(unittest.TestCase):
frappe.db.sql("delete from `tabPOS Profile`")
def make_pos_profile():
frappe.db.sql("delete from `tabPOS Profile`")
pos_profile = frappe.get_doc({
"company": "_Test Company",
"cost_center": "_Test Cost Center - _TC",
@@ -42,6 +44,7 @@ def make_pos_profile():
"naming_series": "_T-POS Profile-",
"selling_price_list": "_Test Price List",
"territory": "_Test Territory",
"customer_group": frappe.db.get_value('Customer Group', {'is_group': 0}, 'name'),
"warehouse": "_Test Warehouse - _TC",
"write_off_account": "_Test Write Off - _TC",
"write_off_cost_center": "_Test Write Off Cost Center - _TC"

View File

@@ -285,8 +285,9 @@ def get_pricing_rules(args):
def filter_pricing_rules(args, pricing_rules):
# filter for qty
stock_qty = args.get('qty') * args.get('conversion_factor', 1)
if pricing_rules:
stock_qty = flt(args.get('qty')) * args.get('conversion_factor', 1)
pricing_rules = filter(lambda x: (flt(stock_qty)>=flt(x.min_qty)
and (flt(stock_qty)<=x.max_qty if x.max_qty else True)), pricing_rules)

View File

@@ -0,0 +1,28 @@
QUnit.module('Pricing Rule"');
QUnit.test("test pricing rule", function(assert) {
assert.expect(2);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make("Pricing Rule", [
{title: 'Test Pricing Rule'},
{item_code:'Test Product 2'},
{selling:1},
{applicable_for:'Customer'},
{customer:'Test Customer 3'},
{min_qty:1},
{max_qty:20},
{valid_upto: frappe.datetime.add_days(frappe.defaults.get_default("year_end_date"), 1)},
{discount_percentage:10},
{for_price_list:'Standard Selling'}
]);
},
() => {
assert.ok(cur_frm.doc.item_code=='Test Product 2');
assert.ok(cur_frm.doc.customer=='Test Customer 3');
},
() => done()
]);
});

View File

@@ -53,6 +53,9 @@ class PurchaseInvoice(BuyingController):
if (self.is_paid == 1):
self.validate_cash()
if self._action=="submit" and self.update_stock:
self.make_batches('warehouse')
self.check_conversion_rate()
self.validate_credit_to_acc()
self.clear_unallocated_advances("Purchase Invoice Advance", "advances")
@@ -510,7 +513,7 @@ class PurchaseInvoice(BuyingController):
i += 1
if self.update_stock and valuation_tax:
if self.auto_accounting_for_stock and self.update_stock and valuation_tax:
for cost_center, amount in valuation_tax.items():
gl_entries.append(
self.get_gl_dict({

View File

@@ -0,0 +1,43 @@
QUnit.module('Purchaes Invoice');
QUnit.test("test purchase invoice", function(assert) {
assert.expect(4);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Purchase Invoice', [
{supplier: 'Test Supplier'},
{items: [
[
{'qty': 5},
{'item_code': 'Test Product 1'},
{'rate':100},
]
]},
{update_stock:1},
{supplier_address: 'Test1-Billing'},
{contact_person: 'Contact 3-Test Supplier'},
{taxes_and_charges: 'TEST In State GST'},
{tc_name: 'Test Term 1'},
{terms: 'This is Test'}
]);
},
() => cur_frm.save(),
() => {
// get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
// get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
// get tax account head details
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
// grand_total Calculated
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
},
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@@ -403,6 +403,27 @@ class TestPurchaseInvoice(unittest.TestCase):
self.assertEquals(expected_gl_entries[gle.account][1], gle.debit)
self.assertEquals(expected_gl_entries[gle.account][2], gle.credit)
def test_auto_batch(self):
item_code = frappe.db.get_value('Item',
{'has_batch_no': 1, 'create_new_batch':1}, 'name')
if not item_code:
doc = frappe.get_doc({
'doctype': 'Item',
'is_stock_item': 1,
'item_code': 'test batch item',
'item_group': 'Products',
'has_batch_no': 1,
'create_new_batch': 1
}).insert(ignore_permissions=True)
item_code = doc.name
pi = make_purchase_invoice(update_stock=1, posting_date=frappe.utils.nowdate(),
posting_time=frappe.utils.nowtime(), item_code=item_code)
self.assertTrue(frappe.db.get_value('Batch',
{'item': item_code, 'reference_name': pi.name}))
def test_update_stock_and_purchase_return(self):
actual_qty_0 = get_qty_after_transaction()

View File

@@ -0,0 +1,26 @@
QUnit.module('Sales Taxes and Charges Template');
QUnit.test("test sales taxes and charges template", function(assert) {
assert.expect(1);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Purchase Taxes and Charges Template', [
{title: "TEST In State GST"},
{taxes:[
[
{charge_type:"On Net Total"},
{account_head:"CGST - "+frappe.get_abbr(frappe.defaults.get_default("Company")) }
],
[
{charge_type:"On Net Total"},
{account_head:"SGST - "+frappe.get_abbr(frappe.defaults.get_default("Company")) }
]
]}
]);
},
() => {assert.ok(cur_frm.doc.title=='TEST In State GST');},
() => done()
]);
});

View File

@@ -3,6 +3,7 @@
from __future__ import unicode_literals
import frappe, json
from frappe import _
from frappe.utils import nowdate
from erpnext.setup.utils import get_exchange_rate
from frappe.core.doctype.communication.email import make
@@ -20,6 +21,7 @@ def get_pos_data():
if pos_profile.get('name'):
pos_profile = frappe.get_doc('POS Profile', pos_profile.get('name'))
pos_profile.validate()
company_data = get_company_data(doc.company)
update_pos_profile_data(doc, pos_profile, company_data)
@@ -149,13 +151,8 @@ def get_items_list(pos_profile):
def get_item_groups(pos_profile):
item_group_dict = {}
if pos_profile.get('item_groups'):
item_groups = []
for d in pos_profile.get('item_groups'):
item_groups.extend(get_child_nodes('Item Group', d.item_group))
else:
item_groups = frappe.db.sql("""Select name,
lft, rgt from `tabItem Group` order by lft""", as_dict=1)
item_groups = frappe.db.sql("""Select name,
lft, rgt from `tabItem Group` order by lft""", as_dict=1)
for data in item_groups:
item_group_dict[data.name] = [data.lft, data.rgt]
@@ -323,8 +320,7 @@ def make_invoice(doc_list={}, email_queue_list={}, customers_list={}):
si_doc.set_posting_time = 1
si_doc.customer = get_customer_id(doc)
si_doc.due_date = doc.get('posting_date')
submit_invoice(si_doc, name, doc)
name_list.append(name)
name_list = submit_invoice(si_doc, name, doc, name_list)
else:
name_list.append(name)
@@ -378,13 +374,27 @@ def add_customer(data):
customer_doc.customer_name = data.get('full_name') or data.get('customer')
customer_doc.customer_pos_id = data.get('customer_pos_id')
customer_doc.customer_type = 'Company'
customer_doc.customer_group = frappe.db.get_single_value('Selling Settings', 'customer_group')
customer_doc.territory = frappe.db.get_single_value('Selling Settings', 'territory')
customer_doc.customer_group = get_customer_group(data)
customer_doc.territory = get_territory(data)
customer_doc.flags.ignore_mandatory = True
customer_doc.save(ignore_permissions = True)
frappe.db.commit()
return customer_doc.name
def get_territory(data):
if data.get('territory'):
return data.get('territory')
return frappe.db.get_single_value('Selling Settings',
'territory') or _('All Territories')
def get_customer_group(data):
if data.get('customer_group'):
return data.get('customer_group')
return frappe.db.get_single_value('Selling Settings',
'customer_group') or frappe.db.get_value('Customer Group', {'is_group': 0}, 'name')
def make_contact(args,customer):
if args.get('email_id') or args.get('phone'):
name = frappe.db.get_value('Dynamic Link',
@@ -464,19 +474,29 @@ def validate_item(doc):
frappe.db.commit()
def submit_invoice(si_doc, name, doc):
def submit_invoice(si_doc, name, doc, name_list):
try:
si_doc.insert()
si_doc.submit()
frappe.db.commit()
except Exception, e:
name_list.append(name)
except Exception as e:
if frappe.message_log: frappe.message_log.pop()
frappe.db.rollback()
save_invoice(e, si_doc, name)
frappe.log_error(frappe.get_traceback())
name_list = save_invoice(e, si_doc, name, name_list)
def save_invoice(e, si_doc, name):
if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}):
si_doc.docstatus = 0
si_doc.flags.ignore_mandatory = True
si_doc.due_date = si_doc.posting_date
si_doc.insert()
return name_list
def save_invoice(e, si_doc, name, name_list):
try:
if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}):
si_doc.docstatus = 0
si_doc.flags.ignore_mandatory = True
si_doc.due_date = si_doc.posting_date
si_doc.insert()
name_list.append(name)
except Exception:
frappe.log_error(frappe.get_traceback())
return name_list

View File

@@ -325,23 +325,6 @@ 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", "");
}
}
});

View File

@@ -19,6 +19,7 @@ from erpnext.accounts.doctype.asset.depreciation \
import get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal
from erpnext.stock.doctype.batch.batch import set_batch_nos
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos, get_delivery_note_serial_no
from erpnext.setup.doctype.company.company import update_company_current_month_sales
form_grid_templates = {
"items": "templates/form_grid/item_grid.html"
@@ -140,7 +141,7 @@ class SalesInvoice(SellingController):
self.update_time_sheet(self.name)
frappe.enqueue('erpnext.setup.doctype.company.company.update_company_current_month_sales', company=self.company)
self.update_current_month_sales()
def validate_pos_paid_amount(self):
if len(self.payments) == 0 and self.is_pos:
@@ -178,6 +179,15 @@ class SalesInvoice(SellingController):
self.make_gl_entries_on_cancel()
frappe.db.set(self, 'status', 'Cancelled')
self.update_current_month_sales()
def update_current_month_sales(self):
if frappe.flags.in_test:
update_company_current_month_sales(self.company)
else:
frappe.enqueue('erpnext.setup.doctype.company.company.update_company_current_month_sales',
company=self.company)
def update_status_updater_args(self):
if cint(self.update_stock):
self.status_updater.extend([{

View File

@@ -0,0 +1,43 @@
QUnit.module('Sales Invoice');
QUnit.test("test sales Invoice", function(assert) {
assert.expect(4);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Sales Invoice', [
{customer: 'Test Customer 1'},
{items: [
[
{'qty': 5},
{'item_code': 'Test Product 1'},
]
]},
{update_stock:1},
{customer_address: 'Test1-Billing'},
{shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'},
{tc_name: 'Test Term 1'},
{terms: 'This is Test'}
]);
},
() => cur_frm.save(),
() => {
// get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
// get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
// get tax account head details
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
// grand_total Calculated
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
},
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@@ -5,6 +5,7 @@ from __future__ import unicode_literals
import frappe
import unittest, copy
from frappe.utils import nowdate, add_days, flt
from frappe.model.dynamic_links import get_dynamic_link_map
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice
from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
@@ -167,15 +168,15 @@ class TestSalesInvoice(unittest.TestCase):
"_Test Account S&H Education Cess - _TC": [1.5, 1619.5, 0.03, 32.39],
"_Test Account CST - _TC": [32.5, 1652, 0.65, 33.04],
"_Test Account VAT - _TC": [156.5, 1808.5, 3.13, 36.17],
"_Test Account Discount - _TC": [-180.5, 1628, -3.61, 32.56]
"_Test Account Discount - _TC": [-181.0, 1627.5, -3.62, 32.55]
}
for d in si.get("taxes"):
for i, k in enumerate(expected_values["keys"]):
self.assertEquals(d.get(k), expected_values[d.account_head][i])
self.assertEquals(si.base_grand_total, 1628)
self.assertEquals(si.grand_total, 32.56)
self.assertEquals(si.base_grand_total, 1627.5)
self.assertEquals(si.grand_total, 32.55)
def test_sales_invoice_with_discount_and_inclusive_tax(self):
si = create_sales_invoice(qty=100, rate=50, do_not_save=True)
@@ -235,21 +236,29 @@ class TestSalesInvoice(unittest.TestCase):
"item_code": "_Test Item Home Desktop 100",
"price_list_rate": 62.5,
"discount_percentage": 0,
"rate": 62.5, "amount": 625,
"rate": 62.5,
"amount": 625,
"base_price_list_rate": 62.5,
"base_rate": 62.5, "base_amount": 625,
"net_rate": 46.54, "net_amount": 465.37,
"base_net_rate": 46.54, "base_net_amount": 465.37
"base_rate": 62.5,
"base_amount": 625,
"net_rate": 46.54,
"net_amount": 465.37,
"base_net_rate": 46.54,
"base_net_amount": 465.37
},
{
"item_code": "_Test Item Home Desktop 200",
"price_list_rate": 190.66,
"discount_percentage": 0,
"rate": 190.66, "amount": 953.3,
"rate": 190.66,
"amount": 953.3,
"base_price_list_rate": 190.66,
"base_rate": 190.66, "base_amount": 953.3,
"net_rate": 139.62, "net_amount": 698.08,
"base_net_rate": 139.62, "base_net_amount": 698.08
"base_rate": 190.66,
"base_amount": 953.3,
"net_rate": 139.62,
"net_amount": 698.08,
"base_net_rate": 139.62,
"base_net_amount": 698.08
}
]
@@ -270,13 +279,13 @@ class TestSalesInvoice(unittest.TestCase):
"keys": ["tax_amount", "tax_amount_after_discount_amount", "total"],
"_Test Account Excise Duty - _TC": [140, 130.31, 1293.76],
"_Test Account Education Cess - _TC": [2.8, 2.61, 1296.37],
"_Test Account S&H Education Cess - _TC": [1.4, 1.31, 1297.68],
"_Test Account CST - _TC": [27.88, 25.96, 1323.64],
"_Test Account VAT - _TC": [156.25, 145.43, 1469.07],
"_Test Account Customs Duty - _TC": [125, 116.35, 1585.42],
"_Test Account Shipping Charges - _TC": [100, 100, 1685.42],
"_Test Account Discount - _TC": [-180.33, -168.54, 1516.88],
"_Test Account Service Tax - _TC": [-18.03, -16.88, 1500]
"_Test Account S&H Education Cess - _TC": [1.4, 1.30, 1297.67],
"_Test Account CST - _TC": [27.88, 25.95, 1323.62],
"_Test Account VAT - _TC": [156.25, 145.43, 1469.05],
"_Test Account Customs Duty - _TC": [125, 116.35, 1585.40],
"_Test Account Shipping Charges - _TC": [100, 100, 1685.40],
"_Test Account Discount - _TC": [-180.33, -168.54, 1516.86],
"_Test Account Service Tax - _TC": [-18.03, -16.86, 1500]
}
for d in si.get("taxes"):
@@ -312,13 +321,13 @@ class TestSalesInvoice(unittest.TestCase):
[test_records[3]["items"][0]["income_account"], 0.0, 1163.45],
[test_records[3]["taxes"][0]["account_head"], 0.0, 130.31],
[test_records[3]["taxes"][1]["account_head"], 0.0, 2.61],
[test_records[3]["taxes"][2]["account_head"], 0.0, 1.31],
[test_records[3]["taxes"][3]["account_head"], 0.0, 25.96],
[test_records[3]["taxes"][2]["account_head"], 0.0, 1.30],
[test_records[3]["taxes"][3]["account_head"], 0.0, 25.95],
[test_records[3]["taxes"][4]["account_head"], 0.0, 145.43],
[test_records[3]["taxes"][5]["account_head"], 0.0, 116.35],
[test_records[3]["taxes"][6]["account_head"], 0.0, 100],
[test_records[3]["taxes"][7]["account_head"], 168.54, 0.0],
["_Test Account Service Tax - _TC", 16.88, 0.0],
["_Test Account Service Tax - _TC", 16.86, 0.0]
])
for gle in gl_entries:
@@ -334,6 +343,61 @@ class TestSalesInvoice(unittest.TestCase):
self.assertFalse(gle)
def test_tax_calculation_with_multiple_items(self):
si = create_sales_invoice(qty=84, rate=4.6, do_not_save=True)
item_row = si.get("items")[0]
for qty in (54, 288, 144, 430):
item_row_copy = copy.deepcopy(item_row)
item_row_copy.qty = qty
si.append("items", item_row_copy)
si.append("taxes", {
"account_head": "_Test Account VAT - _TC",
"charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC",
"description": "VAT",
"doctype": "Sales Taxes and Charges",
"rate": 19
})
si.insert()
self.assertEquals(si.net_total, 4600)
self.assertEquals(si.get("taxes")[0].tax_amount, 874.0)
self.assertEquals(si.get("taxes")[0].total, 5474.0)
self.assertEquals(si.grand_total, 5474.0)
def test_tax_calculation_with_multiple_items_and_discount(self):
si = create_sales_invoice(qty=1, rate=75, do_not_save=True)
item_row = si.get("items")[0]
for rate in (500, 200, 100, 50, 50):
item_row_copy = copy.deepcopy(item_row)
item_row_copy.price_list_rate = rate
item_row_copy.rate = rate
si.append("items", item_row_copy)
si.apply_discount_on = "Net Total"
si.discount_amount = 75.0
si.append("taxes", {
"account_head": "_Test Account VAT - _TC",
"charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC",
"description": "VAT",
"doctype": "Sales Taxes and Charges",
"rate": 24
})
si.insert()
self.assertEquals(si.total, 975)
self.assertEquals(si.net_total, 900)
self.assertEquals(si.get("taxes")[0].tax_amount, 216.0)
self.assertEquals(si.get("taxes")[0].total, 1116.0)
self.assertEquals(si.grand_total, 1116.0)
def test_inclusive_rate_validations(self):
si = frappe.copy_doc(test_records[2])
for i, tax in enumerate(si.get("taxes")):
@@ -416,21 +480,29 @@ class TestSalesInvoice(unittest.TestCase):
"item_code": "_Test Item Home Desktop 100",
"price_list_rate": 55.56,
"discount_percentage": 10,
"rate": 50, "amount": 500,
"rate": 50,
"amount": 500,
"base_price_list_rate": 2778,
"base_rate": 2500, "base_amount": 25000,
"net_rate": 40, "net_amount": 399.98,
"base_net_rate": 2000, "base_net_amount": 19999
"base_rate": 2500,
"base_amount": 25000,
"net_rate": 40,
"net_amount": 399.98,
"base_net_rate": 2000,
"base_net_amount": 19999
},
{
"item_code": "_Test Item Home Desktop 200",
"price_list_rate": 187.5,
"discount_percentage": 20,
"rate": 150, "amount": 750,
"rate": 150,
"amount": 750,
"base_price_list_rate": 9375,
"base_rate": 7500, "base_amount": 37500,
"net_rate": 118.01, "net_amount": 590.05,
"base_net_rate": 5900.5, "base_net_amount": 29502.5
"base_rate": 7500,
"base_amount": 37500,
"net_rate": 118.01,
"net_amount": 590.05,
"base_net_rate": 5900.5,
"base_net_amount": 29502.5
}
]
@@ -450,22 +522,22 @@ class TestSalesInvoice(unittest.TestCase):
# check tax calculation
expected_values = {
"keys": ["base_tax_amount", "base_total", "tax_amount", "total"],
"_Test Account Excise Duty - _TC": [5540.5, 55042, 110.81, 1100.84],
"_Test Account Education Cess - _TC": [111, 55153, 2.22, 1103.06],
"_Test Account S&H Education Cess - _TC": [55.5, 55208.5, 1.11, 1104.17],
"_Test Account CST - _TC": [1104, 56312.5, 22.08, 1126.25],
"_Test Account VAT - _TC": [6188, 62500.5, 123.76, 1250.01],
"_Test Account Customs Duty - _TC": [4950.5, 67451, 99.01, 1349.02],
"_Test Account Shipping Charges - _TC": [ 100, 67551, 2, 1351.02],
"_Test Account Discount - _TC": [ -6755, 60796, -135.10, 1215.92]
"_Test Account Excise Duty - _TC": [5540.0, 55041.5, 110.80, 1100.83],
"_Test Account Education Cess - _TC": [111, 55152.5, 2.22, 1103.05],
"_Test Account S&H Education Cess - _TC": [55.5, 55208.0, 1.11, 1104.16],
"_Test Account CST - _TC": [1104, 56312.0, 22.08, 1126.24],
"_Test Account VAT - _TC": [6187.5, 62499.5, 123.75, 1249.99],
"_Test Account Customs Duty - _TC": [4950.0, 67449.5, 99.0, 1348.99],
"_Test Account Shipping Charges - _TC": [ 100, 67549.5, 2, 1350.99],
"_Test Account Discount - _TC": [ -6755, 60794.5, -135.10, 1215.89]
}
for d in si.get("taxes"):
for i, k in enumerate(expected_values["keys"]):
self.assertEquals(d.get(k), expected_values[d.account_head][i])
self.assertEquals(si.base_grand_total, 60796)
self.assertEquals(si.grand_total, 1215.92)
self.assertEquals(si.base_grand_total, 60794.5)
self.assertEquals(si.grand_total, 1215.89)
def test_outstanding(self):
w = self.make()
@@ -485,6 +557,12 @@ class TestSalesInvoice(unittest.TestCase):
self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 161.8)
link_data = get_dynamic_link_map().get('Sales Invoice', [])
link_doctypes = [d.parent for d in link_data]
# test case for dynamic link order
self.assertTrue(link_doctypes.index('GL Entry') > link_doctypes.index('Journal Entry Account'))
jv.cancel()
self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 561.8)
@@ -910,19 +988,20 @@ class TestSalesInvoice(unittest.TestCase):
"_Test Account Excise Duty - _TC": [70, 70, 70],
"_Test Account Education Cess - _TC": [1.4, 1.4, 1.4],
"_Test Account S&H Education Cess - _TC": [.7, 0.7, 0.7],
"_Test Account CST - _TC": [17.2, 17.2, 17.2],
"_Test Account CST - _TC": [17.19, 17.19, 17.19],
"_Test Account VAT - _TC": [78.13, 78.13, 78.13],
"_Test Account Discount - _TC": [-95.49, -95.49, -95.49]
}
for d in si.get("taxes"):
for i, k in enumerate(expected_values["keys"]):
self.assertEquals(d.get(k), expected_values[d.account_head][i])
if expected_values.get(d.account_head):
self.assertEquals(d.get(k), expected_values[d.account_head][i])
self.assertEquals(si.total_taxes_and_charges, 234.44)
self.assertEquals(si.base_grand_total, 859.44)
self.assertEquals(si.grand_total, 859.44)
self.assertEquals(si.total_taxes_and_charges, 234.43)
self.assertEquals(si.base_grand_total, 859.43)
self.assertEquals(si.grand_total, 859.43)
def test_multi_currency_gle(self):
set_perpetual_inventory(0)
@@ -1193,6 +1272,17 @@ class TestSalesInvoice(unittest.TestCase):
si.insert()
return si
def test_company_monthly_sales(self):
existing_current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
si = create_sales_invoice()
current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
self.assertEqual(current_month_sales, existing_current_month_sales + si.base_grand_total)
si.cancel()
current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
self.assertEqual(current_month_sales, existing_current_month_sales)
def create_sales_invoice(**args):
si = frappe.new_doc("Sales Invoice")
args = frappe._dict(args)

View File

@@ -0,0 +1,43 @@
QUnit.module('Sales Invoice');
QUnit.test("test sales Invoice", function(assert) {
assert.expect(4);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Sales Invoice', [
{customer: 'Test Customer 1'},
{items: [
[
{'qty': 5},
{'item_code': 'Test Product 1'},
]
]},
{update_stock:1},
{customer_address: 'Test1-Billing'},
{shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'},
{tc_name: 'Test Term 1'},
{terms: 'This is Test'}
]);
},
() => cur_frm.save(),
() => {
// get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
// get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
// get tax account head details
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
// grand_total Calculated
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
},
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@@ -0,0 +1,56 @@
QUnit.module('Sales Invoice');
QUnit.test("test sales Invoice with payment", function(assert) {
assert.expect(4);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Sales Invoice', [
{customer: 'Test Customer 1'},
{items: [
[
{'qty': 5},
{'item_code': 'Test Product 1'},
]
]},
{update_stock:1},
{customer_address: 'Test1-Billing'},
{shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'},
{tc_name: 'Test Term 1'},
{terms: 'This is Test'}
]);
},
() => cur_frm.save(),
() => {
// get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
// get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
// grand_total Calculated
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
},
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(2),
() => frappe.tests.click_button('Close'),
() => frappe.tests.click_button('Make'),
() => frappe.tests.click_link('Payment'),
() => frappe.timeout(0.2),
() => { cur_frm.set_value('mode_of_payment','Cash');},
() => { cur_frm.set_value('paid_to','Cash - '+frappe.get_abbr(frappe.defaults.get_default('Company')));},
() => {cur_frm.set_value('reference_no','TEST1234');},
() => {cur_frm.set_value('reference_date',frappe.datetime.add_days(frappe.datetime.nowdate(), 0));},
() => cur_frm.save(),
() => {
// get payment details
assert.ok(cur_frm.doc.paid_amount==590, "Paid Amount Correct");
},
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => done()
]);
});

View File

@@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
@@ -11,16 +12,51 @@
"editable_grid": 1,
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:parent.doctype == 'POS Profile'",
"fieldname": "default",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Default",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "mode_of_payment",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Mode of Payment",
"length": 0,
"no_copy": 0,
@@ -30,6 +66,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@@ -37,9 +74,11 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0.0",
"depends_on": "eval:parent.doctype == 'Sales Invoice'",
"fieldname": "amount",
@@ -48,7 +87,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,
@@ -58,6 +99,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@@ -65,16 +107,20 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -82,6 +128,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,
@@ -89,16 +136,20 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Account",
"length": 0,
"no_copy": 0,
@@ -108,6 +159,7 @@
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -115,16 +167,20 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "type",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Type",
"length": 0,
"no_copy": 0,
@@ -134,6 +190,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,
@@ -141,16 +198,20 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "base_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Base Amount (Company Currency)",
"length": 0,
"no_copy": 1,
@@ -160,6 +221,7 @@
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -167,17 +229,17 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-07-11 03:28:07.779228",
"modified": "2017-07-24 17:25:03.765856",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Payment",
@@ -187,7 +249,9 @@
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0
}

View File

@@ -0,0 +1,26 @@
QUnit.module('Sales Taxes and Charges Template');
QUnit.test("test sales taxes and charges template", function(assert) {
assert.expect(1);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Sales Taxes and Charges Template', [
{title: "TEST In State GST"},
{taxes:[
[
{charge_type:"On Net Total"},
{account_head:"CGST - "+frappe.get_abbr(frappe.defaults.get_default("Company")) }
],
[
{charge_type:"On Net Total"},
{account_head:"SGST - "+frappe.get_abbr(frappe.defaults.get_default("Company")) }
]
]}
]);
},
() => {assert.ok(cur_frm.doc.title=='TEST In State GST');},
() => done()
]);
});

View File

@@ -0,0 +1,35 @@
QUnit.module('Shipping Rule');
QUnit.test("test Shipping Rule", function(assert) {
assert.expect(1);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make("Shipping Rule", [
{label: "Next Day Shipping"},
{conditions:[
[
{from_value:1},
{to_value:200},
{shipping_amount:100}
],
[
{from_value:201},
{to_value:2000},
{shipping_amount:50}
],
]},
{countries:[
[
{country:'India'}
]
]},
{account:'Accounts Payable - '+frappe.get_abbr(frappe.defaults.get_default("Company"))},
{cost_center:'Main - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]);
},
() => {assert.ok(cur_frm.doc.name=='Next Day Shipping');},
() => done()
]);
});

View File

@@ -20,20 +20,22 @@ frappe.ui.form.on("Tax Rule", "refresh", function(frm) {
})
frappe.ui.form.on("Tax Rule", "customer", function(frm) {
frappe.call({
method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
args: {
"party": frm.doc.customer,
"party_type": "customer"
},
callback: function(r) {
if(!r.exc) {
$.each(r.message, function(k, v) {
frm.set_value(k, v);
});
if(frm.doc.customer) {
frappe.call({
method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
args: {
"party": frm.doc.customer,
"party_type": "customer"
},
callback: function(r) {
if(!r.exc) {
$.each(r.message, function(k, v) {
frm.set_value(k, v);
});
}
}
}
});
});
}
});
frappe.ui.form.on("Tax Rule", "supplier", function(frm) {

View File

@@ -8,6 +8,7 @@ from frappe import _
from frappe.model.document import Document
from frappe.utils import cstr, cint
from frappe.contacts.doctype.address.address import get_default_address
from erpnext.setup.doctype.customer_group.customer_group import get_parent_customer_groups
class IncorrectCustomerGroup(frappe.ValidationError): pass
class IncorrectSupplierType(frappe.ValidationError): pass
@@ -134,6 +135,9 @@ def get_tax_template(posting_date, args):
for key, value in args.iteritems():
if key=="use_for_shopping_cart":
conditions.append("use_for_shopping_cart = {0}".format(1 if value else 0))
if key == 'customer_group' and value:
customer_group_condition = get_customer_group_condition(value)
conditions.append("ifnull({0}, '') in ('', {1})".format(key, customer_group_condition))
else:
conditions.append("ifnull({0}, '') in ('', '{1}')".format(key, frappe.db.escape(cstr(value))))
@@ -157,3 +161,10 @@ def get_tax_template(posting_date, args):
return None
return tax_template
def get_customer_group_condition(customer_group):
condition = ""
customer_groups = ["'%s'"%(frappe.db.escape(d.name)) for d in get_parent_customer_groups(customer_group)]
if customer_groups:
condition = ",".join(['%s'] * len(customer_groups))%(tuple(customer_groups))
return condition

View File

@@ -34,6 +34,14 @@ class TestTaxRule(unittest.TestCase):
tax_rule2.save()
self.assertTrue(tax_rule2.name)
def test_for_parent_customer_group(self):
tax_rule1 = make_tax_rule(customer_group= "All Customer Groups",
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01")
tax_rule1.save()
self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial"}),
"_Test Sales Taxes and Charges Template")
def test_conflict_with_overlapping_dates(self):
tax_rule1 = make_tax_rule(customer= "_Test Customer",
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01", to_date = "2015-01-05")

View File

@@ -426,11 +426,16 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
});
this.serach_item.make_input();
this.serach_item.$input.on("keyup", function () {
setTimeout(function () {
me.items = me.get_items();
me.make_item_list();
}, 1000);
this.serach_item.$input.on("keypress", function (event) {
clearTimeout(me.last_search_timeout);
me.last_search_timeout = setTimeout(() => {
if((me.serach_item.$input.val() != "") || (event.which == 13)) {
me.items = me.get_items();
me.make_item_list();
}
}, 400);
});
this.search_item_group = this.wrapper.find('.search-item-group');
@@ -727,14 +732,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
input = input.toLowerCase();
item = this.get_item(item.value);
var searchtext =
Object.keys(item)
.filter(key => ['customer_name', 'customer_group', 'value', 'label', 'email_id', 'phone', 'mobile_no'].includes(key))
.map(key => item[key])
.join(" ")
.toLowerCase();
return searchtext.includes(input)
return item.searchtext.includes(input)
},
item: function (item, input) {
var d = this.get_item(item.value);
@@ -808,7 +806,11 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
territory: c.territory,
phone: contact ? contact["phone"] : '',
mobile_no: contact ? contact["mobile_no"] : '',
email_id: contact ? contact["email_id"] : ''
email_id: contact ? contact["email_id"] : '',
searchtext: ['customer_name', 'customer_group', 'value',
'label', 'email_id', 'phone', 'mobile_no']
.map(key => c[key]).join(' ')
.toLowerCase()
}
});
@@ -979,6 +981,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
get_prompt_details: function() {
this.prompt_details = this.customer_doc.get_values();
this.prompt_details['country'] = this.pos_profile_data.country;
this.prompt_details['territory'] = this.pos_profile_data["territory"];
this.prompt_details['customer_group'] = this.pos_profile_data["customer_group"];
this.prompt_details['customer_pos_id'] = this.customer_doc.fields_dict.customer_pos_id.value;
return JSON.stringify(this.prompt_details)
},

View File

@@ -0,0 +1,61 @@
QUnit.test("test:POS Profile", function(assert) {
assert.expect(1);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make("POS Profile", [
{naming_series: "SINV"},
{company: "Test Company"},
{country: "India"},
{currency: "INR"},
{write_off_account: "Write Off - TC"},
{write_off_cost_center: "Main - TC"},
{payments: [
[
{"default": 1},
{"mode_of_payment": "Cash"}
]]
}
]);
},
() => cur_frm.save(),
() => frappe.timeout(2),
() => {
assert.equal(cur_frm.doc.payments[0].default, 1, "Default mode of payment tested");
},
() => done()
]);
});
QUnit.test("test:Sales Invoice", function(assert) {
assert.expect(2);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make("Sales Invoice", [
{customer: "Test Customer 2"},
{company: "Test Company"},
{is_pos: 1},
{posting_date: frappe.datetime.get_today()},
{due_date: frappe.datetime.get_today()},
{items: [
[
{"item_code": "Test Product 1"},
{"qty": 5},
{"warehouse":'Stores - TC'}
]]
}
]);
},
() => frappe.timeout(2),
() => cur_frm.save(),
() => frappe.timeout(2),
() => {
assert.equal(cur_frm.doc.payments[0].default, 1, "Default mode of payment tested");
assert.equal(cur_frm.doc.payments[0].mode_of_payment, "Cash", "Default mode of payment tested");
},
() => done()
]);
});

View File

@@ -15,7 +15,8 @@ from frappe.contacts.doctype.address.address import (get_address_display,
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
from erpnext import get_default_currency, get_company_currency
class DuplicatePartyAccountError(frappe.ValidationError): pass
@@ -43,6 +44,7 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
frappe.throw(_("Not permitted for {0}").format(party), frappe.PermissionError)
party = frappe.get_doc(party_type, party)
currency = party.default_currency if party.default_currency else get_company_currency(company)
set_address_details(out, party, party_type, doctype, company)
set_contact_details(out, party, party_type)
@@ -77,7 +79,7 @@ def set_address_details(out, party, party_type, doctype=None, company=None):
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']:
if doctype and doctype in ['Delivery Note', 'Sales Invoice']:
out.update(get_company_address(company))
if out.company_address:
out.update(get_fetch_values(doctype, 'company_address', out.company_address))
@@ -273,6 +275,7 @@ def get_due_date(posting_date, party_type, party, company):
return due_date
def get_credit_days(party_type, party, company):
credit_days = 0
if party_type and party:
if party_type == "Customer":
credit_days_based_on, credit_days, customer_group = \
@@ -282,10 +285,10 @@ def get_credit_days(party_type, party, company):
frappe.db.get_value(party_type, party, ["credit_days_based_on", "credit_days", "supplier_type"])
if not credit_days_based_on:
if party_type == "Customer":
if party_type == "Customer" and customer_group:
credit_days_based_on, credit_days = \
frappe.db.get_value("Customer Group", customer_group, ["credit_days_based_on", "credit_days"])
else:
elif party_type == "Supplier" and supplier_type:
credit_days_based_on, credit_days = \
frappe.db.get_value("Supplier Type", supplier_type, ["credit_days_based_on", "credit_days"])

View File

@@ -234,7 +234,7 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency
for period in period_list:
total_row.setdefault(period.key, 0.0)
total_row[period.key] += row.get(period.key, 0.0)
row[period.key] = ""
row[period.key] = 0.0
total_row.setdefault("total", 0.0)
total_row["total"] += flt(row["total"])

View File

@@ -209,7 +209,10 @@ class GrossProfitGenerator(object):
sle.voucher_detail_no == row.item_row:
previous_stock_value = len(my_sle) > i+1 and \
flt(my_sle[i+1].stock_value) or 0.0
return previous_stock_value - flt(sle.stock_value)
if previous_stock_value:
return previous_stock_value - flt(sle.stock_value)
else:
return flt(row.qty) * self.get_average_buying_rate(row, item_code)
else:
return flt(row.qty) * self.get_average_buying_rate(row, item_code)

View File

@@ -7,7 +7,7 @@ frappe.query_reports["Item-wise Purchase Register"] = {
"fieldname":"from_date",
"label": __("From Date"),
"fieldtype": "Date",
"default": frappe.defaults.get_user_default("year_start_date"),
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
"width": "80"
},
{

View File

@@ -2,9 +2,10 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
import frappe, erpnext
from frappe import _
from frappe.utils import flt
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import get_tax_accounts
def execute(filters=None):
return _execute(filters)
@@ -12,12 +13,14 @@ def execute(filters=None):
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = {}
columns = get_columns(additional_table_columns)
last_col = len(columns)
company_currency = erpnext.get_company_currency(filters.company)
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)
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency,
doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges")
columns.append({
"fieldname": "currency",
@@ -25,7 +28,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
"fieldtype": "Data",
"width": 80
})
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
po_pr_map = get_purchase_receipts_against_purchase_order(item_list)
data = []
for d in item_list:
@@ -33,8 +37,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
if d.purchase_receipt:
purchase_receipt = d.purchase_receipt
elif d.po_detail:
purchase_receipt = ", ".join(frappe.db.sql_list("""select distinct parent
from `tabPurchase Receipt Item` where docstatus=1 and purchase_order_item=%s""", d.po_detail))
purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, []))
expense_account = d.expense_account or aii_account_map.get(d.company)
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.supplier,
@@ -46,13 +49,15 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
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
purchase_receipt, expense_account, d.qty, d.stock_uom, d.base_net_rate, d.base_net_amount
]
for tax in tax_accounts:
row.append(item_row_tax.get(d.name, {}).get(tax, 0))
total_tax = 0
for tax in tax_columns:
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
total_tax += flt(item_tax.get("tax_amount"))
total_tax = sum(row[last_col:])
row += [total_tax, d.base_net_amount + total_tax, company_currency]
data.append(row)
@@ -76,7 +81,8 @@ def get_columns(additional_table_columns):
_("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"
_("Qty") + ":Float:120", _("Stock UOM") + "::100",
_("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120"
]
return columns
@@ -106,8 +112,9 @@ def get_items(filters, additional_query_columns):
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 {0}
pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.stock_uom,
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
@@ -116,53 +123,19 @@ def get_items(filters, additional_query_columns):
def get_aii_accounts():
return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))
def get_tax_accounts(item_list, columns):
import json
item_row_tax = {}
tax_accounts = []
invoice_item_row = {}
item_row_map = {}
for d in item_list:
invoice_item_row.setdefault(d.parent, []).append(d)
item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
def get_purchase_receipts_against_purchase_order(item_list):
po_pr_map = frappe._dict()
po_item_rows = list(set([d.po_detail for d in item_list]))
tax_details = frappe.db.sql("""
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 != '')
and category in ('Total', 'Valuation and Total')
and parent in (%s)
""" % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
if po_item_rows:
purchase_receipts = frappe.db.sql("""
select parent, purchase_order_item
from `tabPurchase Receipt Item`
where docstatus=1 and purchase_order_item in (%s)
group by purchase_order_item, parent
""" % (', '.join(['%s']*len(po_item_rows))), tuple(po_item_rows), as_dict=1)
for parent, account_head, item_wise_tax_detail, charge_type, tax_amount in tax_details:
if account_head not in tax_accounts:
tax_accounts.append(account_head)
for pr in purchase_receipts:
po_pr_map.setdefault(pr.po_detail, []).append(pr.parent)
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)
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:
for d in invoice_item_row.get(parent, []):
item_row_tax.setdefault(d.name, {})[account_head] = \
flt((tax_amount * d.base_net_amount) / d.base_net_total)
tax_accounts.sort()
columns += [account_head + ":Currency/currency:80" for account_head in tax_accounts]
columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:80"]
return item_row_tax, tax_accounts
return po_pr_map

View File

@@ -7,7 +7,7 @@ frappe.query_reports["Item-wise Sales Register"] = frappe.query_reports["Sales R
"fieldname":"from_date",
"label": __("From Date"),
"fieldtype": "Date",
"default": frappe.defaults.get_default("year_start_date"),
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
"width": "80"
},
{

View File

@@ -2,9 +2,10 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
import frappe, erpnext
from frappe import _
from frappe.utils import flt
from frappe.model.meta import get_field_precision
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
def execute(filters=None):
@@ -13,19 +14,20 @@ def execute(filters=None):
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = {}
columns = get_columns(additional_table_columns)
last_col = len(columns)
company_currency = erpnext.get_company_currency(filters.company)
item_list = get_items(filters, additional_query_columns)
if item_list:
item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
columns.append({
"fieldname": "currency",
"label": _("Currency"),
"fieldtype": "Data",
"width": 80
})
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]))
so_dn_map = get_delivery_notes_against_sales_order(item_list)
data = []
for d in item_list:
@@ -33,8 +35,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
if d.delivery_note:
delivery_note = d.delivery_note
elif d.so_detail:
delivery_note = ", ".join(frappe.db.sql_list("""select distinct parent
from `tabDelivery Note Item` where docstatus=1 and so_detail=%s""", d.so_detail))
delivery_note = ", ".join(so_dn_map.get(d.so_detail, []))
if not delivery_note and d.update_stock:
delivery_note = d.parent
@@ -47,13 +49,16 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
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.stock_uom,
d.base_net_rate, d.base_net_amount
]
for tax in tax_accounts:
row.append(item_row_tax.get(d.name, {}).get(tax, 0))
total_tax = 0
for tax in tax_columns:
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
total_tax += flt(item_tax.get("tax_amount"))
total_tax = sum(row[last_col:])
row += [total_tax, d.base_net_amount + total_tax, company_currency]
data.append(row)
@@ -77,7 +82,7 @@ def get_columns(additional_table_columns):
_("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100",
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
_("Income Account") + ":Link/Account:140", _("Cost Center") + ":Link/Cost Center:140",
_("Qty") + ":Float:120",
_("Qty") + ":Float:120", _("Stock UOM") + "::100",
_("Rate") + ":Currency/currency:120",
_("Amount") + ":Currency/currency:120"
]
@@ -112,62 +117,111 @@ def get_items(filters, additional_query_columns):
si_item.name, si_item.parent, si.posting_date, si.debit_to, si.project,
si.customer, si.remarks, si.territory, si.company, si.base_net_total,
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 {0}
si_item.delivery_note, si_item.income_account, si_item.cost_center,
si_item.qty, si_item.stock_uom, si_item.base_net_rate, si_item.base_net_amount,
si.customer_name, 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
""".format(additional_query_columns or '') % conditions, filters, as_dict=1)
def get_tax_accounts(item_list, columns):
def get_delivery_notes_against_sales_order(item_list):
so_dn_map = frappe._dict()
so_item_rows = list(set([d.so_detail for d in item_list]))
if so_item_rows:
delivery_notes = frappe.db.sql("""
select parent, so_detail
from `tabDelivery Note Item`
where docstatus=1 and so_detail in (%s)
group by so_detail, parent
""" % (', '.join(['%s']*len(so_item_rows))), tuple(so_item_rows), as_dict=1)
for dn in delivery_notes:
so_dn_map.setdefault(dn.so_detail, []).append(dn.parent)
return so_dn_map
def get_tax_accounts(item_list, columns, company_currency,
doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
import json
item_row_tax = {}
tax_accounts = []
invoice_item_row = {}
item_row_map = {}
tax_columns = []
invoice_item_row = {}
itemised_tax = {}
tax_amount_precision = get_field_precision(frappe.get_meta(tax_doctype).get_field("tax_amount"),
currency=company_currency) or 2
for d in item_list:
invoice_item_row.setdefault(d.parent, []).append(d)
item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
conditions = ""
if doctype == "Purchase Invoice":
conditions = " and category in ('Total', 'Valuation and Total')"
tax_details = frappe.db.sql("""
select
parent, account_head, item_wise_tax_detail,
parent, description, item_wise_tax_detail,
charge_type, base_tax_amount_after_discount_amount
from `tabSales Taxes and Charges`
from `tab%s`
where
parenttype = 'Sales Invoice' and docstatus = 1
and (account_head is not null and account_head != '')
parenttype = %s and docstatus = 1
and (description is not null and description != '')
and parent in (%s)
""" % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
%s
order by description
""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row)), conditions),
tuple([doctype] + invoice_item_row.keys()))
for parent, account_head, item_wise_tax_detail, charge_type, tax_amount in tax_details:
if account_head not in tax_accounts:
tax_accounts.append(account_head)
for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
if description not in tax_columns and tax_amount:
tax_columns.append(description)
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)
for item_code, tax_data in item_wise_tax_detail.items():
itemised_tax.setdefault(item_code, frappe._dict())
if isinstance(tax_data, list):
tax_rate, tax_amount = tax_data
else:
tax_rate = tax_data
tax_amount = 0
if charge_type == "Actual" and not tax_rate:
tax_rate = "NA"
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
item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) \
if item_net_amount else 0
if item_tax_amount:
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
"tax_rate": tax_rate,
"tax_amount": flt(item_tax_amount, tax_amount_precision)
})
except ValueError:
continue
elif charge_type == "Actual" and tax_amount:
for d in invoice_item_row.get(parent, []):
item_row_tax.setdefault(d.name, {})[account_head] = \
flt((tax_amount * d.base_net_amount) / d.base_net_total)
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
"tax_rate": "NA",
"tax_amount": flt((tax_amount * d.base_net_amount) / d.base_net_total,
tax_amount_precision)
})
tax_accounts.sort()
columns += [account_head + ":Currency/currency:80" for account_head in tax_accounts]
columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:80"]
tax_columns.sort()
for desc in tax_columns:
columns.append(desc + " Rate:Data:80")
columns.append(desc + " Amount:Currency/currency:100")
return item_row_tax, tax_accounts
columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:100"]
return itemised_tax, tax_columns

View File

@@ -7,7 +7,7 @@ frappe.query_reports["Purchase Register"] = {
"fieldname":"from_date",
"label": __("From Date"),
"fieldtype": "Date",
"default": frappe.defaults.get_user_default("year_start_date"),
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
"width": "80"
},
{

View File

@@ -7,7 +7,7 @@ frappe.query_reports["Sales Register"] = {
"fieldname":"from_date",
"label": __("From Date"),
"fieldtype": "Date",
"default": frappe.defaults.get_default("year_start_date"),
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
"width": "80"
},
{

View File

@@ -20,36 +20,36 @@ def get_fiscal_year(date=None, fiscal_year=None, label="Date", verbose=1, compan
def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verbose=1, company=None, as_dict=False):
fiscal_years = frappe.cache().hget("fiscal_years", company) or []
if not fiscal_years:
if not fiscal_years:
# if year start date is 2012-04-01, year end date should be 2013-03-31 (hence subdate)
cond = ""
if fiscal_year:
cond += " and fy.name = {0}".format(frappe.db.escape(fiscal_year))
if company:
cond += """
and (not exists (select name
from `tabFiscal Year Company` fyc
where fyc.parent = fy.name)
or exists(select company
from `tabFiscal Year Company` fyc
where fyc.parent = fy.name
and (not exists (select name
from `tabFiscal Year Company` fyc
where fyc.parent = fy.name)
or exists(select company
from `tabFiscal Year Company` fyc
where fyc.parent = fy.name
and fyc.company=%(company)s)
)
"""
fiscal_years = frappe.db.sql("""
select
fy.name, fy.year_start_date, fy.year_end_date
from
select
fy.name, fy.year_start_date, fy.year_end_date
from
`tabFiscal Year` fy
where
where
disabled = 0 {0}
order by
order by
fy.year_start_date desc""".format(cond), {
"company": company
}, as_dict=True)
frappe.cache().hset("fiscal_years", company, fiscal_years)
if transaction_date:
@@ -60,10 +60,10 @@ def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verb
if fiscal_year and fy.name == fiscal_year:
matched = True
if (transaction_date and getdate(fy.year_start_date) <= transaction_date
if (transaction_date and getdate(fy.year_start_date) <= transaction_date
and getdate(fy.year_end_date) >= transaction_date):
matched = True
if matched:
if as_dict:
return (fy,)
@@ -72,7 +72,7 @@ def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verb
error_msg = _("""{0} {1} not in any active Fiscal Year.""").format(label, formatdate(transaction_date))
if verbose==1: frappe.msgprint(error_msg)
raise FiscalYearError, error_msg
raise FiscalYearError(error_msg)
def validate_fiscal_year(date, fiscal_year, company, label="Date", doc=None):
years = [f[0] for f in get_fiscal_years(date, label=_(label), company=company)]
@@ -158,7 +158,6 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
return flt(bal)
def get_count_on(account, fieldname, date):
cond = []
if date:
cond.append("posting_date <= '%s'" % frappe.db.escape(cstr(date)))
@@ -195,11 +194,6 @@ def get_count_on(account, fieldname, date):
select name from `tabAccount` ac where ac.name = gle.account
and ac.lft >= %s and ac.rgt <= %s
)""" % (acc.lft, acc.rgt))
# If group and currency same as company,
# always return balance based on debit and credit in company currency
if acc.account_currency == frappe.db.get_value("Company", acc.company, "default_currency"):
in_account_currency = False
else:
cond.append("""gle.account = "%s" """ % (frappe.db.escape(account, percent=False), ))
@@ -227,7 +221,7 @@ def get_count_on(account, fieldname, date):
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,
{"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
@@ -274,7 +268,7 @@ def add_cc(args=None):
if not args:
args = frappe.local.form_dict
args.doctype = "Cost Center"
args = make_tree_args(**args)
@@ -500,7 +494,8 @@ def get_company_default(company, fieldname):
value = frappe.db.get_value("Company", company, fieldname)
if not value:
throw(_("Please set default {0} in Company {1}").format(frappe.get_meta("Company").get_label(fieldname), company))
throw(_("Please set default {0} in Company {1}")
.format(frappe.get_meta("Company").get_label(fieldname), company))
return value
@@ -534,18 +529,18 @@ def get_stock_and_account_difference(account_list=None, posting_date=None):
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))
difference.setdefault(account_data.get('account'), flt(stock_value) - flt(account_balance))
return difference
def get_currency_precision():
def get_currency_precision():
precision = cint(frappe.db.get_default("currency_precision"))
if not precision:
number_format = frappe.db.get_default("number_format") or "#,###.##"
precision = get_number_format_info(number_format)[2]
return precision
def get_stock_rbnb_difference(posting_date, company):
stock_items = frappe.db.sql_list("""select distinct item_code
from `tabStock Ledger Entry` where company=%s""", company)
@@ -585,9 +580,15 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
dr_or_cr = "credit_in_account_currency - debit_in_account_currency"
payment_dr_or_cr = "payment_gl_entry.debit_in_account_currency - payment_gl_entry.credit_in_account_currency"
invoice = 'Sales Invoice' if party_type == 'Customer' else 'Purchase Invoice'
invoice_list = frappe.db.sql("""
select
voucher_no, voucher_type, posting_date, ifnull(sum({dr_or_cr}), 0) as invoice_amount,
(
case when (voucher_type = 'Sales Invoice' or voucher_type = 'Purchase Invoice')
then (select due_date from `tab{invoice}` where name = voucher_no)
else posting_date end
) as due_date,
(
select ifnull(sum({payment_dr_or_cr}), 0)
from `tabGL Entry` payment_gl_entry
@@ -611,6 +612,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
having (invoice_amount - payment_amount) > 0.005
order by posting_date, name""".format(
dr_or_cr = dr_or_cr,
invoice = invoice,
payment_dr_or_cr = payment_dr_or_cr,
condition = condition or ""
), {
@@ -623,11 +625,13 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
outstanding_invoices.append(frappe._dict({
'voucher_no': d.voucher_no,
'voucher_type': d.voucher_type,
'due_date': d.due_date,
'posting_date': d.posting_date,
'invoice_amount': flt(d.invoice_amount),
'payment_amount': flt(d.payment_amount),
'outstanding_amount': flt(d.invoice_amount - d.payment_amount, precision),
'due_date': frappe.db.get_value(d.voucher_type, d.voucher_no, "due_date"),
'due_date': frappe.db.get_value(d.voucher_type, d.voucher_no,
"posting_date" if party_type=="Employee" else "due_date"),
}))
outstanding_invoices = sorted(outstanding_invoices, key=lambda k: k['due_date'] or getdate(nowdate()))
@@ -654,7 +658,7 @@ def get_companies():
@frappe.whitelist()
def get_children():
from erpnext.accounts.report.financial_statements import sort_root_accounts
args = frappe.local.form_dict
doctype, company = args['doctype'], args['company']
fieldname = frappe.db.escape(doctype.lower().replace(' ','_'))
@@ -695,9 +699,6 @@ def get_children():
return acc
def create_payment_gateway_account(gateway):
create_payment_gateway_account(gateway)
def create_payment_gateway_account(gateway):
from erpnext.setup.setup_wizard.setup_wizard import create_bank_account
@@ -738,4 +739,4 @@ def create_payment_gateway_account(gateway):
except frappe.DuplicateEntryError:
# already exists, due to a reinstall?
pass
pass

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -39,6 +39,8 @@ class PurchaseOrder(BuyingController):
super(PurchaseOrder, self).validate()
self.set_status()
self.validate_supplier()
validate_for_items(self)
self.check_for_closed_status()
@@ -65,6 +67,17 @@ class PurchaseOrder(BuyingController):
}
})
def validate_supplier(self):
prevent_po = frappe.db.get_value("Supplier", self.supplier, 'prevent_pos')
if prevent_po:
standing = frappe.db.get_value("Supplier Scorecard",self.supplier, 'status')
frappe.throw(_("Purchase Orders are not allowed for {0} due to a scorecard standing of {1}.").format(self.supplier, standing))
warn_po = frappe.db.get_value("Supplier", self.supplier, 'warn_pos')
if warn_po:
standing = frappe.db.get_value("Supplier Scorecard",self.supplier, 'status')
frappe.msgprint(_("{0} currently has a {1} Supplier Scorecard standing, and Purchase Orders to this supplier should be issued with caution.").format(self.supplier, standing), title=_("Caution"), indicator='orange')
def validate_minimum_order_qty(self):
items = list(set([d.item_code for d in self.get("items")]))

View File

@@ -0,0 +1,65 @@
QUnit.module('Buying');
QUnit.test("test: purchase order", function(assert) {
assert.expect(11);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Purchase Order', [
{supplier: 'Test Supplier'},
{is_subcontracted: 'No'},
{currency: 'INR'},
{items: [
[
{"item_code": 'Test Product 4'},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"qty": 5},
{"uom": 'Unit'},
{"rate": 100},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]
]},
{tc_name: 'Test Term 1'},
{terms: 'This is a term.'}
]);
},
() => {
// Get supplier details
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
assert.ok($('div.control-value.like-disabled-input.for-description').text().includes('Contact 3'), "Contact display correct");
assert.ok(cur_frm.doc.contact_email == 'test@supplier.com', "Contact email correct");
// Get item details
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item name correct");
assert.ok(cur_frm.doc.items[0].description == 'Test Product 4', "Description correct");
assert.ok(cur_frm.doc.items[0].qty == 5, "Quantity correct");
// Calculate total
assert.ok(cur_frm.doc.total == 500, "Total correct");
// Get terms
assert.ok(cur_frm.doc.terms == 'This is a term.', "Terms correct");
},
() => cur_frm.print_doc(),
() => frappe.timeout(2),
() => {
assert.ok($('.btn-print-print').is(':visible'), "Print Format Available");
assert.ok($('div > div:nth-child(5) > div > div > table > tbody > tr > td:nth-child(4) > div').text().includes('Test Product 4'), "Print Preview Works");
},
() => cur_frm.print_doc(),
() => frappe.timeout(1),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => {
assert.ok(cur_frm.doc.status == 'To Receive and Bill', "Submitted successfully");
},
() => done()
]);
});

View File

@@ -0,0 +1,61 @@
QUnit.module('Buying');
QUnit.test("test: purchase order with get items", function(assert) {
assert.expect(4);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Purchase Order', [
{supplier: 'Test Supplier'},
{is_subcontracted: 'No'},
{buying_price_list: 'Test-Buying-USD'},
{currency: 'USD'},
{items: [
[
{"item_code": 'Test Product 4'},
{"qty": 5},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]
]}
]);
},
() => {
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
},
() => frappe.timeout(0.3),
() => frappe.click_button('Get items from'),
() => frappe.timeout(0.3),
() => frappe.click_link('Product Bundle'),
() => frappe.timeout(0.5),
() => cur_dialog.set_value('product_bundle', 'Computer'),
() => frappe.click_button('Get Items'),
() => frappe.timeout(1),
// Check if items are fetched from Product Bundle
() => {
assert.ok(cur_frm.doc.items[1].item_name == 'CPU', "Product bundle item 1 correct");
assert.ok(cur_frm.doc.items[2].item_name == 'Screen', "Product bundle item 2 correct");
assert.ok(cur_frm.doc.items[3].item_name == 'Keyboard', "Product bundle item 3 correct");
},
() => cur_frm.doc.items[1].warehouse = 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company")),
() => cur_frm.doc.items[2].warehouse = 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company")),
() => cur_frm.doc.items[3].warehouse = 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company")),
() => cur_frm.save(),
() => frappe.timeout(1),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@@ -0,0 +1,74 @@
QUnit.module('Buying');
QUnit.test("test: purchase order receipt", function(assert) {
assert.expect(5);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Purchase Order', [
{supplier: 'Test Supplier'},
{is_subcontracted: 'No'},
{buying_price_list: 'Test-Buying-USD'},
{currency: 'USD'},
{items: [
[
{"item_code": 'Test Product 1'},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"qty": 5},
{"uom": 'Unit'},
{"rate": 100},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]
]},
]);
},
() => {
// Check supplier and item details
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 1', "Item name correct");
assert.ok(cur_frm.doc.items[0].description == 'Test Product 1', "Description correct");
assert.ok(cur_frm.doc.items[0].qty == 5, "Quantity correct");
},
() => frappe.timeout(1),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(1.5),
() => frappe.click_button('Close'),
() => frappe.timeout(0.3),
// Make Purchase Receipt
() => frappe.click_button('Make'),
() => frappe.timeout(0.3),
() => frappe.click_link('Receipt'),
() => frappe.timeout(2),
() => cur_frm.save(),
// Save and submit Purchase Receipt
() => frappe.timeout(1),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(1),
// View Purchase order in Stock Ledger
() => frappe.click_button('View'),
() => frappe.timeout(0.3),
() => frappe.click_link('Stock Ledger'),
() => frappe.timeout(2),
() => {
assert.ok($('div.slick-cell.l2.r2 > a').text().includes('Test Product 1')
&& $('div.slick-cell.l9.r9 > div').text().includes(5), "Stock ledger entry correct");
},
() => done()
]);
});

View File

@@ -0,0 +1,47 @@
QUnit.module('Buying');
QUnit.test("test: purchase order with discount on grand total", function(assert) {
assert.expect(4);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Purchase Order', [
{supplier: 'Test Supplier'},
{is_subcontracted: 'No'},
{buying_price_list: 'Test-Buying-EUR'},
{currency: 'EUR'},
{items: [
[
{"item_code": 'Test Product 4'},
{"qty": 5},
{"uom": 'Unit'},
{"rate": 500 },
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]
]},
{apply_discount_on: 'Grand Total'},
{additional_discount_percentage: 10}
]);
},
() => frappe.timeout(1),
() => {
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
assert.ok(cur_frm.doc.items[0].rate == 500, "Rate correct");
// Calculate total
assert.ok(cur_frm.doc.total == 2500, "Total correct");
// Calculate grand total after discount
assert.ok(cur_frm.doc.grand_total == 2250, "Grand total correct");
},
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@@ -0,0 +1,44 @@
QUnit.module('Buying');
QUnit.test("test: purchase order with item wise discount", function(assert) {
assert.expect(4);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Purchase Order', [
{supplier: 'Test Supplier'},
{is_subcontracted: 'No'},
{buying_price_list: 'Test-Buying-EUR'},
{currency: 'EUR'},
{items: [
[
{"item_code": 'Test Product 4'},
{"qty": 5},
{"uom": 'Unit'},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))},
{"discount_percentage": 20}
]
]}
]);
},
() => frappe.timeout(1),
() => {
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
assert.ok(cur_frm.doc.items[0].discount_percentage == 20, "Discount correct");
// Calculate totals after discount
assert.ok(cur_frm.doc.total == 2000, "Total correct");
assert.ok(cur_frm.doc.grand_total == 2000, "Grand total correct");
},
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@@ -0,0 +1,39 @@
QUnit.module('Buying');
QUnit.test("test: purchase order with multi UOM", function(assert) {
assert.expect(3);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Purchase Order', [
{supplier: 'Test Supplier'},
{is_subcontracted: 'No'},
{items: [
[
{"item_code": 'Test Product 4'},
{"qty": 5},
{"uom": 'Unit'},
{"rate": 100},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]
]}
]);
},
() => {
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item name correct");
assert.ok(cur_frm.doc.items[0].uom == 'Unit', "Multi UOM correct");
},
() => frappe.timeout(1),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@@ -0,0 +1,43 @@
QUnit.module('Buying');
QUnit.test("test: purchase order with taxes and charges", function(assert) {
assert.expect(3);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Purchase Order', [
{supplier: 'Test Supplier'},
{is_subcontracted: 'No'},
{buying_price_list: 'Test-Buying-USD'},
{currency: 'USD'},
{items: [
[
{"item_code": 'Test Product 4'},
{"qty": 5},
{"uom": 'Unit'},
{"rate": 500 },
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]
]},
{taxes_and_charges: 'TEST In State GST'}
]);
},
() => {
// Check taxes and calculate grand total
assert.ok(cur_frm.doc.taxes[1].account_head=='SGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), "Account Head abbr correct");
assert.ok(cur_frm.doc.total_taxes_and_charges == 225, "Taxes and charges correct");
assert.ok(cur_frm.doc.grand_total == 2725, "Grand total correct");
},
() => frappe.timeout(0.3),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@@ -14,6 +14,7 @@
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -45,6 +46,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -74,6 +76,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -104,6 +107,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -132,6 +136,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 1,
"collapsible": 0,
@@ -162,6 +167,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 1,
"collapsible": 0,
@@ -191,6 +197,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -220,6 +227,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -252,6 +260,7 @@
"width": "300px"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -279,6 +288,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -308,6 +318,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -338,6 +349,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -366,6 +378,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -398,6 +411,7 @@
"width": "60px"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -431,6 +445,7 @@
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -458,6 +473,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -491,6 +507,7 @@
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -523,6 +540,7 @@
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -550,6 +568,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -579,6 +598,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -608,6 +628,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -635,6 +656,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -664,6 +686,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -691,6 +714,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -722,6 +746,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -753,6 +778,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -780,6 +806,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -814,6 +841,7 @@
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -845,6 +873,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -874,6 +903,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -902,6 +932,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -932,6 +963,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -962,6 +994,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -990,6 +1023,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1020,6 +1054,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1050,6 +1085,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1078,6 +1114,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1109,6 +1146,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1138,6 +1176,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1171,6 +1210,7 @@
"width": "120px"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1201,6 +1241,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1231,6 +1272,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1260,6 +1302,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1289,6 +1332,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1318,6 +1362,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1347,6 +1392,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1374,6 +1420,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1406,6 +1453,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1437,6 +1485,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1467,6 +1516,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1499,6 +1549,7 @@
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1529,6 +1580,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1559,6 +1611,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1588,6 +1641,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1619,6 +1673,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
@@ -1659,7 +1714,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-04-25 18:49:08.604055",
"modified": "2017-08-02 22:15:47.411235",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",

View File

@@ -44,6 +44,9 @@ frappe.ui.form.on("Request for Quotation",{
freeze: true,
args: {
rfq_name: frm.doc.name
},
callback: function(r){
frm.reload_doc();
}
});
});
@@ -51,6 +54,90 @@ frappe.ui.form.on("Request for Quotation",{
},
get_suppliers_button: function (frm) {
var doc = frm.doc;
var dialog = new frappe.ui.Dialog({
title: __("Get Suppliers"),
fields: [
{ "fieldtype": "Select", "label": __("Get Suppliers By"),
"fieldname": "search_type",
"options": "Tag\nSupplier Type", "reqd": 1 },
{ "fieldtype": "Link", "label": __("Supplier Type"),
"fieldname": "supplier_type",
"options": "Supplier Type", "reqd": 0,
"depends_on": "eval:doc.search_type == 'Supplier Type'"},
{ "fieldtype": "Data", "label": __("Tag"),
"fieldname": "tag", "reqd": 0,
"depends_on": "eval:doc.search_type == 'Tag'" },
{ "fieldtype": "Button", "label": __("Add All Suppliers"),
"fieldname": "add_suppliers", "cssClass": "btn-primary"},
]
});
dialog.fields_dict.add_suppliers.$input.click(function() {
var args = dialog.get_values();
if(!args) return;
dialog.hide();
//Remove blanks
for (var j = 0; j < frm.doc.suppliers.length; j++) {
if(!frm.doc.suppliers[j].hasOwnProperty("supplier")) {
frm.get_field("suppliers").grid.grid_rows[j].remove();
}
}
function load_suppliers(r) {
if(r.message) {
for (var i = 0; i < r.message.length; i++) {
var exists = false;
if (r.message[i].constructor === Array){
var supplier = r.message[i][0];
} else {
var supplier = r.message[i].name;
}
for (var j = 0; j < doc.suppliers.length;j++) {
if (supplier === doc.suppliers[j].supplier) {
exists = true;
}
}
if(!exists) {
var d = frm.add_child('suppliers');
d.supplier = supplier;
frm.script_manager.trigger("supplier", d.doctype, d.name);
}
}
}
frm.refresh_field("suppliers");
}
if (args.search_type === "Tag" && args.tag) {
return frappe.call({
type: "GET",
method: "frappe.desk.tags.get_tagged_docs",
args: {
"doctype": "Supplier",
"tag": args.tag
},
callback: load_suppliers
});
} else if (args.supplier_type) {
return frappe.call({
method: "frappe.client.get_list",
args: {
doctype: "Supplier",
order_by: "name",
fields: ["name"],
filters: [["Supplier", "supplier_type", "=", args.supplier_type]]
},
callback: load_suppliers
});
}
});
dialog.show();
},
make_suppplier_quotation: function(frm) {
var doc = frm.doc;
var dialog = new frappe.ui.Dialog({
@@ -119,6 +206,29 @@ frappe.ui.form.on("Request for Quotation Supplier",{
if(!w) {
frappe.msgprint(__("Please enable pop-ups")); return;
}
},
no_quote: function(frm, cdt, cdn) {
var d = locals[cdt][cdn];
if (d.no_quote) {
if (d.quote_status != __('Received')) {
frappe.model.set_value(cdt, cdn, 'quote_status', 'No Quote');
} else {
frappe.msgprint(__("Cannot set a received RFQ to No Quote"));
frappe.model.set_value(cdt, cdn, 'no_quote', 0);
}
} else {
d.quote_status = __('Pending');
frm.call({
method:"update_rfq_supplier_status",
doc: frm.doc,
args: {
sup_name: d.supplier
},
callback: function(r) {
frm.refresh_field("suppliers");
}
});
}
}
})

View File

@@ -25,7 +25,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Series",
"length": 0,
@@ -59,7 +59,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Company",
"length": 0,
@@ -156,7 +156,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Date",
"length": 0,
@@ -236,6 +236,36 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "get_suppliers_button",
"fieldtype": "Button",
"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": "Get Suppliers",
"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,
@@ -406,7 +436,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Message for Supplier",
"length": 0,
@@ -786,7 +816,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-13 14:29:13.171291",
"modified": "2017-07-21 14:06:46.309322",
"modified_by": "Administrator",
"module": "Buying",
"name": "Request for Quotation",

View File

@@ -21,6 +21,7 @@ STANDARD_USERS = ("Guest", "Administrator")
class RequestforQuotation(BuyingController):
def validate(self):
self.validate_duplicate_supplier()
self.validate_supplier_list()
validate_for_items(self)
self.update_email_id()
@@ -29,6 +30,17 @@ class RequestforQuotation(BuyingController):
if len(supplier_list) != len(set(supplier_list)):
frappe.throw(_("Same supplier has been entered multiple times"))
def validate_supplier_list(self):
for d in self.suppliers:
prevent_rfqs = frappe.db.get_value("Supplier", d.supplier, 'prevent_rfqs')
if prevent_rfqs:
standing = frappe.db.get_value("Supplier Scorecard",d.supplier, 'status')
frappe.throw(_("RFQs are not allowed for {0} due to a scorecard standing of {1}").format(d.supplier, standing))
warn_rfqs = frappe.db.get_value("Supplier", d.supplier, 'warn_rfqs')
if warn_rfqs:
standing = frappe.db.get_value("Supplier Scorecard",d.supplier, 'status')
frappe.msgprint(_("{0} currently has a {1} Supplier Scorecard standing, and RFQs to this supplier should be issued with caution.").format(d.supplier, standing), title=_("Caution"), indicator='orange')
def update_email_id(self):
for rfq_supplier in self.suppliers:
if not rfq_supplier.email_id:
@@ -40,6 +52,9 @@ class RequestforQuotation(BuyingController):
def on_submit(self):
frappe.db.set(self, 'status', 'Submitted')
for supplier in self.suppliers:
supplier.email_sent = 0
supplier.quote_status = 'Pending'
def on_cancel(self):
frappe.db.set(self, 'status', 'Cancelled')
@@ -54,6 +69,8 @@ class RequestforQuotation(BuyingController):
self.update_supplier_part_no(rfq_supplier)
self.supplier_rfq_mail(rfq_supplier, update_password_link, self.get_link())
rfq_supplier.email_sent = 1
rfq_supplier.save()
def get_link(self):
# RFQ link for supplier portal
@@ -84,7 +101,10 @@ class RequestforQuotation(BuyingController):
else:
contact = frappe.new_doc("Contact")
contact.first_name = rfq_supplier.supplier_name or rfq_supplier.supplier
contact.supplier = rfq_supplier.supplier
contact.append('links', {
'link_doctype': 'Supplier',
'link_name': rfq_supplier.supplier
})
if not contact.email_id and not contact.user:
contact.email_id = user.name
@@ -138,6 +158,28 @@ class RequestforQuotation(BuyingController):
attachments.append(frappe.attach_print(self.doctype, self.name, doc=self))
return attachments
def update_rfq_supplier_status(self, sup_name=None):
for supplier in self.suppliers:
if sup_name == None or supplier.supplier == sup_name:
if supplier.quote_status != _('No Quote'):
quote_status = _('Received')
for item in self.items:
sqi_count = frappe.db.sql("""
SELECT
COUNT(sqi.name) as count
FROM
`tabSupplier Quotation Item` as sqi,
`tabSupplier Quotation` as sq
WHERE sq.supplier = %(supplier)s
AND sqi.docstatus = 1
AND sqi.request_for_quotation_item = %(rqi)s
AND sqi.parent = sq.name""",
{"supplier": supplier.supplier, "rqi": item.name}, as_dict=1)[0]
if (sqi_count.count) == 0:
quote_status = _('Pending')
supplier.quote_status = quote_status
@frappe.whitelist()
def send_supplier_emails(rfq_name):
check_portal_enabled('Request for Quotation')
@@ -153,7 +195,12 @@ def check_portal_enabled(reference_doctype):
def get_list_context(context=None):
from erpnext.controllers.website_list_for_contact import get_list_context
list_context = get_list_context(context)
list_context["show_sidebar"] = True
list_context.update({
'show_sidebar': True,
'show_search': True,
'no_breadcrumbs': True,
'title': _('Request for Quotation'),
})
return list_context
def get_supplier_contacts(doctype, txt, searchfield, start, page_len, filters):

View File

@@ -10,21 +10,41 @@ from erpnext.templates.pages.rfq import check_supplier_has_docname_access
from frappe.utils import nowdate
class TestRequestforQuotation(unittest.TestCase):
def test_quote_status(self):
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
rfq = make_request_for_quotation()
self.assertEquals(rfq.get('suppliers')[0].quote_status, 'Pending')
self.assertEquals(rfq.get('suppliers')[1].quote_status, 'Pending')
# Submit the first supplier quotation
sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier)
sq.submit()
# No Quote first supplier quotation
rfq.get('suppliers')[1].no_quote = 1
rfq.get('suppliers')[1].quote_status = 'No Quote'
rfq.update_rfq_supplier_status() #rfq.get('suppliers')[1].supplier)
self.assertEquals(rfq.get('suppliers')[0].quote_status, 'Received')
self.assertEquals(rfq.get('suppliers')[1].quote_status, 'No Quote')
def test_make_supplier_quotation(self):
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
rfq = make_request_for_quotation()
sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier)
sq.submit()
sq1 = make_supplier_quotation(rfq.name, rfq.get('suppliers')[1].supplier)
sq1.submit()
self.assertEquals(sq.supplier, rfq.get('suppliers')[0].supplier)
self.assertEquals(sq.get('items')[0].request_for_quotation, rfq.name)
self.assertEquals(sq.get('items')[0].item_code, "_Test Item")
self.assertEquals(sq.get('items')[0].qty, 5)
self.assertEquals(sq1.supplier, rfq.get('suppliers')[1].supplier)
self.assertEquals(sq1.get('items')[0].request_for_quotation, rfq.name)
self.assertEquals(sq1.get('items')[0].item_code, "_Test Item")
@@ -61,15 +81,15 @@ class TestRequestforQuotation(unittest.TestCase):
rfq.get('items')[0].rate = 100
rfq.supplier = rfq.suppliers[0].supplier
supplier_quotation_name = create_supplier_quotation(rfq)
supplier_quotation_doc = frappe.get_doc('Supplier Quotation', supplier_quotation_name)
self.assertEquals(supplier_quotation_doc.supplier, rfq.get('suppliers')[0].supplier)
self.assertEquals(supplier_quotation_doc.get('items')[0].request_for_quotation, rfq.name)
self.assertEquals(supplier_quotation_doc.get('items')[0].item_code, "_Test Item")
self.assertEquals(supplier_quotation_doc.get('items')[0].qty, 5)
self.assertEquals(supplier_quotation_doc.get('items')[0].amount, 500)
def make_request_for_quotation(supplier_data=None):
"""
@@ -81,10 +101,10 @@ def make_request_for_quotation(supplier_data=None):
rfq.status = 'Draft'
rfq.company = '_Test Company'
rfq.message_for_supplier = 'Please supply the specified items at the best possible rates.'
for data in supplier_data:
rfq.append('suppliers', data)
rfq.append("items", {
"item_code": "_Test Item",
"description": "_Test Item",
@@ -93,11 +113,11 @@ def make_request_for_quotation(supplier_data=None):
"warehouse": "_Test Warehouse - _TC",
"schedule_date": nowdate()
})
rfq.submit()
return rfq
def get_supplier_data():
return [{
"supplier": "_Test Supplier",

View File

@@ -0,0 +1,75 @@
QUnit.module('Buying');
QUnit.test("test: request_for_quotation", function(assert) {
assert.expect(14);
let done = assert.async();
let date;
frappe.run_serially([
() => {
date = frappe.datetime.add_days(frappe.datetime.now_date(), 10);
return frappe.tests.make('Request for Quotation', [
{transaction_date: date},
{suppliers: [
[
{"supplier": 'Test Supplier'},
{"email_id": 'test@supplier.com'}
]
]},
{items: [
[
{"item_code": 'Test Product 4'},
{"qty": 5},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(),20)},
{"warehouse": 'All Warehouses - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]
]},
{message_for_supplier: 'Please supply the specified items at the best possible rates'},
{tc_name: 'Test Term 1'}
]);
},
() => {
assert.ok(cur_frm.doc.transaction_date == date, "Date correct");
assert.ok(cur_frm.doc.company == cur_frm.doc.company, "Company correct");
assert.ok(cur_frm.doc.suppliers[0].supplier_name == 'Test Supplier', "Supplier name correct");
assert.ok(cur_frm.doc.suppliers[0].contact == 'Contact 3-Test Supplier', "Contact correct");
assert.ok(cur_frm.doc.suppliers[0].email_id == 'test@supplier.com', "Email id correct");
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item Name correct");
assert.ok(cur_frm.doc.items[0].warehouse == 'All Warehouses - '+frappe.get_abbr(frappe.defaults.get_default("Company")), "Warehouse correct");
assert.ok(cur_frm.doc.message_for_supplier == 'Please supply the specified items at the best possible rates', "Reply correct");
assert.ok(cur_frm.doc.tc_name == 'Test Term 1', "Term name correct");
},
() => frappe.timeout(0.3),
() => cur_frm.print_doc(),
() => frappe.timeout(1),
() => {
assert.ok($('.btn-print-print').is(':visible'), "Print Format Available");
assert.ok($('.section-break+ .section-break .column-break:nth-child(1) .value').text().includes("Test Product 4"), "Print Preview Works");
},
() => cur_frm.print_doc(),
() => frappe.timeout(1),
() => frappe.click_button('Get items from'),
() => frappe.timeout(0.3),
() => frappe.click_link('Material Request'),
() => frappe.timeout(1),
() => frappe.click_button('Get Items'),
() => frappe.timeout(1),
() => {
assert.ok(cur_frm.doc.items[1].item_name == 'Test Product 1', "Getting items from material requests work");
},
() => cur_frm.save(),
() => frappe.timeout(1),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(1),
() => {
assert.ok(cur_frm.doc.docstatus == 1, "Quotation request submitted");
},
() => frappe.click_button('Send Supplier Emails'),
() => frappe.timeout(3),
() => {
assert.ok($('div.modal.fade.in > div.modal-dialog > div > div.modal-body.ui-front > div.msgprint').text().includes("Email sent to supplier Test Supplier"), "Send emails working");
},
() => frappe.click_button('Close'),
() => done()
]);
});

View File

@@ -0,0 +1,132 @@
QUnit.module('buying');
QUnit.test("Test: Request for Quotation", function (assert) {
assert.expect(5);
let done = assert.async();
let rfq_name = "";
frappe.run_serially([
// Go to RFQ list
() => frappe.set_route("List", "Request for Quotation"),
// Create a new RFQ
() => frappe.new_doc("Request for Quotation"),
() => frappe.timeout(1),
() => cur_frm.set_value("transaction_date", "04-04-2017"),
() => cur_frm.set_value("company", "_Test Company"),
// Add Suppliers
() => {
cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view();
},
() => frappe.timeout(1),
() => {
cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.supplier = "_Test Supplier";
frappe.click_check('Send Email');
cur_frm.cur_grid.frm.script_manager.trigger('supplier');
},
() => frappe.timeout(1),
() => {
cur_frm.cur_grid.toggle_view();
},
() => frappe.timeout(1),
() => frappe.click_button('Add Row',0),
() => frappe.timeout(1),
() => {
cur_frm.fields_dict.suppliers.grid.grid_rows[1].toggle_view();
},
() => frappe.timeout(1),
() => {
cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.supplier = "_Test Supplier 1";
frappe.click_check('Send Email');
cur_frm.cur_grid.frm.script_manager.trigger('supplier');
},
() => frappe.timeout(1),
() => {
cur_frm.cur_grid.toggle_view();
},
() => frappe.timeout(1),
// Add Item
() => {
cur_frm.fields_dict.items.grid.grid_rows[0].toggle_view();
},
() => frappe.timeout(1),
() => {
cur_frm.fields_dict.items.grid.grid_rows[0].doc.item_code = "_Test Item";
frappe.set_control('item_code',"_Test Item");
frappe.set_control('qty',5);
frappe.set_control('schedule_date', "05-05-2017");
cur_frm.cur_grid.frm.script_manager.trigger('supplier');
},
() => frappe.timeout(2),
() => {
cur_frm.cur_grid.toggle_view();
},
() => frappe.timeout(2),
() => {
cur_frm.fields_dict.items.grid.grid_rows[0].doc.warehouse = "_Test Warehouse - _TC";
},
() => frappe.click_button('Save'),
() => frappe.timeout(1),
() => frappe.click_button('Submit'),
() => frappe.timeout(1),
() => frappe.click_button('Yes'),
() => frappe.timeout(1),
() => frappe.click_button('Menu'),
() => frappe.timeout(1),
() => frappe.click_link('Reload'),
() => frappe.timeout(1),
() => {
assert.equal(cur_frm.doc.docstatus, 1);
rfq_name = cur_frm.doc.name;
assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.quote_status == "Pending");
assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.quote_status == "Pending");
},
() => {
cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view();
},
() => frappe.timeout(1),
() => {
frappe.click_check('No Quote');
},
() => frappe.timeout(1),
() => {
cur_frm.cur_grid.toggle_view();
},
() => frappe.click_button('Update'),
() => frappe.timeout(1),
() => frappe.click_button('Supplier Quotation'),
() => frappe.timeout(1),
() => frappe.click_link('Make'),
() => frappe.timeout(1),
() => {
frappe.set_control('supplier',"_Test Supplier 1");
},
() => frappe.timeout(1),
() => frappe.click_button('Make Supplier Quotation'),
() => frappe.timeout(1),
() => cur_frm.set_value("company", "_Test Company"),
() => cur_frm.fields_dict.items.grid.grid_rows[0].doc.rate = 4.99,
() => frappe.timeout(1),
() => frappe.click_button('Save'),
() => frappe.timeout(1),
() => frappe.click_button('Submit'),
() => frappe.timeout(1),
() => frappe.click_button('Yes'),
() => frappe.timeout(1),
() => frappe.set_route("List", "Request for Quotation"),
() => frappe.timeout(2),
() => frappe.set_route("List", "Request for Quotation"),
() => frappe.timeout(2),
() => frappe.click_link(rfq_name),
() => frappe.timeout(1),
() => frappe.click_button('Menu'),
() => frappe.timeout(1),
() => frappe.click_link('Reload'),
() => frappe.timeout(1),
() => {
assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.quote_status == "Received");
assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.no_quote == 1);
},
() => done()
]);
});

View File

@@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
@@ -12,6 +13,7 @@
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
@@ -42,6 +44,39 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"depends_on": "eval:doc.docstatus >= 1",
"fieldname": "email_sent",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Email Sent",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -72,6 +107,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -102,6 +138,70 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.docstatus >= 1 && doc.quote_status != 'Received'",
"fieldname": "no_quote",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "No Quote",
"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": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.docstatus >= 1 && !doc.no_quote",
"fieldname": "quote_status",
"fieldtype": "Select",
"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": "Quote Status",
"length": 0,
"no_copy": 0,
"options": "Pending\nReceived\nNo Quote",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -130,6 +230,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -160,6 +261,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -190,6 +292,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
@@ -219,17 +322,17 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-02-17 16:42:57.254211",
"modified": "2017-07-26 22:25:58.096584",
"modified_by": "Administrator",
"module": "Buying",
"name": "Request for Quotation Supplier",

View File

@@ -322,6 +322,126 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "warn_rfqs",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Warn RFQs",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "warn_pos",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Warn POs",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "prevent_rfqs",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Prevent RFQs",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "prevent_pos",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Prevent POs",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -850,7 +970,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-13 14:29:16.310834",
"modified": "2017-07-06 16:40:46.935608",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier",

View File

@@ -0,0 +1,77 @@
QUnit.module('Buying');
QUnit.test("test: supplier", function(assert) {
assert.expect(6);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Supplier', [
{supplier_name: 'Test Supplier'},
{supplier_type: 'Hardware'},
{country: 'India'},
{default_currency: 'INR'},
{credit_days_based_on: 'Fixed Days'},
{accounts: [
[
{'company': "Test Company"},
{'account': "Creditors - TC"}
]]
}
]);
},
() => frappe.timeout(1),
() => frappe.click_button('New Address'),
() => {
return frappe.tests.set_form_values(cur_frm, [
{address_title:"Test3"},
{address_type: "Billing"},
{address_line1: "Billing Street 3"},
{city: "Billing City 3"},
]);
},
() => cur_frm.save(),
() => frappe.timeout(2),
() => frappe.click_button('New Address'),
() => {
return frappe.tests.set_form_values(cur_frm, [
{address_title:"Test3"},
{address_type: "Shipping"},
{address_line1: "Shipping Street 3"},
{city: "Shipping City 3"},
]);
},
() => cur_frm.save(),
() => frappe.timeout(2),
() => frappe.click_button('New Address'),
() => {
return frappe.tests.set_form_values(cur_frm, [
{address_title:"Test3"},
{address_type: "Warehouse"},
{address_line1: "Warehouse Street 3"},
{city: "Warehouse City 3"},
]);
},
() => cur_frm.save(),
() => frappe.timeout(2),
() => frappe.click_button('New Contact'),
() => {
return frappe.tests.set_form_values(cur_frm, [
{first_name: "Contact 3"}
]);
},
() => cur_frm.save(),
() => frappe.timeout(1),
() => frappe.set_route('Form', 'Supplier', 'Test Supplier'),
() => frappe.timeout(0.3),
() => {
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Name correct");
assert.ok(cur_frm.doc.supplier_type == 'Hardware', "Type correct");
assert.ok(cur_frm.doc.default_currency == 'INR', "Currency correct");
assert.ok(cur_frm.doc.accounts[0].account == 'Creditors - '+frappe.get_abbr('Test Company'), " Account Head abbr correct");
assert.ok($('.address-box:nth-child(3) p').text().includes('Shipping City 3'), "Address correct");
assert.ok($('.col-sm-6+ .col-sm-6 .h6').text().includes('Contact 3'), "Contact correct");
},
() => done()
]);
});

View File

@@ -31,9 +31,11 @@ class SupplierQuotation(BuyingController):
def on_submit(self):
frappe.db.set(self, "status", "Submitted")
self.update_rfq_supplier_status(1)
def on_cancel(self):
frappe.db.set(self, "status", "Cancelled")
self.update_rfq_supplier_status(0)
def on_trash(self):
pass
@@ -50,6 +52,41 @@ class SupplierQuotation(BuyingController):
"is_child_table": True
}
})
def update_rfq_supplier_status(self, include_me):
rfq_list = set([])
for item in self.items:
if item.request_for_quotation:
rfq_list.add(item.request_for_quotation)
for rfq in rfq_list:
doc = frappe.get_doc('Request for Quotation', rfq)
doc_sup = frappe.get_all('Request for Quotation Supplier', filters=
{'parent': doc.name, 'supplier': self.supplier}, fields=['name', 'quote_status'])[0]
quote_status = _('Received')
for item in doc.items:
sqi_count = frappe.db.sql("""
SELECT
COUNT(sqi.name) as count
FROM
`tabSupplier Quotation Item` as sqi,
`tabSupplier Quotation` as sq
WHERE sq.supplier = %(supplier)s
AND sqi.docstatus = 1
AND sq.name != %(me)s
AND sqi.request_for_quotation_item = %(rqi)s
AND sqi.parent = sq.name""",
{"supplier": self.supplier, "rqi": item.name, 'me': self.name}, as_dict=1)[0]
self_count = sum(my_item.request_for_quotation_item == item.name
for my_item in self.items) if include_me else 0
if (sqi_count.count + self_count) == 0:
quote_status = _('Pending')
if quote_status == _('Received') and doc_sup.quote_status == _('No Quote'):
frappe.msgprint(_("{0} indicates that {1} will not provide a quotation, but all items \
have been quoted. Updating the RFQ quote status.").format(doc.name, self.supplier))
frappe.db.set_value('Request for Quotation Supplier', doc_sup.name, 'quote_status', quote_status)
frappe.db.set_value('Request for Quotation Supplier', doc_sup.name, 'no_quote', 0)
elif doc_sup.quote_status != _('No Quote'):
frappe.db.set_value('Request for Quotation Supplier', doc_sup.name, 'quote_status', quote_status)
def get_list_context(context=None):
from erpnext.controllers.website_list_for_contact import get_list_context

View File

@@ -0,0 +1,73 @@
QUnit.module('Buying');
QUnit.test("test: supplier quotation", function(assert) {
assert.expect(11);
let done = assert.async();
let date;
frappe.run_serially([
() => {
date = frappe.datetime.add_days(frappe.datetime.now_date(), 10);
return frappe.tests.make('Supplier Quotation', [
{supplier: 'Test Supplier'},
{transaction_date: date},
{currency: 'INR'},
{items: [
[
{"item_code": 'Test Product 4'},
{"qty": 5},
{"uom": 'Unit'},
{"rate": 200},
{"warehouse": 'All Warehouses - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]
]},
{apply_discount_on: 'Grand Total'},
{additional_discount_percentage: 10},
{tc_name: 'Test Term 1'},
{terms: 'This is a term'}
]);
},
() => {
// Get Supplier details
assert.ok(cur_frm.doc.supplier == 'Test Supplier', "Supplier correct");
assert.ok(cur_frm.doc.company == cur_frm.doc.company, "Company correct");
// Get Contact details
assert.ok(cur_frm.doc.contact_display == 'Contact 3', "Conatct correct");
assert.ok(cur_frm.doc.contact_email == 'test@supplier.com', "Email correct");
// Get uom
assert.ok(cur_frm.doc.items[0].uom == 'Unit', "Multi uom correct");
assert.ok(cur_frm.doc.total == 1000, "Total correct");
// Calculate total after discount
assert.ok(cur_frm.doc.grand_total == 900, "Grand total correct");
// Get terms
assert.ok(cur_frm.doc.tc_name == 'Test Term 1', "Terms correct");
},
() => cur_frm.print_doc(),
() => frappe.timeout(2),
() => {
assert.ok($('.btn-print-print').is(':visible'), "Print Format Available");
assert.ok($("table > tbody > tr > td:nth-child(3) > div").text().includes("Test Product 4"), "Print Preview Works As Expected");
},
() => cur_frm.print_doc(),
() => frappe.timeout(1),
() => frappe.click_button('Get items from'),
() => frappe.timeout(0.3),
() => frappe.click_link('Material Request'),
() => frappe.timeout(0.3),
() => frappe.click_button('Get Items'),
() => frappe.timeout(1),
() => {
// Get item from Material Requests
assert.ok(cur_frm.doc.items[1].item_name == 'Test Product 1', "Getting items from material requests work");
},
() => cur_frm.save(),
() => frappe.timeout(1),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@@ -0,0 +1,34 @@
QUnit.module('Buying');
QUnit.test("test: supplier quotation with item wise discount", function(assert){
assert.expect(2);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Supplier Quotation', [
{supplier: 'Test Supplier'},
{company: 'Test Company'},
{items: [
[
{"item_code": 'Test Product 4'},
{"qty": 5},
{"uom": 'Unit'},
{"warehouse": 'All Warehouses - TC'},
{'discount_percentage': 10},
]
]}
]);
},
() => {
assert.ok(cur_frm.doc.total == 900, "Total correct");
assert.ok(cur_frm.doc.grand_total == 900, "Grand total correct");
},
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@@ -0,0 +1,37 @@
QUnit.module('Buying');
QUnit.test("test: supplier quotation with taxes and charges", function(assert) {
assert.expect(3);
let done = assert.async();
let supplier_quotation_name;
frappe.run_serially([
() => {
return frappe.tests.make('Supplier Quotation', [
{supplier: 'Test Supplier'},
{items: [
[
{"item_code": 'Test Product 4'},
{"qty": 5},
{"rate": 100},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
]
]},
{taxes_and_charges:'TEST In State GST'},
]);
},
() => {supplier_quotation_name = cur_frm.doc.name;},
() => {
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
assert.ok(cur_frm.doc.total_taxes_and_charges == 45, "Taxes and charges correct");
assert.ok(cur_frm.doc.grand_total == 545, "Grand total correct");
},
() => cur_frm.save(),
() => frappe.timeout(0.3),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@@ -0,0 +1,146 @@
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
/* global frappe, refresh_field */
frappe.ui.form.on("Supplier Scorecard", {
onload: function(frm) {
if (frm.doc.indicator_color !== "") {
frm.set_indicator_formatter("status", function(doc) {
return doc.indicator_color.toLowerCase();
});
}
if (frm.doc.__unsaved == 1) {
loadAllCriteria(frm);
loadAllStandings(frm);
}
},
refresh: function(frm) {
if (frm.dashboard.hasOwnProperty('heatmap')) {
frm.dashboard.heatmap.setLegend([0,20,40,60,80,101],["#991600","#169900"]);
}
}
});
frappe.ui.form.on("Supplier Scorecard Scoring Standing", {
standing_name: function(frm, cdt, cdn) {
if (frm.doc.standing_name != undefined) {
var d = frappe.get_doc(cdt, cdn);
return frm.call({
method: "erpnext.buying.doctype.supplier_scorecard_standing.supplier_scorecard_standing.get_scoring_standing",
child: d,
args: {
standing_name: d.standing_name
}
});
}
}
});
frappe.ui.form.on("Supplier Scorecard Scoring Variable", {
variable_label: function(frm, cdt, cdn) {
if (frm.doc.variable_label != undefined) {
var d = frappe.get_doc(cdt, cdn);
return frm.call({
method: "erpnext.buying.doctype.supplier_scorecard_variable.supplier_scorecard_variable.get_scoring_variable",
child: d,
args: {
variable_label: d.variable_label
}
});
}
}
});
frappe.ui.form.on("Supplier Scorecard Scoring Criteria", {
criteria_name: function(frm, cdt, cdn) {
if (frm.doc.criteria_name != undefined) {
var d = frappe.get_doc(cdt, cdn);
frm.call({
method: "erpnext.buying.doctype.supplier_scorecard_criteria.supplier_scorecard_criteria.get_variables",
args: {
criteria_name: d.criteria_name
},
callback: function(r) {
for (var i = 0; i < r.message.length; i++)
{
var exists = false;
for (var j = 0; j < frm.doc.variables.length; j++)
{
if(!frm.doc.variables[j].hasOwnProperty("variable_label")) {
frm.get_field("variables").grid.grid_rows[j].remove();
}
else if(frm.doc.variables[j].variable_label === r.message[i]) {
exists = true;
}
}
if (!exists){
var new_row = frm.add_child("variables");
new_row.variable_label = r.message[i];
frm.script_manager.trigger("variable_label", new_row.doctype, new_row.name);
}
}
refresh_field("variables");
}
});
return frm.call({
method: "erpnext.buying.doctype.supplier_scorecard_criteria.supplier_scorecard_criteria.get_scoring_criteria",
child: d,
args: {
criteria_name: d.criteria_name
}
});
}
}
});
var loadAllCriteria = function(frm) {
frappe.call({
method: "erpnext.buying.doctype.supplier_scorecard_criteria.supplier_scorecard_criteria.get_criteria_list",
callback: function(r) {
for (var j = 0; j < frm.doc.criteria.length; j++)
{
if(!frm.doc.criteria[j].hasOwnProperty("criteria_name")) {
frm.get_field("criteria").grid.grid_rows[j].remove();
}
}
for (var i = 0; i < r.message.length; i++)
{
var new_row = frm.add_child("criteria");
new_row.criteria_name = r.message[i].name;
frm.script_manager.trigger("criteria_name", new_row.doctype, new_row.name);
}
refresh_field("criteria");
}
});
};
var loadAllStandings = function(frm) {
frappe.call({
method: "erpnext.buying.doctype.supplier_scorecard_standing.supplier_scorecard_standing.get_standings_list",
callback: function(r) {
for (var j = 0; j < frm.doc.standings.length; j++)
{
if(!frm.doc.standings[j].hasOwnProperty("standing_name")) {
frm.get_field("standings").grid.grid_rows[j].remove();
}
}
for (var i = 0; i < r.message.length; i++)
{
var new_row = frm.add_child("standings");
new_row.standing_name = r.message[i].name;
frm.script_manager.trigger("standing_name", new_row.doctype, new_row.name);
}
refresh_field("standings");
}
});
};

View File

@@ -0,0 +1,701 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:supplier",
"beta": 1,
"creation": "2017-05-29 01:40:54.786555",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "supplier",
"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": "Supplier",
"length": 0,
"no_copy": 0,
"options": "Supplier",
"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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "supplier_score",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Supplier Score",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "indicator_color",
"fieldtype": "Data",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Indicator Color",
"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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "status",
"fieldtype": "Data",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Status",
"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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Per Month",
"fieldname": "period",
"fieldtype": "Select",
"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": "Evaluation Period",
"length": 0,
"no_copy": 0,
"options": "Per Month\nPer Week\nPer Year",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "scoring_setup",
"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": "Scoring Setup",
"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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "{total_score} * max( 0, min ( 1 , (12 - {period_number}) / 12) )",
"description": "Scorecard variables can be used, as well as:\n{total_score} (the total score from that period),\n{period_number} (the number of periods to present day)\n",
"fieldname": "weighting_function",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Weighting Function",
"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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "standings",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Scoring Standings",
"length": 0,
"no_copy": 0,
"options": "Supplier Scorecard Scoring Standing",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "criteria_setup",
"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": "Criteria Setup",
"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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "criteria",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Scoring Criteria",
"length": 0,
"no_copy": 0,
"options": "Supplier Scorecard Scoring Criteria",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "variables",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Supplier Variables",
"length": 0,
"no_copy": 0,
"options": "Supplier Scorecard Scoring Variable",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "eval: doc.status != 'Unknown'",
"columns": 0,
"fieldname": "scorecard_actions",
"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": "Scorecard Actions",
"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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "warn_rfqs",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Warn for new Request for Quotations",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "warn_pos",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Warn for new Purchase Orders",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "prevent_rfqs",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Prevent RFQs",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "prevent_pos",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Prevent POs",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_16",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "notify_supplier",
"fieldtype": "Check",
"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": "Notify Supplier",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "notify_employee",
"fieldtype": "Check",
"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": "Notify Employee",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "employee",
"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": "Employee",
"length": 0,
"no_copy": 0,
"options": "Employee",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-07-12 07:33:11.874949",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Scorecard",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0
}

View File

@@ -0,0 +1,262 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import throw, _
from frappe.model.document import Document
import time
from datetime import timedelta
from frappe.utils import nowdate, get_last_day, getdate, add_days, add_years
from erpnext.buying.doctype.supplier_scorecard_period.supplier_scorecard_period import make_supplier_scorecard
class SupplierScorecard(Document):
def validate(self):
self.validate_standings()
self.validate_criteria_weights()
self.calculate_total_score()
self.update_standing()
def on_update(self):
score = make_all_scorecards(self.name)
if score > 0:
self.save()
def validate_standings(self):
# Check that there are no overlapping scores and check that there are no missing scores
score = 0
for c1 in self.standings:
for c2 in self.standings:
if c1 != c2:
if (c1.max_grade > c2.min_grade and c1.min_grade < c2.max_grade):
throw(_('Overlap in scoring between {0} and {1}').format(c1.standing_name,c2.standing_name))
if c2.min_grade == score:
score = c2.max_grade
if score < 100:
throw(_('Unable to find score starting at {0}. You need to have standing scores covering 0 to 100').format(score))
def validate_criteria_weights(self):
weight = 0
for c in self.criteria:
weight += c.weight
if weight != 100:
throw(_('Criteria weights must add up to 100%'))
def calculate_total_score(self):
scorecards = frappe.db.sql("""
SELECT
scp.name
FROM
`tabSupplier Scorecard Period` scp
WHERE
scp.scorecard = %(sc)s
ORDER BY
scp.end_date DESC""",
{"sc": self.name}, as_dict=1)
period = 0
total_score = 0
total_max_score = 0
for scp in scorecards:
my_sc = frappe.get_doc('Supplier Scorecard Period', scp.name)
my_scp_weight = self.weighting_function
my_scp_weight = my_scp_weight.replace('{period_number}', str(period))
my_scp_maxweight = my_scp_weight.replace('{total_score}', '100')
my_scp_weight = my_scp_weight.replace('{total_score}', str(my_sc.total_score))
max_score = my_sc.calculate_weighted_score(my_scp_maxweight)
score = my_sc.calculate_weighted_score(my_scp_weight)
total_score += score
total_max_score += max_score
period += 1
if total_max_score > 0:
self.supplier_score = round(100.0 * (total_score / total_max_score) ,1)
else:
self.supplier_score = 100
def update_standing(self):
# Get the setup document
for standing in self.standings:
if (not standing.min_grade or (standing.min_grade <= self.supplier_score)) and \
(not standing.max_grade or (standing.max_grade > self.supplier_score)):
self.status = standing.standing_name
self.indicator_color = standing.standing_color
self.notify_supplier = standing.notify_supplier
self.notify_employee = standing.notify_employee
self.employee_link = standing.employee_link
#Update supplier standing info
for fieldname in ('prevent_pos', 'prevent_rfqs','warn_rfqs','warn_pos'):
self.set(fieldname, standing.get(fieldname))
frappe.db.set_value("Supplier", self.supplier, fieldname, self.get(fieldname))
@frappe.whitelist()
def get_timeline_data(doctype, name):
# Get a list of all the associated scorecards
scs = frappe.get_doc(doctype, name)
out = {}
timeline_data = {}
scorecards = frappe.db.sql("""
SELECT
sc.name
FROM
`tabSupplier Scorecard Period` sc
WHERE
sc.scorecard = %(scs)s""",
{"scs": scs.name}, as_dict=1)
for sc in scorecards:
start_date, end_date, total_score = frappe.db.get_value('Supplier Scorecard Period', sc.name, ['start_date', 'end_date', 'total_score'])
for single_date in daterange(start_date, end_date):
timeline_data[time.mktime(single_date.timetuple())] = total_score
out['timeline_data'] = timeline_data
return out
def daterange(start_date, end_date):
for n in range(int ((end_date - start_date).days)+1):
yield start_date + timedelta(n)
def refresh_scorecards():
scorecards = frappe.db.sql("""
SELECT
sc.name
FROM
`tabSupplier Scorecard` sc""",
{}, as_dict=1)
for sc in scorecards:
# Check to see if any new scorecard periods are created
if make_all_scorecards(sc.name) > 0:
# Save the scorecard to update the score and standings
sc.save()
@frappe.whitelist()
def make_all_scorecards(docname):
sc = frappe.get_doc('Supplier Scorecard', docname)
supplier = frappe.get_doc('Supplier',sc.supplier)
start_date = getdate(supplier.creation)
end_date = get_scorecard_date(sc.period, start_date)
todays = getdate(nowdate())
scp_count = 0
first_start_date = todays
last_end_date = todays
while (start_date < todays) and (end_date <= todays):
# check to make sure there is no scorecard period already created
scorecards = frappe.db.sql("""
SELECT
scp.name
FROM
`tabSupplier Scorecard Period` scp
WHERE
scp.scorecard = %(sc)s
AND (
(scp.start_date > %(end_date)s
AND scp.end_date < %(start_date)s)
OR
(scp.start_date < %(end_date)s
AND scp.end_date > %(start_date)s))
ORDER BY
scp.end_date DESC""",
{"sc": docname, "start_date": start_date, "end_date": end_date, "supplier": supplier}, as_dict=1)
if len(scorecards) == 0:
period_card = make_supplier_scorecard(docname, None)
period_card.start_date = start_date
period_card.end_date = end_date
period_card.save()
scp_count = scp_count + 1
if start_date < first_start_date:
first_start_date = start_date
last_end_date = end_date
start_date = getdate(add_days(end_date,1))
end_date = get_scorecard_date(sc.period, start_date)
if scp_count > 0:
frappe.msgprint(_("Created {0} scorecards for {1} between: ").format(scp_count, sc.supplier) + str(first_start_date) + " - " + str(last_end_date))
return scp_count
def get_scorecard_date(period, start_date):
if period == 'Per Week':
end_date = getdate(add_days(start_date,7))
elif period == 'Per Month':
end_date = get_last_day(start_date)
elif period == 'Per Year':
end_date = add_days(add_years(start_date,1), -1)
return end_date
def make_default_records():
install_variable_docs = [
{"param_name": "total_accepted_items", "variable_label": "Total Accepted Items", \
"path": "get_total_accepted_items"},
{"param_name": "total_accepted_amount", "variable_label": "Total Accepted Amount", \
"path": "get_total_accepted_amount"},
{"param_name": "total_rejected_items", "variable_label": "Total Rejected Items", \
"path": "get_total_rejected_items"},
{"param_name": "total_rejected_amount", "variable_label": "Total Rejected Amount", \
"path": "get_total_rejected_amount"},
{"param_name": "total_received_items", "variable_label": "Total Received Items", \
"path": "get_total_received_items"},
{"param_name": "total_received_amount", "variable_label": "Total Received Amount", \
"path": "get_total_received_amount"},
{"param_name": "rfq_response_days", "variable_label": "RFQ Response Days", \
"path": "get_rfq_response_days"},
{"param_name": "sq_total_items", "variable_label": "SQ Total Items", \
"path": "get_sq_total_items"},
{"param_name": "sq_total_number", "variable_label": "SQ Total Number", \
"path": "get_sq_total_number"},
{"param_name": "rfq_total_number", "variable_label": "RFQ Total Number", \
"path": "get_rfq_total_number"},
{"param_name": "rfq_total_items", "variable_label": "RFQ Total Items", \
"path": "get_rfq_total_items"},
{"param_name": "tot_item_days", "variable_label": "Total Item Days", \
"path": "get_item_workdays"},
{"param_name": "on_time_shipment_num", "variable_label": "# of On Time Shipments", "path": \
"get_on_time_shipments"},
{"param_name": "cost_of_delayed_shipments", "variable_label": "Cost of Delayed Shipments", \
"path": "get_cost_of_delayed_shipments"},
{"param_name": "cost_of_on_time_shipments", "variable_label": "Cost of On Time Shipments", \
"path": "get_cost_of_on_time_shipments"},
{"param_name": "total_working_days", "variable_label": "Total Working Days", \
"path": "get_total_workdays"},
{"param_name": "tot_cost_shipments", "variable_label": "Total Cost of Shipments", \
"path": "get_total_cost_of_shipments"},
{"param_name": "tot_days_late", "variable_label": "Total Days Late", \
"path": "get_total_days_late"},
{"param_name": "total_shipments", "variable_label": "Total Shipments", \
"path": "get_total_shipments"}
]
install_standing_docs = [
{"min_grade": 0.0, "prevent_rfqs": 1, "notify_supplier": 0, "max_grade": 30.0, "prevent_pos": 1, \
"standing_color": "Red", "notify_employee": 0, "standing_name": "Very Poor"},
{"min_grade": 30.0, "prevent_rfqs": 1, "notify_supplier": 0, "max_grade": 50.0, "prevent_pos": 0, \
"standing_color": "Red", "notify_employee": 0, "standing_name": "Poor"},
{"min_grade": 50.0, "prevent_rfqs": 0, "notify_supplier": 0, "max_grade": 80.0, "prevent_pos": 0, \
"standing_color": "Green", "notify_employee": 0, "standing_name": "Average"},
{"min_grade": 80.0, "prevent_rfqs": 0, "notify_supplier": 0, "max_grade": 100.0, "prevent_pos": 0, \
"standing_color": "Blue", "notify_employee": 0, "standing_name": "Excellent"},
]
for d in install_variable_docs:
try:
d['doctype'] = "Supplier Scorecard Variable"
frappe.get_doc(d).insert()
except frappe.NameError:
pass
for d in install_standing_docs:
try:
d['doctype'] = "Supplier Scorecard Standing"
frappe.get_doc(d).insert()
except frappe.NameError:
pass

View File

@@ -0,0 +1,15 @@
from frappe import _
def get_data():
return {
'heatmap': True,
'heatmap_message': _('This covers all scorecards tied to this Setup'),
'fieldname': 'supplier',
'method' : 'erpnext.buying.doctype.supplier_scorecard.supplier_scorecard.get_timeline_data',
'transactions': [
{
'label': _('Scorecards'),
'items': ['Supplier Scorecard Period']
}
]
}

View File

@@ -0,0 +1,17 @@
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
/* global frappe, __ */
frappe.listview_settings["Supplier Scorecard"] = {
add_fields: ["indicator_color", "status"],
get_indicator: function(doc) {
if (doc.indicator_color) {
return [__(doc.status), doc.indicator_color.toLowerCase(), "status,=," + doc.status];
} else {
return [__("Unknown"), "darkgrey", "status,=,''"];
}
},
};

View File

@@ -0,0 +1,190 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals
import frappe
import unittest
class TestSupplierScorecard(unittest.TestCase):
def test_create_scorecard(self):
delete_test_scorecards()
my_doc = make_supplier_scorecard()
doc = my_doc.insert()
self.assertEqual(doc.name, valid_scorecard[0].get("supplier"))
def test_criteria_weight(self):
delete_test_scorecards()
my_doc = make_supplier_scorecard()
for d in my_doc.criteria:
d.weight = 0
self.assertRaises(frappe.ValidationError,my_doc.insert)
def test_missing_variable(self):
delete_test_scorecards()
my_doc = make_supplier_scorecard()
del my_doc.variables
self.assertRaises(frappe.ValidationError,my_doc.insert)
def make_supplier_scorecard():
my_doc = frappe.get_doc(valid_scorecard[0])
# Make sure the criteria exist (making them)
for d in valid_scorecard[0].get("criteria"):
if not frappe.db.exists("Supplier Scorecard Criteria", d.get("criteria_name")):
d["doctype"] = "Supplier Scorecard Criteria"
d["name"] = d.get("criteria_name")
my_criteria = frappe.get_doc(d)
my_criteria.insert()
return my_doc
def delete_test_scorecards():
my_doc = make_supplier_scorecard()
if frappe.db.exists("Supplier Scorecard", my_doc.name):
# Delete all the periods, then delete the scorecard
frappe.db.sql("""delete from `tabSupplier Scorecard Period` where scorecard = %(scorecard)s""", {'scorecard': my_doc.name})
frappe.db.sql("""delete from `tabSupplier Scorecard Scoring Criteria` where parenttype = 'Supplier Scorecard Period'""")
frappe.db.sql("""delete from `tabSupplier Scorecard Scoring Standing` where parenttype = 'Supplier Scorecard Period'""")
frappe.db.sql("""delete from `tabSupplier Scorecard Scoring Variable` where parenttype = 'Supplier Scorecard Period'""")
frappe.delete_doc(my_doc.doctype, my_doc.name)
valid_scorecard = [
{
"standings":[
{
"min_grade":0.0,"name":"Very Poor",
"prevent_rfqs":1,
"notify_supplier":0,
"doctype":"Supplier Scorecard Standing",
"max_grade":30.0,
"prevent_pos":1,
"warn_pos":0,
"warn_rfqs":0,
"standing_color":"Red",
"notify_employee":0,
"standing_name":"Very Poor",
"parenttype":"Supplier Scorecard",
"parentfield":"standings"
},
{
"min_grade":30.0,
"name":"Poor",
"prevent_rfqs":1,
"notify_supplier":0,
"doctype":"Supplier Scorecard Standing",
"max_grade":50.0,
"prevent_pos":0,
"warn_pos":0,
"warn_rfqs":0,
"standing_color":"Red",
"notify_employee":0,
"standing_name":"Poor",
"parenttype":"Supplier Scorecard",
"parentfield":"standings"
},
{
"min_grade":50.0,
"name":"Average",
"prevent_rfqs":0,
"notify_supplier":0,
"doctype":"Supplier Scorecard Standing",
"max_grade":80.0,
"prevent_pos":0,
"warn_pos":0,
"warn_rfqs":0,
"standing_color":"Green",
"notify_employee":0,
"standing_name":"Average",
"parenttype":"Supplier Scorecard",
"parentfield":"standings"
},
{
"min_grade":80.0,
"name":"Excellent",
"prevent_rfqs":0,
"notify_supplier":0,
"doctype":"Supplier Scorecard Standing",
"max_grade":100.0,
"prevent_pos":0,
"warn_pos":0,
"warn_rfqs":0,
"standing_color":"Blue",
"notify_employee":0,
"standing_name":"Excellent",
"parenttype":"Supplier Scorecard",
"parentfield":"standings"
}
],
"prevent_pos":0,
"variables": [
{
"param_name":"cost_of_on_time_shipments",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"Cost of On Time Shipments",
"path":"get_cost_of_on_time_shipments",
"parentfield":"variables"
},
{
"param_name":"tot_cost_shipments",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"Total Cost of Shipments",
"path":"get_total_cost_of_shipments",
"parentfield":"variables"
},
{
"param_name":"tot_days_late",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"Total Days Late",
"path":"get_total_days_late",
"parentfield":"variables"
},
{
"param_name":"total_working_days",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"Total Working Days",
"path":"get_total_workdays",
"parentfield":"variables"
},
{
"param_name":"on_time_shipment_num",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"# of On Time Shipments",
"path":"get_on_time_shipments",
"parentfield":"variables"
},
{
"param_name":"total_shipments",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"Total Shipments",
"path":"get_total_shipments",
"parentfield":"variables"
}
],
"period":"Per Month",
"doctype":"Supplier Scorecard",
"warn_pos":0,
"warn_rfqs":0,
"notify_supplier":0,
"criteria":[
{
"weight":100.0,
"doctype":"Supplier Scorecard Scoring Criteria",
"formula":"(({cost_of_on_time_shipments} / {tot_cost_shipments}) if {tot_cost_shipments} > 0 else 1 )* 100 ",
"criteria_name":"Delivery",
"max_score":100.0,
}
],
"supplier":"_Test Supplier",
"name":"_Test Supplier",
"weighting_function":"{total_score} * max( 0, min ( 1 , (12 - {period_number}) / 12) )",
}
]

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
/* global frappe */
frappe.ui.form.on("Supplier Scorecard Criteria", {
refresh: function() {}
});

View File

@@ -0,0 +1,184 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:criteria_name",
"beta": 1,
"creation": "2017-05-29 01:32:43.064891",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "criteria_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Criteria Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "weight",
"fieldtype": "Percent",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Criteria Weight",
"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": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "100",
"fieldname": "max_score",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Max Score",
"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": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "formula",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Criteria Formula",
"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": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-07-17 10:30:47.458285",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Scorecard Criteria",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

@@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
import re
from frappe.model.document import Document
class InvalidFormulaVariable(frappe.ValidationError): pass
class SupplierScorecardCriteria(Document):
def validate(self):
self.validate_variables()
self.validate_formula()
def validate_variables(self):
# make sure all the variables exist
_get_variables(self)
def validate_formula(self):
# evaluate the formula with 0's to make sure it is valid
test_formula = self.formula.replace("\r", "").replace("\n", "")
regex = r"\{(.*?)\}"
mylist = re.finditer(regex, test_formula, re.MULTILINE | re.DOTALL)
for dummy1, match in enumerate(mylist):
for dummy2 in range(0, len(match.groups())):
test_formula = test_formula.replace('{' + match.group(1) + '}', "0")
test_formula = test_formula.replace('&lt;','<').replace('&gt;','>')
try:
frappe.safe_eval(test_formula, None, {'max':max, 'min': min})
except Exception:
frappe.throw(_("Error evaluating the criteria formula"))
@frappe.whitelist()
def get_scoring_criteria(criteria_name):
criteria = frappe.get_doc("Supplier Scorecard Criteria", criteria_name)
return criteria
@frappe.whitelist()
def get_criteria_list():
criteria = frappe.db.sql("""
SELECT
scs.name
FROM
`tabSupplier Scorecard Criteria` scs""",
{}, as_dict=1)
return criteria
@frappe.whitelist()
def get_variables(criteria_name):
criteria = frappe.get_doc("Supplier Scorecard Criteria", criteria_name)
return _get_variables(criteria)
def _get_variables(criteria):
my_variables = []
regex = r"\{(.*?)\}"
mylist = re.finditer(regex, criteria.formula, re.MULTILINE | re.DOTALL)
for dummy1, match in enumerate(mylist):
for dummy2 in range(0, len(match.groups())):
try:
#var = frappe.get_doc("Supplier Scorecard Variable", {'param_name' : d})
var = frappe.db.sql("""
SELECT
scv.name
FROM
`tabSupplier Scorecard Variable` scv
WHERE
param_name=%(param)s""",
{'param':match.group(1)},)[0][0]
my_variables.append(var)
except Exception:
# Ignore the ones where the variable can't be found
frappe.throw(_('Unable to find variable: ') + str(match.group(1)), InvalidFormulaVariable)
#pass
#frappe.msgprint(str(my_variables))
return my_variables

View File

@@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals
import frappe
import unittest
class TestSupplierScorecardCriteria(unittest.TestCase):
def test_variables_exist(self):
delete_test_scorecards()
for d in test_good_criteria:
frappe.get_doc(d).insert()
self.assertRaises(frappe.ValidationError,frappe.get_doc(test_bad_criteria[0]).insert)
def test_formula_validate(self):
delete_test_scorecards()
self.assertRaises(frappe.ValidationError,frappe.get_doc(test_bad_criteria[1]).insert)
self.assertRaises(frappe.ValidationError,frappe.get_doc(test_bad_criteria[2]).insert)
def delete_test_scorecards():
# Delete all the periods so we can delete all the criteria
frappe.db.sql("""delete from `tabSupplier Scorecard Period`""")
frappe.db.sql("""delete from `tabSupplier Scorecard Scoring Criteria` where parenttype = 'Supplier Scorecard Period'""")
frappe.db.sql("""delete from `tabSupplier Scorecard Scoring Standing` where parenttype = 'Supplier Scorecard Period'""")
frappe.db.sql("""delete from `tabSupplier Scorecard Scoring Variable` where parenttype = 'Supplier Scorecard Period'""")
for d in test_good_criteria:
if frappe.db.exists("Supplier Scorecard Criteria", d.get("name")):
# Delete all the periods, then delete the scorecard
frappe.delete_doc(d.get("doctype"), d.get("name"))
for d in test_bad_criteria:
if frappe.db.exists("Supplier Scorecard Criteria", d.get("name")):
# Delete all the periods, then delete the scorecard
frappe.delete_doc(d.get("doctype"), d.get("name"))
test_good_criteria = [
{
"name":"Delivery",
"weight":40.0,
"doctype":"Supplier Scorecard Criteria",
"formula":"(({cost_of_on_time_shipments} / {tot_cost_shipments}) if {tot_cost_shipments} > 0 else 1 )* 100",
"criteria_name":"Delivery",
"max_score":100.0
},
]
test_bad_criteria = [
{
"name":"Fake Criteria 1",
"weight":40.0,
"doctype":"Supplier Scorecard Criteria",
"formula":"(({fake_variable} / {tot_cost_shipments}) if {tot_cost_shipments} > 0 else 1 )* 100", # Invalid variable name
"criteria_name":"Fake Criteria 1",
"max_score":100.0
},
{
"name":"Fake Criteria 2",
"weight":40.0,
"doctype":"Supplier Scorecard Criteria",
"formula":"(({cost_of_on_time_shipments} / {tot_cost_shipments}))* 100", # Force 0 divided by 0
"criteria_name":"Fake Criteria 2",
"max_score":100.0
},
{
"name":"Fake Criteria 3",
"weight":40.0,
"doctype":"Supplier Scorecard Criteria",
"formula":"(({cost_of_on_time_shipments} {cost_of_on_time_shipments} / {tot_cost_shipments}))* 100", # Two variables beside eachother
"criteria_name":"Fake Criteria 3",
"max_score":100.0
},
]

View File

@@ -0,0 +1,14 @@
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
/* global frappe */
frappe.ui.form.on("Supplier Scorecard Period", {
onload: function(frm) {
frm.get_field("variables").grid.toggle_display("value", true);
frm.get_field("criteria").grid.toggle_display("score", true);
}
});

View File

@@ -0,0 +1,397 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "naming_series:",
"beta": 1,
"creation": "2017-05-30 00:38:18.773013",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "supplier",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Supplier",
"length": 0,
"no_copy": 0,
"options": "Supplier",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"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": "Naming Series",
"length": 0,
"no_copy": 0,
"options": "SSC-",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_score",
"fieldtype": "Percent",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Period Score",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "start_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Start Date",
"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": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "end_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": "End Date",
"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": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "section_break_11",
"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": "Calculations",
"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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "criteria",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Criteria",
"length": 0,
"no_copy": 0,
"options": "Supplier Scorecard Scoring Criteria",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "variables",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Variables",
"length": 0,
"no_copy": 0,
"options": "Supplier Scorecard Scoring Variable",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "sec_ref",
"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": "Reference",
"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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "scorecard",
"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": "Supplier Scorecard Setup",
"length": 0,
"no_copy": 0,
"options": "Supplier Scorecard",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 1,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-07-12 07:33:26.130861",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Scorecard Period",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0
}

View File

@@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import throw, _
from frappe.model.document import Document
from frappe.model.mapper import get_mapped_doc
import erpnext.buying.doctype.supplier_scorecard_variable.supplier_scorecard_variable as variable_functions
class SupplierScorecardPeriod(Document):
def validate(self):
self.validate_criteria_weights()
self.calculate_variables()
self.calculate_criteria()
self.calculate_score()
def validate_criteria_weights(self):
weight = 0
for c in self.criteria:
weight += c.weight
if weight != 100:
throw(_('Criteria weights must add up to 100%'))
def calculate_variables(self):
for var in self.variables:
if '.' in var.path:
method_to_call = import_string_path(var.path)
var.value = method_to_call(self)
else:
method_to_call = getattr(variable_functions, var.path)
var.value = method_to_call(self)
def calculate_criteria(self):
#Get the criteria
for crit in self.criteria:
#me = ""
my_eval_statement = crit.formula.replace("\r", "").replace("\n", "")
#for let in my_eval_statement:
# me += let.encode('hex') + " "
#frappe.msgprint(me)
for var in self.variables:
if var.value:
if var.param_name in my_eval_statement:
my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', "{:.2f}".format(var.value))
else:
if var.param_name in my_eval_statement:
my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', '0.0')
#frappe.msgprint(my_eval_statement )
my_eval_statement = my_eval_statement.replace('&lt;','<').replace('&gt;','>')
try:
crit.score = min(crit.max_score, max( 0 ,frappe.safe_eval(my_eval_statement, None, {'max':max, 'min': min})))
except Exception:
frappe.throw(_("Could not solve criteria score function for {0}. Make sure the formula is valid.".format(crit.criteria_name)),frappe.ValidationError)
crit.score = 0
def calculate_score(self):
myscore = 0
for crit in self.criteria:
myscore += crit.score * crit.weight/100.0
self.total_score = myscore
def calculate_weighted_score(self, weighing_function):
my_eval_statement = weighing_function.replace("\r", "").replace("\n", "")
for var in self.variables:
if var.value:
if var.param_name in my_eval_statement:
my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', "{:.2f}".format(var.value))
else:
if var.param_name in my_eval_statement:
my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', '0.0')
my_eval_statement = my_eval_statement.replace('&lt;','<').replace('&gt;','>')
try:
weighed_score = frappe.safe_eval(my_eval_statement, None, {'max':max, 'min': min})
except Exception:
frappe.throw(_("Could not solve weighted score function. Make sure the formula is valid."),frappe.ValidationError)
weighed_score = 0
return weighed_score
def import_string_path(path):
components = path.split('.')
mod = __import__(components[0])
for comp in components[1:]:
mod = getattr(mod, comp)
return mod
def post_process(source, target):
pass
@frappe.whitelist()
def make_supplier_scorecard(source_name, target_doc=None):
#def update_item(obj, target, source_parent):
# target.qty = flt(obj.qty) - flt(obj.received_qty)
# target.stock_qty = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.conversion_factor)
# target.amount = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.rate)
# target.base_amount = (flt(obj.qty) - flt(obj.received_qty)) * \
# flt(obj.rate) * flt(source_parent.conversion_rate)
doc = get_mapped_doc("Supplier Scorecard", source_name, {
"Supplier Scorecard": {
"doctype": "Supplier Scorecard Period"
},
"Supplier Scorecard Scoring Variable": {
"doctype": "Supplier Scorecard Scoring Variable",
"add_if_empty": True
},
"Supplier Scorecard Scoring Constraint": {
"doctype": "Supplier Scorecard Scoring Constraint",
"add_if_empty": True
}
}, target_doc, post_process)
return doc

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