Compare commits

...

164 Commits

Author SHA1 Message Date
Pratik Vyas
8c78a1abb7 Merge branch 'develop' 2014-01-27 17:19:45 +05:30
Pratik Vyas
8821541f33 bumped to version 3.7.0 2014-01-27 17:49:45 +06:00
Nabin Hait
5cec7ec84a Merge pull request #1355 from akhileshdarjee/hotfix
Allow rename for price list
2014-01-27 02:40:08 -08:00
Nabin Hait
9536f112b5 Merge pull request #1358 from nabinhait/hotfix
Serial no and planned qty
2014-01-27 01:33:56 -08:00
Nabin Hait
44a40b860e Fixed planned qty bug and patch to recalculate planned qty 2014-01-27 15:02:30 +05:30
Nabin Hait
b3d26c08f6 Fixed planned qty bug and patch to recalculate planned qty 2014-01-27 14:58:55 +05:30
Nabin Hait
fa9fabaa49 Serial no status fix: patch to set status not available where no sle exists 2014-01-27 12:46:18 +05:30
Akhilesh Darjee
49e8e783e3 webnotes/erpnext#1353 allow rename for price list 2014-01-27 11:12:24 +05:30
Anand Doshi
c4ee74857d BugFix: Production Planning Tool - get_raw_materials 2014-01-24 21:53:11 +05:30
Anand Doshi
fc13b87fd5 Fixes in Make Demo 2014-01-24 18:54:50 +05:30
Anand Doshi
d9ba544e09 Fix in Item Test Case 2014-01-24 15:59:05 +05:30
Nabin Hait
af21479665 Merge pull request #1342 from akhileshdarjee/hotfix
Item List refresh when price list changed in POS
2014-01-23 05:14:16 -08:00
Nabin Hait
eec59ae7c4 Merge pull request #1345 from nabinhait/hotfix
Order preview through customer login
2014-01-23 01:48:28 -08:00
Nabin Hait
efa9a7ed5b Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-23 13:25:39 +05:30
Nabin Hait
557abdebe0 order preview through customer login 2014-01-23 13:25:26 +05:30
Akhilesh Darjee
8589b1db22 Use model set_value for updating values from POS 2014-01-22 19:25:51 +05:30
Akhilesh Darjee
82a21beba0 Item List refresh when price list changed in POS 2014-01-22 16:55:32 +05:30
Pratik Vyas
256c4da0a5 Merge branch 'develop' 2014-01-22 16:03:07 +05:30
Pratik Vyas
7395dc9969 bumped to version 3.6.6 2014-01-22 16:33:07 +06:00
Nabin Hait
d39bc09e62 Merge pull request #1341 from nabinhait/hotfix
Small fix
2014-01-22 02:21:17 -08:00
Nabin Hait
c7676797e1 Dont display old fraction outstanding in AR report 2014-01-22 15:36:44 +05:30
Nabin Hait
423932fab2 Fixes in general ledger opening 2014-01-22 11:53:44 +05:30
Nabin Hait
efda5b0d36 Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-21 20:58:10 +05:30
Nabin Hait
13a9e27320 Fixes in warehouse merge function 2014-01-21 20:57:39 +05:30
Pratik Vyas
b0433d96a3 Merge branch 'develop' 2014-01-21 12:09:31 +05:30
Pratik Vyas
f3aba2e536 bumped to version 3.6.5 2014-01-21 12:39:31 +06:00
Nabin Hait
1594f102fd Merge pull request #1340 from nabinhait/hotfix
General ledger
2014-01-20 22:29:33 -08:00
Nabin Hait
b2f2df4c64 General ledger: opening balance issue fixed 2014-01-21 11:58:17 +05:30
Nabin Hait
9f6c48d82e Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-21 10:44:16 +05:30
Pratik Vyas
f0307dc75e Merge branch 'develop' 2014-01-20 19:21:25 +05:30
Pratik Vyas
872e4d1f3d bumped to version 3.6.4 2014-01-20 19:51:25 +06:00
Nabin Hait
b164e606f9 Merge pull request #1337 from nabinhait/hotfix
Hotfix
2014-01-20 05:00:43 -08:00
Nabin Hait
806343395a Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-20 18:29:48 +05:30
Nabin Hait
afe93d633c Increased remarks width in general ledger 2014-01-20 18:28:48 +05:30
Nabin Hait
cd20717c3d Merge pull request #1336 from akhileshdarjee/disable-price-list
Enabled feature for Price List
2014-01-20 04:47:10 -08:00
Akhilesh Darjee
529709e08b patch for enabling all price list 2014-01-20 16:39:03 +05:30
Akhilesh Darjee
e82eee512b Enabled feature in Price List 2014-01-20 16:09:45 +05:30
Nabin Hait
ee0c623760 Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-20 10:57:12 +05:30
Nabin Hait
dbb4955483 Merge pull request #1332 from akhileshdarjee/hotfix
decimal places fix in item prices report
2014-01-17 20:18:30 -08:00
Akhilesh Darjee
ed87335513 decimal places fix in item prices report 2014-01-17 18:57:21 +05:30
Akhilesh Darjee
8a4111fe0e decimal places fixed in item prices report 2014-01-17 18:50:44 +05:30
Pratik Vyas
4bfa8d560b Merge branch 'develop' 2014-01-17 16:56:31 +05:30
Pratik Vyas
96db41d996 bumped to version 3.6.3 2014-01-17 17:26:31 +06:00
Nabin Hait
9a74330d6f Merge pull request #1330 from pdvyas/fix-mysql-installer
remove mysql-python pinning to 1.2.4
2014-01-17 02:37:25 -08:00
Nabin Hait
1951baca57 Merge pull request #1319 from pdvyas/about-version
update about erpnext with version number
2014-01-17 02:36:11 -08:00
Pratik Vyas
da08124df2 remove mysql-python pinning to 1.2.4 2014-01-17 15:27:19 +05:30
Nabin Hait
2aecc5a717 Merge pull request #1329 from nabinhait/hotfix
Patch for updating billing status for old zero value order
2014-01-17 01:41:40 -08:00
Nabin Hait
a37ffe162b Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-17 12:05:06 +05:30
Nabin Hait
bc99c9d6e0 Priority to user's deafult price list over customer's default price list 2014-01-17 12:04:24 +05:30
Nabin Hait
f32314dd0b Do not set income/expense account automatically in company master 2014-01-17 11:53:25 +05:30
Nabin Hait
7e73f35916 Merge pull request #1327 from akhileshdarjee/hotfix
Allow renaming of campaign
2014-01-16 21:48:10 -08:00
Akhilesh Darjee
e1e63a91d6 Allow renaming of campaign 2014-01-17 11:12:20 +05:30
Nabin Hait
9a05aad8ea Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-17 10:31:43 +05:30
Nabin Hait
f6b77479d7 Patch: Update billing status for zero value order 2014-01-16 18:18:49 +05:30
Pratik Vyas
3c279163fc Merge branch 'develop' 2014-01-16 16:29:22 +05:30
Pratik Vyas
6933617538 bumped to version 3.6.2 2014-01-16 16:59:22 +06:00
Nabin Hait
2648661757 Merge pull request #1326 from nabinhait/hotfix
Calculate taxes and charges total in server side
2014-01-16 01:28:33 -08:00
Nabin Hait
e31a97f355 Calculate taxes and charges total in server side 2014-01-16 14:24:32 +05:30
Nabin Hait
6bdb73c392 Merge pull request #1324 from nabinhait/hotfix
Minor Fix
2014-01-15 22:44:25 -08:00
Nabin Hait
deda7e2c75 Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-16 12:08:36 +05:30
Nabin Hait
5cdb8cea13 Reset filters in Item Price report on each route 2014-01-16 12:08:12 +05:30
Nabin Hait
90a8c9e636 Merge pull request #1323 from nabinhait/hotfix
Billing status for zero value SO/PO
2014-01-15 05:20:51 -08:00
Nabin Hait
c0c951b6a9 Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-15 17:36:34 +05:30
Nabin Hait
39eb7faeb9 Update billing percentage and status from SI/PI in SO/PO, when net total is zero 2014-01-15 17:36:18 +05:30
Nabin Hait
4829ad3eb8 Merge pull request #1321 from akhileshdarjee/hotfix
Hide fields fix
2014-01-15 03:17:23 -08:00
Akhilesh Darjee
a682d45846 webnotes/erpnext # 1320 - hide fields fix 2014-01-15 16:39:01 +05:30
Pratik Vyas
76dd468f0e update about erpnext with version number 2014-01-15 14:23:38 +05:30
Nabin Hait
a6df26839d Higher priority to user's default price list over customer's default price list 2014-01-15 12:21:14 +05:30
Nabin Hait
c5d4fc38aa Fixes in monthly salary register 2014-01-15 10:54:07 +05:30
Pratik Vyas
02f7e83bd1 Merge branch 'develop' 2014-01-14 18:49:14 +05:30
Pratik Vyas
f55d9414cd bumped to version 3.6.1 2014-01-14 19:19:14 +06:00
Nabin Hait
5644ed37a4 Merge pull request #1316 from nabinhait/hotfix
rounding and divisional loss
2014-01-14 05:05:33 -08:00
Nabin Hait
ee6200576a Highest priority to user properties while fetching warehouse from item 2014-01-14 18:34:10 +05:30
Nabin Hait
eeb8ba18cd Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-14 17:44:47 +05:30
Nabin Hait
3a19370892 Rounding issue and divisional loss adjustment 2014-01-14 17:44:34 +05:30
Nabin Hait
6dc1ba6f7f Merge pull request #1314 from nabinhait/hotfix
comment fix
2014-01-14 02:29:39 -08:00
Nabin Hait
d91af2853e Allowed import for customer issue 2014-01-14 15:56:52 +05:30
Nabin Hait
d23ae108ae Fixes in Comment, if comment by not mentioned, consider owner 2014-01-14 15:52:09 +05:30
Pratik Vyas
72f8ae2d5a Merge branch 'develop' 2014-01-13 18:37:07 +05:30
Pratik Vyas
1e347910d5 bumped to version 3.6.0 2014-01-13 19:07:07 +06:00
Nabin Hait
25cfb700bb Merge pull request #1311 from akhileshdarjee/hotfix
Increase and decrease quantity buttons in POS
2014-01-13 04:33:50 -08:00
Nabin Hait
8d2d4e82fd Merge pull request #1302 from nabinhait/hotfix
Hotfix
2014-01-13 04:33:18 -08:00
Nabin Hait
c43d58ac79 Delete Property Setters for Custom Fields, and set them inside Custom Field 2014-01-13 17:55:24 +05:30
Akhilesh Darjee
0b3c10601c Increase and decrease quantity buttons in POS 2014-01-13 13:34:34 +05:30
Nabin Hait
14bf711d04 Fixes in frozen accounts validation 2014-01-13 13:28:07 +05:30
Nabin Hait
35a9d585b4 Bank Reconciliation Statement: Show balance in debit or credit column based on account type 2014-01-13 12:24:27 +05:30
Nabin Hait
38e56eeb45 Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-13 12:23:29 +05:30
Nabin Hait
3dd1043d5e Merge pull request #1301 from akhileshdarjee/hotfix
pos view showing inclusive taxes
2014-01-10 03:09:12 -08:00
Nabin Hait
55387aa931 Fixed conflict 2014-01-10 16:31:48 +05:30
Nabin Hait
03463ef73b Move related property setters to custom field property 2014-01-10 16:28:41 +05:30
Akhilesh Darjee
371663169c pos view showing inclusive taxes 2014-01-10 15:05:44 +05:30
Nabin Hait
f3ded044e0 Monthly Salary Register: Month is now optional 2014-01-09 17:38:50 +05:30
Nabin Hait
68b0d54b4b Set default accounts in company related to perpetual inventory, only it is enabled 2014-01-09 17:25:55 +05:30
Pratik Vyas
e4a71935eb Merge branch 'develop' 2014-01-09 15:56:53 +05:30
Pratik Vyas
3e846d19d4 bumped to version 3.5.1 2014-01-09 16:26:53 +06:00
Nabin Hait
5411ece766 Merge pull request #1299 from nabinhait/hotfix
Accounts Receivable fix for partial payment in pos
2014-01-09 02:25:12 -08:00
Nabin Hait
aeb68b2899 Accounts Receivable fix for partial payment in pos 2014-01-09 15:54:18 +05:30
Pratik Vyas
0064dc6f4a Merge branch 'develop' 2014-01-09 15:52:09 +05:30
Pratik Vyas
11bf06ad76 bumped to version 3.5.0 2014-01-09 16:22:09 +06:00
Nabin Hait
5c6a2acff7 Merge pull request #1298 from nabinhait/hotfix
Accounts Receivable fix for partial payment in pos
2014-01-09 02:20:06 -08:00
Nabin Hait
cdbd4218a8 Accounts Receivable fix for partial payment in pos 2014-01-09 15:49:26 +05:30
Nabin Hait
701cddfb15 Merge pull request #1297 from nabinhait/hotfix
Hotfix
2014-01-08 23:18:54 -08:00
Nabin Hait
4bbf91bea1 Added match condition in general ledger report 2014-01-09 12:44:44 +05:30
Nabin Hait
e481e81e67 Merge pull request #1296 from akhileshdarjee/hotfix
POS print format fixed
2014-01-08 22:23:56 -08:00
Anand Doshi
102b417b52 Fix: Typo on patch 2014-01-09 11:39:10 +05:30
Akhilesh Darjee
efc2a45835 merge conflict fixed 2014-01-08 19:42:17 +05:30
Akhilesh Darjee
5c119a7e95 Merge branch 'master' of github.com:webnotes/erpnext into hotfix 2014-01-08 19:36:26 +05:30
Akhilesh Darjee
f7a102ffe3 POS print format fixed 2014-01-08 19:35:01 +05:30
Nabin Hait
d659343541 Payment Reconciliation: Fix for outstanding voucher query 2014-01-08 17:29:23 +05:30
Nabin Hait
dbf5e54eab Merge pull request #1290 from akhileshdarjee/price-list
Price List and Item Price : Valid for Buying and Selling as separate check box
2014-01-07 21:49:52 -08:00
Pratik Vyas
5eb139a531 Merge branch 'develop' 2014-01-07 21:45:04 +05:30
Pratik Vyas
9e2358c544 bumped to version 3.4.9 2014-01-07 22:15:04 +06:00
Akhilesh Darjee
8d0ef21911 pos invoice print format changes 2014-01-07 19:45:33 +05:30
Pratik Vyas
9a8f37c579 Merge pull request #1289 from pdvyas/hotfix-installer
fix installer python packages issue
2014-01-07 06:14:08 -08:00
Akhilesh Darjee
029f698c65 patch for item price and price list 2014-01-07 19:43:35 +05:30
Akhilesh Darjee
806017c92a Price List and Item Price : Validfor Buying and Selling as separate check box 2014-01-07 18:37:38 +05:30
Pratik Vyas
69951e5d1c fix installer python packages issue 2014-01-07 18:24:40 +05:30
Nabin Hait
10fd91c78e Close tickets automatically through scheduler 2014-01-07 16:18:41 +05:30
Pratik Vyas
63d71d7f2f Merge branch 'develop' 2014-01-07 13:47:44 +05:30
Pratik Vyas
777bff6e8d bumped to version 3.4.8 2014-01-07 14:17:44 +06:00
Nabin Hait
1e42a3d028 Merge pull request #1287 from nabinhait/hotfix
Fixes in overbilling validation against DN/PR
2014-01-06 23:12:45 -08:00
Nabin Hait
da282d405f Fixes in overbilling validation against DN/PR 2014-01-07 12:41:09 +05:30
Nabin Hait
8f1bb82ab9 Merge pull request #1286 from nabinhait/hotfix
Removed unwanted debug
2014-01-06 22:40:54 -08:00
Anand Doshi
f2b46635b5 Merge pull request #1285 from pdvyas/hotfix-installer
fix branching, pip version and mysql-python version pinning in install_erpnext
2014-01-06 22:35:49 -08:00
Pratik Vyas
a11e14424c fix branching, pip version and mysql-python version pinning in install_erpnext 2014-01-07 12:03:09 +05:30
Nabin Hait
01441ef37f Removed unwanted debug 2014-01-07 11:59:36 +05:30
Nabin Hait
cb665285db Merge pull request #1280 from nabinhait/hotfix
Fixes in item-wise sales/purchase register
2014-01-06 03:03:02 -08:00
Nabin Hait
6b66c387ad Fixes in item-wise sales/purchase register 2014-01-06 16:28:17 +05:30
Nabin Hait
5e702de710 Merge pull request #1279 from akhileshdarjee/hotfix
accounts payable fixed
2014-01-05 23:01:51 -08:00
Akhilesh Darjee
7e79f300a1 accounts payable fixed 2014-01-06 12:23:29 +05:30
Pratik Vyas
955902ccad Merge branch 'develop' 2014-01-06 12:18:58 +05:30
Pratik Vyas
b882fa14f4 bumped to version 3.4.7 2014-01-06 12:48:58 +06:00
Nabin Hait
d12d7142c6 Merge pull request #1278 from nabinhait/hotfix
Fixes in overbilling validation
2014-01-05 22:35:10 -08:00
Nabin Hait
42db5d76a9 Fixes in overbilling validation 2014-01-06 11:20:37 +05:30
Pratik Vyas
bd4030bf85 Merge branch 'develop' 2014-01-03 18:40:11 +05:30
Pratik Vyas
a83337a2dd bumped to version 3.4.6 2014-01-03 19:10:11 +06:00
Nabin Hait
e51e5238ec Merge pull request #1267 from nabinhait/hotfix
Hotfix
2014-01-03 04:59:34 -08:00
Nabin Hait
5d5fe5d9d5 Cost center field added in Purchase Receipt Item table 2014-01-03 18:28:53 +05:30
Nabin Hait
b476c989a4 Fixes test cases for date and year mismatch 2014-01-03 17:43:52 +05:30
Nabin Hait
7f0406f281 Chekc over billing validation considering tolerance 2014-01-03 17:43:19 +05:30
Nabin Hait
33f6b9d6e8 Unlinked message listing all linked entries while cancelling an accounting trandsaction 2014-01-03 15:12:16 +05:30
Pratik Vyas
c196037cb0 Merge branch 'develop' 2014-01-03 13:27:06 +05:30
Pratik Vyas
866103bf66 bumped to version 3.4.5 2014-01-03 13:57:06 +06:00
Nabin Hait
528eb4e4ff Merge pull request #1264 from akhileshdarjee/hotfix
fixed accounts receivable for customer name
2014-01-02 23:53:30 -08:00
Nabin Hait
481454298d Merge pull request #1265 from nabinhait/hotfix
Fixes in general ledger report
2014-01-02 23:53:15 -08:00
Akhilesh Darjee
8a0b7cece1 accounts receivable fixed 2014-01-03 13:21:38 +05:30
Akhilesh Darjee
b4eba77f7b fixed accounts receivable 2014-01-03 12:58:04 +05:30
Akhilesh Darjee
b0a9581e59 fixed accounts receivable for customer name 2014-01-03 12:44:00 +05:30
Nabin Hait
6472bdace2 Fixes in general ledger report 2014-01-03 12:30:24 +05:30
Nabin Hait
c95b9f9221 Merge pull request #1263 from nabinhait/hotfix
Hotfix
2014-01-02 22:44:24 -08:00
Nabin Hait
a4db83a934 Fixes in valuation rate calculation in purchase receipt 2014-01-03 12:13:18 +05:30
Nabin Hait
28acaeb345 Fixes in valuation rate calculation in purchase receipt 2014-01-03 11:16:16 +05:30
Pratik Vyas
5fbb757c2c Merge branch 'develop' 2014-01-02 17:12:01 +05:30
Pratik Vyas
df07c964f7 bumped to version 3.4.4 2014-01-02 17:42:01 +06:00
Nabin Hait
0e2a088ac4 Merge pull request #1260 from nabinhait/hotfix
Hotfix
2014-01-02 03:02:56 -08:00
Nabin Hait
ffc2f8885b Merge branch 'develop' of github.com:webnotes/erpnext into hotfix 2014-01-02 16:30:38 +05:30
Nabin Hait
a1ffacaf0b Valuation related charges should only go to stock items 2014-01-02 16:30:16 +05:30
Pratik Vyas
8c52258e6d Merge branch 'develop' 2013-12-31 14:12:36 +05:30
Pratik Vyas
ffe8af3f2f bumped to version 3.4.3 2013-12-31 14:42:36 +06:00
Nabin Hait
fe5728718f Merge pull request #1251 from nabinhait/hotfix
Hotfix
2013-12-30 21:02:20 -08:00
Nabin Hait
424b4a4b36 Supplier bill info in accounts payable report 2013-12-31 10:24:28 +05:30
Nabin Hait
2a3d7e660f Fixes in general ledger report 2013-12-30 20:28:23 +05:30
Pratik Vyas
a0a43ca4e4 Merge branch 'develop' 2013-12-30 19:34:38 +05:30
Pratik Vyas
9cd9836e18 bumped to version 3.4.2 2013-12-30 20:04:38 +06:00
96 changed files with 1059 additions and 627 deletions

File diff suppressed because one or more lines are too long

View File

@@ -6,6 +6,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes import _
from webnotes.utils import cint
class DocType:
def __init__(self, d, dl):
@@ -14,7 +15,12 @@ class DocType:
def on_update(self):
webnotes.conn.set_default("auto_accounting_for_stock", self.doc.auto_accounting_for_stock)
if self.doc.auto_accounting_for_stock:
if cint(self.doc.auto_accounting_for_stock):
# set default perpetual account in company
for company in webnotes.conn.sql("select name from tabCompany"):
webnotes.bean("Company", company[0]).save()
# Create account head for warehouses
warehouse_list = webnotes.conn.sql("select name, company from tabWarehouse", as_dict=1)
warehouse_with_no_company = [d.name for d in warehouse_list if not d.company]
if warehouse_with_no_company:

View File

@@ -146,11 +146,12 @@ def update_outstanding_amt(account, against_voucher_type, against_voucher, on_ca
webnotes.conn.sql("update `tab%s` set outstanding_amount=%s where name='%s'" %
(against_voucher_type, bal, against_voucher))
def validate_frozen_account(account, adv_adj):
def validate_frozen_account(account, adv_adj=None):
frozen_account = webnotes.conn.get_value("Account", account, "freeze_account")
if frozen_account == 'Yes' and not adv_adj:
frozen_accounts_modifier = webnotes.conn.get_value( 'Accounts Settings', None,
'frozen_accounts_modifier')
if not frozen_accounts_modifier:
webnotes.throw(account + _(" is a frozen account. \
Either make the account active or assign role in Accounts Settings \

View File

@@ -120,7 +120,8 @@ cur_frm.cscript.refresh = function(doc) {
"voucher_no": doc.name,
"from_date": doc.posting_date,
"to_date": doc.posting_date,
"company": doc.company
"company": doc.company,
group_by_voucher: 0
};
wn.set_route("query-report", "General Ledger");
}, "icon-table");

View File

@@ -140,13 +140,13 @@ def gl_entry_details(doctype, txt, searchfield, start, page_len, filters):
and ifnull(gle.%(account_type)s, 0) > 0
and (select ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0)
from `tabGL Entry`
where against_voucher_type = '%(dt)s'
where account = '%(acc)s'
and against_voucher_type = '%(dt)s'
and against_voucher = gle.voucher_no
and voucher_no != gle.voucher_no)
!= abs(ifnull(gle.debit, 0) - ifnull(gle.credit, 0)
)
and if(gle.voucher_type='Sales Invoice', (select is_pos from `tabSales Invoice`
where name=gle.voucher_no), 0)=0
!= abs(ifnull(gle.debit, 0) - ifnull(gle.credit, 0))
and if(gle.voucher_type='Sales Invoice', ifnull((select is_pos from `tabSales Invoice`
where name=gle.voucher_no), 0), 0)=0
%(mcond)s
ORDER BY gle.posting_date desc, gle.voucher_no desc
limit %(start)s, %(page_len)s""" % {

View File

@@ -7,7 +7,7 @@ cur_frm.cscript.onload = function(doc,cdt,cdn){
});
cur_frm.set_query("selling_price_list", function() {
return { filters: { buying_or_selling: "Selling" } };
return { filters: { selling: 1 } };
});
}

View File

@@ -2,7 +2,7 @@
{
"creation": "2013-05-24 12:15:51",
"docstatus": 0,
"modified": "2013-11-02 16:58:38",
"modified": "2014-01-15 16:23:58",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -154,7 +154,7 @@
"reqd": 1
},
{
"depends_on": "eval:sys_defaults.auto_accounting_for_stock",
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
"doctype": "DocField",
"fieldname": "expense_account",
"fieldtype": "Link",

View File

@@ -35,7 +35,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
"voucher_no": doc.name,
"from_date": doc.posting_date,
"to_date": doc.posting_date,
"company": doc.company
"company": doc.company,
group_by_voucher: 0
};
wn.set_route("query-report", "General Ledger");
}, "icon-table");

View File

@@ -302,6 +302,7 @@ class DocType(BuyingController):
self.make_gl_entries()
self.update_against_document_in_jv()
self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
def make_gl_entries(self):
auto_accounting_for_stock = \
@@ -350,7 +351,6 @@ class DocType(BuyingController):
# item gl entries
stock_item_and_auto_accounting_for_stock = False
stock_items = self.get_stock_items()
# rounding_diff = 0.0
for item in self.doclist.get({"parentfield": "entries"}):
if auto_accounting_for_stock and item.item_code in stock_items:
if flt(item.valuation_rate):
@@ -359,12 +359,8 @@ class DocType(BuyingController):
# expense will be booked in sales invoice
stock_item_and_auto_accounting_for_stock = True
valuation_amt = item.amount + item.item_tax_amount + item.rm_supp_cost
# rounding_diff += (flt(item.amount, self.precision("amount", item)) +
# flt(item.item_tax_amount, self.precision("item_tax_amount", item)) +
# flt(item.rm_supp_cost, self.precision("rm_supp_cost", item)) -
# valuation_amt)
valuation_amt = flt(item.amount + item.item_tax_amount + item.rm_supp_cost,
self.precision("amount", item))
gl_entries.append(
self.get_gl_dict({
@@ -392,12 +388,6 @@ class DocType(BuyingController):
# this will balance out valuation amount included in cost of goods sold
expenses_included_in_valuation = \
self.get_company_default("expenses_included_in_valuation")
# if rounding_diff:
# import operator
# cost_center_with_max_value = max(valuation_tax.iteritems(),
# key=operator.itemgetter(1))[0]
# valuation_tax[cost_center_with_max_value] -= flt(rounding_diff)
for cost_center, amount in valuation_tax.items():
gl_entries.append(
@@ -432,7 +422,7 @@ class DocType(BuyingController):
remove_against_link_from_jv(self.doc.doctype, self.doc.name, "against_voucher")
self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
self.make_cancel_gl_entries()
def on_update(self):

View File

@@ -19,8 +19,10 @@ erpnext.POS = Class.extend({
<table class="table table-condensed table-hover" id="cart" style="table-layout: fixed;">\
<thead>\
<tr>\
<th style="width: 50%">Item</th>\
<th style="width: 25%; text-align: right;">Qty</th>\
<th style="width: 40%">Item</th>\
<th style="width: 9%"></th>\
<th style="width: 17%; text-align: right;">Qty</th>\
<th style="width: 9%"></th>\
<th style="width: 25%; text-align: right;">Rate</th>\
</tr>\
</thead>\
@@ -60,10 +62,16 @@ erpnext.POS = Class.extend({
</div>\
</div>\
<br><br>\
<button class="btn btn-success btn-lg make-payment">\
<i class="icon-money"></i> Make Payment</button>\
<button class="btn btn-default btn-lg delete-items pull-right" style="display: none;">\
<i class="icon-trash"></i> Del</button>\
<div class="row">\
<div class="col-sm-9">\
<button class="btn btn-success btn-lg make-payment">\
<i class="icon-money"></i> Make Payment</button>\
</div>\
<div class="col-sm-3">\
<button class="btn btn-default btn-lg remove-items" style="display: none;">\
<i class="icon-trash"></i> Del</button>\
</div>\
</div>\
<br><br>\
</div>\
<div class="col-sm-6">\
@@ -82,7 +90,7 @@ erpnext.POS = Class.extend({
me.refresh();
});
this.call_function("delete-items", function() {me.remove_selected_item();});
this.call_function("remove-items", function() {me.remove_selected_items();});
this.call_function("make-payment", function() {me.make_payment();});
},
check_transaction_type: function() {
@@ -101,6 +109,7 @@ erpnext.POS = Class.extend({
this.party = party;
this.price_list = (party == "Customer" ?
this.frm.doc.selling_price_list : this.frm.doc.buying_price_list);
this.price_list_field = (party == "Customer" ? "selling_price_list" : "buying_price_list");
this.sales_or_purchase = (party == "Customer" ? "Sales" : "Purchase");
this.net_total = "net_total_" + export_or_import;
this.grand_total = "grand_total_" + export_or_import;
@@ -261,22 +270,17 @@ erpnext.POS = Class.extend({
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
if (d.item_code == item_code) {
caught = true;
if (serial_no) {
d.serial_no += '\n' + serial_no;
me.frm.script_manager.trigger("serial_no", d.doctype, d.name);
}
else {
d.qty += 1;
me.frm.script_manager.trigger("qty", d.doctype, d.name);
}
if (serial_no)
wn.model.set_value(d.doctype, d.name, "serial_no", d.serial_no + '\n' + serial_no);
else
wn.model.set_value(d.doctype, d.name, "qty", d.qty + 1);
}
});
}
// if item not found then add new item
if (!caught) {
if (!caught)
this.add_new_item_to_grid(item_code, serial_no);
}
this.refresh();
this.refresh_search_box();
@@ -311,15 +315,16 @@ erpnext.POS = Class.extend({
wn.model.clear_doc(d.doctype, d.name);
me.refresh_grid();
} else {
d.qty = qty;
me.frm.script_manager.trigger("qty", d.doctype, d.name);
wn.model.set_value(d.doctype, d.name, "qty", qty);
}
}
});
me.refresh();
this.refresh();
},
refresh: function() {
var me = this;
this.refresh_item_list();
this.party_field.set_input(this.frm.doc[this.party.toLowerCase()]);
this.barcode.set_input("");
@@ -333,7 +338,7 @@ erpnext.POS = Class.extend({
}
this.disable_text_box_and_button();
this.make_payment_button();
this.hide_payment_button();
// If quotation to is not Customer then remove party
if (this.frm.doctype == "Quotation") {
@@ -342,6 +347,14 @@ erpnext.POS = Class.extend({
this.make_party();
}
},
refresh_item_list: function() {
var me = this;
// refresh item list on change of price list
if (this.frm.doc[this.price_list_field] != this.price_list) {
this.price_list = this.frm.doc[this.price_list_field];
this.make_item_list();
}
},
show_items_in_item_cart: function() {
var me = this;
var $items = this.wrapper.find("#cart tbody").empty();
@@ -351,8 +364,18 @@ erpnext.POS = Class.extend({
$(repl('<tr id="%(item_code)s" data-selected="false">\
<td>%(item_code)s%(item_name)s</td>\
<td><input type="text" value="%(qty)s" \
<td style="vertical-align:middle;" align="right">\
<div class="decrease-qty" style="cursor:pointer;">\
<i class="icon-minus-sign icon-large text-danger"></i>\
</div>\
</td>\
<td style="vertical-align:middle;"><input type="text" value="%(qty)s" \
class="form-control qty" style="text-align: right;"></td>\
<td style="vertical-align:middle;cursor:pointer;">\
<div class="increase-qty" style="cursor:pointer;">\
<i class="icon-plus-sign icon-large text-success"></i>\
</div>\
</td>\
<td style="text-align: right;"><b>%(amount)s</b><br>%(rate)s</td>\
</tr>',
{
@@ -364,27 +387,31 @@ erpnext.POS = Class.extend({
}
)).appendTo($items);
});
this.wrapper.find("input.qty").on("focus", function() {
$(this).select();
});
},
show_taxes: function() {
var me = this;
var taxes = wn.model.get_children(this.sales_or_purchase + " Taxes and Charges",
this.frm.doc.name, this.frm.cscript.other_fname, this.frm.doctype);
$(this.wrapper).find(".tax-table")
.toggle((taxes && taxes.length &&
flt(me.frm.doc.other_charges_total_export ||
me.frm.doc.other_charges_added_import) != 0.0) ? true : false)
.toggle((taxes && taxes.length) ? true : false)
.find("tbody").empty();
$.each(taxes, function(i, d) {
$(repl('<tr>\
<td>%(description)s %(rate)s</td>\
<td style="text-align: right;">%(tax_amount)s</td>\
<tr>', {
description: d.description,
rate: ((d.charge_type == "Actual") ? '' : ("(" + d.rate + "%)")),
tax_amount: format_currency(flt(d.tax_amount)/flt(me.frm.doc.conversion_rate),
me.frm.doc.currency)
})).appendTo(".tax-table tbody");
if (d.tax_amount) {
$(repl('<tr>\
<td>%(description)s %(rate)s</td>\
<td style="text-align: right;">%(tax_amount)s</td>\
<tr>', {
description: d.description,
rate: ((d.charge_type == "Actual") ? '' : ("(" + d.rate + "%)")),
tax_amount: format_currency(flt(d.tax_amount)/flt(me.frm.doc.conversion_rate),
me.frm.doc.currency)
})).appendTo(".tax-table tbody");
}
});
},
set_totals: function() {
@@ -399,10 +426,16 @@ erpnext.POS = Class.extend({
// append quantity to the respective item after change from input box
$(this.wrapper).find("input.qty").on("change", function() {
var item_code = $(this).closest("tr")[0].id;
var item_code = $(this).closest("tr").attr("id");
me.update_qty(item_code, $(this).val());
});
// increase/decrease qty on plus/minus button
$(this.wrapper).find(".increase-qty, .decrease-qty").on("click", function() {
var tr = $(this).closest("tr");
me.increase_decrease_qty(tr, $(this).attr("class"));
});
// on td click toggle the highlighting of row
$(this.wrapper).find("#cart tbody tr td").on("click", function() {
var row = $(this).closest("tr");
@@ -420,6 +453,15 @@ erpnext.POS = Class.extend({
me.refresh_delete_btn();
this.barcode.$input.focus();
},
increase_decrease_qty: function(tr, operation) {
var item_code = tr.attr("id");
var item_qty = cint(tr.find("input.qty").val());
if (operation == "increase-qty")
this.update_qty(item_code, item_qty + 1);
else if (operation == "decrease-qty" && item_qty != 1)
this.update_qty(item_code, item_qty - 1);
},
disable_text_box_and_button: function() {
var me = this;
// if form is submitted & cancelled then disable all input box & buttons
@@ -427,7 +469,7 @@ erpnext.POS = Class.extend({
$(this.wrapper).find('input, button').each(function () {
$(this).prop('disabled', true);
});
$(this.wrapper).find(".delete-items").hide();
$(this.wrapper).find(".remove-items").hide();
$(this.wrapper).find(".make-payment").hide();
}
else {
@@ -437,14 +479,14 @@ erpnext.POS = Class.extend({
$(this.wrapper).find(".make-payment").show();
}
},
make_payment_button: function() {
hide_payment_button: function() {
var me = this;
// Show Make Payment button only in Sales Invoice
if (this.frm.doctype != "Sales Invoice")
$(this.wrapper).find(".make-payment").hide();
},
refresh_delete_btn: function() {
$(this.wrapper).find(".delete-items").toggle($(".item-cart .warning").length ? true : false);
$(this.wrapper).find(".remove-items").toggle($(".item-cart .warning").length ? true : false);
},
add_item_thru_barcode: function() {
var me = this;
@@ -466,7 +508,7 @@ erpnext.POS = Class.extend({
}
});
},
remove_selected_item: function() {
remove_selected_items: function() {
var me = this;
var selected_items = [];
var no_of_items = $(this.wrapper).find("#cart tbody tr").length;
@@ -487,9 +529,11 @@ erpnext.POS = Class.extend({
}
}
});
this.refresh_grid();
},
refresh_grid: function() {
this.frm.dirty();
this.frm.fields_dict[this.frm.cscript.fname].grid.refresh();
this.frm.script_manager.trigger("calculate_taxes_and_totals");
this.refresh();

View File

@@ -54,7 +54,8 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
"voucher_no": doc.name,
"from_date": doc.posting_date,
"to_date": doc.posting_date,
"company": doc.company
"company": doc.company,
group_by_voucher: 0
};
wn.set_route("query-report", "General Ledger");
}, "icon-table");

View File

@@ -88,6 +88,7 @@ class DocType(SellingController):
self.update_status_updater_args()
self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
# this sequence because outstanding may get -ve
self.make_gl_entries()
@@ -114,6 +115,7 @@ class DocType(SellingController):
self.update_status_updater_args()
self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
self.make_cancel_gl_entries()
@@ -318,12 +320,9 @@ class DocType(SellingController):
item = webnotes.conn.sql("select name,is_asset_item,is_sales_item from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())"% d.item_code)
acc = webnotes.conn.sql("select account_type from `tabAccount` where name = '%s' and docstatus != 2" % d.income_account)
if not acc:
msgprint("Account: "+d.income_account+" does not exist in the system")
raise Exception
msgprint("Account: "+d.income_account+" does not exist in the system", raise_exception=True)
elif item and item[0][1] == 'Yes' and not acc[0][0] == 'Fixed Asset Account':
msgprint("Please select income head with account type 'Fixed Asset Account' as Item %s is an asset item" % d.item_code)
raise Exception
msgprint("Please select income head with account type 'Fixed Asset Account' as Item %s is an asset item" % d.item_code, raise_exception=True)
def validate_with_previous_doc(self):
super(DocType, self).validate_with_previous_doc(self.tname, {

View File

@@ -2,7 +2,7 @@
{
"creation": "2013-05-24 19:29:05",
"docstatus": 0,
"modified": "2013-11-18 15:16:50",
"modified": "2014-01-16 15:36:16",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -1091,7 +1091,7 @@
"fieldtype": "Select",
"label": "Recurring Type",
"no_copy": 1,
"options": "Monthly\nQuarterly\nHalf-yearly\nYearly",
"options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly",
"print_hide": 1,
"read_only": 0
},

View File

@@ -565,16 +565,17 @@ class TestSalesInvoice(unittest.TestCase):
where against_invoice=%s""", si.doc.name))
def test_recurring_invoice(self):
from webnotes.utils import now_datetime, get_first_day, get_last_day, add_to_date
today = now_datetime().date()
from webnotes.utils import get_first_day, get_last_day, add_to_date, nowdate, getdate
from accounts.utils import get_fiscal_year
today = nowdate()
base_si = webnotes.bean(copy=test_records[0])
base_si.doc.fields.update({
"convert_into_recurring_invoice": 1,
"recurring_type": "Monthly",
"notification_email_address": "test@example.com, test1@example.com, test2@example.com",
"repeat_on_day_of_month": today.day,
"repeat_on_day_of_month": getdate(today).day,
"posting_date": today,
"fiscal_year": get_fiscal_year(today)[0],
"invoice_period_from_date": get_first_day(today),
"invoice_period_to_date": get_last_day(today)
})

View File

@@ -9,17 +9,19 @@ from accounts.report.accounts_receivable.accounts_receivable import get_ageing_d
def execute(filters=None):
if not filters: filters = {}
columns = get_columns()
supplier_naming_by = webnotes.conn.get_value("Buying Settings", None, "supp_master_name")
columns = get_columns(supplier_naming_by)
entries = get_gl_entries(filters)
account_supplier = dict(webnotes.conn.sql("""select account.name, supplier.supplier_name
from `tabAccount` account, `tabSupplier` supplier
where account.master_type="Supplier" and supplier.name=account.master_name"""))
account_map = dict(((r.name, r) for r in webnotes.conn.sql("""select acc.name,
supp.supplier_name, supp.name as supplier
from `tabAccount` acc, `tabSupplier` supp
where acc.master_type="Supplier" and supp.name=acc.master_name""", as_dict=1)))
entries_after_report_date = [[gle.voucher_type, gle.voucher_no]
for gle in get_gl_entries(filters, before_report_date=False)]
account_supplier_type_map = get_account_supplier_type_map()
pi_map = get_pi_map()
voucher_detail_map = get_voucher_details()
# Age of the invoice on this date
age_on = getdate(filters.get("report_date")) > getdate(nowdate()) \
@@ -29,46 +31,57 @@ def execute(filters=None):
for gle in entries:
if cstr(gle.against_voucher) == gle.voucher_no or not gle.against_voucher \
or [gle.against_voucher_type, gle.against_voucher] in entries_after_report_date:
if gle.voucher_type == "Purchase Invoice":
pi_info = pi_map.get(gle.voucher_no)
due_date = pi_info.get("due_date")
bill_no = pi_info.get("bill_no")
bill_date = pi_info.get("bill_date")
else:
due_date = bill_no = bill_date = ""
voucher_details = voucher_detail_map.get(gle.voucher_type, {}).get(gle.voucher_no, {})
invoiced_amount = gle.credit > 0 and gle.credit or 0
outstanding_amount = get_outstanding_amount(gle,
filters.get("report_date") or nowdate())
if abs(flt(outstanding_amount)) > 0.01:
paid_amount = invoiced_amount - outstanding_amount
row = [gle.posting_date, gle.account, account_supplier.get(gle.account, ""),
gle.voucher_type, gle.voucher_no,
gle.remarks, account_supplier_type_map.get(gle.account), due_date, bill_no,
bill_date, invoiced_amount, paid_amount, outstanding_amount]
row = [gle.posting_date, gle.account, gle.voucher_type, gle.voucher_no,
voucher_details.get("due_date", ""), voucher_details.get("bill_no", ""),
voucher_details.get("bill_date", ""), invoiced_amount,
paid_amount, outstanding_amount]
# Ageing
if filters.get("ageing_based_on") == "Due Date":
ageing_based_on_date = due_date
ageing_based_on_date = voucher_details.get("due_date", "")
else:
ageing_based_on_date = gle.posting_date
row += get_ageing_data(age_on, ageing_based_on_date, outstanding_amount)
row += get_ageing_data(age_on, ageing_based_on_date, outstanding_amount) + \
[account_map.get(gle.account).get("supplier") or ""]
if supplier_naming_by == "Naming Series":
row += [account_map.get(gle.account).get("supplier_name") or ""]
row += [account_supplier_type_map.get(gle.account), gle.remarks]
data.append(row)
for i in range(0, len(data)):
data[i].insert(4, """<a href="%s"><i class="icon icon-share" style="cursor: pointer;"></i></a>""" \
% ("/".join(["#Form", data[i][2], data[i][3]]),))
return columns, data
def get_columns():
return [
"Posting Date:Date:80", "Account:Link/Account:150", "Supplier::150", "Voucher Type::110",
"Voucher No::120", "Remarks::150", "Supplier Type:Link/Supplier Type:120",
"Due Date:Date:80", "Bill No::80", "Bill Date:Date:80",
def get_columns(supplier_naming_by):
columns = [
"Posting Date:Date:80", "Account:Link/Account:150", "Voucher Type::110",
"Voucher No::120", "::30", "Due Date:Date:80", "Bill No::80", "Bill Date:Date:80",
"Invoiced Amount:Currency:100", "Paid Amount:Currency:100",
"Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100",
"30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100"
"30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100",
"Supplier:Link/Supplier:150"
]
if supplier_naming_by == "Naming Series":
columns += ["Supplier Name::110"]
columns += ["Supplier Type:Link/Supplier Type:120", "Remarks::150"]
return columns
def get_gl_entries(filters, before_report_date=True):
conditions, supplier_accounts = get_conditions(filters, before_report_date)
gl_entries = []
@@ -106,20 +119,21 @@ def get_conditions(filters, before_report_date=True):
def get_account_supplier_type_map():
account_supplier_type_map = {}
for each in webnotes.conn.sql("""select t2.name, t1.supplier_type from `tabSupplier` t1,
`tabAccount` t2 where t1.name = t2.master_name group by t2.name"""):
for each in webnotes.conn.sql("""select acc.name, supp.supplier_type from `tabSupplier` supp,
`tabAccount` acc where supp.name = acc.master_name group by acc.name"""):
account_supplier_type_map[each[0]] = each[1]
return account_supplier_type_map
def get_pi_map():
""" get due_date from sales invoice """
pi_map = {}
for t in webnotes.conn.sql("""select name, due_date, bill_no, bill_date
from `tabPurchase Invoice`""", as_dict=1):
pi_map[t.name] = t
def get_voucher_details():
voucher_details = {}
for dt in ["Purchase Invoice", "Journal Voucher"]:
voucher_details.setdefault(dt, webnotes._dict())
for t in webnotes.conn.sql("""select name, due_date, bill_no, bill_date
from `tab%s`""" % dt, as_dict=1):
voucher_details[dt].setdefault(t.name, t)
return pi_map
return voucher_details
def get_outstanding_amount(gle, report_date):
payment_amount = webnotes.conn.sql("""

View File

@@ -15,26 +15,37 @@ class AccountsReceivableReport(object):
else self.filters.report_date
def run(self):
return self.get_columns(), self.get_data()
customer_naming_by = webnotes.conn.get_value("Selling Settings", None, "cust_master_name")
return self.get_columns(customer_naming_by), self.get_data(customer_naming_by)
def get_columns(self):
return [
def get_columns(self, customer_naming_by):
columns = [
"Posting Date:Date:80", "Account:Link/Account:150",
"Voucher Type::110", "Voucher No::120", "::30",
"Due Date:Date:80",
"Invoiced Amount:Currency:100", "Payment Received:Currency:100",
"Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100",
"30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100",
"Customer:Link/Customer:200", "Territory:Link/Territory:80", "Remarks::200"
"Customer:Link/Customer:200"
]
def get_data(self):
if customer_naming_by == "Naming Series":
columns += ["Customer Name::110"]
columns += ["Territory:Link/Territory:80", "Remarks::200"]
return columns
def get_data(self, customer_naming_by):
from accounts.utils import get_currency_precision
currency_precision = get_currency_precision() or 2
data = []
future_vouchers = self.get_entries_after(self.filters.report_date)
for gle in self.get_entries_till(self.filters.report_date):
if self.is_receivable(gle, future_vouchers):
outstanding_amount = self.get_outstanding_amount(gle, self.filters.report_date)
if abs(outstanding_amount) > 0.01:
if abs(outstanding_amount) > 0.1/10**currency_precision:
due_date = self.get_due_date(gle)
invoiced_amount = gle.debit if (gle.debit > 0) else 0
payment_received = invoiced_amount - outstanding_amount
@@ -42,18 +53,23 @@ class AccountsReceivableReport(object):
gle.voucher_type, gle.voucher_no, due_date,
invoiced_amount, payment_received,
outstanding_amount]
entry_date = due_date if self.filters.ageing_based_on=="Due Date" \
entry_date = due_date if self.filters.ageing_based_on == "Due Date" \
else gle.posting_date
row += get_ageing_data(self.age_as_on, entry_date, outstanding_amount)
row += [self.get_customer(gle.account), self.get_territory(gle.account), gle.remarks]
row += get_ageing_data(self.age_as_on, entry_date, outstanding_amount) + \
[self.get_customer(gle.account)]
if customer_naming_by == "Naming Series":
row += [self.get_customer_name(gle.account)]
row += [self.get_territory(gle.account), gle.remarks]
data.append(row)
for i in range(0,len(data)):
for i in range(0, len(data)):
data[i].insert(4, """<a href="%s"><i class="icon icon-share" style="cursor: pointer;"></i></a>""" \
% ("/".join(["#Form", data[i][2], data[i][3]]),))
return data
def get_entries_after(self, report_date):
# returns a distinct list
return list(set([(e.voucher_type, e.voucher_no) for e in self.get_gl_entries()
@@ -65,30 +81,41 @@ class AccountsReceivableReport(object):
if getdate(e.posting_date) <= report_date)
def is_receivable(self, gle, future_vouchers):
return ((not gle.against_voucher) or (gle.against_voucher==gle.voucher_no) or
((gle.against_voucher_type, gle.against_voucher) in future_vouchers))
return (
# advance
(not gle.against_voucher) or
# sales invoice
(gle.against_voucher==gle.voucher_no and gle.debit > 0) or
# entries adjusted with future vouchers
((gle.against_voucher_type, gle.against_voucher) in future_vouchers)
)
def get_outstanding_amount(self, gle, report_date):
payment_received = 0.0
for e in self.get_gl_entries_for(gle.account, gle.voucher_type, gle.voucher_no):
if getdate(e.posting_date) <= report_date and e.name!=gle.name:
payment_received += (flt(e.credit) - flt(e.debit))
return flt(gle.debit) - flt(gle.credit) - payment_received
def get_customer(self, account):
return self.get_account_map().get(account).get("customer") or ""
def get_customer_name(self, account):
return self.get_account_map().get(account).get("customer_name") or ""
def get_territory(self, account):
return self.get_account_map().get(account).get("territory") or ""
def get_account_map(self):
if not hasattr(self, "account_map"):
self.account_map = dict(((r.name, r) for r in webnotes.conn.sql("""select
account.name, customer.name as customer_name, customer.territory
from `tabAccount` account, `tabCustomer` customer
where account.master_type="Customer"
and customer.name=account.master_name""", as_dict=True)))
acc.name, cust.name as customer, cust.customer_name, cust.territory
from `tabAccount` acc, `tabCustomer` cust
where acc.master_type="Customer"
and cust.name=acc.master_name""", as_dict=True)))
return self.account_map
@@ -147,7 +174,7 @@ class AccountsReceivableReport(object):
def execute(filters=None):
return AccountsReceivableReport(filters).run()
def get_ageing_data(age_as_on, entry_date, outstanding_amount):
# [0-30, 30-60, 60-90, 90-above]
outstanding_range = [0.0, 0.0, 0.0, 0.0]

View File

@@ -8,6 +8,7 @@ wn.query_reports["Bank Reconciliation Statement"] = {
"label": wn._("Bank Account"),
"fieldtype": "Link",
"options": "Account",
"reqd": 1,
"get_query": function() {
return {
"query": "accounts.utils.get_account_list",
@@ -22,7 +23,8 @@ wn.query_reports["Bank Reconciliation Statement"] = {
"fieldname":"report_date",
"label": wn._("Date"),
"fieldtype": "Date",
"default": get_today()
"default": get_today(),
"reqd": 1
},
]
}

View File

@@ -3,13 +3,14 @@
from __future__ import unicode_literals
import webnotes
from webnotes import _, msgprint
from webnotes.utils import flt
def execute(filters=None):
if not filters: filters = {}
columns = get_columns()
debit_or_credit = webnotes.conn.get_value("Account", filters["account"], "debit_or_credit")
columns = get_columns()
data = get_entries(filters)
from accounts.utils import get_balance_on
@@ -20,47 +21,39 @@ def execute(filters=None):
total_debit += flt(d[4])
total_credit += flt(d[5])
if webnotes.conn.get_value("Account", filters["account"], "debit_or_credit") == 'Debit':
if debit_or_credit == 'Debit':
bank_bal = flt(balance_as_per_company) - flt(total_debit) + flt(total_credit)
else:
bank_bal = flt(balance_as_per_company) + flt(total_debit) - flt(total_credit)
data += [
["", "", "", "Balance as per company books", balance_as_per_company, ""],
get_balance_row("Balance as per company books", balance_as_per_company, debit_or_credit),
["", "", "", "Amounts not reflected in bank", total_debit, total_credit],
["", "", "", "Balance as per bank", bank_bal, ""]
get_balance_row("Balance as per bank", bank_bal, debit_or_credit)
]
return columns, data
return columns, data
def get_columns():
return ["Journal Voucher:Link/Journal Voucher:140", "Posting Date:Date:100",
"Clearance Date:Date:110", "Against Account:Link/Account:200",
"Debit:Currency:120", "Credit:Currency:120"
]
def get_conditions(filters):
conditions = ""
if not filters.get("account"):
msgprint(_("Please select Bank Account"), raise_exception=1)
else:
conditions += " and jvd.account = %(account)s"
if not filters.get("report_date"):
msgprint(_("Please select Date on which you want to run the report"), raise_exception=1)
else:
conditions += """ and jv.posting_date <= %(report_date)s
and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s"""
return conditions
def get_entries(filters):
conditions = get_conditions(filters)
entries = webnotes.conn.sql("""select jv.name, jv.posting_date, jv.clearance_date,
jvd.against_account, jvd.debit, jvd.credit
from `tabJournal Voucher Detail` jvd, `tabJournal Voucher` jv
where jvd.parent = jv.name and jv.docstatus=1 and ifnull(jv.cheque_no, '')!= '' %s
order by jv.name DESC""" % conditions, filters, as_list=1)
entries = webnotes.conn.sql("""select
jv.name, jv.posting_date, jv.clearance_date, jvd.against_account, jvd.debit, jvd.credit
from
`tabJournal Voucher Detail` jvd, `tabJournal Voucher` jv
where jvd.parent = jv.name and jv.docstatus=1 and ifnull(jv.cheque_no, '')!= ''
and jvd.account = %(account)s and jv.posting_date <= %(report_date)s
and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s
order by jv.name DESC""", filters, as_list=1)
return entries
return entries
def get_balance_row(label, amount, debit_or_credit):
if debit_or_credit == "Debit":
return ["", "", "", label, amount, 0]
else:
return ["", "", "", label, 0, amount]

View File

@@ -38,7 +38,7 @@ wn.query_reports["General Ledger"] = {
"get_query": function() {
var company = wn.query_report.filters_by_name.company.get_value();
return {
"query": "accounts.utils.get_account_list",
"doctype": "Account",
"filters": {
"company": company,
}

View File

@@ -34,7 +34,7 @@ def validate_filters(filters, account_details):
def get_columns():
return ["Posting Date:Date:100", "Account:Link/Account:200", "Debit:Float:100",
"Credit:Float:100", "Voucher Type::120", "Voucher No::160", "Link::20",
"Against Account::120", "Cost Center:Link/Cost Center:100", "Remarks::200"]
"Against Account::120", "Cost Center:Link/Cost Center:100", "Remarks::400"]
def get_result(filters, account_details):
gl_entries = get_gl_entries(filters)
@@ -51,7 +51,7 @@ def get_gl_entries(filters):
gl_entries = webnotes.conn.sql("""select posting_date, account,
sum(ifnull(debit, 0)) as debit, sum(ifnull(credit, 0)) as credit,
voucher_type, voucher_no, cost_center, remarks, is_advance, against
voucher_type, voucher_no, cost_center, remarks, is_opening, against
from `tabGL Entry`
where company=%(company)s {conditions}
{group_by_condition}
@@ -72,6 +72,11 @@ def get_conditions(filters):
if filters.get("voucher_no"):
conditions.append("voucher_no=%(voucher_no)s")
from webnotes.widgets.reportview import build_match_conditions
match_conditions = build_match_conditions("GL Entry")
if match_conditions: conditions.append(match_conditions)
return "and {}".format(" and ".join(conditions)) if conditions else ""
@@ -133,10 +138,10 @@ def get_accountwise_gle(filters, gl_entries, gle_map):
for gle in gl_entries:
amount = flt(gle.debit) - flt(gle.credit)
if filters.get("account") and (gle.posting_date < filters.from_date
or cstr(gle.is_advance) == "Yes"):
or cstr(gle.is_opening) == "Yes"):
gle_map[gle.account].opening += amount
opening += amount
elif gle.posting_date < filters.to_date:
elif gle.posting_date <= filters.to_date:
gle_map[gle.account].entries.append(gle)
gle_map[gle.account].total_debit += flt(gle.debit)
gle_map[gle.account].total_credit += flt(gle.credit)

View File

@@ -12,7 +12,8 @@ def execute(filters=None):
item_list = get_items(filters)
aii_account_map = get_aii_accounts()
item_tax, tax_accounts = get_tax_accounts(item_list, columns)
if item_list:
item_tax, tax_accounts = get_tax_accounts(item_list, columns)
data = []
for d in item_list:

View File

@@ -11,7 +11,8 @@ def execute(filters=None):
last_col = len(columns)
item_list = get_items(filters)
item_tax, tax_accounts = get_tax_accounts(item_list, columns)
if item_list:
item_tax, tax_accounts = get_tax_accounts(item_list, columns)
data = []
for d in item_list:
@@ -39,7 +40,6 @@ def get_columns():
"Qty:Float:120", "Rate:Currency:120", "Amount:Currency:120"
]
def get_conditions(filters):
conditions = ""

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import nowdate, nowtime, cstr, flt, now, getdate, add_months
from webnotes.utils import nowdate, cstr, flt, now, getdate, add_months
from webnotes.model.doc import addchild
from webnotes import msgprint, _
from webnotes.utils import formatdate
@@ -31,6 +31,8 @@ def get_fiscal_years(date=None, fiscal_year=None, label="Date", verbose=1):
if not fy:
error_msg = """%s %s not in any Fiscal Year""" % (label, formatdate(date))
error_msg = """{msg}: {date}""".format(msg=_("Fiscal Year does not exist for date"),
date=formatdate(date))
if verbose: webnotes.msgprint(error_msg)
raise FiscalYearError, error_msg
@@ -62,7 +64,6 @@ def get_balance_on(account=None, date=None):
try:
year_start_date = get_fiscal_year(date, verbose=0)[1]
except FiscalYearError, e:
from webnotes.utils import getdate
if getdate(date) > getdate(nowdate()):
# if fiscal year not found and the date is greater than today
# get fiscal year for today's date and its corresponding year start date
@@ -220,17 +221,26 @@ def get_cost_center_list(doctype, txt, searchfield, start, page_len, filters):
tuple(filter_values + ["%%%s%%" % txt, start, page_len]))
def remove_against_link_from_jv(ref_type, ref_no, against_field):
webnotes.conn.sql("""update `tabJournal Voucher Detail` set `%s`=null,
modified=%s, modified_by=%s
where `%s`=%s and docstatus < 2""" % (against_field, "%s", "%s", against_field, "%s"),
(now(), webnotes.session.user, ref_no))
linked_jv = webnotes.conn.sql_list("""select parent from `tabJournal Voucher Detail`
where `%s`=%s and docstatus < 2""" % (against_field, "%s"), (ref_no))
if linked_jv:
webnotes.conn.sql("""update `tabJournal Voucher Detail` set `%s`=null,
modified=%s, modified_by=%s
where `%s`=%s and docstatus < 2""" % (against_field, "%s", "%s", against_field, "%s"),
(now(), webnotes.session.user, ref_no))
webnotes.conn.sql("""update `tabGL Entry`
set against_voucher_type=null, against_voucher=null,
modified=%s, modified_by=%s
where against_voucher_type=%s and against_voucher=%s
and voucher_no != ifnull(against_voucher, '')""",
(now(), webnotes.session.user, ref_type, ref_no))
webnotes.conn.sql("""update `tabGL Entry`
set against_voucher_type=null, against_voucher=null,
modified=%s, modified_by=%s
where against_voucher_type=%s and against_voucher=%s
and voucher_no != ifnull(against_voucher, '')""",
(now(), webnotes.session.user, ref_type, ref_no))
webnotes.msgprint("{msg} {linked_jv}".format(msg = _("""Following linked Journal Vouchers \
made against this transaction has been unlinked. You can link them again with other \
transactions via Payment Reconciliation Tool."""), linked_jv="\n".join(linked_jv)))
@webnotes.whitelist()
def get_company_default(company, fieldname):
@@ -369,3 +379,12 @@ def get_account_for(account_for_doctype, account_for):
return webnotes.conn.get_value("Account", {account_for_field: account_for_doctype,
"master_name": account_for})
def get_currency_precision(currency=None):
if not currency:
currency = webnotes.conn.get_value("Company",
webnotes.conn.get_default("company"), "default_currency")
currency_format = webnotes.conn.get_value("Currency", currency, "number_format")
from webnotes.utils import get_number_format_info
return get_number_format_info(currency_format)[2]

View File

@@ -22,7 +22,7 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
if(this.frm.fields_dict.buying_price_list) {
this.frm.set_query("buying_price_list", function() {
return{
filters: { 'buying_or_selling': "Buying" }
filters: { 'buying': 1 }
}
});
}
@@ -302,11 +302,11 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
calculate_totals: function() {
var tax_count = this.frm.tax_doclist.length;
this.frm.doc.grand_total = flt(
tax_count ? this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total,
this.frm.doc.grand_total = flt(tax_count ?
this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total,
precision("grand_total"));
this.frm.doc.grand_total_import = flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate,
precision("grand_total_import"));
this.frm.doc.grand_total_import = flt(this.frm.doc.grand_total /
this.frm.doc.conversion_rate, precision("grand_total_import"));
this.frm.doc.total_tax = flt(this.frm.doc.grand_total - this.frm.doc.net_total,
precision("total_tax"));
@@ -321,20 +321,26 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
}
// other charges added/deducted
this.frm.doc.other_charges_added = 0.0
this.frm.doc.other_charges_deducted = 0.0
if(tax_count) {
this.frm.doc.other_charges_added = wn.utils.sum($.map(this.frm.tax_doclist,
function(tax) { return (tax.add_deduct_tax == "Add" && in_list(["Valuation and Total", "Total"], tax.category)) ? tax.tax_amount : 0.0; }));
function(tax) { return (tax.add_deduct_tax == "Add"
&& in_list(["Valuation and Total", "Total"], tax.category)) ?
tax.tax_amount : 0.0; }));
this.frm.doc.other_charges_deducted = wn.utils.sum($.map(this.frm.tax_doclist,
function(tax) { return (tax.add_deduct_tax == "Deduct" && in_list(["Valuation and Total", "Total"], tax.category)) ? tax.tax_amount : 0.0; }));
function(tax) { return (tax.add_deduct_tax == "Deduct"
&& in_list(["Valuation and Total", "Total"], tax.category)) ?
tax.tax_amount : 0.0; }));
wn.model.round_floats_in(this.frm.doc, ["other_charges_added", "other_charges_deducted"]);
this.frm.doc.other_charges_added_import = flt(this.frm.doc.other_charges_added / this.frm.doc.conversion_rate,
precision("other_charges_added_import"));
this.frm.doc.other_charges_deducted_import = flt(this.frm.doc.other_charges_deducted / this.frm.doc.conversion_rate,
precision("other_charges_deducted_import"));
wn.model.round_floats_in(this.frm.doc,
["other_charges_added", "other_charges_deducted"]);
}
this.frm.doc.other_charges_added_import = flt(this.frm.doc.other_charges_added /
this.frm.doc.conversion_rate, precision("other_charges_added_import"));
this.frm.doc.other_charges_deducted_import = flt(this.frm.doc.other_charges_deducted /
this.frm.doc.conversion_rate, precision("other_charges_deducted_import"));
},
_cleanup: function() {

View File

@@ -22,7 +22,7 @@ class TestPurchaseOrder(unittest.TestCase):
pr = make_purchase_receipt(po.doc.name)
pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC"
pr[0]["posting_date"] = "2013-05-12"
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
self.assertEquals(len(pr), len(test_records[0]))
@@ -52,7 +52,7 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
self.assertEquals(len(pr), len(test_records[0]))
pr[0]["posting_date"] = "2013-05-12"
pr[0].naming_series = "_T-Purchase Receipt-"
pr[1].qty = 4.0
pr_bean = webnotes.bean(pr)
@@ -66,6 +66,7 @@ class TestPurchaseOrder(unittest.TestCase):
pr1 = make_purchase_receipt(po.doc.name)
pr1[0].naming_series = "_T-Purchase Receipt-"
pr1[0]["posting_date"] = "2013-05-12"
pr1[1].qty = 8
pr1_bean = webnotes.bean(pr1)
pr1_bean.insert()
@@ -88,7 +89,7 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEquals(pi[0]["doctype"], "Purchase Invoice")
self.assertEquals(len(pi), len(test_records[0]))
pi[0]["posting_date"] = "2013-05-12"
pi[0].bill_no = "NA"
webnotes.bean(pi).insert()

View File

@@ -3,7 +3,7 @@
wn.require('app/setup/doctype/contact_control/contact_control.js');
cur_frm.cscript.refresh = function(doc,dt,dn) {
cur_frm.cscript.refresh = function(doc, dt, dn) {
cur_frm.cscript.make_dashboard(doc);
erpnext.hide_naming_series();
@@ -93,8 +93,8 @@ cur_frm.cscript.make_contact = function() {
cur_frm.contact_list.run();
}
cur_frm.fields_dict['default_price_list'].get_query = function(doc,cdt,cdn) {
cur_frm.fields_dict['default_price_list'].get_query = function(doc, cdt, cdn) {
return{
filters:{'buying_or_selling': "Buying"}
filters:{'buying': 1}
}
}

View File

@@ -2,7 +2,7 @@
{
"creation": "2013-05-13 16:10:02",
"docstatus": 0,
"modified": "2013-05-13 16:21:07",
"modified": "2014-01-24 18:19:11",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -11,7 +11,7 @@
"doctype": "Report",
"is_standard": "Yes",
"name": "__common__",
"query": "select \n mr.name as \"Material Request:Link/Material Request:120\",\n\tmr.transaction_date as \"Date:Date:100\",\n\tmr_item.item_code as \"Item Code:Link/Item:120\",\n\tmr_item.qty as \"Qty:Float:100\",\n\tmr_item.ordered_qty as \"Ordered Qty:Float:100\", \n\t(mr_item.qty - ifnull(mr_item.ordered_qty, 0)) as \"Qty to Order:Float:100\",\n\tmr_item.item_name as \"Item Name::150\",\n\tmr_item.description as \"Description::200\"\nfrom\n\t`tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere\n\tmr_item.parent = mr.name\n\tand mr.material_request_type = \"Purchase\"\n\tand mr.docstatus = 1\n\tand mr.status != \"Stopped\"\n\tand ifnull(mr_item.ordered_qty, 0) < ifnull(mr_item.qty, 0)\norder by mr.transaction_date asc",
"query": "select \n mr.name as \"Material Request:Link/Material Request:120\",\n\tmr.transaction_date as \"Date:Date:100\",\n\tmr_item.item_code as \"Item Code:Link/Item:120\",\n\tsum(ifnull(mr_item.qty, 0)) as \"Qty:Float:100\",\n\tsum(ifnull(mr_item.ordered_qty, 0)) as \"Ordered Qty:Float:100\", \n\t(sum(mr_item.qty) - sum(ifnull(mr_item.ordered_qty, 0))) as \"Qty to Order:Float:100\",\n\tmr_item.item_name as \"Item Name::150\",\n\tmr_item.description as \"Description::200\"\nfrom\n\t`tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere\n\tmr_item.parent = mr.name\n\tand mr.material_request_type = \"Purchase\"\n\tand mr.docstatus = 1\n\tand mr.status != \"Stopped\"\ngroup by mr.name, mr_item.item_code\nhaving\n\tsum(ifnull(mr_item.ordered_qty, 0)) < sum(ifnull(mr_item.qty, 0))\norder by mr.transaction_date asc",
"ref_doctype": "Purchase Order",
"report_name": "Requested Items To Be Ordered",
"report_type": "Query Report"

View File

@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes import msgprint, _
from webnotes import msgprint, _, throw
from webnotes.utils import getdate, flt, add_days, cstr
import json
@@ -89,8 +89,10 @@ def _get_price_list_rate(args, item_bean, meta):
# try fetching from price list
if args.buying_price_list and args.price_list_currency:
price_list_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
where price_list=%s and item_code=%s and buying_or_selling='Buying'""",
price_list_rate = webnotes.conn.sql("""select ip.ref_rate from
`tabItem Price` ip, `tabPrice List` pl
where ip.price_list=pl.name and ip.price_list=%s and
ip.item_code=%s and ip.buying=1 and pl.enabled=1""",
(args.buying_price_list, args.item_code), as_dict=1)
if price_list_rate:
@@ -122,14 +124,12 @@ def _validate_item_details(args, item):
# validate if purchase item or subcontracted item
if item.is_purchase_item != "Yes":
msgprint(_("Item") + (" %s: " % item.name) + _("not a purchase item"),
raise_exception=True)
throw(_("Item") + (" %s: " % item.name) + _("not a purchase item"))
if args.is_subcontracted == "Yes" and item.is_sub_contracted_item != "Yes":
msgprint(_("Item") + (" %s: " % item.name) +
throw(_("Item") + (" %s: " % item.name) +
_("not a sub-contracted item.") +
_("Please select a sub-contracted item or do not sub-contract the transaction."),
raise_exception=True)
_("Please select a sub-contracted item or do not sub-contract the transaction."))
def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
"""returns last purchase details in stock uom"""

View File

@@ -1,6 +1,6 @@
{
"app_name": "ERPNext",
"app_version": "3.4.1",
"app_version": "3.7.0",
"base_template": "app/portal/templates/base.html",
"modules": {
"Accounts": {
@@ -74,5 +74,5 @@
"type": "module"
}
},
"requires_framework_version": "==3.4.1"
"requires_framework_version": "==3.8.0"
}

View File

@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes import _, msgprint
from webnotes import _, throw
from webnotes.utils import flt, cint, today, cstr
from webnotes.model.code import get_obj
from setup.utils import get_company_currency
@@ -44,14 +44,13 @@ class AccountsController(TransactionBase):
def validate_for_freezed_account(self):
for fieldname in ["customer", "supplier"]:
if self.meta.get_field(fieldname) and self.doc.fields.get(fieldname):
accounts = webnotes.conn.get_values("Account", {"master_type": fieldname.title(),
"master_name": self.doc.fields[fieldname], "company": self.doc.company},
"freeze_account", as_dict=1)
accounts = webnotes.conn.get_values("Account",
{"master_type": fieldname.title(), "master_name": self.doc.fields[fieldname],
"company": self.doc.company}, "name")
if accounts:
if not filter(lambda x: cstr(x.freeze_account) in ["", "No"], accounts):
msgprint(_("Account for this ") + fieldname + _(" has been freezed. ") +
self.doc.doctype + _(" can not be made."), raise_exception=1)
from accounts.doctype.gl_entry.gl_entry import validate_frozen_account
for account in accounts:
validate_frozen_account(account[0])
def set_price_list_currency(self, buying_or_selling):
if self.meta.get_field("currency"):
@@ -179,17 +178,17 @@ class AccountsController(TransactionBase):
"""
if tax.charge_type in ["On Previous Row Amount", "On Previous Row Total"] and \
(not tax.row_id or cint(tax.row_id) >= tax.idx):
msgprint((_("Row") + " # %(idx)s [%(taxes_doctype)s]: " + \
throw((_("Row") + " # %(idx)s [%(taxes_doctype)s]: " + \
_("Please specify a valid") + " %(row_id_label)s") % {
"idx": tax.idx,
"taxes_doctype": tax.doctype,
"row_id_label": self.meta.get_label("row_id",
parentfield=self.other_fname)
}, raise_exception=True)
})
def validate_inclusive_tax(self, tax):
def _on_previous_row_error(row_range):
msgprint((_("Row") + " # %(idx)s [%(doctype)s]: " +
throw((_("Row") + " # %(idx)s [%(doctype)s]: " +
_("to be included in Item's rate, it is required that: ") +
" [" + _("Row") + " # %(row_range)s] " + _("also be included in Item's rate")) % {
"idx": tax.idx,
@@ -200,12 +199,12 @@ class AccountsController(TransactionBase):
parentfield=self.other_fname),
"charge_type": tax.charge_type,
"row_range": row_range
}, raise_exception=True)
})
if cint(tax.included_in_print_rate):
if tax.charge_type == "Actual":
# inclusive tax cannot be of type Actual
msgprint((_("Row")
throw((_("Row")
+ " # %(idx)s [%(doctype)s]: %(charge_type_label)s = \"%(charge_type)s\" "
+ "cannot be included in Item's rate") % {
"idx": tax.idx,
@@ -213,7 +212,7 @@ class AccountsController(TransactionBase):
"charge_type_label": self.meta.get_label("charge_type",
parentfield=self.other_fname),
"charge_type": tax.charge_type,
}, raise_exception=True)
})
elif tax.charge_type == "On Previous Row Amount" and \
not cint(self.tax_doclist[tax.row_id - 1].included_in_print_rate):
# referred row should also be inclusive
@@ -224,23 +223,22 @@ class AccountsController(TransactionBase):
_on_previous_row_error("1 - %d" % (tax.row_id,))
def calculate_taxes(self):
for item in self.item_doclist:
# maintain actual tax rate based on idx
actual_tax_dict = dict([[tax.idx, tax.rate] for tax in self.tax_doclist
if tax.charge_type == "Actual"])
for n, item in enumerate(self.item_doclist):
item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
for i, tax in enumerate(self.tax_doclist):
# tax_amount represents the amount of tax for the current step
current_tax_amount = self.get_current_tax_amount(item, tax, item_tax_map)
if hasattr(self, "set_item_tax_amount"):
self.set_item_tax_amount(item, tax, current_tax_amount)
# case when net total is 0 but there is an actual type charge
# in this case add the actual amount to tax.tax_amount
# and tax.grand_total_for_current_item for the first such iteration
if tax.charge_type=="Actual" and \
not (current_tax_amount or self.doc.net_total or tax.tax_amount):
zero_net_total_adjustment = flt(tax.rate, self.precision("tax_amount", tax))
current_tax_amount += zero_net_total_adjustment
# Adjust divisional loss to the last item
if tax.charge_type == "Actual":
actual_tax_dict[tax.idx] -= current_tax_amount
if n == len(self.item_doclist) - 1:
current_tax_amount += actual_tax_dict[tax.idx]
# store tax_amount for current item as it will be used for
# charge type = 'On Previous Row Amount'
@@ -252,7 +250,8 @@ class AccountsController(TransactionBase):
if tax.category:
# if just for valuation, do not add the tax amount in total
# hence, setting it as 0 for further steps
current_tax_amount = 0.0 if (tax.category == "Valuation") else current_tax_amount
current_tax_amount = 0.0 if (tax.category == "Valuation") \
else current_tax_amount
current_tax_amount *= -1.0 if (tax.add_deduct_tax == "Deduct") else 1.0
@@ -271,6 +270,11 @@ class AccountsController(TransactionBase):
# in tax.total, accumulate grand total of each item
tax.total += tax.grand_total_for_current_item
# set precision in the last item iteration
if n == len(self.item_doclist) - 1:
tax.total = flt(tax.total, self.precision("total", tax))
tax.tax_amount = flt(tax.tax_amount, self.precision("tax_amount", tax))
def get_current_tax_amount(self, item, tax, item_tax_map):
tax_rate = self._get_tax_rate(tax, item_tax_map)
current_tax_amount = 0.0
@@ -384,24 +388,45 @@ class AccountsController(TransactionBase):
})
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
from controllers.status_updater import get_tolerance_for
item_tolerance = {}
global_tolerance = None
for item in self.doclist.get({"parentfield": "entries"}):
if item.fields.get(item_ref_dn):
already_billed = webnotes.conn.sql("""select sum(%s) from `tab%s`
where %s=%s and docstatus=1""" % (based_on, self.tname, item_ref_dn, '%s'),
item.fields[item_ref_dn])[0][0]
max_allowed_amt = flt(webnotes.conn.get_value(ref_dt + " Item",
ref_amt = flt(webnotes.conn.get_value(ref_dt + " Item",
item.fields[item_ref_dn], based_on), self.precision(based_on, item))
if not ref_amt:
webnotes.msgprint(_("As amount for item") + ": " + item.item_code + _(" in ") +
ref_dt + _(" is zero, system will not check for over-billed"))
else:
already_billed = webnotes.conn.sql("""select sum(%s) from `tab%s`
where %s=%s and docstatus=1 and parent != %s""" %
(based_on, self.tname, item_ref_dn, '%s', '%s'),
(item.fields[item_ref_dn], self.doc.name))[0][0]
total_billed_amt = flt(flt(already_billed) + flt(item.fields[based_on]),
self.precision(based_on, item))
total_billed_amt = flt(flt(already_billed) + flt(item.fields[based_on]),
self.precision(based_on, item))
tolerance, item_tolerance, global_tolerance = get_tolerance_for(item.item_code,
item_tolerance, global_tolerance)
if max_allowed_amt and total_billed_amt - max_allowed_amt > 0.02:
webnotes.msgprint(_("Row ")+ cstr(item.idx) + ": " + cstr(item.item_code) +
_(" will be over-billed against mentioned ") + cstr(ref_dt) +
_(". Max allowed " + cstr(based_on) + ": " + cstr(max_allowed_amt)),
raise_exception=1)
max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100)
if total_billed_amt - max_allowed_amt > 0.01:
reduce_by = total_billed_amt - max_allowed_amt
webnotes.throw(_("Row #") + cstr(item.idx) + ": " +
_(" Max amount allowed for Item ") + cstr(item.item_code) +
_(" against ") + ref_dt + " " +
cstr(item.fields[ref_dt.lower().replace(" ", "_")]) + _(" is ") +
cstr(max_allowed_amt) + ". \n" +
_("""If you want to increase your overflow tolerance, please increase \
tolerance % in Global Defaults or Item master.
Or, you must reduce the amount by """) + cstr(reduce_by) + "\n" +
_("""Also, please check if the order item has already been billed \
in the Sales Order"""))
def get_company_default(self, fieldname):
from accounts.utils import get_company_default
return get_company_default(self.doc.company, fieldname)

View File

@@ -124,8 +124,8 @@ class BuyingController(StockController):
self.round_floats_in(self.doc, ["net_total", "net_total_import"])
def calculate_totals(self):
self.doc.grand_total = flt(self.tax_doclist and \
self.tax_doclist[-1].total or self.doc.net_total, self.precision("grand_total"))
self.doc.grand_total = flt(self.tax_doclist[-1].total if self.tax_doclist
else self.doc.net_total, self.precision("grand_total"))
self.doc.grand_total_import = flt(self.doc.grand_total / self.doc.conversion_rate,
self.precision("grand_total_import"))
@@ -137,6 +137,24 @@ class BuyingController(StockController):
if self.meta.get_field("rounded_total_import"):
self.doc.rounded_total_import = _round(self.doc.grand_total_import)
if self.meta.get_field("other_charges_added"):
self.doc.other_charges_added = flt(sum([flt(d.tax_amount) for d in self.tax_doclist
if d.add_deduct_tax=="Add" and d.category in ["Valuation and Total", "Total"]]),
self.precision("other_charges_added"))
if self.meta.get_field("other_charges_deducted"):
self.doc.other_charges_deducted = flt(sum([flt(d.tax_amount) for d in self.tax_doclist
if d.add_deduct_tax=="Deduct" and d.category in ["Valuation and Total", "Total"]]),
self.precision("other_charges_deducted"))
if self.meta.get_field("other_charges_added_import"):
self.doc.other_charges_added_import = flt(self.doc.other_charges_added /
self.doc.conversion_rate, self.precision("other_charges_added_import"))
if self.meta.get_field("other_charges_deducted_import"):
self.doc.other_charges_deducted_import = flt(self.doc.other_charges_deducted /
self.doc.conversion_rate, self.precision("other_charges_deducted_import"))
def calculate_outstanding_amount(self):
if self.doc.doctype == "Purchase Invoice" and self.doc.docstatus < 2:
@@ -163,30 +181,49 @@ class BuyingController(StockController):
if not self.meta.get_field("item_tax_amount", parentfield=self.fname):
for item in self.item_doclist:
del item.fields["item_tax_amount"]
def set_item_tax_amount(self, item, tax, current_tax_amount):
# update valuation rate
def update_valuation_rate(self, parentfield):
"""
item_tax_amount is the total tax amount applied on that item
stored for valuation
TODO: rename item_tax_amount to valuation_tax_amount
"""
if tax.category in ["Valuation", "Valuation and Total"] and \
self.meta.get_field("item_tax_amount", parentfield=self.fname):
item.item_tax_amount += flt(current_tax_amount, self.precision("item_tax_amount", item))
# update valuation rate
def update_valuation_rate(self, parentfield):
for item in self.doclist.get({"parentfield": parentfield}):
item.conversion_factor = item.conversion_factor or flt(webnotes.conn.get_value(
"UOM Conversion Detail", {"parent": item.item_code, "uom": item.uom},
"conversion_factor")) or 1
stock_items = self.get_stock_items()
stock_items_qty, stock_items_amount = 0, 0
last_stock_item_idx = 1
for d in self.doclist.get({"parentfield": parentfield}):
if d.item_code and d.item_code in stock_items:
stock_items_qty += flt(d.qty)
stock_items_amount += flt(d.amount)
last_stock_item_idx = d.idx
if item.item_code and item.qty:
total_valuation_amount = sum([flt(d.tax_amount) for d in
self.doclist.get({"parentfield": "purchase_tax_details"})
if d.category in ["Valuation", "Valuation and Total"]])
valuation_amount_adjustment = total_valuation_amount
for i, item in enumerate(self.doclist.get({"parentfield": parentfield})):
if item.item_code and item.qty and item.item_code in stock_items:
item_proportion = flt(item.amount) / stock_items_amount if stock_items_amount \
else flt(item.qty) / stock_items_qty
if i == (last_stock_item_idx - 1):
item.item_tax_amount = flt(valuation_amount_adjustment,
self.precision("item_tax_amount", item))
else:
item.item_tax_amount = flt(item_proportion * total_valuation_amount,
self.precision("item_tax_amount", item))
valuation_amount_adjustment -= item.item_tax_amount
self.round_floats_in(item)
# if no item code, which is sometimes the case in purchase invoice,
# then it is not possible to track valuation against it
item.conversion_factor = item.conversion_factor or flt(webnotes.conn.get_value(
"UOM Conversion Detail", {"parent": item.item_code, "uom": item.uom},
"conversion_factor")) or 1
qty_in_stock_uom = flt(item.qty * item.conversion_factor)
item.valuation_rate = ((item.amount + item.item_tax_amount + item.rm_supp_cost)
/ qty_in_stock_uom)

View File

@@ -191,7 +191,8 @@ class SellingController(StockController):
self.doc.other_charges_total = flt(self.doc.grand_total - self.doc.net_total,
self.precision("other_charges_total"))
self.doc.other_charges_total_export = flt(self.doc.grand_total_export - self.doc.net_total_export,
self.doc.other_charges_total_export = flt(
self.doc.grand_total_export - self.doc.net_total_export,
self.precision("other_charges_total_export"))
self.doc.rounded_total = _round(self.doc.grand_total)

View File

@@ -151,7 +151,9 @@ class StatusUpdater(DocListController):
"""
# check if overflow is within tolerance
tolerance = self.get_tolerance_for(item['item_code'])
tolerance, self.tolerance, self.global_tolerance = get_tolerance_for(item['item_code'],
self.tolerance, self.global_tolerance)
overflow_percent = ((item[args['target_field']] - item[args['target_ref_field']]) /
item[args['target_ref_field']]) * 100
@@ -170,23 +172,6 @@ class StatusUpdater(DocListController):
Also, please check if the order item has already been billed in the Sales Order""" %
item, raise_exception=1)
def get_tolerance_for(self, item_code):
"""
Returns the tolerance for the item, if not set, returns global tolerance
"""
if self.tolerance.get(item_code): return self.tolerance[item_code]
tolerance = flt(webnotes.conn.get_value('Item',item_code,'tolerance') or 0)
if not tolerance:
if self.global_tolerance == None:
self.global_tolerance = flt(webnotes.conn.get_value('Global Defaults', None,
'tolerance'))
tolerance = self.global_tolerance
self.tolerance[item_code] = tolerance
return tolerance
def update_qty(self, change_modified=True):
@@ -245,4 +230,59 @@ class StatusUpdater(DocListController):
set %(status_field)s = if(ifnull(%(target_parent_field)s,0)<0.001,
'Not %(keyword)s', if(%(target_parent_field)s>=99.99,
'Fully %(keyword)s', 'Partly %(keyword)s'))
where name='%(name)s'""" % args)
where name='%(name)s'""" % args)
def update_billing_status_for_zero_amount_refdoc(self, ref_dt):
ref_fieldname = ref_dt.lower().replace(" ", "_")
zero_amount_refdoc = []
all_zero_amount_refdoc = webnotes.conn.sql_list("""select name from `tab%s`
where docstatus=1 and net_total = 0""" % ref_dt)
for item in self.doclist.get({"parentfield": "entries"}):
if item.fields.get(ref_fieldname) \
and item.fields.get(ref_fieldname) in all_zero_amount_refdoc \
and item.fields.get(ref_fieldname) not in zero_amount_refdoc:
zero_amount_refdoc.append(item.fields[ref_fieldname])
if zero_amount_refdoc:
self.update_biling_status(zero_amount_refdoc, ref_dt, ref_fieldname)
def update_biling_status(self, zero_amount_refdoc, ref_dt, ref_fieldname):
for ref_dn in zero_amount_refdoc:
ref_doc_qty = flt(webnotes.conn.sql("""select sum(ifnull(qty, 0)) from `tab%s Item`
where parent=%s""" % (ref_dt, '%s'), (ref_dn))[0][0])
billed_qty = flt(webnotes.conn.sql("""select sum(ifnull(qty, 0))
from `tab%s Item` where %s=%s and docstatus=1""" %
(self.doc.doctype, ref_fieldname, '%s'), (ref_dn))[0][0])
per_billed = ((ref_doc_qty if billed_qty > ref_doc_qty else billed_qty)\
/ ref_doc_qty)*100
webnotes.conn.set_value(ref_dt, ref_dn, "per_billed", per_billed)
from webnotes.model.meta import has_field
if has_field(ref_dt, "billing_status"):
if per_billed < 0.001: billing_status = "Not Billed"
elif per_billed >= 99.99: billing_status = "Fully Billed"
else: billing_status = "Partly Billed"
webnotes.conn.set_value(ref_dt, ref_dn, "billing_status", billing_status)
def get_tolerance_for(item_code, item_tolerance={}, global_tolerance=None):
"""
Returns the tolerance for the item, if not set, returns global tolerance
"""
if item_tolerance.get(item_code):
return item_tolerance[item_code], item_tolerance, global_tolerance
tolerance = flt(webnotes.conn.get_value('Item',item_code,'tolerance') or 0)
if not tolerance:
if global_tolerance == None:
global_tolerance = flt(webnotes.conn.get_value('Global Defaults', None,
'tolerance'))
tolerance = global_tolerance
item_tolerance[item_code] = tolerance
return tolerance, item_tolerance, global_tolerance

View File

@@ -43,7 +43,7 @@ cur_frm.cscript.make_jv = function(doc, dt, dn) {
jv = locals['Journal Voucher'][jv];
jv.voucher_type = 'Bank Voucher';
jv.user_remark = wn._('Payment of salary for the month: ') + doc.month +
wn._('and fiscal year: ') + doc.fiscal_year;
wn._(' and fiscal year: ') + doc.fiscal_year;
jv.fiscal_year = doc.fiscal_year;
jv.company = doc.company;
jv.posting_date = dateutil.obj_to_str(new Date());

View File

@@ -7,7 +7,7 @@ wn.query_reports["Monthly Salary Register"] = {
"fieldname":"month",
"label": wn._("Month"),
"fieldtype": "Select",
"options": "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec",
"options": "\nJan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec",
"default": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
"Dec"][wn.datetime.str_to_obj(wn.datetime.get_today()).getMonth()],
},

View File

@@ -50,17 +50,17 @@ def get_columns(salary_slips):
where ifnull(d_modified_amount, 0) != 0 and parent in (%s)""" %
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]))
columns = columns + [(e + ":Link/Earning Type:120") for e in earning_types] + \
columns = columns + [(e + ":Currency:120") for e in earning_types] + \
["Arrear Amount:Currency:120", "Leave Encashment Amount:Currency:150",
"Gross Pay:Currency:120"] + [(d + ":Link/Deduction Type:120") for d in ded_types] + \
"Gross Pay:Currency:120"] + [(d + ":Currency:120") for d in ded_types] + \
["Total Deduction:Currency:120", "Net Pay:Currency:120"]
return columns, earning_types, ded_types
def get_salary_slips(filters):
conditions, filters = get_conditions(filters)
salary_slips = webnotes.conn.sql("""select * from `tabSalary Slip` where docstatus = 1 %s""" %
conditions, filters, as_dict=1)
salary_slips = webnotes.conn.sql("""select * from `tabSalary Slip` where docstatus = 1 %s
order by employee, month""" % conditions, filters, as_dict=1)
if not salary_slips:
msgprint(_("No salary slip found for month: ") + cstr(filters.get("month")) +
@@ -102,6 +102,6 @@ def get_ss_ded_map(salary_slips):
ss_ded_map = {}
for d in ss_deductions:
ss_ded_map.setdefault(d.parent, webnotes._dict()).setdefault(d.d_type, [])
ss_ded_map[d.parent][d.e_type] = flt(d.d_modified_amount)
ss_ded_map[d.parent][d.d_type] = flt(d.d_modified_amount)
return ss_ded_map

View File

@@ -5,6 +5,7 @@
from __future__ import unicode_literals
import os, sys
import argparse
import subprocess
is_redhat = is_debian = None
root_password = None
@@ -19,7 +20,7 @@ requirements = [
"jinja2",
"markdown2",
"markupsafe",
"mysql-python",
"mysql-python",
"pygeoip",
"python-dateutil",
"python-memcached",
@@ -80,7 +81,7 @@ def validate_install():
return is_redhat, is_debian
def install_using_yum():
packages = "python python-setuptools gcc python-devel MySQL-python git memcached ntp vim-enhanced screen"
packages = "gcc MySQL-python git memcached ntp vim-enhanced screen"
print "-"*80
print "Installing Packages: (This may take some time)"
@@ -88,7 +89,10 @@ def install_using_yum():
print "-"*80
exec_in_shell("yum install -y %s" % packages)
if not exec_in_shell("which mysql"):
try:
exec_in_shell("which mysql")
except subprocess.CalledProcessError:
packages = "mysql mysql-server mysql-devel"
print "Installing Packages:", packages
exec_in_shell("yum install -y %s" % packages)
@@ -101,26 +105,19 @@ def install_using_yum():
exec_in_shell('mysqladmin -u root password "%s"' % (root_password,))
print "Root password set as", root_password
# install htop
if not exec_in_shell("which htop"):
try:
exec_in_shell("cd /tmp && rpm -i --force http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm && yum install -y htop")
except:
pass
update_config_for_redhat()
def update_config_for_redhat():
import re
# set to autostart on startup
for service in ("mysqld", "memcached", "ntpd"):
for service in ("mysqld", "memcached"):
exec_in_shell("chkconfig --level 2345 %s on" % service)
exec_in_shell("service %s restart" % service)
def install_using_apt():
exec_in_shell("apt-get update")
packages = "python python-setuptools python-dev build-essential python-pip python-mysqldb git memcached ntp vim screen htop"
packages = "python python-setuptools python-dev build-essential python-mysqldb git memcached ntp vim screen htop"
print "-"*80
print "Installing Packages: (This may take some time)"
print packages
@@ -132,7 +129,9 @@ def install_using_apt():
exec_in_shell("echo mysql-server mysql-server/root_password password %s | sudo debconf-set-selections" % root_password)
exec_in_shell("echo mysql-server mysql-server/root_password_again password %s | sudo debconf-set-selections" % root_password)
if not exec_in_shell("which mysql"):
try:
exec_in_shell("which mysql")
except subprocess.CalledProcessError:
packages = "mysql-server libmysqlclient-dev"
print "Installing Packages:", packages
exec_in_shell("apt-get install -y %s" % packages)
@@ -140,7 +139,7 @@ def install_using_apt():
update_config_for_debian()
def update_config_for_debian():
for service in ("mysql", "ntpd"):
for service in ("mysql",):
exec_in_shell("service %s restart" % service)
def install_python_modules():
@@ -148,13 +147,14 @@ def install_python_modules():
print "Installing Python Modules: (This may take some time)"
print "-"*80
if not exec_in_shell("which pip"):
exec_in_shell("easy_install pip")
try:
exec_in_shell("which pip2.7")
except subprocess.CalledProcessError:
exec_in_shell("easy_install-2.7 pip")
exec_in_shell("pip install --upgrade pip")
exec_in_shell("pip install --upgrade setuptools")
exec_in_shell("pip install --upgrade virtualenv")
exec_in_shell("pip install {}".format(' '.join(requirements)))
exec_in_shell("pip2.7 install --upgrade setuptools --no-use-wheel")
exec_in_shell("pip2.7 install --upgrade setuptools")
exec_in_shell("pip2.7 install {}".format(' '.join(requirements)))
def install_erpnext(install_path):
print
@@ -200,7 +200,7 @@ def setup_folders(install_path):
app = os.path.join(install_path, "app")
if not os.path.exists(app):
print "Cloning erpnext"
exec_in_shell("cd %s && git clone https://github.com/webnotes/erpnext.git app" % install_path)
exec_in_shell("cd %s && git clone --branch master https://github.com/webnotes/erpnext.git app" % install_path)
exec_in_shell("cd app && git config core.filemode false")
if not os.path.exists(app):
raise Exception, "Couldn't clone erpnext repository"
@@ -208,7 +208,7 @@ def setup_folders(install_path):
lib = os.path.join(install_path, "lib")
if not os.path.exists(lib):
print "Cloning wnframework"
exec_in_shell("cd %s && git clone https://github.com/webnotes/wnframework.git lib" % install_path)
exec_in_shell("cd %s && git clone --branch master https://github.com/webnotes/wnframework.git lib" % install_path)
exec_in_shell("cd lib && git config core.filemode false")
if not os.path.exists(lib):
raise Exception, "Couldn't clone wnframework repository"
@@ -243,28 +243,8 @@ def post_install(install_path):
def exec_in_shell(cmd):
# using Popen instead of os.system - as recommended by python docs
from subprocess import Popen
import tempfile
with tempfile.TemporaryFile() as stdout:
with tempfile.TemporaryFile() as stderr:
p = Popen(cmd, shell=True, stdout=stdout, stderr=stderr)
p.wait()
stdout.seek(0)
out = stdout.read()
if out: out = out.decode('utf-8')
stderr.seek(0)
err = stderr.read()
if err: err = err.decode('utf-8')
if err and any((kw in err.lower() for kw in ["traceback", "error", "exception"])):
print out
raise Exception, err
else:
print "."
import subprocess
out = subprocess.check_output(cmd, shell=True)
return out
def parse_args():

View File

@@ -34,6 +34,8 @@ class TestProductionOrder(unittest.TestCase):
stock_entry = webnotes.bean(stock_entry)
stock_entry.doc.fg_completed_qty = 4
stock_entry.doc.posting_date = "2013-05-12"
stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013"
stock_entry.run_method("get_items")
stock_entry.submit()
@@ -50,7 +52,8 @@ class TestProductionOrder(unittest.TestCase):
stock_entry = make_stock_entry(pro_order, "Manufacture/Repack")
stock_entry = webnotes.bean(stock_entry)
stock_entry.doc.posting_date = "2013-05-12"
stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013"
stock_entry.doc.fg_completed_qty = 15
stock_entry.run_method("get_items")
stock_entry.insert()

View File

@@ -243,10 +243,10 @@ class DocType:
"item_code": [qty_required, description, stock_uom, min_order_qty]
}
"""
bom_wise_item_details = {}
item_list = []
for bom, so_wise_qty in bom_dict.items():
bom_wise_item_details = {}
if self.doc.use_multi_level_bom:
# get all raw materials with sub assembly childs
for d in webnotes.conn.sql("""select fb.item_code,

0
patches/1401/__init__.py Normal file
View File

View File

@@ -0,0 +1,9 @@
# Copyright (c) 2014, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import webnotes
def execute():
webnotes.reload_doc("stock", "doctype", "price_list")
webnotes.conn.sql("""update `tabPrice List` set enabled=1""")

View File

@@ -0,0 +1,10 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import webnotes
def execute():
from utilities.repost_stock import repost_stock
for d in webnotes.conn.sql("""select distinct production_item, fg_warehouse
from `tabProduction Order` where docstatus>0""", as_dict=1):
repost_stock(d.production_item, d.fg_warehouse)

View File

@@ -0,0 +1,17 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import webnotes
def execute():
serial_nos = webnotes.conn.sql("""select name from `tabSerial No` where docstatus=0
and status in ('Available', 'Sales Returned') and ifnull(warehouse, '') = ''""")
for sr in serial_nos:
try:
sr_bean = webnotes.bean("Serial No", sr[0])
sr_bean.make_controller().via_stock_ledger = True
sr_bean.save()
webnotes.conn.commit()
except:
pass

View File

@@ -0,0 +1,29 @@
# Copyright (c) 2014, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import webnotes
def execute():
webnotes.reload_doc("stock", "doctype", "price_list")
webnotes.reload_doc("stock", "doctype", "item_price")
if "buying_or_selling" in webnotes.conn.get_table_columns("Price List"):
webnotes.conn.sql("""update `tabPrice List` set
selling =
case
when buying_or_selling='Selling'
then 1
end,
buying =
case
when buying_or_selling='Buying'
then 1
end
""")
webnotes.conn.sql("""update `tabItem Price` ip, `tabPrice List` pl
set ip.buying=pl.buying, ip.selling=pl.selling
where ip.price_list=pl.name""")
webnotes.conn.sql("""update `tabItem Price` set selling=1 where ifnull(selling, 0)=0 and
ifnull(buying, 0)=0""")

View File

@@ -0,0 +1,25 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import webnotes
def execute():
webnotes.reload_doc("core", "doctype", "custom_field")
cf_doclist = webnotes.get_doctype("Custom Field")
delete_list = []
for d in webnotes.conn.sql("""select cf.name as cf_name, ps.property,
ps.value, ps.name as ps_name
from `tabProperty Setter` ps, `tabCustom Field` cf
where ps.doctype_or_field = 'DocField' and ps.property != 'previous_field'
and ps.doc_type=cf.dt and ps.field_name=cf.fieldname""", as_dict=1):
if cf_doclist.get_field(d.property):
webnotes.conn.sql("""update `tabCustom Field`
set `%s`=%s where name=%s""" % (d.property, '%s', '%s'), (d.value, d.cf_name))
delete_list.append(d.ps_name)
if delete_list:
webnotes.conn.sql("""delete from `tabProperty Setter` where name in (%s)""" %
', '.join(['%s']*len(delete_list)), tuple(delete_list))

View File

@@ -0,0 +1,29 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import webnotes
from webnotes.utils import flt
def execute():
for order_type in ["Sales", "Purchase"]:
for d in webnotes.conn.sql("""select par.name, sum(ifnull(child.qty, 0)) as total_qty
from `tab%s Order` par, `tab%s Order Item` child
where par.name = child.parent and par.docstatus = 1
and ifnull(par.net_total, 0) = 0 group by par.name""" %
(order_type, order_type), as_dict=1):
billed_qty = flt(webnotes.conn.sql("""select sum(ifnull(qty, 0))
from `tab%s Invoice Item` where %s=%s and docstatus=1""" %
(order_type, "sales_order" if order_type=="Sales" else "purchase_order", '%s'),
(d.name))[0][0])
per_billed = ((d.total_qty if billed_qty > d.total_qty else billed_qty)\
/ d.total_qty)*100
webnotes.conn.set_value(order_type+ " Order", d.name, "per_billed", per_billed)
if order_type == "Sales":
if per_billed < 0.001: billing_status = "Not Billed"
elif per_billed >= 99.99: billing_status = "Fully Billed"
else: billing_status = "Partly Billed"
webnotes.conn.set_value("Sales Order", d.name, "billing_status", billing_status)

View File

@@ -8,20 +8,7 @@ from webnotes.utils import cint
def execute():
webnotes.reload_doc("stock", "doctype", "price_list")
webnotes.reload_doc("stock", "doctype", "item_price")
try:
for price_list in webnotes.conn.sql_list("""select name from `tabPrice List`"""):
buying, selling = False, False
for b, s in webnotes.conn.sql("""select distinct buying, selling
from `tabItem Price` where price_list_name=%s""", price_list):
buying = buying or cint(b)
selling = selling or cint(s)
buying_or_selling = "Selling" if selling else "Buying"
webnotes.conn.set_value("Price List", price_list, "buying_or_selling", buying_or_selling)
except webnotes.SQLError, e:
if e.args[0] == 1054:
webnotes.conn.sql("""update `tabPrice List` set buying_or_selling='Selling'
where ifnull(buying_or_selling, '')='' """)
else:
raise
webnotes.conn.sql("""update `tabPrice List` pl, `tabItem Price` ip
set pl.selling=ip.selling, pl.buying=ip.buying
where pl.name=ip.price_list_name""")

View File

@@ -12,9 +12,7 @@ def execute():
where ip.item_code=i.name""")
webnotes.conn.sql("""update `tabItem Price` ip, `tabPrice List` pl
set ip.price_list=pl.name, ip.currency=pl.currency,
ip.buying_or_selling=pl.buying_or_selling
where ip.parent=pl.name""")
set ip.price_list=pl.name, ip.currency=pl.currency where ip.parent=pl.name""")
webnotes.conn.sql("""update `tabItem Price`
set parent=null, parenttype=null, parentfield=null, idx=null""")

View File

@@ -263,4 +263,10 @@ patch_list = [
"patches.1311.p08_email_digest_recipients",
"execute:webnotes.delete_doc('DocType', 'Warehouse Type')",
"patches.1312.p02_update_item_details_in_item_price",
"patches.1401.p01_move_related_property_setters_to_custom_field",
"patches.1401.p01_make_buying_selling_as_check_box_in_price_list",
"patches.1401.update_billing_status_for_zero_value_order",
"patches.1401.enable_all_price_list",
"patches.1401.fix_serial_no_status_and_warehouse",
"patches.1401.fix_planned_qty",
]

View File

@@ -10,9 +10,9 @@
<li class="active"><i class="icon-file icon-fixed-width"></i> {{ doc.name }}</li>
</ul>
<h3><i class="icon-file icon-fixed-width"></i> {{ doc.name }}</h3>
{% if doc.name == "Not Allowed" -%}
{% if session_user == "Guest" -%}
<script>ask_to_login();</script>
{% else %}
{% elif doc.name != "Not Allowed"%}
<hr>
<div>
<div class="row">

View File

@@ -41,21 +41,23 @@ def get_currency_context():
}
def get_transaction_context(doctype, name):
context = {"session_user": webnotes.session.user}
customer = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user},
"customer")
bean = webnotes.bean(doctype, name)
if bean.doc.customer != customer:
return {
"doc": {"name": "Not Allowed"}
}
context.update({"doc": {"name": "Not Allowed"}})
else:
return {
context.update({
"doc": bean.doc,
"doclist": bean.doclist,
"webnotes": webnotes,
"utils": webnotes.utils
}
})
return context
@webnotes.whitelist(allow_guest=True)
def send_message(subject="Website Query", message="", sender="", status="Open"):

View File

@@ -24,16 +24,17 @@ $(document).bind('toolbar_setup', function() {
wn.provide('wn.ui.misc');
wn.ui.misc.about = function() {
if(!wn.ui.misc.about_dialog) {
var d = new wn.ui.Dialog({title: wn._('About ERPNext')})
var d = new wn.ui.Dialog({title: wn._('About')})
$(d.body).html(repl("<div>\
<p>"+wn._("ERPNext is an open-source web based ERP made by Web Notes Technologies Pvt Ltd.\
to provide an integrated tool to manage most processes in a small organization.\
For more information about Web Notes, or to buy hosting servies, go to ")+
"<a href='https://erpnext.com'>https://erpnext.com</a>.</p>\
<p>"+wn._("To report an issue, go to ")+"<a href='https://github.com/webnotes/erpnext/issues'>GitHub Issues</a></p>\
<hr>\
<h2>ERPNext</h2> \
<p><strong>v" + wn.boot.app_version + "</strong></p>\
<p>"+wn._("An open source ERP made for the web.</p>") +
"<p>"+wn._("To report an issue, go to ")+"<a href='https://github.com/webnotes/erpnext/issues'>GitHub Issues</a></p> \
<p><a href='http://erpnext.org' target='_blank'>http://erpnext.org</a>.</p>\
<p><a href='http://www.gnu.org/copyleft/gpl.html'>License: GNU General Public License Version 3</a></p>\
<hr>\
<p>&copy; 2014 Web Notes Technologies Pvt. Ltd and contributers </p> \
</div>", wn.app));
wn.ui.misc.about_dialog = d;

View File

@@ -28,7 +28,8 @@ erpnext.stock.StockController = wn.ui.form.Controller.extend({
voucher_no: me.frm.doc.name,
from_date: me.frm.doc.posting_date,
to_date: me.frm.doc.posting_date,
company: me.frm.doc.company
company: me.frm.doc.company,
group_by_voucher: false
};
wn.set_route("query-report", "General Ledger");
}, "icon-table");

View File

@@ -21,6 +21,6 @@ erpnext.toolbar.setup = function() {
<i class="icon-fixed-width icon-comments"></i> '+wn._('Live Chat')+'</a></li>');
}
$("#toolbar-tools").append('<li><a href="#latest-updates">\
$("#toolbar-tools").append('<li><a href="https://github.com/webnotes/erpnext/releases" target="_blank">\
<i class="icon-fixed-width icon-rss"></i> Latest Updates</li>');
}
}

View File

@@ -330,8 +330,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
doctype: tax.doctype,
row_id_label: wn.meta.get_label(tax.doctype, "row_id", tax.name)
});
msgprint(msg);
throw msg;
wn.throw(msg);
}
},
@@ -347,8 +346,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
charge_type_label: wn.meta.get_label(tax.doctype, "charge_type", tax.name),
charge_type: tax.charge_type
});
msgprint(msg);
throw msg;
wn.throw(msg);
};
var on_previous_row_error = function(row_range) {
@@ -363,8 +361,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
row_range: row_range,
});
msgprint(msg);
throw msg;
wn.throw(msg);
};
if(cint(tax.included_in_print_rate)) {
@@ -543,6 +540,14 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
calculate_taxes: function() {
var me = this;
var actual_tax_dict = {};
// maintain actual tax rate based on idx
$.each(this.frm.tax_doclist, function(i, tax) {
if (tax.charge_type == "Actual") {
actual_tax_dict[tax.idx] = flt(tax.rate);
}
});
$.each(this.frm.item_doclist, function(n, item) {
var item_tax_map = me._load_item_tax_rate(item.item_tax_rate);
@@ -552,15 +557,15 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
var current_tax_amount = me.get_current_tax_amount(item, tax, item_tax_map);
me.set_item_tax_amount && me.set_item_tax_amount(item, tax, current_tax_amount);
// case when net total is 0 but there is an actual type charge
// in this case add the actual amount to tax.tax_amount
// and tax.grand_total_for_current_item for the first such iteration
if(tax.charge_type == "Actual" &&
!(current_tax_amount || me.frm.doc.net_total || tax.tax_amount)) {
var zero_net_total_adjustment = flt(tax.rate, precision("tax_amount", tax));
current_tax_amount += zero_net_total_adjustment;
// Adjust divisional loss to the last item
if (tax.charge_type == "Actual") {
actual_tax_dict[tax.idx] -= current_tax_amount;
if (n == me.frm.item_doclist.length - 1) {
current_tax_amount += actual_tax_dict[tax.idx]
}
}
// store tax_amount for current item as it will be used for
// charge type = 'On Previous Row Amount'
@@ -592,6 +597,11 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
// in tax.total, accumulate grand total for each item
tax.total += tax.grand_total_for_current_item;
if (n == me.frm.item_doclist.length - 1) {
tax.total = flt(tax.total, precision("total", tax));
tax.tax_amount = flt(tax.tax_amount, precision("tax_amount", tax));
}
});
});
},

View File

@@ -1,13 +1,2 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
//--------- ONLOAD -------------
cur_frm.cscript.onload = function(doc, cdt, cdn) {
}
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
}
// License: GNU General Public License v3. See license.txt

View File

@@ -2,11 +2,12 @@
{
"creation": "2013-01-10 16:34:18",
"docstatus": 0,
"modified": "2013-07-05 14:29:57",
"modified": "2014-01-16 12:52:19",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_rename": 1,
"autoname": "field:campaign_name",
"description": "Keep Track of Sales Campaigns. Keep track of Leads, Quotations, Sales Order etc from Campaigns to gauge Return on Investment. ",
"doctype": "DocType",

View File

@@ -18,7 +18,7 @@ cur_frm.cscript.load_defaults = function(doc, dt, dn) {
cur_frm.add_fetch('lead_name', 'company_name', 'customer_name');
cur_frm.add_fetch('default_sales_partner','commission_rate','default_commission_rate');
cur_frm.cscript.refresh = function(doc,dt,dn) {
cur_frm.cscript.refresh = function(doc, dt, dn) {
cur_frm.cscript.setup_dashboard(doc);
erpnext.hide_naming_series();
@@ -107,21 +107,21 @@ cur_frm.cscript.make_contact = function() {
}
cur_frm.fields_dict['customer_group'].get_query = function(doc,dt,dn) {
cur_frm.fields_dict['customer_group'].get_query = function(doc, dt, dn) {
return{
filters:{'is_group': 'No'}
}
}
cur_frm.fields_dict.lead_name.get_query = function(doc,cdt,cdn) {
cur_frm.fields_dict.lead_name.get_query = function(doc, cdt, cdn) {
return{
query:"controllers.queries.lead_query"
}
}
cur_frm.fields_dict['default_price_list'].get_query = function(doc,cdt,cdn) {
cur_frm.fields_dict['default_price_list'].get_query = function(doc, cdt, cdn) {
return{
filters:{'buying_or_selling': "Selling"}
filters:{'selling': 1}
}
}

View File

@@ -28,6 +28,7 @@ class TestQuotation(unittest.TestCase):
sales_order[0]["delivery_date"] = "2014-01-01"
sales_order[0]["naming_series"] = "_T-Quotation-"
sales_order[0]["transaction_date"] = "2013-05-12"
webnotes.bean(sales_order).insert()

View File

@@ -10,11 +10,12 @@ no_cache = True
def get_context():
from portal.utils import get_transaction_context
context = get_transaction_context("Sales Order", webnotes.form_dict.name)
modify_status(context.get("doc"))
context.update({
"parent_link": "orders",
"parent_title": "My Orders"
})
if context.get("doc").get("name") != "Not Allowed":
modify_status(context.get("doc"))
context.update({
"parent_link": "orders",
"parent_title": "My Orders"
})
return context
def modify_status(doc):

View File

@@ -53,6 +53,7 @@ class TestSalesOrder(unittest.TestCase):
self.assertEquals(len([d for d in si if d["doctype"]=="Sales Invoice Item"]), 1)
si = webnotes.bean(si)
si.doc.posting_date = "2013-10-10"
si.insert()
si.submit()

View File

@@ -48,7 +48,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
if(this.frm.fields_dict.selling_price_list) {
this.frm.set_query("selling_price_list", function() {
return { filters: { buying_or_selling: "Selling" } };
return { filters: { selling: 1 } };
});
}

View File

@@ -3,8 +3,8 @@
from __future__ import unicode_literals
import webnotes
from webnotes import msgprint, _
from webnotes.utils import flt, cint, comma_and
from webnotes import _, throw
from webnotes.utils import flt, cint
import json
def get_customer_list(doctype, txt, searchfield, start, page_len, filters):
@@ -100,7 +100,7 @@ def _get_item_code(barcode=None, serial_no=None):
where name=%s""", serial_no)
if not item_code:
msgprint(_("No Item found with ") + input_type + ": %s" % (barcode or serial_no), raise_exception=True)
throw(_("No Item found with ") + input_type + ": %s" % (barcode or serial_no))
return item_code[0]
@@ -111,22 +111,26 @@ def _validate_item_details(args, item):
# validate if sales item or service item
if args.order_type == "Maintenance":
if item.is_service_item != "Yes":
msgprint(_("Item") + (" %s: " % item.name) +
throw(_("Item") + (" %s: " % item.name) +
_("not a service item.") +
_("Please select a service item or change the order type to Sales."),
raise_exception=True)
_("Please select a service item or change the order type to Sales."))
elif item.is_sales_item != "Yes":
msgprint(_("Item") + (" %s: " % item.name) + _("not a sales item"),
raise_exception=True)
throw(_("Item") + (" %s: " % item.name) + _("not a sales item"))
def _get_basic_details(args, item_bean, warehouse_fieldname):
item = item_bean.doc
from webnotes.defaults import get_user_default_as_list
user_default_warehouse_list = get_user_default_as_list('warehouse')
user_default_warehouse = user_default_warehouse_list[0] \
if len(user_default_warehouse_list)==1 else ""
out = webnotes._dict({
"item_code": item.name,
"description": item.description_html or item.description,
warehouse_fieldname: item.default_warehouse or args.get(warehouse_fieldname),
warehouse_fieldname: user_default_warehouse or item.default_warehouse \
or args.get(warehouse_fieldname),
"income_account": item.default_income_account or args.income_account \
or webnotes.conn.get_value("Company", args.company, "default_income_account"),
"expense_account": item.purchase_account or args.expense_account \
@@ -146,8 +150,10 @@ def _get_basic_details(args, item_bean, warehouse_fieldname):
return out
def _get_price_list_rate(args, item_bean, meta):
ref_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
where price_list=%s and item_code=%s and buying_or_selling='Selling'""",
ref_rate = webnotes.conn.sql("""select ip.ref_rate from
`tabItem Price` ip, `tabPrice List` pl
where ip.price_list=pl.name and ip.price_list=%s and
ip.item_code=%s and ip.selling=1 and pl.enabled=1""",
(args.selling_price_list, args.item_code), as_dict=1)
if not ref_rate:

View File

@@ -282,7 +282,7 @@ def apply_cart_settings(party=None, quotation=None):
party = get_lead_or_customer()
if not quotation:
quotation = _get_cart_quotation(party)
cart_settings = webnotes.get_obj("Shopping Cart Settings")
billing_territory = get_address_territory(quotation.doc.customer_address) or \
@@ -310,7 +310,8 @@ def set_price_list_and_rate(quotation, cart_settings, billing_territory):
quotation.run_method("set_price_list_and_item_details")
# set it in cookies for using in product page
webnotes.local._response.set_cookie("selling_price_list", quotation.doc.selling_price_list)
if quotation.doc.selling_price_list:
webnotes.local._response.set_cookie("selling_price_list", quotation.doc.selling_price_list)
def set_taxes(quotation, cart_settings, billing_territory):
"""set taxes based on billing territory"""

View File

@@ -27,8 +27,9 @@ def get_product_info(item_code):
else:
in_stock = -1
price = price_list and webnotes.conn.sql("""select ref_rate, currency from
`tabItem Price` where item_code=%s and price_list=%s""",
price = price_list and webnotes.conn.sql("""select ip.ref_rate, ip.currency from
`tabItem Price` ip, `tabPrice List` pl where ip.price_list=pl.name and
ip.item_code=%s and ip.price_list=%s and pl.enabled=1""",
(item_code, price_list), as_dict=1) or []
price = price and price[0] or None

View File

@@ -5,7 +5,7 @@ from __future__ import unicode_literals
import webnotes
from webnotes import _, msgprint
from webnotes.utils import cstr
from webnotes.utils import cstr, cint
import webnotes.defaults
@@ -237,21 +237,24 @@ class DocType:
account.insert()
def set_default_accounts(self):
accounts = {
"default_income_account": "Sales",
"default_expense_account": "Cost of Goods Sold",
def _set_default_accounts(accounts):
for a in accounts:
account_name = accounts[a] + " - " + self.doc.abbr
if not self.doc.fields.get(a) and webnotes.conn.exists("Account", account_name):
webnotes.conn.set(self.doc, a, account_name)
_set_default_accounts({
"receivables_group": "Accounts Receivable",
"payables_group": "Accounts Payable",
"default_cash_account": "Cash",
"stock_received_but_not_billed": "Stock Received But Not Billed",
"stock_adjustment_account": "Stock Adjustment",
"expenses_included_in_valuation": "Expenses Included In Valuation"
}
"default_cash_account": "Cash"
})
for a in accounts:
account_name = accounts[a] + " - " + self.doc.abbr
if not self.doc.fields.get(a) and webnotes.conn.exists("Account", account_name):
webnotes.conn.set(self.doc, a, account_name)
if cint(webnotes.conn.get_value("Accounts Settings", None, "auto_accounting_for_stock")):
_set_default_accounts({
"stock_received_but_not_billed": "Stock Received But Not Billed",
"stock_adjustment_account": "Stock Adjustment",
"expenses_included_in_valuation": "Expenses Included In Valuation"
})
def create_default_cost_center(self):
cc_list = [

View File

@@ -98,7 +98,9 @@ def create_price_lists(args):
{
"doctype": "Price List",
"price_list_name": "Standard " + pl_type,
"buying_or_selling": pl_type,
"enabled": 1,
"buying": 1 if pl_type == "Buying" else 0,
"selling": 1 if pl_type == "Selling" else 0,
"currency": args["currency"]
},
{

View File

@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes import _, msgprint
from webnotes import _, msgprint, throw
import json
def get_company_currency(company):
@@ -11,8 +11,8 @@ def get_company_currency(company):
if not currency:
currency = webnotes.conn.get_default("currency")
if not currency:
msgprint(_('Please specify Default Currency in Company Master \
and Global Defaults'), raise_exception=True)
throw(_('Please specify Default Currency in Company Master \
and Global Defaults'))
return currency
@@ -32,5 +32,14 @@ def get_ancestors_of(doctype, name):
@webnotes.whitelist()
def get_price_list_currency(price_list):
return {"price_list_currency": webnotes.conn.get_value("Price List", price_list,
"currency")}
price_list_currency = webnotes.conn.get_value("Price List", {"name": price_list,
"enabled": 1}, "currency")
if not price_list_currency:
throw("{message}: {price_list} {disabled}".format(**{
"message": _("Price List"),
"price_list": price_list,
"disabled": _("is disabled.")
}))
else:
return {"price_list_currency": price_list_currency}

View File

@@ -70,6 +70,6 @@ def on_build():
def comment_added(doc):
"""add comment to feed"""
home.make_feed('Comment', doc.comment_doctype, doc.comment_docname, doc.comment_by,
'<i>"' + doc.comment + '"</i>', '#6B24B3')
home.make_feed('Comment', doc.comment_doctype, doc.comment_docname,
doc.comment_by or doc.owner, '<i>"' + doc.comment + '"</i>', '#6B24B3')

View File

@@ -53,6 +53,10 @@ def execute_daily():
# email digest
from setup.doctype.email_digest.email_digest import send
run_fn(send)
# auto close support tickets
from support.doctype.support_ticket.support_ticket import auto_close_tickets
run_fn(auto_close_tickets)
def execute_weekly():
from setup.doctype.backup_manager.backup_manager import take_backups_weekly

View File

@@ -29,10 +29,7 @@ cur_frm.cscript.make_dashboard = function() {
cur_frm.cscript.edit_prices_button = function() {
cur_frm.add_custom_button("Add / Edit Prices", function() {
wn.route_options = {
"item_code": cur_frm.doc.name
};
wn.set_route("Report", "Item Price");
wn.set_route("Report", "Item Price", {"item_code": cur_frm.doc.name});
}, "icon-money");
}

View File

@@ -36,6 +36,7 @@ test_records = [
"stock_uom": "_Test UOM",
"default_income_account": "Sales - _TC",
"default_warehouse": "_Test Warehouse - _TC",
"purchase_account": "_Test Account Cost for Goods Sold - _TC"
}, {
"doctype": "Item Reorder",
"parentfield": "item_reorder",
@@ -64,6 +65,7 @@ test_records = [
"stock_uom": "_Test UOM",
"default_income_account": "Sales - _TC",
"default_warehouse": "_Test Warehouse - _TC",
"purchase_account": "_Test Account Cost for Goods Sold - _TC"
}],
[{
"doctype": "Item",
@@ -73,6 +75,7 @@ test_records = [
"item_group": "_Test Item Group Desktops",
"default_warehouse": "_Test Warehouse - _TC",
"default_income_account": "Sales - _TC",
"purchase_account": "_Test Account Cost for Goods Sold - _TC",
"is_stock_item": "Yes",
"is_asset_item": "No",
"has_batch_no": "No",
@@ -99,6 +102,7 @@ test_records = [
"item_group": "_Test Item Group Desktops",
"default_warehouse": "_Test Warehouse - _TC",
"default_income_account": "Sales - _TC",
"purchase_account": "_Test Account Cost for Goods Sold - _TC",
"is_stock_item": "Yes",
"is_asset_item": "No",
"has_batch_no": "No",
@@ -119,6 +123,7 @@ test_records = [
"description": "_Test Sales BOM Item",
"item_group": "_Test Item Group Desktops",
"default_income_account": "Sales - _TC",
"purchase_account": "_Test Account Cost for Goods Sold - _TC",
"is_stock_item": "No",
"is_asset_item": "No",
"has_batch_no": "No",
@@ -140,6 +145,7 @@ test_records = [
"is_stock_item": "Yes",
"default_warehouse": "_Test Warehouse - _TC",
"default_income_account": "Sales - _TC",
"purchase_account": "_Test Account Cost for Goods Sold - _TC",
"is_asset_item": "No",
"has_batch_no": "No",
"has_serial_no": "No",
@@ -216,6 +222,7 @@ test_records = [
"item_group": "_Test Item Group Desktops",
"default_warehouse": "_Test Warehouse - _TC",
"default_income_account": "Sales - _TC",
"purchase_account": "_Test Account Cost for Goods Sold - _TC",
"is_stock_item": "Yes",
"is_asset_item": "No",
"has_batch_no": "No",
@@ -238,6 +245,7 @@ test_records = [
"is_stock_item": "Yes",
"default_warehouse": "_Test Warehouse - _TC",
"default_income_account": "Sales - _TC",
"purchase_account": "_Test Account Cost for Goods Sold - _TC",
"is_asset_item": "No",
"has_batch_no": "No",
"has_serial_no": "No",

View File

@@ -2,11 +2,10 @@
// License: GNU General Public License v3. See license.txt
$.extend(cur_frm.cscript, {
onload: function () {
// Fetch price list details
cur_frm.add_fetch("price_list", "buying_or_selling", "buying_or_selling");
cur_frm.add_fetch("price_list", "buying", "buying");
cur_frm.add_fetch("price_list", "selling", "selling");
cur_frm.add_fetch("price_list", "currency", "currency");
// Fetch item details

View File

@@ -1,11 +1,9 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# For license information, please see license.txt
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import webnotes
from webnotes import _
from webnotes import throw, _
class ItemPriceDuplicateItem(webnotes.ValidationError): pass
@@ -14,26 +12,36 @@ class DocType:
self.doc, self.doclist = d, dl
def validate(self):
self.validate_price_list()
self.check_duplicate_item()
self.update_price_list_details()
self.update_item_details()
def update_price_list_details(self):
self.doc.buying_or_selling, self.doc.currency = webnotes.conn.get_value("Price List",
self.doc.price_list, ["buying_or_selling", "currency"])
def update_item_details(self):
self.doc.item_name, self.doc.item_description = webnotes.conn.get_value("Item",
self.doc.item_code, ["item_name", "description"])
def validate_price_list(self):
enabled = webnotes.conn.get_value("Price List", self.doc.price_list, "enabled")
if not enabled:
throw("{message}: {price_list} {disabled}".format(**{
"message": _("Price List"),
"price_list": self.doc.price_list,
"disabled": _("is disabled.")
}))
def check_duplicate_item(self):
if webnotes.conn.sql("""select name from `tabItem Price`
where item_code=%s and price_list=%s and name!=%s""",
(self.doc.item_code, self.doc.price_list, self.doc.name)):
webnotes.throw("{duplicate_item}: {item_code}, {already}: {price_list}".format(**{
throw("{duplicate_item}: {item_code}, {already}: {price_list}".format(**{
"duplicate_item": _("Duplicate Item"),
"item_code": self.doc.item_code,
"already": _("already available in Price List"),
"price_list": self.doc.price_list
}), ItemPriceDuplicateItem)
def update_price_list_details(self):
self.doc.buying, self.doc.selling, self.doc.currency = webnotes.conn.get_value("Price List",
{"name": self.doc.price_list, "enabled": 1}, ["buying", "selling", "currency"])
def update_item_details(self):
self.doc.item_name, self.doc.item_description = webnotes.conn.get_value("Item",
self.doc.item_code, ["item_name", "description"])

View File

@@ -2,7 +2,7 @@
{
"creation": "2013-05-02 16:29:48",
"docstatus": 0,
"modified": "2013-10-31 12:59:02",
"modified": "2014-01-07 19:16:49",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -43,6 +43,13 @@
"doctype": "DocType",
"name": "Item Price"
},
{
"doctype": "DocField",
"fieldname": "price_list_details",
"fieldtype": "Section Break",
"label": "Price List",
"options": "icon-tags"
},
{
"doctype": "DocField",
"fieldname": "price_list",
@@ -52,6 +59,29 @@
"options": "Price List",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "buying",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Buying",
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "selling",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Selling",
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "item_details",
"fieldtype": "Section Break",
"label": "Item",
"options": "icon-tag"
},
{
"doctype": "DocField",
"fieldname": "item_code",
@@ -83,16 +113,6 @@
"fieldname": "col_br_1",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "buying_or_selling",
"fieldtype": "Select",
"in_filter": 1,
"in_list_view": 1,
"label": "Valid for Buying or Selling?",
"options": "Selling\nBuying",
"reqd": 0
},
{
"doctype": "DocField",
"fieldname": "item_name",

View File

@@ -125,6 +125,7 @@ class TestMaterialRequest(unittest.TestCase):
from stock.doctype.material_request.material_request import make_purchase_order
po_doclist = make_purchase_order(mr.doc.name)
po_doclist[0].supplier = "_Test Supplier"
po_doclist[0].transaction_date = "2013-07-07"
po_doclist[1].qty = 27.0
po_doclist[2].qty = 1.5
po_doclist[1].schedule_date = "2013-07-09"

View File

@@ -1,7 +0,0 @@
.table-grid tbody tr {
cursor: pointer;
}
.table-grid thead tr {
height: 50px;
}

View File

@@ -3,16 +3,15 @@
from __future__ import unicode_literals
import webnotes
from webnotes import msgprint, _
from webnotes.utils import comma_or, cint
from webnotes import msgprint, _, throw
from webnotes.utils import cint
from webnotes.model.controller import DocListController
import webnotes.defaults
class DocType(DocListController):
def validate(self):
if self.doc.buying_or_selling not in ["Buying", "Selling"]:
msgprint(_(self.meta.get_label("buying_or_selling")) + " " + _("must be one of") + " " +
comma_or(["Buying", "Selling"]), raise_exception=True)
if not cint(self.doc.buying) and not cint(self.doc.selling):
throw(_("Price List must be applicable for Buying or Selling"))
if not self.doclist.get({"parentfield": "valid_for_territories"}):
# if no territory, set default territory
@@ -25,24 +24,24 @@ class DocType(DocListController):
else:
# at least one territory
self.validate_table_has_rows("valid_for_territories")
def on_update(self):
self.set_default_if_missing()
self.update_item_price()
cart_settings = webnotes.get_obj("Shopping Cart Settings")
if cint(cart_settings.doc.enabled):
cart_settings.validate_price_lists()
def set_default_if_missing(self):
if self.doc.buying_or_selling=="Selling":
if cint(self.doc.selling):
if not webnotes.conn.get_value("Selling Settings", None, "selling_price_list"):
webnotes.set_value("Selling Settings", "Selling Settings", "selling_price_list", self.doc.name)
elif self.doc.buying_or_selling=="Buying":
elif cint(self.doc.buying):
if not webnotes.conn.get_value("Buying Settings", None, "buying_price_list"):
webnotes.set_value("Buying Settings", "Buying Settings", "buying_price_list", self.doc.name)
def update_item_price(self):
webnotes.conn.sql("""update `tabItem Price` set currency=%s,
buying_or_selling=%s, modified=NOW() where price_list=%s""",
(self.doc.currency, self.doc.buying_or_selling, self.doc.name))
buying=%s, selling=%s, modified=NOW() where price_list=%s""",
(self.doc.currency, cint(self.doc.buying), cint(self.doc.selling), self.doc.name))

View File

@@ -2,7 +2,7 @@
{
"creation": "2013-01-25 11:35:09",
"docstatus": 0,
"modified": "2013-10-31 19:24:33",
"modified": "2014-01-27 11:11:08",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -11,6 +11,7 @@
"allow_copy": 0,
"allow_email": 1,
"allow_print": 1,
"allow_rename": 1,
"autoname": "field:price_list_name",
"description": "Price List Master",
"doctype": "DocType",
@@ -42,6 +43,18 @@
"doctype": "DocType",
"name": "Price List"
},
{
"default": "1",
"doctype": "DocField",
"fieldname": "enabled",
"fieldtype": "Check",
"label": "Enabled"
},
{
"doctype": "DocField",
"fieldname": "sb_1",
"fieldtype": "Section Break"
},
{
"doctype": "DocField",
"fieldname": "price_list_name",
@@ -61,14 +74,19 @@
"reqd": 1
},
{
"default": "Selling",
"doctype": "DocField",
"fieldname": "buying_or_selling",
"fieldtype": "Select",
"fieldname": "buying",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Valid for Buying or Selling?",
"options": "Buying\nSelling",
"reqd": 1
"label": "Buying"
},
{
"doctype": "DocField",
"fieldname": "selling",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Selling",
"reqd": 0
},
{
"doctype": "DocField",

View File

@@ -11,8 +11,9 @@ test_records = [
{
"doctype": "Price List",
"price_list_name": "_Test Price List",
"enabled": 1,
"currency": "INR",
"buying_or_selling": "Selling"
"selling": 1
},
{
"doctype": "Applicable Territory",
@@ -24,8 +25,9 @@ test_records = [
{
"doctype": "Price List",
"price_list_name": "_Test Price List 2",
"enabled": 1,
"currency": "INR",
"buying_or_selling": "Selling"
"selling": 1
},
{
"doctype": "Applicable Territory",
@@ -37,8 +39,9 @@ test_records = [
{
"doctype": "Price List",
"price_list_name": "_Test Price List India",
"enabled": 1,
"currency": "INR",
"buying_or_selling": "Selling"
"selling": 1
},
{
"doctype": "Applicable Territory",
@@ -50,8 +53,9 @@ test_records = [
{
"doctype": "Price List",
"price_list_name": "_Test Price List Rest of the World",
"enabled": 1,
"currency": "USD",
"buying_or_selling": "Selling"
"selling": 1
},
{
"doctype": "Applicable Territory",

View File

@@ -2,7 +2,7 @@
{
"creation": "2013-05-24 19:29:10",
"docstatus": 0,
"modified": "2013-12-18 10:38:39",
"modified": "2014-01-15 16:00:44",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -334,6 +334,16 @@
"report_hide": 0,
"reqd": 0
},
{
"default": ":Company",
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
"doctype": "DocField",
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center",
"print_hide": 1
},
{
"doctype": "DocField",
"fieldname": "project_name",

View File

@@ -87,6 +87,8 @@ class DocType(StockController):
self.doc.status = "Sales Returned"
else:
self.doc.status = "Available"
if not self.doc.warehouse:
self.doc.warehouse = last_sle.warehouse
else:
if document_type == "Purchase Return":
self.doc.status = "Purchase Returned"
@@ -94,6 +96,8 @@ class DocType(StockController):
self.doc.status = "Delivered"
else:
self.doc.status = "Not Available"
else:
self.doc.status = "Not Available"
def set_purchase_details(self, purchase_sle):
if purchase_sle:
@@ -185,10 +189,9 @@ class DocType(StockController):
def on_stock_ledger_entry(self):
if self.via_stock_ledger and not self.doc.fields.get("__islocal"):
last_sle = self.get_last_sle()
if last_sle:
self.set_status(last_sle.get("last_sle"))
self.set_purchase_details(last_sle.get("purchase_sle"))
self.set_sales_details(last_sle.get("delivery_sle"))
self.set_status(last_sle.get("last_sle"))
self.set_purchase_details(last_sle.get("purchase_sle"))
self.set_sales_details(last_sle.get("delivery_sle"))
def on_communication(self):
return

View File

@@ -346,7 +346,8 @@ class DocType(StockController):
pro_bean = webnotes.bean("Production Order", self.doc.production_order)
_validate_production_order(pro_bean)
self.update_produced_qty(pro_bean)
self.update_planned_qty(pro_bean)
if self.doc.purpose == "Manufacture/Repack":
self.update_planned_qty(pro_bean)
def update_produced_qty(self, pro_bean):
if self.doc.purpose == "Manufacture/Repack":

View File

@@ -2,7 +2,7 @@
{
"creation": "2013-03-29 18:22:12",
"docstatus": 0,
"modified": "2013-11-08 16:15:44",
"modified": "2014-01-15 16:08:45",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -165,7 +165,7 @@
"read_only": 1
},
{
"depends_on": "eval:sys_defaults.auto_accounting_for_stock",
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
"doctype": "DocField",
"fieldname": "expense_account",
"fieldtype": "Link",
@@ -175,7 +175,7 @@
},
{
"default": ":Company",
"depends_on": "eval:sys_defaults.auto_accounting_for_stock",
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
"doctype": "DocField",
"fieldname": "cost_center",
"fieldtype": "Link",

View File

@@ -2,7 +2,7 @@
{
"creation": "2013-03-28 10:35:31",
"docstatus": 0,
"modified": "2013-09-24 15:35:12",
"modified": "2014-01-15 15:45:07",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -102,7 +102,7 @@
"reqd": 1
},
{
"depends_on": "eval:sys_defaults.auto_accounting_for_stock",
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
"doctype": "DocField",
"fieldname": "expense_account",
"fieldtype": "Link",
@@ -110,6 +110,7 @@
"options": "Account"
},
{
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
"doctype": "DocField",
"fieldname": "cost_center",
"fieldtype": "Link",

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import cint, validate_email_add
from webnotes import msgprint, _
from webnotes import throw, msgprint, _
class DocType:
def __init__(self, doc, doclist=[]):
@@ -18,7 +18,7 @@ class DocType:
def validate(self):
if self.doc.email_id and not validate_email_add(self.doc.email_id):
msgprint("Please enter valid Email Id", raise_exception=1)
throw(_("Please enter valid Email Id"))
self.update_parent_account()
@@ -76,8 +76,8 @@ class DocType:
for d in bins:
if d['actual_qty'] or d['reserved_qty'] or d['ordered_qty'] or \
d['indented_qty'] or d['projected_qty'] or d['planned_qty']:
msgprint("""Warehouse: %s can not be deleted as qty exists for item: %s"""
% (self.doc.name, d['item_code']), raise_exception=1)
throw("""Warehouse: %s can not be deleted as qty exists for item: %s"""
% (self.doc.name, d['item_code']))
else:
webnotes.conn.sql("delete from `tabBin` where name = %s", d['name'])
@@ -88,27 +88,23 @@ class DocType:
if webnotes.conn.sql("""select name from `tabStock Ledger Entry`
where warehouse = %s""", self.doc.name):
msgprint("""Warehouse can not be deleted as stock ledger entry
exists for this warehouse.""", raise_exception=1)
throw(_("""Warehouse can not be deleted as stock ledger entry
exists for this warehouse."""))
def before_rename(self, olddn, newdn, merge=False):
# Add company abbr if not provided
from setup.doctype.company.company import get_name_with_abbr
new_warehouse = get_name_with_abbr(newdn, self.doc.company)
if merge:
if not webnotes.conn.exists("Warehouse", newdn):
webnotes.throw(_("Warehouse ") + newdn +_(" does not exists"))
if self.doc.company != webnotes.conn.get_value("Warehouse", new_warehouse, "company"):
if self.doc.company != webnotes.conn.get_value("Warehouse", newdn, "company"):
webnotes.throw(_("Both Warehouse must belong to same Company"))
webnotes.conn.sql("delete from `tabBin` where warehouse=%s", olddn)
from accounts.utils import rename_account_for
rename_account_for("Warehouse", olddn, new_warehouse, merge)
rename_account_for("Warehouse", olddn, newdn, merge)
return new_warehouse
return newdn
def after_rename(self, olddn, newdn, merge=False):
if merge:

View File

@@ -15,8 +15,8 @@ def execute(filters=None):
bom_rate = get_item_bom_rate()
val_rate_map = get_valuation_rate()
precision = get_currency_precision or 2
from accounts.utils import get_currency_precision
precision = get_currency_precision() or 2
data = []
for item in sorted(item_map):
data.append([item, item_map[item]["item_name"],
@@ -30,14 +30,6 @@ def execute(filters=None):
])
return columns, data
def get_currency_precision():
company_currency = webnotes.conn.get_value("Company",
webnotes.conn.get_default("company"), "default_currency")
currency_format = webnotes.conn.get_value("Currency", company_currency, "number_format")
from webnotes.utils import get_number_format_info
return get_number_format_info(currency_format)[2]
def get_columns(filters):
"""return columns based on filters"""
@@ -65,13 +57,14 @@ def get_price_list():
rate = {}
price_list = webnotes.conn.sql("""select item_code, buying_or_selling,
concat(price_list, " - ", currency, " ", ref_rate) as price
from `tabItem Price`""", as_dict=1)
price_list = webnotes.conn.sql("""select ip.item_code, ip.buying, ip.selling,
concat(ip.price_list, " - ", ip.currency, " ", ip.ref_rate) as price
from `tabItem Price` ip, `tabPrice List` pl
where ip.price_list=pl.name and pl.enabled=1""", as_dict=1)
for j in price_list:
if j.price:
rate.setdefault(j.item_code, {}).setdefault(j.buying_or_selling, []).append(j.price)
rate.setdefault(j.item_code, {}).setdefault("Buying" if j.buying else "Selling", []).append(j.price)
item_rate_map = {}
for item in rate:

View File

@@ -0,0 +1,22 @@
[
{
"creation": "2013-09-25 10:21:15",
"docstatus": 0,
"modified": "2014-01-07 18:35:22",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doctype": "Report",
"is_standard": "Yes",
"json": "{\"filters\":[[\"Item Price\",\"price_list\",\"like\",\"%\"],[\"Item Price\",\"item_code\",\"like\",\"%\"]],\"columns\":[[\"name\",\"Item Price\"],[\"price_list\",\"Item Price\"],[\"item_code\",\"Item Price\"],[\"item_name\",\"Item Price\"],[\"item_description\",\"Item Price\"],[\"ref_rate\",\"Item Price\"],[\"buying\",\"Item Price\"],[\"selling\",\"Item Price\"],[\"currency\",\"Item Price\"]],\"sort_by\":\"Item Price.modified\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}",
"name": "__common__",
"ref_doctype": "Price List",
"report_name": "Item-wise Price List Rate",
"report_type": "Report Builder"
},
{
"doctype": "Report",
"name": "Item-wise Price List Rate"
}
]

View File

@@ -2,11 +2,12 @@
{
"creation": "2013-01-10 16:34:30",
"docstatus": 0,
"modified": "2013-11-02 16:59:22",
"modified": "2014-01-14 15:56:22",
"modified_by": "Administrator",
"owner": "harshada@webnotestech.com"
},
{
"allow_import": 1,
"autoname": "naming_series:",
"doctype": "DocType",
"icon": "icon-bug",

View File

@@ -52,11 +52,6 @@ Original Query:
subject = '['+cstr(d.name)+'] ' + cstr(d.subject), \
msg = cstr(response))
def auto_close_tickets(self):
webnotes.conn.sql("""update `tabSupport Ticket` set status = 'Closed'
where status = 'Replied'
and date_sub(curdate(),interval 15 Day) > modified""")
def get_support_mails():
if cint(webnotes.conn.get_value('Email Settings', None, 'sync_support_mails')):
SupportMailbox()

View File

@@ -66,4 +66,9 @@ class DocType(TransactionBase):
def set_status(name, status):
st = webnotes.bean("Support Ticket", name)
st.doc.status = status
st.save()
st.save()
def auto_close_tickets():
webnotes.conn.sql("""update `tabSupport Ticket` set status = 'Closed'
where status = 'Replied'
and date_sub(curdate(),interval 15 Day) > modified""")

View File

@@ -20,4 +20,5 @@ Info:,,,,,"One of: No, Yes"
Start entering data below this line,,,,
,,2009,01-01-2009,31-12-2009,No
,,2010,01-01-2010,31-12-2010,No
,,2011,01-01-2011,31-12-2011,No
,,2011,01-01-2011,31-12-2011,No
,,2012,01-01-2012,31-12-2012,No
1 Data Import Template
20 Start entering data below this line
21 2009 01-01-2009 31-12-2009
22 2010 01-01-2010 31-12-2010
23 2011 01-01-2011 31-12-2011
24 2012 01-01-2012 31-12-2012

View File

@@ -1,49 +1,49 @@
Data Import Template,,,,,,,
Table:,Item Price,,,,,,
,,,,,,,
,,,,,,,
Notes:,,,,,,,
Please do not change the template headings.,,,,,,,
First data column must be blank.,,,,,,,
"If you are uploading new records, leave the ""name"""" (ID) column blank.""",,,,,,,
"If you are uploading new records, ""Naming Series"""" becomes mandatory"," if present.""",,,,,,
Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish.,,,,,,,
"For updating, you can update only selective columns.",,,,,,,
You can only upload upto 5000 records in one go. (may be less in some cases),,,,,,,
,,,,,,,
DocType:,Item Price,,,,,,
Column Labels:,ID,Price List,Item Code,Rate,Valid for Buying or Selling?,Item Name,Item Description
Column Name:,name,price_list,item_code,ref_rate,buying_or_selling,item_name,item_description
Mandatory:,Yes,Yes,Yes,Yes,No,No,No
Type:,Data (text),Link,Link,Currency,Select,Data,Text
Info:,,Valid Price List,Valid Item,,"One of: Selling, Buying",,
Start entering data below this line,,,,,,,
,,Standard Buying,Base Bearing Plate,15,Buying,,
,,Standard Buying,Base Plate,20,Buying,,
,,Standard Buying,Bearing Block,10,Buying,,
,,Standard Buying,Bearing Collar,20,Buying,,
,,Standard Buying,Bearing Pipe,15,Buying,,
,,Standard Buying,Blade Rib,10,Buying,,
,,Standard Buying,Disc Collars,74,Buying,,
,,Standard Buying,External Disc,45,Buying,,
,,Standard Buying,Internal Disc,33,Buying,,
,,Standard Buying,Shaft,30,Buying,,
,,Standard Buying,Stand,40,Buying,,
,,Standard Buying,Upper Bearing Plate,50,Buying,,
,,Standard Buying,Wing Sheet,22,Buying,,
,,Standard Selling,Wind Turbine,21,Selling,,
,,Standard Selling,Wind Mill A Series,28,Selling,,
,,Standard Selling,Wind MIll C Series,14,Selling,,
,,Standard Selling,Base Bearing Plate,28,Selling,,
,,Standard Selling,Base Plate,21,Selling,,
,,Standard Selling,Bearing Block,14,Selling,,
,,Standard Selling,Bearing Collar,103.6,Selling,,
,,Standard Selling,Bearing Pipe,63,Selling,,
,,Standard Selling,Blade Rib,46.2,Selling,,
,,Standard Selling,Disc Collars,42,Selling,,
,,Standard Selling,External Disc,56,Selling,,
,,Standard Selling,Internal Disc,70,Selling,,
,,Standard Selling,Shaft,340,Selling,,
,,Standard Selling,Stand,400,Selling,,
,,Standard Selling,Upper Bearing Plate,300,Selling,,
,,Standard Selling,Wing Sheet,30.8,Selling,,
Data Import Template,,,,,,,,
Table:,Item Price,,,,,,,
,,,,,,,,
,,,,,,,,
Notes:,,,,,,,,
Please do not change the template headings.,,,,,,,,
First data column must be blank.,,,,,,,,
"If you are uploading new records, leave the ""name"" (ID) column blank.",,,,,,,,
"If you are uploading new records, ""Naming Series"" becomes mandatory, if present.",,,,,,,,
Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish.,,,,,,,,
"For updating, you can update only selective columns.",,,,,,,,
You can only upload upto 5000 records in one go. (may be less in some cases),,,,,,,,
,,,,,,,,
DocType:,Item Price,,,,,,,
Column Labels:,ID,Price List,Item Code,Rate,Buying,Selling,Item Name,Item Description
Column Name:,name,price_list,item_code,ref_rate,buying,selling,item_name,item_description
Mandatory:,Yes,Yes,Yes,Yes,No,No,No,No
Type:,Data (text),Link,Link,Currency,Check,Check,Data,Text
Info:,,Valid Price List,Valid Item,,0 or 1,0 or 1,,
Start entering data below this line,,,,,,,,
,,Standard Buying,Base Bearing Plate,15,1,,,
,,Standard Buying,Base Plate,20,1,,,
,,Standard Buying,Bearing Block,10,1,,,
,,Standard Buying,Bearing Collar,20,1,,,
,,Standard Buying,Bearing Pipe,15,1,,,
,,Standard Buying,Blade Rib,10,1,,,
,,Standard Buying,Disc Collars,74,1,,,
,,Standard Buying,External Disc,45,1,,,
,,Standard Buying,Internal Disc,33,1,,,
,,Standard Buying,Shaft,30,1,,,
,,Standard Buying,Stand,40,1,,,
,,Standard Buying,Upper Bearing Plate,50,1,,,
,,Standard Buying,Wing Sheet,22,1,,,
,,Standard Selling,Wind Turbine,21,,1,,
,,Standard Selling,Wind Mill A Series,28,,1,,
,,Standard Selling,Wind MIll C Series,14,,1,,
,,Standard Selling,Base Bearing Plate,28,,1,,
,,Standard Selling,Base Plate,21,,1,,
,,Standard Selling,Bearing Block,14,,1,,
,,Standard Selling,Bearing Collar,103.6,,1,,
,,Standard Selling,Bearing Pipe,63,,1,,
,,Standard Selling,Blade Rib,46.2,,1,,
,,Standard Selling,Disc Collars,42,,1,,
,,Standard Selling,External Disc,56,,1,,
,,Standard Selling,Internal Disc,70,,1,,
,,Standard Selling,Shaft,340,,1,,
,,Standard Selling,Stand,400,,1,,
,,Standard Selling,Upper Bearing Plate,300,,1,,
,,Standard Selling,Wing Sheet,30.8,,1,,
1 Data Import Template
2 Table: Item Price
3
4
5 Notes:
6 Please do not change the template headings.
7 First data column must be blank.
8 If you are uploading new records, leave the "name"" (ID) column blank." If you are uploading new records, leave the "name" (ID) column blank.
9 If you are uploading new records, "Naming Series"" becomes mandatory If you are uploading new records, "Naming Series" becomes mandatory, if present. if present."
10 Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish.
11 For updating, you can update only selective columns.
12 You can only upload upto 5000 records in one go. (may be less in some cases)
13
14 DocType: Item Price
15 Column Labels: ID Price List Item Code Rate Valid for Buying or Selling? Buying Item Name Selling Item Description Item Name Item Description
16 Column Name: name price_list item_code ref_rate buying_or_selling buying item_name selling item_description item_name item_description
17 Mandatory: Yes Yes Yes Yes No No No No
18 Type: Data (text) Link Link Currency Select Check Data Check Text Data Text
19 Info: Valid Price List Valid Item One of: Selling, Buying 0 or 1 0 or 1
20 Start entering data below this line
21 Standard Buying Base Bearing Plate 15 Buying 1
22 Standard Buying Base Plate 20 Buying 1
23 Standard Buying Bearing Block 10 Buying 1
24 Standard Buying Bearing Collar 20 Buying 1
25 Standard Buying Bearing Pipe 15 Buying 1
26 Standard Buying Blade Rib 10 Buying 1
27 Standard Buying Disc Collars 74 Buying 1
28 Standard Buying External Disc 45 Buying 1
29 Standard Buying Internal Disc 33 Buying 1
30 Standard Buying Shaft 30 Buying 1
31 Standard Buying Stand 40 Buying 1
32 Standard Buying Upper Bearing Plate 50 Buying 1
33 Standard Buying Wing Sheet 22 Buying 1
34 Standard Selling Wind Turbine 21 Selling 1
35 Standard Selling Wind Mill A Series 28 Selling 1
36 Standard Selling Wind MIll C Series 14 Selling 1
37 Standard Selling Base Bearing Plate 28 Selling 1
38 Standard Selling Base Plate 21 Selling 1
39 Standard Selling Bearing Block 14 Selling 1
40 Standard Selling Bearing Collar 103.6 Selling 1
41 Standard Selling Bearing Pipe 63 Selling 1
42 Standard Selling Blade Rib 46.2 Selling 1
43 Standard Selling Disc Collars 42 Selling 1
44 Standard Selling External Disc 56 Selling 1
45 Standard Selling Internal Disc 70 Selling 1
46 Standard Selling Shaft 340 Selling 1
47 Standard Selling Stand 400 Selling 1
48 Standard Selling Upper Bearing Plate 300 Selling 1
49 Standard Selling Wing Sheet 30.8 Selling 1

View File

@@ -19,7 +19,7 @@ company_abbr = "WP"
country = "United States"
currency = "USD"
time_zone = "America/New_York"
start_date = '2013-01-01'
start_date = '2014-01-01'
bank_name = "Citibank"
runs_for = None
prob = {
@@ -105,6 +105,10 @@ def run_accounts(current_date):
for so in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Sales Invoice")]:
si = webnotes.bean(make_sales_invoice(so))
si.doc.posting_date = current_date
for d in si.doclist.get({"parentfield": "entries"}):
if not d.income_account:
d.income_account = "Sales - {}".format(company_abbr)
si.insert()
si.submit()
webnotes.conn.commit()
@@ -170,6 +174,9 @@ def run_stock(current_date):
dn = webnotes.bean(make_delivery_note(so))
dn.doc.posting_date = current_date
dn.doc.fiscal_year = current_date.year
for d in dn.doclist.get({"parentfield": "delivery_note_details"}):
d.expense_account = "Cost of Goods Sold - {}".format(company_abbr)
dn.insert()
try:
dn.submit()
@@ -236,7 +243,7 @@ def run_manufacturing(current_date):
ppt = webnotes.bean("Production Planning Tool", "Production Planning Tool")
ppt.doc.company = company
ppt.doc.use_multi_level_bom = 1
ppt.doc.purchase_request_for_warehouse = "Stores - WP"
ppt.doc.purchase_request_for_warehouse = "Stores - {}".format(company_abbr)
ppt.run_method("get_open_sales_orders")
ppt.run_method("get_items_from_so")
ppt.run_method("raise_production_order")
@@ -380,8 +387,8 @@ def complete_setup():
setup_account({
"first_name": "Test",
"last_name": "User",
"fy_start_date": "2013-01-01",
"fy_end_date": "2013-12-31",
"fy_start_date": "2014-01-01",
"fy_end_date": "2014-12-31",
"industry": "Manufacturing",
"company_name": company,
"company_abbr": company_abbr,

View File

@@ -78,10 +78,12 @@ class TransactionBase(StatusUpdater):
3. Clears existing Sales Team and fetches the one mentioned in Customer
"""
customer_defaults = self.get_customer_defaults()
customer_defaults["selling_price_list"] = customer_defaults.get("price_list") or \
webnotes.conn.get_value("Customer Group", self.doc.customer_group, "default_price_list") or \
self.doc.selling_price_list
customer_defaults["selling_price_list"] = \
self.get_user_default_price_list("selling_price_list") or \
customer_defaults.get("price_list") or \
webnotes.conn.get_value("Customer Group", self.doc.customer_group,
"default_price_list") or self.doc.selling_price_list
for fieldname, val in customer_defaults.items():
if self.meta.get_field(fieldname):
@@ -90,6 +92,12 @@ class TransactionBase(StatusUpdater):
if self.meta.get_field("sales_team") and self.doc.customer:
self.set_sales_team_for_customer()
def get_user_default_price_list(self, price_list):
from webnotes.defaults import get_defaults_for
user_default_price_list = get_defaults_for(webnotes.session.user).get(price_list)
return cstr(user_default_price_list) \
if not isinstance(user_default_price_list, list) else ""
def set_sales_team_for_customer(self):
from webnotes.model import default_fields
@@ -120,8 +128,9 @@ class TransactionBase(StatusUpdater):
out["supplier_name"] = supplier.supplier_name
if supplier.default_currency:
out["currency"] = supplier.default_currency
if supplier.default_price_list:
out["buying_price_list"] = supplier.default_price_list
out["buying_price_list"] = self.get_user_default_price_list("buying_price_list") or \
supplier.default_price_list or self.doc.buying_price_list
return out