Compare commits
392 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f32218bc0 | ||
|
|
b4bff7e298 | ||
|
|
41c5fda196 | ||
|
|
305c82bd8d | ||
|
|
cd11bdfdbb | ||
|
|
0c0e49a421 | ||
|
|
3f398d24f3 | ||
|
|
d9a82738d0 | ||
|
|
1f7a5dcd07 | ||
|
|
452619c668 | ||
|
|
9d0dba5569 | ||
|
|
3df1327b94 | ||
|
|
38eaaade89 | ||
|
|
2a98e59bd4 | ||
|
|
03348364e9 | ||
|
|
83fd31973f | ||
|
|
ac64b39562 | ||
|
|
c73c576536 | ||
|
|
034429b34d | ||
|
|
874866e9f9 | ||
|
|
c365ce8f21 | ||
|
|
3a11f34355 | ||
|
|
91eac5a7cf | ||
|
|
aef7a6ec44 | ||
|
|
6192d24235 | ||
|
|
24fe7286fc | ||
|
|
991c121b57 | ||
|
|
23ec18e3e4 | ||
|
|
500ddc94c7 | ||
|
|
bbd8b04012 | ||
|
|
bb1b6b42e2 | ||
|
|
8e71074e1c | ||
|
|
ff0deedca9 | ||
|
|
4bb90add1d | ||
|
|
44ec05f79b | ||
|
|
7844b79274 | ||
|
|
ea75295bb3 | ||
|
|
d2c643eb0b | ||
|
|
94fcb0e9f9 | ||
|
|
3362d6b948 | ||
|
|
75c1682e61 | ||
|
|
2dc8972794 | ||
|
|
f786eccdf9 | ||
|
|
a1036ad50b | ||
|
|
5b34d00bc0 | ||
|
|
ee3b788024 | ||
|
|
b509b06edf | ||
|
|
5fcccda883 | ||
|
|
4fb9230d16 | ||
|
|
37d3686372 | ||
|
|
5eafa5a487 | ||
|
|
97dbb4d125 | ||
|
|
17ac38ff29 | ||
|
|
65652071ff | ||
|
|
79dc8ac9cc | ||
|
|
15e7646edd | ||
|
|
d1b87ba41c | ||
|
|
a5576f5b21 | ||
|
|
8976ad5ca1 | ||
|
|
c7f8b82fff | ||
|
|
6b62b86bbf | ||
|
|
8fbf856618 | ||
|
|
7d6d678e8d | ||
|
|
c22ba2ec26 | ||
|
|
0cf0ebf08b | ||
|
|
0ff35a852a | ||
|
|
e04431ea5c | ||
|
|
fafc277666 | ||
|
|
fe1e4a41e6 | ||
|
|
7a8c5b0c2c | ||
|
|
056ecdca6a | ||
|
|
3b281a0a1b | ||
|
|
a60ab1af75 | ||
|
|
550fc695f1 | ||
|
|
013493de7a | ||
|
|
b3737c812a | ||
|
|
6d5a29af6a | ||
|
|
20d8c52d2a | ||
|
|
e11f299b21 | ||
|
|
68000c66fc | ||
|
|
3cc77b52e7 | ||
|
|
bd4348db10 | ||
|
|
4fd1cebf95 | ||
|
|
b892cc8b02 | ||
|
|
8652bce9e3 | ||
|
|
4e372a30fa | ||
|
|
df327f2974 | ||
|
|
3ccbb8f8b7 | ||
|
|
0d931e1d7d | ||
|
|
431b4fba72 | ||
|
|
fba985d49d | ||
|
|
4bd562d669 | ||
|
|
bb88e964a4 | ||
|
|
5f79479bd0 | ||
|
|
12b4096e68 | ||
|
|
1ef72c0b66 | ||
|
|
648191b9e8 | ||
|
|
624927bf0b | ||
|
|
3df2639a32 | ||
|
|
d982e8fcda | ||
|
|
af497ef669 | ||
|
|
79f3ea4094 | ||
|
|
e0a47aeb2f | ||
|
|
1516b8d54a | ||
|
|
e33047250e | ||
|
|
c4e38ffd4d | ||
|
|
be7703387d | ||
|
|
b800382abf | ||
|
|
e689a903d8 | ||
|
|
ecc6af9d2a | ||
|
|
5c5688b374 | ||
|
|
80f30094fb | ||
|
|
6fb2117767 | ||
|
|
0631aed3d9 | ||
|
|
88b0a1305f | ||
|
|
9e98fdfc6e | ||
|
|
cd6b955b99 | ||
|
|
bfd26b7084 | ||
|
|
18960c7757 | ||
|
|
9a7838265d | ||
|
|
57d3c93e6b | ||
|
|
a0b846fb88 | ||
|
|
8356d4b892 | ||
|
|
ba62013cbb | ||
|
|
59de1dae6a | ||
|
|
91cecf8eac | ||
|
|
6ec558bd59 | ||
|
|
11dd3ffdb5 | ||
|
|
f0ef673498 | ||
|
|
57d07d6b8e | ||
|
|
fc682c86c6 | ||
|
|
15f52e7b71 | ||
|
|
26bfede116 | ||
|
|
86217ca96c | ||
|
|
ae4ff5a403 | ||
|
|
0452b405f4 | ||
|
|
dc7004e083 | ||
|
|
ebdefade9b | ||
|
|
e9afbfde76 | ||
|
|
086da451ca | ||
|
|
91d2ace9bb | ||
|
|
91a9ee5179 | ||
|
|
11137850cb | ||
|
|
584153a1b1 | ||
|
|
eed0a4e2df | ||
|
|
f5cc1bd44c | ||
|
|
cc56ff5c37 | ||
|
|
20d3bef3c3 | ||
|
|
1f4c263a63 | ||
|
|
d0a2b1619b | ||
|
|
0fe6ced99d | ||
|
|
e50e0e4b30 | ||
|
|
cd717e422f | ||
|
|
6b862fcae5 | ||
|
|
a22e0d0c99 | ||
|
|
8ca5940f76 | ||
|
|
6c46b4edc4 | ||
|
|
8395a7ad6f | ||
|
|
6863b03790 | ||
|
|
a76067eea1 | ||
|
|
216f9373c9 | ||
|
|
5fe88ea93e | ||
|
|
fbeab5bf73 | ||
|
|
a3e070bc6b | ||
|
|
3ffe89659a | ||
|
|
5c3b69476d | ||
|
|
da17ceea73 | ||
|
|
2d84945839 | ||
|
|
8dc4c945dc | ||
|
|
cc9c7d5e2a | ||
|
|
07d0e9a2b2 | ||
|
|
f38d6d9c44 | ||
|
|
07bb1811af | ||
|
|
f07462860b | ||
|
|
720b06495c | ||
|
|
83ad646af4 | ||
|
|
8179bcbabd | ||
|
|
6be8bea934 | ||
|
|
0b9129e519 | ||
|
|
778e06d0ee | ||
|
|
3f5e80ebe3 | ||
|
|
ea943c6fe4 | ||
|
|
82a9fde921 | ||
|
|
b35721029b | ||
|
|
f403031449 | ||
|
|
25f36489b3 | ||
|
|
5005e467a0 | ||
|
|
68a148e293 | ||
|
|
205eae322b | ||
|
|
935f4a474b | ||
|
|
aa62a62bb0 | ||
|
|
104f62090d | ||
|
|
3ff7f79cc7 | ||
|
|
89e7f8b387 | ||
|
|
2fbc8509f5 | ||
|
|
67d87e29e3 | ||
|
|
55cf6c5f7e | ||
|
|
f3cf15fa0d | ||
|
|
d53d2ed791 | ||
|
|
34aeefc0a1 | ||
|
|
d8031d1a53 | ||
|
|
1098755d26 | ||
|
|
774f676a25 | ||
|
|
1629393618 | ||
|
|
4cf46edabc | ||
|
|
e6498996fa | ||
|
|
98b7bb5679 | ||
|
|
99017b173d | ||
|
|
42f2d1a7a8 | ||
|
|
a125a6199c | ||
|
|
ba1cdc6c57 | ||
|
|
875c941f3d | ||
|
|
8eeb5694ba | ||
|
|
0bef91c241 | ||
|
|
ae02209b6a | ||
|
|
e0adb6bbd6 | ||
|
|
efa191c72e | ||
|
|
40fe3a2cdf | ||
|
|
ed77429496 | ||
|
|
c7afbea708 | ||
|
|
dd8fba6783 | ||
|
|
8e74df09a4 | ||
|
|
3d73a6f7f2 | ||
|
|
46c8ccc6a8 | ||
|
|
5d0674a23a | ||
|
|
a831868d02 | ||
|
|
943dc09f29 | ||
|
|
ea7533fa75 | ||
|
|
b9399d8781 | ||
|
|
8cd0f67b25 | ||
|
|
32a118d68c | ||
|
|
a02d5d1104 | ||
|
|
36cd433999 | ||
|
|
6ff3a094e2 | ||
|
|
50d8c4a10f | ||
|
|
7c088ff623 | ||
|
|
7cf01e7c75 | ||
|
|
fc03a0463c | ||
|
|
5ecc26bf15 | ||
|
|
c1cf495a93 | ||
|
|
ce642d73cb | ||
|
|
2fa057e4ad | ||
|
|
7e0e85912b | ||
|
|
defecd3785 | ||
|
|
fccf7f2a68 | ||
|
|
cce7189b4f | ||
|
|
31a96d2a3f | ||
|
|
39c0add5a2 | ||
|
|
58200182b4 | ||
|
|
c2c73ae96a | ||
|
|
ae95a8aa15 | ||
|
|
b9f54ca946 | ||
|
|
a8c6ec27c0 | ||
|
|
3c1b153cdb | ||
|
|
06f91e2dc1 | ||
|
|
13f39eb821 | ||
|
|
a8fb2db001 | ||
|
|
27cf190269 | ||
|
|
7ad556cd4c | ||
|
|
475729cefe | ||
|
|
f7713ebfa7 | ||
|
|
92640cc899 | ||
|
|
826f020862 | ||
|
|
93a186aa11 | ||
|
|
742d3e5549 | ||
|
|
bcbe32ce7c | ||
|
|
b434f2687e | ||
|
|
a752eca82c | ||
|
|
37da7d7d05 | ||
|
|
b5d9b38dee | ||
|
|
11e2a9ac90 | ||
|
|
1275ea5123 | ||
|
|
812224e56e | ||
|
|
8f17281011 | ||
|
|
8233cb11ed | ||
|
|
984a7a7e61 | ||
|
|
b5cc946771 | ||
|
|
65dd1f6b4c | ||
|
|
7c9a6eba3f | ||
|
|
f2ccde0454 | ||
|
|
9e4889d756 | ||
|
|
b81ece9ddf | ||
|
|
2f822476dd | ||
|
|
dcfe19d868 | ||
|
|
4f40b2dca5 | ||
|
|
1b48fde986 | ||
|
|
33db332eca | ||
|
|
257e18b640 | ||
|
|
292f46fec0 | ||
|
|
78a0be666f | ||
|
|
ce4f520908 | ||
|
|
29160441bb | ||
|
|
1b18bba04a | ||
|
|
f8c26bb778 | ||
|
|
ccd0617e19 | ||
|
|
bf10d0f98b | ||
|
|
dbb67fb4fd | ||
|
|
404f39d373 | ||
|
|
bbee9b6cc4 | ||
|
|
69b0535e10 | ||
|
|
7f63c1ad7c | ||
|
|
ebe1ebead2 | ||
|
|
f2b3307136 | ||
|
|
9d215c2d9b | ||
|
|
3cf0d51e65 | ||
|
|
9fc5ddc26e | ||
|
|
0ff31f0ebf | ||
|
|
40349f4b00 | ||
|
|
b36517158b | ||
|
|
3b9720f0be | ||
|
|
cf26b2ca1c | ||
|
|
02a40e9d7b | ||
|
|
ea199f9cd9 | ||
|
|
161f35a687 | ||
|
|
fcb984b294 | ||
|
|
723fe8fb1b | ||
|
|
47c0c8ba49 | ||
|
|
3e0a937cb8 | ||
|
|
bd63f0056a | ||
|
|
55daa9cd24 | ||
|
|
764b9bfeba | ||
|
|
62b985d405 | ||
|
|
ed393d1025 | ||
|
|
ed376cacc8 | ||
|
|
7461806b1c | ||
|
|
bb7c5ac0f8 | ||
|
|
0272fc05bf | ||
|
|
4f6b68fef2 | ||
|
|
eae2ddac69 | ||
|
|
99be9d17d5 | ||
|
|
5df63e36d4 | ||
|
|
bd99606a14 | ||
|
|
b0a46f397a | ||
|
|
53c9b63c0b | ||
|
|
9b2078feab | ||
|
|
30304e68ff | ||
|
|
6bc500bffa | ||
|
|
8be895091e | ||
|
|
f5f8a1f288 | ||
|
|
c925a38f79 | ||
|
|
c23230faea | ||
|
|
6855b87f76 | ||
|
|
07d030208f | ||
|
|
47f6e32920 | ||
|
|
7bd1453f8f | ||
|
|
bf416cfbf8 | ||
|
|
67918fff32 | ||
|
|
132dac9712 | ||
|
|
57914f140e | ||
|
|
ede0af97cd | ||
|
|
ad4ede0e23 | ||
|
|
cfcf9b3832 | ||
|
|
d2065ce3bf | ||
|
|
31edddace6 | ||
|
|
8f29159fb7 | ||
|
|
d9f1b539dc | ||
|
|
60bd383a25 | ||
|
|
c0ec3c3f7b | ||
|
|
60aa1170d5 | ||
|
|
9630aa3d7f | ||
|
|
aa6576c0ea | ||
|
|
fa5ecb066e | ||
|
|
c36524ec54 | ||
|
|
cba3570cf6 | ||
|
|
5b7503c074 | ||
|
|
8441dd9184 | ||
|
|
78869f1e77 | ||
|
|
ff8f1bc88e | ||
|
|
91b0dce4d8 | ||
|
|
59f7b8c4a1 | ||
|
|
2476a8aab9 | ||
|
|
46ffbb74ff | ||
|
|
492aff2a8b | ||
|
|
c3fbc04aab | ||
|
|
5b866db6bc | ||
|
|
9fbb8192e1 | ||
|
|
ea1408f2e0 | ||
|
|
f2a941b1a4 | ||
|
|
ca1cfd91ea | ||
|
|
c3d43e672b | ||
|
|
e141fdcfcc | ||
|
|
7cb8f890bc | ||
|
|
d6aadef395 | ||
|
|
11c899bc1f | ||
|
|
00efeb26f4 | ||
|
|
1129ac711e | ||
|
|
2ea593bdd8 | ||
|
|
02fd6f56d6 | ||
|
|
098b444f6f | ||
|
|
e72bde5159 | ||
|
|
c10e106f8f | ||
|
|
2c111b7b14 |
68
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
68
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
Issue: Bug report
|
||||
|
||||
Our project, as you've probably heard, is getting really popular and truth is we're getting a bit overwhelmed by the activity surrounding it. There are just too many issues for us to manage properly.
|
||||
|
||||
**Do the checklist before filing an issue:**
|
||||
- [ ] Have a usage question? Ask your question on [Discuss Forum](https://discuss.erpnext.com). We use [Discuss Forum](https://discuss.erpnext.com) for usage question and GitHub for bugs.
|
||||
- [ ] Can you replicate the issue?
|
||||
- [ ] Is this something you can debug and fix? Send a pull request! Bug fixes and documentation fixes are welcome
|
||||
|
||||
**Describe the bug** :chart_with_downwards_trend:
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce** :page_with_curl:
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior** :chart_with_upwards_trend:
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots** :crystal_ball:
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):** :cyclone:
|
||||
- OS:
|
||||
- [ ] Linux
|
||||
- [ ] macOS
|
||||
- [ ] Windows
|
||||
- [ ] Others? Please mention:
|
||||
- Browser:
|
||||
- [ ] Safari
|
||||
- [ ] Chrome
|
||||
- [ ] Firefox
|
||||
- [ ] Other? Please mention:
|
||||
|
||||
**Smartphone (please complete the following information):** :iphone: :computer:
|
||||
- Device:
|
||||
- [ ] iPhone
|
||||
- [ ] Android
|
||||
- Browser:
|
||||
- [ ] Safari
|
||||
- [ ] Chrome
|
||||
- [ ] Firefox
|
||||
- [ ] Other? Please mention:
|
||||
|
||||
**Version Information**
|
||||
- Which branch are you on?
|
||||
- [ ] `master` :star2:
|
||||
- [ ] `develop` :fire:
|
||||
- Frappe Version:
|
||||
- ERPNext Version:
|
||||
|
||||
**Additional context** :page_facing_up:
|
||||
Add any other context about the problem here.
|
||||
|
||||
**Possible Solution** :bookmark_tabs:
|
||||
Any idea what might be causing the issue. Or if you have a proposed solution to the problem,
|
||||
|
||||
**Please don't be intimidated by the long list of options you've fill. Try to fill out as much as you can. Remember, the more the information the easier it is for us to replicate and fix the issue** :grin:
|
||||
|
||||
21
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
21
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
Issue: Feature Request
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
|
||||
|
||||
28
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
28
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
Pull-Request
|
||||
|
||||
- [ ] Have you followed the guidelines in our Contributing document?
|
||||
- [ ] Have you checked to ensure there aren't other open [Pull Requests](../pulls) for the same update/change?
|
||||
- [ ] Have you lint your code locally prior to submission?
|
||||
- [ ] Have you successfully run tests with your changes locally?
|
||||
- [ ] Does your commit message have an explanation for your changes and why you'd like us to include them?
|
||||
- [ ] Docs have been added / updated
|
||||
- [ ] Tests for the changes have been added (for bug fixes / features)
|
||||
- [ ] Did you modify the existing test cases? If yes, why?
|
||||
|
||||
---
|
||||
|
||||
What type of a PR is this?
|
||||
|
||||
- [ ] Changes to Existing Features
|
||||
- [ ] New Feature Submissions
|
||||
- [ ] Bug Fix
|
||||
- [ ] Breaking Change
|
||||
|
||||
---
|
||||
|
||||
- Motivation and Context (What existing problem does the pull request solve):
|
||||
- Related Issue:
|
||||
- Screenshots (if applicable, remember, a picture tells a thousand words):
|
||||
|
||||
**Please don't be intimidated by the long list of options you've fill. Try to fill out as much as you can. Remember, the more the information the easier it is for us to test and get your pull request merged** :grin:
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,3 +8,4 @@ latest_updates.json
|
||||
*.egg-info
|
||||
dist/
|
||||
erpnext/docs/current
|
||||
*.swp
|
||||
|
||||
@@ -11,6 +11,7 @@ install:
|
||||
- pip install flake8==3.3.0
|
||||
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
|
||||
- sudo rm /etc/apt/sources.list.d/docker.list
|
||||
- sudo apt-get install hhvm && rm -rf /home/travis/.kiex/
|
||||
- sudo apt-get purge -y mysql-common mysql-server mysql-client
|
||||
- nvm install v7.10.0
|
||||
- wget https://raw.githubusercontent.com/frappe/bench/master/playbooks/install.py
|
||||
@@ -32,6 +33,7 @@ before_script:
|
||||
- bench reinstall --yes
|
||||
- bench build
|
||||
- bench scheduler disable
|
||||
- sed -i 's/9000/9001/g' sites/common_site_config.json
|
||||
- bench start &
|
||||
- sleep 10
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '10.1.20'
|
||||
__version__ = '10.1.66'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -49,10 +49,16 @@ frappe.ui.form.on('Account', {
|
||||
}
|
||||
|
||||
if(!frm.doc.__islocal) {
|
||||
frm.add_custom_button(__('Update Account Number'), function () {
|
||||
frm.add_custom_button(__('Update Account Name / Number'), function () {
|
||||
frm.trigger("update_account_number");
|
||||
});
|
||||
}
|
||||
|
||||
if(!frm.doc.__islocal) {
|
||||
frm.add_custom_button(__('Merge Account'), function () {
|
||||
frm.trigger("merge_account");
|
||||
});
|
||||
}
|
||||
},
|
||||
account_type: function (frm) {
|
||||
if (frm.doc.is_group == 0) {
|
||||
@@ -98,20 +104,65 @@ frappe.ui.form.on('Account', {
|
||||
}
|
||||
},
|
||||
|
||||
update_account_number: function(frm) {
|
||||
merge_account: function(frm) {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Update Account Number'),
|
||||
title: __('Merge with Existing Account'),
|
||||
fields: [
|
||||
{
|
||||
"label": "Account Number",
|
||||
"fieldname": "account_number",
|
||||
"label" : "Name",
|
||||
"fieldname": "name",
|
||||
"fieldtype": "Data",
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"default": frm.doc.name
|
||||
}
|
||||
],
|
||||
primary_action: function() {
|
||||
var data = d.get_values();
|
||||
if(data.account_number === frm.doc.account_number) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.account.account.merge_account",
|
||||
args: {
|
||||
old: frm.doc.name,
|
||||
new: data.name,
|
||||
is_group: frm.doc.is_group,
|
||||
root_type: frm.doc.root_type,
|
||||
company: frm.doc.company
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
if(r.message) {
|
||||
frappe.set_route("Form", "Account", r.message);
|
||||
}
|
||||
d.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
primary_action_label: __('Merge')
|
||||
});
|
||||
d.show();
|
||||
},
|
||||
|
||||
update_account_number: function(frm) {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Update Account Number / Name'),
|
||||
fields: [
|
||||
{
|
||||
"label": "Account Name",
|
||||
"fieldname": "account_name",
|
||||
"fieldtype": "Data",
|
||||
"reqd": 1,
|
||||
"default": frm.doc.account_name
|
||||
},
|
||||
{
|
||||
"label": "Account Number",
|
||||
"fieldname": "account_number",
|
||||
"fieldtype": "Data",
|
||||
"default": frm.doc.account_number
|
||||
}
|
||||
],
|
||||
primary_action: function() {
|
||||
var data = d.get_values();
|
||||
if(data.account_number === frm.doc.account_number && data.account_name === frm.doc.account_name) {
|
||||
d.hide();
|
||||
return;
|
||||
}
|
||||
@@ -120,6 +171,7 @@ frappe.ui.form.on('Account', {
|
||||
method: "erpnext.accounts.doctype.account.account.update_account_number",
|
||||
args: {
|
||||
account_number: data.account_number,
|
||||
account_name: data.account_name,
|
||||
name: frm.doc.name
|
||||
},
|
||||
callback: function(r) {
|
||||
@@ -128,6 +180,7 @@ frappe.ui.form.on('Account', {
|
||||
frappe.set_route("Form", "Account", r.message);
|
||||
} else {
|
||||
frm.set_value("account_number", data.account_number);
|
||||
frm.set_value("account_name", data.account_name);
|
||||
}
|
||||
d.hide();
|
||||
}
|
||||
@@ -138,4 +191,4 @@ frappe.ui.form.on('Account', {
|
||||
});
|
||||
d.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"allow_copy": 1,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2013-01-30 12:49:46",
|
||||
"custom": 0,
|
||||
@@ -40,6 +40,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -68,6 +69,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@@ -100,6 +102,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -130,6 +133,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -161,6 +165,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -193,6 +198,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -223,6 +229,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -253,6 +260,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -285,6 +293,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -313,6 +322,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@@ -346,6 +356,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -379,6 +390,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -411,6 +423,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -444,6 +457,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -474,6 +488,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -503,6 +518,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -532,6 +548,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -561,6 +578,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@@ -575,7 +593,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-08-22 17:39:10.711343",
|
||||
"modified": "2018-07-08 09:47:04.287841",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Account",
|
||||
|
||||
@@ -165,53 +165,6 @@ class Account(NestedSet):
|
||||
|
||||
super(Account, self).on_trash(True)
|
||||
|
||||
def before_rename(self, old, new, merge=False):
|
||||
# Add company abbr if not provided
|
||||
from erpnext.setup.doctype.company.company import get_name_with_abbr
|
||||
new_account = get_name_with_abbr(new, self.company)
|
||||
if not merge:
|
||||
new_account = get_name_with_number(new_account, self.account_number)
|
||||
else:
|
||||
# Validate properties before merging
|
||||
if not frappe.db.exists("Account", new):
|
||||
throw(_("Account {0} does not exist").format(new))
|
||||
|
||||
val = list(frappe.db.get_value("Account", new_account,
|
||||
["is_group", "root_type", "company"]))
|
||||
|
||||
if val != [self.is_group, self.root_type, self.company]:
|
||||
throw(_("""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company"""))
|
||||
|
||||
if self.is_group and frappe.db.get_value("Account", new, "parent_account") == old:
|
||||
frappe.db.set_value("Account", new, "parent_account",
|
||||
frappe.db.get_value("Account", old, "parent_account"))
|
||||
|
||||
return new_account
|
||||
|
||||
def after_rename(self, old, new, merge=False):
|
||||
super(Account, self).after_rename(old, new, merge)
|
||||
|
||||
if not merge:
|
||||
new_acc = frappe.db.get_value("Account", new, ["account_name", "account_number"], as_dict=1)
|
||||
|
||||
# exclude company abbr
|
||||
new_parts = new.split(" - ")[:-1]
|
||||
# update account number and remove from parts
|
||||
if new_parts[0][0].isdigit():
|
||||
# if account number is separate by space, split using space
|
||||
if len(new_parts) == 1:
|
||||
new_parts = new.split(" ")
|
||||
if new_acc.account_number != new_parts[0]:
|
||||
self.account_number = new_parts[0]
|
||||
self.db_set("account_number", new_parts[0])
|
||||
new_parts = new_parts[1:]
|
||||
|
||||
# update account name
|
||||
account_name = " - ".join(new_parts)
|
||||
if new_acc.account_name != account_name:
|
||||
self.account_name = account_name
|
||||
self.db_set("account_name", account_name)
|
||||
|
||||
def get_parent_account(doctype, txt, searchfield, start, page_len, filters):
|
||||
return frappe.db.sql("""select name from tabAccount
|
||||
where is_group = 1 and docstatus != 2 and company = %s
|
||||
@@ -252,25 +205,38 @@ def validate_account_number(name, account_number, company):
|
||||
.format(account_number, account_with_same_number))
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_account_number(name, account_number):
|
||||
account = frappe.db.get_value("Account", name, ["account_name", "company"], as_dict=True)
|
||||
def update_account_number(name, account_name, account_number=None):
|
||||
|
||||
account = frappe.db.get_value("Account", name, "company", as_dict=True)
|
||||
if not account: return
|
||||
validate_account_number(name, account_number, account.company)
|
||||
|
||||
frappe.db.set_value("Account", name, "account_number", account_number)
|
||||
|
||||
account_name = account.account_name
|
||||
if account_name[0].isdigit():
|
||||
separator = " - " if " - " in account_name else " "
|
||||
account_name = account_name.split(separator, 1)[1]
|
||||
frappe.db.set_value("Account", name, "account_name", account_name)
|
||||
if account_number:
|
||||
frappe.db.set_value("Account", name, "account_number", account_number.strip())
|
||||
else:
|
||||
frappe.db.set_value("Account", name, "account_number", "")
|
||||
frappe.db.set_value("Account", name, "account_name", account_name.strip())
|
||||
|
||||
new_name = get_account_autoname(account_number, account_name, account.company)
|
||||
if name != new_name:
|
||||
frappe.rename_doc("Account", name, new_name)
|
||||
frappe.rename_doc("Account", name, new_name, ignore_permissions=1)
|
||||
return new_name
|
||||
|
||||
def get_name_with_number(new_account, account_number):
|
||||
if account_number and not new_account[0].isdigit():
|
||||
new_account = account_number + " - " + new_account
|
||||
return new_account
|
||||
@frappe.whitelist()
|
||||
def merge_account(old, new, is_group, root_type, company):
|
||||
# Validate properties before merging
|
||||
if not frappe.db.exists("Account", new):
|
||||
throw(_("Account {0} does not exist").format(new))
|
||||
|
||||
val = list(frappe.db.get_value("Account", new,
|
||||
["is_group", "root_type", "company"]))
|
||||
|
||||
if val != [cint(is_group), root_type, company]:
|
||||
throw(_("""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company"""))
|
||||
|
||||
if is_group and frappe.db.get_value("Account", new, "parent_account") == old:
|
||||
frappe.db.set_value("Account", new, "parent_account",
|
||||
frappe.db.get_value("Account", old, "parent_account"))
|
||||
|
||||
frappe.rename_doc("Account", old, new, merge=1, ignore_permissions=1)
|
||||
|
||||
return new
|
||||
|
||||
@@ -71,7 +71,7 @@ frappe.treeview_settings["Account"] = {
|
||||
|
||||
// financial statements
|
||||
for (let report of ['Trial Balance', 'General Ledger', 'Balance Sheet',
|
||||
'Profit and Loss', 'Cash Flow Statement', 'Accounts Payable', 'Accounts Receivable']) {
|
||||
'Profit and Loss Statement', 'Cash Flow Statement', 'Accounts Payable', 'Accounts Receivable']) {
|
||||
treeview.page.add_inner_button(__(report), function() {
|
||||
frappe.set_route('query-report', report, {company: get_company()});
|
||||
}, __('Financial Statements'));
|
||||
|
||||
@@ -165,7 +165,7 @@ def build_account_tree(tree, parent, all_accounts):
|
||||
tree[child.account_name] = {}
|
||||
|
||||
# assign account_type and root_type
|
||||
if child.account_type:
|
||||
if child.account_number:
|
||||
tree[child.account_name]["account_number"] = child.account_number
|
||||
if child.account_type:
|
||||
tree[child.account_name]["account_type"] = child.account_type
|
||||
@@ -175,4 +175,4 @@ def build_account_tree(tree, parent, all_accounts):
|
||||
tree[child.account_name]["root_type"] = child.root_type
|
||||
|
||||
# call recursively to build a subtree for current account
|
||||
build_account_tree(tree[child.account_name], child, all_accounts)
|
||||
build_account_tree(tree[child.account_name], child, all_accounts)
|
||||
|
||||
@@ -5,6 +5,8 @@ from __future__ import unicode_literals
|
||||
import unittest
|
||||
import frappe
|
||||
from erpnext.stock import get_warehouse_account, get_company_default_inventory_account
|
||||
from erpnext.accounts.doctype.account.account import update_account_number
|
||||
from erpnext.accounts.doctype.account.account import merge_account
|
||||
|
||||
class TestAccount(unittest.TestCase):
|
||||
def test_rename_account(self):
|
||||
@@ -21,21 +23,79 @@ class TestAccount(unittest.TestCase):
|
||||
self.assertEqual(account_number, "1210")
|
||||
self.assertEqual(account_name, "Debtors")
|
||||
|
||||
frappe.rename_doc("Account", "1210 - Debtors - _TC", "1211 - Debtors 1 - _TC")
|
||||
new_account_number = "1211-11-4 - 6 - "
|
||||
new_account_name = "Debtors 1 - Test - "
|
||||
|
||||
new_acc = frappe.db.get_value("Account", "1211 - Debtors 1 - _TC",
|
||||
update_account_number("1210 - Debtors - _TC", new_account_name, new_account_number)
|
||||
|
||||
new_acc = frappe.db.get_value("Account", "1211-11-4 - 6 - - Debtors 1 - Test - - _TC",
|
||||
["account_name", "account_number"], as_dict=1)
|
||||
self.assertEqual(new_acc.account_name, "Debtors 1")
|
||||
self.assertEqual(new_acc.account_number, "1211")
|
||||
|
||||
frappe.rename_doc("Account", "1211 - Debtors 1 - _TC", "Debtors 2")
|
||||
self.assertEqual(new_acc.account_name, "Debtors 1 - Test -")
|
||||
self.assertEqual(new_acc.account_number, "1211-11-4 - 6 -")
|
||||
|
||||
new_acc = frappe.db.get_value("Account", "1211 - Debtors 2 - _TC",
|
||||
["account_name", "account_number"], as_dict=1)
|
||||
self.assertEqual(new_acc.account_name, "Debtors 2")
|
||||
self.assertEqual(new_acc.account_number, "1211")
|
||||
frappe.delete_doc("Account", "1211-11-4 - 6 - Debtors 1 - Test - - _TC")
|
||||
|
||||
frappe.delete_doc("Account", "1211 - Debtors 2 - _TC")
|
||||
def test_merge_account(self):
|
||||
if not frappe.db.exists("Account", "Current Assets - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Current Assets"
|
||||
acc.is_group = 1
|
||||
acc.parent_account = "Application of Funds (Assets) - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Securities and Deposits - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Securities and Deposits"
|
||||
acc.parent_account = "Current Assets - _TC"
|
||||
acc.is_group = 1
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Earnest Money - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Earnest Money"
|
||||
acc.parent_account = "Securities and Deposits - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Cash In Hand - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Cash In Hand"
|
||||
acc.is_group = 1
|
||||
acc.parent_account = "Current Assets - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Accumulated Depreciation - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Accumulated Depreciation"
|
||||
acc.parent_account = "Fixed Assets - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
|
||||
doc = frappe.get_doc("Account", "Securities and Deposits - _TC")
|
||||
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
|
||||
|
||||
self.assertEqual(parent, "Securities and Deposits - _TC")
|
||||
|
||||
merge_account("Securities and Deposits - _TC", "Cash In Hand - _TC", doc.is_group, doc.root_type, doc.company)
|
||||
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
|
||||
|
||||
# Parent account of the child account changes after merging
|
||||
self.assertEqual(parent, "Cash In Hand - _TC")
|
||||
|
||||
# Old account doesn't exist after merging
|
||||
self.assertFalse(frappe.db.exists("Account", "Securities and Deposits - _TC"))
|
||||
|
||||
doc = frappe.get_doc("Account", "Current Assets - _TC")
|
||||
|
||||
# Raise error as is_group property doesn't match
|
||||
self.assertRaises(frappe.ValidationError, merge_account, "Current Assets - _TC",\
|
||||
"Accumulated Depreciation - _TC", doc.is_group, doc.root_type, doc.company)
|
||||
|
||||
doc = frappe.get_doc("Account", "Capital Stock - _TC")
|
||||
|
||||
# Raise error as root_type property doesn't match
|
||||
self.assertRaises(frappe.ValidationError, merge_account, "Capital Stock - _TC",\
|
||||
"Softwares - _TC", doc.is_group, doc.root_type, doc.company)
|
||||
|
||||
def _make_test_records(verbose):
|
||||
from frappe.test_runner import make_test_objects
|
||||
|
||||
@@ -27,13 +27,21 @@ class Budget(Document):
|
||||
def validate_duplicate(self):
|
||||
budget_against_field = frappe.scrub(self.budget_against)
|
||||
budget_against = self.get(budget_against_field)
|
||||
existing_budget = frappe.db.get_value("Budget", {budget_against_field: budget_against,
|
||||
"fiscal_year": self.fiscal_year, "company": self.company,
|
||||
"name": ["!=", self.name], "docstatus": ["!=", 2]})
|
||||
if existing_budget:
|
||||
frappe.throw(_("Another Budget record '{0}' already exists against {1} '{2}' for fiscal year {3}")
|
||||
.format(existing_budget, self.budget_against, budget_against, self.fiscal_year), DuplicateBudgetError)
|
||||
|
||||
|
||||
accounts = [d.account for d in self.accounts] or []
|
||||
existing_budget = frappe.db.sql("""
|
||||
select
|
||||
b.name, ba.account from `tabBudget` b, `tabBudget Account` ba
|
||||
where
|
||||
ba.parent = b.name and b.docstatus < 2 and b.company = %s and %s=%s and
|
||||
b.fiscal_year=%s and b.name != %sand ba.account in (%s) """
|
||||
% ('%s', budget_against_field, '%s', '%s', '%s', ','.join(['%s'] * len(accounts))),
|
||||
(self.company, budget_against, self.fiscal_year, self.name) + tuple(accounts), as_dict=1)
|
||||
|
||||
for d in existing_budget:
|
||||
frappe.throw(_("Another Budget record '{0}' already exists against {1} '{2}' and account '{3}' for fiscal year {4}")
|
||||
.format(d.name, self.budget_against, budget_against, d.account, self.fiscal_year), DuplicateBudgetError)
|
||||
|
||||
def validate_accounts(self):
|
||||
account_list = []
|
||||
for d in self.get('accounts'):
|
||||
|
||||
@@ -27,22 +27,32 @@ def create_or_update_cheque_print_format(template_name):
|
||||
doc = frappe.get_doc("Cheque Print Template", template_name)
|
||||
|
||||
cheque_print.html = """
|
||||
<style>
|
||||
.print-format {
|
||||
padding: 0px;
|
||||
}
|
||||
@media screen {
|
||||
.print-format {
|
||||
padding: 0in;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div style="position: relative; top:%(starting_position_from_top_edge)scm">
|
||||
<div style="width:%(cheque_width)scm;height:%(cheque_height)scm;">
|
||||
<span style="top: {{ %(acc_pay_dist_from_top_edge)s }}cm; left: {{ %(acc_pay_dist_from_left_edge)s }}cm;
|
||||
border-bottom: solid 1px;border-top:solid 1px; position: absolute;">
|
||||
<span style="top:%(acc_pay_dist_from_top_edge)scm; left:%(acc_pay_dist_from_left_edge)scm;
|
||||
border-bottom: solid 1px;border-top:solid 1px; width:2cm;text-align: center; position: absolute;">
|
||||
%(message_to_show)s
|
||||
</span>
|
||||
<span style="top:%(date_dist_from_top_edge)s cm; left:%(date_dist_from_left_edge)scm;
|
||||
<span style="top:%(date_dist_from_top_edge)scm; left:%(date_dist_from_left_edge)scm;
|
||||
position: absolute;">
|
||||
{{ frappe.utils.formatdate(doc.reference_date) or '' }}
|
||||
</span>
|
||||
<span style="top:%(acc_no_dist_from_top_edge)scm;left:%(acc_no_dist_from_left_edge)scm;
|
||||
position: absolute;">
|
||||
position: absolute; min-width: 6cm;">
|
||||
{{ doc.account_no or '' }}
|
||||
</span>
|
||||
<span style="top:%(payer_name_from_top_edge)scm;left: %(payer_name_from_left_edge)scm;
|
||||
position: absolute;">
|
||||
position: absolute; min-width: 6cm;">
|
||||
{{doc.party_name}}
|
||||
</span>
|
||||
<span style="top:%(amt_in_words_from_top_edge)scm; left:%(amt_in_words_from_left_edge)scm;
|
||||
@@ -51,11 +61,11 @@ def create_or_update_cheque_print_format(template_name):
|
||||
{{frappe.utils.money_in_words(doc.base_paid_amount or doc.base_received_amount)}}
|
||||
</span>
|
||||
<span style="top:%(amt_in_figures_from_top_edge)scm;left: %(amt_in_figures_from_left_edge)scm;
|
||||
position: absolute;">
|
||||
position: absolute; min-width: 4cm;">
|
||||
{{doc.get_formatted("base_paid_amount") or doc.get_formatted("base_received_amount")}}
|
||||
</span>
|
||||
<span style="top:%(signatory_from_top_edge)scm;left: %(signatory_from_left_edge)scm;
|
||||
position: absolute;">
|
||||
position: absolute; min-width: 6cm;">
|
||||
{{doc.company}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -702,7 +702,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
@@ -718,7 +718,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-20 12:40:09.611951",
|
||||
"modified": "2018-08-10 16:16:53.019380",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "GL Entry",
|
||||
@@ -794,4 +794,4 @@
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
}
|
||||
@@ -381,7 +381,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -1443,7 +1443,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-08-31 11:21:09.442695",
|
||||
"modified": "2018-08-10 16:35:31.361030",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Journal Entry",
|
||||
|
||||
@@ -82,7 +82,7 @@ class JournalEntry(AccountsController):
|
||||
d.reference_type = ''
|
||||
d.reference_name = ''
|
||||
d.db_update()
|
||||
|
||||
|
||||
def unlink_asset_reference(self):
|
||||
for d in self.get("accounts"):
|
||||
if d.reference_type=="Asset" and d.reference_name:
|
||||
@@ -125,7 +125,7 @@ class JournalEntry(AccountsController):
|
||||
if (d.party_type == 'Customer' and flt(d.credit) > 0) or \
|
||||
(d.party_type == 'Supplier' and flt(d.debit) > 0):
|
||||
if d.is_advance=="No":
|
||||
msgprint(_("Row {0}: Please check 'Is Advance' against Account {1} if this is an advance entry.").format(d.idx, d.account))
|
||||
msgprint(_("Row {0}: Please check 'Is Advance' against Account {1} if this is an advance entry.").format(d.idx, d.account), alert=1)
|
||||
elif d.reference_type in ("Sales Order", "Purchase Order") and d.is_advance != "Yes":
|
||||
frappe.throw(_("Row {0}: Payment against Sales/Purchase Order should always be marked as advance").format(d.idx))
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -661,7 +661,7 @@
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -795,7 +795,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-07 19:54:19.851534",
|
||||
"modified": "2018-08-10 16:35:42.833549",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Journal Entry Account",
|
||||
|
||||
@@ -138,7 +138,8 @@ class OpeningInvoiceCreationTool(Document):
|
||||
income_expense_account_field = "expense_account"
|
||||
|
||||
item = get_item_dict()
|
||||
return frappe._dict({
|
||||
|
||||
args = frappe._dict({
|
||||
"items": [item],
|
||||
"is_opening": "Yes",
|
||||
"set_posting_time": 1,
|
||||
@@ -150,6 +151,11 @@ class OpeningInvoiceCreationTool(Document):
|
||||
"currency": frappe.db.get_value("Company", self.company, "default_currency")
|
||||
})
|
||||
|
||||
if self.invoice_type == "Sales":
|
||||
args["is_pos"] = 0
|
||||
|
||||
return args
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_temporary_opening_account(company=None):
|
||||
if not company:
|
||||
|
||||
@@ -588,6 +588,10 @@ frappe.ui.form.on('Payment Entry', {
|
||||
allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
|
||||
var total_positive_outstanding_including_order = 0;
|
||||
var total_negative_outstanding = 0;
|
||||
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
|
||||
function(d) { return flt(d.amount) }));
|
||||
|
||||
paid_amount -= total_deductions;
|
||||
|
||||
$.each(frm.doc.references || [], function(i, row) {
|
||||
if(flt(row.outstanding_amount) > 0)
|
||||
@@ -815,23 +819,30 @@ frappe.ui.form.on('Payment Entry Reference', {
|
||||
|
||||
reference_name: function(frm, cdt, cdn) {
|
||||
var row = locals[cdt][cdn];
|
||||
return frappe.call({
|
||||
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_reference_details",
|
||||
args: {
|
||||
reference_doctype: row.reference_doctype,
|
||||
reference_name: row.reference_name,
|
||||
party_account_currency: frm.doc.payment_type=="Receive" ?
|
||||
frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
if(r.message) {
|
||||
$.each(r.message, function(field, value) {
|
||||
frappe.model.set_value(cdt, cdn, field, value);
|
||||
})
|
||||
frm.refresh_fields();
|
||||
if (row.reference_name && row.reference_doctype) {
|
||||
return frappe.call({
|
||||
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_reference_details",
|
||||
args: {
|
||||
reference_doctype: row.reference_doctype,
|
||||
reference_name: row.reference_name,
|
||||
party_account_currency: frm.doc.payment_type=="Receive" ?
|
||||
frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
if(r.message) {
|
||||
$.each(r.message, function(field, value) {
|
||||
frappe.model.set_value(cdt, cdn, field, value);
|
||||
})
|
||||
|
||||
let allocated_amount = frm.doc.unallocated_amount > row.outstanding_amount ?
|
||||
row.outstanding_amount : frm.doc.unallocated_amount;
|
||||
|
||||
frappe.model.set_value(cdt, cdn, 'allocated_amount', allocated_amount);
|
||||
frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
allocated_amount: function(frm) {
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -72,7 +71,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 1,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -104,7 +102,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -134,7 +131,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -166,7 +162,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -198,7 +193,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -230,7 +224,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -262,7 +255,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -294,9 +286,8 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -329,7 +320,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -359,7 +349,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -392,7 +381,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -423,7 +411,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -455,7 +442,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -488,7 +474,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -521,7 +506,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -554,7 +538,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -584,7 +567,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -617,7 +599,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -650,7 +631,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -683,7 +663,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -716,7 +695,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -749,7 +727,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -781,7 +758,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -814,7 +790,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -844,7 +819,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -877,7 +851,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -909,7 +882,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -942,7 +914,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -975,7 +946,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1008,7 +978,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1041,7 +1010,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1073,7 +1041,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1105,7 +1072,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1138,7 +1104,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1169,7 +1134,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1199,7 +1163,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1231,7 +1194,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1264,7 +1226,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1296,7 +1257,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1329,7 +1289,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1361,7 +1320,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1392,7 +1350,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1424,7 +1381,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1454,7 +1410,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1484,9 +1439,8 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1518,7 +1472,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1551,7 +1504,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1584,7 +1536,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1604,7 +1555,7 @@
|
||||
"in_standard_filter": 0,
|
||||
"label": "Remarks",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@@ -1615,7 +1566,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1645,7 +1595,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1677,7 +1626,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1709,7 +1657,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1740,7 +1687,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1772,7 +1718,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1803,7 +1748,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1834,7 +1778,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@@ -1848,7 +1791,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-19 16:58:23.899015",
|
||||
"modified": "2018-08-10 16:34:46.771275",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry",
|
||||
|
||||
@@ -337,14 +337,15 @@ class PaymentEntry(AccountsController):
|
||||
total_negative_outstanding = sum([abs(flt(d.outstanding_amount))
|
||||
for d in self.get("references") if flt(d.outstanding_amount) < 0])
|
||||
|
||||
party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
|
||||
paid_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
|
||||
additional_charges = sum([flt(d.amount) for d in self.deductions])
|
||||
|
||||
if not total_negative_outstanding:
|
||||
frappe.throw(_("Cannot {0} {1} {2} without any negative outstanding invoice")
|
||||
.format(self.payment_type, ("to" if self.party_type=="Customer" else "from"),
|
||||
self.party_type), InvalidPaymentEntry)
|
||||
|
||||
elif party_amount > total_negative_outstanding:
|
||||
elif paid_amount - additional_charges > total_negative_outstanding:
|
||||
frappe.throw(_("Paid Amount cannot be greater than total negative outstanding amount {0}")
|
||||
.format(total_negative_outstanding), InvalidPaymentEntry)
|
||||
|
||||
@@ -724,8 +725,11 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
||||
exchange_rate = ref_doc.get("conversion_rate") or \
|
||||
get_exchange_rate(party_account_currency, company_currency, ref_doc.posting_date)
|
||||
|
||||
if reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim"):
|
||||
if reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||
outstanding_amount = ref_doc.get("outstanding_amount")
|
||||
elif reference_doctype == "Expense Claim":
|
||||
outstanding_amount = flt(ref_doc.get("total_sanctioned_amount")) \
|
||||
- flt(ref_doc.get("total_amount+reimbursed")) - flt(ref_doc.get("total_advance_amount"))
|
||||
elif reference_doctype == "Employee Advance":
|
||||
outstanding_amount = ref_doc.advance_amount - flt(ref_doc.paid_amount)
|
||||
else:
|
||||
|
||||
@@ -111,8 +111,8 @@ def apply_pricing_rule(args):
|
||||
|
||||
item_list = args.get("items")
|
||||
args.pop("items")
|
||||
|
||||
set_serial_nos_based_on_fifo = frappe.db.get_single_value("Stock Settings",
|
||||
|
||||
set_serial_nos_based_on_fifo = frappe.db.get_single_value("Stock Settings",
|
||||
"automatically_set_serial_nos_based_on_fifo")
|
||||
|
||||
for item in item_list:
|
||||
@@ -122,7 +122,7 @@ def apply_pricing_rule(args):
|
||||
if set_serial_nos_based_on_fifo and not args.get('is_return'):
|
||||
out.append(get_serial_no_for_item(args_copy))
|
||||
return out
|
||||
|
||||
|
||||
def get_serial_no_for_item(args):
|
||||
from erpnext.stock.get_item_details import get_serial_no
|
||||
|
||||
@@ -143,7 +143,7 @@ def get_pricing_rule_for_item(args):
|
||||
"name": args.name,
|
||||
"pricing_rule": None
|
||||
})
|
||||
|
||||
|
||||
if args.ignore_pricing_rule or not args.item_code:
|
||||
if frappe.db.exists(args.doctype, args.name) and args.get("pricing_rule"):
|
||||
item_details = remove_pricing_rule_for_item(args.get("pricing_rule"), item_details)
|
||||
@@ -180,7 +180,7 @@ def get_pricing_rule_for_item(args):
|
||||
item_details.margin_rate_or_amount = pricing_rule.margin_rate_or_amount
|
||||
if pricing_rule.price_or_discount == "Price":
|
||||
item_details.update({
|
||||
"price_list_rate": (pricing_rule.price/flt(args.conversion_rate)) * args.conversion_factor or 1.0 \
|
||||
"price_list_rate": (pricing_rule.price/flt(args.conversion_rate)) * (args.conversion_factor or 1.0) \
|
||||
if args.conversion_rate else 0.0,
|
||||
"discount_percentage": 0.0
|
||||
})
|
||||
@@ -192,7 +192,7 @@ def get_pricing_rule_for_item(args):
|
||||
return item_details
|
||||
|
||||
def remove_pricing_rule_for_item(pricing_rule, item_details):
|
||||
pricing_rule = frappe.db.get_value('Pricing Rule', pricing_rule,
|
||||
pricing_rule = frappe.db.get_value('Pricing Rule', pricing_rule,
|
||||
['price_or_discount', 'margin_type'], as_dict=1)
|
||||
if pricing_rule and pricing_rule.price_or_discount == 'Discount Percentage':
|
||||
item_details.discount_percentage = 0.0
|
||||
@@ -209,14 +209,14 @@ def remove_pricing_rule_for_item(pricing_rule, item_details):
|
||||
def remove_pricing_rules(item_list):
|
||||
if isinstance(item_list, basestring):
|
||||
item_list = json.loads(item_list)
|
||||
|
||||
out = []
|
||||
|
||||
out = []
|
||||
for item in item_list:
|
||||
item = frappe._dict(item)
|
||||
out.append(remove_pricing_rule_for_item(item.get("pricing_rule"), item))
|
||||
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def get_pricing_rules(args):
|
||||
def _get_tree_conditions(parenttype, allow_blank=True):
|
||||
field = frappe.scrub(parenttype)
|
||||
|
||||
@@ -21,8 +21,6 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
if(!this.frm.doc.supplier && this.frm.doc.credit_to) {
|
||||
this.frm.set_df_property("credit_to", "print_hide", 0);
|
||||
}
|
||||
} else {
|
||||
this.frm.set_value("disable_rounded_total", cint(frappe.sys_defaults.disable_rounded_total));
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1239,7 +1239,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_bulk_edit": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -3410,6 +3410,65 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "group_same_items",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Group same items",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_112",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "select_print_heading",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -3914,7 +3973,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-12-20 17:49:51.230092",
|
||||
"modified": "2018-07-06 02:38:40.310899",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
|
||||
@@ -363,7 +363,10 @@ class PurchaseInvoice(BuyingController):
|
||||
return gl_entries
|
||||
|
||||
def make_supplier_gl_entry(self, gl_entries):
|
||||
grand_total = self.rounded_total or self.grand_total
|
||||
# Checked both rounding_adjustment and rounded_total
|
||||
# because rounded_total had value even before introcution of posting GLE based on rounded total
|
||||
grand_total = self.rounded_total if (self.rounding_adjustment and self.rounded_total) else self.grand_total
|
||||
|
||||
if grand_total:
|
||||
# Didnot use base_grand_total to book rounding loss gle
|
||||
grand_total_in_company_currency = flt(grand_total * self.conversion_rate,
|
||||
@@ -388,16 +391,20 @@ class PurchaseInvoice(BuyingController):
|
||||
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
|
||||
warehouse_account = get_warehouse_account_map()
|
||||
|
||||
voucher_wise_stock_value = {}
|
||||
if self.update_stock:
|
||||
for d in frappe.get_all('Stock Ledger Entry',
|
||||
fields = ["voucher_detail_no", "stock_value_difference"], filters={'voucher_no': self.name}):
|
||||
voucher_wise_stock_value.setdefault(d.voucher_detail_no, d.stock_value_difference)
|
||||
|
||||
for item in self.get("items"):
|
||||
if flt(item.base_net_amount):
|
||||
account_currency = get_account_currency(item.expense_account)
|
||||
|
||||
if self.update_stock and self.auto_accounting_for_stock and item.item_code in stock_items:
|
||||
val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
|
||||
|
||||
# warehouse account
|
||||
warehouse_debit_amount = flt(flt(item.valuation_rate, val_rate_db_precision)
|
||||
* flt(item.qty) * flt(item.conversion_factor), item.precision("base_net_amount"))
|
||||
warehouse_debit_amount = self.make_stock_adjustment_entry(gl_entries,
|
||||
item, voucher_wise_stock_value, account_currency)
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
@@ -469,6 +476,36 @@ class PurchaseInvoice(BuyingController):
|
||||
self.negative_expense_to_be_booked += flt(item.item_tax_amount, \
|
||||
item.precision("item_tax_amount"))
|
||||
|
||||
def make_stock_adjustment_entry(self, gl_entries, item, voucher_wise_stock_value, account_currency):
|
||||
net_amt_precision = item.precision("base_net_amount")
|
||||
val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
|
||||
|
||||
warehouse_debit_amount = flt(flt(item.valuation_rate, val_rate_db_precision)
|
||||
* flt(item.qty) * flt(item.conversion_factor), net_amt_precision)
|
||||
|
||||
# Stock ledger value is not matching with the warehouse amount
|
||||
if (self.update_stock and voucher_wise_stock_value.get(item.name) and
|
||||
warehouse_debit_amount != flt(voucher_wise_stock_value.get(item.name), net_amt_precision)):
|
||||
|
||||
cost_of_goods_sold_account = self.get_company_default("default_expense_account")
|
||||
stock_amount = flt(voucher_wise_stock_value.get(item.name), net_amt_precision)
|
||||
stock_adjustment_amt = warehouse_debit_amount - stock_amount
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": cost_of_goods_sold_account,
|
||||
"against": item.expense_account,
|
||||
"debit": stock_adjustment_amt,
|
||||
"remarks": self.get("remarks") or _("Stock Adjustment"),
|
||||
"cost_center": item.cost_center,
|
||||
"project": item.project
|
||||
}, account_currency)
|
||||
)
|
||||
|
||||
warehouse_debit_amount = stock_amount
|
||||
|
||||
return warehouse_debit_amount
|
||||
|
||||
def make_tax_gl_entries(self, gl_entries):
|
||||
# tax table gl entries
|
||||
valuation_tax = {}
|
||||
|
||||
@@ -585,6 +585,38 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "discount_percentage",
|
||||
"fieldname": "discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Discount Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2156,7 +2188,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-30 14:21:00.962126",
|
||||
"modified": "2018-08-06 05:17:38.205356",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice Item",
|
||||
|
||||
@@ -506,6 +506,7 @@ def save_invoice(doc, name, name_list):
|
||||
frappe.db.commit()
|
||||
name_list.append(name)
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
|
||||
return name_list
|
||||
|
||||
@@ -319,6 +319,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
},
|
||||
|
||||
pos_profile: function() {
|
||||
this.frm.doc.taxes = []
|
||||
this.set_pos_data();
|
||||
},
|
||||
|
||||
|
||||
@@ -639,6 +639,66 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_21",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.is_return && doc.return_against",
|
||||
"fieldname": "update_billed_amount_in_sales_order",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Update Billed Amount in Sales Order",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1459,7 +1519,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_bulk_edit": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -3742,12 +3802,12 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "language",
|
||||
"fieldtype": "Data",
|
||||
"fieldname": "group_same_items",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@@ -3755,14 +3815,14 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Print Language",
|
||||
"label": "Group same items",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
@@ -3831,6 +3891,36 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "language",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Print Language",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -4683,7 +4773,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2018-03-16 15:19:54.711885",
|
||||
"modified": "2018-07-17 13:46:52.449142",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
@@ -4774,7 +4864,7 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 1,
|
||||
"search_fields": "posting_date, due_date, customer, base_grand_total, outstanding_amount",
|
||||
"search_fields": "posting_date,due_date,customer,base_grand_total,outstanding_amount",
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
|
||||
@@ -116,7 +116,7 @@ class SalesInvoice(SellingController):
|
||||
|
||||
self.check_prev_docstatus()
|
||||
|
||||
if self.is_return:
|
||||
if self.is_return and not self.update_billed_amount_in_sales_order:
|
||||
# NOTE status updating bypassed for is_return
|
||||
self.status_updater = []
|
||||
|
||||
@@ -161,7 +161,7 @@ class SalesInvoice(SellingController):
|
||||
if frappe.db.get_single_value('Accounts Settings', 'unlink_payment_on_cancellation_of_invoice'):
|
||||
unlink_ref_doc_from_payment_entries(self)
|
||||
|
||||
if self.is_return:
|
||||
if self.is_return and not self.update_billed_amount_in_sales_order:
|
||||
# NOTE status updating bypassed for is_return
|
||||
self.status_updater = []
|
||||
|
||||
@@ -318,6 +318,7 @@ class SalesInvoice(SellingController):
|
||||
if not for_validate and not self.customer:
|
||||
self.customer = pos.customer
|
||||
|
||||
self.ignore_pricing_rule = pos.ignore_pricing_rule
|
||||
if pos.get('account_for_change_amount'):
|
||||
self.account_for_change_amount = pos.get('account_for_change_amount')
|
||||
|
||||
@@ -334,7 +335,7 @@ class SalesInvoice(SellingController):
|
||||
for item in self.get("items"):
|
||||
if item.get('item_code'):
|
||||
for fname, val in get_pos_profile_item_details(pos,
|
||||
frappe._dict(item.as_dict()), pos).items():
|
||||
frappe._dict(item.as_dict()), pos, True).items():
|
||||
|
||||
if (not for_validate) or (for_validate and not item.get(fname)):
|
||||
item.set(fname, val)
|
||||
@@ -640,7 +641,9 @@ class SalesInvoice(SellingController):
|
||||
return gl_entries
|
||||
|
||||
def make_customer_gl_entry(self, gl_entries):
|
||||
grand_total = self.rounded_total or self.grand_total
|
||||
# Checked both rounding_adjustment and rounded_total
|
||||
# because rounded_total had value even before introcution of posting GLE based on rounded total
|
||||
grand_total = self.rounded_total if (self.rounding_adjustment and self.rounded_total) else self.grand_total
|
||||
if grand_total:
|
||||
# Didnot use base_grand_total to book rounding loss gle
|
||||
grand_total_in_company_currency = flt(grand_total * self.conversion_rate,
|
||||
@@ -668,9 +671,11 @@ class SalesInvoice(SellingController):
|
||||
self.get_gl_dict({
|
||||
"account": tax.account_head,
|
||||
"against": self.customer,
|
||||
"credit": flt(tax.base_tax_amount_after_discount_amount),
|
||||
"credit_in_account_currency": flt(tax.base_tax_amount_after_discount_amount) \
|
||||
if account_currency==self.company_currency else flt(tax.tax_amount_after_discount_amount),
|
||||
"credit": flt(tax.base_tax_amount_after_discount_amount,
|
||||
tax.precision("tax_amount_after_discount_amount")),
|
||||
"credit_in_account_currency": (flt(tax.base_tax_amount_after_discount_amount,
|
||||
tax.precision("base_tax_amount_after_discount_amount")) if account_currency==self.company_currency else
|
||||
flt(tax.tax_amount_after_discount_amount, tax.precision("tax_amount_after_discount_amount"))),
|
||||
"cost_center": tax.cost_center
|
||||
}, account_currency)
|
||||
)
|
||||
@@ -678,7 +683,7 @@ class SalesInvoice(SellingController):
|
||||
def make_item_gl_entries(self, gl_entries):
|
||||
# income account gl entries
|
||||
for item in self.get("items"):
|
||||
if flt(item.base_net_amount):
|
||||
if flt(item.base_net_amount, item.precision("base_net_amount")):
|
||||
if item.is_fixed_asset:
|
||||
asset = frappe.get_doc("Asset", item.asset)
|
||||
|
||||
@@ -695,9 +700,10 @@ class SalesInvoice(SellingController):
|
||||
self.get_gl_dict({
|
||||
"account": item.income_account,
|
||||
"against": self.customer,
|
||||
"credit": item.base_net_amount,
|
||||
"credit_in_account_currency": item.base_net_amount \
|
||||
if account_currency==self.company_currency else item.net_amount,
|
||||
"credit": flt(item.base_net_amount, item.precision("base_net_amount")),
|
||||
"credit_in_account_currency": (flt(item.base_net_amount, item.precision("base_net_amount"))
|
||||
if account_currency==self.company_currency
|
||||
else flt(item.net_amount, item.precision("net_amount"))),
|
||||
"cost_center": item.cost_center
|
||||
}, account_currency)
|
||||
)
|
||||
@@ -768,7 +774,7 @@ class SalesInvoice(SellingController):
|
||||
|
||||
def make_write_off_gl_entry(self, gl_entries):
|
||||
# write off entries, applicable if only pos
|
||||
if self.write_off_account and self.write_off_amount:
|
||||
if self.write_off_account and flt(self.write_off_amount, self.precision("write_off_amount")):
|
||||
write_off_account_currency = get_account_currency(self.write_off_account)
|
||||
default_cost_center = frappe.db.get_value('Company', self.company, 'cost_center')
|
||||
|
||||
@@ -778,9 +784,10 @@ class SalesInvoice(SellingController):
|
||||
"party_type": "Customer",
|
||||
"party": self.customer,
|
||||
"against": self.write_off_account,
|
||||
"credit": self.base_write_off_amount,
|
||||
"credit_in_account_currency": self.base_write_off_amount \
|
||||
if self.party_account_currency==self.company_currency else self.write_off_amount,
|
||||
"credit": flt(self.base_write_off_amount, self.precision("base_write_off_amount")),
|
||||
"credit_in_account_currency": (flt(self.base_write_off_amount,
|
||||
self.precision("base_write_off_amount")) if self.party_account_currency==self.company_currency
|
||||
else flt(self.write_off_amount, self.precision("write_off_amount"))),
|
||||
"against_voucher": self.return_against if cint(self.is_return) else self.name,
|
||||
"against_voucher_type": self.doctype
|
||||
}, self.party_account_currency)
|
||||
@@ -789,15 +796,16 @@ class SalesInvoice(SellingController):
|
||||
self.get_gl_dict({
|
||||
"account": self.write_off_account,
|
||||
"against": self.customer,
|
||||
"debit": self.base_write_off_amount,
|
||||
"debit_in_account_currency": self.base_write_off_amount \
|
||||
if write_off_account_currency==self.company_currency else self.write_off_amount,
|
||||
"debit": flt(self.base_write_off_amount, self.precision("base_write_off_amount")),
|
||||
"debit_in_account_currency": (flt(self.base_write_off_amount,
|
||||
self.precision("base_write_off_amount")) if write_off_account_currency==self.company_currency
|
||||
else flt(self.write_off_amount, self.precision("write_off_amount"))),
|
||||
"cost_center": self.write_off_cost_center or default_cost_center
|
||||
}, write_off_account_currency)
|
||||
)
|
||||
|
||||
def make_gle_for_rounding_adjustment(self, gl_entries):
|
||||
if self.rounding_adjustment:
|
||||
if flt(self.rounding_adjustment, self.precision("rounding_adjustment")):
|
||||
round_off_account, round_off_cost_center = \
|
||||
get_round_off_account_and_cost_center(self.company)
|
||||
|
||||
@@ -805,8 +813,10 @@ class SalesInvoice(SellingController):
|
||||
self.get_gl_dict({
|
||||
"account": round_off_account,
|
||||
"against": self.customer,
|
||||
"credit_in_account_currency": self.rounding_adjustment,
|
||||
"credit": self.base_rounding_adjustment,
|
||||
"credit_in_account_currency": flt(self.rounding_adjustment,
|
||||
self.precision("rounding_adjustment")),
|
||||
"credit": flt(self.base_rounding_adjustment,
|
||||
self.precision("base_rounding_adjustment")),
|
||||
"cost_center": round_off_cost_center,
|
||||
}
|
||||
))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,18 +39,20 @@ frappe.ui.form.on("Tax Rule", "customer", function(frm) {
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Tax Rule", "supplier", function(frm) {
|
||||
frappe.call({
|
||||
method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
|
||||
args: {
|
||||
"party": frm.doc.supplier,
|
||||
"party_type": "supplier"
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
$.each(r.message, function(k, v) {
|
||||
frm.set_value(k, v);
|
||||
});
|
||||
if(frm.doc.supplier) {
|
||||
frappe.call({
|
||||
method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
|
||||
args: {
|
||||
"party": frm.doc.supplier,
|
||||
"party_type": "supplier"
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
$.each(r.message, function(k, v) {
|
||||
frm.set_value(k, v);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -20,8 +20,8 @@ from erpnext import get_default_currency, get_company_currency
|
||||
class DuplicatePartyAccountError(frappe.ValidationError): pass
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_party_details(party=None, account=None, party_type="Customer", company=None,
|
||||
posting_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False):
|
||||
def get_party_details(party=None, account=None, party_type="Customer", company=None, posting_date=None,
|
||||
price_list=None, currency=None, doctype=None, ignore_permissions=False, fetch_payment_terms_template=True):
|
||||
|
||||
if not party:
|
||||
return {}
|
||||
@@ -30,10 +30,10 @@ def get_party_details(party=None, account=None, party_type="Customer", company=N
|
||||
frappe.throw(_("{0}: {1} does not exists").format(party_type, party))
|
||||
|
||||
return _get_party_details(party, account, party_type,
|
||||
company, posting_date, price_list, currency, doctype, ignore_permissions)
|
||||
company, posting_date, price_list, currency, doctype, ignore_permissions, fetch_payment_terms_template)
|
||||
|
||||
def _get_party_details(party=None, account=None, party_type="Customer", company=None,
|
||||
posting_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False):
|
||||
def _get_party_details(party=None, account=None, party_type="Customer", company=None, posting_date=None,
|
||||
price_list=None, currency=None, doctype=None, ignore_permissions=False, fetch_payment_terms_template=True):
|
||||
|
||||
out = frappe._dict(set_account_and_due_date(party, account, party_type, company, posting_date, doctype))
|
||||
|
||||
@@ -50,7 +50,9 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
|
||||
set_other_values(out, party, party_type)
|
||||
set_price_list(out, party, party_type, price_list)
|
||||
out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group, out.supplier_type)
|
||||
out["payment_terms_template"] = get_pyt_term_template(party.name, party_type, company)
|
||||
|
||||
if fetch_payment_terms_template:
|
||||
out["payment_terms_template"] = get_pyt_term_template(party.name, party_type, company)
|
||||
|
||||
if not out.get("currency"):
|
||||
out["currency"] = currency
|
||||
@@ -272,6 +274,7 @@ def get_due_date(posting_date, party_type, party, company=None):
|
||||
if posting_date and party:
|
||||
due_date = posting_date
|
||||
template_name = get_pyt_term_template(party, party_type, company)
|
||||
|
||||
if template_name:
|
||||
due_date = get_due_date_from_template(template_name, posting_date).strftime("%Y-%m-%d")
|
||||
else:
|
||||
@@ -304,11 +307,13 @@ def get_due_date_from_template(template_name, posting_date):
|
||||
|
||||
return due_date
|
||||
|
||||
def validate_due_date(posting_date, due_date, party_type, party, company=None):
|
||||
def validate_due_date(posting_date, due_date, party_type, party, company=None, template_name=None):
|
||||
if getdate(due_date) < getdate(posting_date):
|
||||
frappe.throw(_("Due Date cannot be before Posting Date"))
|
||||
else:
|
||||
default_due_date = get_due_date(posting_date, party_type, party, company)
|
||||
if not template_name: return
|
||||
|
||||
default_due_date = get_due_date_from_template(template_name, posting_date).strftime("%Y-%m-%d")
|
||||
if not default_due_date:
|
||||
return
|
||||
|
||||
@@ -404,10 +409,21 @@ def get_timeline_data(doctype, name):
|
||||
from frappe.desk.form.load import get_communication_data
|
||||
|
||||
out = {}
|
||||
fields = 'date(creation), count(name)'
|
||||
after = add_years(None, -1).strftime('%Y-%m-%d')
|
||||
group_by='group by date(creation)'
|
||||
|
||||
data = get_communication_data(doctype, name,
|
||||
fields = 'date(creation), count(name)',
|
||||
after = add_years(None, -1).strftime('%Y-%m-%d'),
|
||||
group_by='group by date(creation)', as_dict=False)
|
||||
fields=fields, after=after, group_by=group_by, as_dict=False)
|
||||
|
||||
# fetch and append data from Activity Log
|
||||
data += frappe.db.sql("""select {fields}
|
||||
from `tabActivity Log`
|
||||
where reference_doctype="{doctype}" and reference_name="{name}"
|
||||
and status!='Success' and creation > {after}
|
||||
{group_by} order by creation desc
|
||||
""".format(doctype=frappe.db.escape(doctype), name=frappe.db.escape(name), fields=fields,
|
||||
group_by=group_by, after=after), as_dict=False)
|
||||
|
||||
timeline_items = dict(data)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ frappe.query_reports["Accounts Payable"] = {
|
||||
"fieldname":"ageing_based_on",
|
||||
"label": __("Ageing Based On"),
|
||||
"fieldtype": "Select",
|
||||
"options": 'Posting Date\nDue Date',
|
||||
"options": 'Posting Date\nDue Date\nSupplier Invoice Date',
|
||||
"default": "Posting Date"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -19,7 +19,13 @@
|
||||
|
||||
|
||||
<h2 class="text-center">{%= __(report.report_name) %}</h2>
|
||||
<h4 class="text-center">{%= filters.customer || filters.supplier %} </h4>
|
||||
<h4 class="text-center">
|
||||
{% if (filters.customer_name) { %}
|
||||
{%= filters.customer_name %}
|
||||
{% } else { %}
|
||||
{%= filters.customer || filters.supplier %}
|
||||
{% } %}
|
||||
</h4>
|
||||
<h6 class="text-center">
|
||||
{% if (filters.tax_id) { %}
|
||||
{%= __("Tax Id: ")%} {%= filters.tax_id %}
|
||||
@@ -69,7 +75,7 @@
|
||||
<td class="text-right">{%= format_currency(balance_row[range3]) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row[range4]) %}</td>
|
||||
<td class="text-right">
|
||||
{%= format_currency(flt(balance_row[__("Outstanding Amount")]), data[data.length-1]["currency"]) %}
|
||||
{%= format_currency(flt(balance_row[("outstanding_amount")]), data[data.length-1]["currency"]) %}
|
||||
</td>
|
||||
</tr>
|
||||
<td>{%= __("PDC/LC") %}</td>
|
||||
@@ -78,7 +84,7 @@
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="text-right">
|
||||
{%= format_currency(flt(balance_row[__("PDC/LC Amount")]), data[data.length-1]["currency"]) %}
|
||||
{%= format_currency(flt(balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}
|
||||
</td>
|
||||
<tr class="cvs-footer">
|
||||
<th class="text-left">{%= __("Cheques Required") %}</th>
|
||||
@@ -87,7 +93,7 @@
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th class="text-right">
|
||||
{%= format_currency(flt(balance_row[__("Outstanding Amount")]-balance_row[__("PDC/LC Amount")]), data[data.length-1]["currency"]) %}</th>
|
||||
{%= format_currency(flt(balance_row[("outstanding_amount")]-balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -155,26 +161,26 @@
|
||||
</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["invoiced_amount"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %}</td>
|
||||
{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["debit_note"], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Outstanding Amount"], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(filters.show_pdc_in_print) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
<td style="text-align: right">
|
||||
{%= data[i][__("Customer LPO")] %}</td>
|
||||
{%= data[i]["po_no"] %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
|
||||
<td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("Remaining Balance")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][("pdc/lc_date")]) %}</td>
|
||||
<td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
<td></td>
|
||||
@@ -183,15 +189,15 @@
|
||||
{% } %}
|
||||
<td><b>{%= __("Total") %}</b></td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"] ) %}</td>
|
||||
{%= format_currency(data[i]["invoiced_amount"], data[i]["currency"] ) %}</td>
|
||||
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} </td>
|
||||
{%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} </td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Outstanding Amount"], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(filters.show_pdc_in_print) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
@@ -199,9 +205,9 @@
|
||||
{%= data[i][__("Customer LPO")] %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
|
||||
<td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("Remaining Balance")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
@@ -222,14 +228,14 @@
|
||||
{% } else { %}
|
||||
<td><b>{%= __("Total") %}</b></td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("Total Invoiced Amt")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("Total Paid Amt")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("total_invoiced_amt")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("total_paid_amt")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= report.report_name === "Accounts Receivable Summary" ? format_currency(data[i][__("Credit Note Amt")], data[i]["currency"]) : format_currency(data[i][__("Debit Note Amt")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("Total Outstanding Amt")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("total_outstanding_amt")], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } %}
|
||||
</tr>
|
||||
{% } %}
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-right text-muted">{{ __("Printed On ") }}{%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}</p>
|
||||
<p class="text-right text-muted">{{ __("Printed On ") }}{%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}</p>
|
||||
|
||||
@@ -17,8 +17,9 @@ frappe.query_reports["Accounts Receivable"] = {
|
||||
"options": "Customer",
|
||||
on_change: () => {
|
||||
var customer = frappe.query_report_filters_by_name.customer.get_value();
|
||||
frappe.db.get_value('Customer', customer, "tax_id", function(value) {
|
||||
frappe.db.get_value('Customer', customer, ["tax_id", "customer_name"], function(value) {
|
||||
frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]);
|
||||
frappe.query_report_filters_by_name.customer_name.set_value(value["customer_name"]);
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -81,6 +82,12 @@ frappe.query_reports["Accounts Receivable"] = {
|
||||
"label": __("Tax Id"),
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1
|
||||
},
|
||||
{
|
||||
"fieldname":"customer_name",
|
||||
"label": __("Customer Name"),
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ class ReceivablePayableReport(object):
|
||||
for label in ("Invoiced Amount", "Paid Amount", credit_or_debit_note, "Outstanding Amount"):
|
||||
columns.append({
|
||||
"label": label,
|
||||
"fieldname": frappe.scrub(label),
|
||||
"fieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"width": 120
|
||||
@@ -87,25 +88,49 @@ class ReceivablePayableReport(object):
|
||||
"width": 120
|
||||
})
|
||||
|
||||
columns.append({
|
||||
columns += [
|
||||
{
|
||||
"fieldname": "currency",
|
||||
"label": _("Currency"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Currency",
|
||||
"width": 100
|
||||
})
|
||||
|
||||
columns += [
|
||||
_("PDC/LC Date") + ":Date:110",
|
||||
_("PDC/LC Ref") + ":Data:110",
|
||||
_("PDC/LC Amount") + ":Currency/currency:130",
|
||||
_("Remaining Balance") + ":Currency/currency:130"
|
||||
]
|
||||
},
|
||||
{
|
||||
"fieldname": "pdc/lc_date",
|
||||
"label": _("PDC/LC Date"),
|
||||
"fieldtype": "Date",
|
||||
"width": 110
|
||||
},
|
||||
{
|
||||
"fieldname": "pdc/lc_ref",
|
||||
"label": _("PDC/LC Ref"),
|
||||
"fieldtype": "Data",
|
||||
"width": 110
|
||||
},
|
||||
{
|
||||
"fieldname": "pdc/lc_amount",
|
||||
"label": _("PDC/LC Amount"),
|
||||
"fieldtype": "Currency",
|
||||
"options": "Currency",
|
||||
"width": 130
|
||||
},
|
||||
{
|
||||
"fieldname": "remaining_balance",
|
||||
"label": _("Remaining Balance"),
|
||||
"fieldtype": "Currency",
|
||||
"options": "Currency",
|
||||
"width": 130
|
||||
}]
|
||||
|
||||
if args.get('party_type') == 'Customer':
|
||||
columns += [_("Customer LPO") + ":Data:100"]
|
||||
columns.append({
|
||||
"label": _("Customer LPO"),
|
||||
"fieldtype": "Data",
|
||||
"fieldname": "po_no",
|
||||
"width": 100,
|
||||
})
|
||||
columns += [_("Delivery Note") + ":Data:100"]
|
||||
|
||||
if args.get("party_type") == "Customer":
|
||||
columns += [
|
||||
_("Territory") + ":Link/Territory:80",
|
||||
@@ -123,9 +148,6 @@ class ReceivablePayableReport(object):
|
||||
currency_precision = get_currency_precision() or 2
|
||||
dr_or_cr = "debit" if args.get("party_type") == "Customer" else "credit"
|
||||
|
||||
dn_details = get_dn_details(args.get("party_type"))
|
||||
voucher_details = self.get_voucher_details(args.get("party_type"), dn_details)
|
||||
|
||||
future_vouchers = self.get_entries_after(self.filters.report_date, args.get("party_type"))
|
||||
|
||||
if not self.filters.get("company"):
|
||||
@@ -137,8 +159,14 @@ class ReceivablePayableReport(object):
|
||||
|
||||
data = []
|
||||
pdc_details = get_pdc_details(args.get("party_type"), self.filters.report_date)
|
||||
gl_entries_data = self.get_entries_till(self.filters.report_date, args.get("party_type"))
|
||||
|
||||
for gle in self.get_entries_till(self.filters.report_date, args.get("party_type")):
|
||||
if gl_entries_data:
|
||||
voucher_nos = [d.voucher_no for d in gl_entries_data] or []
|
||||
dn_details = get_dn_details(args.get("party_type"), voucher_nos)
|
||||
voucher_details = get_voucher_details(args.get("party_type"), voucher_nos, dn_details)
|
||||
|
||||
for gle in gl_entries_data:
|
||||
if self.is_receivable_or_payable(gle, dr_or_cr, future_vouchers):
|
||||
outstanding_amount, credit_note_amount = self.get_outstanding_amount(gle,
|
||||
self.filters.report_date, dr_or_cr, return_entries, currency_precision)
|
||||
@@ -151,6 +179,7 @@ class ReceivablePayableReport(object):
|
||||
|
||||
# get due date
|
||||
due_date = voucher_details.get(gle.voucher_no, {}).get("due_date", "")
|
||||
bill_date = voucher_details.get(gle.voucher_no, {}).get("bill_date", "")
|
||||
|
||||
row += [gle.voucher_type, gle.voucher_no, due_date]
|
||||
|
||||
@@ -167,15 +196,25 @@ class ReceivablePayableReport(object):
|
||||
row += [invoiced_amount, paid_amt, credit_note_amount, outstanding_amount]
|
||||
|
||||
# ageing data
|
||||
entry_date = due_date if self.filters.ageing_based_on == "Due Date" else gle.posting_date
|
||||
if self.filters.ageing_based_on == "Due Date":
|
||||
entry_date = due_date
|
||||
elif self.filters.ageing_based_on == "Supplier Invoice Date":
|
||||
entry_date = bill_date
|
||||
else:
|
||||
entry_date = gle.posting_date
|
||||
row += get_ageing_data(cint(self.filters.range1), cint(self.filters.range2),
|
||||
cint(self.filters.range3), self.age_as_on, entry_date, outstanding_amount)
|
||||
|
||||
|
||||
# issue 6371-Ageing buckets should not have amounts if due date is not reached
|
||||
if self.filters.ageing_based_on == "Due Date" \
|
||||
and getdate(due_date) > getdate(self.filters.report_date):
|
||||
row[-1]=row[-2]=row[-3]=row[-4]=0
|
||||
|
||||
if self.filters.ageing_based_on == "Supplier Invoice Date" \
|
||||
and getdate(bill_date) > getdate(self.filters.report_date):
|
||||
row[-1]=row[-2]=row[-3]=row[-4]=0
|
||||
|
||||
if self.filters.get(scrub(args.get("party_type"))):
|
||||
row.append(gle.account_currency)
|
||||
else:
|
||||
@@ -207,12 +246,11 @@ class ReceivablePayableReport(object):
|
||||
|
||||
def get_entries_after(self, report_date, party_type):
|
||||
# returns a distinct list
|
||||
return list(set([(e.voucher_type, e.voucher_no) for e in self.get_gl_entries(party_type)
|
||||
if getdate(e.posting_date) > report_date]))
|
||||
return list(set([(e.voucher_type, e.voucher_no) for e in self.get_gl_entries(party_type, report_date, for_future=True)]))
|
||||
|
||||
def get_entries_till(self, report_date, party_type):
|
||||
# returns a generator
|
||||
return (e for e in self.get_gl_entries(party_type) if getdate(e.posting_date) <= report_date)
|
||||
return self.get_gl_entries(party_type, report_date)
|
||||
|
||||
def is_receivable_or_payable(self, gle, dr_or_cr, future_vouchers):
|
||||
return (
|
||||
@@ -239,14 +277,16 @@ class ReceivablePayableReport(object):
|
||||
|
||||
for e in self.get_gl_entries_for(gle.party, gle.party_type, gle.voucher_type, gle.voucher_no):
|
||||
if getdate(e.posting_date) <= report_date and e.name!=gle.name:
|
||||
amount = flt(e.get(reverse_dr_or_cr)) - flt(e.get(dr_or_cr))
|
||||
amount = flt(e.get(reverse_dr_or_cr), currency_precision) - flt(e.get(dr_or_cr), currency_precision)
|
||||
if e.voucher_no not in return_entries:
|
||||
payment_amount += amount
|
||||
else:
|
||||
credit_note_amount += amount
|
||||
|
||||
outstanding_amount = flt((flt(gle.get(dr_or_cr)) - flt(gle.get(reverse_dr_or_cr)) \
|
||||
- payment_amount - credit_note_amount), currency_precision)
|
||||
outstanding_amount = (flt((flt(gle.get(dr_or_cr), currency_precision)
|
||||
- flt(gle.get(reverse_dr_or_cr), currency_precision)
|
||||
- payment_amount - credit_note_amount), currency_precision))
|
||||
|
||||
credit_note_amount = flt(credit_note_amount, currency_precision)
|
||||
|
||||
return outstanding_amount, credit_note_amount
|
||||
@@ -275,39 +315,31 @@ class ReceivablePayableReport(object):
|
||||
|
||||
return self.party_map
|
||||
|
||||
def get_voucher_details(self, party_type, dn_details):
|
||||
voucher_details = frappe._dict()
|
||||
def get_gl_entries(self, party_type, date=None, for_future=False):
|
||||
conditions, values = self.prepare_conditions(party_type)
|
||||
|
||||
if party_type == "Customer":
|
||||
for si in frappe.db.sql("""select name, due_date, po_no
|
||||
from `tabSales Invoice` where docstatus=1""", as_dict=1):
|
||||
si['delivery_note'] = dn_details.get(si.name)
|
||||
voucher_details.setdefault(si.name, si)
|
||||
if self.filters.get(scrub(party_type)):
|
||||
select_fields = "sum(debit_in_account_currency) as debit, sum(credit_in_account_currency) as credit"
|
||||
else:
|
||||
select_fields = "sum(debit) as debit, sum(credit) as credit"
|
||||
|
||||
if party_type == "Supplier":
|
||||
for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date
|
||||
from `tabPurchase Invoice` where docstatus=1""", as_dict=1):
|
||||
voucher_details.setdefault(pi.name, pi)
|
||||
if date and not for_future:
|
||||
conditions += " and posting_date <= '%s'" % date
|
||||
|
||||
return voucher_details
|
||||
if date and for_future:
|
||||
conditions += " and posting_date > '%s'" % date
|
||||
|
||||
def get_gl_entries(self, party_type):
|
||||
if not hasattr(self, "gl_entries"):
|
||||
conditions, values = self.prepare_conditions(party_type)
|
||||
|
||||
if self.filters.get(scrub(party_type)):
|
||||
select_fields = "sum(debit_in_account_currency) as debit, sum(credit_in_account_currency) as credit"
|
||||
else:
|
||||
select_fields = "sum(debit) as debit, sum(credit) as credit"
|
||||
|
||||
self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party,
|
||||
voucher_type, voucher_no, against_voucher_type, against_voucher,
|
||||
account_currency, remarks, {0}
|
||||
from `tabGL Entry`
|
||||
where docstatus < 2 and party_type=%s and (party is not null and party != '') {1}
|
||||
self.gl_entries = frappe.db.sql("""
|
||||
select
|
||||
name, posting_date, account, party_type, party, voucher_type, voucher_no,
|
||||
against_voucher_type, against_voucher, account_currency, remarks, {0}
|
||||
from
|
||||
`tabGL Entry`
|
||||
where
|
||||
docstatus < 2 and party_type=%s and (party is not null and party != '') {1}
|
||||
group by voucher_type, voucher_no, against_voucher_type, against_voucher, party
|
||||
order by posting_date, party"""
|
||||
.format(select_fields, conditions), values, as_dict=True)
|
||||
.format(select_fields, conditions), values, as_dict=True)
|
||||
|
||||
return self.gl_entries
|
||||
|
||||
@@ -416,7 +448,6 @@ def get_pdc_details(party_type, report_date):
|
||||
and pent.party_type = %s
|
||||
group by pent.party, pref.reference_name""", (report_date, party_type), as_dict=1):
|
||||
pdc_details.setdefault((pdc.invoice_no, pdc.party), pdc)
|
||||
|
||||
if scrub(party_type):
|
||||
amount_field = ("jea.debit_in_account_currency"
|
||||
if party_type == 'Supplier' else "jea.credit_in_account_currency")
|
||||
@@ -443,18 +474,57 @@ def get_pdc_details(party_type, report_date):
|
||||
|
||||
return pdc_details
|
||||
|
||||
def get_dn_details(party_type):
|
||||
def get_dn_details(party_type, voucher_nos):
|
||||
dn_details = frappe._dict()
|
||||
|
||||
if party_type == "Customer":
|
||||
for si in frappe.db.sql("""select parent, GROUP_CONCAT(delivery_note SEPARATOR ', ') as dn
|
||||
from `tabSales Invoice Item`
|
||||
where docstatus=1 and delivery_note is not null and delivery_note != '' group by parent
|
||||
Union
|
||||
select against_sales_invoice as parent, GROUP_CONCAT(parent SEPARATOR ', ') as dn
|
||||
from `tabDelivery Note Item`
|
||||
where docstatus=1 and against_sales_invoice is not null
|
||||
and against_sales_invoice != '' group by against_sales_invoice""", as_dict=1):
|
||||
for si in frappe.db.sql("""
|
||||
select
|
||||
parent, GROUP_CONCAT(delivery_note SEPARATOR ', ') as dn
|
||||
from
|
||||
`tabSales Invoice Item`
|
||||
where
|
||||
docstatus=1 and delivery_note is not null and delivery_note != ''
|
||||
and parent in (%s) group by parent
|
||||
""" %(','.join(['%s'] * len(voucher_nos))), tuple(voucher_nos) , as_dict=1):
|
||||
dn_details.setdefault(si.parent, si.dn)
|
||||
|
||||
for si in frappe.db.sql("""
|
||||
select
|
||||
against_sales_invoice as parent, GROUP_CONCAT(parent SEPARATOR ', ') as dn
|
||||
from
|
||||
`tabDelivery Note Item`
|
||||
where
|
||||
docstatus=1 and against_sales_invoice is not null and against_sales_invoice != ''
|
||||
and against_sales_invoice in (%s)
|
||||
group by against_sales_invoice
|
||||
""" %(','.join(['%s'] * len(voucher_nos))), tuple(voucher_nos) , as_dict=1):
|
||||
if si.parent in dn_details:
|
||||
dn_details[si.parent] += ', %s' %(si.dn)
|
||||
else:
|
||||
dn_details.setdefault(si.parent, si.dn)
|
||||
|
||||
return dn_details
|
||||
|
||||
def get_voucher_details(party_type, voucher_nos, dn_details):
|
||||
voucher_details = frappe._dict()
|
||||
|
||||
if party_type == "Customer":
|
||||
for si in frappe.db.sql("""select name, due_date, po_no
|
||||
from `tabSales Invoice` where docstatus=1 and name in (%s)
|
||||
""" %(','.join(['%s'] *len(voucher_nos))), (tuple(voucher_nos)), as_dict=1):
|
||||
si['delivery_note'] = dn_details.get(si.name)
|
||||
voucher_details.setdefault(si.name, si)
|
||||
|
||||
if party_type == "Supplier":
|
||||
for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date
|
||||
from `tabPurchase Invoice` where docstatus = 1 and name in (%s)
|
||||
""" %(','.join(['%s'] *len(voucher_nos))), (tuple(voucher_nos)), as_dict=1):
|
||||
voucher_details.setdefault(pi.name, pi)
|
||||
|
||||
for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date from
|
||||
`tabJournal Entry` where docstatus = 1 and bill_no is not NULL and name in (%s)
|
||||
""" %(','.join(['%s'] *len(voucher_nos))), (tuple(voucher_nos)), as_dict=1):
|
||||
voucher_details.setdefault(pi.name, pi)
|
||||
|
||||
return voucher_details
|
||||
|
||||
@@ -3,47 +3,75 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import flt
|
||||
from frappe import _
|
||||
|
||||
def execute(filters=None):
|
||||
columns, data = get_columns(), get_data(filters)
|
||||
return columns, data
|
||||
|
||||
|
||||
def get_data(filters):
|
||||
data = frappe.db.sql("""
|
||||
select
|
||||
a.name as asset, a.asset_category, a.status,
|
||||
a.depreciation_method, a.purchase_date, a.gross_purchase_amount,
|
||||
ds.schedule_date as depreciation_date, ds.depreciation_amount,
|
||||
ds.accumulated_depreciation_amount,
|
||||
(a.gross_purchase_amount - ds.accumulated_depreciation_amount) as amount_after_depreciation,
|
||||
ds.journal_entry as depreciation_entry
|
||||
from
|
||||
`tabAsset` a, `tabDepreciation Schedule` ds
|
||||
where
|
||||
a.name = ds.parent
|
||||
and a.docstatus=1
|
||||
and ifnull(ds.journal_entry, '') != ''
|
||||
and ds.schedule_date between %(from_date)s and %(to_date)s
|
||||
and a.company = %(company)s
|
||||
{conditions}
|
||||
order by
|
||||
a.name asc, ds.schedule_date asc
|
||||
""".format(conditions=get_filter_conditions(filters)), filters, as_dict=1)
|
||||
|
||||
return data
|
||||
|
||||
def get_filter_conditions(filters):
|
||||
conditions = ""
|
||||
|
||||
data = []
|
||||
depreciation_accounts = frappe.db.sql_list(""" select name from tabAccount
|
||||
where ifnull(account_type, '') = 'Depreciation' """)
|
||||
|
||||
filters_data = [["company", "=", filters.get('company')],
|
||||
["posting_date", ">=", filters.get('from_date')],
|
||||
["posting_date", "<=", filters.get('to_date')],
|
||||
["against_voucher_type", "=", "Asset"],
|
||||
["account", "in", depreciation_accounts]]
|
||||
|
||||
if filters.get("asset"):
|
||||
conditions += " and a.name = %(asset)s"
|
||||
|
||||
filters_data.append(["against_voucher", "=", filters.get("asset")])
|
||||
|
||||
if filters.get("asset_category"):
|
||||
conditions += " and a.asset_category = %(asset_category)s"
|
||||
|
||||
return conditions
|
||||
assets = frappe.db.sql_list("""select name from tabAsset
|
||||
where asset_category = %s and docstatus=1""", filters.get("asset_category"))
|
||||
|
||||
filters_data.append(["against_voucher", "in", assets])
|
||||
|
||||
gl_entries = frappe.get_all('GL Entry',
|
||||
filters= filters_data,
|
||||
fields = ["against_voucher", "debit_in_account_currency as debit", "voucher_no", "posting_date"],
|
||||
order_by= "against_voucher, posting_date")
|
||||
|
||||
if not gl_entries:
|
||||
return data
|
||||
|
||||
assets = [d.against_voucher for d in gl_entries]
|
||||
assets_details = get_assets_details(assets)
|
||||
|
||||
for d in gl_entries:
|
||||
asset_data = assets_details.get(d.against_voucher)
|
||||
if not asset_data.get("accumulated_depreciation_amount"):
|
||||
asset_data.accumulated_depreciation_amount = d.debit
|
||||
else:
|
||||
asset_data.accumulated_depreciation_amount += d.debit
|
||||
|
||||
row = frappe._dict(asset_data)
|
||||
row.update({
|
||||
"depreciation_amount": d.debit,
|
||||
"depreciation_date": d.posting_date,
|
||||
"amount_after_depreciation": (flt(row.gross_purchase_amount) -
|
||||
flt(row.accumulated_depreciation_amount)),
|
||||
"depreciation_entry": d.voucher_no
|
||||
})
|
||||
|
||||
data.append(row)
|
||||
|
||||
return data
|
||||
|
||||
def get_assets_details(assets):
|
||||
assets_details = {}
|
||||
|
||||
fields = ["name as asset", "gross_purchase_amount",
|
||||
"asset_category", "status", "depreciation_method", "purchase_date"]
|
||||
|
||||
for d in frappe.get_all("Asset", fields = fields, filters = {'name': ('in', assets)}):
|
||||
assets_details.setdefault(d.asset, d)
|
||||
|
||||
return assets_details
|
||||
|
||||
def get_columns():
|
||||
return [
|
||||
{
|
||||
|
||||
@@ -39,6 +39,12 @@ frappe.query_reports["Budget Variance Report"] = {
|
||||
options: ["Cost Center", "Project"],
|
||||
default: "Cost Center",
|
||||
reqd: 1
|
||||
}
|
||||
},
|
||||
{
|
||||
fieldname: "cost_center",
|
||||
label: __("Cost Center"),
|
||||
fieldtype: "Link",
|
||||
options: "Cost Center"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,9 +10,13 @@ from erpnext.controllers.trends import get_period_date_ranges, get_period_month_
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
validate_filters(filters)
|
||||
columns = get_columns(filters)
|
||||
cost_centers = get_cost_centers(filters)
|
||||
if filters.get("cost_center"):
|
||||
cost_centers = [filters.get("cost_center")]
|
||||
else:
|
||||
cost_centers = get_cost_centers(filters)
|
||||
|
||||
period_month_ranges = get_period_month_ranges(filters["period"], filters["fiscal_year"])
|
||||
cam_map = get_cost_center_account_month_map(filters)
|
||||
|
||||
@@ -39,6 +43,10 @@ def execute(filters=None):
|
||||
|
||||
return columns, data
|
||||
|
||||
def validate_filters(filters):
|
||||
if filters.get("budget_against")=="Project" and filters.get("cost_center"):
|
||||
frappe.throw(_("Filter based on Cost Center is only applicable if Budget Against is selected as Cost Center"))
|
||||
|
||||
def get_columns(filters):
|
||||
columns = [_(filters.get("budget_against")) + ":Link/%s:120"%(filters.get("budget_against")), _("Account") + ":Link/Account:120"]
|
||||
|
||||
@@ -66,12 +74,16 @@ def get_cost_centers(filters):
|
||||
|
||||
#Get cost center & target details
|
||||
def get_cost_center_target_details(filters):
|
||||
cond = ""
|
||||
if filters.get("cost_center"):
|
||||
cond += " and b.cost_center='%s'" % frappe.db.escape(filters.get("cost_center"))
|
||||
|
||||
return frappe.db.sql("""
|
||||
select b.{budget_against} as budget_against, b.monthly_distribution, ba.account, ba.budget_amount
|
||||
from `tabBudget` b, `tabBudget Account` ba
|
||||
where b.name=ba.parent and b.docstatus = 1 and b.fiscal_year=%s
|
||||
and b.budget_against = %s and b.company=%s
|
||||
""".format(budget_against=filters.get("budget_against").replace(" ", "_").lower()),
|
||||
and b.budget_against = %s and b.company=%s {cond}
|
||||
""".format(budget_against=filters.get("budget_against").replace(" ", "_").lower(), cond=cond),
|
||||
(filters.fiscal_year, filters.budget_against, filters.company), as_dict=True)
|
||||
|
||||
#Get target distribution details of accounts of cost center
|
||||
|
||||
@@ -185,14 +185,15 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
|
||||
has_value = False
|
||||
total = 0
|
||||
row = frappe._dict({
|
||||
"account_name": _(d.account_name),
|
||||
"account": _(d.name),
|
||||
"parent_account": _(d.parent_account),
|
||||
"indent": flt(d.indent),
|
||||
"year_start_date": year_start_date,
|
||||
"year_end_date": year_end_date,
|
||||
"currency": company_currency,
|
||||
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1)
|
||||
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1),
|
||||
"account_name": ('{} - {}'.format(_(d.account_number), _(d.account_name))
|
||||
if d.account_number else _(d.account_name))
|
||||
})
|
||||
for period in period_list:
|
||||
if d.get(period.key) and balance_must_be=="Credit":
|
||||
@@ -253,7 +254,7 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency
|
||||
out.append({})
|
||||
|
||||
def get_accounts(company, root_type):
|
||||
return frappe.db.sql("""select name, parent_account, lft, rgt, root_type, report_type, account_name from `tabAccount`
|
||||
return frappe.db.sql("""select name, account_number, parent_account, lft, rgt, root_type, report_type, account_name from `tabAccount`
|
||||
where company=%s and root_type=%s order by lft""", (company, root_type), as_dict=True)
|
||||
|
||||
def filter_accounts(accounts, depth=10):
|
||||
@@ -305,19 +306,20 @@ def set_gl_entries_by_account(company, from_date, to_date, root_lft, root_rgt, f
|
||||
|
||||
additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters)
|
||||
|
||||
accounts = frappe.db.sql_list("""select name from `tabAccount`
|
||||
where lft >= %s and rgt <= %s""", (root_lft, root_rgt))
|
||||
additional_conditions += " and account in ('{}')"\
|
||||
.format("', '".join([frappe.db.escape(d) for d in accounts]))
|
||||
|
||||
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year from `tabGL Entry`
|
||||
where company=%(company)s
|
||||
{additional_conditions}
|
||||
and posting_date <= %(to_date)s
|
||||
and account in (select name from `tabAccount`
|
||||
where lft >= %(lft)s and rgt <= %(rgt)s)
|
||||
order by account, posting_date""".format(additional_conditions=additional_conditions),
|
||||
{
|
||||
"company": company,
|
||||
"from_date": from_date,
|
||||
"to_date": to_date,
|
||||
"lft": root_lft,
|
||||
"rgt": root_rgt
|
||||
},
|
||||
as_dict=True)
|
||||
|
||||
|
||||
@@ -71,8 +71,8 @@ def set_account_currency(filters):
|
||||
if gle_currency:
|
||||
account_currency = gle_currency
|
||||
else:
|
||||
account_currency = None if filters.party_type in ["Employee", "Student", "Shareholder"] else \
|
||||
frappe.db.get_value(filters.party_type, filters.party, "default_currency")
|
||||
account_currency = (None if filters.party_type in ["Employee", "Student", "Shareholder", "Member"] else
|
||||
frappe.db.get_value(filters.party_type, filters.party, "default_currency"))
|
||||
|
||||
filters["account_currency"] = account_currency or filters.company_currency
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ class GrossProfitGenerator(object):
|
||||
row.qty += returned_item_row.qty
|
||||
row.base_amount += returned_item_row.base_amount
|
||||
row.buying_amount = row.qty * row.buying_rate
|
||||
if row.qty:
|
||||
if row.qty or row.base_amount:
|
||||
row = self.set_average_rate(row)
|
||||
self.grouped_data.append(row)
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
|
||||
row += [
|
||||
d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
|
||||
purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_rate, d.base_net_amount
|
||||
purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_amount / d.stock_qty, d.base_net_amount
|
||||
]
|
||||
|
||||
total_tax = 0
|
||||
@@ -120,8 +120,7 @@ def get_items(filters, additional_query_columns):
|
||||
`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
|
||||
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
|
||||
`tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`,
|
||||
`tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_rate`,
|
||||
`tabPurchase Invoice Item`.`base_net_amount`,
|
||||
`tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_amount`,
|
||||
`tabPurchase Invoice`.supplier_name, `tabPurchase Invoice`.mode_of_payment {0}
|
||||
from `tabPurchase Invoice`, `tabPurchase Invoice Item`
|
||||
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and
|
||||
|
||||
@@ -53,7 +53,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom
|
||||
]
|
||||
|
||||
row += [d.base_net_rate/d.stock_qty, d.base_net_amount] \
|
||||
row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount] \
|
||||
if d.stock_uom != d.uom else [d.base_net_rate, d.base_net_amount]
|
||||
|
||||
total_tax = 0
|
||||
@@ -133,7 +133,7 @@ def get_items(filters, additional_query_columns):
|
||||
`tabSales Invoice Item`.stock_uom, `tabSales Invoice Item`.base_net_rate,
|
||||
`tabSales Invoice Item`.base_net_amount, `tabSales Invoice`.customer_name,
|
||||
`tabSales Invoice`.customer_group, `tabSales Invoice Item`.so_detail,
|
||||
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom {0}
|
||||
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0}
|
||||
from `tabSales Invoice`, `tabSales Invoice Item`
|
||||
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
|
||||
and `tabSales Invoice`.docstatus = 1 %s %s
|
||||
@@ -157,6 +157,9 @@ def get_delivery_notes_against_sales_order(item_list):
|
||||
|
||||
return so_dn_map
|
||||
|
||||
def get_deducted_taxes():
|
||||
return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'")
|
||||
|
||||
def get_tax_accounts(item_list, columns, company_currency,
|
||||
doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
|
||||
import json
|
||||
@@ -176,9 +179,10 @@ def get_tax_accounts(item_list, columns, company_currency,
|
||||
if doctype == "Purchase Invoice":
|
||||
conditions = " and category in ('Total', 'Valuation and Total') and base_tax_amount_after_discount_amount != 0"
|
||||
|
||||
deducted_tax = get_deducted_taxes()
|
||||
tax_details = frappe.db.sql("""
|
||||
select
|
||||
parent, description, item_wise_tax_detail,
|
||||
name, parent, description, item_wise_tax_detail,
|
||||
charge_type, base_tax_amount_after_discount_amount
|
||||
from `tab%s`
|
||||
where
|
||||
@@ -190,7 +194,7 @@ def get_tax_accounts(item_list, columns, company_currency,
|
||||
""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row)), conditions),
|
||||
tuple([doctype] + invoice_item_row.keys()))
|
||||
|
||||
for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
||||
for name, parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
||||
description = handle_html(description)
|
||||
if description not in tax_columns and tax_amount:
|
||||
# as description is text editor earlier and markup can break the column convention in reports
|
||||
@@ -219,9 +223,13 @@ def get_tax_accounts(item_list, columns, company_currency,
|
||||
item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) \
|
||||
if item_net_amount else 0
|
||||
if item_tax_amount:
|
||||
tax_value = flt(item_tax_amount, tax_amount_precision)
|
||||
tax_value = (tax_value * -1
|
||||
if (doctype == 'Purchase Invoice' and name in deducted_tax) else tax_value)
|
||||
|
||||
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
||||
"tax_rate": tax_rate,
|
||||
"tax_amount": flt(item_tax_amount, tax_amount_precision)
|
||||
"tax_amount": tax_value
|
||||
})
|
||||
|
||||
except ValueError:
|
||||
|
||||
@@ -51,7 +51,7 @@ def validate_filters(filters):
|
||||
filters.to_date = filters.year_end_date
|
||||
|
||||
def get_data(filters):
|
||||
accounts = frappe.db.sql("""select name, parent_account, account_name, root_type, report_type, lft, rgt
|
||||
accounts = frappe.db.sql("""select name, account_number, parent_account, account_name, root_type, report_type, lft, rgt
|
||||
from `tabAccount` where company=%s order by lft""", filters.company, as_dict=True)
|
||||
company_currency = erpnext.get_company_currency(filters.company)
|
||||
|
||||
@@ -162,8 +162,6 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
|
||||
total_row["credit"] += d["credit"]
|
||||
total_row["opening_debit"] += d["opening_debit"]
|
||||
total_row["opening_credit"] += d["opening_credit"]
|
||||
total_row["closing_debit"] += (d["opening_debit"] + d["debit"])
|
||||
total_row["closing_credit"] += (d["opening_credit"] + d["credit"])
|
||||
|
||||
return total_row
|
||||
|
||||
@@ -176,16 +174,19 @@ def accumulate_values_into_parents(accounts, accounts_by_name):
|
||||
def prepare_data(accounts, filters, total_row, parent_children_map, company_currency):
|
||||
data = []
|
||||
|
||||
total_row["closing_debit"] = total_row["closing_credit"] = 0
|
||||
|
||||
for d in accounts:
|
||||
has_value = False
|
||||
row = {
|
||||
"account_name": d.account_name,
|
||||
"account": d.name,
|
||||
"parent_account": d.parent_account,
|
||||
"indent": d.indent,
|
||||
"from_date": filters.from_date,
|
||||
"to_date": filters.to_date,
|
||||
"currency": company_currency
|
||||
"currency": company_currency,
|
||||
"account_name": ('{} - {}'.format(d.account_number, d.account_name)
|
||||
if d.account_number else d.account_name)
|
||||
}
|
||||
|
||||
prepare_opening_and_closing(d)
|
||||
@@ -200,6 +201,10 @@ def prepare_data(accounts, filters, total_row, parent_children_map, company_curr
|
||||
row["has_value"] = has_value
|
||||
data.append(row)
|
||||
|
||||
if not d.parent_account:
|
||||
total_row["closing_debit"] += (d["debit"] - d["credit"]) if (d["debit"] - d["credit"]) > 0 else 0
|
||||
total_row["closing_credit"] += abs(d["debit"] - d["credit"]) if (d["debit"] - d["credit"]) < 0 else 0
|
||||
|
||||
data.extend([{},total_row])
|
||||
|
||||
return data
|
||||
|
||||
@@ -23,6 +23,14 @@ frappe.ui.form.on('Asset', {
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("cost_center", function() {
|
||||
return {
|
||||
"filters": {
|
||||
"company": frm.doc.company,
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
@@ -59,11 +67,33 @@ frappe.ui.form.on('Asset', {
|
||||
frm.trigger("create_asset_maintenance");
|
||||
}, __("Make"));
|
||||
}
|
||||
|
||||
if (!frm.doc.calculate_depreciation) {
|
||||
frm.add_custom_button(__("Depreciation Entry"), function() {
|
||||
frm.trigger("make_journal_entry");
|
||||
}, __("Make"));
|
||||
}
|
||||
|
||||
frm.page.set_inner_btn_group_as_primary(__("Make"));
|
||||
frm.trigger("setup_chart");
|
||||
}
|
||||
},
|
||||
|
||||
make_journal_entry: function(frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.assets.doctype.asset.asset.make_journal_entry",
|
||||
args: {
|
||||
asset_name: frm.doc.name
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
var doclist = frappe.model.sync(r.message);
|
||||
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
setup_chart: function(frm) {
|
||||
var x_intervals = [frm.doc.purchase_date];
|
||||
var asset_values = [frm.doc.gross_purchase_amount];
|
||||
|
||||
@@ -415,6 +415,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Cost Center",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1221,7 +1252,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-19 12:58:44.137460",
|
||||
"modified": "2018-07-17 06:30:25.506194",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Assets",
|
||||
"name": "Asset",
|
||||
|
||||
@@ -283,3 +283,34 @@ def get_item_details(item_code):
|
||||
})
|
||||
|
||||
return ret
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_journal_entry(asset_name):
|
||||
asset = frappe.get_doc("Asset", asset_name)
|
||||
fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
|
||||
get_depreciation_accounts(asset)
|
||||
|
||||
depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
|
||||
["depreciation_cost_center", "series_for_depreciation_entry"])
|
||||
depreciation_cost_center = asset.cost_center or depreciation_cost_center
|
||||
|
||||
je = frappe.new_doc("Journal Entry")
|
||||
je.voucher_type = "Depreciation Entry"
|
||||
je.naming_series = depreciation_series
|
||||
je.company = asset.company
|
||||
je.remark = "Depreciation Entry against asset {0}".format(asset_name)
|
||||
|
||||
je.append("accounts", {
|
||||
"account": depreciation_expense_account,
|
||||
"reference_type": "Asset",
|
||||
"reference_name": asset.name,
|
||||
"cost_center": depreciation_cost_center
|
||||
})
|
||||
|
||||
je.append("accounts", {
|
||||
"account": accumulated_depreciation_account,
|
||||
"reference_type": "Asset",
|
||||
"reference_name": asset.name
|
||||
})
|
||||
|
||||
return je
|
||||
@@ -5,13 +5,13 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt, today, getdate
|
||||
from frappe.utils import flt, today, getdate, cint
|
||||
|
||||
def post_depreciation_entries(date=None):
|
||||
# Return if automatic booking of asset depreciation is disabled
|
||||
if not frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically"):
|
||||
if not cint(frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically")):
|
||||
return
|
||||
|
||||
|
||||
if not date:
|
||||
date = today()
|
||||
for asset in get_depreciable_assets(date):
|
||||
@@ -38,7 +38,7 @@ def make_depreciation_entry(asset_name, date=None):
|
||||
|
||||
depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
|
||||
["depreciation_cost_center", "series_for_depreciation_entry"])
|
||||
|
||||
depreciation_cost_center = asset.cost_center or depreciation_cost_center
|
||||
|
||||
for d in asset.get("schedules"):
|
||||
if not d.journal_entry and getdate(d.schedule_date) <= getdate(date):
|
||||
@@ -154,6 +154,7 @@ def restore_asset(asset_name):
|
||||
def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
|
||||
fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset)
|
||||
disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company)
|
||||
depreciation_cost_center = asset.cost_center or depreciation_cost_center
|
||||
|
||||
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation)
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ frappe.ui.form.on('Asset Category', {
|
||||
var d = locals[cdt][cdn];
|
||||
return {
|
||||
"filters": {
|
||||
"root_type": "Asset",
|
||||
"account_type": "Accumulated Depreciation",
|
||||
"is_group": 0,
|
||||
"company": d.company_name
|
||||
}
|
||||
@@ -41,4 +41,4 @@ frappe.ui.form.on('Asset Category', {
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "field:maintenance_task",
|
||||
"autoname": "",
|
||||
"beta": 0,
|
||||
"creation": "2017-10-20 07:10:55.903571",
|
||||
"custom": 0,
|
||||
@@ -42,7 +42,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 1
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
@@ -625,7 +625,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-28 12:22:34.151430",
|
||||
"modified": "2018-06-18 16:12:04.330021",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Assets",
|
||||
"name": "Asset Maintenance Task",
|
||||
|
||||
@@ -7,4 +7,5 @@ import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class AssetMaintenanceTask(Document):
|
||||
pass
|
||||
def autoname(self):
|
||||
self.name = self.maintenance_task
|
||||
|
||||
@@ -1,231 +1,276 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2013-06-25 11:04:03",
|
||||
"custom": 0,
|
||||
"description": "Settings for Buying Module",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Other",
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Supplier Name",
|
||||
"fieldname": "supp_master_name",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Supplier Naming By",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Supplier Name\nNaming Series",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "supplier_type",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Default Supplier Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Supplier Type",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "buying_price_list",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Default Buying Price List",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Price List",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "po_required",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Purchase Order Required",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "No\nYes",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "pr_required",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Purchase Receipt Required",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "No\nYes",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "maintain_same_rate",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Maintain same rate throughout purchase cycle",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "allow_multiple_items",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Allow Item to be added multiple times in a transaction",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"description": "If enabled, last purchase details of items will not be fetched from previous purchase order or purchase receipt",
|
||||
"fieldname": "disable_fetch_last_purchase_rate",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Disable Fetching Last Purchase Details in Purchase Order",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "fa fa-cog",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"modified": "2017-12-27 15:20:06.052342",
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-07-18 07:52:38.062488",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Buying Settings",
|
||||
@@ -252,6 +297,10 @@
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -32,12 +32,7 @@ frappe.ui.form.on("Purchase Order", {
|
||||
erpnext.queries.setup_queries(frm, "Warehouse", function() {
|
||||
return erpnext.queries.warehouse(frm.doc);
|
||||
});
|
||||
|
||||
if (frm.doc.__onload) {
|
||||
frm.toggle_display('get_last_purchase_rate',
|
||||
frm.doc.__onload.disable_fetch_last_purchase_rate);
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Purchase Order Item", {
|
||||
@@ -318,6 +313,73 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
||||
})
|
||||
}, __("Add items from"));
|
||||
|
||||
this.frm.add_custom_button(__('Update rate as per last purchase'),
|
||||
function() {
|
||||
frappe.call({
|
||||
"method": "get_last_purchase_rate",
|
||||
"doc": me.frm.doc,
|
||||
callback: function(r, rt) {
|
||||
me.frm.dirty();
|
||||
me.frm.cscript.calculate_taxes_and_totals();
|
||||
}
|
||||
})
|
||||
}, __("Tools"));
|
||||
|
||||
this.frm.add_custom_button(__('Link to Material Request'),
|
||||
function() {
|
||||
var my_items = [];
|
||||
for (var i in me.frm.doc.items) {
|
||||
if(!me.frm.doc.items[i].material_request){
|
||||
my_items.push(me.frm.doc.items[i].item_code);
|
||||
}
|
||||
}
|
||||
frappe.call({
|
||||
method: "erpnext.buying.utils.get_linked_material_requests",
|
||||
args:{
|
||||
items: my_items
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.exc) return;
|
||||
|
||||
var i = 0;
|
||||
var item_length = me.frm.doc.items.length;
|
||||
while (i < item_length) {
|
||||
var qty = me.frm.doc.items[i].qty;
|
||||
(r.message[0] || []).forEach(function(d) {
|
||||
if (d.qty > 0 && qty > 0 && me.frm.doc.items[i].item_code == d.item_code && !me.frm.doc.items[i].material_request_item)
|
||||
{
|
||||
me.frm.doc.items[i].material_request = d.mr_name;
|
||||
me.frm.doc.items[i].material_request_item = d.mr_item;
|
||||
var my_qty = Math.min(qty, d.qty);
|
||||
qty = qty - my_qty;
|
||||
d.qty = d.qty - my_qty;
|
||||
me.frm.doc.items[i].stock_qty = my_qty * me.frm.doc.items[i].conversion_factor;
|
||||
me.frm.doc.items[i].qty = my_qty;
|
||||
|
||||
frappe.msgprint("Assigning " + d.mr_name + " to " + d.item_code + " (row " + me.frm.doc.items[i].idx + ")");
|
||||
if (qty > 0) {
|
||||
frappe.msgprint("Splitting " + qty + " units of " + d.item_code);
|
||||
var new_row = frappe.model.add_child(me.frm.doc, me.frm.doc.items[i].doctype, "items");
|
||||
item_length++;
|
||||
|
||||
for (var key in me.frm.doc.items[i]) {
|
||||
new_row[key] = me.frm.doc.items[i][key];
|
||||
}
|
||||
|
||||
new_row.idx = item_length;
|
||||
new_row["stock_qty"] = new_row.conversion_factor * qty;
|
||||
new_row["qty"] = qty;
|
||||
new_row["material_request"] = "";
|
||||
new_row["material_request_item"] = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
i++;
|
||||
}
|
||||
refresh_field("items");
|
||||
}
|
||||
});
|
||||
}, __("Tools"));
|
||||
},
|
||||
|
||||
tc_name: function() {
|
||||
@@ -346,17 +408,6 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
||||
cur_frm.cscript.update_status('Deliver', 'Delivered')
|
||||
},
|
||||
|
||||
get_last_purchase_rate: function() {
|
||||
frappe.call({
|
||||
"method": "get_last_purchase_rate",
|
||||
"doc": cur_frm.doc,
|
||||
callback: function(r, rt) {
|
||||
cur_frm.dirty();
|
||||
cur_frm.cscript.calculate_taxes_and_totals();
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
items_on_form_rendered: function() {
|
||||
set_schedule_date(this.frm);
|
||||
},
|
||||
|
||||
@@ -1207,7 +1207,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_bulk_edit": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1238,68 +1238,6 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus===0 && (doc.items && doc.items.length)",
|
||||
"fieldname": "get_last_purchase_rate",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Get last purchase rate",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus===0 && (doc.items && doc.items.length)",
|
||||
"fieldname": "link_to_mrs",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Link to material requests",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2440,6 +2378,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rounded_total",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounded Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2471,6 +2440,36 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "disable_rounded_total",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Disable Rounded Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -3355,7 +3354,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-17 11:00:05.037716",
|
||||
"modified": "2018-08-01 15:18:33.155409",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
|
||||
@@ -33,12 +33,6 @@ class PurchaseOrder(BuyingController):
|
||||
'percent_join_field': 'material_request'
|
||||
}]
|
||||
|
||||
def onload(self):
|
||||
super(PurchaseOrder, self).onload()
|
||||
|
||||
self.set_onload('disable_fetch_last_purchase_rate',
|
||||
cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")))
|
||||
|
||||
def validate(self):
|
||||
super(PurchaseOrder, self).validate()
|
||||
|
||||
@@ -122,7 +116,6 @@ class PurchaseOrder(BuyingController):
|
||||
|
||||
def get_last_purchase_rate(self):
|
||||
"""get last purchase rates for all items"""
|
||||
if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
|
||||
|
||||
conversion_rate = flt(self.get('conversion_rate')) or 1.0
|
||||
for d in self.get("items"):
|
||||
@@ -286,7 +279,6 @@ class PurchaseOrder(BuyingController):
|
||||
|
||||
def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor= 1.0):
|
||||
"""get last purchase rate for an item"""
|
||||
if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
|
||||
|
||||
conversion_rate = flt(conversion_rate) or 1.0
|
||||
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
QUnit.module('Buying');
|
||||
|
||||
QUnit.test("test: purchase order with last purchase rate", function(assert) {
|
||||
assert.expect(9);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{currency: 'INR'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 800},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
],
|
||||
[
|
||||
{"item_code": 'Test Product 1'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 400},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
|
||||
() => {
|
||||
// Get item details
|
||||
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item 1 name correct");
|
||||
assert.ok(cur_frm.doc.items[1].item_name == 'Test Product 1', "Item 2 name correct");
|
||||
},
|
||||
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(3),
|
||||
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{currency: 'INR'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 600},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
],
|
||||
[
|
||||
{"item_code": 'Test Product 1'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 200},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
|
||||
() => frappe.timeout(2),
|
||||
|
||||
// Get the last purchase rate of items
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.items[0].last_purchase_rate == 800, "Last purchase rate of item 1 correct");
|
||||
assert.ok(cur_frm.doc.items[1].last_purchase_rate != 0);
|
||||
},
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.items[1].last_purchase_rate == 400, "Last purchase rate of item 2 correct");
|
||||
assert.ok(cur_frm.doc.items[1].last_purchase_rate != 0);
|
||||
},
|
||||
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(3),
|
||||
|
||||
() => frappe.tests.click_button('Close'),
|
||||
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.status == 'To Receive and Bill', "Submitted successfully");
|
||||
},
|
||||
|
||||
// enable allow_last_purchase_rate
|
||||
() => {
|
||||
return frappe.tests.make('Buying Settings', [
|
||||
// values to be set
|
||||
{"disable_fetch_last_purchase_rate": 1}
|
||||
]);
|
||||
},
|
||||
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{currency: 'INR'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 800},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
],
|
||||
[
|
||||
{"item_code": 'Test Product 1'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 400},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
|
||||
() => {
|
||||
// Get item details
|
||||
assert.ok(cur_frm.doc.items[0].last_purchase_rate == 0);
|
||||
assert.ok(cur_frm.doc.items[1].last_purchase_rate == 0);
|
||||
},
|
||||
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(3),
|
||||
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
// enable allow_last_purchase_rate
|
||||
() => frappe.tests.make('Buying Settings', [
|
||||
// values to be set
|
||||
{"disable_fetch_last_purchase_rate": 0}
|
||||
]),
|
||||
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -629,6 +629,38 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "discount_percentage",
|
||||
"fieldname": "discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Discount Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -680,7 +712,7 @@
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
@@ -1897,7 +1929,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-14 09:36:40.837027",
|
||||
"modified": "2018-08-06 05:16:58.258276",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Item",
|
||||
|
||||
@@ -781,7 +781,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_bulk_edit": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1983,6 +1983,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rounded_total",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounded Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2014,6 +2045,36 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "disable_rounded_total",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Disable Rounded Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2171,6 +2232,65 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "group_same_items",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Group same items",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_72",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
@@ -2490,7 +2610,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-11-29 14:07:56.698355",
|
||||
"modified": "2018-08-01 15:18:23.265621",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation",
|
||||
|
||||
@@ -60,7 +60,12 @@ class SupplierQuotation(BuyingController):
|
||||
for rfq in rfq_list:
|
||||
doc = frappe.get_doc('Request for Quotation', rfq)
|
||||
doc_sup = frappe.get_all('Request for Quotation Supplier', filters=
|
||||
{'parent': doc.name, 'supplier': self.supplier}, fields=['name', 'quote_status'])[0]
|
||||
{'parent': doc.name, 'supplier': self.supplier}, fields=['name', 'quote_status'])
|
||||
|
||||
doc_sup = doc_sup[0] if doc_sup else None
|
||||
if not doc_sup:
|
||||
frappe.throw(_("Supplier {0} not found in {1}").format(self.supplier,
|
||||
"<a href='desk#Form/Request for Quotation/{0}'> Request for Quotation {0} </a>".format(doc.name)))
|
||||
|
||||
quote_status = _('Received')
|
||||
for item in doc.items:
|
||||
@@ -152,4 +157,4 @@ def make_quotation(source_name, target_doc=None):
|
||||
}
|
||||
}, target_doc)
|
||||
|
||||
return doclist
|
||||
return doclist
|
||||
|
||||
@@ -470,6 +470,38 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "discount_percentage",
|
||||
"fieldname": "discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Discount Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1645,7 +1677,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-01-25 15:04:40.171617",
|
||||
"modified": "2018-08-06 05:33:07.404385",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation Item",
|
||||
|
||||
@@ -291,14 +291,6 @@ def get_data():
|
||||
"label": _("Healthcare"),
|
||||
"hidden": 1
|
||||
},
|
||||
{
|
||||
"module_name": "Hub",
|
||||
"color": "#009248",
|
||||
"icon": "/assets/erpnext/images/hub_logo.svg",
|
||||
"type": "page",
|
||||
"link": "hub",
|
||||
"label": _("Hub")
|
||||
},
|
||||
{
|
||||
"module_name": "Data Import",
|
||||
"color": "#FFF168",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
source_link = "https://github.com/frappe/erpnext"
|
||||
source_link = "https://github.com/erpnext/foundation"
|
||||
|
||||
@@ -36,13 +36,13 @@ def get_data():
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Job Applicant",
|
||||
"description": _("Applicant for a Job."),
|
||||
"name": "Job Opening",
|
||||
"description": _("Opening for a Job."),
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Job Opening",
|
||||
"description": _("Opening for a Job."),
|
||||
"name": "Job Applicant",
|
||||
"description": _("Applicant for a Job."),
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
from frappe import _
|
||||
|
||||
def get_data():
|
||||
return [
|
||||
{
|
||||
"label": _("Setup"),
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Hub Settings"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Hub"),
|
||||
"items": [
|
||||
{
|
||||
"type": "page",
|
||||
"name": "hub"
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
@@ -82,7 +82,8 @@ class AccountsController(TransactionBase):
|
||||
self.validate_non_invoice_documents_schedule()
|
||||
|
||||
def before_print(self):
|
||||
if self.doctype in ['Purchase Order', 'Sales Order']:
|
||||
if self.doctype in ['Purchase Order', 'Sales Order', 'Sales Invoice', 'Purchase Invoice',
|
||||
'Supplier Quotation', 'Purchase Receipt', 'Delivery Note', 'Quotation']:
|
||||
if self.get("group_same_items"):
|
||||
self.group_similar_items()
|
||||
|
||||
@@ -130,14 +131,18 @@ class AccountsController(TransactionBase):
|
||||
self.meta.get_label(date_field), self)
|
||||
|
||||
def validate_due_date(self):
|
||||
if self.get('is_pos'): return
|
||||
|
||||
from erpnext.accounts.party import validate_due_date
|
||||
if self.doctype == "Sales Invoice":
|
||||
if not self.due_date:
|
||||
frappe.throw(_("Due Date is mandatory"))
|
||||
|
||||
validate_due_date(self.posting_date, self.due_date, "Customer", self.customer, self.company)
|
||||
validate_due_date(self.posting_date, self.due_date,
|
||||
"Customer", self.customer, self.company, self.payment_terms_template)
|
||||
elif self.doctype == "Purchase Invoice":
|
||||
validate_due_date(self.posting_date, self.due_date, "Supplier", self.supplier, self.company)
|
||||
validate_due_date(self.posting_date, self.due_date,
|
||||
"Supplier", self.supplier, self.company, self.payment_terms_template)
|
||||
|
||||
def set_price_list_currency(self, buying_or_selling):
|
||||
if self.meta.get_field("posting_date"):
|
||||
@@ -232,7 +237,7 @@ class AccountsController(TransactionBase):
|
||||
|
||||
tax_master_doctype = self.meta.get_field("taxes_and_charges").options
|
||||
|
||||
if self.is_new() and not self.get("taxes"):
|
||||
if (self.is_new() or self.is_pos_profile_changed()) and not self.get("taxes"):
|
||||
if self.company and not self.get("taxes_and_charges"):
|
||||
# get the default tax master
|
||||
self.taxes_and_charges = frappe.db.get_value(tax_master_doctype,
|
||||
@@ -240,6 +245,11 @@ class AccountsController(TransactionBase):
|
||||
|
||||
self.append_taxes_from_master(tax_master_doctype)
|
||||
|
||||
def is_pos_profile_changed(self):
|
||||
if (self.doctype == 'Sales Invoice' and self.is_pos and
|
||||
self.pos_profile != frappe.db.get_value('Sales Invoice', self.name, 'pos_profile')):
|
||||
return True
|
||||
|
||||
def append_taxes_from_master(self, tax_master_doctype=None):
|
||||
if self.get("taxes_and_charges"):
|
||||
if not tax_master_doctype:
|
||||
@@ -658,6 +668,7 @@ class AccountsController(TransactionBase):
|
||||
if item.item_code in group_item_qty:
|
||||
item.qty = group_item_qty[item.item_code]
|
||||
item.amount = group_item_amount[item.item_code]
|
||||
item.rate = flt(flt(item.amount)/flt(item.qty), item.precision("rate"))
|
||||
del group_item_qty[item.item_code]
|
||||
else:
|
||||
duplicate_list.append(item)
|
||||
|
||||
@@ -35,6 +35,7 @@ class BuyingController(StockController):
|
||||
if getattr(self, "supplier", None) and not self.supplier_name:
|
||||
self.supplier_name = frappe.db.get_value("Supplier", self.supplier, "supplier_name")
|
||||
|
||||
self.validate_items()
|
||||
self.set_qty_as_per_stock_uom()
|
||||
self.validate_stock_or_nonstock_items()
|
||||
self.validate_warehouse()
|
||||
@@ -98,9 +99,16 @@ class BuyingController(StockController):
|
||||
def set_total_in_words(self):
|
||||
from frappe.utils import money_in_words
|
||||
if self.meta.get_field("base_in_words"):
|
||||
self.base_in_words = money_in_words(self.base_grand_total, self.company_currency)
|
||||
amount = (self.base_rounded_total
|
||||
if not self.get("disable_rounded_total") else self.base_grand_total)
|
||||
|
||||
self.base_in_words = money_in_words(amount, self.company_currency)
|
||||
|
||||
if self.meta.get_field("in_words"):
|
||||
self.in_words = money_in_words(self.grand_total, self.currency)
|
||||
amount = (self.rounded_total
|
||||
if not self.get("disable_rounded_total") else self.grand_total)
|
||||
|
||||
self.in_words = money_in_words(amount, self.currency)
|
||||
|
||||
# update valuation rate
|
||||
def update_valuation_rate(self, parentfield):
|
||||
@@ -456,3 +464,32 @@ class BuyingController(StockController):
|
||||
else:
|
||||
frappe.throw(_("Please enter Reqd by Date"))
|
||||
|
||||
def validate_items(self):
|
||||
# validate items to see if they have is_purchase_item or is_subcontracted_item enabled
|
||||
if self.doctype=="Material Request": return
|
||||
|
||||
if hasattr(self, "is_subcontracted") and self.is_subcontracted == 'Yes':
|
||||
validate_item_type(self, "is_sub_contracted_item", "subcontracted")
|
||||
else:
|
||||
validate_item_type(self, "is_purchase_item", "purchase")
|
||||
|
||||
def validate_item_type(doc, fieldname, message):
|
||||
# iterate through items and check if they are valid sales or purchase items
|
||||
items = [d.item_code for d in doc.items if d.item_code]
|
||||
|
||||
# No validation check inase of creating transaction using 'Opening Invoice Creation Tool'
|
||||
if not items:
|
||||
return
|
||||
|
||||
item_list = ", ".join(["'%s'" % frappe.db.escape(d) for d in items])
|
||||
|
||||
invalid_items = [d[0] for d in frappe.db.sql("""
|
||||
select item_code from tabItem where name in ({0}) and {1}=0
|
||||
""".format(item_list, fieldname), as_list=True)]
|
||||
|
||||
if invalid_items:
|
||||
frappe.throw(_("Following item {items} {verb} not marked as {message} item.\
|
||||
You can enable them as {message} item from its Item master".format(
|
||||
items = ", ".join([d for d in invalid_items]),
|
||||
verb = "are" if len(invalid_items) > 1 else "is",
|
||||
message = message)))
|
||||
|
||||
@@ -176,6 +176,14 @@ def create_variant(item, args):
|
||||
@frappe.whitelist()
|
||||
def enqueue_multiple_variant_creation(item, args):
|
||||
# There can be innumerable attribute combinations, enqueue
|
||||
if isinstance(args, basestring):
|
||||
variants = json.loads(args)
|
||||
total_variants = 1
|
||||
for key in variants:
|
||||
total_variants *= len(variants[key])
|
||||
if total_variants >= 600:
|
||||
frappe.msgprint("Please do not create more than 500 items at a time", raise_exception=1)
|
||||
return
|
||||
frappe.enqueue("erpnext.controllers.item_variant.create_multiple_variants",
|
||||
item=item, args=args, now=frappe.flags.in_test);
|
||||
|
||||
|
||||
@@ -157,9 +157,10 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
|
||||
# scan description only if items are less than 50000
|
||||
description_cond = 'or tabItem.description LIKE %(txt)s'
|
||||
|
||||
return frappe.db.sql("""select tabItem.name, tabItem.item_group,
|
||||
return frappe.db.sql("""select tabItem.name,
|
||||
if(length(tabItem.item_name) > 40,
|
||||
concat(substr(tabItem.item_name, 1, 40), "..."), item_name) as item_name,
|
||||
tabItem.item_group,
|
||||
if(length(tabItem.description) > 40, \
|
||||
concat(substr(tabItem.description, 1, 40), "..."), description) as decription
|
||||
from tabItem
|
||||
@@ -217,7 +218,8 @@ def bom(doctype, txt, searchfield, start, page_len, filters):
|
||||
def get_project_name(doctype, txt, searchfield, start, page_len, filters):
|
||||
cond = ''
|
||||
if filters.get('customer'):
|
||||
cond = '(`tabProject`.customer = "' + filters['customer'] + '" or ifnull(`tabProject`.customer,"")="") and'
|
||||
cond = """(`tabProject`.customer = '%s' or
|
||||
ifnull(`tabProject`.customer,"")="") and""" %(frappe.db.escape(filters.get("customer")))
|
||||
|
||||
return frappe.db.sql("""select `tabProject`.name from `tabProject`
|
||||
where `tabProject`.status not in ("Completed", "Cancelled")
|
||||
|
||||
@@ -83,15 +83,15 @@ def validate_returned_items(doc):
|
||||
else:
|
||||
ref = valid_items.get(d.item_code, frappe._dict())
|
||||
validate_quantity(doc, d, ref, valid_items, already_returned_items)
|
||||
|
||||
|
||||
if ref.rate and doc.doctype in ("Delivery Note", "Sales Invoice") and flt(d.rate) > ref.rate:
|
||||
frappe.throw(_("Row # {0}: Rate cannot be greater than the rate used in {1} {2}")
|
||||
.format(d.idx, doc.doctype, doc.return_against))
|
||||
|
||||
|
||||
elif ref.batch_no and d.batch_no not in ref.batch_no:
|
||||
frappe.throw(_("Row # {0}: Batch No must be same as {1} {2}")
|
||||
.format(d.idx, doc.doctype, doc.return_against))
|
||||
|
||||
|
||||
elif ref.serial_no:
|
||||
if not d.serial_no:
|
||||
frappe.throw(_("Row # {0}: Serial No is mandatory").format(d.idx))
|
||||
@@ -120,25 +120,30 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items):
|
||||
|
||||
for column in fields:
|
||||
returned_qty = flt(already_returned_data.get(column, 0)) if len(already_returned_data) > 0 else 0
|
||||
reference_qty = (ref.get(column) if column == 'stock_qty'
|
||||
else ref.get(column) * ref.get("conversion_factor", 1.0))
|
||||
|
||||
if column == 'stock_qty':
|
||||
reference_qty = ref.get(column)
|
||||
current_stock_qty = args.get(column)
|
||||
else:
|
||||
reference_qty = ref.get(column) * ref.get("conversion_factor", 1.0)
|
||||
current_stock_qty = args.get(column) * args.get("conversion_factor", 1.0)
|
||||
|
||||
max_returnable_qty = flt(reference_qty) - returned_qty
|
||||
label = column.replace('_', ' ').title()
|
||||
|
||||
if reference_qty:
|
||||
if reference_qty:
|
||||
if flt(args.get(column)) > 0:
|
||||
frappe.throw(_("{0} must be negative in return document").format(label))
|
||||
elif returned_qty >= reference_qty and args.get(column):
|
||||
frappe.throw(_("Item {0} has already been returned")
|
||||
.format(args.item_code), StockOverReturnError)
|
||||
elif (abs(args.get(column)) * args.get("conversion_factor", 1.0)) > max_returnable_qty:
|
||||
elif abs(current_stock_qty) > max_returnable_qty:
|
||||
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
|
||||
.format(args.idx, reference_qty, args.item_code), StockOverReturnError)
|
||||
.format(args.idx, max_returnable_qty, args.item_code), StockOverReturnError)
|
||||
|
||||
def get_ref_item_dict(valid_items, ref_item_row):
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
|
||||
|
||||
valid_items.setdefault(ref_item_row.item_code, frappe._dict({
|
||||
"qty": 0,
|
||||
"rate": 0,
|
||||
@@ -146,6 +151,7 @@ def get_ref_item_dict(valid_items, ref_item_row):
|
||||
"rejected_qty": 0,
|
||||
"received_qty": 0,
|
||||
"serial_no": [],
|
||||
"conversion_factor": ref_item_row.get("conversion_factor", 1),
|
||||
"batch_no": []
|
||||
}))
|
||||
item_dict = valid_items[ref_item_row.item_code]
|
||||
@@ -160,10 +166,10 @@ def get_ref_item_dict(valid_items, ref_item_row):
|
||||
|
||||
if ref_item_row.get("serial_no"):
|
||||
item_dict["serial_no"] += get_serial_nos(ref_item_row.serial_no)
|
||||
|
||||
|
||||
if ref_item_row.get("batch_no"):
|
||||
item_dict["batch_no"].append(ref_item_row.batch_no)
|
||||
|
||||
|
||||
return valid_items
|
||||
|
||||
def get_already_returned_items(doc):
|
||||
|
||||
@@ -35,6 +35,7 @@ class SellingController(StockController):
|
||||
|
||||
def validate(self):
|
||||
super(SellingController, self).validate()
|
||||
self.validate_items()
|
||||
self.validate_max_discount()
|
||||
self.validate_selling_price()
|
||||
self.set_qty_as_per_stock_uom()
|
||||
@@ -51,9 +52,15 @@ class SellingController(StockController):
|
||||
def set_missing_lead_customer_details(self):
|
||||
if getattr(self, "customer", None):
|
||||
from erpnext.accounts.party import _get_party_details
|
||||
fetch_payment_terms_template = False
|
||||
if (self.get("__islocal") or
|
||||
self.company != frappe.db.get_value(self.doctype, self.name, 'company')):
|
||||
fetch_payment_terms_template = True
|
||||
|
||||
party_details = _get_party_details(self.customer,
|
||||
ignore_permissions=self.flags.ignore_permissions,
|
||||
doctype=self.doctype, company=self.company)
|
||||
doctype=self.doctype, company=self.company,
|
||||
fetch_payment_terms_template=fetch_payment_terms_template)
|
||||
if not self.meta.get_field("sales_team"):
|
||||
party_details.pop("sales_team")
|
||||
|
||||
@@ -337,6 +344,11 @@ class SellingController(StockController):
|
||||
po_nos = frappe.get_all('Sales Order', 'po_no', filters = {'name': ('in', sales_orders)})
|
||||
self.po_no = ', '.join(list(set([d.po_no for d in po_nos if d.po_no])))
|
||||
|
||||
def validate_items(self):
|
||||
# validate items to see if they have is_sales_item enabled
|
||||
from erpnext.controllers.buying_controller import validate_item_type
|
||||
validate_item_type(self, "is_sales_item", "sales")
|
||||
|
||||
def check_active_sales_items(obj):
|
||||
for d in obj.get("items"):
|
||||
if d.item_code:
|
||||
|
||||
@@ -29,6 +29,7 @@ class calculate_taxes_and_totals(object):
|
||||
self.set_item_wise_tax_breakup()
|
||||
|
||||
def _calculate(self):
|
||||
self.validate_conversion_rate()
|
||||
self.calculate_item_values()
|
||||
self.initialize_taxes()
|
||||
self.determine_exclusive_rate()
|
||||
@@ -37,6 +38,7 @@ class calculate_taxes_and_totals(object):
|
||||
self.manipulate_grand_total_for_inclusive_tax()
|
||||
self.calculate_totals()
|
||||
self._cleanup()
|
||||
self.calculate_total_net_weight()
|
||||
|
||||
def validate_conversion_rate(self):
|
||||
# validate conversion rate
|
||||
@@ -327,6 +329,13 @@ class calculate_taxes_and_totals(object):
|
||||
|
||||
self.set_rounded_total()
|
||||
|
||||
def calculate_total_net_weight(self):
|
||||
if self.doc.meta.get_field('total_net_weight'):
|
||||
self.doc.total_net_weight = 0.0
|
||||
for d in self.doc.items:
|
||||
if d.total_weight:
|
||||
self.doc.total_net_weight += d.total_weight
|
||||
|
||||
def set_rounded_total(self):
|
||||
if self.doc.meta.get_field("rounded_total"):
|
||||
if self.doc.is_rounded_total_disabled():
|
||||
@@ -557,7 +566,8 @@ def get_itemised_tax_breakup_html(doc):
|
||||
itemised_tax=itemised_tax,
|
||||
itemised_taxable_amount=itemised_taxable_amount,
|
||||
tax_accounts=tax_accounts,
|
||||
company_currency=erpnext.get_company_currency(doc.company)
|
||||
conversion_rate=doc.conversion_rate,
|
||||
currency=doc.currency
|
||||
)
|
||||
)
|
||||
|
||||
@@ -590,16 +600,19 @@ def get_itemised_tax(taxes):
|
||||
for item_code, tax_data in item_tax_map.items():
|
||||
itemised_tax.setdefault(item_code, frappe._dict())
|
||||
|
||||
tax_rate = 0.0
|
||||
tax_amount = 0.0
|
||||
|
||||
if isinstance(tax_data, list):
|
||||
itemised_tax[item_code][tax.description] = frappe._dict(dict(
|
||||
tax_rate=flt(tax_data[0]),
|
||||
tax_amount=flt(tax_data[1])
|
||||
))
|
||||
tax_rate = flt(tax_data[0])
|
||||
tax_amount = flt(tax_data[1])
|
||||
else:
|
||||
itemised_tax[item_code][tax.description] = frappe._dict(dict(
|
||||
tax_rate=flt(tax_data),
|
||||
tax_amount=0.0
|
||||
))
|
||||
tax_rate = flt(tax_data)
|
||||
|
||||
itemised_tax[item_code][tax.description] = frappe._dict(dict(
|
||||
tax_rate = tax_rate,
|
||||
tax_amount = tax_amount
|
||||
))
|
||||
|
||||
return itemised_tax
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ frappe.ui.form.on("Opportunity", {
|
||||
frm.trigger('set_contact_link');
|
||||
},
|
||||
|
||||
with_items: function(frm) {
|
||||
frm.trigger('toggle_mandatory');
|
||||
},
|
||||
|
||||
customer_address: function(frm, cdt, cdn) {
|
||||
erpnext.utils.get_address_display(frm, 'customer_address', 'address_display', false);
|
||||
},
|
||||
@@ -35,6 +39,7 @@ frappe.ui.form.on("Opportunity", {
|
||||
var doc = frm.doc;
|
||||
frm.events.enquiry_from(frm);
|
||||
frm.trigger('set_contact_link');
|
||||
frm.trigger('toggle_mandatory');
|
||||
erpnext.toggle_naming_series();
|
||||
|
||||
if(!doc.__islocal && doc.status!=="Lost") {
|
||||
@@ -84,6 +89,10 @@ frappe.ui.form.on("Opportunity", {
|
||||
method: "erpnext.crm.doctype.opportunity.opportunity.make_supplier_quotation",
|
||||
frm: cur_frm
|
||||
})
|
||||
},
|
||||
|
||||
toggle_mandatory: function(frm) {
|
||||
frm.toggle_reqd("items", frm.doc.with_items ? 1:0);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -51,12 +51,12 @@ def enroll_random_student(current_date):
|
||||
|
||||
def assign_student_group(student, student_name, program, courses, batch):
|
||||
course_list = [d["course"] for d in courses]
|
||||
for d in frappe.get_list("Student Group", fields=("name"), filters={"program": program, "course":("in", course_list)}):
|
||||
for d in frappe.get_list("Student Group", fields=("name"), filters={"program": program, "course":("in", course_list), "disabled": 0}):
|
||||
student_group = frappe.get_doc("Student Group", d.name)
|
||||
student_group.append("students", {"student": student, "student_name": student_name,
|
||||
"group_roll_number":len(student_group.students)+1, "active":1})
|
||||
student_group.save()
|
||||
student_batch = frappe.get_list("Student Group", fields=("name"), filters={"program": program, "group_based_on":"Batch", "batch":batch})[0]
|
||||
student_batch = frappe.get_list("Student Group", fields=("name"), filters={"program": program, "group_based_on":"Batch", "batch":batch, "disabled": 0})[0]
|
||||
student_batch_doc = frappe.get_doc("Student Group", student_batch.name)
|
||||
student_batch_doc.append("students", {"student": student, "student_name": student_name,
|
||||
"group_roll_number":len(student_batch_doc.students)+1, "active":1})
|
||||
@@ -65,7 +65,7 @@ def assign_student_group(student, student_name, program, courses, batch):
|
||||
|
||||
def mark_student_attendance(current_date):
|
||||
status = ["Present", "Absent"]
|
||||
for d in frappe.db.get_list("Student Group", filters={"group_based_on": "Batch"}):
|
||||
for d in frappe.db.get_list("Student Group", filters={"group_based_on": "Batch", "disabled": 0}):
|
||||
students = get_student_group_students(d.name)
|
||||
for stud in students:
|
||||
make_attendance_records(stud.student, stud.student_name, status[weighted_choice([9,4])], None, d.name, current_date)
|
||||
@@ -77,7 +77,7 @@ def make_fees():
|
||||
|
||||
def make_assessment_plan(date):
|
||||
for d in range(1,4):
|
||||
random_group = get_random("Student Group", {"group_based_on": "Course"}, True)
|
||||
random_group = get_random("Student Group", {"group_based_on": "Course", "disabled": 0}, True)
|
||||
doc = frappe.new_doc("Assessment Plan")
|
||||
doc.student_group = random_group.name
|
||||
doc.course = random_group.course
|
||||
|
||||
@@ -4,7 +4,7 @@ We can also send the feedback request to Customer/User without configuring the
|
||||
Feedback Trigger.
|
||||
|
||||
To request a feedback manually go to respective document e.g. Sales Order, Issue etc.
|
||||
and click on Ask a Feedback option in Menu.
|
||||
and click on Request Feedback option in Menu.
|
||||
|
||||
<img class="screenshot" alt="Setting Condition" src="/docs/assets/img/setup/feedback/manual-feedback-request-option.png">
|
||||
|
||||
|
||||
@@ -88,16 +88,14 @@ def make_attendance_records(student, student_name, status, course_schedule=None,
|
||||
:param course_schedule: Course Schedule.
|
||||
:param status: Status (Present/Absent)
|
||||
"""
|
||||
student_attendance_list = frappe.get_list("Student Attendance", fields = ['name'], filters = {
|
||||
student_attendance = frappe.get_doc({
|
||||
"doctype": "Student Attendance",
|
||||
"student": student,
|
||||
"course_schedule": course_schedule,
|
||||
"student_group": student_group,
|
||||
"date": date
|
||||
})
|
||||
|
||||
if student_attendance_list:
|
||||
student_attendance = frappe.get_doc("Student Attendance", student_attendance_list[0])
|
||||
else:
|
||||
if not student_attendance:
|
||||
student_attendance = frappe.new_doc("Student Attendance")
|
||||
student_attendance.student = student
|
||||
student_attendance.student_name = student_name
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "RES.######",
|
||||
"beta": 0,
|
||||
@@ -662,7 +662,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-01-09 14:14:30.090317",
|
||||
"modified": "2018-08-20 11:21:19.248393",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Assessment Result",
|
||||
|
||||
@@ -195,6 +195,38 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"description": "If enabled, field Academic Term will be Mandatory in Program Enrollment Tool.",
|
||||
"fieldname": "academic_term_reqd",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Make Academic Term Mandatory",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -267,7 +299,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-28 15:45:30.324324",
|
||||
"modified": "2018-07-26 04:43:35.406690",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Education Settings",
|
||||
|
||||
@@ -31,7 +31,8 @@ frappe.ui.form.on('Fee Schedule', {
|
||||
return {
|
||||
"program": frm.doc.program,
|
||||
"academic_term": frm.doc.academic_term,
|
||||
"academic_year": frm.doc.academic_year
|
||||
"academic_year": frm.doc.academic_year,
|
||||
"disabled": 0
|
||||
};
|
||||
});
|
||||
frappe.realtime.on("fee_schedule_progress", function(data) {
|
||||
|
||||
@@ -671,7 +671,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-12-27 10:59:36.838548",
|
||||
"modified": "2018-07-26 04:44:03.781418",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Program Enrollment",
|
||||
|
||||
@@ -26,7 +26,6 @@ class ProgramEnrollment(Document):
|
||||
"student": self.student,
|
||||
"program": self.program,
|
||||
"academic_year": self.academic_year,
|
||||
"academic_term": self.academic_term,
|
||||
"docstatus": ("<", 2),
|
||||
"name": ("!=", self.name)
|
||||
})
|
||||
@@ -86,7 +85,6 @@ def get_program_courses(doctype, txt, searchfield, start, page_len, filters):
|
||||
"program": filters['program']
|
||||
})
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_students(doctype, txt, searchfield, start, page_len, filters):
|
||||
if not filters.get("academic_term"):
|
||||
|
||||
@@ -5,6 +5,9 @@ frappe.ui.form.on("Program Enrollment Tool", {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch("student", "title", "student_name");
|
||||
frm.add_fetch("student_applicant", "title", "student_name");
|
||||
if(frm.doc.__onload && frm.doc.__onload.academic_term_reqd) {
|
||||
frm.toggle_reqd("academic_term", true);
|
||||
}
|
||||
},
|
||||
|
||||
"refresh": function(frm) {
|
||||
|
||||
@@ -513,7 +513,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-01-02 11:59:40.230689",
|
||||
"modified": "2018-07-26 04:44:13.232146",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Program Enrollment Tool",
|
||||
|
||||
@@ -7,8 +7,13 @@ import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from erpnext.education.api import enroll_student
|
||||
from frappe.utils import cint
|
||||
|
||||
class ProgramEnrollmentTool(Document):
|
||||
def onload(self):
|
||||
academic_term_reqd = cint(frappe.db.get_single_value('Education Settings', 'academic_term_reqd'))
|
||||
self.set_onload("academic_term_reqd", academic_term_reqd)
|
||||
|
||||
def get_students(self):
|
||||
students = []
|
||||
if not self.get_students_from:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "SA.######",
|
||||
"autoname": "",
|
||||
"beta": 0,
|
||||
"creation": "2015-11-05 15:20:23.045996",
|
||||
"custom": 0,
|
||||
@@ -40,7 +40,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -101,7 +101,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -239,7 +239,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-10 19:09:51.041960",
|
||||
"modified": "2018-07-27 10:48:22.301531",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Student Attendance",
|
||||
|
||||
@@ -7,7 +7,8 @@ frappe.ui.form.on('Student Attendance Tool', {
|
||||
frm.set_query("student_group", function() {
|
||||
return {
|
||||
"filters": {
|
||||
"group_based_on": frm.doc.group_based_on
|
||||
"group_based_on": frm.doc.group_based_on,
|
||||
"disabled": 0
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -82,36 +82,39 @@ frappe.ui.form.on("Student Group", {
|
||||
max_roll_no = d.group_roll_number;
|
||||
}
|
||||
});
|
||||
frappe.call({
|
||||
method: "erpnext.education.doctype.student_group.student_group.get_students",
|
||||
args: {
|
||||
"academic_year": frm.doc.academic_year,
|
||||
"academic_term": frm.doc.academic_term,
|
||||
"group_based_on": frm.doc.group_based_on,
|
||||
"program": frm.doc.program,
|
||||
"batch" : frm.doc.batch,
|
||||
"course": frm.doc.course
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
$.each(r.message, function(i, d) {
|
||||
if(!in_list(student_list, d.student)) {
|
||||
var s = frm.add_child("students");
|
||||
s.student = d.student;
|
||||
s.student_name = d.student_name;
|
||||
if (d.active === 0) {
|
||||
s.active = 0;
|
||||
|
||||
if(frm.doc.academic_year) {
|
||||
frappe.call({
|
||||
method: "erpnext.education.doctype.student_group.student_group.get_students",
|
||||
args: {
|
||||
"academic_year": frm.doc.academic_year,
|
||||
"academic_term": frm.doc.academic_term,
|
||||
"group_based_on": frm.doc.group_based_on,
|
||||
"program": frm.doc.program,
|
||||
"batch" : frm.doc.batch,
|
||||
"course": frm.doc.course
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
$.each(r.message, function(i, d) {
|
||||
if(!in_list(student_list, d.student)) {
|
||||
var s = frm.add_child("students");
|
||||
s.student = d.student;
|
||||
s.student_name = d.student_name;
|
||||
if (d.active === 0) {
|
||||
s.active = 0;
|
||||
}
|
||||
s.group_roll_number = ++max_roll_no;
|
||||
}
|
||||
s.group_roll_number = ++max_roll_no;
|
||||
}
|
||||
});
|
||||
refresh_field("students");
|
||||
frm.save();
|
||||
} else {
|
||||
frappe.msgprint(__("Student Group is already updated."))
|
||||
});
|
||||
refresh_field("students");
|
||||
frm.save();
|
||||
} else {
|
||||
frappe.msgprint(__("Student Group is already updated."))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
frappe.msgprint(__("Select students manually for the Activity based Group"));
|
||||
}
|
||||
|
||||
@@ -293,6 +293,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Disabled",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -459,7 +490,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-11-10 19:09:37.370864",
|
||||
"modified": "2018-07-26 04:17:10.836912",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Student Group",
|
||||
|
||||
@@ -33,7 +33,7 @@ class StudentGroup(Document):
|
||||
program_enrollment = get_program_enrollment(self.academic_year, self.academic_term, self.program, self.batch, self.course)
|
||||
students = [d.student for d in program_enrollment] if program_enrollment else []
|
||||
for d in self.students:
|
||||
if not frappe.db.get_value("Student", d.student, "enabled") and d.active:
|
||||
if not frappe.db.get_value("Student", d.student, "enabled") and d.active and not self.disabled:
|
||||
frappe.throw(_("{0} - {1} is inactive student".format(d.group_roll_number, d.student_name)))
|
||||
|
||||
if (self.group_based_on == "Batch") and cint(frappe.defaults.get_defaults().validate_batch)\
|
||||
|
||||
@@ -24,7 +24,7 @@ frappe.ui.form.on('Student Report Generation Tool', {
|
||||
frm.page.clear_indicator();
|
||||
frm.page.set_primary_action(__('Print Report Card'), () => {
|
||||
let url = "/api/method/erpnext.education.doctype.student_report_generation_tool.student_report_generation_tool.preview_report_card";
|
||||
open_url_post(url, frm.doc, true);
|
||||
open_url_post(url, {"doc": frm.doc}, true);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, json
|
||||
from frappe.model.document import Document
|
||||
from erpnext.education.api import get_grade
|
||||
from frappe.utils.pdf import get_pdf
|
||||
@@ -16,8 +16,8 @@ class StudentReportGenerationTool(Document):
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def preview_report_card(**kwargs):
|
||||
doc = frappe._dict(**kwargs)
|
||||
def preview_report_card(doc):
|
||||
doc = frappe._dict(json.loads(doc))
|
||||
doc.students = [doc.student]
|
||||
if not (doc.student_name and doc.student_batch):
|
||||
program_enrollment = frappe.get_all("Program Enrollment", fields=["student_batch_name", "student_name"],
|
||||
@@ -33,7 +33,7 @@ def preview_report_card(**kwargs):
|
||||
course_criteria = get_courses_criteria(courses)
|
||||
|
||||
# get the assessment group as per the user selection
|
||||
if int(doc.include_all_assessment):
|
||||
if doc.include_all_assessment:
|
||||
assessment_groups = get_child_assessment_groups(doc.assessment_group)
|
||||
else:
|
||||
assessment_groups = [doc.assessment_group]
|
||||
@@ -55,7 +55,7 @@ def preview_report_card(**kwargs):
|
||||
"assessment_groups": assessment_groups,
|
||||
"course_criteria": course_criteria,
|
||||
"letterhead": letterhead.content,
|
||||
"add_letterhead": int(doc.add_letterhead) if int(doc.add_letterhead) else 0
|
||||
"add_letterhead": doc.add_letterhead if doc.add_letterhead else 0
|
||||
})
|
||||
final_template = frappe.render_template(base_template_path, {"body": html, "title": "Report Card"})
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ def get_guardian_map(student_list):
|
||||
|
||||
def get_student_roll_no(academic_year, program, batch):
|
||||
student_group = frappe.get_all("Student Group",
|
||||
filters={"academic_year":academic_year, "program":program, "batch":batch})
|
||||
filters={"academic_year":academic_year, "program":program, "batch":batch, "disabled": 0})
|
||||
if student_group:
|
||||
roll_no_dict = dict(frappe.db.sql('''select student, group_roll_number from `tabStudent Group Student` where parent=%s''',
|
||||
(student_group[0].name)))
|
||||
|
||||
@@ -73,6 +73,7 @@ def get_attendance_list(from_date, to_date, student_group, students_list):
|
||||
return att_map
|
||||
|
||||
def get_students_with_leave_application(from_date, to_date, students_list):
|
||||
if not students_list: return
|
||||
leave_applications = frappe.db.sql("""
|
||||
select student, from_date, to_date
|
||||
from `tabStudent Leave Application`
|
||||
|
||||
@@ -6,7 +6,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import getdate
|
||||
from frappe.utils import getdate, cstr
|
||||
import json
|
||||
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
|
||||
|
||||
@@ -113,9 +113,11 @@ def insert_consultation_to_medical_record(doc):
|
||||
|
||||
def update_consultation_to_medical_record(consultation):
|
||||
medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s", (consultation.name))
|
||||
if(medical_record_id[0][0]):
|
||||
if medical_record_id and medical_record_id[0][0]:
|
||||
subject = set_subject_field(consultation)
|
||||
frappe.db.set_value("Patient Medical Record", medical_record_id[0][0], "subject", subject)
|
||||
else:
|
||||
insert_consultation_to_medical_record(consultation)
|
||||
|
||||
def delete_medical_record(consultation):
|
||||
frappe.db.sql("""delete from `tabPatient Medical Record` where reference_name = %s""", (consultation.name))
|
||||
@@ -123,7 +125,7 @@ def delete_medical_record(consultation):
|
||||
def set_subject_field(consultation):
|
||||
subject = "No Diagnosis "
|
||||
if(consultation.diagnosis):
|
||||
subject = "Diagnosis: \n"+ str(consultation.diagnosis)+". "
|
||||
subject = "Diagnosis: \n"+ cstr(consultation.diagnosis)+". "
|
||||
if(consultation.drug_prescription):
|
||||
subject +="\nDrug(s) Prescribed. "
|
||||
if(consultation.test_prescription):
|
||||
|
||||
@@ -6,7 +6,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
import json
|
||||
from frappe.utils import getdate
|
||||
from frappe.utils import getdate, cstr
|
||||
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account
|
||||
from frappe import _
|
||||
|
||||
@@ -228,9 +228,9 @@ def get_employee_by_user_id(user_id):
|
||||
return employee
|
||||
|
||||
def insert_lab_test_to_medical_record(doc):
|
||||
subject = str(doc.test_name)
|
||||
subject = cstr(doc.test_name)
|
||||
if(doc.test_comment):
|
||||
subject += ", \n"+str(doc.test_comment)
|
||||
subject += ", \n"+ cstr(doc.test_comment)
|
||||
medical_record = frappe.new_doc("Patient Medical Record")
|
||||
medical_record.patient = doc.patient
|
||||
medical_record.subject = subject
|
||||
@@ -244,7 +244,7 @@ def insert_lab_test_to_medical_record(doc):
|
||||
def delete_lab_test_from_medical_record(self):
|
||||
medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s",(self.name))
|
||||
|
||||
if(medical_record_id[0][0]):
|
||||
if medical_record_id and medical_record_id[0][0]:
|
||||
frappe.delete_doc("Patient Medical Record", medical_record_id[0][0])
|
||||
|
||||
def create_item_line(test_code, sales_invoice):
|
||||
|
||||
@@ -34,7 +34,7 @@ class LabTestTemplate(Document):
|
||||
# remove template refernce from item and disable item
|
||||
if(self.item):
|
||||
try:
|
||||
frappe.delete_doc("Item",self.item)
|
||||
frappe.delete_doc("Item",self.item, force=True)
|
||||
except Exception:
|
||||
frappe.throw("""Not permitted. Please disable the Test Template""")
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ frappe.ui.form.on('Patient Appointment', {
|
||||
frm.set_value('appointment_time', selected_slot);
|
||||
frm.set_value('duration', data.time_per_appointment);
|
||||
d.hide();
|
||||
frm.enable_save();
|
||||
frm.save();
|
||||
}
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user