Compare commits

..

113 Commits

Author SHA1 Message Date
Anand Doshi
62d1256d44 [fix] injection 2015-12-01 17:02:04 +05:30
Nabin Hait
e9b445c853 [fix] Stock Entry additional costs patch fix for v4 accounts 2015-09-05 11:17:11 +05:30
Anand Doshi
41793bddd2 Merge branch 'develop' 2015-08-17 14:36:48 +05:30
Anand Doshi
b23049a55e bumped to version 5.6.4 2015-08-17 15:06:48 +06:00
Nabin Hait
99bf6c0927 Update patches.txt 2015-08-17 14:31:29 +05:30
Anand Doshi
b528c5cad2 Merge pull request #3893 from nabinhait/fix2
[fix] Get Balance only if account or party mentioned
2015-08-17 14:29:03 +05:30
Nabin Hait
dc76823a81 [fix] Get Balance only if account or party mentioned 2015-08-17 14:28:19 +05:30
Anand Doshi
862c36832a Merge pull request #3892 from nabinhait/fix1
[fix] Get stock and rate function restored
2015-08-17 14:26:01 +05:30
Anand Doshi
bd9dad96ae Merge pull request #3894 from nabinhait/fix3
Included Party and reference name in Journal Entry Account grid view
2015-08-17 14:24:52 +05:30
Anand Doshi
8ca933a83f Merge pull request #3895 from nabinhait/fix4
[fix] Additional Costs patch fixed for version 4 to 5 migration
2015-08-17 14:24:30 +05:30
Anand Doshi
f0107db3ca Merge pull request #3896 from nabinhait/fix5
[fix] precision issue in stock entry
2015-08-17 14:20:51 +05:30
Nabin Hait
c01342190c [fix] precision issue in stock entry 2015-08-17 14:18:44 +05:30
Nabin Hait
f763c1af25 [fix] Additional Costs patch fixed for version 4 to 5 migration 2015-08-17 12:06:53 +05:30
Nabin Hait
cbfd387c0b Included Party and reference name in Journal Entry Account grid view 2015-08-17 11:42:48 +05:30
Nabin Hait
ac07b1cc07 [fix] Get stock and rate function restored 2015-08-17 10:50:30 +05:30
Anand Doshi
4a1319289e Merge branch 'develop' 2015-08-14 17:53:41 +05:30
Anand Doshi
c5a43e46d8 bumped to version 5.6.3 2015-08-14 18:23:40 +06:00
Anand Doshi
04dfd7b98f [fix] Journal Entry Reference Name query 2015-08-14 17:34:43 +05:30
Anand Doshi
85e0e87f01 [fix] Show 'Backflush Raw Materials Based On' in Manufacturing Settings 2015-08-14 12:55:27 +05:30
Anand Doshi
e7a3c7c5ab Merge branch 'develop' 2015-08-14 12:21:37 +05:30
Anand Doshi
acc32fe7f7 bumped to version 5.6.2 2015-08-14 12:51:37 +06:00
Anand Doshi
487454e817 [hotfix] [patch] cleanup journal entry 2015-08-14 12:17:34 +05:30
Anand Doshi
dc278a7427 [hotfix] [patch] cleanup journal entry 2015-08-14 12:05:50 +05:30
Anand Doshi
698ee434c0 [hotfix] translation in es.csv 2015-08-14 11:45:43 +05:30
Anand Doshi
e116cb596c [hotfix] [report] payment period based on invoice date 2015-08-13 17:25:20 +05:30
Anand Doshi
169c3ed09d Merge branch 'develop' 2015-08-13 15:54:41 +05:30
Anand Doshi
d7ba618b92 bumped to version 5.6.1 2015-08-13 16:24:41 +06:00
Anand Doshi
0a37f5575f [hotfix] [patch] stock entry additional cost for docstatus < 2 2015-08-13 15:53:40 +05:30
Anand Doshi
b1bae1bde8 Merge branch 'develop' 2015-08-13 15:44:03 +05:30
Anand Doshi
bcfd4277f4 bumped to version 5.6.0 2015-08-13 16:14:03 +06:00
Anand Doshi
2b6915519f [change-log] 2015-08-13 15:36:18 +05:30
Anand Doshi
5eb84352ec Merge pull request #3868 from nabinhait/price_list_rate
[fix] Reset price list rate based on Pricing Rule type
2015-08-13 15:10:08 +05:30
Anand Doshi
1580bf9ca4 Merge pull request #3869 from rmehta/pricing-rule-layout
[minor] pricing rule layout
2015-08-13 15:08:54 +05:30
Rushabh Mehta
4c4c534dcd [minor] pricing rule layout 2015-08-13 15:00:54 +05:30
Nabin Hait
0da11f1b10 [fix] Reset price list rate based on Pricing Rule type 2015-08-13 14:58:19 +05:30
Anand Doshi
cb4784c940 Merge pull request #3822 from neilLasrado/item-uom
Changed UOM validation for Item Master
2015-08-13 14:36:37 +05:30
Nabin Hait
4c8ee279f3 Merge branch 'bobzz-zone-patch-7' into develop 2015-08-13 14:15:45 +05:30
Nabin Hait
58aea1f819 minor fix 2015-08-13 14:15:27 +05:30
Nabin Hait
760bfb27d0 Merge branch 'patch-7' of https://github.com/bobzz-zone/erpnext into bobzz-zone-patch-7 2015-08-13 14:14:26 +05:30
Anand Doshi
c0c4e866be Merge branch 'nabinhait-item_description' into develop
Conflicts:
	erpnext/patches.txt
2015-08-13 13:40:33 +05:30
Anand Doshi
b16474e606 [minor] Reload Journal Entry Account 2015-08-13 13:38:22 +05:30
Rushabh Mehta
bbed8972c3 [minor] pincode label changed to postal code, #3770 2015-08-13 13:38:21 +05:30
Rushabh Mehta
35f94dfbc6 [patch] cleanup_journal_entry 2015-08-13 13:38:21 +05:30
Rushabh Mehta
832fa2e76b [patch] cleanup_journal_entry 2015-08-13 13:38:21 +05:30
Rushabh Mehta
682ce24f8c [patch] cleanup_journal_entry 2015-08-13 13:38:21 +05:30
Nabin Hait
9f02b08427 minor fix 2015-08-13 13:38:20 +05:30
Rushabh Mehta
2645980f62 [patch] cleanup_journal_entry 2015-08-13 13:38:20 +05:30
Anand Doshi
ae1a91835e Merge pull request #3866 from nabinhait/fix3
[fix] fraction issue in gl entry
2015-08-13 13:35:57 +05:30
Anand Doshi
094755415a Merge pull request #3867 from rmehta/salary-slip-fix
[fix] salary slip to consider disable rounded total, #3792
2015-08-13 13:35:02 +05:30
Anand Doshi
746eae4d1a [minor] Reload Journal Entry Account 2015-08-13 12:52:13 +05:30
Rushabh Mehta
cdbb448f6c [fix] salary slip to consider disable rounded total, #3792 2015-08-13 12:48:04 +05:30
Rushabh Mehta
907ea7dd8a [minor] pincode label changed to postal code, #3770 2015-08-13 12:35:43 +05:30
Neil Trini Lasrado
9a73b7a319 Changed UOM validation for Item Master 2015-08-13 12:21:32 +05:30
Nabin Hait
2e54da2ea5 [fix] fraction issue in gl entry 2015-08-13 12:19:27 +05:30
Rushabh Mehta
7e4b93f48e [patch] cleanup_journal_entry 2015-08-13 12:10:21 +05:30
Rushabh Mehta
b01cc1b449 [patch] cleanup_journal_entry 2015-08-13 11:54:04 +05:30
Rushabh Mehta
f738b951c5 [patch] cleanup_journal_entry 2015-08-13 11:50:51 +05:30
Anand Doshi
bb1679b74b Merge pull request #3865 from nabinhait/fix3
minor fix
2015-08-13 11:48:47 +05:30
Nabin Hait
6ddcac7cee minor fix 2015-08-13 11:47:35 +05:30
Rushabh Mehta
bcf7da6b1e [patch] cleanup_journal_entry 2015-08-13 11:46:01 +05:30
Nabin Hait
c51d5ba5df [patch] Update item description in Production Order based on item master 2015-08-13 11:39:45 +05:30
Anand Doshi
57ca765d9e Merge pull request #3848 from rmehta/journal-entry-refactor
[refactor] added dynamic link in journal entry, #3847, #3814
2015-08-13 11:39:13 +05:30
Anand Doshi
92e7d1f41d Merge pull request #3855 from nabinhait/discount
discount percentage should not be reset to zero on applying price list
2015-08-13 11:39:03 +05:30
Rushabh Mehta
ed40542658 [fix] minor auto-select party type and add has_permission in whitelisted methods 2015-08-13 10:34:49 +05:30
Rushabh Mehta
207b3efed7 [fix] journal entry get_query 2015-08-12 15:18:35 +05:30
Rushabh Mehta
3131c732ff [fix] capacity planning error 2015-08-12 12:29:16 +05:30
Rushabh Mehta
1828c12481 [refactor] added dynamic link in journal entry, #3847 2015-08-12 12:28:33 +05:30
Nabin Hait
4a91c49e0d discount percentage should not be reset to zero on applying price list 2015-08-11 18:16:10 +05:30
Anand Doshi
ba1f4263dd Added Rohit Industries as sponsors for #3546 2015-08-11 17:05:17 +05:30
Anand Doshi
7d45929872 Merge pull request #3829 from dottenbr/customer-taxid
Tax ID added and Customer Details description updated
2015-08-11 12:33:32 +05:30
Rushabh Mehta
b70f871592 Merge pull request #3850 from dottenbr/patch-1
Update README.md
2015-08-11 10:15:42 +05:30
Rushabh Mehta
d58df13150 Merge pull request #3849 from dottenbr/phone-mandatory-removed
Phone removed from mandatory in Address
2015-08-11 10:03:28 +05:30
Dominik
4101a48869 Update README.md 2015-08-10 23:59:16 +05:30
Dominik
28eff7fb91 Phone removed from mandatory in Address 2015-08-10 20:22:21 +05:30
Nabin Hait
6dc40e9baf Update accounts_controller.py 2015-08-10 19:18:39 +05:30
Nabin Hait
ac6d11eb3c minor improvements 2015-08-10 19:14:43 +05:30
Neil Trini Lasrado
1c6eeb228f Fixes in Stock Entry 2015-08-10 19:14:43 +05:30
Neil Trini Lasrado
b44f26d1ba Fixed Max value for update FG Item in Production Order 2015-08-10 19:14:43 +05:30
Neil Trini Lasrado
8ea2f45713 Renamed update_fg_goods_based_on in Manufacturing Settings to backflush_raw_materials_based_on 2015-08-10 19:14:43 +05:30
Neil Trini Lasrado
dde65752b6 Fixed code to consider partial FG entry 2015-08-10 19:14:43 +05:30
Neil Trini Lasrado
845980c010 Added Feature - Update FG based on Material Transfer For Manufacturing 2015-08-10 19:14:43 +05:30
Rushabh Mehta
6f593130d0 Merge pull request #3823 from nabinhait/stock-entry-tax
Stock entry tax
2015-08-10 14:31:20 +05:30
Nabin Hait
52f3bfca73 change log and sponsors page 2015-08-10 14:07:45 +05:30
Nabin Hait
3c3a3ecea8 Additional Costs in Stock Entry 2015-08-10 14:07:45 +05:30
Nabin Hait
246e47e76e [fix] Dashboard in customer / supplier 2015-08-10 14:07:02 +05:30
Nabin Hait
f6aad5ed2d Distribute tax amount between items in stock entry 2015-08-10 14:07:01 +05:30
Nabin Hait
aa87931172 Show only active BOM in stock entry 2015-08-10 14:07:01 +05:30
Nabin Hait
fc155c7712 Added tax table in stock entry 2015-08-10 14:07:01 +05:30
Rushabh Mehta
47b5e6272d Merge pull request #3844 from nabinhait/fix12
[fix] Made expense account non-mandatory in POS Profile
2015-08-10 13:16:39 +05:30
Rushabh Mehta
eae56cae54 Merge pull request #3843 from thecarly/patch-1
[minor] fixed typo
2015-08-10 13:13:00 +05:30
Nabin Hait
ea925d26a8 [fix] Made expense account non-mandatory in POS Profile 2015-08-10 12:57:05 +05:30
thecarly
56f5156f3c [minor] fixed typo 2015-08-10 12:50:44 +05:30
Rushabh Mehta
ee069d47b5 Merge pull request #3797 from anandpdoshi/fix-missing-item-images
Rename old filenames for Item
2015-08-10 11:58:54 +05:30
Rushabh Mehta
6c83b6bddc Merge pull request #3811 from rmehta/opportunity-customer
[minor] add close button in opportunity and project links in customer
2015-08-10 11:57:23 +05:30
Rushabh Mehta
815b460ddd Merge pull request #3809 from nabinhait/journal_entry_fix
[fix] Party / Account Validation message against Invoice
2015-08-10 11:57:01 +05:30
Dominik
d1416542a0 Tax ID added and Customer Details description updated
Tax ID is a relatively generic descriptor for VAT (Value Added Tax) or any other countrie's tax identification system and should be required by most users of an ERP system. Since this removes the necessity to put the VAT into the Customer Description (not the ideal place to begin with) the description was updated and slimmed down.
2015-08-08 00:05:38 +05:30
Rushabh Mehta
69095e7285 [fix] website search 2015-08-07 15:48:53 +05:30
Rushabh Mehta
d6bdad7adf [fix] [hot] total in time log batch 2015-08-06 15:46:42 +05:30
Rushabh Mehta
48cccca9af [minor] add close button in opportunity and project links in customer 2015-08-06 15:37:01 +05:30
Nabin Hait
7c5124140e [fix] Party / Account Validation message against Invoice 2015-08-06 12:58:53 +05:30
Nabin Hait
143f384986 Merge branch 'develop' 2015-08-05 19:14:37 +05:30
Nabin Hait
37fdc43c88 bumped to version 5.5.1 2015-08-05 19:44:37 +06:00
Nabin Hait
ceb761852e Merge pull request #3807 from nabinhait/hotfix
[fix] fifo in stock ledger
2015-08-05 19:13:12 +05:30
Nabin Hait
65d8de36d0 Merge pull request #3804 from nabinhait/fix1
Fixes
2015-08-05 19:04:41 +05:30
Nabin Hait
8142cd2865 [fix] fifo in stock ledger 2015-08-05 18:57:37 +05:30
Anand Doshi
ed3a6cf748 [minor] removed print 2015-08-05 18:38:33 +05:30
Nabin Hait
2285eb7649 Merge pull request #3801 from bobzz-zone/patch-8
Update buying_controller.py
2015-08-05 16:15:02 +05:30
Nabin Hait
1648605950 [fix] Disabled OHADA system while fetching COA based on country 2015-08-05 15:56:05 +05:30
Nabin Hait
039154faa9 [fix] Asynchronus issue while fetching item description in Production Order 2015-08-05 15:56:05 +05:30
Rushabh Mehta
147acfd502 [fix] [mobile] abs url erpnext icon 2015-08-05 14:49:32 +05:30
bobzz-zone
b4c7bad33d Update buying_controller.py
dont force change conversion factor
2015-08-05 11:30:12 +07:00
bobzz-zone
ff04bf6346 Update stock_entry.py
fixed for null expense account
2015-08-05 11:28:11 +07:00
Anand Doshi
aa5182bb9e [fix] rename old filenames that start with FileData and fix missing Item images 2015-08-04 23:06:01 +05:30
82 changed files with 4474 additions and 1558 deletions

View File

@@ -16,7 +16,7 @@ ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a
### Full Install
The Easy Way install script for bench will install all dependencies (e.g. MariaDB). See https://github.com/frappe/bench
The Easy Way: our install script for bench will install all dependencies (e.g. MariaDB). See https://github.com/frappe/bench for more details.
New passwords will be created for the ERPNext "Administrator" user, the MariaDB root user, and the frappe user (the script displays the passwords and saves them to ~/frappe_passwords.txt).
@@ -71,6 +71,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 the Frappe Technologies for clarification.
When in doubt about your use of the ERPNext name or logo, please contact Frappe Technologies for clarification.
(inspired from WordPress)
(inspired by WordPress)

View File

@@ -1,2 +1,2 @@
from __future__ import unicode_literals
__version__ = '5.5.0'
__version__ = '5.6.4'

View File

@@ -92,13 +92,13 @@ def get_charts_for_country(country):
with open(os.path.join(path, fname), "r") as f:
_get_chart_name(f.read())
countries_use_OHADA_system = ["Benin", "Burkina Faso", "Cameroon", "Central African Republic", "Comoros",
"Congo", "Ivory Coast", "Gabon", "Guinea", "Guinea Bissau", "Equatorial Guinea", "Mali", "Niger",
"Replica of Democratic Congo", "Senegal", "Chad", "Togo"]
if country in countries_use_OHADA_system:
with open(os.path.join(os.path.dirname(__file__), "syscohada_syscohada_chart_template.json"), "r") as f:
_get_chart_name(f.read())
# countries_use_OHADA_system = ["Benin", "Burkina Faso", "Cameroon", "Central African Republic", "Comoros",
# "Congo", "Ivory Coast", "Gabon", "Guinea", "Guinea Bissau", "Equatorial Guinea", "Mali", "Niger",
# "Replica of Democratic Congo", "Senegal", "Chad", "Togo"]
#
# if country in countries_use_OHADA_system:
# with open(os.path.join(os.path.dirname(__file__), "syscohada_syscohada_chart_template.json"), "r") as f:
# _get_chart_name(f.read())
if len(charts) != 1:
charts.append("Standard")

View File

@@ -19,7 +19,8 @@ class BankReconciliation(Document):
dl = frappe.db.sql("""select t1.name, t1.cheque_no, t1.cheque_date, t2.debit,
t2.credit, t1.posting_date, t2.against_account, t1.clearance_date
t2.credit, t1.posting_date, t2.against_account, t1.clearance_date,
t2.reference_type, t2.reference_name
from
`tabJournal Entry` t1, `tabJournal Entry Account` t2
where

View File

@@ -1,11 +1,19 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"creation": "2013-02-22 01:27:37",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"allow_on_submit": 0,
"fieldname": "voucher_id",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Voucher ID",
"no_copy": 0,
@@ -13,46 +21,84 @@
"oldfieldtype": "Link",
"options": "Journal Entry",
"permlevel": 0,
"search_index": 0
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "clearance_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Clearance Date",
"no_copy": 0,
"oldfieldname": "clearance_date",
"oldfieldtype": "Date",
"permlevel": 0,
"search_index": 0
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "against_account",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Against Account",
"no_copy": 0,
"oldfieldname": "against_account",
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"search_index": 0
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "cheque_number",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Cheque Number",
"no_copy": 0,
"oldfieldname": "cheque_number",
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"search_index": 0
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "debit",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Debit",
"no_copy": 0,
@@ -60,12 +106,21 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"search_index": 0
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "credit",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Credit",
"no_copy": 0,
@@ -73,40 +128,113 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"search_index": 0
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "reference_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Reference Type",
"no_copy": 0,
"options": "DocType",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "reference_name",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Reference Name",
"no_copy": 0,
"options": "reference_type",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "posting_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Posting Date",
"no_copy": 0,
"oldfieldname": "posting_date",
"oldfieldtype": "Date",
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"search_index": 0
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "cheque_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Cheque Date",
"no_copy": 0,
"oldfieldname": "cheque_date",
"oldfieldtype": "Date",
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"search_index": 0
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"modified": "2015-04-21 01:29:29.570890",
"modified": "2015-08-10 16:59:43.974705",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Reconciliation Detail",
"owner": "Administrator",
"permissions": []
"permissions": [],
"read_only": 0,
"read_only_onload": 0
}

View File

@@ -48,34 +48,49 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
}
});
$.each([["against_voucher", "Purchase Invoice", "supplier"],
["against_invoice", "Sales Invoice", "customer"]], function(i, opts) {
me.frm.set_query(opts[0], "accounts", function(doc, cdt, cdn) {
var jvd = frappe.get_doc(cdt, cdn);
frappe.model.validate_missing(jvd, "party_type");
frappe.model.validate_missing(jvd, "party");
return {
filters: [
[opts[1], opts[2], "=", jvd.party],
[opts[1], "docstatus", "=", 1],
[opts[1], "outstanding_amount", "!=", 0]
]
};
});
});
this.frm.set_query("against_jv", "accounts", function(doc, cdt, cdn) {
me.frm.set_query("reference_name", "accounts", function(doc, cdt, cdn) {
var jvd = frappe.get_doc(cdt, cdn);
frappe.model.validate_missing(jvd, "account");
return {
query: "erpnext.accounts.doctype.journal_entry.journal_entry.get_against_jv",
filters: {
account: jvd.account,
party: jvd.party
}
// expense claim
if(jvd.reference_type==="Expense Claim") {
return {};
}
// journal entry
if(jvd.reference_type==="Journal Entry") {
frappe.model.validate_missing(jvd, "account");
return {
query: "erpnext.accounts.doctype.journal_entry.journal_entry.get_against_jv",
filters: {
account: jvd.account,
party: jvd.party
}
};
}
// against party
frappe.model.validate_missing(jvd, "party_type");
frappe.model.validate_missing(jvd, "party");
var out = {
filters: [
[jvd.reference_type, jvd.reference_type.indexOf("Sales")===0 ? "customer" : "supplier", "=", jvd.party],
[jvd.reference_type, "docstatus", "=", 1],
]
};
if(in_list(["Sales Invoice", "Purchase Invoice"], jvd.reference_type)) {
out.filters.push([jvd.reference_type, "outstanding_amount", "!=", 0]);
} else {
out.filters.push([jvd.reference_type, "per_billed", "<", 100]);
}
return out;
});
},
setup_balance_formatter: function() {
@@ -93,24 +108,16 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
})
},
against_voucher: function(doc, cdt, cdn) {
reference_name: function(doc, cdt, cdn) {
var d = frappe.get_doc(cdt, cdn);
if (d.against_voucher && !flt(d.debit)) {
this.get_outstanding('Purchase Invoice', d.against_voucher, d);
if (d.reference_type==="Purchase Invoice" && !flt(d.debit)) {
this.get_outstanding('Purchase Invoice', d.reference_name, d);
}
},
against_invoice: function(doc, cdt, cdn) {
var d = frappe.get_doc(cdt, cdn);
if (d.against_invoice && !flt(d.credit)) {
this.get_outstanding('Sales Invoice', d.against_invoice, d);
if (d.reference_type==="Sales Invoice" && !flt(d.credit)) {
this.get_outstanding('Sales Invoice', d.reference_name, d);
}
},
against_jv: function(doc, cdt, cdn) {
var d = frappe.get_doc(cdt, cdn);
if (d.against_jv && !flt(d.credit) && !flt(d.debit)) {
this.get_outstanding('Journal Entry', d.against_jv, d);
if (d.reference_type==="Journal Entry" && !flt(d.credit) && !flt(d.debit)) {
this.get_outstanding('Journal Entry', d.reference_name, d);
}
},
@@ -214,11 +221,12 @@ cur_frm.cscript.account = function(doc,dt,dn) {
var d = locals[dt][dn];
if(d.account) {
return frappe.call({
method: "erpnext.accounts.utils.get_balance_on",
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_account_balance_and_party_type",
args: {account: d.account, date: doc.posting_date},
callback: function(r) {
d.balance = r.message;
$.extend(d, r.message);
refresh_field('balance', d.name, 'accounts');
refresh_field('party_type', d.name, 'accounts');
}
});
}

View File

@@ -28,13 +28,10 @@ class JournalEntry(AccountsController):
self.validate_entries_for_advance()
self.validate_debit_and_credit()
self.validate_against_jv()
self.validate_against_sales_invoice()
self.validate_against_purchase_invoice()
self.validate_reference_doc()
self.set_against_account()
self.create_remarks()
self.set_print_format_fields()
self.validate_against_sales_order()
self.validate_against_purchase_order()
self.check_due_date()
self.validate_expense_claim()
self.validate_credit_debit_note()
@@ -54,10 +51,8 @@ class JournalEntry(AccountsController):
advance_paid = frappe._dict()
for d in self.get("accounts"):
if d.is_advance:
if d.against_sales_order:
advance_paid.setdefault("Sales Order", []).append(d.against_sales_order)
elif d.against_purchase_order:
advance_paid.setdefault("Purchase Order", []).append(d.against_purchase_order)
if d.reference_type in ("Sales Order", "Purchase Order"):
advance_paid.setdefault(d.reference_type, []).append(d.reference_name)
for voucher_type, order_list in advance_paid.items():
for voucher_no in list(set(order_list)):
@@ -65,7 +60,7 @@ class JournalEntry(AccountsController):
def on_cancel(self):
from erpnext.accounts.utils import remove_against_link_from_jv
remove_against_link_from_jv(self.doctype, self.name, "against_jv")
remove_against_link_from_jv(self.doctype, self.name)
self.make_gl_entries(1)
self.update_advance_paid()
@@ -93,10 +88,8 @@ class JournalEntry(AccountsController):
for d in self.get("accounts"):
if d.party_type and d.party and d.get("credit" if d.party_type=="Customer" else "debit") > 0:
due_date = None
if d.against_invoice:
due_date = frappe.db.get_value("Sales Invoice", d.against_invoice, "due_date")
elif d.against_voucher:
due_date = frappe.db.get_value("Purchase Invoice", d.against_voucher, "due_date")
if d.reference_type in ("Sales Invoice", "Purchase Invoice"):
due_date = frappe.db.get_value(d.reference_type, d.reference_name, "due_date")
if due_date and getdate(self.cheque_date) > getdate(due_date):
diff = date_diff(self.cheque_date, due_date)
@@ -115,17 +108,17 @@ class JournalEntry(AccountsController):
def validate_entries_for_advance(self):
for d in self.get('accounts'):
if not (d.against_voucher and d.against_invoice and d.against_jv):
if d.reference_type not in ("Sales Invoice", "Purchase Invoice", "Journal Entry"):
if (d.party_type == 'Customer' and flt(d.credit) > 0) or \
(d.party_type == 'Supplier' and flt(d.debit) > 0):
if not d.is_advance:
if d.is_advance=="No":
msgprint(_("Row {0}: Please check 'Is Advance' against Account {1} if this is an advance entry.").format(d.idx, d.account))
elif (d.against_sales_order or d.against_purchase_order) and d.is_advance != "Yes":
elif d.reference_type in ("Sales Order", "Purchase Order") and d.is_advance != "Yes":
frappe.throw(_("Row {0}: Payment against Sales/Purchase Order should always be marked as advance").format(d.idx))
def validate_against_jv(self):
for d in self.get('accounts'):
if d.against_jv:
if d.reference_type=="Journal Entry":
account_root_type = frappe.db.get_value("Account", d.account, "root_type")
if account_root_type == "Asset" and flt(d.debit) > 0:
frappe.throw(_("For {0}, only credit accounts can be linked against another debit entry")
@@ -134,17 +127,17 @@ class JournalEntry(AccountsController):
frappe.throw(_("For {0}, only debit accounts can be linked against another credit entry")
.format(d.account))
if d.against_jv == self.name:
if d.reference_name == self.name:
frappe.throw(_("You can not enter current voucher in 'Against Journal Entry' column"))
against_entries = frappe.db.sql("""select * from `tabJournal Entry Account`
where account = %s and docstatus = 1 and parent = %s
and ifnull(against_jv, '') = '' and ifnull(against_invoice, '') = ''
and ifnull(against_voucher, '') = ''""", (d.account, d.against_jv), as_dict=True)
and ifnull(reference_type, '') in ("", "Sales Order", "Purchase Order")
""", (d.account, d.reference_name), as_dict=True)
if not against_entries:
frappe.throw(_("Journal Entry {0} does not have account {1} or already matched against other voucher")
.format(d.against_jv, d.account))
.format(d.reference_name, d.account))
else:
dr_or_cr = "debit" if d.credit > 0 else "credit"
valid = False
@@ -153,88 +146,99 @@ class JournalEntry(AccountsController):
valid = True
if not valid:
frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry")
.format(d.against_jv, dr_or_cr))
.format(d.reference_name, dr_or_cr))
def validate_against_sales_invoice(self):
self.validate_account_in_against_voucher("against_invoice", "Sales Invoice")
def validate_against_purchase_invoice(self):
self.validate_account_in_against_voucher("against_voucher", "Purchase Invoice")
def validate_against_sales_order(self):
payment_against_voucher = self.validate_account_in_against_voucher("against_sales_order", "Sales Order")
self.validate_against_order_fields("Sales Order", payment_against_voucher)
def validate_against_purchase_order(self):
payment_against_voucher = self.validate_account_in_against_voucher("against_purchase_order", "Purchase Order")
self.validate_against_order_fields("Purchase Order", payment_against_voucher)
def validate_account_in_against_voucher(self, against_field, doctype):
payment_against_voucher = frappe._dict()
field_dict = {'Sales Invoice': ["Customer", "Debit To"],
def validate_reference_doc(self):
"""Validates reference document"""
field_dict = {
'Sales Invoice': ["Customer", "Debit To"],
'Purchase Invoice': ["Supplier", "Credit To"],
'Sales Order': ["Customer"],
'Purchase Order': ["Supplier"]
}
}
self.reference_totals = {}
self.reference_types = {}
for d in self.get("accounts"):
if d.get(against_field):
dr_or_cr = "credit" if against_field in ["against_invoice", "against_sales_order"] \
if not d.reference_type:
d.reference_name = None
if not d.reference_name:
d.reference_type = None
if d.reference_type and d.reference_name and (d.reference_type in field_dict.keys()):
dr_or_cr = "credit" if d.reference_type in ("Sales Order", "Sales Invoice") \
else "debit"
if against_field == "against_sales_order" and flt(d.debit) > 0:
frappe.throw(_("Row {0}: Debit entry can not be linked with a {1}").format(d.idx, doctype))
if against_field == "against_purchase_order" and flt(d.credit) > 0:
frappe.throw(_("Row {0}: Credit entry can not be linked with a {1}").format(d.idx, doctype))
# check debit or credit type Sales / Purchase Order
if d.reference_type=="Sales Order" and flt(d.debit) > 0:
frappe.throw(_("Row {0}: Debit entry can not be linked with a {1}").format(d.idx, d.reference_type))
against_voucher = frappe.db.get_value(doctype, d.get(against_field),
[scrub(dt) for dt in field_dict.get(doctype)])
if d.reference_type == "Purchase Order" and flt(d.credit) > 0:
frappe.throw(_("Row {0}: Credit entry can not be linked with a {1}").format(d.idx, d.reference_type))
if against_field in ["against_invoice", "against_voucher"]:
if (against_voucher[0] !=d.party or against_voucher[1] != d.account):
frappe.throw(_("Row {0}: Party / Account does not match with \
Customer / Debit To in {1}").format(d.idx, doctype))
else:
payment_against_voucher.setdefault(d.get(against_field), []).append(flt(d.get(dr_or_cr)))
# set totals
if not d.reference_name in self.reference_totals:
self.reference_totals[d.reference_name] = 0.0
self.reference_totals[d.reference_name] += flt(d.get(dr_or_cr))
self.reference_types[d.reference_name] = d.reference_type
if against_field in ["against_sales_order", "against_purchase_order"]:
against_voucher = frappe.db.get_value(d.reference_type, d.reference_name,
[scrub(dt) for dt in field_dict.get(d.reference_type)])
# check if party and account match
if d.reference_type in ("Sales Invoice", "Purchase Invoice"):
if (against_voucher[0] != d.party or against_voucher[1] != d.account):
frappe.throw(_("Row {0}: Party / Account does not match with {1} / {2} in {3} {4}")
.format(d.idx, field_dict.get(d.reference_type)[0], field_dict.get(d.reference_type)[1],
d.reference_type, d.reference_name))
# check if party matches for Sales / Purchase Order
if d.reference_type in ("Sales Order", "Purchase Order"):
# set totals
if against_voucher != d.party:
frappe.throw(_("Row {0}: {1} {2} does not match with {3}") \
.format(d.idx, d.party_type, d.party, doctype))
elif d.is_advance == "Yes":
payment_against_voucher.setdefault(d.get(against_field), []).append(flt(d.get(dr_or_cr)))
.format(d.idx, d.party_type, d.party, d.reference_type))
return payment_against_voucher
self.validate_orders()
self.validate_invoices()
def validate_against_invoice_fields(self, doctype, payment_against_voucher):
for voucher_no, payment_list in payment_against_voucher.items():
voucher_properties = frappe.db.get_value(doctype, voucher_no,
["docstatus", "outstanding_amount"])
def validate_orders(self):
"""Validate totals, stopped and docstatus for orders"""
for reference_name, total in self.reference_totals.iteritems():
reference_type = self.reference_types[reference_name]
if voucher_properties[0] != 1:
frappe.throw(_("{0} {1} is not submitted").format(doctype, voucher_no))
if reference_type in ("Sales Order", "Purchase Order"):
voucher_properties = frappe.db.get_value(reference_type, reference_name,
["docstatus", "per_billed", "status", "advance_paid", "base_grand_total"])
if flt(voucher_properties[1]) < flt(sum(payment_list)):
frappe.throw(_("Payment against {0} {1} cannot be greater \
than Outstanding Amount {2}").format(doctype, voucher_no, voucher_properties[1]))
if voucher_properties[0] != 1:
frappe.throw(_("{0} {1} is not submitted").format(reference_type, reference_name))
def validate_against_order_fields(self, doctype, payment_against_voucher):
for voucher_no, payment_list in payment_against_voucher.items():
voucher_properties = frappe.db.get_value(doctype, voucher_no,
["docstatus", "per_billed", "status", "advance_paid", "base_grand_total"])
if flt(voucher_properties[1]) >= 100:
frappe.throw(_("{0} {1} is fully billed").format(reference_type, reference_name))
if voucher_properties[0] != 1:
frappe.throw(_("{0} {1} is not submitted").format(doctype, voucher_no))
if cstr(voucher_properties[2]) == "Stopped":
frappe.throw(_("{0} {1} is stopped").format(reference_type, reference_name))
if flt(voucher_properties[1]) >= 100:
frappe.throw(_("{0} {1} is fully billed").format(doctype, voucher_no))
if flt(voucher_properties[4]) < (flt(voucher_properties[3]) + total):
frappe.throw(_("Advance paid against {0} {1} cannot be greater \
than Grand Total {2}").format(reference_type, reference_name, voucher_properties[4]))
if cstr(voucher_properties[2]) == "Stopped":
frappe.throw(_("{0} {1} is stopped").format(doctype, voucher_no))
def validate_invoices(self):
"""Validate totals and docstatus for invoices"""
for reference_name, total in self.reference_totals.iteritems():
reference_type = self.reference_types[reference_name]
if flt(voucher_properties[4]) < flt(voucher_properties[3]) + flt(sum(payment_list)):
frappe.throw(_("Advance paid against {0} {1} cannot be greater \
than Grand Total {2}").format(doctype, voucher_no, voucher_properties[3]))
if reference_type in ("Sales Invoice", "Purchase Invoice"):
voucher_properties = frappe.db.get_value(reference_type, reference_name,
["docstatus", "outstanding_amount"])
if voucher_properties[0] != 1:
frappe.throw(_("{0} {1} is not submitted").format(reference_type, reference_name))
if flt(voucher_properties[1]) < total:
frappe.throw(_("Payment against {0} {1} cannot be greater \
than Outstanding Amount {2}").format(reference_type, reference_name, voucher_properties[1]))
def set_against_account(self):
accounts_debited, accounts_credited = [], []
@@ -274,25 +278,25 @@ class JournalEntry(AccountsController):
company_currency = get_company_currency(self.company)
for d in self.get('accounts'):
if d.against_invoice and d.credit:
if d.reference_type=="Sales Invoice" and d.credit:
r.append(_("{0} against Sales Invoice {1}").format(fmt_money(flt(d.credit), currency = company_currency), \
d.against_invoice))
d.reference_name))
if d.against_sales_order and d.credit:
if d.reference_type=="Sales Order" and d.credit:
r.append(_("{0} against Sales Order {1}").format(fmt_money(flt(d.credit), currency = company_currency), \
d.against_sales_order))
d.reference_name))
if d.against_voucher and d.debit:
if d.reference_type == "Purchase Invoice" and d.debit:
bill_no = frappe.db.sql("""select bill_no, bill_date
from `tabPurchase Invoice` where name=%s""", d.against_voucher)
from `tabPurchase Invoice` where name=%s""", d.reference_name)
if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() \
not in ['na', 'not applicable', 'none']:
r.append(_('{0} against Bill {1} dated {2}').format(fmt_money(flt(d.debit), currency=company_currency), bill_no[0][0],
bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d'))))
if d.against_purchase_order and d.debit:
if d.reference_type == "Purchase Order" and d.debit:
r.append(_("{0} against Purchase Order {1}").format(fmt_money(flt(d.credit), currency = company_currency), \
d.against_purchase_order))
d.reference_name))
if self.user_remark:
r.append(_("Note: {0}").format(self.user_remark))
@@ -331,13 +335,8 @@ class JournalEntry(AccountsController):
"against": d.against_account,
"debit": flt(d.debit, self.precision("debit", "accounts")),
"credit": flt(d.credit, self.precision("credit", "accounts")),
"against_voucher_type": (("Purchase Invoice" if d.against_voucher else None)
or ("Sales Invoice" if d.against_invoice else None)
or ("Journal Entry" if d.against_jv else None)
or ("Sales Order" if d.against_sales_order else None)
or ("Purchase Order" if d.against_purchase_order else None)),
"against_voucher": d.against_voucher or d.against_invoice or d.against_jv
or d.against_sales_order or d.against_purchase_order,
"against_voucher_type": d.reference_type,
"against_voucher": d.reference_name,
"remarks": self.remark,
"cost_center": d.cost_center
})
@@ -384,11 +383,13 @@ class JournalEntry(AccountsController):
if self.write_off_based_on == 'Accounts Receivable':
jd1.party_type = "Customer"
jd1.credit = flt(d.outstanding_amount, self.precision("credit", "accounts"))
jd1.against_invoice = cstr(d.name)
jd1.reference_type = "Sales Invoice"
jd1.reference_name = cstr(d.name)
elif self.write_off_based_on == 'Accounts Payable':
jd1.party_type = "Supplier"
jd1.debit = flt(d.outstanding_amount, self.precision("debit", "accounts"))
jd1.against_voucher = cstr(d.name)
jd1.reference_type = "Purchase Invoice"
jd1.reference_name = cstr(d.name)
jd2 = self.append('accounts', {})
if self.write_off_based_on == 'Accounts Receivable':
@@ -414,19 +415,20 @@ class JournalEntry(AccountsController):
def update_expense_claim(self):
for d in self.accounts:
if d.against_expense_claim:
if d.reference_type=="Expense Claim":
amt = frappe.db.sql("""select sum(debit) as amt from `tabJournal Entry Account`
where against_expense_claim = %s and docstatus = 1""", d.against_expense_claim ,as_dict=1)[0].amt
frappe.db.set_value("Expense Claim", d.against_expense_claim , "total_amount_reimbursed", amt)
where reference_type = "Expense Claim" and
reference_name = %s and docstatus = 1""", d.reference_name ,as_dict=1)[0].amt
frappe.db.set_value("Expense Claim", d.reference_name , "total_amount_reimbursed", amt)
def validate_expense_claim(self):
for d in self.accounts:
if d.against_expense_claim:
if d.reference_type=="Expense Claim":
sanctioned_amount, reimbursed_amount = frappe.db.get_value("Expense Claim",
d.against_expense_claim, ("total_sanctioned_amount", "total_amount_reimbursed"))
d.reference_name, ("total_sanctioned_amount", "total_amount_reimbursed"))
pending_amount = flt(sanctioned_amount) - flt(reimbursed_amount)
if d.debit > pending_amount:
frappe.throw(_("Row No {0}: Amount cannot be greater than Pending Amount against Expense Claim {1}. Pending Amount is {2}".format(d.idx, d.against_expense_claim, pending_amount)))
frappe.throw(_("Row No {0}: Amount cannot be greater than Pending Amount against Expense Claim {1}. Pending Amount is {2}".format(d.idx, d.reference_name, pending_amount)))
def validate_credit_debit_note(self):
if self.stock_entry:
@@ -466,6 +468,7 @@ def get_default_bank_cash_account(company, voucher_type, mode_of_payment=None):
@frappe.whitelist()
def get_payment_entry_from_sales_invoice(sales_invoice):
"""Returns new Journal Entry document as dict for given Sales Invoice"""
from erpnext.accounts.utils import get_balance_on
si = frappe.get_doc("Sales Invoice", sales_invoice)
jv = get_payment_entry(si)
@@ -478,7 +481,8 @@ def get_payment_entry_from_sales_invoice(sales_invoice):
jv.get("accounts")[0].balance = get_balance_on(si.debit_to)
jv.get("accounts")[0].party_balance = get_balance_on(party=si.customer, party_type="Customer")
jv.get("accounts")[0].credit = si.outstanding_amount
jv.get("accounts")[0].against_invoice = si.name
jv.get("accounts")[0].reference_type = si.doctype
jv.get("accounts")[0].reference_name = si.name
# debit bank
jv.get("accounts")[1].debit = si.outstanding_amount
@@ -487,6 +491,7 @@ def get_payment_entry_from_sales_invoice(sales_invoice):
@frappe.whitelist()
def get_payment_entry_from_purchase_invoice(purchase_invoice):
"""Returns new Journal Entry document as dict for given Purchase Invoice"""
pi = frappe.get_doc("Purchase Invoice", purchase_invoice)
jv = get_payment_entry(pi)
jv.remark = 'Payment against Purchase Invoice {0}. {1}'.format(pi.name, pi.remarks)
@@ -498,13 +503,78 @@ def get_payment_entry_from_purchase_invoice(purchase_invoice):
jv.get("accounts")[0].balance = get_balance_on(pi.credit_to)
jv.get("accounts")[0].party_balance = get_balance_on(party=pi.supplier, party_type="Supplier")
jv.get("accounts")[0].debit = pi.outstanding_amount
jv.get("accounts")[0].against_voucher = pi.name
jv.get("accounts")[0].reference_type = pi.doctype
jv.get("accounts")[0].reference_name = pi.name
# credit bank
jv.get("accounts")[1].credit = pi.outstanding_amount
return jv.as_dict()
@frappe.whitelist()
def get_payment_entry_from_sales_order(sales_order):
"""Returns new Journal Entry document as dict for given Sales Order"""
from erpnext.accounts.utils import get_balance_on
from erpnext.accounts.party import get_party_account
so = frappe.get_doc("Sales Order", sales_order)
if flt(so.per_billed, 2) != 0.0:
frappe.throw(_("Can only make payment against unbilled Sales Order"))
jv = get_payment_entry(so)
jv.remark = 'Advance payment received against Sales Order {0}.'.format(so.name)
party_account = get_party_account(so.company, so.customer, "Customer")
amount = flt(so.base_grand_total) - flt(so.advance_paid)
# credit customer
jv.get("accounts")[0].account = party_account
jv.get("accounts")[0].party_type = "Customer"
jv.get("accounts")[0].party = so.customer
jv.get("accounts")[0].balance = get_balance_on(party_account)
jv.get("accounts")[0].party_balance = get_balance_on(party=so.customer, party_type="Customer")
jv.get("accounts")[0].credit = amount
jv.get("accounts")[0].reference_type = so.doctype
jv.get("accounts")[0].reference_name = so.name
jv.get("accounts")[0].is_advance = "Yes"
# debit bank
jv.get("accounts")[1].debit = amount
return jv.as_dict()
@frappe.whitelist()
def get_payment_entry_from_purchase_order(purchase_order):
"""Returns new Journal Entry document as dict for given Sales Order"""
from erpnext.accounts.utils import get_balance_on
from erpnext.accounts.party import get_party_account
po = frappe.get_doc("Purchase Order", purchase_order)
if flt(po.per_billed, 2) != 0.0:
frappe.throw(_("Can only make payment against unbilled Sales Order"))
jv = get_payment_entry(po)
jv.remark = 'Advance payment made against Purchase Order {0}.'.format(po.name)
party_account = get_party_account(po.company, po.supplier, "Supplier")
amount = flt(po.base_grand_total) - flt(po.advance_paid)
# credit customer
jv.get("accounts")[0].account = party_account
jv.get("accounts")[0].party_type = "Supplier"
jv.get("accounts")[0].party = po.supplier
jv.get("accounts")[0].balance = get_balance_on(party_account)
jv.get("accounts")[0].party_balance = get_balance_on(party=po.supplier, party_type="Supplier")
jv.get("accounts")[0].debit = amount
jv.get("accounts")[0].reference_type = po.doctype
jv.get("accounts")[0].reference_name = po.name
jv.get("accounts")[0].is_advance = "Yes"
# debit bank
jv.get("accounts")[1].credit = amount
return jv.as_dict()
def get_payment_entry(doc):
bank_account = get_default_bank_cash_account(doc.company, "Bank Entry")
@@ -535,22 +605,22 @@ def get_against_jv(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""select jv.name, jv.posting_date, jv.user_remark
from `tabJournal Entry` jv, `tabJournal Entry Account` jv_detail
where jv_detail.parent = jv.name and jv_detail.account = %s and ifnull(jv_detail.party, '') = %s
and (ifnull(jv_detail.against_invoice, '') = '' and ifnull(jv_detail.against_voucher, '') = ''
and ifnull(jv_detail.against_jv, '') = '' )
and ifnull(jv_detail.reference_type, '') = ''
and jv.docstatus = 1 and jv.{0} like %s order by jv.name desc limit %s, %s""".format(searchfield),
(filters.get("account"), cstr(filters.get("party")), "%{0}%".format(txt), start, page_len))
@frappe.whitelist()
def get_outstanding(args):
if not frappe.has_permission("Account"):
frappe.msgprint(_("No Permission"), raise_exception=1)
args = eval(args)
if args.get("doctype") == "Journal Entry":
condition = " and party=%(party)s" if args.get("party") else ""
against_jv_amount = frappe.db.sql("""
select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
from `tabJournal Entry Account` where parent=%(docname)s and account=%(account)s {0}
and ifnull(against_invoice, '')='' and ifnull(against_voucher, '')=''
and ifnull(against_jv, '')=''""".format(condition), args)
and ifnull(reference_type, '')=''""".format(condition), args)
against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0
return {
@@ -569,6 +639,9 @@ def get_outstanding(args):
@frappe.whitelist()
def get_party_account_and_balance(company, party_type, party):
if not frappe.has_permission("Account"):
frappe.msgprint(_("No Permission"), raise_exception=1)
from erpnext.accounts.party import get_party_account
account = get_party_account(company, party, party_type)
@@ -580,3 +653,16 @@ def get_party_account_and_balance(company, party_type, party):
"balance": account_balance,
"party_balance": party_balance
}
@frappe.whitelist()
def get_account_balance_and_party_type(account, date):
"""Returns dict of account balance and party type to be set in Journal Entry on selection of account."""
if not frappe.has_permission("Account"):
frappe.msgprint(_("No Permission"), raise_exception=1)
account_type = frappe.db.get_value("Account", account, "account_type")
return {
"balance": get_balance_on(account, date),
"party_type": {"Receivable":"Customer", "Payable":"Supplier"}.get(account_type, "")
}

View File

@@ -29,10 +29,6 @@ class TestJournalEntry(unittest.TestCase):
def jv_against_voucher_testcase(self, base_jv, test_voucher):
dr_or_cr = "credit" if test_voucher.doctype in ["Sales Order", "Journal Entry"] else "debit"
field_dict = {'Journal Entry': "against_jv",
'Sales Order': "against_sales_order",
'Purchase Order': "against_purchase_order"
}
test_voucher.insert()
test_voucher.submit()
@@ -42,21 +38,20 @@ class TestJournalEntry(unittest.TestCase):
where account = %s and docstatus = 1 and parent = %s""",
("_Test Receivable - _TC", test_voucher.name)))
self.assertTrue(not frappe.db.sql("""select name from `tabJournal Entry Account`
where %s=%s""" % (field_dict.get(test_voucher.doctype), '%s'), (test_voucher.name)))
self.assertFalse(frappe.db.sql("""select name from `tabJournal Entry Account`
where reference_type = %s and reference_name = %s""", (test_voucher.doctype, test_voucher.name)))
base_jv.get("accounts")[0].is_advance = "Yes" if (test_voucher.doctype in ["Sales Order", "Purchase Order"]) else "No"
base_jv.get("accounts")[0].set(field_dict.get(test_voucher.doctype), test_voucher.name)
base_jv.get("accounts")[0].set("reference_type", test_voucher.doctype)
base_jv.get("accounts")[0].set("reference_name", test_voucher.name)
base_jv.insert()
base_jv.submit()
submitted_voucher = frappe.get_doc(test_voucher.doctype, test_voucher.name)
self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
where %s=%s""" % (field_dict.get(test_voucher.doctype), '%s'), (submitted_voucher.name)))
self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
where %s=%s and %s=400""" % (field_dict.get(submitted_voucher.doctype), '%s', dr_or_cr), (submitted_voucher.name)))
where reference_type = %s and reference_name = %s and {0}=400""".format(dr_or_cr),
(submitted_voucher.doctype, submitted_voucher.name)))
if base_jv.get("accounts")[0].is_advance == "Yes":
self.advance_paid_testcase(base_jv, submitted_voucher, dr_or_cr)
@@ -74,8 +69,8 @@ class TestJournalEntry(unittest.TestCase):
if test_voucher.doctype == "Journal Entry":
# if test_voucher is a Journal Entry, test cancellation of test_voucher
test_voucher.cancel()
self.assertTrue(not frappe.db.sql("""select name from `tabJournal Entry Account`
where against_jv=%s""", test_voucher.name))
self.assertFalse(frappe.db.sql("""select name from `tabJournal Entry Account`
where reference_type='Journal Entry' and reference_name=%s""", test_voucher.name))
elif test_voucher.doctype in ["Sales Order", "Purchase Order"]:
# if test_voucher is a Sales Order/Purchase Order, test error on cancellation of test_voucher
@@ -102,23 +97,23 @@ class TestJournalEntry(unittest.TestCase):
def test_monthly_budget_crossed_ignore(self):
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
self.set_total_expense_zero("2013-02-28")
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", 40000, "_Test Cost Center - _TC", submit=True)
self.assertTrue(frappe.db.get_value("GL Entry",
{"voucher_type": "Journal Entry", "voucher_no": jv.name}))
def test_monthly_budget_crossed_stop(self):
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Stop")
self.set_total_expense_zero("2013-02-28")
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", 40000, "_Test Cost Center - _TC")
self.assertRaises(BudgetError, jv.submit)
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
@@ -127,37 +122,37 @@ class TestJournalEntry(unittest.TestCase):
self.test_monthly_budget_crossed_ignore()
frappe.db.set_value("Company", "_Test Company", "yearly_bgt_flag", "Stop")
self.set_total_expense_zero("2013-02-28")
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", 150000, "_Test Cost Center - _TC")
self.assertRaises(BudgetError, jv.submit)
frappe.db.set_value("Company", "_Test Company", "yearly_bgt_flag", "Ignore")
def test_monthly_budget_on_cancellation(self):
self.set_total_expense_zero("2013-02-28")
jv1 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
jv1 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", 20000, "_Test Cost Center - _TC", submit=True)
self.assertTrue(frappe.db.get_value("GL Entry",
{"voucher_type": "Journal Entry", "voucher_no": jv1.name}))
jv2 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
jv2 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", 20000, "_Test Cost Center - _TC", submit=True)
self.assertTrue(frappe.db.get_value("GL Entry",
{"voucher_type": "Journal Entry", "voucher_no": jv2.name}))
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Stop")
self.assertRaises(BudgetError, jv1.cancel)
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
def get_actual_expense(self, monthly_end_date):
return get_actual_expense({
"account": "_Test Account Cost for Goods Sold - _TC",
@@ -166,19 +161,19 @@ class TestJournalEntry(unittest.TestCase):
"company": "_Test Company",
"fiscal_year": get_fiscal_year(monthly_end_date)[0]
})
def set_total_expense_zero(self, posting_date):
existing_expense = self.get_actual_expense(posting_date)
make_journal_entry("_Test Account Cost for Goods Sold - _TC",
make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", -existing_expense, "_Test Cost Center - _TC", submit=True)
def make_journal_entry(account1, account2, amount, cost_center=None, submit=False):
jv = frappe.new_doc("Journal Entry")
jv.posting_date = "2013-02-14"
jv.company = "_Test Company"
jv.fiscal_year = "_Test Fiscal Year 2013"
jv.user_remark = "test"
jv.set("accounts", [
{
"account": account1,
@@ -193,11 +188,11 @@ def make_journal_entry(account1, account2, amount, cost_center=None, submit=Fals
}
])
jv.insert()
if submit:
jv.submit()
return jv
test_records = frappe.get_test_records('Journal Entry')

View File

@@ -1,28 +1,45 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "hash",
"creation": "2013-02-22 01:27:39",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"allow_on_submit": 0,
"fieldname": "account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 1,
"in_list_view": 1,
"label": "Account",
"no_copy": 0,
"oldfieldname": "account",
"oldfieldtype": "Link",
"options": "Account",
"permlevel": 0,
"print_hide": 0,
"print_width": "250px",
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
"unique": 0,
"width": "250px"
},
{
"allow_on_submit": 0,
"fieldname": "balance",
"fieldtype": "Currency",
"in_list_view": 1,
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Account Balance",
"no_copy": 1,
"oldfieldname": "balance",
@@ -30,186 +47,336 @@
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 1,
"read_only": 1
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"default": ":Company",
"description": "If Income or Expense",
"fieldname": "cost_center",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 1,
"in_list_view": 1,
"in_list_view": 0,
"label": "Cost Center",
"no_copy": 0,
"oldfieldname": "cost_center",
"oldfieldtype": "Link",
"options": "Cost Center",
"permlevel": 0,
"print_hide": 1,
"print_width": "180px",
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "180px"
},
{
"allow_on_submit": 0,
"fieldname": "col_break1",
"fieldtype": "Column Break",
"permlevel": 0
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "party_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Party Type",
"no_copy": 0,
"options": "DocType",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "party",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Party",
"no_copy": 0,
"options": "party_type",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "party_balance",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Party Balance",
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"read_only": 1
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "sec_break1",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Amount",
"permlevel": 0
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "debit",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Debit",
"no_copy": 0,
"oldfieldname": "debit",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "col_break2",
"fieldtype": "Column Break",
"permlevel": 0
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "credit",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Credit",
"no_copy": 0,
"oldfieldname": "credit",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "reference",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Reference",
"permlevel": 0
},
{
"fieldname": "against_invoice",
"fieldtype": "Link",
"in_filter": 1,
"label": "Against Sales Invoice",
"no_copy": 1,
"oldfieldname": "against_invoice",
"oldfieldtype": "Link",
"options": "Sales Invoice",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"search_index": 1
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"fieldname": "against_voucher",
"fieldtype": "Link",
"in_filter": 1,
"allow_on_submit": 0,
"fieldname": "reference_type",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Reference Type",
"no_copy": 0,
"options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "reference_name",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Against Purchase Invoice",
"no_copy": 1,
"oldfieldname": "against_voucher",
"oldfieldtype": "Link",
"options": "Purchase Invoice",
"label": "Reference Name",
"no_copy": 0,
"options": "reference_type",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"search_index": 1
},
{
"fieldname": "against_jv",
"fieldtype": "Link",
"in_filter": 1,
"label": "Against Journal Entry",
"no_copy": 1,
"oldfieldname": "against_jv",
"oldfieldtype": "Link",
"options": "Journal Entry",
"permlevel": 0,
"print_hide": 0,
"search_index": 1
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "col_break3",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "against_sales_order",
"fieldtype": "Link",
"label": "Against Sales Order",
"options": "Sales Order",
"permlevel": 0
},
{
"fieldname": "against_purchase_order",
"fieldtype": "Link",
"label": "Against Purchase Order",
"options": "Purchase Order",
"permlevel": 0
},
{
"fieldname": "against_expense_claim",
"fieldtype": "Link",
"label": "Against Expense Claim",
"options": "Expense Claim",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"precision": ""
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "is_advance",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Is Advance",
"no_copy": 1,
"oldfieldname": "is_advance",
"oldfieldtype": "Select",
"options": "No\nYes",
"permlevel": 0,
"print_hide": 1
"print_hide": 1,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "against_account",
"fieldtype": "Text",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Against Account",
"no_copy": 1,
"oldfieldname": "against_account",
"oldfieldtype": "Text",
"permlevel": 0,
"print_hide": 1
"print_hide": 1,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"modified": "2015-02-19 01:07:00.388689",
"modified": "2015-08-17 02:11:33.991361",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry Account",
"owner": "Administrator",
"permissions": []
"permissions": [],
"read_only": 0,
"read_only_onload": 0
}

View File

@@ -34,8 +34,8 @@ class PaymentReconciliation(Document):
t1.name = t2.parent and t1.docstatus = 1 and t2.docstatus = 1
and t2.party_type = %(party_type)s and t2.party = %(party)s
and t2.account = %(account)s and {dr_or_cr} > 0
and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')=''
and ifnull(t2.against_jv, '')='' {cond}
and ifnull(t2.reference_type, '') in ('', 'Sales Order', 'Purchase Order')
{cond}
and (CASE
WHEN t1.voucher_type in ('Debit Note', 'Credit Note')
THEN 1=1
@@ -190,7 +190,7 @@ class PaymentReconciliation(Document):
if flt(p.allocated_amount) > flt(p.amount):
frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equals to JV amount {2}")
.format(p.idx, p.allocated_amount, p.amount))
invoice_outstanding = unreconciled_invoices.get(p.invoice_type, {}).get(p.invoice_number)
if flt(p.allocated_amount) - invoice_outstanding > 0.009:
frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equals to invoice outstanding amount {2}")

View File

@@ -12,13 +12,6 @@ class PaymentTool(Document):
def make_journal_entry(self):
from erpnext.accounts.utils import get_balance_on
total_payment_amount = 0.00
invoice_voucher_type = {
'Sales Invoice': 'against_invoice',
'Purchase Invoice': 'against_voucher',
'Journal Entry': 'against_jv',
'Sales Order': 'against_sales_order',
'Purchase Order': 'against_purchase_order',
}
jv = frappe.new_doc('Journal Entry')
jv.voucher_type = 'Journal Entry'
@@ -41,7 +34,8 @@ class PaymentTool(Document):
d1.party = self.party
d1.balance = get_balance_on(self.party_account)
d1.set("debit" if self.received_or_paid=="Paid" else "credit", flt(v.payment_amount))
d1.set(invoice_voucher_type.get(v.against_voucher_type), v.against_voucher_no)
d1.set("reference_type", v.against_voucher_type)
d1.set("reference_name", v.against_voucher_no)
d1.set('is_advance', 'Yes' if v.against_voucher_type in ['Sales Order', 'Purchase Order'] else 'No')
total_payment_amount = flt(total_payment_amount) + flt(d1.debit) - flt(d1.credit)

View File

@@ -23,10 +23,11 @@ class TestPaymentTool(unittest.TestCase):
# Create SO with partial outstanding
so1 = make_sales_order(customer="_Test Customer 3", qty=10, rate=100)
self.create_against_jv(jv_test_records[0], {
"party": "_Test Customer 3",
"against_sales_order": so1.name,
"reference_type": "Sales Order",
"reference_name": so1.name,
"is_advance": "Yes"
})
@@ -36,7 +37,8 @@ class TestPaymentTool(unittest.TestCase):
self.create_against_jv(jv_test_records[0], {
"party": "_Test Customer 3",
"against_sales_order": so2.name,
"reference_type": "Sales Order",
"reference_name": so2.name,
"credit": 1000,
"is_advance": "Yes"
})
@@ -52,7 +54,8 @@ class TestPaymentTool(unittest.TestCase):
self.create_against_jv(jv_test_records[0], {
"party": "_Test Customer 3",
"against_invoice": si1.name
"reference_type": si1.doctype,
"reference_name": si1.name
})
#Create SI with no outstanding
si2 = self.create_voucher(si_test_records[0], {
@@ -62,7 +65,8 @@ class TestPaymentTool(unittest.TestCase):
self.create_against_jv(jv_test_records[0], {
"party": "_Test Customer 3",
"against_invoice": si2.name,
"reference_type": si2.doctype,
"reference_name": si2.name,
"credit": 561.80
})
@@ -125,7 +129,7 @@ class TestPaymentTool(unittest.TestCase):
def make_voucher_for_party(self, args, expected_outstanding):
#Make Journal Entry for Party
payment_tool_doc = frappe.new_doc("Payment Tool")
for k, v in args.items():
payment_tool_doc.set(k, v)
@@ -153,29 +157,12 @@ class TestPaymentTool(unittest.TestCase):
new_jv = paytool.make_journal_entry()
#Create a list of expected values as [party account, payment against, against_jv, against_invoice,
#against_voucher, against_sales_order, against_purchase_order]
expected_values = [
[paytool.party_account, paytool.party, 100.00, expected_outstanding.get("Journal Entry")[0], None, None, None, None],
[paytool.party_account, paytool.party, 100.00, None, expected_outstanding.get("Sales Invoice")[0], None, None, None],
[paytool.party_account, paytool.party, 100.00, None, None, expected_outstanding.get("Purchase Invoice")[0], None, None],
[paytool.party_account, paytool.party, 100.00, None, None, None, expected_outstanding.get("Sales Order")[0], None],
[paytool.party_account, paytool.party, 100.00, None, None, None, None, expected_outstanding.get("Purchase Order")[0]]
]
for jv_entry in new_jv.get("accounts"):
if paytool.party_account == jv_entry.get("account") and paytool.party == jv_entry.get("party"):
row = [
jv_entry.get("account"),
jv_entry.get("party"),
jv_entry.get("debit" if paytool.party_type=="Supplier" else "credit"),
jv_entry.get("against_jv"),
jv_entry.get("against_invoice"),
jv_entry.get("against_voucher"),
jv_entry.get("against_sales_order"),
jv_entry.get("against_purchase_order"),
]
self.assertTrue(row in expected_values)
self.assertEquals(100.00,
jv_entry.get("debit" if paytool.party_type=="Supplier" else "credit"))
self.assertEquals(jv_entry.reference_name,
expected_outstanding[jv_entry.reference_type][0])
self.assertEquals(new_jv.get("cheque_no"), paytool.reference_no)
self.assertEquals(new_jv.get("cheque_date"), paytool.reference_date)

View File

@@ -11,7 +11,6 @@ from frappe.model.document import Document
class POSProfile(Document):
def validate(self):
self.check_for_duplicate()
self.validate_expense_account()
self.validate_all_link_fields()
def check_for_duplicate(self):
@@ -26,11 +25,6 @@ class POSProfile(Document):
msgprint(_("Global POS Profile {0} already created for company {1}").format(res[0][0],
self.company), raise_exception=1)
def validate_expense_account(self):
if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) \
and not self.expense_account:
msgprint(_("Expense Account is mandatory"), raise_exception=1)
def validate_all_link_fields(self):
accounts = {"Account": [self.cash_bank_account, self.income_account,
self.expense_account], "Cost Center": [self.cost_center],

File diff suppressed because it is too large Load Diff

View File

@@ -147,6 +147,7 @@ def get_pricing_rule_for_item(args):
if pricing_rule:
item_details.pricing_rule = pricing_rule.name
item_details.pricing_rule_for = pricing_rule.price_or_discount
if pricing_rule.price_or_discount == "Price":
item_details.update({
"price_list_rate": pricing_rule.price/flt(args.conversion_rate) \

View File

@@ -21,16 +21,15 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
// Show / Hide button
this.show_general_ledger();
if(!doc.is_return) {
if(doc.docstatus==1) {
if(doc.outstanding_amount > 0) {
this.frm.add_custom_button(__('Make Payment Entry'), this.make_bank_entry);
this.frm.add_custom_button(__('Payment'), this.make_bank_entry).addClass("btn-primary");
}
cur_frm.add_custom_button(__('Make Debit Note'), this.make_debit_note);
cur_frm.add_custom_button(__('Debit Note'), this.make_debit_note);
}
if(doc.docstatus===0) {
cur_frm.add_custom_button(__('From Purchase Order'), function() {
frappe.model.map_current_doc({
@@ -102,7 +101,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
if(row.purchase_receipt) frappe.model.clear_doc("Purchase Receipt", row.purchase_receipt)
})
},
make_debit_note: function() {
frappe.model.open_mapped_doc({
method: "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_debit_note",

View File

@@ -41,8 +41,8 @@ class PurchaseInvoice(BuyingController):
self.po_required()
self.pr_required()
self.validate_supplier_invoice()
self.validate_advance_jv("advances", "purchase_order")
self.validate_advance_jv("Purchase Order")
self.check_active_purchase_items()
self.check_conversion_rate()
self.validate_credit_to_acc()
@@ -233,7 +233,7 @@ class PurchaseInvoice(BuyingController):
self.update_against_document_in_jv()
self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
self.update_project()
def make_gl_entries(self):
@@ -365,7 +365,7 @@ class PurchaseInvoice(BuyingController):
def on_cancel(self):
if not self.is_return:
from erpnext.accounts.utils import remove_against_link_from_jv
remove_against_link_from_jv(self.doctype, self.name, "against_voucher")
remove_against_link_from_jv(self.doctype, self.name)
self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
@@ -413,4 +413,4 @@ def get_expense_account(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
def make_debit_note(source_name, target_doc=None):
from erpnext.controllers.sales_and_purchase_return import make_return_doc
return make_return_doc("Purchase Invoice", source_name, target_doc)
return make_return_doc("Purchase Invoice", source_name, target_doc)

View File

@@ -218,23 +218,20 @@ class TestPurchaseInvoice(unittest.TestCase):
pi.load_from_db()
self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
where against_voucher=%s""", pi.name))
self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
where against_voucher=%s and debit=300""", pi.name))
where reference_type='Purchase Invoice' and reference_name=%s and debit=300""", pi.name))
self.assertEqual(pi.outstanding_amount, 1212.30)
pi.cancel()
self.assertTrue(not frappe.db.sql("""select name from `tabJournal Entry Account`
where against_voucher=%s""", pi.name))
self.assertFalse(frappe.db.sql("""select name from `tabJournal Entry Account`
where reference_type='Purchase Invoice' and reference_name=%s""", pi.name))
def test_recurring_invoice(self):
from erpnext.controllers.tests.test_recurring_document import test_recurring_document
test_recurring_document(self, test_records)
def test_total_purchase_cost_for_project(self):
def test_total_purchase_cost_for_project(self):
purchase_invoice = frappe.new_doc('Purchase Invoice')
purchase_invoice.update({
"credit_to": "_Test Payable - _TC",
@@ -260,29 +257,29 @@ class TestPurchaseInvoice(unittest.TestCase):
]
})
purchase_invoice.save()
purchase_invoice.submit()
purchase_invoice.submit()
self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), 2000)
purchase_invoice1 = frappe.copy_doc(purchase_invoice)
purchase_invoice1.save()
purchase_invoice1.submit()
self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), 4000)
purchase_invoice1.cancel()
purchase_invoice1.cancel()
self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), 2000)
purchase_invoice.cancel()
purchase_invoice.cancel()
self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), 0)
def test_return_purchase_invoice(self):
set_perpetual_inventory()
pi = make_purchase_invoice()
return_pi = make_purchase_invoice(is_return=1, return_against=pi.name, qty=-2)
# check gl entries for return
gl_entries = frappe.db.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type=%s and voucher_no=%s
@@ -298,9 +295,9 @@ class TestPurchaseInvoice(unittest.TestCase):
for gle in gl_entries:
self.assertEquals(expected_values[gle.account][0], gle.debit)
self.assertEquals(expected_values[gle.account][1], gle.credit)
set_perpetual_inventory(0)
def make_purchase_invoice(**args):
pi = frappe.new_doc("Purchase Invoice")
args = frappe._dict(args)
@@ -313,7 +310,7 @@ def make_purchase_invoice(**args):
pi.currency = args.currency or "INR"
pi.is_return = args.is_return
pi.return_against = args.return_against
pi.append("items", {
"item_code": args.item or args.item_code or "_Test Item",
"warehouse": args.warehouse or "_Test Warehouse - _TC",

View File

@@ -40,14 +40,17 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
this._super();
cur_frm.dashboard.reset();
this.frm.toggle_reqd("due_date", !this.frm.doc.is_return);
this.show_general_ledger();
if(doc.update_stock) this.show_stock_ledger();
if(doc.docstatus==1 && !doc.is_return) {
cur_frm.add_custom_button(doc.update_stock ? __('Sales Return') : __('Credit Note'),
this.make_sales_return);
if(cint(doc.update_stock)!=1) {
// show Make Delivery Note button only if Sales Invoice is not created from Delivery Note
var from_delivery_note = false;
@@ -57,16 +60,13 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
});
if(!from_delivery_note) {
cur_frm.add_custom_button(__('Make Delivery'), cur_frm.cscript['Make Delivery Note'])
cur_frm.add_custom_button(__('Delivery'), cur_frm.cscript['Make Delivery Note']).addClass("btn-primary");
}
}
if(doc.outstanding_amount!=0 && !cint(doc.is_return)) {
cur_frm.add_custom_button(__('Make Payment Entry'), cur_frm.cscript.make_bank_entry);
cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry).addClass("btn-primary");
}
cur_frm.add_custom_button(doc.update_stock ? __('Make Sales Return') : __('Make Credit Note'),
this.make_sales_return);
}
// Show buttons only when pos view is active
@@ -201,7 +201,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
items_on_form_rendered: function() {
erpnext.setup_serial_no();
},
make_sales_return: function() {
frappe.model.open_mapped_doc({
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.make_sales_return",
@@ -390,4 +390,4 @@ cur_frm.set_query("debit_to", function(doc) {
['Account', 'account_type', '=', 'Receivable']
]
}
});
});

View File

@@ -46,7 +46,7 @@ class SalesInvoice(SellingController):
self.validate_debit_to_acc()
self.validate_fixed_asset_account()
self.clear_unallocated_advances("Sales Invoice Advance", "advances")
self.validate_advance_jv("advances", "sales_order")
self.validate_advance_jv("Sales Order")
self.add_remarks()
self.validate_write_off_account()
@@ -105,7 +105,7 @@ class SalesInvoice(SellingController):
self.check_stop_sales_order("sales_order")
from erpnext.accounts.utils import remove_against_link_from_jv
remove_against_link_from_jv(self.doctype, self.name, "against_invoice")
remove_against_link_from_jv(self.doctype, self.name)
if not self.is_return:
self.update_status_updater_args()
@@ -420,7 +420,7 @@ class SalesInvoice(SellingController):
for d in self.get_item_list():
if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1 and d.warehouse and flt(d['qty']):
self.update_reserved_qty(d)
incoming_rate = 0
if cint(self.is_return) and self.return_against and self.docstatus==1:
incoming_rate = self.get_incoming_rate_for_sales_return(d.item_code,
@@ -447,7 +447,7 @@ class SalesInvoice(SellingController):
if update_outstanding == "No":
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
update_outstanding_amt(self.debit_to, "Customer", self.customer,
update_outstanding_amt(self.debit_to, "Customer", self.customer,
self.doctype, self.return_against if cint(self.is_return) else self.name)
if repost_future_gle and cint(self.update_stock) \

View File

@@ -391,7 +391,8 @@ class TestSalesInvoice(unittest.TestCase):
import test_records as jv_test_records
jv = frappe.get_doc(frappe.copy_doc(jv_test_records[0]))
jv.get("accounts")[0].against_invoice = w.name
jv.get("accounts")[0].reference_type = w.doctype
jv.get("accounts")[0].reference_name = w.name
jv.insert()
jv.submit()
@@ -656,17 +657,17 @@ class TestSalesInvoice(unittest.TestCase):
si.load_from_db()
self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
where against_invoice=%s""", si.name))
where reference_name=%s""", si.name))
self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
where against_invoice=%s and credit=300""", si.name))
where reference_name=%s and credit=300""", si.name))
self.assertEqual(si.outstanding_amount, 261.8)
si.cancel()
self.assertTrue(not frappe.db.sql("""select name from `tabJournal Entry Account`
where against_invoice=%s""", si.name))
where reference_name=%s""", si.name))
def test_recurring_invoice(self):
from erpnext.controllers.tests.test_recurring_document import test_recurring_document
@@ -728,68 +729,67 @@ class TestSalesInvoice(unittest.TestCase):
# hack! because stock ledger entires are already inserted and are not rolled back!
self.assertRaises(SerialNoDuplicateError, si.cancel)
def test_invoice_due_date_against_customers_credit_days(self):
# set customer's credit days
frappe.db.set_value("Customer", "_Test Customer", "credit_days_based_on", "Fixed Days")
frappe.db.set_value("Customer", "_Test Customer", "credit_days", 10)
si = create_sales_invoice()
self.assertEqual(si.due_date, add_days(nowdate(), 10))
# set customer's credit days is last day of the next month
frappe.db.set_value("Customer", "_Test Customer", "credit_days_based_on", "Last Day of the Next Month")
si1 = create_sales_invoice(posting_date="2015-07-05")
si1 = create_sales_invoice(posting_date="2015-07-05")
self.assertEqual(si1.due_date, "2015-08-31")
def test_return_sales_invoice(self):
set_perpetual_inventory()
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, incoming_rate=100)
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100)
actual_qty_0 = get_qty_after_transaction()
si = create_sales_invoice(qty=5, rate=500, update_stock=1)
actual_qty_1 = get_qty_after_transaction()
self.assertEquals(actual_qty_0 - 5, actual_qty_1)
# outgoing_rate
outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Sales Invoice",
outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Sales Invoice",
"voucher_no": si.name}, "stock_value_difference") / 5
# return entry
si1 = create_sales_invoice(is_return=1, return_against=si.name, qty=-2, rate=500, update_stock=1)
actual_qty_2 = get_qty_after_transaction()
self.assertEquals(actual_qty_1 + 2, actual_qty_2)
incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
{"voucher_type": "Sales Invoice", "voucher_no": si1.name},
incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
{"voucher_type": "Sales Invoice", "voucher_no": si1.name},
["incoming_rate", "stock_value_difference"])
self.assertEquals(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3)))
# Check gl entry
gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
"voucher_no": si1.name, "account": "_Test Warehouse - _TC"}, "debit")
self.assertEquals(gle_warehouse_amount, stock_value_difference)
party_credited = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
party_credited = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
"voucher_no": si1.name, "account": "Debtors - _TC", "party": "_Test Customer"}, "credit")
self.assertEqual(party_credited, 1000)
# Check outstanding amount
self.assertFalse(si1.outstanding_amount)
self.assertEqual(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"), 1500)
set_perpetual_inventory(0)
def test_discount_on_net_total(self):
si = frappe.copy_doc(test_records[2])
si.apply_discount_on = "Net Total"
@@ -798,7 +798,7 @@ class TestSalesInvoice(unittest.TestCase):
expected_values = {
"keys": ["price_list_rate", "discount_percentage", "rate", "amount",
"base_price_list_rate", "base_rate", "base_amount",
"base_price_list_rate", "base_rate", "base_amount",
"net_rate", "base_net_rate", "net_amount", "base_net_amount"],
"_Test Item Home Desktop 100": [50, 0, 50, 500, 50, 50, 500, 25, 25, 250, 250],
"_Test Item Home Desktop 200": [150, 0, 150, 750, 150, 150, 750, 75, 75, 375, 375],
@@ -821,7 +821,7 @@ class TestSalesInvoice(unittest.TestCase):
# check tax calculation
expected_values = {
"keys": ["tax_amount", "tax_amount_after_discount_amount",
"keys": ["tax_amount", "tax_amount_after_discount_amount",
"base_tax_amount_after_discount_amount"],
"_Test Account Shipping Charges - _TC": [100, 100, 100],
"_Test Account Customs Duty - _TC": [62.5, 62.5, 62.5],
@@ -836,12 +836,12 @@ class TestSalesInvoice(unittest.TestCase):
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.total_taxes_and_charges, 234.44)
self.assertEquals(si.base_grand_total, 859.44)
self.assertEquals(si.grand_total, 859.44)
def create_sales_invoice(**args):
si = frappe.new_doc("Sales Invoice")

View File

@@ -11,8 +11,7 @@ from erpnext.accounts.utils import validate_expense_against_budget
class StockAccountInvalidTransaction(frappe.ValidationError): pass
def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True,
update_outstanding='Yes'):
def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, update_outstanding='Yes'):
if gl_map:
if not cancel:
gl_map = process_gl_map(gl_map, merge_entries)
@@ -51,7 +50,7 @@ def merge_similar_entries(gl_map):
merged_gl_map.append(entry)
# filter zero debit and credit entries
merged_gl_map = filter(lambda x: flt(x.debit)!=0 or flt(x.credit)!=0, merged_gl_map)
merged_gl_map = filter(lambda x: flt(x.debit, 9)!=0 or flt(x.credit, 9)!=0, merged_gl_map)
return merged_gl_map
def check_if_in_list(gle, gl_map):

View File

@@ -202,7 +202,7 @@ erpnext.AccountsChart = Class.extend({
title:__('New Account'),
fields: [
{fieldtype:'Data', fieldname:'account_name', label:__('New Account Name'), reqd:true,
description: __("Name of new Account. Note: Please don't create accounts for Customers and Suppliers, they are created automatically from the Customer and Supplier master")},
description: __("Name of new Account. Note: Please don't create accounts for Customers and Suppliers")},
{fieldtype:'Check', fieldname:'is_group', label:__('Is Group'),
description: __('Further accounts can be made under Groups, but entries can be made against non-Groups')},
{fieldtype:'Select', fieldname:'account_type', label:__('Account Type'),

View File

@@ -26,9 +26,9 @@ def get_children():
acc = frappe.db.sql(""" select
name as value, is_group as expandable %s
from `tab%s`
where ifnull(parent_%s,'') = ''
where ifnull(`parent_%s`,'') = ''
and `company` = %s and docstatus<2
order by name""" % (select_cond, ctype, ctype.lower().replace(' ','_'), '%s'),
order by name""" % (select_cond, frappe.db.escape(ctype), frappe.db.escape(ctype.lower().replace(' ','_')), '%s'),
company, as_dict=1)
if args["parent"]=="Accounts":
@@ -38,9 +38,9 @@ def get_children():
acc = frappe.db.sql("""select
name as value, is_group as expandable
from `tab%s`
where ifnull(parent_%s,'') = %s
where ifnull(`parent_%s`,'') = %s
and docstatus<2
order by name""" % (ctype, ctype.lower().replace(' ','_'), '%s'),
order by name""" % (frappe.db.escape(ctype), frappe.db.escape(ctype.lower().replace(' ','_')), '%s'),
args['parent'], as_dict=1)
if ctype == 'Account':

View File

@@ -15,21 +15,19 @@ def execute(filters=None):
entries = get_entries(filters)
invoice_posting_date_map = get_invoice_posting_date_map(filters)
against_date = ""
outstanding_amount = 0.0
data = []
for d in entries:
if d.against_voucher:
against_date = d.against_voucher and invoice_posting_date_map[d.against_voucher] or ""
against_date = invoice_posting_date_map.get(d.reference_name) or ""
if d.reference_type=="Purchase Invoice":
payment_amount = flt(d.debit) or -1 * flt(d.credit)
else:
against_date = d.against_invoice and invoice_posting_date_map[d.against_invoice] or ""
payment_amount = flt(d.credit) or -1 * flt(d.debit)
row = [d.name, d.party_type, d.party, d.posting_date, d.against_voucher or d.against_invoice,
row = [d.name, d.party_type, d.party, d.posting_date, d.reference_name,
against_date, d.debit, d.credit, d.cheque_no, d.cheque_date, d.remark]
if d.against_voucher or d.against_invoice:
if d.reference_name:
row += get_ageing_data(30, 60, 90, d.posting_date, against_date, payment_amount)
else:
row += ["", "", "", "", ""]
@@ -82,7 +80,7 @@ def get_conditions(filters):
def get_entries(filters):
conditions = get_conditions(filters)
entries = frappe.db.sql("""select jv.name, jvd.party_type, jvd.party, jv.posting_date,
jvd.against_voucher, jvd.against_invoice, jvd.debit, jvd.credit,
jvd.reference_type, jvd.reference_name, jvd.debit, jvd.credit,
jv.cheque_no, jv.cheque_date, jv.remark
from `tabJournal Entry Account` jvd, `tabJournal Entry` jv
where jvd.parent = jv.name and jv.docstatus=1 %s order by jv.name DESC""" %

View File

@@ -62,7 +62,7 @@ def get_balance_on(account=None, date=None, party_type=None, party=None):
cond = []
if date:
cond.append("posting_date <= '%s'" % date)
cond.append("posting_date <= '%s'" % frappe.db.escape(date))
else:
# get balance of all entries that exist
date = nowdate()
@@ -95,19 +95,20 @@ def get_balance_on(account=None, date=None, party_type=None, party=None):
and ac.lft >= %s and ac.rgt <= %s
)""" % (acc.lft, acc.rgt))
else:
cond.append("""gle.account = "%s" """ % (account.replace('"', '\\"'), ))
cond.append("""gle.account = "%s" """ % (frappe.db.escape(account),))
if party_type and party:
cond.append("""gle.party_type = "%s" and gle.party = "%s" """ %
(party_type.replace('"', '\\"'), party.replace('"', '\\"')))
(frappe.db.escape(party_type), frappe.db.escape(party)))
bal = frappe.db.sql("""
SELECT sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
FROM `tabGL Entry` gle
WHERE %s""" % " and ".join(cond))[0][0]
if account or (party_type and party):
bal = frappe.db.sql("""
SELECT sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
FROM `tabGL Entry` gle
WHERE %s""" % " and ".join(cond))[0][0]
# if bal is None, return 0
return flt(bal)
# if bal is None, return 0
return flt(bal)
@frappe.whitelist()
def add_ac(args=None):
@@ -142,13 +143,6 @@ def reconcile_against_document(args):
for d in args:
check_if_jv_modified(d)
validate_allocated_amount(d)
against_fld = {
'Journal Entry' : 'against_jv',
'Sales Invoice' : 'against_invoice',
'Purchase Invoice' : 'against_voucher'
}
d['against_fld'] = against_fld[d['against_voucher_type']]
# cancel JV
jv_obj = frappe.get_doc('Journal Entry', d['voucher_no'])
@@ -173,8 +167,7 @@ def check_if_jv_modified(args):
select t2.{dr_or_cr} from `tabJournal Entry` t1, `tabJournal Entry Account` t2
where t1.name = t2.parent and t2.account = %(account)s
and t2.party_type = %(party_type)s and t2.party = %(party)s
and ifnull(t2.against_voucher, '')=''
and ifnull(t2.against_invoice, '')='' and ifnull(t2.against_jv, '')=''
and ifnull(t2.reference_type, '') in ("", "Sales Order", "Purchase Order")
and t1.name = %(voucher_no)s and t2.name = %(voucher_detail_no)s
and t1.docstatus=1 """.format(dr_or_cr = args.get("dr_or_cr")), args)
@@ -193,7 +186,12 @@ def update_against_doc(d, jv_obj):
"""
jv_detail = jv_obj.get("accounts", {"name": d["voucher_detail_no"]})[0]
jv_detail.set(d["dr_or_cr"], d["allocated_amt"])
jv_detail.set(d["against_fld"], d["against_voucher"])
original_reference_type = jv_detail.reference_type
original_reference_name = jv_detail.reference_name
jv_detail.set("reference_type", d["against_voucher_type"])
jv_detail.set("reference_name", d["against_voucher"])
if d['allocated_amt'] < d['unadjusted_amt']:
jvd = frappe.db.sql("""select cost_center, balance, against_account, is_advance
@@ -208,6 +206,8 @@ def update_against_doc(d, jv_obj):
ch.set(d['dr_or_cr'], flt(d['unadjusted_amt']) - flt(d['allocated_amt']))
ch.set(d['dr_or_cr']== 'debit' and 'credit' or 'debit', 0)
ch.against_account = cstr(jvd[0][2])
ch.reference_type = original_reference_type
ch.reference_name = original_reference_name
ch.is_advance = cstr(jvd[0][3])
ch.docstatus = 1
@@ -215,15 +215,16 @@ def update_against_doc(d, jv_obj):
jv_obj.flags.ignore_validate_update_after_submit = True
jv_obj.save()
def remove_against_link_from_jv(ref_type, ref_no, against_field):
def remove_against_link_from_jv(ref_type, ref_no):
linked_jv = frappe.db.sql_list("""select parent from `tabJournal Entry Account`
where `%s`=%s and docstatus < 2""" % (against_field, "%s"), (ref_no))
where reference_type=%s and reference_name=%s and docstatus < 2""", (ref_type, ref_no))
if linked_jv:
frappe.db.sql("""update `tabJournal Entry Account` set `%s`=null,
frappe.db.sql("""update `tabJournal Entry Account`
set reference_type=null, reference_name = null,
modified=%s, modified_by=%s
where `%s`=%s and docstatus < 2""" % (against_field, "%s", "%s", against_field, "%s"),
(now(), frappe.session.user, ref_no))
where reference_type=%s and reference_name=%s
and docstatus < 2""", (now(), frappe.session.user, ref_type, ref_no))
frappe.db.sql("""update `tabGL Entry`
set against_voucher_type=null, against_voucher=null,

View File

@@ -5,6 +5,14 @@ frappe.provide("erpnext.buying");
{% include 'buying/doctype/purchase_common/purchase_common.js' %};
frappe.ui.form.on("Purchase Order", {
onload: function(frm) {
erpnext.queries.setup_queries(frm, "Warehouse", function() {
return erpnext.queries.warehouse(frm.doc);
});
}
});
erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend({
refresh: function(doc, cdt, cdn) {
var me = this;
@@ -12,31 +20,38 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
// this.frm.dashboard.reset();
if(doc.docstatus == 1 && doc.status != 'Stopped') {
if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100)
cur_frm.add_custom_button(__('Stop'), cur_frm.cscript['Stop Purchase Order']);
if(flt(doc.per_billed)==0) {
cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry);
}
if(flt(doc.per_received, 2) < 100) {
cur_frm.add_custom_button(__('Make Purchase Receipt'), this.make_purchase_receipt);
cur_frm.add_custom_button(__('Receive'), this.make_purchase_receipt).addClass("btn-primary");
if(doc.is_subcontracted==="Yes") {
cur_frm.add_custom_button(__('Transfer Material to Supplier'), this.make_stock_entry);
}
}
if(flt(doc.per_billed, 2) < 100)
cur_frm.add_custom_button(__('Make Invoice'), this.make_purchase_invoice);
if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100)
cur_frm.add_custom_button(__('Stop'), cur_frm.cscript['Stop Purchase Order']);
cur_frm.add_custom_button(__('Invoice'), this.make_purchase_invoice);
} else if(doc.docstatus===0) {
cur_frm.cscript.add_from_mappers();
}
if(doc.docstatus == 1 && doc.status == 'Stopped')
cur_frm.add_custom_button(__('Unstop Purchase Order'), cur_frm.cscript['Unstop Purchase Order']);
cur_frm.add_custom_button(__('Unstop'), cur_frm.cscript['Unstop Purchase Order']);
},
make_stock_entry: function() {
var items = $.map(cur_frm.doc.items, function(d) { return d.bom ? d.item_code : false; });
var me = this;
if(items.length===1) {
me._make_stock_entry(items[0]);
return;
@@ -126,7 +141,21 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
items_add: function(doc, cdt, cdn) {
var row = frappe.get_doc(cdt, cdn);
this.frm.script_manager.copy_from_first_row("items", row, ["schedule_date"]);
},
make_bank_entry: function() {
return frappe.call({
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_from_purchase_order",
args: {
"purchase_order": cur_frm.doc.name
},
callback: function(r) {
var doclist = frappe.model.sync(r.message);
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
}
});
}
});
// for backward compatibility: combine new and previous states

View File

@@ -46,6 +46,8 @@ cur_frm.cscript.make_dashboard = function(doc) {
+ '</b> / <span class="text-muted">' + __("Total Unpaid") + ": <b>"
+ format_currency(r.message.total_unpaid, r.message.company_currency[0])
+ '</b></span>');
} else {
cur_frm.dashboard.set_headline("");
}
}
cur_frm.dashboard.set_badge_count(r.message);

View File

@@ -0,0 +1,6 @@
- For referencing a line in **Journal Entry**, now you can reference by the **Reference Type** and **Reference Name** columns, instead of "Against Sales Invoice", "Against Purchase Invoice", etc.
- Additional Costs in Stock Entry **[Sponsored by PT. Ridho Sribumi Sejahtera]**
Now additional costs like shipping charges, operating costs etc can be added in Stock Entry in item valuation
- **Update Finished Goods** in Production Order can now use the items from **Transfer Materials for Manufacture** step instead of items from the Bill of Materials. This can be configured in Manufacturing Settings
- Added field **Tax ID** in Customer
- Bug fixes in Item, Time Log Batch, Pricing Rule, Salary Slip, Address and Stock Entry

View File

@@ -11,7 +11,7 @@ from erpnext.utilities.transaction_base import TransactionBase
from erpnext.controllers.recurring_document import convert_to_recurring, validate_recurring_document
from erpnext.controllers.sales_and_purchase_return import validate_return
force_item_fields = ("item_name", "item_group", "barcode", "brand", "stock_uom")
force_item_fields = ("item_group", "barcode", "brand", "stock_uom")
class CustomerFrozen(frappe.ValidationError): pass
@@ -153,9 +153,10 @@ class AccountsController(TransactionBase):
item.set(fieldname, value)
if ret.get("pricing_rule"):
for field in ["base_price_list_rate", "price_list_rate",
"discount_percentage", "base_rate", "rate"]:
item.set(field, ret.get(field))
item.set("discount_percentage", ret.get("discount_percentage"))
if ret.get("pricing_rule_for") == "Price":
item.set("pricing_list_rate", ret.get("pricing_list_rate"))
def set_taxes(self):
if not self.meta.get_field("taxes"):
@@ -211,29 +212,32 @@ class AccountsController(TransactionBase):
and ifnull(allocated_amount, 0) = 0""" % (childtype, '%s', '%s'), (parentfield, self.name))
def get_advances(self, account_head, party_type, party, child_doctype, parentfield, dr_or_cr, against_order_field):
so_list = list(set([d.get(against_order_field) for d in self.get("items") if d.get(against_order_field)]))
cond = ""
if so_list:
cond = "or (ifnull(t2.%s, '') in (%s))" % ("against_" + against_order_field, ', '.join(['%s']*len(so_list)))
"""Returns list of advances against Account, Party, Reference"""
order_list = list(set([d.get(against_order_field) for d in self.get("items") if d.get(against_order_field)]))
if not order_list:
return
in_placeholder = ', '.join(['%s'] * len(order_list))
# conver sales_order to "Sales Order"
reference_type = against_order_field.replace("_", " ").title()
res = frappe.db.sql("""
select
t1.name as jv_no, t1.remark, t2.{0} as amount, t2.name as jv_detail_no, `against_{1}` as against_order
t1.name as jv_no, t1.remark, t2.{0} as amount, t2.name as jv_detail_no,
reference_name as against_order
from
`tabJournal Entry` t1, `tabJournal Entry Account` t2
where
t1.name = t2.parent and t2.account = %s
and t2.party_type=%s and t2.party=%s
and t2.party_type = %s and t2.party = %s
and t2.is_advance = 'Yes' and t1.docstatus = 1
and ((
ifnull(t2.against_voucher, '') = ''
and ifnull(t2.against_invoice, '') = ''
and ifnull(t2.against_jv, '') = ''
and ifnull(t2.against_sales_order, '') = ''
and ifnull(t2.against_purchase_order, '') = ''
) {2})
order by t1.posting_date""".format(dr_or_cr, against_order_field, cond),
[account_head, party_type, party] + so_list, as_dict=1)
and (
ifnull(t2.reference_type, '')=''
or (t2.reference_type = %s and ifnull(t2.reference_name, '') in ({1})))
order by t1.posting_date""".format(dr_or_cr, in_placeholder),
[account_head, party_type, party, reference_type] + order_list, as_dict=1)
self.set(parentfield, [])
for d in res:
@@ -246,25 +250,26 @@ class AccountsController(TransactionBase):
"allocated_amount": flt(d.amount) if d.against_order else 0
})
def validate_advance_jv(self, advance_table_fieldname, against_order_field):
def validate_advance_jv(self, reference_type):
against_order_field = frappe.scrub(reference_type)
order_list = list(set([d.get(against_order_field) for d in self.get("items") if d.get(against_order_field)]))
if order_list:
account = self.get("debit_to" if self.doctype=="Sales Invoice" else "credit_to")
jv_against_order = frappe.db.sql("""select parent, %s as against_order
jv_against_order = frappe.db.sql("""select parent, reference_name as against_order
from `tabJournal Entry Account`
where docstatus=1 and account=%s and ifnull(is_advance, 'No') = 'Yes'
and ifnull(against_sales_order, '') in (%s)
group by parent, against_sales_order""" %
("against_" + against_order_field, '%s', ', '.join(['%s']*len(order_list))),
tuple([account] + order_list), as_dict=1)
and reference_type=%s
and ifnull(reference_name, '') in ({0})
group by parent, reference_name""".format(', '.join(['%s']*len(order_list))),
tuple([account, reference_type] + order_list), as_dict=1)
if jv_against_order:
order_jv_map = {}
for d in jv_against_order:
order_jv_map.setdefault(d.against_order, []).append(d.parent)
advance_jv_against_si = [d.journal_entry for d in self.get(advance_table_fieldname)]
advance_jv_against_si = [d.journal_entry for d in self.get("advances")]
for order, jv_list in order_jv_map.items():
for jv in jv_list:
@@ -318,10 +323,8 @@ class AccountsController(TransactionBase):
def set_total_advance_paid(self):
if self.doctype == "Sales Order":
dr_or_cr = "credit"
against_field = "against_sales_order"
else:
dr_or_cr = "debit"
against_field = "against_purchase_order"
advance_paid = frappe.db.sql("""
select
@@ -329,8 +332,10 @@ class AccountsController(TransactionBase):
from
`tabJournal Entry Account`
where
{against_field} = %s and docstatus = 1 and is_advance = "Yes" """.format(dr_or_cr=dr_or_cr, \
against_field=against_field), self.name)
reference_type = %s and
reference_name = %s and
docstatus = 1 and is_advance = "Yes" """.format(dr_or_cr=dr_or_cr),
(self.doctype, self.name))
if advance_paid:
advance_paid = flt(advance_paid[0][0], self.precision("advance_paid"))

View File

@@ -112,8 +112,8 @@ class BuyingController(StockController):
valuation_amount_adjustment -= item.item_tax_amount
self.round_floats_in(item)
item.conversion_factor = get_conversion_factor(item.item_code, item.uom).get("conversion_factor") or 1.0
if flt(item.conversion_factor)==0:
item.conversion_factor = get_conversion_factor(item.item_code, item.uom).get("conversion_factor") or 1.0
qty_in_stock_uom = flt(item.qty * item.conversion_factor)
rm_supp_cost = flt(item.rm_supp_cost) if self.doctype=="Purchase Receipt" else 0.0

View File

@@ -138,8 +138,6 @@ def subscribe(email):
_("Click here to verify")
)
print url
content = """
<p>{0}. {1}.</p>
<p><a href="{2}">{3}</a></p>

View File

@@ -80,9 +80,23 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) {
if(doc.status!=="Quotation")
cur_frm.add_custom_button(__('Opportunity Lost'),
cur_frm.cscript['Declare Opportunity Lost'], "icon-remove", "btn-default");
}
var frm = cur_frm;
if(frm.perm[0].write && doc.docstatus==0) {
if(frm.doc.status==="Open") {
frm.add_custom_button("Close", function() {
frm.set_value("status", "Closed");
frm.save();
});
} else {
frm.add_custom_button("Reopen", function() {
frm.set_value("status", "Open");
frm.save();
});
}
}
}
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {

View File

@@ -27,7 +27,7 @@ blogs.
"""
app_icon = "icon-th"
app_color = "#e74c3c"
app_version = "5.5.0"
app_version = "5.6.4"
github_link = "https://github.com/frappe/erpnext"
error_report_email = "support@erpnext.com"

View File

@@ -24,13 +24,15 @@ erpnext.hr.ExpenseClaimController = frappe.ui.form.Controller.extend({
var d1 = frappe.model.add_child(jv, 'Journal Entry Account', 'accounts');
d1.debit = expense[i].sanctioned_amount;
d1.account = expense[i].default_account;
d1.against_expense_claim = cur_frm.doc.name;
d1.reference_type = cur_frm.doc.doctype;
d1.reference_name = cur_frm.doc.name;
}
// credit to bank
var d1 = frappe.model.add_child(jv, 'Journal Entry Account', 'accounts');
d1.credit = cur_frm.doc.total_sanctioned_amount;
d1.against_expense_claim = cur_frm.doc.name;
d1.reference_type = cur_frm.doc.doctype;
d1.reference_name = cur_frm.doc.name;
if(r.message) {
d1.account = r.message.account;
d1.balance = r.message.balance;
@@ -179,5 +181,5 @@ cur_frm.fields_dict['task'].get_query = function(doc) {
filters:{
'project': doc.project
}
}
}
}
}

View File

@@ -152,8 +152,8 @@ class SalarySlip(TransactionBase):
self.gross_pay = flt(self.arrear_amount) + flt(self.leave_encashment_amount)
for d in self.get("earnings"):
if cint(d.e_depends_on_lwp) == 1:
d.e_modified_amount = rounded(flt(d.e_amount) * flt(self.payment_days)
/ cint(self.total_days_in_month), 2)
d.e_modified_amount = rounded((flt(d.e_amount) * flt(self.payment_days)
/ cint(self.total_days_in_month)), self.precision("e_modified_amount", "earnings"))
elif not self.payment_days:
d.e_modified_amount = 0
elif not d.e_modified_amount:
@@ -164,8 +164,8 @@ class SalarySlip(TransactionBase):
self.total_deduction = 0
for d in self.get('deductions'):
if cint(d.d_depends_on_lwp) == 1:
d.d_modified_amount = rounded(flt(d.d_amount) * flt(self.payment_days)
/ cint(self.total_days_in_month), 2)
d.d_modified_amount = rounded((flt(d.d_amount) * flt(self.payment_days)
/ cint(self.total_days_in_month)), self.precision("d_modified_amount", "deductions"))
elif not self.payment_days:
d.d_modified_amount = 0
elif not d.d_modified_amount:
@@ -174,10 +174,13 @@ class SalarySlip(TransactionBase):
self.total_deduction += flt(d.d_modified_amount)
def calculate_net_pay(self):
disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
self.calculate_earning_total()
self.calculate_ded_total()
self.net_pay = flt(self.gross_pay) - flt(self.total_deduction)
self.rounded_total = rounded(self.net_pay)
self.rounded_total = rounded(self.net_pay,
self.precision("net_pay") if disable_rounded_total else 0)
def on_submit(self):
if(self.email_check == 1):

View File

@@ -1,114 +1,123 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"creation": "2014-11-27 14:12:07.542534",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Master",
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"creation": "2014-11-27 14:12:07.542534",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Master",
"fields": [
{
"fieldname": "capacity_planning",
"fieldtype": "Section Break",
"label": "Capacity Planning",
"permlevel": 0,
"fieldname": "capacity_planning",
"fieldtype": "Section Break",
"label": "Capacity Planning",
"permlevel": 0,
"precision": ""
},
},
{
"description": "Disables creation of time logs against Production Orders.\nOperations shall not be tracked against Production Order",
"fieldname": "disable_capacity_planning",
"fieldtype": "Check",
"label": "Disable Capacity Planning and Time Tracking",
"permlevel": 0,
"description": "Disables creation of time logs against Production Orders.\nOperations shall not be tracked against Production Order",
"fieldname": "disable_capacity_planning",
"fieldtype": "Check",
"label": "Disable Capacity Planning and Time Tracking",
"permlevel": 0,
"precision": ""
},
},
{
"description": "Plan time logs outside Workstation Working Hours.",
"fieldname": "allow_overtime",
"fieldtype": "Check",
"label": "Allow Overtime",
"permlevel": 0,
"description": "Plan time logs outside Workstation Working Hours.",
"fieldname": "allow_overtime",
"fieldtype": "Check",
"label": "Allow Overtime",
"permlevel": 0,
"precision": ""
},
},
{
"default": "",
"fieldname": "allow_production_on_holidays",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Allow Production on Holidays",
"options": "",
"permlevel": 0,
"default": "",
"fieldname": "allow_production_on_holidays",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Allow Production on Holidays",
"options": "",
"permlevel": 0,
"precision": ""
},
},
{
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"permlevel": 0,
"default": "BOM",
"fieldname": "backflush_raw_materials_based_on",
"fieldtype": "Select",
"label": "Backflush Raw Materials Based On",
"options": "BOM\nMaterial Transferred for Manufacture",
"permlevel": 0,
"precision": ""
},
},
{
"default": "30",
"description": "Try planning operations for X days in advance.",
"fieldname": "capacity_planning_for_days",
"fieldtype": "Int",
"label": "Capacity Planning For (Days)",
"permlevel": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"permlevel": 0,
"precision": ""
},
},
{
"description": "Default 10 mins",
"fieldname": "mins_between_operations",
"fieldtype": "Int",
"label": "Time Between Operations (in mins)",
"permlevel": 0,
"default": "30",
"description": "Try planning operations for X days in advance.",
"fieldname": "capacity_planning_for_days",
"fieldtype": "Int",
"label": "Capacity Planning For (Days)",
"permlevel": 0,
"precision": ""
},
},
{
"fieldname": "over_production_allowance_percentage",
"fieldtype": "Percent",
"label": "Over Production Allowance Percentage",
"permlevel": 0,
"description": "Default 10 mins",
"fieldname": "mins_between_operations",
"fieldtype": "Int",
"label": "Time Between Operations (in mins)",
"permlevel": 0,
"precision": ""
},
{
"fieldname": "over_production_allowance_percentage",
"fieldtype": "Percent",
"label": "Over Production Allowance Percentage",
"permlevel": 0,
"precision": ""
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-wrench",
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 1,
"istable": 0,
"modified": "2015-07-23 08:12:33.889753",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Manufacturing Settings",
"name_case": "",
"owner": "Administrator",
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-wrench",
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 1,
"istable": 0,
"modified": "2015-08-12 08:12:33.889753",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Manufacturing Settings",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 0,
"email": 0,
"export": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"role": "Manufacturing Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 0,
"email": 0,
"export": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"role": "Manufacturing Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
],
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC"
}
}

View File

@@ -4,6 +4,14 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe.utils import cint
from dateutil.relativedelta import relativedelta
class ManufacturingSettings(Document):
pass
def get_mins_between_operations():
if not hasattr(frappe.local, "_mins_between_operations"):
frappe.local._mins_between_operations = cint(frappe.db.get_single_value("Manufacturing Settings",
"mins_between_operations")) or 10
return relativedelta(minutes=frappe.local._mins_between_operations)

View File

@@ -152,7 +152,9 @@ $.extend(cur_frm.cscript, {
method: "erpnext.manufacturing.doctype.production_order.production_order.get_item_details",
args: { item: doc.production_item },
callback: function(r) {
cur_frm.set_value(r.message);
$.each(["description", "stock_uom", "bom_no"], function(i, field) {
cur_frm.set_value(field, r.message[field]);
});
}
});
},
@@ -160,7 +162,7 @@ $.extend(cur_frm.cscript, {
make_se: function(purpose) {
var me = this;
var max = (purpose === "Manufacture") ?
flt(this.frm.doc.qty) - flt(this.frm.doc.produced_qty) :
flt(this.frm.doc.material_transferred_for_manufacturing) - flt(this.frm.doc.produced_qty) :
flt(this.frm.doc.qty) - flt(this.frm.doc.material_transferred_for_manufacturing);
frappe.prompt({fieldtype:"Int", label: __("Qty for {0}", [purpose]), fieldname:"qty",
@@ -187,8 +189,8 @@ $.extend(cur_frm.cscript, {
bom_no: function() {
return this.frm.call({
doc: this.frm.doc,
method: "set_production_order_operations"
doc: this.frm.doc,
method: "set_production_order_operations"
});
},

View File

@@ -10,6 +10,10 @@ from frappe.model.document import Document
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
from dateutil.relativedelta import relativedelta
from erpnext.stock.doctype.item.item import validate_end_of_life
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError, NotInWorkingHoursError
from erpnext.projects.doctype.time_log.time_log import OverlapError
from erpnext.stock.doctype.stock_entry.stock_entry import get_additional_costs
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
class OverProductionError(frappe.ValidationError): pass
class StockOverProductionError(frappe.ValidationError): pass
@@ -17,9 +21,6 @@ class OperationTooLongError(frappe.ValidationError): pass
class ProductionNotApplicableError(frappe.ValidationError): pass
class ItemHasVariantError(frappe.ValidationError): pass
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError, NotInWorkingHoursError
from erpnext.projects.doctype.time_log.time_log import OverlapError
form_grid_templates = {
"operations": "templates/form_grid/production_order_grid.html"
}
@@ -231,6 +232,7 @@ class ProductionOrder(Document):
original_start_time = time_log.from_time
while True:
_from_time = time_log.from_time
try:
time_log.save()
break
@@ -248,6 +250,7 @@ class ProductionOrder(Document):
frappe.msgprint(_("Unable to find Time Slot in the next {0} days for Operation {1}").format(plan_days, d.operation))
break
# if time log needs to be moved, make sure that the from time is not the same
if _from_time == time_log.from_time:
frappe.throw("Capacity Planning Error")
@@ -273,19 +276,13 @@ class ProductionOrder(Document):
d.planned_start_time = self.planned_start_date
else:
d.planned_start_time = get_datetime(self.operations[i-1].planned_end_time)\
+ self.get_mins_between_operations()
+ get_mins_between_operations()
d.planned_end_time = get_datetime(d.planned_start_time) + relativedelta(minutes = d.time_in_mins)
if d.planned_start_time == d.planned_end_time:
frappe.throw(_("Capacity Planning Error"))
def get_mins_between_operations(self):
if not hasattr(self, "_mins_between_operations"):
self._mins_between_operations = cint(frappe.db.get_single_value("Manufacturing Settings",
"mins_between_operations")) or 10
return relativedelta(minutes=self._mins_between_operations)
def check_operation_fits_in_working_hours(self, d):
"""Raises expection if operation is longer than working hours in the given workstation."""
from erpnext.manufacturing.doctype.workstation.workstation import check_if_within_operating_hours
@@ -356,7 +353,6 @@ def make_stock_entry(production_order_id, purpose, qty=None):
stock_entry.company = production_order.company
stock_entry.from_bom = 1
stock_entry.bom_no = production_order.bom_no
stock_entry.additional_operating_cost = production_order.additional_operating_cost
stock_entry.use_multi_level_bom = production_order.use_multi_level_bom
stock_entry.fg_completed_qty = qty or (flt(production_order.qty) - flt(production_order.produced_qty))
@@ -365,6 +361,8 @@ def make_stock_entry(production_order_id, purpose, qty=None):
else:
stock_entry.from_warehouse = production_order.wip_warehouse
stock_entry.to_warehouse = production_order.fg_warehouse
additional_costs = get_additional_costs(production_order, fg_qty=stock_entry.fg_completed_qty)
stock_entry.set("additional_costs", additional_costs)
stock_entry.get_items()
return stock_entry.as_dict()

View File

@@ -28,9 +28,9 @@ class TestProductionOrder(unittest.TestCase):
# add raw materials to stores
test_stock_entry.make_stock_entry(item_code="_Test Item",
target="Stores - _TC", qty=100, incoming_rate=100)
target="Stores - _TC", qty=100, basic_rate=100)
test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
target="Stores - _TC", qty=100, incoming_rate=100)
target="Stores - _TC", qty=100, basic_rate=100)
# from stores to wip
s = frappe.get_doc(make_stock_entry(pro_order.name, "Material Transfer for Manufacture", 4))
@@ -58,9 +58,9 @@ class TestProductionOrder(unittest.TestCase):
pro_doc = self.check_planned_qty()
test_stock_entry.make_stock_entry(item_code="_Test Item",
target="_Test Warehouse - _TC", qty=100, incoming_rate=100)
target="_Test Warehouse - _TC", qty=100, basic_rate=100)
test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
target="_Test Warehouse - _TC", qty=100, incoming_rate=100)
target="_Test Warehouse - _TC", qty=100, basic_rate=100)
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 7))
s.insert()

View File

@@ -99,7 +99,6 @@ execute:frappe.db.sql("update `tabMaterial Request` set material_request_type =
execute:frappe.reload_doc('stock', 'doctype', 'item')
execute:frappe.db.sql("update `tabItem` i set apply_warehouse_wise_reorder_level=1, re_order_level=0, re_order_qty=0 where exists(select name from `tabItem Reorder` where parent=i.name)")
erpnext.patches.v5_0.set_default_company_in_bom
erpnext.patches.v5_0.capacity_planning
execute:frappe.reload_doc('crm', 'doctype', 'lead')
execute:frappe.reload_doc('crm', 'doctype', 'opportunity')
erpnext.patches.v5_0.rename_taxes_and_charges_master
@@ -188,3 +187,7 @@ erpnext.patches.v5_4.set_root_and_report_type
erpnext.patches.v5_4.notify_system_managers_regarding_wrong_tax_calculation
erpnext.patches.v5_4.fix_invoice_outstanding
execute:frappe.db.sql("update `tabStock Ledger Entry` set stock_queue = '[]' where voucher_type = 'Stock Reconciliation' and ifnull(qty_after_transaction, 0) = 0")
erpnext.patches.v5_4.fix_missing_item_images
erpnext.patches.v5_4.stock_entry_additional_costs
erpnext.patches.v5_4.cleanup_journal_entry #2015-08-14
execute:frappe.db.sql("update `tabProduction Order` pro set description = (select description from tabItem where name=pro.production_item) where ifnull(description, '') = ''")

View File

@@ -1,9 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import frappe
def execute():
frappe.reload_doc("stock", "doctype", "stock_entry")
if "total_fixed_cost" in frappe.db.get_table_columns("Stock Entry"):
frappe.db.sql("update `tabStock Entry` set additional_operating_cost = total_fixed_cost")

View File

@@ -0,0 +1,20 @@
import frappe
from MySQLdb import OperationalError
def execute():
frappe.reload_doctype("Journal Entry Account")
for doctype, fieldname in (
("Sales Order", "against_sales_order"),
("Purchase Order", "against_purchase_order"),
("Sales Invoice", "against_invoice"),
("Purchase Invoice", "against_voucher"),
("Journal Entry", "against_jv"),
("Expense Claim", "against_expense_claim"),
):
try:
frappe.db.sql("""update `tabJournal Entry Account`
set reference_type=%s, reference_name={0} where ifnull({0}, '') != ''
""".format(fieldname), doctype)
except OperationalError:
# column not found
pass

View File

@@ -0,0 +1,116 @@
from __future__ import unicode_literals
import frappe
import os
from frappe.utils import get_files_path
from frappe.utils.file_manager import get_content_hash
def execute():
files_path = get_files_path()
# get files that don't have attached_to_name but exist
unlinked_files = get_unlinked_files(files_path)
if not unlinked_files:
return
fixed_files = fix_files_for_item(files_path, unlinked_files)
# fix remaining files
for key, file_data in unlinked_files.items():
if key not in fixed_files:
rename_and_set_content_hash(files_path, unlinked_files, key)
frappe.db.commit()
def fix_files_for_item(files_path, unlinked_files):
fixed_files = []
# make a list of files/something and /files/something to check in child table's image column
file_urls = [key for key in unlinked_files.keys()] + ["/" + key for key in unlinked_files.keys()]
file_item_code = get_file_item_code(file_urls)
for (file_url, item_code), children in file_item_code.items():
new_file_url = "/files/{0}".format(unlinked_files[file_url]["file_name"])
for row in children:
# print file_url, new_file_url, item_code, row.doctype, row.name
# replace image in these rows with the new file url
frappe.db.set_value(row.doctype, row.name, "image", new_file_url, update_modified=False)
# set it as attachment of this item code
file_data = frappe.get_doc("File Data", unlinked_files[file_url]["file"])
file_data.attached_to_doctype = "Item"
file_data.attached_to_name = item_code
file_data.save()
# set it as image in Item
if not frappe.db.get_value("Item", item_code, "image"):
frappe.db.set_value("Item", item_code, "image", new_file_url, update_modified=False)
rename_and_set_content_hash(files_path, unlinked_files, file_url)
fixed_files.append(file_url)
# commit
frappe.db.commit()
return fixed_files
def rename_and_set_content_hash(files_path, unlinked_files, file_url):
# rename this file
old_filename = os.path.join(files_path, unlinked_files[file_url]["file"])
new_filename = os.path.join(files_path, unlinked_files[file_url]["file_name"])
if not os.path.exists(new_filename):
os.rename(old_filename, new_filename)
# set content hash if missing
file_data_name = unlinked_files[file_url]["file"]
if not frappe.db.get_value("File Data", file_data_name, "content_hash"):
with open(new_filename, "r") as f:
content_hash = get_content_hash(f.read())
frappe.db.set_value("File Data", file_data_name, "content_hash", content_hash)
def get_unlinked_files(files_path):
# find files that have the same name as a File Data doc
# and the file_name mentioned in that File Data doc doesn't exist
# and it isn't already attached to a doc
unlinked_files = {}
files = os.listdir(files_path)
for file in files:
if not frappe.db.exists("File Data", {"file_name": file}):
file_data = frappe.db.get_value("File Data", {"name": file},
["file_name", "attached_to_doctype", "attached_to_name"], as_dict=True)
if (file_data
and file_data.file_name
and file_data.file_name not in files
and not file_data.attached_to_doctype
and not file_data.attached_to_name):
file_data["file"] = file
unlinked_files["files/{0}".format(file)] = file_data
return unlinked_files
def get_file_item_code(file_urls):
# get a map of file_url, item_code and list of documents where file_url will need to be changed in image field
file_item_code = {}
doctypes = frappe.db.sql_list("""select name from `tabDocType` dt
where istable=1
and exists (select name from `tabDocField` df where df.parent=dt.name and df.fieldname='item_code')
and exists (select name from `tabDocField` df where df.parent=dt.name and df.fieldname='image')""")
for doctype in doctypes:
result = frappe.db.sql("""select name, image, item_code, '{0}' as doctype from `tab{0}`
where image in ({1})""".format(doctype, ", ".join(["%s"]*len(file_urls))),
file_urls, as_dict=True)
for r in result:
key = (r.image, r.item_code)
if key not in file_item_code:
file_item_code[key] = []
file_item_code[key].append(r)
return file_item_code

View File

@@ -0,0 +1,53 @@
# Copyright (c) 2015, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.utils import flt
def execute():
frappe.reload_doctype("Stock Entry")
frappe.reload_doctype("Stock Entry Detail")
frappe.reload_doctype("Landed Cost Taxes and Charges")
stock_entry_db_columns = frappe.db.get_table_columns("Stock Entry")
if "additional_operating_cost" in stock_entry_db_columns:
operating_cost_fieldname = "additional_operating_cost"
elif "total_fixed_cost" in stock_entry_db_columns:
operating_cost_fieldname = "total_fixed_cost"
else:
return
frappe.db.sql("""update `tabStock Entry Detail` sed, `tabStock Entry` se
set sed.valuation_rate=sed.incoming_rate, sed.basic_rate=sed.incoming_rate, sed.basic_amount=sed.amount
where sed.parent = se.name
and (se.purpose not in ('Manufacture', 'Repack') or ifnull({0}, 0)=0)
""".format(operating_cost_fieldname))
stock_entries = frappe.db.sql_list("""select name from `tabStock Entry`
where purpose in ('Manufacture', 'Repack') and ifnull({0}, 0)!=0
and docstatus < 2""".format(operating_cost_fieldname))
for d in stock_entries:
stock_entry = frappe.get_doc("Stock Entry", d)
stock_entry.append("additional_costs", {
"description": "Additional Operating Cost",
"amount": stock_entry.get(operating_cost_fieldname)
})
number_of_fg_items = len([t.t_warehouse for t in stock_entry.get("items") if t.t_warehouse])
for d in stock_entry.get("items"):
d.valuation_rate = d.incoming_rate
if d.bom_no or (d.t_warehouse and number_of_fg_items == 1):
d.additional_cost = stock_entry.get(operating_cost_fieldname)
d.basic_rate = flt(d.valuation_rate) - flt(d.additional_cost)
d.basic_amount = flt(flt(d.basic_rate) *flt(d.transfer_qty), d.precision("basic_amount"))
stock_entry.flags.ignore_validate = True
stock_entry.flags.ignore_validate_update_after_submit = True
stock_entry.save()

View File

@@ -6,6 +6,7 @@ import frappe, json
from frappe import _
from frappe.utils import cstr, flt, get_datetime, get_time, getdate
from dateutil.relativedelta import relativedelta
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
class OverlapError(frappe.ValidationError): pass
class OverProductionLoggedError(frappe.ValidationError): pass
@@ -182,9 +183,14 @@ class TimeLog(Document):
def move_to_next_non_overlapping_slot(self):
"""If in overlap, set start as the end point of the overlapping time log"""
overlapping = self.get_overlap_for("workstation")
if overlapping:
self.from_time = get_datetime(overlapping.to_time) + relativedelta(minutes=10)
overlapping = self.get_overlap_for("workstation") \
or self.get_overlap_for("employee") \
or self.get_overlap_for("user")
if not overlapping:
frappe.throw("Logical error: Must find overlapping")
self.from_time = get_datetime(overlapping.to_time) + get_mins_between_operations()
def get_time_log_summary(self):
"""Returns 'Actual Operating Time'. """

View File

@@ -15,6 +15,8 @@ class TimeLogBatch(Document):
def validate(self):
self.set_status()
self.total_hours = 0.0
self.total_billing_amount = 0.0
for d in self.get("time_logs"):
tl = frappe.get_doc("Time Log", d.time_log)
self.update_time_log_values(d, tl)

View File

@@ -11,7 +11,8 @@ $(document).bind('toolbar_setup', function() {
href="https://discuss.erpnext.com">Feedback</a></p>'
$('.navbar-home').html('<img class="erpnext-icon" src="/assets/erpnext/images/erp-icon.svg" />');
$('.navbar-home').html('<img class="erpnext-icon" src="'+
frappe.urllib.get_base_url()+'/assets/erpnext/images/erp-icon.svg" />');
$('[data-link="docs"]').attr("href", "https://manual.erpnext.com")
});

View File

@@ -13,30 +13,8 @@ erpnext.stock.StockController = frappe.ui.form.Controller.extend({
setup_warehouse_query: function() {
var me = this;
var warehouse_query_method = function() {
erpnext.queries.setup_queries(this.frm, "Warehouse", function() {
return erpnext.queries.warehouse(me.frm.doc);
};
var _set_warehouse_query = function(doctype, parentfield) {
var warehouse_link_fields = frappe.meta.get_docfields(doctype, me.frm.doc.name,
{"fieldtype": "Link", "options": "Warehouse"});
$.each(warehouse_link_fields, function(i, df) {
if(parentfield) {
me.frm.set_query(df.fieldname, parentfield, warehouse_query_method);
} else {
me.frm.set_query(df.fieldname, warehouse_query_method);
}
});
};
_set_warehouse_query(me.frm.doc.doctype);
// warehouse field in tables
var table_fields = frappe.meta.get_docfields(me.frm.doc.doctype, me.frm.doc.name,
{"fieldtype": "Table"});
$.each(table_fields, function(i, df) {
_set_warehouse_query(df.options, df.fieldname);
});
},

View File

@@ -75,3 +75,26 @@ $.extend(erpnext.queries, {
}
}
});
erpnext.queries.setup_queries = function(frm, options, query_fn) {
var me = this;
var set_query = function(doctype, parentfield) {
var link_fields = frappe.meta.get_docfields(doctype, frm.doc.name,
{"fieldtype": "Link", "options": options});
$.each(link_fields, function(i, df) {
if(parentfield) {
frm.set_query(df.fieldname, parentfield, query_fn);
} else {
frm.set_query(df.fieldname, query_fn);
}
});
};
set_query(frm.doc.doctype);
// warehouse field in tables
$.each(frappe.meta.get_docfields(frm.doc.doctype, frm.doc.name, {"fieldtype": "Table"}),
function(i, df) {
set_query(df.options, df.fieldname);
});
}

View File

@@ -46,6 +46,7 @@ cur_frm.cscript.setup_dashboard = function(doc) {
cur_frm.dashboard.add_doctype_badge("Sales Order", "customer");
cur_frm.dashboard.add_doctype_badge("Delivery Note", "customer");
cur_frm.dashboard.add_doctype_badge("Sales Invoice", "customer");
cur_frm.dashboard.add_doctype_badge("Project", "customer");
return frappe.call({
type: "GET",
@@ -62,6 +63,8 @@ cur_frm.cscript.setup_dashboard = function(doc) {
+ '</b> / <span class="text-muted">' + __("Unpaid") + ": <b>"
+ format_currency(r.message.total_unpaid, r.message["company_currency"][0])
+ '</b></span>');
} else {
cur_frm.dashboard.set_headline("");
}
}
cur_frm.dashboard.set_badge_count(r.message);

View File

@@ -1,35 +1,62 @@
{
"allow_copy": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "naming_series:",
"creation": "2013-06-11 14:26:44",
"custom": 0,
"description": "Buyer of Goods and Services.",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Master",
"fields": [
{
"allow_on_submit": 0,
"fieldname": "basic_info",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "",
"no_copy": 0,
"oldfieldtype": "Section Break",
"options": "icon-user",
"permlevel": 0,
"reqd": 0
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Series",
"no_copy": 1,
"options": "CUST-",
"permlevel": 0,
"print_hide": 0
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "customer_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 1,
"in_list_view": 0,
"label": "Full Name",
@@ -38,25 +65,43 @@
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "customer_type",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Type",
"no_copy": 0,
"oldfieldname": "customer_type",
"oldfieldtype": "Select",
"options": "\nCompany\nIndividual",
"permlevel": 0,
"reqd": 1
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "lead_name",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 1,
"in_list_view": 0,
"label": "From Lead",
"no_copy": 1,
"oldfieldname": "lead_name",
@@ -64,228 +109,580 @@
"options": "Lead",
"permlevel": 0,
"print_hide": 1,
"report_hide": 1
"read_only": 0,
"report_hide": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_on_submit": 0,
"description": "",
"fieldname": "customer_group",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 1,
"in_list_view": 1,
"label": "Customer Group",
"no_copy": 0,
"oldfieldname": "customer_group",
"oldfieldtype": "Link",
"options": "Customer Group",
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"description": "",
"fieldname": "territory",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Territory",
"no_copy": 0,
"oldfieldname": "territory",
"oldfieldtype": "Link",
"options": "Territory",
"permlevel": 0,
"print_hide": 1,
"reqd": 1
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "tax_id",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Tax ID",
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "is_frozen",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Is Frozen",
"no_copy": 0,
"permlevel": 0,
"precision": ""
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"depends_on": "eval:!doc.__islocal",
"fieldname": "address_contacts",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "",
"no_copy": 0,
"options": "icon-map-marker",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "address_html",
"fieldtype": "HTML",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Address HTML",
"no_copy": 0,
"permlevel": 0,
"read_only": 1
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_on_submit": 0,
"fieldname": "contact_html",
"fieldtype": "HTML",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Contact HTML",
"no_copy": 0,
"oldfieldtype": "HTML",
"permlevel": 0,
"read_only": 1
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "default_receivable_accounts",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Default Receivable Accounts",
"permlevel": 0
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"depends_on": "eval:!doc.__islocal",
"description": "Mention if non-standard receivable account applicable",
"fieldname": "accounts",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Accounts",
"no_copy": 0,
"options": "Party Account",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "",
"no_copy": 0,
"oldfieldtype": "Section Break",
"options": "icon-file-text",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"description": "Your Customer's TAX registration numbers (if applicable) or any general information",
"allow_on_submit": 0,
"description": "Additional information regarding the customer.",
"fieldname": "customer_details",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Customer Details",
"no_copy": 0,
"oldfieldname": "customer_details",
"oldfieldtype": "Code",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "column_break3",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_on_submit": 0,
"fieldname": "default_currency",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"in_filter": 0,
"in_list_view": 0,
"label": "Currency",
"no_copy": 1,
"options": "Currency",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "default_price_list",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"in_filter": 0,
"in_list_view": 0,
"label": "Price List",
"no_copy": 0,
"options": "Price List",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "default_taxes_and_charges",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"in_filter": 0,
"in_list_view": 0,
"label": "Taxes and Charges",
"no_copy": 0,
"options": "Sales Taxes and Charges Template",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "credit_days_based_on",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Credit Days Based On",
"no_copy": 0,
"options": "\nFixed Days\nLast Day of the Next Month",
"permlevel": 0,
"precision": ""
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"depends_on": "eval:doc.credit_days_based_on=='Fixed Days'",
"fieldname": "credit_days",
"fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Credit Days",
"no_copy": 0,
"oldfieldname": "credit_days",
"oldfieldtype": "Int",
"permlevel": 1
"permlevel": 1,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "credit_limit",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Credit Limit",
"no_copy": 0,
"oldfieldname": "credit_limit",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 1
"permlevel": 1,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "website",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Website",
"permlevel": 0
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "sales_team_section_break",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "",
"no_copy": 0,
"oldfieldtype": "Section Break",
"options": "icon-group",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "default_sales_partner",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"in_filter": 0,
"in_list_view": 0,
"label": "Sales Partner",
"no_copy": 0,
"oldfieldname": "default_sales_partner",
"oldfieldtype": "Link",
"options": "Sales Partner",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "default_commission_rate",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Commission Rate",
"no_copy": 0,
"oldfieldname": "default_commission_rate",
"oldfieldtype": "Currency",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "sales_team",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Sales Team Details",
"no_copy": 0,
"oldfieldname": "sales_team",
"oldfieldtype": "Table",
"options": "Sales Team",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "communications",
"fieldtype": "Table",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Communications",
"no_copy": 0,
"options": "Communication",
"permlevel": 0,
"print_hide": 1
"print_hide": 1,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-user",
"idx": 1,
"modified": "2015-07-17 09:38:50.086978",
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"modified": "2015-08-07 20:34:25.761769",
"modified_by": "Administrator",
"module": "Selling",
"name": "Customer",
@@ -294,38 +691,73 @@
{
"amend": 0,
"apply_user_permissions": 1,
"cancel": 0,
"create": 1,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 1,
"print": 0,
"read": 1,
"role": "Sales User"
"report": 0,
"role": "Sales User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales Manager"
"role": "Sales Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -337,46 +769,108 @@
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 1,
"print": 0,
"read": 1,
"report": 0,
"role": "Sales Master Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Stock User"
"role": "Stock User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Stock Manager"
"role": "Stock Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User"
"role": "Accounts User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager"
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
}
],
"read_only": 0,
"read_only_onload": 0,
"search_fields": "customer_name,customer_group,territory",
"title_field": "customer_name"
}

View File

@@ -119,7 +119,8 @@ def get_dashboard_info(customer):
frappe.msgprint(_("Not permitted"), raise_exception=True)
out = {}
for doctype in ["Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
for doctype in ["Opportunity", "Quotation", "Sales Order", "Delivery Note",
"Sales Invoice", "Project"]:
out[doctype] = frappe.db.get_value(doctype,
{"customer": customer, "docstatus": ["!=", 2] }, "count(*)")

View File

@@ -3,6 +3,14 @@
{% include 'selling/sales_common.js' %}
frappe.ui.form.on("Sales Order", {
onload: function(frm) {
erpnext.queries.setup_queries(frm, "Warehouse", function() {
return erpnext.queries.warehouse(frm.doc);
});
}
});
erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({
refresh: function(doc, dt, dn) {
this._super();
@@ -16,29 +24,32 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
// cur_frm.dashboard.add_progress(cint(doc.per_billed) + __("% Billed"),
// doc.per_billed);
// delivery note
if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1)
cur_frm.add_custom_button(__('Make Delivery'), this.make_delivery_note);
// indent
if(!doc.order_type || ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1)
cur_frm.add_custom_button(__('Make ') + __('Material Request'),
this.make_material_request);
cur_frm.add_custom_button(__('Material Request'), this.make_material_request);
// sales invoice
if(flt(doc.per_billed, 2) < 100) {
cur_frm.add_custom_button(__('Make Invoice'), this.make_sales_invoice);
if(flt(doc.per_billed)==0) {
cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry);
}
// stop
if(flt(doc.per_delivered, 2) < 100 || doc.per_billed < 100)
cur_frm.add_custom_button(__('Stop'), cur_frm.cscript['Stop Sales Order'])
// maintenance
if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) {
cur_frm.add_custom_button(__('Make Maint. Visit'), this.make_maintenance_visit);
cur_frm.add_custom_button(__('Make Maint. Schedule'), this.make_maintenance_schedule);
}
// maintenance
if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) {
cur_frm.add_custom_button(__('Maint. Visit'), this.make_maintenance_visit);
cur_frm.add_custom_button(__('Maint. Schedule'), this.make_maintenance_schedule);
}
// delivery note
if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1)
cur_frm.add_custom_button(__('Delivery'), this.make_delivery_note).addClass("btn-primary");
// sales invoice
if(flt(doc.per_billed, 2) < 100) {
cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice).addClass("btn-primary");
}
} else {
// un-stop
@@ -122,6 +133,20 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
frm: cur_frm
})
},
make_bank_entry: function() {
return frappe.call({
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_from_sales_order",
args: {
"sales_order": cur_frm.doc.name
},
callback: function(r) {
var doclist = frappe.model.sync(r.message);
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
}
});
}
});
// for backward compatibility: combine new and previous states

View File

@@ -32,7 +32,7 @@ class Company(Document):
frappe.throw(_("Abbreviation cannot have more than 5 characters"))
if not self.abbr.strip():
frappe.throw(_("Abbr can not be blank or space"))
frappe.throw(_("Abbreviation is mandatory"))
self.previous_default_currency = frappe.db.get_value("Company", self.name, "default_currency")
if self.default_currency and self.previous_default_currency and \

View File

@@ -8,28 +8,28 @@ frappe.provide("erpnext.stock.delivery_note");
erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend({
refresh: function(doc, dt, dn) {
this._super();
if (!doc.is_return) {
if(doc.__onload && !doc.__onload.billing_complete && doc.docstatus==1) {
// show Make Invoice button only if Delivery Note is not created from Sales Invoice
var from_sales_invoice = false;
from_sales_invoice = cur_frm.doc.items.some(function(item) {
return item.against_sales_invoice ? true : false;
});
return item.against_sales_invoice ? true : false;
});
if(!from_sales_invoice)
cur_frm.add_custom_button(__('Make Invoice'), this.make_sales_invoice);
cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice).addClass("btn-primary");
}
if(flt(doc.per_installed, 2) < 100 && doc.docstatus==1)
cur_frm.add_custom_button(__('Make Installation Note'), this.make_installation_note);
cur_frm.add_custom_button(__('Installation Note'), this.make_installation_note);
if (doc.docstatus==1) {
cur_frm.add_custom_button(__('Make Sales Return'), this.make_sales_return);
cur_frm.add_custom_button(__('Sales Return'), this.make_sales_return);
}
if(doc.docstatus==0 && !doc.__islocal) {
cur_frm.add_custom_button(__('Make Packing Slip'),
cur_frm.add_custom_button(__('Packing Slip'),
cur_frm.cscript['Make Packing Slip'], frappe.boot.doctype_icons["Packing Slip"]);
}
@@ -51,15 +51,15 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
});
}
}
if (doc.docstatus==1) {
this.show_stock_ledger();
if (cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
this.show_general_ledger();
}
}
erpnext.stock.delivery_note.set_print_hide(doc, dt, dn);
@@ -81,7 +81,7 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
frm: cur_frm
});
},
make_sales_return: function() {
frappe.model.open_mapped_doc({
method: "erpnext.stock.doctype.delivery_note.delivery_note.make_sales_return",

View File

@@ -37,7 +37,7 @@ class TestDeliveryNote(unittest.TestCase):
set_perpetual_inventory(0)
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 0)
make_stock_entry(target="_Test Warehouse - _TC", qty=5, incoming_rate=100)
make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100)
stock_queue = json.loads(get_previous_sle({
"item_code": "_Test Item",
@@ -59,7 +59,7 @@ class TestDeliveryNote(unittest.TestCase):
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
frappe.db.set_value("Item", "_Test Item", "valuation_method", "FIFO")
make_stock_entry(target="_Test Warehouse - _TC", qty=5, incoming_rate=100)
make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100)
stock_in_hand_account = frappe.db.get_value("Account", {"warehouse": "_Test Warehouse - _TC"})
prev_bal = get_balance_on(stock_in_hand_account)
@@ -85,7 +85,7 @@ class TestDeliveryNote(unittest.TestCase):
# back dated incoming entry
make_stock_entry(posting_date=add_days(nowdate(), -2), target="_Test Warehouse - _TC",
qty=5, incoming_rate=100)
qty=5, basic_rate=100)
gl_entries = get_gl_entries("Delivery Note", dn.name)
self.assertTrue(gl_entries)
@@ -107,9 +107,9 @@ class TestDeliveryNote(unittest.TestCase):
def test_delivery_note_gl_entry_packing_item(self):
set_perpetual_inventory()
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=10, incoming_rate=100)
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=10, basic_rate=100)
make_stock_entry(item_code="_Test Item Home Desktop 100",
target="_Test Warehouse - _TC", qty=10, incoming_rate=100)
target="_Test Warehouse - _TC", qty=10, basic_rate=100)
stock_in_hand_account = frappe.db.get_value("Account", {"warehouse": "_Test Warehouse - _TC"})
prev_bal = get_balance_on(stock_in_hand_account)
@@ -184,7 +184,7 @@ class TestDeliveryNote(unittest.TestCase):
def test_sales_return_for_non_bundled_items(self):
set_perpetual_inventory()
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, incoming_rate=100)
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100)
actual_qty_0 = get_qty_after_transaction()

View File

@@ -48,7 +48,7 @@ class Item(WebsiteGenerator):
self.website_image = self.image
self.check_warehouse_is_set_for_stock_item()
self.check_stock_uom_with_bin()
self.validate_uom()
self.add_default_uom_in_conversion_factor_table()
self.validate_conversion_factor()
self.validate_item_type()
@@ -105,35 +105,6 @@ class Item(WebsiteGenerator):
[self.remove(d) for d in to_remove]
def check_stock_uom_with_bin(self):
if not self.get("__islocal"):
if self.stock_uom == frappe.db.get_value("Item", self.name, "stock_uom"):
return
matched=True
ref_uom = frappe.db.get_value("Stock Ledger Entry",
{"item_code": self.name}, "stock_uom")
if ref_uom:
if cstr(ref_uom) != cstr(self.stock_uom):
matched = False
else:
bin_list = frappe.db.sql("select * from tabBin where item_code=%s",
self.item_code, as_dict=1)
for bin in bin_list:
if (bin.reserved_qty > 0 or bin.ordered_qty > 0 or bin.indented_qty > 0 \
or bin.planned_qty > 0) and cstr(bin.stock_uom) != cstr(self.stock_uom):
matched = False
break
if matched and bin_list:
frappe.db.sql("""update tabBin set stock_uom=%s where item_code=%s""",
(self.stock_uom, self.name))
if not matched:
frappe.throw(_("Default Unit of Measure for Item {0} cannot be changed directly because you have already made some transaction(s) with another UOM. To change default UOM, use 'UOM Replace Utility' tool under Stock module.").format(self.name))
def update_template_tables(self):
template = frappe.get_doc("Item", self.variant_of)
@@ -344,6 +315,17 @@ class Item(WebsiteGenerator):
or ifnull(reserved_qty, 0) > 0 or ifnull(indented_qty, 0) > 0 or ifnull(planned_qty, 0) > 0)""", self.name)
if stock_in:
frappe.throw(_("Item Template cannot have stock or Open Sales/Purchase/Production Orders."), ItemTemplateCannotHaveStock)
def validate_uom(self):
if not self.get("__islocal"):
check_stock_uom_with_bin(self.name, self.stock_uom)
if self.has_variants:
for d in frappe.db.get_all("Item", filters= {"variant_of": self.name}):
check_stock_uom_with_bin(d.name, self.stock_uom)
if self.variant_of:
template_uom = frappe.db.get_value("Item", self.variant_of, "stock_uom")
if template_uom != self.stock_uom:
frappe.throw(_("Default Unit of Measure for Variant must be same as Template"))
def validate_end_of_life(item_code, end_of_life=None, verbose=1):
if not end_of_life:
@@ -449,3 +431,30 @@ def invalidate_cache_for_item(doc):
if doc.get("old_item_group") and doc.get("old_item_group") != doc.item_group:
invalidate_cache_for(doc, doc.old_item_group)
def check_stock_uom_with_bin(item, stock_uom):
if stock_uom == frappe.db.get_value("Item", item, "stock_uom"):
return
matched=True
ref_uom = frappe.db.get_value("Stock Ledger Entry",
{"item_code": item}, "stock_uom")
if ref_uom:
if cstr(ref_uom) != cstr(stock_uom):
matched = False
else:
bin_list = frappe.db.sql("select * from tabBin where item_code=%s", item, as_dict=1)
for bin in bin_list:
if (bin.reserved_qty > 0 or bin.ordered_qty > 0 or bin.indented_qty > 0 \
or bin.planned_qty > 0) and cstr(bin.stock_uom) != cstr(stock_uom):
matched = False
break
if matched and bin_list:
frappe.db.sql("""update tabBin set stock_uom=%s where item_code=%s""", (stock_uom, item))
if not matched:
frappe.throw(_("Default Unit of Measure for Item {0} cannot be changed directly because \
you have already made some transaction(s) with another UOM. To change default UOM, \
use 'UOM Replace Utility' tool under Stock module.").format(item))

View File

@@ -47,7 +47,7 @@ class TestItem(unittest.TestCase):
def test_template_cannot_have_stock(self):
item = self.get_item(10)
make_stock_entry(item_code=item.name, target="Stores - _TC", qty=1, incoming_rate=1)
make_stock_entry(item_code=item.name, target="Stores - _TC", qty=1, basic_rate=1)
item.has_variants = 1
self.assertRaises(ItemTemplateCannotHaveStock, item.save)

View File

@@ -305,7 +305,7 @@ def make_stock_entry(source_name, target_doc=None):
def set_missing_values(source, target):
target.purpose = source.material_request_type
target.run_method("get_stock_and_rate")
target.run_method("calculate_rate_and_amount")
doclist = get_mapped_doc("Material Request", source_name, {
"Material Request": {

View File

@@ -72,7 +72,7 @@ class TestMaterialRequest(unittest.TestCase):
"doctype": "Stock Entry Detail",
"item_code": "_Test Item Home Desktop 100",
"parentfield": "items",
"incoming_rate": 100,
"basic_rate": 100,
"qty": qty1,
"stock_uom": "_Test UOM 1",
"transfer_qty": qty1,
@@ -84,7 +84,7 @@ class TestMaterialRequest(unittest.TestCase):
"doctype": "Stock Entry Detail",
"item_code": "_Test Item Home Desktop 200",
"parentfield": "items",
"incoming_rate": 100,
"basic_rate": 100,
"qty": qty2,
"stock_uom": "_Test UOM 1",
"transfer_qty": qty2,
@@ -196,13 +196,13 @@ class TestMaterialRequest(unittest.TestCase):
"qty": 27.0,
"transfer_qty": 27.0,
"s_warehouse": "_Test Warehouse 1 - _TC",
"incoming_rate": 1.0
"basic_rate": 1.0
})
se_doc.get("items")[1].update({
"qty": 1.5,
"transfer_qty": 1.5,
"s_warehouse": "_Test Warehouse 1 - _TC",
"incoming_rate": 1.0
"basic_rate": 1.0
})
# make available the qty in _Test Warehouse 1 before transfer
@@ -279,13 +279,13 @@ class TestMaterialRequest(unittest.TestCase):
"qty": 60.0,
"transfer_qty": 60.0,
"s_warehouse": "_Test Warehouse 1 - _TC",
"incoming_rate": 1.0
"basic_rate": 1.0
})
se_doc.get("items")[1].update({
"qty": 3.0,
"transfer_qty": 3.0,
"s_warehouse": "_Test Warehouse 1 - _TC",
"incoming_rate": 1.0
"basic_rate": 1.0
})
# make available the qty in _Test Warehouse 1 before transfer
@@ -350,13 +350,13 @@ class TestMaterialRequest(unittest.TestCase):
"transfer_qty": 60.0,
"s_warehouse": "_Test Warehouse - _TC",
"t_warehouse": "_Test Warehouse 1 - _TC",
"incoming_rate": 1.0
"basic_rate": 1.0
})
se_doc.get("items")[1].update({
"qty": 3.0,
"transfer_qty": 3.0,
"s_warehouse": "_Test Warehouse 1 - _TC",
"incoming_rate": 1.0
"basic_rate": 1.0
})
# check for stopped status of Material Request

View File

@@ -50,16 +50,15 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend
})
});
}
if(this.frm.doc.docstatus == 1) {
cur_frm.add_custom_button(__('Return'), this.make_purchase_return);
if(this.frm.doc.__onload && !this.frm.doc.__onload.billing_complete) {
cur_frm.add_custom_button(__('Make Purchase Invoice'), this.make_purchase_invoice);
cur_frm.add_custom_button(__('Invoice'), this.make_purchase_invoice).addClass("btn-primary");
}
cur_frm.add_custom_button(__('Make Purchase Return'), this.make_purchase_return);
}
}
this.frm.toggle_reqd("supplier_warehouse", this.frm.doc.is_subcontracted==="Yes");
},
@@ -111,7 +110,7 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend
frm: cur_frm
})
},
make_purchase_return: function() {
frappe.model.open_mapped_doc({
method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_return",

View File

@@ -80,9 +80,9 @@ class TestPurchaseReceipt(unittest.TestCase):
def test_subcontracting(self):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
make_stock_entry(item_code="_Test Item", target="_Test Warehouse 1 - _TC", qty=100, incoming_rate=100)
make_stock_entry(item_code="_Test Item", target="_Test Warehouse 1 - _TC", qty=100, basic_rate=100)
make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse 1 - _TC",
qty=100, incoming_rate=100)
qty=100, basic_rate=100)
pr = make_purchase_receipt(item_code="_Test FG Item", qty=10, rate=500, is_subcontracted="Yes")
self.assertEquals(len(pr.get("supplied_items")), 2)

View File

@@ -10,7 +10,10 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
this.frm.fields_dict.bom_no.get_query = function() {
return {
filters:{ 'docstatus': 1 }
filters:{
"docstatus": 1,
"is_active": 1
}
};
};
@@ -22,7 +25,8 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
return {
"filters": {
"docstatus": 1,
"is_subcontracted": "Yes"
"is_subcontracted": "Yes",
"company": me.frm.doc.company
}
};
});
@@ -38,6 +42,14 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
}
}
}
this.frm.set_query("difference_account", function() {
return {
"filters": {
"company": me.frm.doc.company,
"is_group": 0
}
};
});
}
},
@@ -122,25 +134,37 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
var d = locals[cdt][cdn];
d.transfer_qty = flt(d.qty) * flt(d.conversion_factor);
refresh_field('items');
calculate_total(doc, cdt, cdn);
},
incoming_rate: function(doc, cdt, cdn) {
calculate_total(doc, cdt, cdn);
},
production_order: function() {
var me = this;
this.toggle_enable_bom();
return this.frm.call({
method: "get_production_order_details",
args: {production_order: this.frm.doc.production_order},
return frappe.call({
method: "erpnext.stock.doctype.stock_entry.stock_entry.get_production_order_details",
args: {production_order: me.frm.doc.production_order},
callback: function(r) {
if (!r.exc) {
$.each(["from_bom", "bom_no", "fg_completed_qty", "use_multi_level_bom"], function(i, field) {
me.frm.set_value(field, r.message[field]);
})
if (me.frm.doc.purpose == "Material Transfer for Manufacture" && !me.frm.doc.to_warehouse)
me.frm.set_value("to_warehouse", r.message["wip_warehouse"]);
me.frm.set_value("from_bom", 1);
if (me.frm.doc.purpose == "Manufacture") {
if(r.message["additional_costs"].length) {
$.each(r.message["additional_costs"], function(i, row) {
me.frm.add_child("additional_costs", row);
})
refresh_field("additional_costs");
}
if (!me.frm.doc.from_warehouse) me.frm.set_value("from_warehouse", r.message["wip_warehouse"]);
if (!me.frm.doc.to_warehouse) me.frm.set_value("to_warehouse", r.message["fg_warehouse"]);
}
me.get_items()
}
}
});
@@ -228,13 +252,20 @@ cur_frm.cscript.toggle_related_fields = function(doc) {
if(doc.purpose == "Material Receipt") {
cur_frm.set_value("from_bom", 0);
}
// Addition costs based on purpose
cur_frm.toggle_display(["additional_costs", "total_additional_costs", "additional_costs_section"],
doc.purpose!='Material Issue');
cur_frm.fields_dict["items"].grid.set_column_disp("additional_cost", doc.purpose!='Material Issue');
}
cur_frm.fields_dict['production_order'].get_query = function(doc) {
return {
filters: [
['Production Order', 'docstatus', '=', 1],
['Production Order', 'qty', '>','`tabProduction Order`.produced_qty']
['Production Order', 'qty', '>','`tabProduction Order`.produced_qty'],
['Production Order', 'company', '=', cur_frm.doc.company]
]
}
}
@@ -374,17 +405,4 @@ cur_frm.cscript.company = function(doc, cdt, cdn) {
cur_frm.cscript.posting_date = function(doc, cdt, cdn){
erpnext.get_fiscal_year(doc.company, doc.posting_date);
}
var calculate_total = function(doc, cdt, cdn){
var d = locals[cdt][cdn];
amount = flt(d.incoming_rate) * flt(d.transfer_qty)
frappe.model.set_value(cdt, cdn, 'amount', amount);
var total_amount = 0.0;
var items = doc.items || [];
for(var i=0;i<items.length;i++) {
total_amount += flt(items[i].amount);
}
doc.total_amount = total_amount;
refresh_field("total_amount");
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -29,8 +29,7 @@ class StockEntry(StockController):
def onload(self):
if self.docstatus==1:
for item in self.get("items"):
item.update(get_available_qty(item.item_code,
item.s_warehouse))
item.update(get_available_qty(item.item_code, item.s_warehouse))
def validate(self):
self.pro_doc = None
@@ -46,14 +45,13 @@ class StockEntry(StockController):
self.validate_uom_is_integer("stock_uom", "transfer_qty")
self.validate_warehouse()
self.validate_production_order()
self.get_stock_and_rate()
self.validate_bom()
self.validate_finished_goods()
self.validate_with_material_request()
self.validate_valuation_rate()
self.set_total_incoming_outgoing_value()
self.set_total_amount()
self.validate_batch()
self.set_actual_qty()
self.calculate_rate_and_amount()
def on_submit(self):
self.update_stock_ledger()
@@ -100,7 +98,7 @@ class StockEntry(StockController):
if f in ["stock_uom", "conversion_factor"] or not item.get(f):
item.set(f, item_details.get(f))
if self.difference_account:
if self.difference_account and not item.expense_account:
item.expense_account = self.difference_account
if not item.transfer_qty:
@@ -213,6 +211,92 @@ class StockEntry(StockController):
if fg_qty_already_entered >= qty:
frappe.throw(_("Stock Entries already created for Production Order ")
+ self.production_order + ":" + ", ".join(other_ste), DuplicateEntryForProductionOrderError)
def set_actual_qty(self):
allow_negative_stock = cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock"))
for d in self.get('items'):
previous_sle = get_previous_sle({
"item_code": d.item_code,
"warehouse": d.s_warehouse or d.t_warehouse,
"posting_date": self.posting_date,
"posting_time": self.posting_time
})
# get actual stock at source warehouse
d.actual_qty = previous_sle.get("qty_after_transaction") or 0
# validate qty during submit
if d.docstatus==1 and d.s_warehouse and not allow_negative_stock and d.actual_qty < d.transfer_qty:
frappe.throw(_("""Row {0}: Qty not avalable in warehouse {1} on {2} {3}.
Available Qty: {4}, Transfer Qty: {5}""").format(d.idx, d.s_warehouse,
self.posting_date, self.posting_time, d.actual_qty, d.transfer_qty), NegativeStockError)
def get_stock_and_rate(self):
self.set_actual_qty()
self.calculate_rate_and_amount()
def calculate_rate_and_amount(self, force=False):
self.set_basic_rate(force)
self.distribute_additional_costs()
self.update_valuation_rate()
self.validate_valuation_rate()
self.set_total_incoming_outgoing_value()
self.set_total_amount()
def set_basic_rate(self, force=False):
"""get stock and incoming rate on posting date"""
raw_material_cost = 0.0
for d in self.get('items'):
args = frappe._dict({
"item_code": d.item_code,
"warehouse": d.s_warehouse or d.t_warehouse,
"posting_date": self.posting_date,
"posting_time": self.posting_time,
"qty": d.s_warehouse and -1*flt(d.transfer_qty) or flt(d.transfer_qty),
"serial_no": d.serial_no,
})
# get basic rate
if not d.bom_no:
if not flt(d.basic_rate) or d.s_warehouse or force:
basic_rate = flt(get_incoming_rate(args), self.precision("basic_rate", d))
if basic_rate > 0:
d.basic_rate = basic_rate
d.basic_amount = flt(flt(d.transfer_qty) * flt(d.basic_rate), d.precision("basic_amount"))
if not d.t_warehouse:
raw_material_cost += flt(d.basic_amount)
self.set_basic_rate_for_finished_goods(raw_material_cost)
def set_basic_rate_for_finished_goods(self, raw_material_cost):
if self.purpose in ["Manufacture", "Repack"]:
number_of_fg_items = len([t.t_warehouse for t in self.get("items") if t.t_warehouse])
for d in self.get("items"):
if d.bom_no or (d.t_warehouse and number_of_fg_items == 1):
d.basic_rate = flt(raw_material_cost / flt(d.transfer_qty), d.precision("basic_rate"))
d.basic_amount = flt(raw_material_cost, d.precision("basic_amount"))
def distribute_additional_costs(self):
if self.purpose == "Material Issue":
self.additional_costs = []
self.total_additional_costs = sum([flt(t.amount) for t in self.get("additional_costs")])
total_basic_amount = sum([flt(t.basic_amount) for t in self.get("items") if t.t_warehouse])
for d in self.get("items"):
if d.t_warehouse and total_basic_amount:
d.additional_cost = (flt(d.basic_amount) / total_basic_amount) * self.total_additional_costs
else:
d.additional_cost = 0
def update_valuation_rate(self):
for d in self.get("items"):
d.amount = flt(d.basic_amount + flt(d.additional_cost), d.precision("amount"))
d.valuation_rate = flt(flt(d.basic_rate) + flt(d.additional_cost) / flt(d.transfer_qty),
d.precision("valuation_rate"))
def validate_valuation_rate(self):
if self.purpose in ["Manufacture", "Repack"]:
@@ -224,100 +308,22 @@ class StockEntry(StockController):
valuation_at_target += flt(d.amount)
if valuation_at_target + 0.001 < valuation_at_source:
frappe.throw(_("Total valuation ({0}) for manufactured or repacked item(s) can not be less than total valuation of raw materials ({1})").format(valuation_at_target,
valuation_at_source))
frappe.throw(_("Total valuation ({0}) for manufactured or repacked item(s) can not be less than total valuation of raw materials ({1})")
.format(valuation_at_target, valuation_at_source))
def set_total_incoming_outgoing_value(self):
self.total_incoming_value = self.total_outgoing_value = 0.0
for d in self.get("items"):
if d.s_warehouse:
self.total_incoming_value += flt(d.amount)
if d.t_warehouse:
self.total_incoming_value += flt(d.amount)
if d.s_warehouse:
self.total_outgoing_value += flt(d.amount)
self.value_difference = self.total_outgoing_value - self.total_incoming_value
self.value_difference = self.total_incoming_value - self.total_outgoing_value
def set_total_amount(self):
self.total_amount = sum([flt(item.amount) for item in self.get("items")])
def get_stock_and_rate(self, force=False):
"""get stock and incoming rate on posting date"""
raw_material_cost = 0.0
if not self.posting_date or not self.posting_time:
frappe.throw(_("Posting date and posting time is mandatory"))
allow_negative_stock = cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock"))
for d in self.get('items'):
d.transfer_qty = flt(d.transfer_qty)
args = frappe._dict({
"item_code": d.item_code,
"warehouse": d.s_warehouse or d.t_warehouse,
"posting_date": self.posting_date,
"posting_time": self.posting_time,
"qty": d.s_warehouse and -1*d.transfer_qty or d.transfer_qty,
"serial_no": d.serial_no,
})
# get actual stock at source warehouse
d.actual_qty = get_previous_sle(args).get("qty_after_transaction") or 0
# validate qty during submit
if d.docstatus==1 and d.s_warehouse and not allow_negative_stock and d.actual_qty < d.transfer_qty:
frappe.throw(_("""Row {0}: Qty not avalable in warehouse {1} on {2} {3}.
Available Qty: {4}, Transfer Qty: {5}""").format(d.idx, d.s_warehouse,
self.posting_date, self.posting_time, d.actual_qty, d.transfer_qty), NegativeStockError)
# get incoming rate
if not d.bom_no:
if not flt(d.incoming_rate) or d.s_warehouse or force:
incoming_rate = flt(get_incoming_rate(args), self.precision("incoming_rate", d))
if incoming_rate > 0:
d.incoming_rate = incoming_rate
d.amount = flt(flt(d.transfer_qty) * flt(d.incoming_rate), d.precision("amount"))
if not d.t_warehouse:
raw_material_cost += flt(d.amount)
self.add_operation_cost(raw_material_cost, force)
def add_operation_cost(self, raw_material_cost, force):
"""Adds operating cost if Production Order is set"""
# set incoming rate for fg item
if self.purpose in ["Manufacture", "Repack"]:
number_of_fg_items = len([t.t_warehouse for t in self.get("items") if t.t_warehouse])
for d in self.get("items"):
if d.bom_no or (d.t_warehouse and number_of_fg_items == 1):
operation_cost_per_unit = self.get_operation_cost_per_unit(d.bom_no, d.qty)
d.incoming_rate = operation_cost_per_unit + (raw_material_cost / flt(d.transfer_qty))
d.amount = flt(flt(d.transfer_qty) * flt(d.incoming_rate), self.precision("transfer_qty", d))
break
def get_operation_cost_per_unit(self, bom_no, qty):
"""Returns operating cost from Production Order for given `bom_no`"""
operation_cost_per_unit = 0
if self.production_order:
if not getattr(self, "pro_doc", None):
self.pro_doc = frappe.get_doc("Production Order", self.production_order)
for d in self.pro_doc.get("operations"):
if flt(d.completed_qty):
operation_cost_per_unit += flt(d.actual_operating_cost) / flt(d.completed_qty)
else:
operation_cost_per_unit += flt(d.planned_operating_cost) / flt(self.pro_doc.qty)
# set operating cost from BOM if specified.
if not operation_cost_per_unit and bom_no:
bom = frappe.db.get_value("BOM", bom_no, ["operating_cost", "quantity"], as_dict=1)
operation_cost_per_unit = flt(bom.operating_cost) / flt(bom.quantity)
return operation_cost_per_unit + (flt(self.additional_operating_cost) / flt(qty))
def validate_purchase_order(self):
"""Throw exception if more raw material is transferred against Purchase Order than in
the raw materials supplied table"""
@@ -366,7 +372,7 @@ class StockEntry(StockController):
def update_stock_ledger(self):
sl_entries = []
for d in self.get('items'):
for d in self.get('items'):
if cstr(d.s_warehouse) and self.docstatus == 1:
sl_entries.append(self.get_sl_entries(d, {
"warehouse": cstr(d.s_warehouse),
@@ -378,7 +384,7 @@ class StockEntry(StockController):
sl_entries.append(self.get_sl_entries(d, {
"warehouse": cstr(d.t_warehouse),
"actual_qty": flt(d.transfer_qty),
"incoming_rate": flt(d.incoming_rate)
"incoming_rate": flt(d.valuation_rate)
}))
# On cancellation, make stock ledger entry for
@@ -392,6 +398,32 @@ class StockEntry(StockController):
}))
self.make_sl_entries(sl_entries, self.amended_from and 'Yes' or 'No')
def get_gl_entries(self, warehouse_account):
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
gl_entries = super(StockEntry, self).get_gl_entries(warehouse_account)
for d in self.get("items"):
additional_cost = flt(d.additional_cost, d.precision("additional_cost"))
if additional_cost:
gl_entries.append(self.get_gl_dict({
"account": expenses_included_in_valuation,
"against": d.expense_account,
"cost_center": d.cost_center,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"credit": additional_cost
}))
gl_entries.append(self.get_gl_dict({
"account": d.expense_account,
"against": expenses_included_in_valuation,
"cost_center": d.cost_center,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"credit": -1 * additional_cost # put it as negative credit instead of debit purposefully
}))
return gl_entries
def update_production_order(self):
def _validate_production_order(pro_doc):
@@ -442,7 +474,7 @@ class StockEntry(StockController):
'conversion_factor' : 1,
'batch_no' : '',
'actual_qty' : 0,
'incoming_rate' : 0
'basic_rate' : 0
}
for d in [["Account", "expense_account", "default_expense_account"],
["Cost Center", "cost_center", "cost_center"]]:
@@ -490,13 +522,16 @@ class StockEntry(StockController):
ret = {
"actual_qty" : get_previous_sle(args).get("qty_after_transaction") or 0,
"incoming_rate" : get_incoming_rate(args)
"basic_rate" : get_incoming_rate(args)
}
return ret
def get_items(self):
self.set('items', [])
self.validate_production_order()
if not self.posting_date or not self.posting_time:
frappe.throw(_("Posting date and posting time is mandatory"))
if not getattr(self, "pro_doc", None):
self.pro_doc = None
@@ -520,6 +555,12 @@ class StockEntry(StockController):
if self.to_warehouse and self.pro_doc:
for item in item_dict.values():
item["to_warehouse"] = self.pro_doc.wip_warehouse
self.add_to_stock_entry_detail(item_dict)
elif self.production_order and self.purpose == "Manufacture" and \
frappe.db.get_single_value("Manufacturing Settings", "backflush_raw_materials_based_on")== "Material Transferred for Manufacture":
self.get_transfered_raw_materials()
else:
if not self.fg_completed_qty:
frappe.throw(_("Manufacturing Quantity is mandatory"))
@@ -530,15 +571,14 @@ class StockEntry(StockController):
item["from_warehouse"] = self.pro_doc.wip_warehouse
item["to_warehouse"] = self.to_warehouse if self.purpose=="Subcontract" else ""
# add raw materials to Stock Entry Detail table
self.add_to_stock_entry_detail(item_dict)
self.add_to_stock_entry_detail(item_dict)
# add finished goods item
if self.purpose in ("Manufacture", "Repack"):
self.load_items_from_bom()
self.get_stock_and_rate()
self.set_actual_qty()
self.calculate_rate_and_amount()
def load_items_from_bom(self):
if self.production_order:
@@ -568,12 +608,70 @@ class StockEntry(StockController):
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
# item dict = { item_code: {qty, description, stock_uom} }
item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=qty, fetch_exploded = self.use_multi_level_bom)
item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=qty,
fetch_exploded = self.use_multi_level_bom)
for item in item_dict.values():
item.from_warehouse = self.from_warehouse or item.default_warehouse
return item_dict
def get_transfered_raw_materials(self):
transferred_materials = frappe.db.sql("""
select
item_name, item_code, sum(qty) as qty, sed.t_warehouse as warehouse,
description, stock_uom, expense_account, cost_center
from `tabStock Entry` se,`tabStock Entry Detail` sed
where
se.name = sed.parent and se.docstatus=1 and se.purpose='Material Transfer for Manufacture'
and se.production_order= %s and ifnull(sed.t_warehouse, '') != ''
group by sed.item_code, sed.t_warehouse
""", self.production_order, as_dict=1)
materials_already_backflushed = frappe.db.sql("""
select
item_code, sed.s_warehouse as warehouse, sum(qty) as qty
from
`tabStock Entry` se, `tabStock Entry Detail` sed
where
se.name = sed.parent and se.docstatus=1 and se.purpose='Manufacture'
and se.production_order= %s and ifnull(sed.s_warehouse, '') != ''
group by sed.item_code, sed.s_warehouse
""", self.production_order, as_dict=1)
backflushed_materials= {}
for d in materials_already_backflushed:
backflushed_materials.setdefault(d.item_code,[]).append({d.warehouse: d.qty})
po_qty = frappe.db.sql("""select qty, produced_qty, material_transferred_for_manufacturing from
`tabProduction Order` where name=%s""", self.production_order, as_dict=1)[0]
manufacturing_qty = flt(po_qty.qty)
produced_qty = flt(po_qty.produced_qty)
trans_qty = flt(po_qty.material_transferred_for_manufacturing)
for item in transferred_materials:
qty= item.qty
if manufacturing_qty > (produced_qty + flt(self.fg_completed_qty)):
qty = (qty/trans_qty) * flt(self.fg_completed_qty)
elif backflushed_materials.get(item.item_code):
for d in backflushed_materials.get(item.item_code):
if d.get(item.warehouse):
qty-= d.get(item.warehouse)
if qty > 0:
self.add_to_stock_entry_detail({
item.item_code: {
"from_warehouse": item.warehouse,
"to_warehouse": "",
"qty": qty,
"item_name": item.item_name,
"description": item.description,
"stock_uom": item.stock_uom,
"expense_account": item.expense_account,
"cost_center": item.buying_cost_center,
}
})
def get_pending_raw_materials(self):
"""
@@ -639,7 +737,7 @@ class StockEntry(StockController):
se_child.s_warehouse = self.from_warehouse
if se_child.t_warehouse==None:
se_child.t_warehouse = self.to_warehouse
# in stock uom
se_child.transfer_qty = flt(item_dict[d]["qty"])
se_child.conversion_factor = 1.00
@@ -667,12 +765,56 @@ class StockEntry(StockController):
if getdate(self.posting_date) > getdate(expiry_date):
frappe.throw(_("Batch {0} of Item {1} has expired.").format(item.batch_no, item.item_code))
@frappe.whitelist()
def get_production_order_details(production_order):
res = frappe.db.sql("""select bom_no, use_multi_level_bom, wip_warehouse,
ifnull(qty, 0) - ifnull(produced_qty, 0) as fg_completed_qty,
(ifnull(additional_operating_cost, 0) / qty)*(ifnull(qty, 0) - ifnull(produced_qty, 0)) as additional_operating_cost
from `tabProduction Order` where name = %s""", production_order, as_dict=1)
return res and res[0] or {}
production_order = frappe.get_doc("Production Order", production_order)
pending_qty_to_produce = flt(production_order.qty) - flt(production_order.produced_qty)
return {
"from_bom": 1,
"bom_no": production_order.bom_no,
"use_multi_level_bom": production_order.use_multi_level_bom,
"wip_warehouse": production_order.wip_warehouse,
"fg_warehouse": production_order.fg_warehouse,
"fg_completed_qty": pending_qty_to_produce,
"additional_costs": get_additional_costs(production_order, fg_qty=pending_qty_to_produce)
}
def get_additional_costs(production_order=None, bom_no=None, fg_qty=None):
additional_costs = []
operating_cost_per_unit = get_operating_cost_per_unit(production_order, bom_no)
if operating_cost_per_unit:
additional_costs.append({
"description": "Operating Cost as per Production Order / BOM",
"amount": operating_cost_per_unit * flt(fg_qty)
})
if production_order and production_order.additional_operating_cost:
additional_operating_cost_per_unit = \
flt(production_order.additional_operating_cost) / flt(production_order.qty)
additional_costs.append({
"description": "Additional Operating Cost",
"amount": additional_operating_cost_per_unit * flt(fg_qty)
})
return additional_costs
def get_operating_cost_per_unit(production_order=None, bom_no=None):
operating_cost_per_unit = 0
if production_order:
if not bom_no:
bom_no = production_order.bom_no
for d in production_order.get("operations"):
if flt(d.completed_qty):
operating_cost_per_unit += flt(d.actual_operating_cost) / flt(d.completed_qty)
else:
operating_cost_per_unit += flt(d.planned_operating_cost) / flt(production_order.qty)
# Get operating cost from BOM if not found in production_order.
if not operating_cost_per_unit and bom_no:
bom = frappe.db.get_value("BOM", bom_no, ["operating_cost", "quantity"], as_dict=1)
operating_cost_per_unit = flt(bom.operating_cost) / flt(bom.quantity)
return operating_cost_per_unit

View File

@@ -8,7 +8,7 @@
"cost_center": "_Test Cost Center - _TC",
"doctype": "Stock Entry Detail",
"expense_account": "Stock Adjustment - _TC",
"incoming_rate": 100,
"basic_rate": 100,
"item_code": "_Test Item",
"parentfield": "items",
"qty": 50.0,
@@ -32,7 +32,7 @@
"cost_center": "_Test Cost Center - _TC",
"doctype": "Stock Entry Detail",
"expense_account": "Stock Adjustment - _TC",
"incoming_rate": 100,
"basic_rate": 100,
"item_code": "_Test Item",
"parentfield": "items",
"qty": 40.0,
@@ -57,7 +57,7 @@
"cost_center": "_Test Cost Center - _TC",
"doctype": "Stock Entry Detail",
"expense_account": "Stock Adjustment - _TC",
"incoming_rate": 100,
"basic_rate": 100,
"item_code": "_Test Item",
"parentfield": "items",
"qty": 45.0,
@@ -83,7 +83,7 @@
"cost_center": "_Test Cost Center - _TC",
"doctype": "Stock Entry Detail",
"expense_account": "Stock Adjustment - _TC",
"incoming_rate": 100,
"basic_rate": 100,
"item_code": "_Test Item",
"parentfield": "items",
"qty": 50.0,
@@ -97,7 +97,7 @@
"cost_center": "_Test Cost Center - _TC",
"doctype": "Stock Entry Detail",
"expense_account": "Stock Adjustment - _TC",
"incoming_rate": 5000,
"basic_rate": 5000,
"item_code": "_Test Item Home Desktop 100",
"parentfield": "items",
"qty": 1,

View File

@@ -36,12 +36,12 @@ class TestStockEntry(unittest.TestCase):
create_stock_reconciliation(item_code="_Test Item 2", warehouse="_Test Warehouse - _TC",
qty=0, rate=100)
make_stock_entry(item_code=item_code, target=warehouse, qty=1, incoming_rate=10)
make_stock_entry(item_code=item_code, target=warehouse, qty=1, basic_rate=10)
sle = get_sle(item_code = item_code, warehouse = warehouse)[0]
self.assertEqual([[1, 10]], eval(sle.stock_queue))
# negative qty
make_stock_entry(item_code=item_code, source=warehouse, qty=2, incoming_rate=10)
make_stock_entry(item_code=item_code, source=warehouse, qty=2, basic_rate=10)
sle = get_sle(item_code = item_code, warehouse = warehouse)[0]
self.assertEqual([[-1, 10]], eval(sle.stock_queue))
@@ -53,12 +53,12 @@ class TestStockEntry(unittest.TestCase):
self.assertEqual([[-2, 10]], eval(sle.stock_queue))
# move stock to positive
make_stock_entry(item_code=item_code, target=warehouse, qty=3, incoming_rate=20)
make_stock_entry(item_code=item_code, target=warehouse, qty=3, basic_rate=20)
sle = get_sle(item_code = item_code, warehouse = warehouse)[0]
self.assertEqual([[1, 20]], eval(sle.stock_queue))
# incoming entry with diff rate
make_stock_entry(item_code=item_code, target=warehouse, qty=1, incoming_rate=30)
make_stock_entry(item_code=item_code, target=warehouse, qty=1, basic_rate=30)
sle = get_sle(item_code = item_code, warehouse = warehouse)[0]
self.assertEqual([[1, 20],[1, 30]], eval(sle.stock_queue))
@@ -125,7 +125,7 @@ class TestStockEntry(unittest.TestCase):
set_perpetual_inventory()
mr = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
qty=50, incoming_rate=100)
qty=50, basic_rate=100)
stock_in_hand_account = frappe.db.get_value("Account", {"account_type": "Warehouse",
"warehouse": mr.get("items")[0].t_warehouse})
@@ -152,7 +152,7 @@ class TestStockEntry(unittest.TestCase):
set_perpetual_inventory()
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
qty=50, incoming_rate=100)
qty=50, basic_rate=100)
mi = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC", qty=40)
@@ -217,9 +217,9 @@ class TestStockEntry(unittest.TestCase):
def test_repack_no_change_in_valuation(self):
set_perpetual_inventory(0)
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, incoming_rate=100)
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100)
make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC",
qty=50, incoming_rate=100)
qty=50, basic_rate=100)
repack = frappe.copy_doc(test_records[3])
repack.posting_date = nowdate()
@@ -238,15 +238,24 @@ class TestStockEntry(unittest.TestCase):
set_perpetual_inventory(0)
def test_repack_with_change_in_valuation(self):
def test_repack_with_additional_costs(self):
set_perpetual_inventory()
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, incoming_rate=100)
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100)
repack = frappe.copy_doc(test_records[3])
repack.posting_date = nowdate()
repack.posting_time = nowtime()
repack.additional_operating_cost = 1000.0
repack.set("additional_costs", [
{
"description": "Actual Oerating Cost",
"amount": 1000
},
{
"description": "additional operating costs",
"amount": 200
},
])
repack.insert()
repack.submit()
@@ -260,11 +269,13 @@ class TestStockEntry(unittest.TestCase):
"voucher_no": repack.name, "item_code": "_Test Item Home Desktop 100"}, "stock_value_difference"))
stock_value_diff = flt(fg_stock_value_diff - rm_stock_value_diff, 2)
self.assertEqual(stock_value_diff, 1200)
self.check_gl_entries("Stock Entry", repack.name,
sorted([
[stock_in_hand_account, stock_value_diff, 0.0],
["Stock Adjustment - _TC", 0.0, stock_value_diff],
[stock_in_hand_account, 1200, 0.0],
["Expenses Included In Valuation - _TC", 0.0, 1200.0]
])
)
set_perpetual_inventory(0)
@@ -291,10 +302,9 @@ class TestStockEntry(unittest.TestCase):
gl_entries = frappe.db.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type=%s and voucher_no=%s
order by account asc, debit asc""", (voucher_type, voucher_no), as_list=1)
self.assertTrue(gl_entries)
gl_entries.sort(key=lambda x: x[0])
for i, gle in enumerate(gl_entries):
self.assertEquals(expected_gl_entries[i][0], gle[0])
self.assertEquals(expected_gl_entries[i][1], gle[1])
@@ -503,6 +513,8 @@ class TestStockEntry(unittest.TestCase):
frappe.db.set_value("Stock Settings", None, "stock_frozen_upto_days", 0)
def test_production_order(self):
from erpnext.manufacturing.doctype.production_order.production_order \
import make_stock_entry as _make_stock_entry
bom_no, bom_operation_cost = frappe.db.get_value("BOM", {"item": "_Test FG Item 2",
"is_default": 1, "docstatus": 1}, ["name", "operating_cost"])
@@ -514,22 +526,15 @@ class TestStockEntry(unittest.TestCase):
"bom_no": bom_no,
"qty": 1.0,
"stock_uom": "_Test UOM",
"wip_warehouse": "_Test Warehouse - _TC"
"wip_warehouse": "_Test Warehouse - _TC",
"additional_operating_cost": 1000
})
production_order.insert()
production_order.submit()
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, incoming_rate=100)
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100)
stock_entry = frappe.new_doc("Stock Entry")
stock_entry.update({
"purpose": "Manufacture",
"production_order": production_order.name,
"bom_no": bom_no,
"fg_completed_qty": "1",
"additional_operating_cost": 1000
})
stock_entry.get_items()
stock_entry = _make_stock_entry(production_order.name, "Manufacture", 1)
rm_cost = 0
for d in stock_entry.get("items"):
@@ -538,7 +543,7 @@ class TestStockEntry(unittest.TestCase):
fg_cost = filter(lambda x: x.item_code=="_Test FG Item 2", stock_entry.get("items"))[0].amount
self.assertEqual(fg_cost,
flt(rm_cost + bom_operation_cost + stock_entry.additional_operating_cost, 2))
flt(rm_cost + bom_operation_cost + production_order.additional_operating_cost, 2))
def test_variant_production_order(self):
@@ -610,7 +615,7 @@ def make_stock_entry(**args):
"s_warehouse": args.from_warehouse or args.source,
"t_warehouse": args.to_warehouse or args.target,
"qty": args.qty,
"incoming_rate": args.incoming_rate,
"basic_rate": args.basic_rate,
"expense_account": args.expense_account or "Stock Adjustment - _TC",
"conversion_factor": 1.0,
"cost_center": "_Test Cost Center - _TC"

View File

@@ -1,25 +1,58 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "hash",
"creation": "2013-03-29 18:22:12",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"allow_on_submit": 0,
"fieldname": "barcode",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Barcode",
"no_copy": 0,
"permlevel": 0,
"precision": ""
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "section_break_2",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"precision": ""
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "s_warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 1,
"in_list_view": 1,
"label": "Source Warehouse",
@@ -28,16 +61,38 @@
"oldfieldtype": "Link",
"options": "Warehouse",
"permlevel": 0,
"read_only": 0
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "col_break1",
"fieldtype": "Column Break",
"permlevel": 0
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "t_warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 1,
"in_list_view": 1,
"label": "Target Warehouse",
@@ -46,240 +101,631 @@
"oldfieldtype": "Link",
"options": "Warehouse",
"permlevel": 0,
"read_only": 0
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "sec_break1",
"fieldtype": "Section Break",
"permlevel": 0
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "item_code",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 1,
"in_list_view": 1,
"label": "Item Code",
"no_copy": 0,
"oldfieldname": "item_code",
"oldfieldtype": "Link",
"options": "Item",
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "col_break2",
"fieldtype": "Column Break",
"permlevel": 0
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Qty",
"no_copy": 0,
"oldfieldname": "qty",
"oldfieldtype": "Currency",
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"reqd": 1
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"precision": ""
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "item_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Item Name",
"no_copy": 0,
"permlevel": 0,
"print_hide": 1,
"read_only": 1
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "description",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Description",
"no_copy": 0,
"oldfieldname": "description",
"oldfieldtype": "Text",
"permlevel": 0,
"print_hide": 0,
"print_width": "300px",
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "300px"
},
{
"allow_on_submit": 0,
"fieldname": "column_break_10",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"precision": ""
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "image",
"fieldtype": "Attach",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Image",
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1
"print_hide": 1,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "image_view",
"fieldtype": "Image",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Image View",
"no_copy": 0,
"options": "image",
"permlevel": 0,
"precision": ""
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "quantity_and_rate",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Quantity and Rate",
"permlevel": 0
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"fieldname": "incoming_rate",
"allow_on_submit": 0,
"fieldname": "basic_rate",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Valuation Rate",
"label": "Basic Rate (as per Stock UOM)",
"no_copy": 0,
"oldfieldname": "incoming_rate",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 1,
"read_only": 0,
"reqd": 0
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "basic_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Basic Amount",
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "additional_cost",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Additional Cost",
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Amount",
"no_copy": 0,
"oldfieldname": "amount",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0,
"read_only": 1
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "valuation_rate",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Valuation Rate",
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "col_break3",
"fieldtype": "Column Break",
"permlevel": 0
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "uom",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "UOM",
"no_copy": 0,
"oldfieldname": "uom",
"oldfieldtype": "Link",
"options": "UOM",
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"reqd": 1
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "conversion_factor",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Conversion Factor",
"no_copy": 0,
"oldfieldname": "conversion_factor",
"oldfieldtype": "Currency",
"permlevel": 0,
"print_hide": 1,
"read_only": 1,
"reqd": 1
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "stock_uom",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Stock UOM",
"no_copy": 0,
"oldfieldname": "stock_uom",
"oldfieldtype": "Link",
"options": "UOM",
"permlevel": 0,
"print_hide": 1,
"read_only": 1,
"report_hide": 0,
"reqd": 1,
"search_index": 0
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "transfer_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Qty as per Stock UOM",
"no_copy": 0,
"oldfieldname": "transfer_qty",
"oldfieldtype": "Currency",
"permlevel": 0,
"print_hide": 1,
"read_only": 1,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "serial_no_batch",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Serial No / Batch",
"permlevel": 0
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "serial_no",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Serial No",
"no_copy": 1,
"oldfieldname": "serial_no",
"oldfieldtype": "Text",
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"reqd": 0
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "col_break4",
"fieldtype": "Column Break",
"permlevel": 0
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "batch_no",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Batch No",
"no_copy": 0,
"oldfieldname": "batch_no",
"oldfieldtype": "Link",
"options": "Batch",
"permlevel": 0,
"print_hide": 0,
"read_only": 0
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "accounting",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Accounting",
"permlevel": 0
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
"fieldname": "expense_account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Difference Account",
"no_copy": 0,
"options": "Account",
"permlevel": 0,
"print_hide": 1
"print_hide": 1,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "col_break5",
"fieldtype": "Column Break",
"permlevel": 0
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"default": ":Company",
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
"fieldname": "cost_center",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Cost Center",
"no_copy": 0,
"options": "Cost Center",
"permlevel": 0,
"print_hide": 1,
"read_only": 0,
"reqd": 0
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "More Info",
"permlevel": 0
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"fieldname": "actual_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 1,
"in_list_view": 0,
"label": "Actual Qty (at source/target)",
"no_copy": 1,
"oldfieldname": "actual_qty",
@@ -287,67 +733,107 @@
"permlevel": 0,
"print_hide": 1,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 1
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"description": "BOM No. for a Finished Good Item",
"fieldname": "bom_no",
"fieldtype": "Link",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "BOM No",
"no_copy": 0,
"options": "BOM",
"permlevel": 0,
"print_hide": 1,
"read_only": 0
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "col_break6",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "transfer_qty",
"fieldtype": "Float",
"label": "Qty as per Stock UOM",
"oldfieldname": "transfer_qty",
"oldfieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 1,
"read_only": 1,
"reqd": 1
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"description": "Material Request used to make this Stock Entry",
"fieldname": "material_request",
"fieldtype": "Link",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Material Request",
"no_copy": 1,
"options": "Material Request",
"permlevel": 0,
"print_hide": 1,
"read_only": 1
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "material_request_item",
"fieldtype": "Link",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Material Request Item",
"no_copy": 1,
"options": "Material Request Item",
"permlevel": 0,
"print_hide": 1,
"read_only": 1
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"modified": "2015-07-02 05:32:56.511570",
"modified": "2015-08-07 13:21:23.840052",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Entry Detail",
"owner": "Administrator",
"permissions": []
"permissions": [],
"read_only": 0,
"read_only_onload": 0
}

View File

@@ -82,13 +82,13 @@ class TestStockReconciliation(unittest.TestCase):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
make_stock_entry(posting_date="2012-12-15", posting_time="02:00", item_code="_Test Item",
target="_Test Warehouse - _TC", qty=10, incoming_rate=700)
target="_Test Warehouse - _TC", qty=10, basic_rate=700)
make_stock_entry(posting_date="2012-12-25", posting_time="03:00", item_code="_Test Item",
source="_Test Warehouse - _TC", qty=15)
make_stock_entry(posting_date="2013-01-05", posting_time="07:00", item_code="_Test Item",
target="_Test Warehouse - _TC", qty=15, incoming_rate=1200)
target="_Test Warehouse - _TC", qty=15, basic_rate=1200)
def create_stock_reconciliation(**args):
args = frappe._dict(args)

View File

@@ -10,6 +10,28 @@ from frappe import _
from frappe.model.document import Document
class StockUOMReplaceUtility(Document):
# Update Stock UOM
def update_stock_uom(self):
self.validate_item()
self.validate_mandatory()
self.validate_uom_integer_type()
update_stock_ledger_entry(self.item_code, self.new_stock_uom, self.conversion_factor)
update_bin(self.item_code, self.new_stock_uom, self.conversion_factor)
update_item_master(self.item_code, self.new_stock_uom, self.conversion_factor)
#if item is template change UOM for all associated variants
if frappe.db.get_value("Item", self.item_code, "has_variants"):
for d in frappe.db.get_all("Item", filters= {"variant_of": self.item_code}):
update_stock_ledger_entry(d.name, self.new_stock_uom, self.conversion_factor)
update_bin(d.name, self.new_stock_uom, self.conversion_factor)
update_item_master(d.name, self.new_stock_uom, self.conversion_factor)
def validate_item(self):
if frappe.db.get_value("Item", self.item_code, "variant_of"):
frappe.throw(_("You cannot change default UOM of Variant. To change default UOM for Variant change default UOM of the Template"))
def validate_mandatory(self):
if not cstr(self.item_code):
frappe.throw(_("Item is required"))
@@ -27,72 +49,7 @@ class StockUOMReplaceUtility(Document):
stock_uom = frappe.db.get_value("Item", self.item_code, "stock_uom")
if cstr(self.new_stock_uom) == cstr(stock_uom):
frappe.throw(_("Item is updated"))
def update_item_master(self):
item_doc = frappe.get_doc("Item", self.item_code)
item_doc.stock_uom = self.new_stock_uom
item_doc.save()
frappe.msgprint(_("Stock UOM updated for Item {0}").format(self.item_code))
def update_bin(self):
# update bin
if flt(self.conversion_factor) != flt(1):
frappe.db.sql("""update `tabBin`
set stock_uom = %s,
indented_qty = ifnull(indented_qty,0) * %s,
ordered_qty = ifnull(ordered_qty,0) * %s,
reserved_qty = ifnull(reserved_qty,0) * %s,
planned_qty = ifnull(planned_qty,0) * %s,
projected_qty = actual_qty + ordered_qty + indented_qty +
planned_qty - reserved_qty
where item_code = %s""", (self.new_stock_uom, self.conversion_factor,
self.conversion_factor, self.conversion_factor,
self.conversion_factor, self.item_code))
else:
frappe.db.sql("update `tabBin` set stock_uom = %s where item_code = %s",
(self.new_stock_uom, self.item_code) )
# acknowledge user
frappe.msgprint(_("Stock balances updated"))
def update_stock_ledger_entry(self):
# update stock ledger entry
from erpnext.stock.stock_ledger import update_entries_after
if flt(self.conversion_factor) != flt(1):
frappe.db.sql("""update `tabStock Ledger Entry`
set stock_uom = %s, actual_qty = ifnull(actual_qty,0) * %s
where item_code = %s""",
(self.new_stock_uom, self.conversion_factor, self.item_code))
else:
frappe.db.sql("""update `tabStock Ledger Entry` set stock_uom=%s
where item_code=%s""", (self.new_stock_uom, self.item_code))
# acknowledge user
frappe.msgprint(_("Stock Ledger entries balances updated"))
# update item valuation
if flt(self.conversion_factor) != flt(1):
wh = frappe.db.sql("select name from `tabWarehouse`")
for w in wh:
update_entries_after({"item_code": self.item_code, "warehouse": w[0]})
# acknowledge user
frappe.msgprint(_("Item valuation updated"))
# Update Stock UOM
def update_stock_uom(self):
self.validate_mandatory()
self.validate_uom_integer_type()
self.update_stock_ledger_entry()
self.update_bin()
self.update_item_master()
def validate_uom_integer_type(self):
current_is_integer = frappe.db.get_value("UOM", self.current_stock_uom, "must_be_whole_number")
new_is_integer = frappe.db.get_value("UOM", self.new_stock_uom, "must_be_whole_number")
@@ -103,6 +60,53 @@ class StockUOMReplaceUtility(Document):
if current_is_integer and new_is_integer and cint(self.conversion_factor)!=self.conversion_factor:
frappe.throw(_("Conversion factor cannot be in fractions"))
def update_item_master(item_code, new_stock_uom, conversion_factor):
frappe.db.set_value("Item", item_code, "stock_uom", new_stock_uom)
frappe.msgprint(_("Stock UOM updated for Item {0}").format(item_code))
def update_bin(item_code, new_stock_uom, conversion_factor):
# update bin
if flt(conversion_factor) != flt(1):
frappe.db.sql("""update `tabBin`
set stock_uom = %s,
indented_qty = ifnull(indented_qty,0) * %s,
ordered_qty = ifnull(ordered_qty,0) * %s,
reserved_qty = ifnull(reserved_qty,0) * %s,
planned_qty = ifnull(planned_qty,0) * %s,
projected_qty = actual_qty + ordered_qty + indented_qty +
planned_qty - reserved_qty
where item_code = %s""", (new_stock_uom, conversion_factor,
conversion_factor, conversion_factor,
conversion_factor, item_code))
else:
frappe.db.sql("update `tabBin` set stock_uom = %s where item_code = %s",
(new_stock_uom, item_code) )
def update_stock_ledger_entry(item_code, new_stock_uom, conversion_factor):
# update stock ledger entry
from erpnext.stock.stock_ledger import update_entries_after
if flt(conversion_factor) != flt(1):
frappe.db.sql("""update `tabStock Ledger Entry`
set stock_uom = %s, actual_qty = ifnull(actual_qty,0) * %s
where item_code = %s""",
(new_stock_uom, conversion_factor, item_code))
else:
frappe.db.sql("""update `tabStock Ledger Entry` set stock_uom=%s
where item_code=%s""", (new_stock_uom, item_code))
# acknowledge user
frappe.msgprint(_("Stock Ledger entries balances updated"))
# update item valuation
if flt(conversion_factor) != flt(1):
wh = frappe.db.sql("select name from `tabWarehouse`")
for w in wh:
update_entries_after({"item_code": item_code, "warehouse": w[0]})
# acknowledge user
frappe.msgprint(_("Item valuation updated"))
@frappe.whitelist()
def get_stock_uom(item_code):
return { 'current_stock_uom': cstr(frappe.db.get_value('Item', item_code, 'stock_uom')) }

View File

@@ -401,7 +401,6 @@ def apply_price_list_on_item(args):
item_details = frappe._dict()
item_doc = frappe.get_doc("Item", args.item_code)
get_price_list_rate(args, item_doc, item_details)
item_details.discount_percentage = 0.0
item_details.update(get_pricing_rule_for_item(args))
return item_details

View File

@@ -300,22 +300,21 @@ class update_entries_after(object):
# select first batch or the batch with same rate
batch = self.stock_queue[index]
if batch[0]:
if qty_to_pop >= batch[0]:
# consume current batch
qty_to_pop = qty_to_pop - batch[0]
self.stock_queue.pop(index)
if not self.stock_queue and qty_to_pop:
# stock finished, qty still remains to be withdrawn
# negative stock, keep in as a negative batch
self.stock_queue.append([-qty_to_pop, outgoing_rate or batch[1]])
break
if qty_to_pop >= batch[0]:
# consume current batch
qty_to_pop = qty_to_pop - batch[0]
self.stock_queue.pop(index)
if not self.stock_queue and qty_to_pop:
# stock finished, qty still remains to be withdrawn
# negative stock, keep in as a negative batch
self.stock_queue.append([-qty_to_pop, outgoing_rate or batch[1]])
break
else:
# qty found in current batch
# consume it and exit
batch[0] = batch[0] - qty_to_pop
qty_to_pop = 0
else:
# qty found in current batch
# consume it and exit
batch[0] = batch[0] - qty_to_pop
qty_to_pop = 0
stock_value = sum((flt(batch[0]) * flt(batch[1]) for batch in self.stock_queue))
stock_qty = sum((flt(batch[0]) for batch in self.stock_queue))

View File

@@ -133,20 +133,19 @@ def get_fifo_rate(previous_stock_queue, qty):
qty_to_pop = abs(qty)
while qty_to_pop and previous_stock_queue:
batch = previous_stock_queue[0]
if batch[0]:
if 0 < batch[0] <= qty_to_pop:
# if batch qty > 0
# not enough or exactly same qty in current batch, clear batch
available_qty_for_outgoing += flt(batch[0])
outgoing_cost += flt(batch[0]) * flt(batch[1])
qty_to_pop -= batch[0]
previous_stock_queue.pop(0)
else:
# all from current batch
available_qty_for_outgoing += flt(qty_to_pop)
outgoing_cost += flt(qty_to_pop) * flt(batch[1])
batch[0] -= qty_to_pop
qty_to_pop = 0
if 0 < batch[0] <= qty_to_pop:
# if batch qty > 0
# not enough or exactly same qty in current batch, clear batch
available_qty_for_outgoing += flt(batch[0])
outgoing_cost += flt(batch[0]) * flt(batch[1])
qty_to_pop -= batch[0]
previous_stock_queue.pop(0)
else:
# all from current batch
available_qty_for_outgoing += flt(qty_to_pop)
outgoing_cost += flt(qty_to_pop) * flt(batch[1])
batch[0] -= qty_to_pop
qty_to_pop = 0
return outgoing_cost / available_qty_for_outgoing

View File

@@ -1,6 +1,6 @@
{% var visible_columns = row.get_visible_columns(["item_code",
"item_name", "amount", "stock_uom", "uom", "qty",
"s_warehouse", "t_warehouse", "incoming_rate"]);
"s_warehouse", "t_warehouse", "valuation_rate"]);
%}
{% if(!doc) { %}
@@ -43,7 +43,7 @@
<div class="col-sm-2 col-xs-2 text-right">
{%= doc.get_formatted("amount") %}
<div class="small text-muted">
{%= doc.get_formatted("incoming_rate") %}
{%= doc.get_formatted("valuation_rate") %}
</div>
</div>
</div>

View File

@@ -33,7 +33,7 @@ def get_product_list(search=None, start=0, limit=10):
for d in data:
d.route = ((d.parent_website_route + "/") if d.parent_website_route else "") \
+ d.page_name
+ (d.page_name or "")
return [get_item_for_list_in_html(r) for r in data]

View File

@@ -255,7 +255,7 @@ apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +122,Row {0
apps/erpnext/erpnext/stock/utils.py +174,Warehouse {0} does not belong to company {1},Almacén {0} no pertenece a la empresa {1}
DocType: Bulk Email,Message,Mensaje
DocType: Item Website Specification,Item Website Specification,Artículo Website Especificación
DocType: Backup Manager,Dropbox Access Key,Clave de Acceso de Dropbox
DocType: Backup Manager,Dropbox Access Key,Clave de Acceso de Dropbox
DocType: Payment Tool,Reference No,Referencia
apps/erpnext/erpnext/hr/doctype/leave_application/leave_application.py +349,Leave Blocked,Vacaciones Bloqueadas
apps/erpnext/erpnext/stock/doctype/item/item.py +349,Item {0} has reached its end of life on {1},Artículo {0} ha llegado al término de la vida en {1}
@@ -367,7 +367,7 @@ DocType: Delivery Note,Instructions,Instrucciones
DocType: Quality Inspection,Inspected By,Inspección realizada por
DocType: Maintenance Visit,Maintenance Type,Tipo de Mantenimiento
apps/erpnext/erpnext/selling/doctype/installation_note/installation_note.py +69,Serial No {0} does not belong to Delivery Note {1},Número de orden {0} no pertenece a la nota de entrega {1}
DocType: Item Quality Inspection Parameter,Item Quality Inspection Parameter,Parámetro de Inspección de Calidad del Articulo
DocType: Item Quality Inspection Parameter,Item Quality Inspection Parameter,Parámetro de Inspección de Calidad del Articulo
DocType: Leave Application,Leave Approver Name,Nombre de Supervisor de Vacaciones
,Schedule Date,Horario Fecha
DocType: Packed Item,Packed Item,Artículo Empacado
@@ -433,7 +433,7 @@ DocType: Purchase Taxes and Charges,"If checked, the tax amount will be consider
apps/erpnext/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py +48,Total Qty,Cantidad Total
DocType: Employee,Health Concerns,Preocupaciones de salud
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js +15,Unpaid,No Pagado
DocType: Packing Slip,From Package No.,Del Paquete N º
DocType: Packing Slip,From Package No.,Del Paquete N º
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +29,Securities and Deposits,Valores y Depósitos
DocType: Features Setup,Imports,Importaciones
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +143,Adhesive bonding,Union adhesiva
@@ -504,7 +504,7 @@ DocType: Job Applicant,Thread HTML,Tema HTML
DocType: Company,Ignore,Pasar por Alto
apps/erpnext/erpnext/setup/doctype/sms_settings/sms_settings.py +86,SMS sent to following numbers: {0},SMS enviado a los teléfonos: {0}
DocType: Backup Manager,Enter Verification Code,Instroduzca el Código de Verificación
apps/erpnext/erpnext/controllers/buying_controller.py +135,Supplier Warehouse mandatory for sub-contracted Purchase Receipt,Almacén de Proveedor es necesario para recibos de compras sub contratadas
apps/erpnext/erpnext/controllers/buying_controller.py +135,Supplier Warehouse mandatory for sub-contracted Purchase Receipt,Almacén de Proveedor es necesario para recibos de compras sub contratadas
DocType: Pricing Rule,Valid From,Válido desde
DocType: Sales Invoice,Total Commission,Total Comisión
DocType: Pricing Rule,Sales Partner,Socio de Ventas
@@ -683,7 +683,7 @@ The tax rate you define here will be the standard tax rate for all **Items**. If
#### Description of Columns
1. Calculation Type:
1. Calculation Type:
- This can be on **Net Total** (that is the sum of basic amount).
- **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.
- **Actual** (as mentioned).
@@ -694,19 +694,19 @@ The tax rate you define here will be the standard tax rate for all **Items**. If
6. Amount: Tax amount.
7. Total: Cumulative total to this point.
8. Enter Row: If based on ""Previous Row Total"" you can select the row number which will be taken as a base for this calculation (default is the previous row).
9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.","Plantilla de gravamen que puede aplicarse a todas las transacciones de venta. Esta plantilla puede contener lista de cabezas de impuestos y también otros jefes de gastos / ingresos como ""envío"", ""Seguros"", ""Manejo"", etc.
9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.","Plantilla de gravamen que puede aplicarse a todas las transacciones de venta. Esta plantilla puede contener lista de cabezas de impuestos y también otros jefes de gastos / ingresos como ""envío"", ""Seguros"", ""Manejo"", etc.
#### Nota
#### Nota
La tasa de impuesto que definir aquí será el tipo impositivo general para todos los artículos ** **. Si hay ** ** Los artículos que tienen diferentes tasas, deben ser añadidos en el Impuesto ** ** Artículo mesa en el Artículo ** ** maestro.
#### Descripción de las Columnas
#### Descripción de las Columnas
1. Tipo de Cálculo:
1. Tipo de Cálculo:
- Esto puede ser en ** Neto Total ** (que es la suma de la cantidad básica).
- ** En Fila Anterior total / importe ** (por impuestos o cargos acumulados). Si selecciona esta opción, el impuesto se aplica como un porcentaje de la fila anterior (en la tabla de impuestos) Cantidad o total.
- Actual ** ** (como se ha mencionado).
2. Cuenta Cabeza: El libro mayor de cuentas en las que se reservó este impuesto
2. Cuenta Cabeza: El libro mayor de cuentas en las que se reservó este impuesto
3. Centro de Costo: Si el impuesto / carga es un ingreso (como el envío) o gasto en que debe ser reservado en contra de un centro de costos.
4. Descripción: Descripción del impuesto (que se imprimirán en facturas / comillas).
5. Rate: Tasa de impuesto.
@@ -888,7 +888,7 @@ apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.js +492,Upload your le
apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +156,White,Blanco
DocType: SMS Center,All Lead (Open),Todas las Oportunidades (Abiertas)
DocType: Purchase Invoice,Get Advances Paid,Cómo anticipos pagados
apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.js +362,Attach Your Picture,Adjunte su Fotografía
apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.js +362,Attach Your Picture,Adjunte su Fotografía
DocType: Journal Entry,Total Amount in Words,Importe Total con Letras
DocType: Workflow State,Stop,Deténgase
apps/erpnext/erpnext/setup/doctype/email_digest/email_digest.js +7,There was an error. One probable reason could be that you haven't saved the form. Please contact support@erpnext.com if the problem persists.,"Ha ocurrido un error . Una razón probable podría ser que usted no ha guardado el formulario. Por favor, póngase en contacto con support@erpnext.com si el problema persiste."
@@ -975,7 +975,7 @@ DocType: Journal Entry,Make Difference Entry,Hacer Entrada de Diferencia
DocType: Upload Attendance,Attendance From Date,Asistencia De Fecha
DocType: Appraisal Template Goal,Key Performance Area,Área Clave de Rendimiento
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/industry_type.py +53,Transportation,Transporte
DocType: SMS Center,Total Characters,Total Caracteres
DocType: SMS Center,Total Characters,Total Caracteres
apps/erpnext/erpnext/controllers/buying_controller.py +139,Please select BOM in BOM field for Item {0},"Por favor, seleccione la Solicitud de Materiales en el campo de Solicitud de Materiales para el punto {0}"
DocType: C-Form Invoice Detail,C-Form Invoice Detail,Detalle C -Form Factura
DocType: Payment Reconciliation Invoice,Payment Reconciliation Invoice,Factura Reconciliación Pago
@@ -1018,7 +1018,7 @@ apps/erpnext/erpnext/stock/utils.py +167,{0} valid serial nos for Item {1},{0} N
apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py +58,Item Code cannot be changed for Serial No.,Código del Artículo no se puede cambiar de Número de Serie
apps/erpnext/erpnext/accounts/doctype/pos_profile/pos_profile.py +23,POS Profile {0} already created for user: {1} and company {2},POS Perfil {0} ya creado para el usuario: {1} y compañía {2}
DocType: Purchase Order Item,UOM Conversion Factor,Factor de Conversión de Unidad de Medida
DocType: Stock Settings,Default Item Group,Grupo de artículos predeterminado
DocType: Stock Settings,Default Item Group,Grupo de artículos predeterminado
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +155,Laminated object manufacturing,Fabricación de objetos laminado
apps/erpnext/erpnext/config/buying.py +13,Supplier database.,Base de datos de proveedores.
DocType: Account,Balance Sheet,Hoja de Balance
@@ -1042,7 +1042,7 @@ DocType: Event,Saturday,Sábado
DocType: Leave Control Panel,Leave blank if considered for all branches,Dejar en blanco si se considera para todas las ramas
,Daily Time Log Summary,Resumen Diario de Registro de Hora
DocType: DocField,Label,Etiqueta
DocType: Payment Reconciliation,Unreconciled Payment Details,Detalles de Pago No Conciliadas
DocType: Payment Reconciliation,Unreconciled Payment Details,Detalles de Pago No Conciliadas
DocType: Global Defaults,Current Fiscal Year,Año Fiscal Actual
DocType: Global Defaults,Disable Rounded Total,Desactivar Total Redondeado
DocType: Lead,Call,Llamada
@@ -1064,7 +1064,7 @@ DocType: Sales Order,Delivery Status,Estado del Envío
DocType: Production Order,Manufacture against Sales Order,Fabricación contra Pedido de Ventas
apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.py +496,Rest Of The World,Resto del mundo
apps/erpnext/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +79,The Item {0} cannot have Batch,El artículo {0} no puede tener lotes
,Budget Variance Report,Informe de Varianza en el Presupuesto
,Budget Variance Report,Informe de Varianza en el Presupuesto
DocType: Salary Slip,Gross Pay,Pago bruto
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +186,Dividends Paid,Dividendos pagados
DocType: Stock Reconciliation,Difference Amount,Diferencia
@@ -1116,7 +1116,7 @@ apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.js +611,Your Products
DocType: Mode of Payment,Mode of Payment,Modo de Pago
apps/erpnext/erpnext/setup/doctype/item_group/item_group.js +31,This is a root item group and cannot be edited.,Se trata de un grupo de elementos raíz y no se puede editar .
DocType: Purchase Invoice Item,Purchase Order,Orden de Compra
DocType: Warehouse,Warehouse Contact Info,Información de Contacto del Almacén
DocType: Warehouse,Warehouse Contact Info,Información de Contacto del Almacén
sites/assets/js/form.min.js +182,Name is required,El nombre es necesario
DocType: Purchase Invoice,Recurring Type,Tipo Recurrente
DocType: Address,City/Town,Ciudad/Provincia
@@ -1127,7 +1127,7 @@ apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +416,Delive
apps/erpnext/erpnext/stock/get_item_details.py +136,Item {0} must be a Sub-contracted Item,Artículo {0} debe ser un artículo subcontratada
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +41,Capital Equipments,Equipos de Capitales
apps/erpnext/erpnext/accounts/doctype/pricing_rule/pricing_rule.js +31,"Pricing Rule is first selected based on 'Apply On' field, which can be Item, Item Group or Brand.","Regla precios se selecciona por primera vez basado en 'Aplicar On' de campo, que puede ser elemento, elemento de grupo o Marca."
DocType: Hub Settings,Seller Website,Sitio Web Vendedor
DocType: Hub Settings,Seller Website,Sitio Web Vendedor
apps/erpnext/erpnext/controllers/selling_controller.py +147,Total allocated percentage for sales team should be 100,Porcentaje del total asignado para el equipo de ventas debe ser de 100
apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order.py +108,Production Order status is {0},Estado de la orden de producción es de {0}
DocType: Appraisal Goal,Goal,Meta/Objetivo
@@ -1163,7 +1163,7 @@ DocType: BOM Operation,Workstation,Puesto de Trabajo
apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +112,Hardware,Hardware
DocType: Attendance,HR Manager,Gerente de Recursos Humanos
apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +50,Privilege Leave,Permiso con Privilegio
DocType: Purchase Invoice,Supplier Invoice Date,Fecha de la Factura de Proveedor
DocType: Purchase Invoice,Supplier Invoice Date,Fecha de la Factura de Proveedor
apps/erpnext/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py +169,You need to enable Shopping Cart,Necesita habilitar Carito de Compras
sites/assets/js/form.min.js +200,No Data,No hay datos
DocType: Appraisal Template Goal,Appraisal Template Goal,Objetivo Plantilla de Evaluación
@@ -1354,7 +1354,7 @@ DocType: Quality Inspection Reading,Reading 4,Lectura 4
apps/erpnext/erpnext/config/hr.py +23,Claims for company expense.,Peticiones para gastos de empresa.
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +7,Centrifugal casting,La fundición centrífuga
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +118,Magnetic field-assisted finishing,Acabado asistida por campo magnético
DocType: Company,Default Holiday List,Lista de vacaciones Por Defecto
DocType: Company,Default Holiday List,Lista de vacaciones Por Defecto
apps/erpnext/erpnext/projects/doctype/time_log/time_log.py +229,Task is Mandatory if Time Log is against a project,Tarea es obligatoria si Hora de registro está en contra de un proyecto
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +165,Stock Liabilities,Inventario de Pasivos
DocType: Purchase Receipt,Supplier Warehouse,Almacén Proveedor
@@ -1374,7 +1374,7 @@ apps/erpnext/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sa
sites/assets/js/erpnext.min.js +49,{0} View,{0} Ver
DocType: Salary Structure Deduction,Salary Structure Deduction,Estructura Salarial Deducción
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +157,Selective laser sintering,Sinterización selectiva por láser
apps/erpnext/erpnext/stock/doctype/item/item.py +153,Unit of Measure {0} has been entered more than once in Conversion Factor Table,Unidad de Medida {0} se ha introducido más de una vez en la Tabla de Factores de Conversión
apps/erpnext/erpnext/stock/doctype/item/item.py +153,Unit of Measure {0} has been entered more than once in Conversion Factor Table,Unidad de Medida {0} se ha introducido más de una vez en la Tabla de Factores de Conversión
apps/frappe/frappe/core/page/data_import_tool/data_import_tool.js +83,Import Successful!,¡Importación Exitosa!
apps/erpnext/erpnext/projects/report/project_wise_stock_tracking/project_wise_stock_tracking.py +27,Cost of Issued Items,Costo de Artículos Emitidas
DocType: Email Digest,Expenses Booked,gastos Reservados
@@ -1408,7 +1408,7 @@ apps/erpnext/erpnext/accounts/doctype/payment_tool/payment_tool.js +189,Row {0}:
DocType: Expense Claim,Total Amount Reimbursed,Monto total reembolsado
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +151,Press fitting,Press apropiado
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +63,Against Supplier Invoice {0} dated {1},Contra Factura de Proveedor {0} con fecha{1}
DocType: Selling Settings,Default Price List,Lista de precios Por defecto
DocType: Selling Settings,Default Price List,Lista de precios Por defecto
DocType: Journal Entry,User Remark will be added to Auto Remark,Observación usuario se añadirá a Observación Auto
DocType: Payment Reconciliation,Payments,Pagos
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +23,Hot isostatic pressing,Prensado isostático en caliente
@@ -1442,7 +1442,7 @@ apps/erpnext/erpnext/stock/get_item_details.py +122,Item {0} must be a Service I
apps/erpnext/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +158,Please select item code,"Por favor, seleccione el código del artículo"
DocType: Salary Structure Deduction,Reduce Deduction for Leave Without Pay (LWP),Reducir Deducción por Licencia sin Sueldo ( LWP )
DocType: Territory,Territory Manager,Gerente de Territorio
DocType: Selling Settings,Selling Settings,Configuración de Ventas
DocType: Selling Settings,Selling Settings,Configuración de Ventas
apps/erpnext/erpnext/stock/doctype/manage_variants/manage_variants.py +68,Item cannot be a variant of a variant,El Artículo no puede ser una variante de una variante
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/industry_type.py +38,Online Auctions,Subastas en Línea
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +94,Please specify either Quantity or Valuation Rate or both,Por favor especificar Cantidad o valoración de tipo o ambos
@@ -1647,7 +1647,7 @@ apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +492,
apps/erpnext/erpnext/accounts/party.py +152,Please select company first.,Por favor seleccione la empresa en primer lugar.
DocType: Activity Cost,Costing Rate,Costeo Rate
DocType: Journal Entry Account,Against Journal Entry,Contra la Entrada de Diario
DocType: Employee,Resignation Letter Date,Fecha de Carta de Renuncia
DocType: Employee,Resignation Letter Date,Fecha de Carta de Renuncia
apps/erpnext/erpnext/accounts/doctype/pricing_rule/pricing_rule.js +37,Pricing Rules are further filtered based on quantity.,Reglas de de precios también se filtran en base a la cantidad.
apps/erpnext/erpnext/buying/page/purchase_analytics/purchase_analytics.js +137,Not Set,No Especificado
DocType: Communication,Date,Fecha
@@ -2025,7 +2025,7 @@ DocType: Item,Will also apply for variants unless overrridden,También se aplica
DocType: Purchase Invoice,Advances,Anticipos
apps/erpnext/erpnext/setup/doctype/authorization_rule/authorization_rule.py +32,Approving User cannot be same as user the rule is Applicable To,El usuario que aprueba no puede ser igual que el usuario para el que la regla es aplicable
DocType: SMS Log,No of Requested SMS,No. de SMS solicitados
DocType: Campaign,Campaign-.####,Campaña-.####
DocType: Campaign,Campaign-.####,Campaña-.####
apps/erpnext/erpnext/buying/doctype/purchase_order/purchase_order.js +480,Make Invoice,Hacer Factura
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +54,Piercing,Perforación
DocType: Customer,Your Customer's TAX registration numbers (if applicable) or any general information,Los números de registro de impuestos de su cliente ( si es aplicable) o cualquier información de carácter general
@@ -2046,7 +2046,7 @@ The tax rate you define here will be the standard tax rate for all **Items**. If
#### Description of Columns
1. Calculation Type:
1. Calculation Type:
- This can be on **Net Total** (that is the sum of basic amount).
- **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.
- **Actual** (as mentioned).
@@ -2058,19 +2058,19 @@ The tax rate you define here will be the standard tax rate for all **Items**. If
7. Total: Cumulative total to this point.
8. Enter Row: If based on ""Previous Row Total"" you can select the row number which will be taken as a base for this calculation (default is the previous row).
9. Consider Tax or Charge for: In this section you can specify if the tax / charge is only for valuation (not a part of total) or only for total (does not add value to the item) or for both.
10. Add or Deduct: Whether you want to add or deduct the tax.","Plantilla de gravamen que puede aplicarse a todas las operaciones de compra. Esta plantilla puede contener lista de cabezas de impuestos y también otros jefes de gastos como ""envío"", ""Seguros"", ""Manejo"", etc.
10. Add or Deduct: Whether you want to add or deduct the tax.","Plantilla de gravamen que puede aplicarse a todas las operaciones de compra. Esta plantilla puede contener lista de cabezas de impuestos y también otros jefes de gastos como ""envío"", ""Seguros"", ""Manejo"", etc.
#### Nota
#### Nota
El tipo impositivo se define aquí será el tipo de gravamen general para todos los artículos ** **. Si hay ** ** Los artículos que tienen diferentes tasas, deben ser añadidos en el Impuesto ** ** Artículo mesa en el Artículo ** ** maestro.
#### Descripción de las Columnas
#### Descripción de las Columnas
1. Tipo de Cálculo:
1. Tipo de Cálculo:
- Esto puede ser en ** Neto Total ** (que es la suma de la cantidad básica).
- ** En Fila Anterior total / importe ** (por impuestos o cargos acumulados). Si selecciona esta opción, el impuesto se aplica como un porcentaje de la fila anterior (en la tabla de impuestos) Cantidad o total.
- Actual ** ** (como se ha mencionado).
2. Cuenta Cabeza: El libro mayor de cuentas en las que se reservó este impuesto
2. Cuenta Cabeza: El libro mayor de cuentas en las que se reservó este impuesto
3. Centro de Costo: Si el impuesto / carga es un ingreso (como el envío) o gasto en que debe ser reservado en contra de un centro de costos.
4. Descripción: Descripción del impuesto (que se imprimirán en facturas / comillas).
5. Rate: Tasa de impuesto.
@@ -2252,7 +2252,7 @@ Examples:
1. Ways of addressing disputes, indemnity, liability, etc.
1. Address and Contact of your Company.","Términos y Condiciones que se pueden agregar a compras y ventas estándar.
Ejemplos:
Ejemplos:
1. Validez de la oferta.
1. Condiciones de pago (por adelantado, el crédito, parte antelación etc).
@@ -2261,7 +2261,7 @@ Examples:
1. Garantía si los hay.
1. Política de las vueltas.
1. Términos de envío, si aplica.
1. Formas de disputas que abordan, indemnización, responsabilidad, etc.
1. Formas de disputas que abordan, indemnización, responsabilidad, etc.
1. Dirección y contacto de su empresa."
DocType: Attendance,Leave Type,Tipo de Vacaciones
apps/erpnext/erpnext/controllers/stock_controller.py +173,Expense / Difference account ({0}) must be a 'Profit or Loss' account,"Cuenta de gastos / Diferencia ({0}) debe ser una cuenta de 'utilidad o pérdida """
@@ -2535,7 +2535,7 @@ apps/erpnext/erpnext/manufacturing/doctype/bom/bom.js +18,Browse BOM,Navegar por
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +175,Secured Loans,Préstamos Garantizados
apps/erpnext/erpnext/utilities/doctype/rename_tool/rename_tool.py +49,Ignored:,Ignorado:
apps/erpnext/erpnext/shopping_cart/__init__.py +68,{0} cannot be purchased using Shopping Cart,{0} no se puede comprar con el carrito
apps/erpnext/erpnext/setup/page/setup_wizard/data/sample_home_page.html +3,Awesome Products,Productos Increíbles
apps/erpnext/erpnext/setup/page/setup_wizard/data/sample_home_page.html +3,Awesome Products,Productos Increíbles
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +189,Opening Balance Equity,Saldo inicial Equidad
apps/erpnext/erpnext/hr/doctype/leave_application/leave_application.py +80,Cannot approve leave as you are not authorized to approve leaves on Block Dates,"No se puede permitir la aprobación, ya que no está autorizado para aprobar sobre fechas bloqueadas"
DocType: Appraisal,Appraisal,Evaluación
@@ -2655,7 +2655,7 @@ apps/erpnext/erpnext/config/manufacturing.py +34,Where manufacturing operations
DocType: Page,All,Todos
DocType: Stock Entry Detail,Source Warehouse,fuente de depósito
DocType: Installation Note,Installation Date,Fecha de Instalación
DocType: Employee,Confirmation Date,Fecha Confirmación
DocType: Employee,Confirmation Date,Fecha Confirmación
DocType: C-Form,Total Invoiced Amount,Total Facturado
DocType: Communication,Sales User,Usuario de Ventas
apps/erpnext/erpnext/accounts/doctype/pricing_rule/pricing_rule.py +46,Min Qty can not be greater than Max Qty,Qty del minuto no puede ser mayor que Max Und
@@ -2672,7 +2672,7 @@ DocType: Sales Invoice,Against Income Account,Contra la Cuenta de Utilidad
apps/erpnext/erpnext/controllers/website_list_for_contact.py +52,{0}% Delivered,{0}% Entregado
apps/erpnext/erpnext/buying/doctype/purchase_order/purchase_order.py +82,Item {0}: Ordered qty {1} cannot be less than minimum order qty {2} (defined in Item).,Artículo {0}: Cantidad ordenada {1} no puede ser menor que el qty pedido mínimo {2} (definido en el artículo).
DocType: Monthly Distribution Percentage,Monthly Distribution Percentage,Distribución Mensual Porcentual
DocType: Territory,Territory Targets,Territorios Objetivos
DocType: Territory,Territory Targets,Territorios Objetivos
DocType: Delivery Note,Transporter Info,Información de Transportista
DocType: Purchase Order Item Supplied,Purchase Order Item Supplied,Orden de Compra del Artículo Suministrado
apps/erpnext/erpnext/config/setup.py +27,Letter Heads for print templates.,Membretes para las plantillas de impresión.
@@ -2784,7 +2784,7 @@ apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +78,Decamber
apps/erpnext/erpnext/setup/doctype/company/company.js +22,Please re-type company name to confirm,"Por favor, vuelva a escribir nombre de la empresa para confirmar"
apps/erpnext/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +70,Total Outstanding Amt,Monto Total Soprepasado
DocType: Time Log Batch,Total Hours,Total de Horas
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +265,Total Debit must be equal to Total Credit. The difference is {0},El total de Débitos debe ser igual al total de Créditos. La diferencia es {0}
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +265,Total Debit must be equal to Total Credit. The difference is {0},El total de Débitos debe ser igual al total de Créditos. La diferencia es {0}
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/industry_type.py +10,Automotive,Automotor
apps/erpnext/erpnext/hr/doctype/leave_allocation/leave_allocation.py +37,Leaves for type {0} already allocated for Employee {1} for Fiscal Year {0},Vacaciones para el tipo {0} ya asignado para Empleado {1} para el Año Fiscal {0}
apps/erpnext/erpnext/stock/doctype/stock_uom_replace_utility/stock_uom_replace_utility.py +15,Item is required,Articulo es requerido
@@ -2906,7 +2906,7 @@ DocType: BOM Replace Tool,The new BOM after replacement,La nueva Solicitud de Ma
DocType: Features Setup,Point of Sale,Punto de Venta
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +82,Curling,Curling
DocType: Account,Tax,Impuesto
apps/erpnext/erpnext/accounts/doctype/payment_tool/payment_tool.py +34,Row {0}: {1} is not a valid {2},Fila {0}: {1} no es un {2} válido
apps/erpnext/erpnext/accounts/doctype/payment_tool/payment_tool.py +34,Row {0}: {1} is not a valid {2},Fila {0}: {1} no es un {2} válido
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +88,Refining,Refinación
DocType: Production Planning Tool,Production Planning Tool,Herramienta de Planificación de la producción
DocType: Quality Inspection,Report Date,Fecha del Informe
@@ -2921,7 +2921,7 @@ apps/erpnext/erpnext/config/support.py +28,Visit report for maintenance call.,In
DocType: Stock Settings,Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units.,"Porcentaje que se les permite recibir o entregar más en contra de la cantidad pedida . Por ejemplo : Si se ha pedido 100 unidades. y el subsidio es de 10 %, entonces se le permite recibir 110 unidades."
DocType: Pricing Rule,Customer Group,Grupo de Clientes
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +156,Expense account is mandatory for item {0},Cuenta de gastos es obligatorio para el elemento {0}
DocType: Item,Website Description,Descripción del Sitio Web
DocType: Item,Website Description,Descripción del Sitio Web
DocType: Serial No,AMC Expiry Date,AMC Fecha de caducidad
,Sales Register,Resitro de Ventas
DocType: Quotation,Quotation Lost Reason,Cotización Pérdida Razón
@@ -2955,7 +2955,7 @@ DocType: Project,Expected End Date,Fecha de finalización prevista
DocType: Appraisal Template,Appraisal Template Title,Titulo de la Plantilla deEvaluación
apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.py +419,Commercial,Comercial
DocType: Cost Center,Distribution Id,Id Distribución
apps/erpnext/erpnext/setup/page/setup_wizard/data/sample_home_page.html +14,Awesome Services,Servicios Impresionantes
apps/erpnext/erpnext/setup/page/setup_wizard/data/sample_home_page.html +14,Awesome Services,Servicios Impresionantes
apps/erpnext/erpnext/config/manufacturing.py +29,All Products or Services.,Todos los Productos o Servicios .
DocType: Purchase Invoice,Supplier Address,Dirección del proveedor
DocType: Contact Us Settings,Address Line 2,Dirección Línea 2
@@ -2969,7 +2969,7 @@ apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/industry_type.py +27,Finan
DocType: Opportunity,Sales,Venta
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.py +155,Warehouse required for stock Item {0},Almacén requerido para la acción del artículo {0}
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.js +87,Cr,Cr
DocType: Customer,Default Receivable Accounts,Cuentas por Cobrar Por Defecto
DocType: Customer,Default Receivable Accounts,Cuentas por Cobrar Por Defecto
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +101,Sawing,Serrar
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +31,Laminating,Laminación
DocType: Item Reorder,Transfer,Transferencia
@@ -3011,7 +3011,7 @@ apps/erpnext/erpnext/accounts/page/accounts_browser/accounts_browser.js +212,Opt
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +104,Negative Valuation Rate is not allowed,Negativo valoración de tipo no está permitida
DocType: Holiday List,Weekly Off,Semanal Desactivado
DocType: Fiscal Year,"For e.g. 2012, 2012-13","Por ejemplo, 2012 , 2012-13"
apps/erpnext/erpnext/accounts/report/balance_sheet/balance_sheet.py +32,Provisional Profit / Loss (Credit),Beneficio / Pérdida (Crédito) Provisional
apps/erpnext/erpnext/accounts/report/balance_sheet/balance_sheet.py +32,Provisional Profit / Loss (Credit),Beneficio / Pérdida (Crédito) Provisional
DocType: Sales Invoice,Return Against Sales Invoice,Regreso Contra Ventas Factura
apps/erpnext/erpnext/stock/report/bom_search/bom_search.js +32,Item 5,Tema 5
apps/erpnext/erpnext/accounts/utils.py +243,Please set default value {0} in Company {1},"Por favor, establece el valor por defecto {0} en la empresa {1}"
@@ -3029,9 +3029,9 @@ DocType: Sales Team,Contact No.,Contacto No.
apps/erpnext/erpnext/accounts/doctype/gl_entry/gl_entry.py +64,'Profit and Loss' type account {0} not allowed in Opening Entry,"""Pérdidas y Ganancias "" tipo de cuenta {0} no se permite en la Entrada de Apertura"
DocType: Workflow State,Time,Tiempo
DocType: Features Setup,Sales Discounts,Descuentos sobre Ventas
DocType: Hub Settings,Seller Country,País del Vendedor
DocType: Hub Settings,Seller Country,País del Vendedor
DocType: Authorization Rule,Authorization Rule,Regla de Autorización
DocType: Sales Invoice,Terms and Conditions Details,Detalle de Términos y Condiciones
DocType: Sales Invoice,Terms and Conditions Details,Detalle de Términos y Condiciones
apps/erpnext/erpnext/templates/generators/item.html +52,Specifications,Especificaciones
DocType: Sales Taxes and Charges Template,Sales Taxes and Charges Template,Impuestos y cargos de venta de plantilla
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/industry_type.py +9,Apparel & Accessories,Ropa y Accesorios
@@ -3120,7 +3120,7 @@ apps/erpnext/erpnext/crm/doctype/newsletter/newsletter.py +135,Thank you for you
,Qty to Transfer,Cantidad a Transferir
apps/erpnext/erpnext/config/selling.py +18,Quotes to Leads or Customers.,Cotizaciones a Oportunidades o Clientes
DocType: Stock Settings,Role Allowed to edit frozen stock,Función Permitida para editar Inventario Congelado
,Territory Target Variance Item Group-Wise,Variación de Grupo por Territorio Objetivo
,Territory Target Variance Item Group-Wise,Variación de Grupo por Territorio Objetivo
apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +101,All Customer Groups,Todos los Grupos de Clientes
apps/erpnext/erpnext/controllers/accounts_controller.py +399,{0} is mandatory. Maybe Currency Exchange record is not created for {1} to {2}.,{0} es obligatorio. Tal vez no se ha creado registro para el Tipo de Cambio {1} a {2}.
apps/erpnext/erpnext/accounts/doctype/account/account.py +37,Account {0}: Parent account {1} does not exist,Cuenta {0}: Cuenta Padre {1} no existe
@@ -3157,7 +3157,7 @@ apps/erpnext/erpnext/selling/report/territory_target_variance_item_group_wise/te
DocType: Accounts Settings,"If enabled, the system will post accounting entries for inventory automatically.","Si está habilitado, el sistema contabiliza los asientos contables para el inventario de forma automática."
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/industry_type.py +14,Brokerage,Brokerage
DocType: Production Order Operation,"in Minutes
Updated via 'Time Log'","en minutos
Updated via 'Time Log'","en minutos
Actualizado a través de 'Hora de registro'"
DocType: Customer,From Lead,De la iniciativa
apps/erpnext/erpnext/config/manufacturing.py +19,Orders released for production.,Las órdenes publicadas para la producción.
@@ -3306,7 +3306,7 @@ apps/erpnext/erpnext/buying/doctype/purchase_common/purchase_common.py +45,Pleas
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +35,Warning: Sales Order {0} already exists against same Purchase Order number,Advertencia: Orden de Venta {0} ya existe contra el mismo número de Orden de Compra
DocType: Employee External Work History,Employee External Work History,Historial de Trabajo Externo del Empleado
DocType: Notification Control,Purchase,Compra
apps/erpnext/erpnext/buying/doctype/purchase_order/purchase_order.py +178,Status of {0} {1} is now {2},Situación de {0} {1} { 2 es ahora }
apps/erpnext/erpnext/buying/doctype/purchase_order/purchase_order.py +178,Status of {0} {1} is now {2},Situación de {0} {1} es ahora {2}
apps/erpnext/erpnext/stock/report/stock_ledger/stock_ledger.py +34,Balance Qty,Cantidad en Balance
DocType: Item Group,Parent Item Group,Grupo Principal de Artículos
apps/erpnext/erpnext/projects/doctype/activity_cost/activity_cost.py +21,{0} for {1},{0} de {1}
@@ -3329,7 +3329,7 @@ apps/erpnext/erpnext/selling/page/sales_browser/sales_browser.js +118,New {0} Na
apps/erpnext/erpnext/controllers/recurring_document.py +128,Please find attached {0} #{1},Encuentre {0} # adjunto {1}
DocType: Job Applicant,Applicant Name,Nombre del Solicitante
DocType: Authorization Rule,Customer / Item Name,Cliente / Nombre de Artículo
DocType: Product Bundle,"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**.
DocType: Product Bundle,"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**.
The package **Item** will have ""Is Stock Item"" as ""No"" and ""Is Sales Item"" as ""Yes"".
@@ -3473,17 +3473,17 @@ DocType: Address Template,"<h4>Default Template</h4>
{% if phone %}Phone: {{ phone }}&lt;br&gt;{% endif -%}
{% if fax %}Fax: {{ fax }}&lt;br&gt;{% endif -%}
{% if email_id %}Email: {{ email_id }}&lt;br&gt;{% endif -%}
</code></pre>","<H4> Por defecto la plantilla </ h4>
<p> <a Usos href=""http://jinja.pocoo.org/docs/templates/""> Jinja Templating </a> y todos los campos de la Dirección ( incluyendo campos personalizados en su caso) estará disponible </ p>
<pre> <code> {{address_line1}} & lt; br & gt;
{% if address_line2%} {{address_line2}} & lt; br & gt; { endif% -%}
{{ciudad}} & lt; br & gt;
{% if%} Estado {{Estado}} & lt; br & gt; {% endif -%} {% if
código PIN%} PIN: {{código PIN}} & lt; br & gt; {% endif -%}
{{país}} & lt; br & gt;
{% if teléfono%} Teléfono: {{teléfono}} & lt; br & gt; { % endif -%}
{% if fax%} Fax: {{fax}} & lt; br & gt; {% endif -%}
{% if email_ID%} Email: {{email_ID}} & lt; br & gt ; {% endif -%}
</code></pre>","<H4> Por defecto la plantilla </ h4>
<p> <a Usos href=""http://jinja.pocoo.org/docs/templates/""> Jinja Templating </a> y todos los campos de la Dirección ( incluyendo campos personalizados en su caso) estará disponible </ p>
<pre> <code> {{address_line1}} & lt; br & gt;
{% if address_line2%} {{address_line2}} & lt; br & gt; { endif% -%}
{{ciudad}} & lt; br & gt;
{% if%} Estado {{Estado}} & lt; br & gt; {% endif -%} {% if
código PIN%} PIN: {{código PIN}} & lt; br & gt; {% endif -%}
{{país}} & lt; br & gt;
{% if teléfono%} Teléfono: {{teléfono}} & lt; br & gt; { % endif -%}
{% if fax%} Fax: {{fax}} & lt; br & gt; {% endif -%}
{% if email_ID%} Email: {{email_ID}} & lt; br & gt ; {% endif -%}
</ code> </ pre>"
DocType: Salary Slip Deduction,Default Amount,Importe por Defecto
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +89,Warehouse not found in the system,Almacén no se encuentra en el sistema
@@ -3664,7 +3664,7 @@ DocType: Sales Invoice,Existing Customer,Cliente Existente
DocType: Email Digest,Receivables,Cuentas por Cobrar
DocType: Quality Inspection Reading,Reading 5,Lectura 5
DocType: Purchase Order,"Enter email id separated by commas, order will be mailed automatically on particular date","Ingrese correo electrónico de identificación separadas por comas, la orden será enviada automáticamente en una fecha particular"
apps/erpnext/erpnext/crm/doctype/lead/lead.py +37,Campaign Name is required,Es necesario ingresar el nombre de la Campaña
apps/erpnext/erpnext/crm/doctype/lead/lead.py +37,Campaign Name is required,Es necesario ingresar el nombre de la Campaña
DocType: Maintenance Visit,Maintenance Date,Fecha de Mantenimiento
DocType: Purchase Receipt Item,Rejected Serial No,Rechazado Serie No
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +50,Deep drawing,Embutición profunda
@@ -3672,7 +3672,7 @@ apps/erpnext/erpnext/crm/doctype/newsletter_list/newsletter_list.js +40,New News
apps/erpnext/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +167,Start date should be less than end date for Item {0},La fecha de inicio debe ser menor que la fecha de finalización para el punto {0}
apps/erpnext/erpnext/stock/doctype/item/item.js +13,Show Balance,Mostrar Equilibrio
DocType: Item,"Example: ABCD.#####
If series is set and Serial No is not mentioned in transactions, then automatic serial number will be created based on this series. If you always want to explicitly mention Serial Nos for this item. leave this blank.","Ejemplo:. ABCD #####
If series is set and Serial No is not mentioned in transactions, then automatic serial number will be created based on this series. If you always want to explicitly mention Serial Nos for this item. leave this blank.","Ejemplo:. ABCD #####
Si la serie se establece y Número de Serie no se menciona en las transacciones, entonces se creara un número de serie automático sobre la base de esta serie. Si siempre quiere mencionar explícitamente los números de serie para este artículo, déjelo en blanco."
DocType: Upload Attendance,Upload Attendance,Subir Asistencia
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.js +107,BOM and Manufacturing Quantity are required,Lista de materiales y de fabricación se requieren Cantidad
@@ -3775,7 +3775,7 @@ apps/erpnext/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +516,Mak
DocType: Bank Reconciliation Detail,Voucher ID,Comprobante ID
apps/erpnext/erpnext/setup/doctype/territory/territory.js +14,This is a root territory and cannot be edited.,Este es un territorio raíz y no se puede editar .
DocType: Packing Slip,Gross Weight UOM,Peso Bruto de la Unidad de Medida
DocType: Email Digest,Receivables / Payables,Cobrables/ Pagables
DocType: Email Digest,Receivables / Payables,Cobrables/ Pagables
DocType: Journal Entry Account,Against Sales Invoice,Contra la Factura de Venta
apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +62,Stamping,Estampado
DocType: Landed Cost Item,Landed Cost Item,Landed Cost artículo
@@ -3972,7 +3972,7 @@ apps/erpnext/erpnext/config/manufacturing.py +120,Bill of Materials,Lista de mat
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +79,Row {0}: Party Type and Party is required for Receivable / Payable account {1},Fila {0}: Partido Tipo y Partido se requiere para la cuenta por cobrar / pagar {1}
DocType: Backup Manager,Send Notifications To,Enviar notificaciones a
apps/erpnext/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html +26,Ref Date,Fecha Ref
DocType: Employee,Reason for Leaving,Razones de Renuncia
DocType: Employee,Reason for Leaving,Razones de Renuncia
DocType: Expense Claim Detail,Sanctioned Amount,importe sancionado
DocType: GL Entry,Is Opening,está abriendo
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +187,Row {0}: Debit entry can not be linked with a {1},Fila {0}: Débito no puede vincularse con {1}
1 DocType: Employee Salary Mode Modo de Salario
255 DocType: Item Website Specification Item Website Specification Artículo Website Especificación
256 DocType: Backup Manager Dropbox Access Key Clave de Acceso de Dropbox Clave de Acceso de Dropbox
257 DocType: Payment Tool Reference No Referencia
258 apps/erpnext/erpnext/hr/doctype/leave_application/leave_application.py +349 Leave Blocked Vacaciones Bloqueadas
259 apps/erpnext/erpnext/stock/doctype/item/item.py +349 Item {0} has reached its end of life on {1} Artículo {0} ha llegado al término de la vida en {1}
260 apps/erpnext/erpnext/accounts/utils.py +306 Annual Anual
261 DocType: Stock Reconciliation Item Stock Reconciliation Item Articulo de Reconciliación de Inventario
367 Schedule Date Horario Fecha
368 DocType: Packed Item Packed Item Artículo Empacado
369 apps/erpnext/erpnext/config/buying.py +54 Default settings for buying transactions. Ajustes por defecto para de las transacciones de compra.
370 apps/erpnext/erpnext/projects/doctype/activity_cost/activity_cost.py +29 Activity Cost exists for Employee {0} against Activity Type - {1} Existe Costo Actividad de Empleado {0} contra el Tipo de Actividad - {1}
371 apps/erpnext/erpnext/accounts/page/accounts_browser/accounts_browser.js +29 Please do NOT create Accounts for Customers and Suppliers. They are created directly from the Customer / Supplier masters. Por favor, NO crear cuentas de clientes y proveedores. Se crean directamente de los maestros de clientes/proveedores.
372 DocType: Currency Exchange Currency Exchange Cambio de Divisas
373 DocType: Purchase Invoice Item Item Name Nombre del Articulo
433 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +143 Adhesive bonding Union adhesiva
434 DocType: Job Opening Description of a Job Opening Descripción de una oferta de trabajo
435 apps/erpnext/erpnext/config/hr.py +28 Attendance record. Registro de Asistencia .
436 DocType: Bank Reconciliation Journal Entries Comprobantes de Diario
437 DocType: Sales Order Item Used for Production Plan Se utiliza para el Plan de Producción
438 DocType: System Settings Loading... Cargando ...
439 DocType: DocField Password Contraseña
504 DocType: Monthly Distribution **Monthly Distribution** helps you distribute your budget across months if you have seasonality in your business. To distribute a budget using this distribution, set this **Monthly Distribution** in the **Cost Center** ** Distribución Mensual ** le ayuda a distribuir su presupuesto a través de meses si tiene periodos en su negocio. Para distribuir un presupuesto utilizando esta distribución, establecer **Distribución Mensual ** en el **Centro de Costos**
505 apps/erpnext/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +172 No records found in the Invoice table No se encontraron registros en la tabla de facturas
506 apps/erpnext/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js +20 Please select Company and Party Type first Por favor, seleccione de la empresa y el Partido Tipo primero
507 apps/erpnext/erpnext/config/accounts.py +84 Financial / accounting year. Ejercicio / contabilidad.
508 apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py +172 Sorry, Serial Nos cannot be merged Lo sentimos , Nos de serie no se puede fusionar
509 DocType: Email Digest New Supplier Quotations Nueva Cotización de Proveedores
510 apps/erpnext/erpnext/selling/doctype/quotation/quotation.js +608 Make Sales Order Hacer Orden de Venta
683 apps/erpnext/erpnext/hr/doctype/expense_claim/expense_claim.py +61 Sanctioned Amount cannot be greater than Claim Amount in Row {0}. Importe sancionado no puede ser mayor que la reclamación Cantidad en la fila {0}.
684 DocType: Company Default Cost of Goods Sold Account Costo por defecto de la cuenta mercancías vendidas
685 apps/erpnext/erpnext/stock/get_item_details.py +237 Price List not selected Lista de precios no seleccionado
686 DocType: Employee Family Background antecedentes familiares
687 DocType: Process Payroll Send Email Enviar Correo Electronico
688 apps/erpnext/erpnext/buying/doctype/supplier/supplier.py +85 No Permission Sin permiso
689 DocType: Company Default Bank Account Cuenta Bancaria por defecto
694 DocType: Bank Reconciliation Detail Bank Reconciliation Detail Detalle de Conciliación Bancaria
695 apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +580 My Invoices Mis Facturas
696 apps/erpnext/erpnext/hr/doctype/leave_control_panel/leave_control_panel.py +39 No employee found Empleado no encontrado
697 DocType: Purchase Order Stopped Detenido
698 DocType: Item If subcontracted to a vendor Si subcontratado a un proveedor
699 apps/erpnext/erpnext/manufacturing/page/bom_browser/bom_browser.js +17 Select BOM to start Seleccione la lista de materiales para comenzar
700 DocType: SMS Center All Customer Contact Todos Contactos de Clientes
701 apps/erpnext/erpnext/config/stock.py +64 Upload stock balance via csv. Sube saldo de existencias a través csv .
702 apps/erpnext/erpnext/setup/doctype/email_digest/email_digest.js +32 Send Now Enviar ahora
703 Support Analytics Analitico de Soporte
704 DocType: Item Website Warehouse Almacén del Sitio Web
705 DocType: Sales Invoice The day of the month on which auto invoice will be generated e.g. 05, 28 etc El día del mes en el que se generará factura automática por ejemplo 05, 28, etc.
706 apps/erpnext/erpnext/hr/doctype/appraisal/appraisal.js +49 Score must be less than or equal to 5 Puntuación debe ser menor o igual a 5
707 apps/erpnext/erpnext/config/accounts.py +164 C-Form records Registros C -Form
708 apps/erpnext/erpnext/config/selling.py +294 Customer and Supplier Clientes y Proveedores
709 DocType: Email Digest Email Digest Settings Configuración del Boletin de Correo Electrónico
710 apps/erpnext/erpnext/config/support.py +13 Support queries from customers. Consultas de soporte de clientes .
711 DocType: Bin Moving Average Rate Porcentaje de Promedio Movil
712 DocType: Production Planning Tool Select Items Seleccione Artículos
888 DocType: Issue Issue Asunto
889 apps/erpnext/erpnext/config/stock.py +141 Attributes for Item Variants. e.g Size, Color etc. Atributos para Elementos variables. por ejemplo, tamaño, color, etc.
890 apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order_calendar.js +30 WIP Warehouse WIP Almacén
891 apps/erpnext/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +204 Serial No {0} is under maintenance contract upto {1} Número de orden {0} tiene un contrato de mantenimiento hasta {1}
892 DocType: BOM Operation Operation Operación
893 DocType: Lead Organization Name Nombre de la Organización
894 apps/erpnext/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +61 Item must be added using 'Get Items from Purchase Receipts' button El artículo debe ser añadido usando 'Obtener elementos de recibos de compra' botón
975 apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +588 Cost Center For Item with Item Code ' Centro de Costos para artículo con Código del artículo '
976 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +44 Stretch forming Formando Stretch
977 DocType: Opportunity Your sales person will get a reminder on this date to contact the customer Su persona de ventas recibirá un aviso con esta fecha para ponerse en contacto con el cliente
978 apps/erpnext/erpnext/accounts/page/accounts_browser/accounts_browser.js +207 Further accounts can be made under Groups, but entries can be made against non-Groups Otras cuentas se pueden organizar dentro de Grupos, pero las entradas solò se pueden hacer contra los que no son de Grupo
979 apps/erpnext/erpnext/config/hr.py +125 Tax and other salary deductions. Impuestos y otras deducciones salariales.
980 DocType: Lead Lead Iniciativa
981 DocType: Email Digest Payables Cuentas por Pagar
1018 DocType: Salary Slip Gross Pay Pago bruto
1019 apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +186 Dividends Paid Dividendos pagados
1020 DocType: Stock Reconciliation Difference Amount Diferencia
1021 apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +192 Retained Earnings Ganancias Retenidas
1022 DocType: Purchase Order Required raw materials issued to the supplier for producing a sub - contracted item. Las materias primas necesarias emitidas al proveedor para la producción de un ítem sub - contratado .
1023 DocType: BOM Item Item Description Descripción del Artículo
1024 DocType: Payment Tool Payment Mode Modo de Pago
1042 Accounts Payable Summary Resumen de Cuentas por Pagar
1043 apps/erpnext/erpnext/accounts/doctype/gl_entry/gl_entry.py +170 Not authorized to edit frozen Account {0} No autorizado para editar la cuenta congelada {0}
1044 DocType: Journal Entry Get Outstanding Invoices Verifique Facturas Pendientes
1045 apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order.py +59 Sales Order {0} is not valid Orden de Venta {0} no es válida
1046 DocType: Email Digest New Stock Entries Comentarios Nuevo archivo
1047 apps/erpnext/erpnext/setup/doctype/company/company.py +169 Sorry, companies cannot be merged Lo sentimos , las empresas no se pueden combinar
1048 apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +145 Small Pequeño
1064 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/industry_type.py +7 Agriculture Agricultura
1065 apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.js +611 Your Products or Services Sus Productos o Servicios
1066 DocType: Mode of Payment Mode of Payment Modo de Pago
1067 apps/erpnext/erpnext/setup/doctype/item_group/item_group.js +31 This is a root item group and cannot be edited. Se trata de un grupo de elementos raíz y no se puede editar .
1068 DocType: Purchase Invoice Item Purchase Order Orden de Compra
1069 DocType: Warehouse Warehouse Contact Info Información de Contacto del Almacén Información de Contacto del Almacén
1070 sites/assets/js/form.min.js +182 Name is required El nombre es necesario
1116 DocType: Purchase Invoice Supplier Invoice Date Fecha de la Factura de Proveedor Fecha de la Factura de Proveedor
1117 apps/erpnext/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py +169 You need to enable Shopping Cart Necesita habilitar Carito de Compras
1118 sites/assets/js/form.min.js +200 No Data No hay datos
1119 DocType: Appraisal Template Goal Appraisal Template Goal Objetivo Plantilla de Evaluación
1120 DocType: Salary Slip Earning Ganancia
1121 BOM Browser BOM Browser
1122 DocType: Purchase Taxes and Charges Add or Deduct Agregar o Deducir
1127 apps/erpnext/erpnext/stock/doctype/manage_variants/manage_variants.py +167 Item Variants {0} deleted {0} variantes borradas del artículo
1128 apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +38 Food Comida
1129 apps/erpnext/erpnext/accounts/report/accounts_payable/accounts_payable.js +51 Ageing Range 3 Rango Envejecimiento 3
1130 apps/erpnext/erpnext/stock/doctype/manage_variants/manage_variants.py +84 {0} {1} is entered more than once in Attributes table {0} {1} se introduce más de una vez en la tabla Atributos
1131 apps/erpnext/erpnext/projects/doctype/time_log/time_log.py +130 You can make a time log only against a submitted production order Usted puede hacer un registro de tiempo sólo contra una orden de producción presentada
1132 DocType: Maintenance Schedule Item No of Visits No. de visitas
1133 DocType: Cost Center old_parent old_parent
1163 DocType: Sales Order Item Planned Quantity Cantidad Planificada
1164 DocType: Purchase Invoice Item Item Tax Amount Total de impuestos de los artículos
1165 DocType: Item Maintain Stock Mantener Stock
1166 DocType: Supplier Quotation Get Terms and Conditions Verificar Términos y Condiciones
1167 DocType: Leave Control Panel Leave blank if considered for all designations Dejar en blanco si se considera para todas las designaciones
1168 apps/erpnext/erpnext/controllers/accounts_controller.py +424 Charge of type 'Actual' in row {0} cannot be included in Item Rate Cargo del tipo ' Real ' en la fila {0} no puede ser incluido en el Punto de Cambio
1169 apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order.js +167 Max: {0} Max: {0}
1354 apps/erpnext/erpnext/accounts/doctype/payment_tool/payment_tool.js +189 Row {0}: Payment amount can not be negative Fila {0}: Cantidad de pago no puede ser negativo
1355 DocType: Expense Claim Total Amount Reimbursed Monto total reembolsado
1356 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +151 Press fitting Press apropiado
1357 apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +63 Against Supplier Invoice {0} dated {1} Contra Factura de Proveedor {0} con fecha{1}
1358 DocType: Selling Settings Default Price List Lista de precios Por defecto Lista de precios Por defecto
1359 DocType: Journal Entry User Remark will be added to Auto Remark Observación usuario se añadirá a Observación Auto
1360 DocType: Payment Reconciliation Payments Pagos
1374 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +36 Forging Forjando
1375 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +125 Plating Enchapado
1376 DocType: Purchase Invoice End date of current invoice's period Fecha final del periodo de facturación actual
1377 DocType: Pricing Rule Applicable For Aplicable para
1378 apps/erpnext/erpnext/stock/doctype/item/item.py +342 Item Template cannot have stock or Open Sales/Purchase/Production Orders. Plantilla de artículo no puede tener acciones o abierto de compra / venta / Producción Órdenes.
1379 DocType: Bank Reconciliation From Date Desde la Fecha
1380 DocType: Backup Manager Validate Validar
1408 DocType: Upload Attendance Get Template Verificar Plantilla
1409 DocType: Address Postal Postal
1410 DocType: Email Digest Total amount of invoices sent to the customer during the digest period Importe total de las facturas enviadas a los clientes durante el período de digestión
1411 DocType: Item Weightage Coeficiente de Ponderación
1412 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +158 Mining Minería
1413 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +16 Resin casting Resina de colada
1414 apps/erpnext/erpnext/selling/doctype/customer/customer.py +79 A Customer Group exists with same name please change the Customer name or rename the Customer Group Existe un Grupo de Clientes con el mismo nombre, por favor cambie el nombre del Cliente o cambie el nombre del Grupo de Clientes
1442 apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +154 Stopped order cannot be cancelled. Unstop to cancel. Orden detenida no puede ser cancelada . Continuar antes de Cancelar.
1443 apps/erpnext/erpnext/stock/doctype/item/item.py +175 Default BOM ({0}) must be active for this item or its template Por defecto la lista de materiales ({0}) debe estar activo para este material o su plantilla
1444 DocType: Employee Leave Encashed? Vacaciones Descansadas?
1445 apps/erpnext/erpnext/crm/doctype/opportunity/opportunity.py +31 Opportunity From field is mandatory El campo Oportunidad De es obligatorio
1446 DocType: Sales Invoice Considered as an Opening Balance Considerado como Saldo Inicial
1447 DocType: Item Variants Variantes
1448 apps/erpnext/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js +469 Make Purchase Order Hacer Orden de Compra
1647 DocType: Purchase Receipt Warehouse where you are maintaining stock of rejected items Almacén en el que está manteniendo un balance de los artículos rechazados
1648 apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.js +408 Your financial year ends on Su año Financiero termina en
1649 DocType: POS Profile Price List Lista de Precios
1650 apps/erpnext/erpnext/accounts/doctype/fiscal_year/fiscal_year.py +20 {0} is now the default Fiscal Year. Please refresh your browser for the change to take effect. {0} es ahora la Año Fiscal predeterminado . Por favor, actualice su navegador para que el cambio surta efecto.
1651 apps/erpnext/erpnext/projects/doctype/project/project.js +47 Expense Claims Las reclamaciones de gastos
1652 DocType: Email Digest Support Soporte
1653 DocType: Authorization Rule Approving Role Aprobar Rol
2025 DocType: Notification Control Sales Order Message Mensaje de la Orden de Venta
2026 apps/erpnext/erpnext/config/setup.py +15 Set Default Values like Company, Currency, Current Fiscal Year, etc. Establecer Valores Predeterminados , como Empresa , Moneda, Año Fiscal Actual, etc
2027 apps/erpnext/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.js +28 Payment Type Tipo de Pago
2028 DocType: Process Payroll Select Employees Seleccione Empleados
2029 DocType: Bank Reconciliation To Date Hasta la fecha
2030 DocType: Opportunity Potential Sales Deal Trato de ventas potenciales
2031 sites/assets/js/form.min.js +294 Details Detalles
2046 DocType: Account Account Type Tipo de Cuenta
2047 apps/erpnext/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +222 Maintenance Schedule is not generated for all the items. Please click on 'Generate Schedule' Programa de mantenimiento no se genera para todos los artículos. Por favor, haga clic en ¨ Generar Programación¨
2048 To Produce Producir
2049 apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +119 For row {0} in {1}. To include {2} in Item rate, rows {3} must also be included Para la fila {0} en {1}. Para incluir {2} en la tasa de artículo, filas {3} también deben ser incluidos
2050 DocType: Packing Slip Identification of the package for the delivery (for print) La identificación del paquete para la entrega (para impresión)
2051 DocType: Bin Reserved Quantity Cantidad Reservada
2052 DocType: Landed Cost Voucher Purchase Receipt Items Artículos de Recibo de Compra
2058 DocType: Stock Reconciliation Item Current Qty Cant. Actual
2059 DocType: BOM Item See "Rate Of Materials Based On" in Costing Section Consulte " Cambio de materiales a base On" en la sección Cálculo del coste
2060 DocType: Appraisal Goal Key Responsibility Area Área de Responsabilidad Clave
2061 DocType: Item Reorder Material Request Type Tipo de Solicitud de Material
2062 apps/frappe/frappe/desk/moduleview.py +61 Documents Documentos
2063 apps/erpnext/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +17 Ref Referencia
2064 DocType: Cost Center Cost Center Centro de Costos
2065 apps/erpnext/erpnext/stock/report/stock_ledger/stock_ledger.js +48 Voucher # Comprobante #
2066 DocType: Notification Control Purchase Order Message Mensaje de la Orden de Compra
2067 DocType: Upload Attendance Upload HTML Subir HTML
2068 apps/erpnext/erpnext/controllers/accounts_controller.py +337 Total advance ({0}) against Order {1} cannot be greater \ than the Grand Total ({2}) Avance total ({0}) en contra de la orden {1} no puede ser mayor \ que el Gran Total ({2})
2069 DocType: Employee Relieving Date Aliviar Fecha
2070 apps/erpnext/erpnext/accounts/doctype/pricing_rule/pricing_rule.js +12 Pricing Rule is made to overwrite Price List / define discount percentage, based on some criteria. Regla de precios está sobrescribir Precio de lista / definir porcentaje de descuento, sobre la base de algunos criterios.
2071 DocType: Serial No Warehouse can only be changed via Stock Entry / Delivery Note / Purchase Receipt Depósito sólo se puede cambiar a través de la Entrada de Almacén / Nota de Entrega / Recibo de Compra
2072 DocType: Employee Education Class / Percentage Clase / Porcentaje
2073 apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +92 Head of Marketing and Sales Director de Marketing y Ventas
2074 apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +31 Income Tax Impuesto sobre la Renta
2075 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +156 Laser engineered net shaping Láser diseñado conformación neta
2076 apps/erpnext/erpnext/accounts/doctype/pricing_rule/pricing_rule.js +15 If selected Pricing Rule is made for 'Price', it will overwrite Price List. Pricing Rule price is the final price, so no further discount should be applied. Hence, in transactions like Sales Order, Purchase Order etc, it will be fetched in 'Rate' field, rather than 'Price List Rate' field. Si Regla precios seleccionada está hecho para 'Precio', sobrescribirá Lista de Precios. Regla precio El precio es el precio final, así que no hay descuento adicional debe aplicarse. Por lo tanto, en las transacciones como pedidos de venta, órdenes de compra, etc, se fue a buscar en el campo "Rate", en lugar de campo 'Precio de lista Rate'.
2252 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +124 Vibratory finishing Acabado vibratorio
2253 DocType: Item Customer Detail For the convenience of customers, these codes can be used in print formats like Invoices and Delivery Notes Para comodidad de los clientes , estos códigos se pueden utilizar en formatos impresos como facturas y notas de entrega
2254 DocType: Journal Entry Account Against Purchase Order Contra la Orden de Compra
2255 DocType: Employee You can enter any date manually Puede introducir cualquier fecha manualmente
2256 DocType: Sales Invoice Advertisement Anuncio
2257 apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +165 Probationary Period Período De Prueba
2258 DocType: Customer Group Only leaf nodes are allowed in transaction Sólo las Cuentas de Detalle se permiten en una transacción
2261 sites/assets/js/erpnext.min.js +46 Pay Pagar
2262 apps/erpnext/erpnext/projects/report/daily_time_log_summary/daily_time_log_summary.py +17 To Datetime Para Fecha y Hora
2263 DocType: SMS Settings SMS Gateway URL SMS Gateway URL
2264 apps/erpnext/erpnext/config/crm.py +48 Logs for maintaining sms delivery status Registros para mantener el estado de entrega de sms
2265 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +136 Grinding Molienda
2266 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +33 Shrink wrapping Retractilado
2267 apps/erpnext/erpnext/crm/doctype/newsletter/newsletter.py +167 Confirmed Confirmado
2535 apps/frappe/frappe/core/page/permission_manager/permission_manager.js +428 Set conjunto
2536 DocType: Item Warehouse-wise Reorder Levels Re ordenar Niveles de Almacén
2537 DocType: Lead Lead Owner Propietario de la Iniciativa
2538 apps/erpnext/erpnext/accounts/page/accounts_browser/accounts_browser.js +245 Warehouse is required Se requiere Almacén
2539 DocType: Employee Marital Status Estado Civil
2540 DocType: Stock Settings Auto Material Request Solicitud de Materiales Automatica
2541 DocType: Time Log Will be updated when billed. Se actualizará cuando se facture.
2655 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +78 Decambering Decambering
2656 apps/erpnext/erpnext/setup/doctype/company/company.js +22 Please re-type company name to confirm Por favor, vuelva a escribir nombre de la empresa para confirmar
2657 apps/erpnext/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +70 Total Outstanding Amt Monto Total Soprepasado
2658 DocType: Time Log Batch Total Hours Total de Horas
2659 apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +265 Total Debit must be equal to Total Credit. The difference is {0} El total de Débitos debe ser igual al total de Créditos. La diferencia es {0} El total de Débitos debe ser igual al total de Créditos. La diferencia es {0}
2660 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/industry_type.py +10 Automotive Automotor
2661 apps/erpnext/erpnext/hr/doctype/leave_allocation/leave_allocation.py +37 Leaves for type {0} already allocated for Employee {1} for Fiscal Year {0} Vacaciones para el tipo {0} ya asignado para Empleado {1} para el Año Fiscal {0}
2672 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +90 Pickling Decapado
2673 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +17 Sand casting Fundición de arena
2674 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +116 Electroplating Galvanoplastia
2675 DocType: Purchase Invoice Item Rate Tarifa
2676 apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +62 Intern Interno
2677 DocType: Manage Variants Item Manage Variants Item Administrar Variantes del artículo
2678 DocType: Newsletter A Lead with this email id should exist Una Iniciativa con este correo electrónico debería existir
2784 apps/erpnext/erpnext/setup/doctype/email_digest/email_digest.js +84 {0} Recipients {0} Destinatarios
2785 DocType: Features Setup Item Groups in Details Grupos de componentes en detalles
2786 apps/erpnext/erpnext/accounts/doctype/pos_profile/pos_profile.py +32 Expense Account is mandatory Cuenta de Gastos es obligatorio
2787 apps/erpnext/erpnext/accounts/page/pos/pos.js +4 Start Point-of-Sale (POS) Inicio de punto de venta (POS)
2788 apps/erpnext/erpnext/config/support.py +28 Visit report for maintenance call. Informe de visita por llamada de mantenimiento .
2789 DocType: Stock Settings Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units. Porcentaje que se les permite recibir o entregar más en contra de la cantidad pedida . Por ejemplo : Si se ha pedido 100 unidades. y el subsidio es de 10 %, entonces se le permite recibir 110 unidades.
2790 DocType: Pricing Rule Customer Group Grupo de Clientes
2906 DocType: Item Group HTML / Banner that will show on the top of product list. HTML / Banner que aparecerá en la parte superior de la lista de productos.
2907 DocType: Shipping Rule Specify conditions to calculate shipping amount Especificar condiciones de calcular el importe de envío
2908 apps/erpnext/erpnext/accounts/page/accounts_browser/accounts_browser.js +121 Add Child Añadir Hijo
2909 DocType: Accounts Settings Role Allowed to Set Frozen Accounts & Edit Frozen Entries Función Permitida para Establecer Cuentas Congeladas y Editar Entradas Congeladas
2910 apps/erpnext/erpnext/accounts/doctype/cost_center/cost_center.py +52 Cannot convert Cost Center to ledger as it has child nodes No se puede convertir de Centros de Costos a una cuenta del Libro de Mayor , ya que tiene nodos secundarios
2911 apps/erpnext/erpnext/stock/doctype/stock_uom_replace_utility/stock_uom_replace_utility.py +25 Conversion Factor is required Se requiere el factor de conversión
2912 apps/erpnext/erpnext/stock/report/stock_ledger/stock_ledger.py +37 Serial # Serial #
2921 apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +176 Sales Invoice {0} must be cancelled before cancelling this Sales Order Factura {0} debe ser cancelado antes de cancelar esta Orden Ventas
2922 apps/erpnext/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +34 Age Edad
2923 DocType: Time Log Billing Amount Facturación Monto
2924 apps/erpnext/erpnext/stock/doctype/packing_slip/packing_slip.js +84 Invalid quantity specified for item {0}. Quantity should be greater than 0. Cantidad no válido para el elemento {0} . Cantidad debe ser mayor que 0 .
2925 apps/erpnext/erpnext/config/hr.py +18 Applications for leave. Las solicitudes de licencia .
2926 apps/erpnext/erpnext/accounts/doctype/account/account.py +144 Account with existing transaction can not be deleted Cuenta con transacción existente no se puede eliminar
2927 apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +99 Legal Expenses Gastos Legales
2955 apps/erpnext/erpnext/projects/doctype/time_log/time_log_list.js +9 Make Time Log Batch Haga Registro de Tiempo de Lotes
2956 apps/erpnext/erpnext/stock/doctype/material_request/material_request_list.js +14 Issued Emitido
2957 DocType: Project Total Billing Amount (via Time Logs) Monto total de facturación (a través de los registros de tiempo)
2958 apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.js +629 We sell this Item Vendemos este artículo
2959 apps/erpnext/erpnext/accounts/report/purchase_register/purchase_register.py +65 Supplier Id Proveedor Id
2960 DocType: Journal Entry Cash Entry Entrada de Efectivo
2961 DocType: Sales Partner Contact Desc Desc. de Contacto
2969 DocType: Production Order Total Operating Cost Costo Total de Funcionamiento
2970 apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.py +142 Note: Item {0} entered multiple times Nota : El artículo {0} entrado varias veces
2971 apps/erpnext/erpnext/config/crm.py +27 All Contacts. Todos los Contactos .
2972 DocType: Newsletter Test Email Id Prueba de Identificación del email
2973 apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.js +394 Company Abbreviation Abreviatura de la Empresa
2974 DocType: Features Setup If you follow Quality Inspection. Enables Item QA Required and QA No in Purchase Receipt Si usted sigue la Inspección de calidad . Permite Artículo QA Obligatorio y QA No en recibo de compra
2975 DocType: GL Entry Party Type Tipo de Partida
3011 apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +235 {0} {1} is stopped {0} {1} esta detenido
3012 apps/erpnext/erpnext/stock/doctype/item/item.py +204 Barcode {0} already used in Item {1} Código de Barras {0} ya se utiliza en el elemento {1}
3013 DocType: Lead Add to calendar on this date Añadir al calendario en esta fecha
3014 apps/erpnext/erpnext/config/selling.py +132 Rules for adding shipping costs. Reglas para la adición de los gastos de envío .
3015 apps/erpnext/erpnext/support/doctype/warranty_claim/warranty_claim.py +20 Customer is required Se requiere Cliente
3016 DocType: Letter Head Letter Head Membrete
3017 apps/erpnext/erpnext/controllers/sales_and_purchase_return.py +21 {0} is mandatory for Return {0} es obligatorio para el Retorno
3029 apps/erpnext/erpnext/accounts/page/financial_analytics/financial_analytics.js +42 Select Fiscal Year... Seleccione el año fiscal ...
3030 apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +387 POS Profile required to make POS Entry POS perfil requerido para hacer la entrada POS
3031 DocType: Hub Settings Name Token Nombre Token
3032 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +105 Planing Cepillado
3033 apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.py +166 Standard Selling Venta estándar
3034 apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.py +138 Atleast one warehouse is mandatory Al menos un almacén es obligatorio
3035 DocType: Serial No Out of Warranty Fuera de Garantía
3036 DocType: BOM Replace Tool Replace Reemplazar
3037 apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +280 {0} against Sales Invoice {1} {0} contra Factura de Ventas {1}
3120 DocType: SMS Settings SMS Settings Ajustes de SMS
3121 apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +60 Temporary Accounts Cuentas Temporales
3122 DocType: Payment Tool Column Break 1 Columna Pausa 1
3123 apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +155 Black Negro
3124 DocType: BOM Explosion Item BOM Explosion Item BOM Explosion Artículo
3125 DocType: Account Auditor Auditor
3126 DocType: Purchase Order End date of current order's period Fecha de finalización del período de orden actual
3157 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +104 Shaping Shaping
3158 DocType: Employee Reports to Informes al
3159 DocType: SMS Settings Enter url parameter for receiver nos Introduzca el parámetro url para el receptor no
3160 DocType: Sales Invoice Paid Amount Cantidad pagada
3161 apps/erpnext/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py +25 Closing Account {0} must be of type 'Liability' Cuenta de Cierre{0} debe ser de tipo 'Patrimonio'
3162 Available Stock for Packing Items Inventario Disponible de Artículos de Embalaje
3163 apps/erpnext/erpnext/controllers/stock_controller.py +237 Reserved Warehouse is missing in Sales Order Almacén Reservado falta de órdenes de venta
3306 apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +28 Expected Delivery Date cannot be before Purchase Order Date Fecha prevista de entrega no puede ser anterior Fecha de Orden de Compra
3307 DocType: Appraisal Appraisal Template Plantilla de Evaluación
3308 DocType: Communication Email Correo Electronico
3309 DocType: Item Group Item Classification Clasificación de Artículos
3310 apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +89 Business Development Manager Gerente de Desarrollo de Negocios
3311 DocType: Maintenance Visit Purpose Maintenance Visit Purpose Propósito de la Visita de Mantenimiento
3312 apps/erpnext/erpnext/accounts/report/budget_variance_report/budget_variance_report.js +15 Period Período
3329 apps/erpnext/erpnext/stock/doctype/stock_settings/stock_settings.py +26 `Freeze Stocks Older Than` should be smaller than %d days. `Congelar Inventarios Anteriores a` debe ser menor que %d días .
3330 Project wise Stock Tracking Sabio proyecto Stock Tracking
3331 apps/erpnext/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +176 Maintenance Schedule {0} exists against {0} Programa de mantenimiento {0} existe en contra de {0}
3332 DocType: Stock Entry Detail Actual Qty (at source/target) Cantidad Real (en origen/destino)
3333 DocType: Item Customer Detail Ref Code Código Referencia
3334 apps/erpnext/erpnext/config/hr.py +13 Employee records. Registros de empleados .
3335 DocType: HR Settings Payroll Settings Configuración de Nómina
3473 DocType: Attendance Present Presente
3474 apps/erpnext/erpnext/stock/doctype/packing_slip/packing_slip.py +35 Delivery Note {0} must not be submitted Nota de Entrega {0} no debe estar presentada
3475 DocType: Notification Control Sales Invoice Message Mensaje de la Factura
3476 DocType: Email Digest Income Booked Ingresos Reservados
3477 DocType: Authorization Rule Based On Basado en
3478 Ordered Qty Cantidad Pedida
3479 DocType: Stock Settings Stock Frozen Upto Inventario Congelado hasta
3480 apps/erpnext/erpnext/config/projects.py +13 Project activity / task. Actividad del Proyecto / Tarea.
3481 apps/erpnext/erpnext/config/hr.py +65 Generate Salary Slips Generar Salario Slips
3482 apps/frappe/frappe/utils/__init__.py +87 {0} is not a valid email id {0} no es un Correo Electrónico de identificación válida
3483 apps/erpnext/erpnext/accounts/doctype/pricing_rule/pricing_rule.py +41 Buying must be checked, if Applicable For is selected as {0} Compra debe comprobarse, si se selecciona Aplicable Para como {0}
3484 apps/erpnext/erpnext/setup/doctype/authorization_rule/authorization_rule.py +40 Discount must be less than 100 El descuento debe ser inferior a 100
3485 DocType: ToDo Low Bajo
3486 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +70 Spinning Hilado
3487 DocType: Landed Cost Voucher Landed Cost Voucher Vale Landed Cost
3488 apps/erpnext/erpnext/hr/doctype/process_payroll/process_payroll.py +55 Please set {0} Por favor, configure {0}
3489 DocType: Purchase Invoice Repeat on Day of Month Repita el Día del mes
3664 apps/erpnext/erpnext/hr/doctype/salary_slip/salary_slip.py +194 Company Email ID not found, hence mail not sent Correo de la Empresa no encontrado, por lo tanto, correo no enviado
3665 apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +9 Application of Funds (Assets) Aplicación de Fondos (Activos )
3666 DocType: Production Planning Tool Filter based on item Filtro basado en artículo
3667 DocType: Fiscal Year Year Start Date Año de Inicio
3668 DocType: Attendance Employee Name Nombre del Empleado
3669 DocType: Sales Invoice Rounded Total (Company Currency) Total Redondeado (Moneda Local)
3670 apps/erpnext/erpnext/accounts/doctype/account/account.py +89 Cannot covert to Group because Account Type is selected. No se puede convertir a Grupo porque se seleccionó Tipo de Cuenta.
3672 apps/erpnext/erpnext/stock/doctype/material_request/material_request.py +93 {0} {1} has been modified. Please refresh. {0} {1} ha sido modificado. Por favor regenere .
3673 DocType: Leave Block List Stop users from making Leave Applications on following days. Deje que los usuarios realicen Solicitudes de Vacaciones en los siguientes días .
3674 apps/erpnext/erpnext/selling/doctype/quotation/quotation.js +618 From Opportunity De Oportunidades
3675 apps/erpnext/erpnext/setup/page/setup_wizard/fixtures/operations.py +45 Blanking Supresión
3676 apps/erpnext/erpnext/setup/page/setup_wizard/install_fixtures.py +166 Employee Benefits Beneficios a los Empleados
3677 DocType: Sales Invoice Is POS Es POS
3678 apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.py +212 Packed quantity must equal quantity for Item {0} in row {1} La cantidad embalada debe ser igual a la del elmento {0} en la fila {1}
3775 apps/erpnext/erpnext/setup/doctype/currency_exchange/currency_exchange.py +19 From Currency and To Currency cannot be same Desde Moneda y A Moneda no puede ser el mismo
3776 DocType: Stock Entry Repack Vuelva a embalar
3777 apps/erpnext/erpnext/setup/doctype/email_digest/email_digest.js +6 You must Save the form before proceeding Debe guardar el formulario antes de proceder
3778 apps/erpnext/erpnext/setup/page/setup_wizard/setup_wizard.js +500 Attach Logo Adjunte Logo
3779 DocType: Customer Commission Rate Comisión de Tarifas
3780 apps/erpnext/erpnext/config/hr.py +145 Block leave applications by department. Bloquee solicitudes de vacaciones por departamento.
3781 DocType: Production Order Actual Operating Cost Costo de Funcionamiento Real
3972
3973
3974
3975
3976
3977
3978

View File

@@ -1,268 +1,268 @@
{
"allow_import": 1,
"allow_rename": 1,
"creation": "2013-01-10 16:34:32",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Master",
"allow_import": 1,
"allow_rename": 1,
"creation": "2013-01-10 16:34:32",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Master",
"fields": [
{
"fieldname": "address_details",
"fieldtype": "Section Break",
"label": "",
"options": "icon-map-marker",
"fieldname": "address_details",
"fieldtype": "Section Break",
"label": "",
"options": "icon-map-marker",
"permlevel": 0
},
},
{
"description": "Name of person or organization that this address belongs to.",
"fieldname": "address_title",
"fieldtype": "Data",
"in_list_view": 0,
"label": "Address Title",
"permlevel": 0,
"description": "Name of person or organization that this address belongs to.",
"fieldname": "address_title",
"fieldtype": "Data",
"in_list_view": 0,
"label": "Address Title",
"permlevel": 0,
"reqd": 0
},
},
{
"fieldname": "address_type",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Address Type",
"options": "Billing\nShipping\nOffice\nPersonal\nPlant\nPostal\nShop\nSubsidiary\nWarehouse\nOther",
"permlevel": 0,
"fieldname": "address_type",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Address Type",
"options": "Billing\nShipping\nOffice\nPersonal\nPlant\nPostal\nShop\nSubsidiary\nWarehouse\nOther",
"permlevel": 0,
"reqd": 1
},
},
{
"fieldname": "address_line1",
"fieldtype": "Data",
"label": "Address Line 1",
"permlevel": 0,
"fieldname": "address_line1",
"fieldtype": "Data",
"label": "Address Line 1",
"permlevel": 0,
"reqd": 1
},
},
{
"fieldname": "address_line2",
"fieldtype": "Data",
"label": "Address Line 2",
"fieldname": "address_line2",
"fieldtype": "Data",
"label": "Address Line 2",
"permlevel": 0
},
},
{
"fieldname": "city",
"fieldtype": "Data",
"in_filter": 1,
"in_list_view": 1,
"label": "City/Town",
"permlevel": 0,
"reqd": 1,
"fieldname": "city",
"fieldtype": "Data",
"in_filter": 1,
"in_list_view": 1,
"label": "City/Town",
"permlevel": 0,
"reqd": 1,
"search_index": 1
},
},
{
"fieldname": "state",
"fieldtype": "Data",
"in_filter": 1,
"in_list_view": 0,
"label": "State",
"permlevel": 0,
"fieldname": "state",
"fieldtype": "Data",
"in_filter": 1,
"in_list_view": 0,
"label": "State",
"permlevel": 0,
"search_index": 0
},
},
{
"fieldname": "pincode",
"fieldtype": "Data",
"in_filter": 1,
"in_list_view": 0,
"label": "Pincode",
"permlevel": 0,
"fieldname": "pincode",
"fieldtype": "Data",
"in_filter": 1,
"in_list_view": 0,
"label": "Postal Code",
"permlevel": 0,
"search_index": 1
},
},
{
"fieldname": "country",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 0,
"label": "Country",
"options": "Country",
"permlevel": 0,
"reqd": 1,
"fieldname": "country",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 0,
"label": "Country",
"options": "Country",
"permlevel": 0,
"reqd": 1,
"search_index": 1
},
},
{
"fieldname": "column_break0",
"fieldtype": "Column Break",
"permlevel": 0,
"print_hide": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"permlevel": 0,
"print_hide": 0,
"width": "50%"
},
},
{
"fieldname": "email_id",
"fieldtype": "Data",
"label": "Email Id",
"fieldname": "email_id",
"fieldtype": "Data",
"label": "Email Id",
"permlevel": 0
},
},
{
"fieldname": "phone",
"fieldtype": "Data",
"label": "Phone",
"permlevel": 0,
"reqd": 1
},
"fieldname": "phone",
"fieldtype": "Data",
"label": "Phone",
"permlevel": 0,
"reqd": 0
},
{
"fieldname": "fax",
"fieldtype": "Data",
"in_filter": 1,
"label": "Fax",
"fieldname": "fax",
"fieldtype": "Data",
"in_filter": 1,
"label": "Fax",
"permlevel": 0
},
},
{
"default": "0",
"description": "",
"fieldname": "is_primary_address",
"fieldtype": "Check",
"label": "Preferred Billing Address",
"default": "0",
"description": "",
"fieldname": "is_primary_address",
"fieldtype": "Check",
"label": "Preferred Billing Address",
"permlevel": 0
},
},
{
"default": "0",
"description": "",
"fieldname": "is_shipping_address",
"fieldtype": "Check",
"in_list_view": 0,
"label": "Preferred Shipping Address",
"default": "0",
"description": "",
"fieldname": "is_shipping_address",
"fieldtype": "Check",
"in_list_view": 0,
"label": "Preferred Shipping Address",
"permlevel": 0
},
},
{
"fieldname": "linked_with",
"fieldtype": "Section Break",
"label": "Reference",
"options": "icon-pushpin",
"fieldname": "linked_with",
"fieldtype": "Section Break",
"label": "Reference",
"options": "icon-pushpin",
"permlevel": 0
},
},
{
"fieldname": "customer",
"fieldtype": "Link",
"label": "Customer",
"options": "Customer",
"fieldname": "customer",
"fieldtype": "Link",
"label": "Customer",
"options": "Customer",
"permlevel": 0
},
},
{
"fieldname": "customer_name",
"fieldtype": "Data",
"in_filter": 1,
"in_list_view": 0,
"label": "Customer Name",
"permlevel": 0,
"fieldname": "customer_name",
"fieldtype": "Data",
"in_filter": 1,
"in_list_view": 0,
"label": "Customer Name",
"permlevel": 0,
"read_only": 1
},
},
{
"fieldname": "supplier",
"fieldtype": "Link",
"label": "Supplier",
"options": "Supplier",
"fieldname": "supplier",
"fieldtype": "Link",
"label": "Supplier",
"options": "Supplier",
"permlevel": 0
},
},
{
"fieldname": "supplier_name",
"fieldtype": "Data",
"in_filter": 1,
"in_list_view": 0,
"label": "Supplier Name",
"permlevel": 0,
"read_only": 1,
"fieldname": "supplier_name",
"fieldtype": "Data",
"in_filter": 1,
"in_list_view": 0,
"label": "Supplier Name",
"permlevel": 0,
"read_only": 1,
"search_index": 0
},
},
{
"fieldname": "sales_partner",
"fieldtype": "Link",
"label": "Sales Partner",
"options": "Sales Partner",
"fieldname": "sales_partner",
"fieldtype": "Link",
"label": "Sales Partner",
"options": "Sales Partner",
"permlevel": 0
},
},
{
"fieldname": "column_break_22",
"fieldtype": "Column Break",
"fieldname": "column_break_22",
"fieldtype": "Column Break",
"permlevel": 0
},
},
{
"depends_on": "eval:!doc.supplier && !doc.sales_partner",
"fieldname": "lead",
"fieldtype": "Link",
"label": "Lead",
"options": "Lead",
"depends_on": "eval:!doc.supplier && !doc.sales_partner",
"fieldname": "lead",
"fieldtype": "Link",
"label": "Lead",
"options": "Lead",
"permlevel": 0
},
},
{
"depends_on": "eval:!doc.supplier && !doc.sales_partner",
"fieldname": "lead_name",
"fieldtype": "Data",
"label": "Lead Name",
"permlevel": 0,
"depends_on": "eval:!doc.supplier && !doc.sales_partner",
"fieldname": "lead_name",
"fieldtype": "Data",
"label": "Lead Name",
"permlevel": 0,
"read_only": 1
}
],
"icon": "icon-map-marker",
"idx": 1,
"in_dialog": 0,
"modified": "2015-06-01 06:42:18.331818",
"modified_by": "Administrator",
"module": "Utilities",
"name": "Address",
"owner": "Administrator",
],
"icon": "icon-map-marker",
"idx": 1,
"in_dialog": 0,
"modified": "2015-08-10 19:42:18.331819",
"modified_by": "Administrator",
"module": "Utilities",
"name": "Address",
"owner": "Administrator",
"permissions": [
{
"apply_user_permissions": 1,
"create": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"share": 1,
"submit": 0,
"apply_user_permissions": 1,
"create": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"share": 1,
"submit": 0,
"write": 1
},
},
{
"apply_user_permissions": 1,
"create": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Purchase User",
"share": 1,
"submit": 0,
"apply_user_permissions": 1,
"create": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Purchase User",
"share": 1,
"submit": 0,
"write": 1
},
},
{
"apply_user_permissions": 1,
"create": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Maintenance User",
"share": 1,
"submit": 0,
"apply_user_permissions": 1,
"create": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Maintenance User",
"share": 1,
"submit": 0,
"write": 1
},
},
{
"apply_user_permissions": 1,
"create": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"share": 1,
"submit": 0,
"apply_user_permissions": 1,
"create": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"share": 1,
"submit": 0,
"write": 1
}
],
"search_fields": "customer, supplier, sales_partner, country, state",
"sort_field": "modified",
],
"search_fields": "customer, supplier, sales_partner, country, state",
"sort_field": "modified",
"sort_order": "DESC"
}
}

View File

@@ -237,7 +237,7 @@ def repost_all_stock_vouchers():
doc = frappe.get_doc(voucher_type, voucher_no)
if voucher_type=="Stock Entry" and doc.purpose in ["Manufacture", "Repack"]:
doc.get_stock_and_rate(force=1)
doc.calculate_rate_and_amount(force=1)
elif voucher_type=="Purchase Receipt" and doc.is_subcontracted == "Yes":
doc.validate()

View File

@@ -1,6 +1,6 @@
from setuptools import setup, find_packages
version = "5.5.0"
version = "5.6.4"
with open("requirements.txt", "r") as f:
install_requires = f.readlines()

View File

@@ -29,5 +29,21 @@
For Sales / Purchase Return Enhancement <a href="https://github.com/frappe/erpnext/issues/3582">#3582</a>
</td>
</tr>
<tr>
<td style="width: 30%">
PT. Ridho Sribumi Sejahtera
</td>
<td>
For Additional Costs in Stock Entry <a href="https://github.com/frappe/erpnext/issues/3613">#3613</a>
</td>
</tr>
<tr>
<td style="width: 30%">
<a href="http://www.rigpl.com">Rohit Industries</a>
</td>
<td>
For Mandrill Integration <a href="https://github.com/frappe/erpnext/issues/3546">#3546</a>
</td>
</tr>
</tbody>
</table>