Compare commits
230 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9bfb64cd9 | ||
|
|
8470b39d4c | ||
|
|
932423ecba | ||
|
|
1c09a991f3 | ||
|
|
fcc0246b38 | ||
|
|
3ce41d6b1f | ||
|
|
470535ae9b | ||
|
|
a1923574c6 | ||
|
|
ef027e9030 | ||
|
|
bd8c7d683b | ||
|
|
fd37516165 | ||
|
|
504eba7fb2 | ||
|
|
e15721df48 | ||
|
|
c482aeda1a | ||
|
|
8811cc6b5b | ||
|
|
61165127fc | ||
|
|
d71a1c5e67 | ||
|
|
fb73621db2 | ||
|
|
3df7eef6cc | ||
|
|
b674d27285 | ||
|
|
949fbc559e | ||
|
|
1117125841 | ||
|
|
e94c6e7b8e | ||
|
|
c75becc42c | ||
|
|
ed5543adda | ||
|
|
a1c23a584d | ||
|
|
589927b37d | ||
|
|
2afb9b96cd | ||
|
|
8c9fb76854 | ||
|
|
0da9bc6309 | ||
|
|
5a8a5b7d06 | ||
|
|
71373a176d | ||
|
|
1b6270ef40 | ||
|
|
ac28ffb41e | ||
|
|
0e6ac8b9b4 | ||
|
|
07ef5f42c4 | ||
|
|
7b04f092a6 | ||
|
|
c98f37f91c | ||
|
|
b6a8920489 | ||
|
|
f26dcbc1a6 | ||
|
|
ecd46588ec | ||
|
|
96c247c834 | ||
|
|
db8f41ba55 | ||
|
|
f7d81c7a7f | ||
|
|
5b73a4864a | ||
|
|
85622f9ccb | ||
|
|
c27d9f712b | ||
|
|
175646572a | ||
|
|
7cfacb315b | ||
|
|
d5d8db7a3f | ||
|
|
39bcb3de4b | ||
|
|
09fe8e0522 | ||
|
|
17737e4ab1 | ||
|
|
2fca72ae8e | ||
|
|
0dbe8547e7 | ||
|
|
e1ed5ba726 | ||
|
|
0fc57a7df2 | ||
|
|
c7a72684fd | ||
|
|
e0c34bfd77 | ||
|
|
020dedd00e | ||
|
|
28dad095fa | ||
|
|
e7125c0ea2 | ||
|
|
8590d5b05d | ||
|
|
66951e528f | ||
|
|
9b20e07431 | ||
|
|
d7afa69c6f | ||
|
|
c61dc9c7ea | ||
|
|
9cf6d630e9 | ||
|
|
5687e2da9d | ||
|
|
e3c122d8c4 | ||
|
|
4cc5e61f60 | ||
|
|
6293263095 | ||
|
|
810e483757 | ||
|
|
398f144833 | ||
|
|
e2741e85fd | ||
|
|
dd70fbfdae | ||
|
|
6eaf281b2b | ||
|
|
134487ab2a | ||
|
|
7bd7df3742 | ||
|
|
56c1b2a625 | ||
|
|
b12e15dcc4 | ||
|
|
e5fdd47fd8 | ||
|
|
04c69fb46d | ||
|
|
f04ef8dfe0 | ||
|
|
7544904857 | ||
|
|
c44910370b | ||
|
|
551406ab11 | ||
|
|
e385b5b97b | ||
|
|
bb2670d57a | ||
|
|
0b293133be | ||
|
|
83c1c3a171 | ||
|
|
c3d642e5d1 | ||
|
|
8230ce095f | ||
|
|
e713a7d840 | ||
|
|
557847a5ba | ||
|
|
9bac58cdc6 | ||
|
|
5650bf9ba5 | ||
|
|
9afb53203f | ||
|
|
825e053e66 | ||
|
|
3e519770de | ||
|
|
e42fb32f6f | ||
|
|
00bec1c272 | ||
|
|
68ae9f3f88 | ||
|
|
8f3cc81302 | ||
|
|
9e9d242a24 | ||
|
|
287fe81329 | ||
|
|
24053478a1 | ||
|
|
f382373cf4 | ||
|
|
61f4a8e757 | ||
|
|
eef55185fc | ||
|
|
8691e0777b | ||
|
|
2de3bf7a0f | ||
|
|
2e6f12b850 | ||
|
|
ba41242f1f | ||
|
|
0633df5872 | ||
|
|
f4f774d1df | ||
|
|
695327a513 | ||
|
|
019501e4a0 | ||
|
|
2704162f5a | ||
|
|
117be7ddd5 | ||
|
|
f59920500c | ||
|
|
8a01980757 | ||
|
|
5123a8519b | ||
|
|
d7de3c606b | ||
|
|
dc981dc546 | ||
|
|
ed019123e2 | ||
|
|
4d1cf53466 | ||
|
|
e2431fd5e9 | ||
|
|
d12a4f5e8c | ||
|
|
ad65be8250 | ||
|
|
ae30026005 | ||
|
|
54c4240d9c | ||
|
|
79683d0871 | ||
|
|
a6d1876958 | ||
|
|
346928f2bc | ||
|
|
310d238d17 | ||
|
|
5e25731188 | ||
|
|
83ca262e38 | ||
|
|
8a2e6f427b | ||
|
|
8371c1c4cd | ||
|
|
361e7f6ddc | ||
|
|
798fd3484f | ||
|
|
22cedeb006 | ||
|
|
83c8ed0827 | ||
|
|
e3c117e32c | ||
|
|
68a8b0c2a9 | ||
|
|
307543f968 | ||
|
|
6681b0d2aa | ||
|
|
54d9c9eaf4 | ||
|
|
9b11d9b45d | ||
|
|
cca55ddc33 | ||
|
|
1c68509426 | ||
|
|
1e05077b1f | ||
|
|
b81244342f | ||
|
|
8e92250798 | ||
|
|
d20ec25c92 | ||
|
|
25bcb14c1d | ||
|
|
f6149f1507 | ||
|
|
2f3585f949 | ||
|
|
ed8ad9cfee | ||
|
|
3a2727c9eb | ||
|
|
16d92e7270 | ||
|
|
8c7eb444ef | ||
|
|
9a0efc7710 | ||
|
|
3ddfce4f17 | ||
|
|
a236f4e586 | ||
|
|
0b62c6ebd4 | ||
|
|
40ca4c3bbb | ||
|
|
c454dc7af5 | ||
|
|
994cef5ee3 | ||
|
|
185762aeeb | ||
|
|
1b32d913a2 | ||
|
|
64f29f819a | ||
|
|
2efe05c1ce | ||
|
|
17c675547d | ||
|
|
a220e96867 | ||
|
|
e471b02172 | ||
|
|
19f90e984e | ||
|
|
b5608f9b14 | ||
|
|
5adce495aa | ||
|
|
66272a168d | ||
|
|
2192c244c0 | ||
|
|
141c244ece | ||
|
|
a57b020620 | ||
|
|
d1fda1ff2b | ||
|
|
b9d0e7622a | ||
|
|
2f9703c20e | ||
|
|
46b6d4ea47 | ||
|
|
417145bec5 | ||
|
|
1ff1368280 | ||
|
|
768a888bf2 | ||
|
|
8037a0e3d5 | ||
|
|
0b665ac791 | ||
|
|
87ad6d074a | ||
|
|
95108ac80b | ||
|
|
9b9777be3f | ||
|
|
075b299673 | ||
|
|
e0271a8331 | ||
|
|
3fc3305251 | ||
|
|
236f7aac7f | ||
|
|
29ee263093 | ||
|
|
4782e8b751 | ||
|
|
b58979fd3e | ||
|
|
9365641777 | ||
|
|
5e9d72d57b | ||
|
|
0d230afd22 | ||
|
|
a906b3f11c | ||
|
|
aa6f00c403 | ||
|
|
d681c88d79 | ||
|
|
fc11fce990 | ||
|
|
faf51d91b6 | ||
|
|
08a42e00ae | ||
|
|
549a2827e5 | ||
|
|
9264313f0e | ||
|
|
8013d1813a | ||
|
|
ffc807cd57 | ||
|
|
ba6559c2e9 | ||
|
|
7eea52d4e9 | ||
|
|
93a990f006 | ||
|
|
2861955632 | ||
|
|
099163b16d | ||
|
|
0d114b4c31 | ||
|
|
fcf34dc570 | ||
|
|
6f038bc1f3 | ||
|
|
9300013acc | ||
|
|
8d8cba7faa | ||
|
|
2d132e32aa | ||
|
|
2e47654f43 | ||
|
|
9d9cb8b7b1 | ||
|
|
033e2fa8b6 |
75
.github/CONTRIBUTING.md
vendored
@@ -1,67 +1,36 @@
|
||||
## General Overview
|
||||
### Introduction (first timers)
|
||||
|
||||
There are three branches where all the work happens:
|
||||
Thank you for your interest in raising an Issue with ERPNext. An Issue could mean a bug report or a request for a missing feature. By raising a bug report, you are contributing to the development of ERPNext and this is the first step of participating in the community. Bug reports are very helpful for developers as they quickly fix the issue before other users start facing it.
|
||||
|
||||
* **master** - This is the production / stable branch for releases.
|
||||
* **develop** - This is bleeding edge with features and fixes. Non critical bug fixes and new features go here. All updates to master also get pushed to develop.
|
||||
* **hotfix** - Urgent bug fixes go here. This is merged into master for releases.
|
||||
Feature requests are also a great way to take the product forward. New ideas can come in any user scenario and the issue list also acts a roadmap of future features.
|
||||
|
||||
## Release Cycles
|
||||
When you are raising an Issue, you should keep a few things in mind. Remember that the developer does not have access to your machine so you must give all the information you can while raising an Issue. If you are suggesting a feature, you should be very clear about what you want.
|
||||
|
||||
Usually, hotfix / develop is pushed to master roughly every week.
|
||||
The Issue list is not the right place to ask a question or start a general discussion. If you want to do that , then the right place is the forum [https://discuss.erpnext.com](https://discuss.erpnext.com).
|
||||
|
||||
If we are close to a major release, then all bugfixes get pushed to hotfix and a release is done every week or as necessary.
|
||||
### Reply and Closing Policy
|
||||
|
||||
***
|
||||
If your issue is not clear or does not meet the guidelines, then it will be closed. If it is closed, please supply the information asked and re-open it.
|
||||
|
||||
### General Issue Guidelines
|
||||
|
||||
## Contributing
|
||||
1. **Search existing Issues:** Before raising a Issue, search if it has been raised before. Maybe add a 👍 or give additional help by creating a mockup if it is not already created.
|
||||
1. **Report each issue separately:** Don't club multiple, unreleated issues in one note.
|
||||
1. **Brief:** Please don't include long explanations. Use screenshots and bullet points instead of descriptive paragraphs.
|
||||
|
||||
Contributing to ERPNext is not very different from the usual Pull Request workflow on GitHub.
|
||||
### Bug Report Guidelines
|
||||
|
||||
### Prerequisites :
|
||||
1. **Steps to Reproduce:** The bug report must have a list of steps needed to reproduce a bug. If we cannot reproduce it, then we cannot solve it.
|
||||
1. **Version Number:** Please add the version number in your report. Often a bug is fixed in the latest version
|
||||
1. **Clear Title:** Add a clear subject to your bug report like "Unable to submit Purchase Order without Basic Rate" instead of just "Cannot Submit"
|
||||
1. **Screenshots:** Screenshots are a great way of communicating the issues. Try adding annotations or using LiceCAP to take a screencast in `gif`.
|
||||
|
||||
* You need to know [Git and Github basics](https://try.github.io/levels/1/challenges/1)
|
||||
* You need to have a Fork of the [ERPNext repo](https://github.com/frappe/erpnext) in your personal Github account
|
||||
* You need to add a [remote](#glossary) for your Forked repository. `git remote add origin [your-erpnext-repo-url]`
|
||||
### Feature Request Guidelines
|
||||
|
||||
### The Process:
|
||||
1. **Clarity:** Clearly specify how do you want the feature to behave. Don't just say "I would like multiple PDF formats", say that "Ability to add multiple print formats for customers with different languages".
|
||||
1. **Solution:** Try and identify how the feature should look like.
|
||||
1. **Mockups:** Mockups are a great way to explain your requirement.
|
||||
|
||||
1. Make sure you're in the right branch. **develop** for adding features / fixing issues and **hotfix** for urgent bug fixes
|
||||
2. Make your changes
|
||||
3. Create and checkout a new branch for the changes you've made. `git checkout -b [branch-name]`
|
||||
4. Add and commit your changes `git commit -am "[commit-message]"
|
||||
5. If you have been working on sometime for a long time, you should [rebase](#glossary) your branch with main develop branch. `git pull upstream develop --rebase` where `upstream` is the remote name of our repo
|
||||
6. Now, push your changes to your fork. `git push origin [branch-name]`
|
||||
If you rebased your commits, you will have to [force push](http://vignette2.wikia.nocookie.net/starwars/images/e/ea/Yodapush.png/revision/latest?cb=20130205190454) `git push origin [branch-name] --force`
|
||||
7. You should now be able to see your pushed branch on Github, now create a pull request against the branch that you want to merge to.
|
||||
8. Wait for us to review it
|
||||
### What if my Issue is closed
|
||||
|
||||
### Your Pull Request Should have
|
||||
|
||||
1. Clear explanation of the use case
|
||||
1. Screenshots / Screecast GIF
|
||||
1. Test Cases (if applicable)
|
||||
1. Update to documentation
|
||||
|
||||
### Common Problems:
|
||||
|
||||
* During rebase you might face _merge conflicts_. A merge conflict occurs when you have made changes to the same file that someone else has, in the commits you're pulling. You need to resolve these conflicts by picking which code you want to keep, yours or theirs. You can use `git mergetool` for help.
|
||||
* Sometimes you don't have a local branch to which you want to make changes to. In that case you first run `git fetch` followed by `git checkout --track -b upstream/[branch-name]`
|
||||
|
||||
|
||||
### Good practices:
|
||||
|
||||
* You should rebase your branch with the branch you plan to make a Pull Request (PR) to as often as you can.
|
||||
* Your commit messages should be precise and explain exactly what the commit does. Same goes for the Pull Request title.
|
||||
* When making a PR make sure that all your code is committed properly by checking the diffs.
|
||||
* If you're working on different things at the same time, make sure you make separate branches for each.
|
||||
* Don't create new DocTypes unless absolutely necessary. If you find that there is a another DocType with a similar functionality, then please try and extend that functionality.
|
||||
* DRY. Don't Repeat Yourself. Before writing up a similar function /feature make sure it doesn't exist in the codebase already.
|
||||
* Tabs, not spaces.
|
||||
|
||||
|
||||
### Glossary
|
||||
|
||||
* remote - A remote is a connection to a Github repo. You should have two remotes, one that points to your repo and one to ours.
|
||||
* rebase - When you rebase a branch, you pull commits from your remote branch and move your commits on top of it. This allows you to update your branch with the latest changes without losing your changes.
|
||||
Don't worry, take the feedback, supply the correct information and re-open it!
|
||||
|
||||
@@ -38,6 +38,15 @@ The ERPNext code is licensed as GNU General Public License (v3) and the Document
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
1. [Issue Guidelines](https://github.com/frappe/erpnext/wiki/Issue-Guidelines)
|
||||
1. [Pull Request Requirements](https://github.com/frappe/erpnext/wiki/Contribution-Guidelines)
|
||||
1. [Translations](https://translate.erpnext.com)
|
||||
1. [Chart of Accounts](https://charts.erpnext.com)
|
||||
|
||||
---
|
||||
|
||||
## Logo and Trademark
|
||||
|
||||
The brand name ERPNext and the logo are trademarks of Frappe Technologies Pvt. Ltd.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
__version__ = '8.0.6'
|
||||
__version__ = '8.0.22'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -189,8 +189,8 @@ class Account(Document):
|
||||
|
||||
if account_balance != stock_balance:
|
||||
frappe.throw(_('Account balance ({0}) and stock value ({1}) must be same')\
|
||||
.format(fmt_money(account_balance, self.account_currency),
|
||||
fmt_money(stock_balance, self.account_currency)))
|
||||
.format(fmt_money(account_balance, currency=self.account_currency),
|
||||
fmt_money(stock_balance, currency=self.account_currency)))
|
||||
|
||||
elif self.warehouse:
|
||||
self.warehouse = None
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
@@ -25,7 +26,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Make Accounting Entry For Every Stock Movement",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -33,6 +36,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -51,7 +55,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Accounts Frozen Upto",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -59,6 +65,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -77,7 +84,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Role Allowed to Set Frozen Accounts & Edit Frozen Entries",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -86,6 +95,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -103,7 +113,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@@ -111,6 +123,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -129,7 +142,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Credit Controller",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -138,6 +153,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -155,7 +171,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Check Supplier Invoice Number Uniqueness",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -164,6 +182,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -181,7 +200,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Make Payment via Journal Entry",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -190,6 +211,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -208,7 +230,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Unlink Payment on Cancellation of Invoice",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -217,6 +241,37 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"fieldname": "book_asset_depreciation_entry_automatically",
|
||||
"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": "Book Asset Depreciation Entry Automatically",
|
||||
"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,
|
||||
@@ -224,18 +279,18 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "fa fa-cog",
|
||||
"icon": "icon-cog",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-10-20 16:12:38.595075",
|
||||
"modified": "2017-04-18 13:35:59.166250",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounts Settings",
|
||||
@@ -251,7 +306,6 @@
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
@@ -266,6 +320,8 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -114,8 +114,17 @@ class Asset(Document):
|
||||
|
||||
def set_accumulated_depreciation(self):
|
||||
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
|
||||
for d in self.get("schedules"):
|
||||
accumulated_depreciation += flt(d.depreciation_amount, d.precision("depreciation_amount"))
|
||||
value_after_depreciation = flt(self.value_after_depreciation)
|
||||
for i, d in enumerate(self.get("schedules")):
|
||||
depreciation_amount = flt(d.depreciation_amount, d.precision("depreciation_amount"))
|
||||
value_after_depreciation -= flt(depreciation_amount)
|
||||
|
||||
if i==len(self.get("schedules"))-1 and self.depreciation_method == "Straight Line":
|
||||
depreciation_amount += flt(value_after_depreciation - flt(self.expected_value_after_useful_life),
|
||||
d.precision("depreciation_amount"))
|
||||
|
||||
d.depreciation_amount = depreciation_amount
|
||||
accumulated_depreciation += d.depreciation_amount
|
||||
d.accumulated_depreciation_amount = flt(accumulated_depreciation, d.precision("accumulated_depreciation_amount"))
|
||||
|
||||
def get_depreciation_amount(self, depreciable_value):
|
||||
|
||||
@@ -8,6 +8,10 @@ from frappe import _
|
||||
from frappe.utils import flt, today, getdate
|
||||
|
||||
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"):
|
||||
return
|
||||
|
||||
if not date:
|
||||
date = today()
|
||||
for asset in get_depreciable_assets(date):
|
||||
|
||||
@@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
from frappe.utils import cstr, nowdate, getdate
|
||||
from frappe.utils import cstr, nowdate, getdate, flt
|
||||
from erpnext.accounts.doctype.asset.depreciation import post_depreciation_entries, scrap_asset, restore_asset
|
||||
from erpnext.accounts.doctype.asset.asset import make_sales_invoice, make_purchase_invoice
|
||||
|
||||
@@ -166,6 +166,23 @@ class TestAsset(unittest.TestCase):
|
||||
|
||||
self.assertEqual(gle, expected_gle)
|
||||
self.assertEqual(asset.get("value_after_depreciation"), 70000)
|
||||
|
||||
def test_depreciation_entry_cancellation(self):
|
||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||
asset.submit()
|
||||
post_depreciation_entries(date="2021-01-01")
|
||||
|
||||
asset.load_from_db()
|
||||
|
||||
# cancel depreciation entry
|
||||
depr_entry = asset.get("schedules")[0].journal_entry
|
||||
self.assertTrue(depr_entry)
|
||||
frappe.get_doc("Journal Entry", depr_entry).cancel()
|
||||
|
||||
asset.load_from_db()
|
||||
depr_entry = asset.get("schedules")[0].journal_entry
|
||||
self.assertFalse(depr_entry)
|
||||
|
||||
|
||||
def test_scrap_asset(self):
|
||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||
@@ -226,6 +243,23 @@ class TestAsset(unittest.TestCase):
|
||||
|
||||
self.assertEqual(frappe.db.get_value("Asset", "Macbook Pro 1", "status"), "Partially Depreciated")
|
||||
|
||||
def test_asset_expected_value_after_useful_life(self):
|
||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||
asset.depreciation_method = "Straight Line"
|
||||
asset.is_existing_asset = 1
|
||||
asset.total_number_of_depreciations = 400
|
||||
asset.gross_purchase_amount = 16866177.00
|
||||
asset.expected_value_after_useful_life = 500000
|
||||
asset.save()
|
||||
|
||||
accumulated_depreciation_after_full_schedule = \
|
||||
max([d.accumulated_depreciation_amount for d in asset.get("schedules")])
|
||||
|
||||
asset_value_after_full_schedule = (flt(asset.gross_purchase_amount) -
|
||||
flt(accumulated_depreciation_after_full_schedule))
|
||||
|
||||
self.assertTrue(asset.expected_value_after_useful_life >= asset_value_after_full_schedule)
|
||||
|
||||
def tearDown(self):
|
||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||
|
||||
@@ -297,4 +331,7 @@ def set_depreciation_settings_in_company():
|
||||
company.depreciation_expense_account = "_Test Depreciations - _TC"
|
||||
company.disposal_account = "_Test Gain/Loss on Asset Disposal - _TC"
|
||||
company.depreciation_cost_center = "_Test Cost Center - _TC"
|
||||
company.save()
|
||||
company.save()
|
||||
|
||||
# Enable booking asset depreciation entry automatically
|
||||
frappe.db.set_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically", 1)
|
||||
30
erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Bank Guarantee', {
|
||||
refresh: function(frm) {
|
||||
cur_frm.set_query("account", function() {
|
||||
return {
|
||||
"filters": {
|
||||
"account_type": "Bank",
|
||||
"is_group": 0
|
||||
}
|
||||
};
|
||||
});
|
||||
cur_frm.set_query("project", function() {
|
||||
return {
|
||||
"filters": {
|
||||
"customer": cur_frm.doc.customer
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
start_date: function(frm) {
|
||||
end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
|
||||
cur_frm.set_value("end_date", end_date);
|
||||
},
|
||||
validity: function(frm) {
|
||||
end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
|
||||
cur_frm.set_value("end_date", end_date);
|
||||
}
|
||||
});
|
||||
448
erpnext/accounts/doctype/bank_guarantee/bank_guarantee.json
Normal file
@@ -0,0 +1,448 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "BG-.#####",
|
||||
"beta": 0,
|
||||
"creation": "2016-12-17 10:43:35.731631",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Document",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Customer",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Customer",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "project",
|
||||
"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": "Project",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_6",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "start_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Start Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fieldname": "validity",
|
||||
"fieldtype": "Int",
|
||||
"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": "Validity in Days",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "end_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "End Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "bank_guarantee_number",
|
||||
"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": "Bank Guarantee Number",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_10",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "More Information",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "more_information",
|
||||
"fieldtype": "Text Editor",
|
||||
"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": "Notes",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "amended_from",
|
||||
"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": "Amended From",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Bank Guarantee",
|
||||
"permlevel": 0,
|
||||
"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
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-04-25 13:31:49.627831",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Guarantee",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"search_fields": "customer",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "customer",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
10
erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class BankGuarantee(Document):
|
||||
pass
|
||||
@@ -0,0 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Bank Guarantee')
|
||||
|
||||
class TestBankGuarantee(unittest.TestCase):
|
||||
pass
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
frappe.ui.form.on("Bank Reconciliation", {
|
||||
setup: function(frm) {
|
||||
frm.get_docfield("payment_entries").allow_bulk_edit = 1;
|
||||
frm.add_fetch("bank_account", "account_currency", "account_currency");
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
var default_bank_account = locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"];
|
||||
|
||||
let default_bank_account = frappe.defaults.get_user_default("Company")?
|
||||
locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"]: "";
|
||||
frm.set_value("bank_account", default_bank_account);
|
||||
|
||||
frm.set_query("bank_account", function() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 1,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
@@ -7,11 +8,15 @@
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Document",
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Select account head of the bank where cheque was deposited.",
|
||||
"fieldname": "bank_account",
|
||||
"fieldtype": "Link",
|
||||
@@ -19,7 +24,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -28,6 +35,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -35,16 +43,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "account_currency",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Account Currency",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -53,6 +65,7 @@
|
||||
"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,
|
||||
@@ -60,16 +73,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "From Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -77,6 +94,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -84,16 +102,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "To Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -101,6 +123,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -108,16 +131,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "include_reconciled_entries",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Include Reconciled Entries",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -125,6 +152,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -132,16 +160,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "get_payment_entries",
|
||||
"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 Payment Entries",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -150,6 +182,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -157,16 +190,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "payment_entries",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Payment Entries",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -175,6 +212,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -182,16 +220,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "update_clearance_date",
|
||||
"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": "Update Clearance Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -200,6 +242,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -207,16 +250,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "total_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": "Total Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -225,6 +272,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -232,19 +280,19 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 1,
|
||||
"hide_toolbar": 1,
|
||||
"icon": "fa fa-check",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2016-06-28 13:11:09.396353",
|
||||
"modified": "2017-04-21 16:58:26.902732",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Reconciliation",
|
||||
@@ -274,7 +322,8 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 1,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_order": "ASC",
|
||||
"track_seen": 0,
|
||||
"version": 0
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "GL.#######",
|
||||
@@ -12,6 +13,7 @@
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -22,6 +24,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Posting Date",
|
||||
@@ -41,6 +44,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -51,6 +55,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Transaction Date",
|
||||
@@ -70,6 +75,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -80,6 +86,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Account",
|
||||
@@ -100,6 +107,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -110,6 +118,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Party Type",
|
||||
@@ -128,6 +137,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -138,6 +148,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Party",
|
||||
@@ -156,6 +167,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -166,6 +178,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Cost Center",
|
||||
@@ -186,6 +199,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -196,6 +210,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Debit Amount",
|
||||
@@ -217,6 +232,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -227,6 +243,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Credit Amount",
|
||||
@@ -248,6 +265,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -258,6 +276,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Account Currency",
|
||||
@@ -277,6 +296,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -287,6 +307,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Debit Amount in Account Currency",
|
||||
@@ -306,6 +327,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -316,6 +338,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Credit Amount in Account Currency",
|
||||
@@ -335,6 +358,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -345,6 +369,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Against",
|
||||
@@ -364,6 +389,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -374,6 +400,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Against Voucher Type",
|
||||
@@ -394,6 +421,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -404,6 +432,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Against Voucher",
|
||||
@@ -424,6 +453,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -434,6 +464,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Voucher Type",
|
||||
@@ -454,6 +485,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -464,6 +496,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Voucher No",
|
||||
@@ -484,6 +517,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -494,6 +528,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Project",
|
||||
@@ -513,6 +548,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -523,6 +559,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Remarks",
|
||||
@@ -542,6 +579,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -552,6 +590,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Is Opening",
|
||||
@@ -572,6 +611,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -582,6 +622,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Is Advance",
|
||||
@@ -602,6 +643,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -612,6 +654,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Fiscal Year",
|
||||
@@ -632,6 +675,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -642,6 +686,7 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Company",
|
||||
@@ -662,18 +707,18 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "fa fa-list",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 1,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-12-15 14:44:41.098790",
|
||||
"modified": "2017-04-27 13:18:06.617940",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "GL Entry",
|
||||
@@ -689,7 +734,6 @@
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
@@ -710,7 +754,6 @@
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
@@ -731,7 +774,6 @@
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
@@ -744,10 +786,12 @@
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only": 1,
|
||||
"read_only_onload": 0,
|
||||
"search_fields": "voucher_no,account,posting_date,against_voucher",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "naming_series:",
|
||||
@@ -1325,19 +1326,19 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "fa fa-file-text",
|
||||
"idx": 176,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-02-17 16:17:48.991851",
|
||||
"modified": "2017-04-10 12:07:44.599804",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Journal Entry",
|
||||
@@ -1412,6 +1413,6 @@
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "title",
|
||||
"track_changes": 0,
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -72,6 +72,7 @@ class JournalEntry(AccountsController):
|
||||
self.update_expense_claim()
|
||||
self.update_employee_loan()
|
||||
self.unlink_advance_entry_reference()
|
||||
self.unlink_asset_reference()
|
||||
|
||||
def unlink_advance_entry_reference(self):
|
||||
for d in self.get("accounts"):
|
||||
@@ -81,6 +82,18 @@ 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:
|
||||
asset = frappe.get_doc("Asset", d.reference_name)
|
||||
for s in asset.get("schedules"):
|
||||
if s.journal_entry == self.name:
|
||||
s.db_set("journal_entry", None)
|
||||
asset.value_after_depreciation += s.depreciation_amount
|
||||
|
||||
asset.db_set("value_after_depreciation", asset.value_after_depreciation)
|
||||
asset.set_status()
|
||||
|
||||
def validate_party(self):
|
||||
for d in self.get("accounts"):
|
||||
@@ -501,7 +514,7 @@ class JournalEntry(AccountsController):
|
||||
|
||||
def update_expense_claim(self):
|
||||
for d in self.accounts:
|
||||
if d.reference_type=="Expense Claim" and d.party:
|
||||
if d.reference_type=="Expense Claim" and d.reference_name:
|
||||
doc = frappe.get_doc("Expense Claim", d.reference_name)
|
||||
update_reimbursed_amount(doc)
|
||||
|
||||
|
||||
@@ -1675,7 +1675,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-03-14 17:12:48.816644",
|
||||
"modified": "2017-04-10 12:06:22.176045",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry",
|
||||
@@ -1730,6 +1730,6 @@
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "title",
|
||||
"track_changes": 0,
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -23,6 +23,8 @@ class PricingRule(Document):
|
||||
self.validate_price_or_discount()
|
||||
self.validate_max_discount()
|
||||
|
||||
if not self.margin_type: self.margin_rate_or_amount = 0.0
|
||||
|
||||
def validate_mandatory(self):
|
||||
for field in ["apply_on", "applicable_for"]:
|
||||
tocheck = frappe.scrub(self.get(field) or "")
|
||||
@@ -144,7 +146,7 @@ def get_pricing_rule_for_item(args):
|
||||
|
||||
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(args, item_details)
|
||||
item_details = remove_pricing_rule_for_item(args.get("pricing_rule"), item_details)
|
||||
return item_details
|
||||
|
||||
if not (args.item_group and args.brand):
|
||||
@@ -178,19 +180,20 @@ 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) \
|
||||
"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
|
||||
})
|
||||
else:
|
||||
item_details.discount_percentage = pricing_rule.discount_percentage
|
||||
elif args.get('pricing_rule'):
|
||||
item_details = remove_pricing_rule(args, item_details)
|
||||
item_details = remove_pricing_rule_for_item(args.get("pricing_rule"), item_details)
|
||||
|
||||
return item_details
|
||||
|
||||
def remove_pricing_rule(args, item_details):
|
||||
pricing_rule = frappe.db.get_value('Pricing Rule', args.get('pricing_rule'), ['price_or_discount', 'margin_type'], as_dict=1)
|
||||
def remove_pricing_rule_for_item(pricing_rule, item_details):
|
||||
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
|
||||
|
||||
@@ -198,8 +201,22 @@ def remove_pricing_rule(args, item_details):
|
||||
item_details.margin_rate_or_amount = 0.0
|
||||
item_details.margin_type = None
|
||||
|
||||
if item_details.pricing_rule:
|
||||
item_details.pricing_rule = None
|
||||
return item_details
|
||||
|
||||
@frappe.whitelist()
|
||||
def remove_pricing_rules(item_list):
|
||||
if isinstance(item_list, basestring):
|
||||
item_list = json.loads(item_list)
|
||||
|
||||
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)
|
||||
|
||||
@@ -3646,7 +3646,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-03-15 14:29:51.957287",
|
||||
"modified": "2017-04-10 12:05:28.082020",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
@@ -3762,6 +3762,6 @@
|
||||
"sort_order": "DESC",
|
||||
"timeline_field": "supplier",
|
||||
"title_field": "title",
|
||||
"track_changes": 0,
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -628,10 +628,12 @@ class PurchaseInvoice(BuyingController):
|
||||
pi = frappe.db.sql('''select name from `tabPurchase Invoice`
|
||||
where
|
||||
bill_no = %(bill_no)s
|
||||
and supplier = %(supplier)s
|
||||
and name != %(name)s
|
||||
and docstatus < 2
|
||||
and posting_date between %(year_start_date)s and %(year_end_date)s''', {
|
||||
"bill_no": self.bill_no,
|
||||
"supplier": self.supplier,
|
||||
"name": self.name,
|
||||
"year_start_date": fiscal_year.year_start_date,
|
||||
"year_end_date": fiscal_year.year_end_date
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "hash",
|
||||
@@ -335,6 +336,36 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "stock_uom",
|
||||
"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": "Stock UOM",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "UOM",
|
||||
"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_on_submit": 0,
|
||||
"bold": 0,
|
||||
@@ -419,6 +450,35 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "stock_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Stock Qty",
|
||||
"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_on_submit": 0,
|
||||
"bold": 0,
|
||||
@@ -1362,11 +1422,11 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "is_sample_item",
|
||||
"fieldname": "allow_zero_valuation_rate",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -1375,7 +1435,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Is Sample Item",
|
||||
"label": "Allow Zero Valuation Rate",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
@@ -1448,7 +1508,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -1869,17 +1929,17 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-17 16:28:26.719053",
|
||||
"modified": "2017-04-19 11:54:16.112134",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice Item",
|
||||
@@ -1893,4 +1953,4 @@
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ def get_pos_data():
|
||||
'doc': doc,
|
||||
'default_customer': pos_profile.get('customer'),
|
||||
'items': get_items_list(pos_profile),
|
||||
'item_groups': get_item_group(pos_profile),
|
||||
'item_groups': get_item_groups(pos_profile),
|
||||
'customers': customers,
|
||||
'address': get_customers_address(customers),
|
||||
'serial_no_data': get_serial_no_data(pos_profile, doc.company),
|
||||
@@ -132,7 +132,7 @@ def get_items_list(pos_profile):
|
||||
if pos_profile.get('item_groups'):
|
||||
# Get items based on the item groups defined in the POS profile
|
||||
for d in pos_profile.get('item_groups'):
|
||||
item_groups.extend(get_child_nodes('Item Group', d.item_group))
|
||||
item_groups.extend([d.name for d in get_child_nodes('Item Group', d.item_group)])
|
||||
cond = "item_group in (%s)"%(', '.join(['%s']*len(item_groups)))
|
||||
|
||||
return frappe.db.sql("""
|
||||
@@ -146,14 +146,19 @@ def get_items_list(pos_profile):
|
||||
disabled = 0 and has_variants = 0 and is_sales_item = 1 and {cond}
|
||||
""".format(cond=cond), tuple(item_groups), as_dict=1)
|
||||
|
||||
def get_item_group(pos_profile):
|
||||
def get_item_groups(pos_profile):
|
||||
item_group_dict = {}
|
||||
if pos_profile.get('item_groups'):
|
||||
item_groups = []
|
||||
for d in pos_profile.get('item_groups'):
|
||||
item_groups.extend(get_child_nodes('Item Group', d.item_group))
|
||||
return item_groups
|
||||
else:
|
||||
return frappe.db.sql_list("""Select name from `tabItem Group` order by name""")
|
||||
item_groups = frappe.db.sql("""Select name,
|
||||
lft, rgt from `tabItem Group` order by lft""", as_dict=1)
|
||||
|
||||
for data in item_groups:
|
||||
item_group_dict[data.name] = [data.lft, data.rgt]
|
||||
return item_group_dict
|
||||
|
||||
def get_customers_list(pos_profile):
|
||||
cond = "1=1"
|
||||
@@ -161,7 +166,7 @@ def get_customers_list(pos_profile):
|
||||
if pos_profile.get('customer_groups'):
|
||||
# Get customers based on the customer groups defined in the POS profile
|
||||
for d in pos_profile.get('customer_groups'):
|
||||
customer_groups.extend(get_child_nodes('Customer Group', d.customer_group))
|
||||
customer_groups.extend([d.name for d in get_child_nodes('Customer Group', d.customer_group)])
|
||||
cond = "customer_group in (%s)"%(', '.join(['%s']*len(customer_groups)))
|
||||
|
||||
return frappe.db.sql(""" select name, customer_name, customer_group,
|
||||
@@ -182,12 +187,13 @@ def get_customers_address(customers):
|
||||
address_data = address[0]
|
||||
address_data.update({'full_name': data.customer_name})
|
||||
customer_address[data.name] = address_data
|
||||
|
||||
return customer_address
|
||||
|
||||
def get_child_nodes(group_type, root):
|
||||
lft, rgt = frappe.db.get_value(group_type, root, ["lft", "rgt"])
|
||||
return frappe.db.sql_list(""" Select name from `tab{tab}` where
|
||||
lft >= {lft} and rgt <= {rgt}""".format(tab=group_type, lft=lft, rgt=rgt))
|
||||
return frappe.db.sql(""" Select name, lft, rgt from `tab{tab}` where
|
||||
lft >= {lft} and rgt <= {rgt} order by lft""".format(tab=group_type, lft=lft, rgt=rgt), as_dict=1)
|
||||
|
||||
def get_serial_no_data(pos_profile, company):
|
||||
# get itemwise serial no data
|
||||
@@ -295,9 +301,9 @@ def make_invoice(doc_list={}, email_queue_list={}, customers_list={}):
|
||||
if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}):
|
||||
validate_records(doc)
|
||||
si_doc = frappe.new_doc('Sales Invoice')
|
||||
si_doc.due_date = doc.get('posting_date')
|
||||
si_doc.offline_pos_name = name
|
||||
si_doc.update(doc)
|
||||
si_doc.due_date = doc.get('posting_date')
|
||||
submit_invoice(si_doc, name, doc)
|
||||
name_list.append(name)
|
||||
else:
|
||||
@@ -319,8 +325,10 @@ def make_customer_and_address(customers):
|
||||
if not frappe.db.exists('Customer', name):
|
||||
name = add_customer(name)
|
||||
data = json.loads(data)
|
||||
make_contact(data, name)
|
||||
make_address(data, name)
|
||||
customer_list.append(name)
|
||||
frappe.db.commit()
|
||||
return customer_list
|
||||
|
||||
def add_customer(name):
|
||||
@@ -334,14 +342,40 @@ def add_customer(name):
|
||||
frappe.db.commit()
|
||||
return customer_doc.name
|
||||
|
||||
def make_contact(args,customer):
|
||||
if args.get('email_id') or args.get('phone'):
|
||||
name = frappe.db.get_value('Dynamic Link',
|
||||
{'link_doctype': 'Customer', 'link_name': customer, 'parenttype': 'Contact'}, 'parent')
|
||||
|
||||
args = {
|
||||
'email_id': args.get('email_id'),
|
||||
'phone': args.get('phone')
|
||||
}
|
||||
|
||||
doc = frappe.new_doc('Contact')
|
||||
if name:
|
||||
doc = frappe.get_doc('Contact', name)
|
||||
|
||||
doc.update(args)
|
||||
if not name:
|
||||
doc.first_name = customer
|
||||
doc.append('links',{
|
||||
'link_doctype': 'Customer',
|
||||
'link_name': customer
|
||||
})
|
||||
doc.save(ignore_permissions=True)
|
||||
|
||||
def make_address(args, customer):
|
||||
if not args.get('address_line1'): return
|
||||
|
||||
name = args.get('name') or get_customers_address(customer)[customer].get("name")
|
||||
name = args.get('name')
|
||||
|
||||
if not name:
|
||||
data = get_customers_address(customer)
|
||||
name = data[customer].get('name') if data else None
|
||||
|
||||
if name:
|
||||
address = frappe.get_doc('Address', name)
|
||||
frappe.errprint(address)
|
||||
address = frappe.get_doc('Address', name)
|
||||
else:
|
||||
address = frappe.new_doc('Address')
|
||||
address.country = frappe.db.get_value('Company', args.get('company'), 'country')
|
||||
@@ -400,4 +434,5 @@ def save_invoice(e, si_doc, name):
|
||||
if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}):
|
||||
si_doc.docstatus = 0
|
||||
si_doc.flags.ignore_mandatory = True
|
||||
si_doc.due_date = si_doc.posting_date
|
||||
si_doc.insert()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"beta": 0,
|
||||
"creation": "2013-05-24 19:29:05",
|
||||
"custom": 0,
|
||||
"default_print_format": "Sample Print",
|
||||
"default_print_format": "",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
@@ -4417,8 +4417,8 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-03-29 05:09:56.656338",
|
||||
"modified_by": "Administrator",
|
||||
"modified": "2017-04-12 15:11:45.931485",
|
||||
"modified_by": "faris@erpnext.com",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
"owner": "Administrator",
|
||||
@@ -4513,6 +4513,6 @@
|
||||
"sort_order": "DESC",
|
||||
"timeline_field": "customer",
|
||||
"title_field": "title",
|
||||
"track_changes": 0,
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -147,9 +147,9 @@
|
||||
"price_list_rate": 50,
|
||||
"qty": 10,
|
||||
"rate": 50,
|
||||
"uom": "_Test UOM",
|
||||
"uom": "_Test UOM 1",
|
||||
"conversion_factor": 1,
|
||||
"stock_uom": "_Test UOM"
|
||||
"stock_uom": "_Test UOM 1"
|
||||
},
|
||||
{
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
@@ -273,9 +273,9 @@
|
||||
"parentfield": "items",
|
||||
"price_list_rate": 62.5,
|
||||
"qty": 10,
|
||||
"uom": "_Test UOM",
|
||||
"conversion_factor": 1,
|
||||
"stock_uom": "_Test UOM"
|
||||
"uom": "_Test UOM 1",
|
||||
"conversion_factor": 1,
|
||||
"stock_uom": "_Test UOM 1"
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1043,6 +1043,25 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
#check outstanding after advance cancellation
|
||||
self.assertEqual(flt(si.outstanding_amount), flt(si.grand_total + si.total_advance, si.precision("outstanding_amount")))
|
||||
|
||||
def test_multiple_uom_in_selling(self):
|
||||
si = frappe.copy_doc(test_records[1])
|
||||
|
||||
si.items[0].uom = "_Test UOM 1"
|
||||
si.items[0].conversion_factor = None
|
||||
si.items[0].price_list_rate = None
|
||||
si.save()
|
||||
|
||||
expected_values = {
|
||||
"keys": ["price_list_rate", "stock_uom", "uom", "conversion_factor", "rate", "amount",
|
||||
"base_price_list_rate", "base_rate", "base_amount"],
|
||||
"_Test Item": [1000, "_Test UOM", "_Test UOM 1", 10.0, 1000, 1000, 1000, 1000, 1000]
|
||||
}
|
||||
|
||||
# check if the conversion_factor and price_list_rate is calculated according to uom
|
||||
for d in si.get("items"):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.get(k), expected_values[d.item_code][i])
|
||||
|
||||
def create_sales_invoice(**args):
|
||||
si = frappe.new_doc("Sales Invoice")
|
||||
args = frappe._dict(args)
|
||||
|
||||
@@ -1548,11 +1548,11 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "is_sample_item",
|
||||
"fieldname": "allow_zero_valuation_rate",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -1561,7 +1561,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Is Sample Item",
|
||||
"label": "Allow Zero Valuation Rate",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
@@ -2094,7 +2094,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-03-30 16:26:36.507924",
|
||||
"modified": "2017-04-19 11:53:26.682964",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
|
||||
@@ -327,6 +327,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
this.name = null;
|
||||
this.load_data(true);
|
||||
this.setup();
|
||||
this.set_default_customer()
|
||||
},
|
||||
|
||||
load_data: function (load_doc) {
|
||||
@@ -360,6 +361,16 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
}
|
||||
},
|
||||
|
||||
set_default_customer: function() {
|
||||
if (this.default_customer && !this.frm.doc.customer) {
|
||||
this.party_field.$input.val(this.default_customer);
|
||||
this.frm.doc.customer = this.default_customer;
|
||||
this.numeric_keypad.show();
|
||||
this.toggle_list_customer(false)
|
||||
this.toggle_item_cart(true)
|
||||
}
|
||||
},
|
||||
|
||||
set_transaction_defaults: function (party) {
|
||||
var me = this;
|
||||
this.party = party;
|
||||
@@ -407,8 +418,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
});
|
||||
|
||||
this.search_item_group = this.wrapper.find('.search-item-group');
|
||||
|
||||
var dropdown_html = me.item_groups.map(function(item_group) {
|
||||
sorted_item_groups = this.get_sorted_item_groups()
|
||||
var dropdown_html = sorted_item_groups.map(function(item_group) {
|
||||
return "<li><a class='option' data-value='"+item_group+"'>"+item_group+"</a></li>";
|
||||
}).join("");
|
||||
|
||||
@@ -437,6 +448,15 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
})
|
||||
},
|
||||
|
||||
get_sorted_item_groups: function() {
|
||||
list = {}
|
||||
$.each(this.item_groups, function(i, data) {
|
||||
list[i] = data[0]
|
||||
})
|
||||
|
||||
return Object.keys(list).sort(function(a,b){return list[a]-list[b]})
|
||||
},
|
||||
|
||||
toggle_more_btn: function() {
|
||||
if(!this.items || this.items.length <= this.page_len) {
|
||||
this.wrapper.find(".btn-more").hide();
|
||||
@@ -666,11 +686,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
me.toggle_delete_button();
|
||||
}
|
||||
|
||||
if (this.default_customer && !this.frm.doc.customer) {
|
||||
this.party_field.$input.val(this.default_customer);
|
||||
this.frm.doc.customer = this.default_customer;
|
||||
}
|
||||
|
||||
this.party_field.awesomeplete =
|
||||
new Awesomplete(this.party_field.$input.get(0), {
|
||||
minChars: 0,
|
||||
@@ -851,6 +866,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
this.customer_doc.set_primary_action(__("Save"), function () {
|
||||
me.make_offline_customer(new_customer);
|
||||
me.pos_bill.show();
|
||||
me.list_customers.hide();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -951,6 +967,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
item_price: format_currency(me.price_list_data[obj.name], me.frm.doc.currency),
|
||||
item_name: obj.name === obj.item_name ? "" : obj.item_name,
|
||||
item_image: obj.image,
|
||||
item_stock: __('Stock Qty') + ": " + me.get_actual_qty(obj),
|
||||
color: frappe.get_palette(obj.item_name),
|
||||
abbr: frappe.get_abbr(obj.item_name)
|
||||
})).tooltip().appendTo($wrap);
|
||||
@@ -1090,9 +1107,9 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
// $(me.wrapper).find(".pos-item-wrapper").on("click", function () {
|
||||
$(this.wrapper).on("click", ".pos-item-wrapper", function () {
|
||||
me.item_code = '';
|
||||
me.customer_validate();
|
||||
if($(me.pos_bill).is(":hidden")) return;
|
||||
|
||||
me.customer_validate();
|
||||
if (me.frm.doc.docstatus == 0) {
|
||||
me.items = me.get_items($(this).attr("data-item-code"))
|
||||
me.add_to_cart();
|
||||
@@ -1355,7 +1372,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
discount_percentage: d.discount_percentage || 0.0,
|
||||
actual_qty: me.actual_qty_dict[d.item_code] || 0.0,
|
||||
projected_qty: d.projected_qty,
|
||||
rate: format_number(d.rate, me.frm.doc.currency),
|
||||
rate: format_currency(d.rate, me.frm.doc.currency),
|
||||
enabled: me.pos_profile_data["allow_user_to_edit_rate"] ? true : false,
|
||||
amount: format_currency(d.amount, me.frm.doc.currency),
|
||||
selected_class: (me.item_code == d.item_code) ? "active" : ""
|
||||
@@ -1767,7 +1784,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
var me = this;
|
||||
return $.grep(this.pricing_rules, function (data) {
|
||||
if (item.qty >= data.min_qty && (item.qty <= (data.max_qty ? data.max_qty : item.qty))) {
|
||||
if (data.item_code == item.item_code || in_list(['All Item Groups', item.item_group], data.item_group) || item.brand == data.brand) {
|
||||
if (me.validate_item_condition(data, item)) {
|
||||
if (in_list(['Customer', 'Customer Group', 'Territory', 'Campaign'], data.applicable_for)) {
|
||||
return me.validate_condition(data)
|
||||
} else {
|
||||
@@ -1778,6 +1795,26 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
})
|
||||
},
|
||||
|
||||
validate_item_condition: function (data, item) {
|
||||
var apply_on = frappe.model.scrub(data.apply_on);
|
||||
|
||||
return (data.apply_on == 'Item Group')
|
||||
? this.validate_item_group(data.item_group, item.item_group) : (data[apply_on] == item[apply_on]);
|
||||
},
|
||||
|
||||
validate_item_group: function (pr_item_group, cart_item_group) {
|
||||
//pr_item_group = pricing rule's item group
|
||||
//cart_item_group = cart item's item group
|
||||
//this.item_groups has information about item group's lft and rgt
|
||||
//for example: {'Foods': [12, 19]}
|
||||
|
||||
pr_item_group = this.item_groups[pr_item_group]
|
||||
cart_item_group = this.item_groups[cart_item_group]
|
||||
|
||||
return (cart_item_group[0] >= pr_item_group[0] &&
|
||||
cart_item_group[1] <= pr_item_group[1])
|
||||
},
|
||||
|
||||
validate_condition: function (data) {
|
||||
//This method check condition based on applicable for
|
||||
condition = this.get_mapper_for_pricing_rule(data)[data.applicable_for]
|
||||
@@ -1856,4 +1893,4 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
frappe.throw(__("LocalStorage is full , did not save"))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -341,7 +341,7 @@ def validate_party_frozen_disabled(party_type, party_name):
|
||||
|
||||
elif party_type == "Employee":
|
||||
if frappe.db.get_value("Employee", party_name, "status") == "Left":
|
||||
frappe.msgprint(_("{0} {1} is not active").format(party_type, party_name), PartyDisabled, alert=True)
|
||||
frappe.msgprint(_("{0} {1} is not active").format(party_type, party_name), alert=True)
|
||||
|
||||
def get_timeline_data(doctype, name):
|
||||
'''returns timeline data for the past one year'''
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
"docstatus": 0,
|
||||
"doctype": "Print Format",
|
||||
"font": "Default",
|
||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ company }}<br>\n\t{{ __(\"POS No : \") }}{{offline_pos_name}}<br>\n</p>\n<p>\n\t<b>{{ __(\"Date\") }}:</b> {{ dateutil.global_date_format(posting_date) }}<br>\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ __(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{% for item in items %}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_name }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ format_number(item.qty, precision(\"difference\")) }}<br>@ {{ format_currency(item.rate, currency) }}</td>\n\t\t\t<td class=\"text-right\">{{ format_currency(item.amount, currency) }}</td>\n\t\t</tr>\n\t\t{% endfor %}\n\t</tbody>\n</table>\n\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ __(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% for row in taxes %}\n\t\t{% if not row.included_in_print_rate %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(row.tax_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t{% endfor %}\n\t\t{% if discount_amount %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ __(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(discount_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(grand_total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Paid Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(paid_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n\n\n<hr>\n<p>{{ terms }}</p>\n<p class=\"text-center\">{{ __(\"Thank you, please visit again.\") }}</p>",
|
||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ company }}<br>\n\t{{ __(\"POS No : \") }} {{ offline_pos_name }}<br>\n</p>\n<p>\n\t<b>{{ __(\"Date\") }}:</b> {{ dateutil.global_date_format(posting_date) }}<br>\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ __(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{% for item in items %}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_name }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ format_number(item.qty, null,precision(\"difference\")) }}<br>@ {{ format_currency(item.rate, currency) }}</td>\n\t\t\t<td class=\"text-right\">{{ format_currency(item.amount, currency) }}</td>\n\t\t</tr>\n\t\t{% endfor %}\n\t</tbody>\n</table>\n\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ __(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% for row in taxes %}\n\t\t{% if not row.included_in_print_rate %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(row.tax_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t{% endfor %}\n\t\t{% if discount_amount %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ __(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(discount_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(grand_total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Paid Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(paid_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n\n\n<hr>\n<p>{{ terms }}</p>\n<p class=\"text-center\">{{ __(\"Thank you, please visit again.\") }}</p>",
|
||||
"idx": 0,
|
||||
"line_breaks": 0,
|
||||
"modified": "2017-01-12 14:56:12.571032",
|
||||
"modified": "2017-04-19 13:28:05.129504",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Point of Sale",
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{% var letterhead= filters.letter_head || frappe.get_doc(":Company", filters.company).default_letter_head || frappe.defaults.get_default("letter_head"); %}
|
||||
{% if(letterhead) { %}
|
||||
<div style="margin-bottom: 7px;" class="text-center">
|
||||
{%= frappe.boot.letter_heads[frappe.get_doc(":Company", filters.company).default_letter_head || frappe.defaults.get_default("letter_head")] %}
|
||||
{%= frappe.boot.letter_heads[letterhead].header %}
|
||||
</div>
|
||||
{% } %}
|
||||
<h2 class="text-center">{%= __(report.report_name) %}</h2>
|
||||
<h4 class="text-center">{%= filters.customer || filters.supplier %} </h4>
|
||||
<h5 class="text-center">
|
||||
|
||||
@@ -16,6 +16,21 @@ frappe.query_reports["Accounts Receivable"] = {
|
||||
"fieldtype": "Link",
|
||||
"options": "Customer"
|
||||
},
|
||||
{
|
||||
"fieldname":"customer_group",
|
||||
"label": __("Customer Group"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Customer Group"
|
||||
},
|
||||
{
|
||||
"fieldname":"credit_days_based_on",
|
||||
"label": __("Credit Days Based On"),
|
||||
"fieldtype": "Select",
|
||||
"options": "" + NEWLINE + "Fixed Days" + NEWLINE + "Last Day of the Next Month"
|
||||
},
|
||||
{
|
||||
"fieldtype": "Break",
|
||||
},
|
||||
{
|
||||
"fieldname":"report_date",
|
||||
"label": __("As on Date"),
|
||||
@@ -29,9 +44,6 @@ frappe.query_reports["Accounts Receivable"] = {
|
||||
"options": 'Posting Date' + NEWLINE + 'Due Date',
|
||||
"default": "Posting Date"
|
||||
},
|
||||
{
|
||||
"fieldtype": "Break",
|
||||
},
|
||||
{
|
||||
"fieldname":"range1",
|
||||
"label": __("Ageing Range 1"),
|
||||
|
||||
@@ -71,7 +71,10 @@ class ReceivablePayableReport(object):
|
||||
"width": 100
|
||||
})
|
||||
if args.get("party_type") == "Customer":
|
||||
columns += [_("Territory") + ":Link/Territory:80"]
|
||||
columns += [
|
||||
_("Territory") + ":Link/Territory:80",
|
||||
_("Customer Group") + ":Link/Customer Group:120"
|
||||
]
|
||||
if args.get("party_type") == "Supplier":
|
||||
columns += [_("Supplier Type") + ":Link/Supplier Type:80"]
|
||||
|
||||
@@ -139,7 +142,7 @@ class ReceivablePayableReport(object):
|
||||
|
||||
# customer territory / supplier type
|
||||
if args.get("party_type") == "Customer":
|
||||
row += [self.get_territory(gle.party)]
|
||||
row += [self.get_territory(gle.party), self.get_customer_group(gle.party)]
|
||||
if args.get("party_type") == "Supplier":
|
||||
row += [self.get_supplier_type(gle.party)]
|
||||
|
||||
@@ -186,6 +189,9 @@ class ReceivablePayableReport(object):
|
||||
|
||||
def get_territory(self, party_name):
|
||||
return self.get_party_map("Customer").get(party_name, {}).get("territory") or ""
|
||||
|
||||
def get_customer_group(self, party_name):
|
||||
return self.get_party_map("Customer").get(party_name, {}).get("customer_group") or ""
|
||||
|
||||
def get_supplier_type(self, party_name):
|
||||
return self.get_party_map("Supplier").get(party_name, {}).get("supplier_type") or ""
|
||||
@@ -193,12 +199,12 @@ class ReceivablePayableReport(object):
|
||||
def get_party_map(self, party_type):
|
||||
if not hasattr(self, "party_map"):
|
||||
if party_type == "Customer":
|
||||
self.party_map = dict(((r.name, r) for r in frappe.db.sql("""select {0}, {1}, {2} from `tab{3}`"""
|
||||
.format("name", "customer_name", "territory", party_type), as_dict=True)))
|
||||
|
||||
select_fields = "name, customer_name, territory, customer_group"
|
||||
elif party_type == "Supplier":
|
||||
self.party_map = dict(((r.name, r) for r in frappe.db.sql("""select {0}, {1}, {2} from `tab{3}`"""
|
||||
.format("name", "supplier_name", "supplier_type", party_type), as_dict=True)))
|
||||
select_fields = "name, supplier_name, supplier_type"
|
||||
|
||||
self.party_map = dict(((r.name, r) for r in frappe.db.sql("select {0} from `tab{1}`"
|
||||
.format(select_fields, party_type), as_dict=True)))
|
||||
|
||||
return self.party_map
|
||||
|
||||
@@ -251,6 +257,19 @@ class ReceivablePayableReport(object):
|
||||
conditions.append("party=%s")
|
||||
values.append(self.filters.get(party_type_field))
|
||||
|
||||
if party_type_field=="customer":
|
||||
if self.filters.get("customer_group"):
|
||||
lft, rgt = frappe.db.get_value("Customer Group",
|
||||
self.filters.get("customer_group"), ["lft", "rgt"])
|
||||
|
||||
conditions.append("""party in (select name from tabCustomer
|
||||
where exists(select name from `tabCustomer Group` where lft >= {0} and rgt <= {1}
|
||||
and name=tabCustomer.customer_group))""".format(lft, rgt))
|
||||
|
||||
if self.filters.get("credit_days_based_on"):
|
||||
conditions.append("party in (select name from tabCustomer where credit_days_based_on=%s)")
|
||||
values.append(self.filters.get("credit_days_based_on"))
|
||||
|
||||
return " and ".join(conditions), values
|
||||
|
||||
def get_gl_entries_for(self, party, party_type, against_voucher_type, against_voucher):
|
||||
|
||||
@@ -16,6 +16,21 @@ frappe.query_reports["Accounts Receivable Summary"] = {
|
||||
"fieldtype": "Link",
|
||||
"options": "Customer"
|
||||
},
|
||||
{
|
||||
"fieldname":"customer_group",
|
||||
"label": __("Customer Group"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Customer Group"
|
||||
},
|
||||
{
|
||||
"fieldname":"credit_days_based_on",
|
||||
"label": __("Credit Days Based On"),
|
||||
"fieldtype": "Select",
|
||||
"options": "" + NEWLINE + "Fixed Days" + NEWLINE + "Last Day of the Next Month"
|
||||
},
|
||||
{
|
||||
"fieldtype": "Break",
|
||||
},
|
||||
{
|
||||
"fieldname":"report_date",
|
||||
"label": __("Date"),
|
||||
@@ -29,9 +44,6 @@ frappe.query_reports["Accounts Receivable Summary"] = {
|
||||
"options": 'Posting Date' + NEWLINE + 'Due Date',
|
||||
"default": "Posting Date"
|
||||
},
|
||||
{
|
||||
"fieldtype": "Break",
|
||||
},
|
||||
{
|
||||
"fieldname":"range1",
|
||||
"label": __("Ageing Range 1"),
|
||||
|
||||
@@ -27,7 +27,10 @@ class AccountsReceivableSummary(ReceivablePayableReport):
|
||||
str(self.filters.range3) + _("-Above") + ":Currency/currency:100"]
|
||||
|
||||
if args.get("party_type") == "Customer":
|
||||
columns += [_("Territory") + ":Link/Territory:80"]
|
||||
columns += [
|
||||
_("Territory") + ":Link/Territory:80",
|
||||
_("Customer Group") + ":Link/Customer Group:120"
|
||||
]
|
||||
if args.get("party_type") == "Supplier":
|
||||
columns += [_("Supplier Type") + ":Link/Supplier Type:80"]
|
||||
|
||||
@@ -58,7 +61,7 @@ class AccountsReceivableSummary(ReceivablePayableReport):
|
||||
]
|
||||
|
||||
if args.get("party_type") == "Customer":
|
||||
row += [self.get_territory(party)]
|
||||
row += [self.get_territory(party), self.get_customer_group(party)]
|
||||
if args.get("party_type") == "Supplier":
|
||||
row += [self.get_supplier_type(party)]
|
||||
|
||||
@@ -107,7 +110,7 @@ class AccountsReceivableSummary(ReceivablePayableReport):
|
||||
if args.get("party_type") == "Supplier":
|
||||
cols += ["supplier_type", "remarks"]
|
||||
if args.get("party_type") == "Customer":
|
||||
cols += ["territory", "remarks"]
|
||||
cols += ["territory", "customer_group", "remarks"]
|
||||
|
||||
return self.make_data_dict(cols, voucherwise_data)
|
||||
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
|
||||
frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
||||
frappe.query_reports["Balance Sheet"] = erpnext.financial_statements;
|
||||
|
||||
frappe.query_reports["Balance Sheet"]["filters"].push({
|
||||
"fieldname": "accumulated_values",
|
||||
"label": __("Accumulated Values"),
|
||||
"fieldtype": "Check",
|
||||
"default": 1
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -8,11 +8,20 @@ from frappe.utils import flt, cint
|
||||
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
|
||||
|
||||
def execute(filters=None):
|
||||
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year, filters.periodicity, filters.company)
|
||||
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
||||
filters.periodicity, company=filters.company)
|
||||
|
||||
asset = get_data(filters.company, "Asset", "Debit", period_list, only_current_fiscal_year=False)
|
||||
liability = get_data(filters.company, "Liability", "Credit", period_list, only_current_fiscal_year=False)
|
||||
equity = get_data(filters.company, "Equity", "Credit", period_list, only_current_fiscal_year=False)
|
||||
asset = get_data(filters.company, "Asset", "Debit", period_list,
|
||||
only_current_fiscal_year=False, filters=filters,
|
||||
accumulated_values=filters.accumulated_values)
|
||||
|
||||
liability = get_data(filters.company, "Liability", "Credit", period_list,
|
||||
only_current_fiscal_year=False, filters=filters,
|
||||
accumulated_values=filters.accumulated_values)
|
||||
|
||||
equity = get_data(filters.company, "Equity", "Credit", period_list,
|
||||
only_current_fiscal_year=False, filters=filters,
|
||||
accumulated_values=filters.accumulated_values)
|
||||
|
||||
provisional_profit_loss, total_credit = get_provisional_profit_loss(asset, liability, equity,
|
||||
period_list, filters.company)
|
||||
@@ -43,9 +52,9 @@ def execute(filters=None):
|
||||
if total_credit:
|
||||
data.append(total_credit)
|
||||
|
||||
columns = get_columns(filters.periodicity, period_list, company=filters.company)
|
||||
columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, company=filters.company)
|
||||
|
||||
chart = get_chart_data(columns, asset, liability, equity)
|
||||
chart = get_chart_data(filters, columns, asset, liability, equity)
|
||||
|
||||
return columns, data, message, chart
|
||||
|
||||
@@ -102,12 +111,13 @@ def check_opening_balance(asset, liability, equity):
|
||||
opening_balance -= flt(liability[0].get("opening_balance", 0), float_precision)
|
||||
if equity:
|
||||
opening_balance -= flt(equity[0].get("opening_balance", 0), float_precision)
|
||||
|
||||
|
||||
opening_balance = flt(opening_balance, float_precision)
|
||||
if opening_balance:
|
||||
return _("Previous Financial Year is not closed"),opening_balance
|
||||
return None,None
|
||||
|
||||
def get_chart_data(columns, asset, liability, equity):
|
||||
def get_chart_data(filters, columns, asset, liability, equity):
|
||||
x_intervals = ['x'] + [d.get("label") for d in columns[2:]]
|
||||
|
||||
asset_data, liability_data, equity_data = [], [], []
|
||||
@@ -128,9 +138,14 @@ def get_chart_data(columns, asset, liability, equity):
|
||||
if equity_data:
|
||||
columns.append(["Equity"] + equity_data)
|
||||
|
||||
return {
|
||||
chart = {
|
||||
"data": {
|
||||
'x': 'x',
|
||||
'columns': columns
|
||||
}
|
||||
}
|
||||
|
||||
if not filters.accumulated_values:
|
||||
chart["chart_type"] = "bar"
|
||||
|
||||
return chart
|
||||
@@ -22,7 +22,8 @@ frappe.query_reports["Bank Clearance Summary"] = {
|
||||
"fieldtype": "Link",
|
||||
"options": "Account",
|
||||
"reqd": 1,
|
||||
"default": locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"],
|
||||
"default": frappe.defaults.get_user_default("Company")?
|
||||
locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"]: "",
|
||||
"get_query": function() {
|
||||
return {
|
||||
"query": "erpnext.controllers.queries.get_account_list",
|
||||
|
||||
@@ -8,7 +8,8 @@ frappe.query_reports["Bank Reconciliation Statement"] = {
|
||||
"label": __("Bank Account"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Account",
|
||||
"default": locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"],
|
||||
"default": frappe.defaults.get_user_default("Company")?
|
||||
locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"]: "",
|
||||
"reqd": 1,
|
||||
"get_query": function() {
|
||||
return {
|
||||
|
||||
@@ -11,7 +11,7 @@ from erpnext.accounts.utils import get_fiscal_year
|
||||
|
||||
def execute(filters=None):
|
||||
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
||||
filters.periodicity, filters.company)
|
||||
filters.periodicity, filters.accumulated_values, filters.company)
|
||||
|
||||
operation_accounts = {
|
||||
"section_name": "Operations",
|
||||
|
||||
@@ -13,12 +13,16 @@
|
||||
height: 37px;
|
||||
}
|
||||
</style>
|
||||
{% var letterhead= filters.letter_head || frappe.get_doc(":Company", filters.company).default_letter_head || frappe.defaults.get_default("letter_head"); %}
|
||||
{% if(letterhead) { %}
|
||||
<div style="margin-bottom: 7px;" class="text-center">
|
||||
{%= frappe.boot.letter_heads[frappe.get_doc(":Company", filters.company).default_letter_head || frappe.defaults.get_default("letter_head")] %}
|
||||
{%= frappe.boot.letter_heads[letterhead].header %}
|
||||
</div>
|
||||
{% } %}
|
||||
<h2 class="text-center">{%= __(report.report_name) %}</h2>
|
||||
<h4 class="text-center">{%= filters.company %}</h3>
|
||||
<h4 class="text-center">{%= filters.fiscal_year %}</h3>
|
||||
<h3 class="text-center">{%= filters.company %}</h3>
|
||||
<h3 class="text-center">{%= filters.fiscal_year %}</h3>
|
||||
<h5 class="text-center">{%= __("Currency") %} : {%= erpnext.get_currency(filters.company) %} </h4>
|
||||
{% if (filters.from_date) { %}
|
||||
<h4 class="text-center">{%= dateutil.str_to_user(filters.from_date) %} - {%= dateutil.str_to_user(filters.to_date) %}</h3>
|
||||
{% } %}
|
||||
@@ -47,7 +51,7 @@
|
||||
<td class="text-right">
|
||||
{% var fieldname = report.columns[i].field; %}
|
||||
{% if (!is_null(row[fieldname])) { %}
|
||||
{%= format_currency(row[fieldname], row.currency) %}
|
||||
{%= format_number(row[fieldname], null)%}
|
||||
{% } %}
|
||||
</td>
|
||||
{% } %}
|
||||
|
||||
@@ -4,9 +4,13 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt, getdate, get_first_day, add_months, add_days, formatdate
|
||||
from frappe.utils import (flt, getdate, get_first_day, get_last_day, date_diff,
|
||||
add_months, add_days, formatdate, cint)
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
|
||||
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, company):
|
||||
|
||||
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
|
||||
company=None, reset_period_on_fy_change=True):
|
||||
"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
|
||||
Periodicity can be (Yearly, Quarterly, Monthly)"""
|
||||
|
||||
@@ -48,7 +52,8 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, company):
|
||||
# if a fiscal year ends before a 12 month period
|
||||
period.to_date = year_end_date
|
||||
|
||||
period.to_date_fiscal_year = get_date_fiscal_year(period.to_date, company)
|
||||
period.to_date_fiscal_year = get_fiscal_year(period.to_date, company=company)[0]
|
||||
period.from_date_fiscal_year_start_date = get_fiscal_year(period.from_date, company=company)[1]
|
||||
|
||||
period_list.append(period)
|
||||
|
||||
@@ -58,11 +63,17 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, company):
|
||||
# common processing
|
||||
for opts in period_list:
|
||||
key = opts["to_date"].strftime("%b_%Y").lower()
|
||||
if periodicity == "Monthly":
|
||||
if periodicity == "Monthly" and not accumulated_values:
|
||||
label = formatdate(opts["to_date"], "MMM YYYY")
|
||||
else:
|
||||
label = get_label(periodicity, opts["from_date"], opts["to_date"])
|
||||
|
||||
if not accumulated_values:
|
||||
label = get_label(periodicity, opts["from_date"], opts["to_date"])
|
||||
else:
|
||||
if reset_period_on_fy_change:
|
||||
label = get_label(periodicity, opts.from_date_fiscal_year_start_date, opts["to_date"])
|
||||
else:
|
||||
label = get_label(periodicity, period_list[0].from_date, opts["to_date"])
|
||||
|
||||
opts.update({
|
||||
"key": key.replace(" ", "_").replace("-", "_"),
|
||||
"label": label,
|
||||
@@ -139,16 +150,13 @@ def calculate_values(accounts_by_name, gl_entries_by_account, period_list, accum
|
||||
|
||||
if entry.posting_date <= period.to_date:
|
||||
if (accumulated_values or entry.posting_date >= period.from_date) and \
|
||||
(not ignore_accumulated_values_for_fy or entry.fiscal_year == period.to_date_fiscal_year):
|
||||
(not ignore_accumulated_values_for_fy or
|
||||
entry.fiscal_year == period.to_date_fiscal_year):
|
||||
d[period.key] = d.get(period.key, 0.0) + flt(entry.debit) - flt(entry.credit)
|
||||
|
||||
if entry.posting_date < period_list[0].year_start_date:
|
||||
d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
|
||||
|
||||
def get_date_fiscal_year(date, company):
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
return get_fiscal_year(date, company=company)[0]
|
||||
|
||||
def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values):
|
||||
"""accumulate children's values in parent accounts"""
|
||||
for d in reversed(accounts):
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{% var letterhead= filters.letter_head || frappe.get_doc(":Company", filters.company).default_letter_head || frappe.defaults.get_default("letter_head"); %}
|
||||
{% if(letterhead) { %}
|
||||
<div style="margin-bottom: 7px;" class="text-center">
|
||||
{%= frappe.boot.letter_heads[filters.letter_head || frappe.get_doc(":Company", filters.company).default_letter_head || frappe.defaults.get_default("letter_head")] %}
|
||||
{%= frappe.boot.letter_heads[letterhead].header %}
|
||||
</div>
|
||||
{% } %}
|
||||
<h2 class="text-center">{%= __("Statement of Account") %}</h2>
|
||||
<h4 class="text-center">{%= (filters.party || filters.account) && ((filters.party || filters.account) + ", ") || "" %} {%= filters.company %}</h4>
|
||||
<h5 class="text-center">
|
||||
|
||||
@@ -66,7 +66,8 @@ def set_account_currency(filters):
|
||||
if gle_currency:
|
||||
account_currency = gle_currency
|
||||
else:
|
||||
account_currency = frappe.db.get_value(filters.party_type, filters.party, "default_currency")
|
||||
account_currency = None if filters.party_type == "Employee" else \
|
||||
frappe.db.get_value(filters.party_type, filters.party, "default_currency")
|
||||
|
||||
filters["account_currency"] = account_currency or filters.company_currency
|
||||
|
||||
|
||||
@@ -9,12 +9,15 @@ from erpnext.accounts.report.financial_statements import (get_period_list, get_c
|
||||
|
||||
def execute(filters=None):
|
||||
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
||||
filters.periodicity, filters.company)
|
||||
filters.periodicity, filters.accumulated_values, filters.company)
|
||||
|
||||
income = get_data(filters.company, "Income", "Credit", period_list, filters = filters,
|
||||
accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
|
||||
accumulated_values=filters.accumulated_values,
|
||||
ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
|
||||
|
||||
expense = get_data(filters.company, "Expense", "Debit", period_list, filters=filters,
|
||||
accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
|
||||
accumulated_values=filters.accumulated_values,
|
||||
ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
|
||||
|
||||
net_profit_loss = get_net_profit_loss(income, expense, period_list, filters.company)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from frappe.utils import flt
|
||||
from frappe import msgprint, _
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
if not filters: filters = frappe._dict({})
|
||||
|
||||
invoice_list = get_invoices(filters)
|
||||
columns, income_accounts, tax_accounts = get_columns(invoice_list)
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import frappe.defaults
|
||||
from frappe.utils import nowdate, cstr, flt, cint, now, getdate
|
||||
from frappe import throw, _
|
||||
from frappe.utils import formatdate
|
||||
from frappe.utils import formatdate, get_number_format_info
|
||||
|
||||
# imported to enable erpnext.accounts.utils.get_account_currency
|
||||
from erpnext.accounts.doctype.account.account import get_account_currency
|
||||
import frappe.defaults
|
||||
from erpnext.accounts.report.financial_statements import sort_root_accounts
|
||||
|
||||
class FiscalYearError(frappe.ValidationError): pass
|
||||
|
||||
@@ -537,15 +536,14 @@ def get_stock_and_account_difference(account_list=None, posting_date=None):
|
||||
|
||||
return difference
|
||||
|
||||
def get_currency_precision(currency=None):
|
||||
if not currency:
|
||||
currency = frappe.db.get_value("Company",
|
||||
frappe.db.get_default("Company"), "default_currency", cache=True)
|
||||
currency_format = frappe.db.get_value("Currency", currency, "number_format", cache=True)
|
||||
|
||||
from frappe.utils import get_number_format_info
|
||||
return get_number_format_info(currency_format)[2]
|
||||
|
||||
def get_currency_precision():
|
||||
precision = cint(frappe.db.get_default("currency_precision"))
|
||||
if not precision:
|
||||
number_format = frappe.db.get_default("number_format") or "#,###.##"
|
||||
precision = get_number_format_info(number_format)[2]
|
||||
|
||||
return precision
|
||||
|
||||
def get_stock_rbnb_difference(posting_date, company):
|
||||
stock_items = frappe.db.sql_list("""select distinct item_code
|
||||
from `tabStock Ledger Entry` where company=%s""", company)
|
||||
@@ -653,6 +651,8 @@ def get_companies():
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_children():
|
||||
from erpnext.accounts.report.financial_statements import sort_root_accounts
|
||||
|
||||
args = frappe.local.form_dict
|
||||
doctype, company = args['doctype'], args['company']
|
||||
fieldname = frappe.db.escape(doctype.lower().replace(' ','_'))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "naming_series:",
|
||||
@@ -341,7 +342,7 @@
|
||||
"remember_last_selected_value": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -1207,6 +1208,8 @@
|
||||
"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",
|
||||
@@ -3185,18 +3188,18 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "fa fa-file-text",
|
||||
"idx": 105,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-28 18:20:15.650815",
|
||||
"modified": "2017-04-18 18:49:49.535066",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
@@ -3294,4 +3297,4 @@
|
||||
"title_field": "title",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
}
|
||||
@@ -340,7 +340,8 @@ def make_stock_entry(purchase_order, item_code):
|
||||
stock_entry.purchase_order = purchase_order.name
|
||||
stock_entry.supplier = purchase_order.supplier
|
||||
stock_entry.supplier_name = purchase_order.supplier_name
|
||||
stock_entry.supplier_address = purchase_order.address_display
|
||||
stock_entry.supplier_address = purchase_order.supplier_address
|
||||
stock_entry.address_display = purchase_order.address_display
|
||||
stock_entry.company = purchase_order.company
|
||||
stock_entry.from_bom = 1
|
||||
po_item = [d for d in purchase_order.items if d.item_code == item_code][0]
|
||||
|
||||
@@ -3,6 +3,10 @@ from frappe import _
|
||||
def get_data():
|
||||
return {
|
||||
'fieldname': 'purchase_order',
|
||||
'non_standard_fieldnames': {
|
||||
'Journal Entry': 'reference_name',
|
||||
'Payment Entry': 'reference_name'
|
||||
},
|
||||
'internal_links': {
|
||||
'Material Request': ['items', 'material_request'],
|
||||
'Supplier Quotation': ['items', 'supplier_quotation'],
|
||||
@@ -13,6 +17,10 @@ def get_data():
|
||||
'label': _('Related'),
|
||||
'items': ['Purchase Receipt', 'Purchase Invoice']
|
||||
},
|
||||
{
|
||||
'label': _('Payment'),
|
||||
'items': ['Payment Entry', 'Journal Entry']
|
||||
},
|
||||
{
|
||||
'label': _('Reference'),
|
||||
'items': ['Material Request', 'Supplier Quotation', 'Project']
|
||||
@@ -20,6 +28,6 @@ def get_data():
|
||||
{
|
||||
'label': _('Sub-contracting'),
|
||||
'items': ['Stock Entry']
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "hash",
|
||||
@@ -98,7 +99,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -156,7 +157,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -799,6 +800,7 @@
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "100px",
|
||||
@@ -1647,17 +1649,17 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-17 16:44:55.434162",
|
||||
"modified": "2017-04-25 18:49:08.604055",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Item",
|
||||
|
||||
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import flt, cstr, cint
|
||||
from frappe import _
|
||||
import json
|
||||
|
||||
from erpnext.stock.doctype.item.item import get_last_purchase_details
|
||||
from erpnext.stock.doctype.item.item import validate_end_of_life
|
||||
@@ -78,3 +79,25 @@ def check_for_closed_status(doctype, docname):
|
||||
if status == "Closed":
|
||||
frappe.throw(_("{0} {1} status is {2}").format(doctype, docname, status), frappe.InvalidStatusError)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_linked_material_requests(items):
|
||||
items = json.loads(items)
|
||||
mr_list = []
|
||||
for item in items:
|
||||
material_request = frappe.db.sql("""SELECT distinct mr.name AS mr_name,
|
||||
(mr_item.qty - mr_item.ordered_qty) AS qty,
|
||||
mr_item.item_code AS item_code,
|
||||
mr_item.name AS mr_item
|
||||
FROM `tabMaterial Request` mr, `tabMaterial Request Item` mr_item
|
||||
WHERE mr.name = mr_item.parent
|
||||
AND mr_item.item_code = %(item)s
|
||||
AND mr.material_request_type = 'Purchase'
|
||||
AND mr.per_ordered < 99.99
|
||||
AND mr.docstatus = 1
|
||||
AND mr.status != 'Stopped'
|
||||
ORDER BY mr_item.item_code ASC""",{"item": item}, as_dict=1)
|
||||
if material_request:
|
||||
mr_list.append(material_request)
|
||||
|
||||
return mr_list
|
||||
|
||||
|
||||
@@ -159,6 +159,11 @@ def get_data():
|
||||
"is_query_report": True,
|
||||
"doctype": "Journal Entry"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Bank Guarantee",
|
||||
"doctype": "Bank Guarantee"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -32,6 +32,12 @@ def get_data():
|
||||
"label": _("Reports"),
|
||||
"icon": "fa fa-list",
|
||||
"items": [
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Lead Details",
|
||||
"doctype": "Lead"
|
||||
},
|
||||
{
|
||||
"type": "page",
|
||||
"name": "sales-funnel",
|
||||
@@ -40,15 +46,15 @@ def get_data():
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"name": "Minutes to First Response for Opportunity",
|
||||
"doctype": "Opportunity",
|
||||
"name": "Prospects Engaged But Not Converted",
|
||||
"doctype": "Lead",
|
||||
"is_query_report": True
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Lead Details",
|
||||
"doctype": "Lead"
|
||||
"name": "Minutes to First Response for Opportunity",
|
||||
"doctype": "Opportunity",
|
||||
"is_query_report": True
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
@@ -62,6 +68,18 @@ def get_data():
|
||||
"name": "Inactive Customers",
|
||||
"doctype": "Sales Order"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Campaign Efficiency",
|
||||
"doctype": "Lead"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Lead Owner Efficiency",
|
||||
"doctype": "Lead"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -106,7 +106,7 @@ def get_data():
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Course Schedule",
|
||||
"route": "Calendar/Course Schedule"
|
||||
"route": "List/Course Schedule/Calendar"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
@@ -205,6 +205,10 @@ def get_data():
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Academic Year"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "School Settings"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -186,15 +186,19 @@ class AccountsController(TransactionBase):
|
||||
|
||||
ret = get_item_details(args)
|
||||
|
||||
|
||||
for fieldname, value in ret.items():
|
||||
if item.meta.get_field(fieldname) and value is not None:
|
||||
if (item.get(fieldname) is None or fieldname in force_item_fields):
|
||||
item.set(fieldname, value)
|
||||
|
||||
elif fieldname == "cost_center" and not item.get("cost_center"):
|
||||
elif fieldname in ['cost_center', 'conversion_factor'] and not item.get(fieldname):
|
||||
item.set(fieldname, value)
|
||||
|
||||
elif fieldname == "serial_no":
|
||||
stock_qty = item.get("stock_qty") * -1 if item.get("stock_qty") < 0 else item.get("stock_qty")
|
||||
if stock_qty != len(item.get('serial_no').split('\n')):
|
||||
item.set(fieldname, value)
|
||||
|
||||
elif fieldname == "conversion_factor" and not item.get("conversion_factor"):
|
||||
item.set(fieldname, value)
|
||||
|
||||
|
||||
@@ -42,10 +42,8 @@ def make_variant_based_on_manufacturer(template, manufacturer, manufacturer_part
|
||||
|
||||
copy_attributes_to_variant(template, variant)
|
||||
|
||||
variant.append("manufacturers", {
|
||||
"manufacturer": manufacturer,
|
||||
"manufacturer_part_no": manufacturer_part_no
|
||||
})
|
||||
variant.manufacturer = manufacturer
|
||||
variant.manufacturer_part_no = manufacturer_part_no
|
||||
|
||||
variant.item_code = append_number_if_name_exists('Item', template.name)
|
||||
|
||||
|
||||
@@ -106,24 +106,25 @@ def validate_returned_items(doc):
|
||||
|
||||
def validate_quantity(doc, args, ref, valid_items, already_returned_items):
|
||||
fields = ['qty']
|
||||
if doc.doctype in ['Purchase Invoice', 'Purchase Receipt']:
|
||||
if doc.doctype in ['Purchase Receipt', 'Purchase Invoice']:
|
||||
fields.extend(['received_qty', 'rejected_qty'])
|
||||
|
||||
already_returned_data = already_returned_items.get(args.item_code) or {}
|
||||
|
||||
for column in fields:
|
||||
return_qty = flt(already_returned_data.get(column, 0)) if len(already_returned_data) > 0 else 0
|
||||
referenced_qty = ref.get(column)
|
||||
max_return_qty = flt(referenced_qty) - return_qty
|
||||
returned_qty = flt(already_returned_data.get(column, 0)) if len(already_returned_data) > 0 else 0
|
||||
reference_qty = ref.get(column)
|
||||
max_returnable_qty = flt(reference_qty) - returned_qty
|
||||
label = column.replace('_', ' ').title()
|
||||
|
||||
if flt(args.get(column)) > 0:
|
||||
frappe.throw(_("{0} must be negative in return document").format(label))
|
||||
elif return_qty >= referenced_qty and flt(args.get(column)) != 0:
|
||||
frappe.throw(_("Item {0} has already been returned").format(args.item_code), StockOverReturnError)
|
||||
elif abs(args.get(column)) > max_return_qty:
|
||||
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
|
||||
.format(args.idx, referenced_qty, args.item_code), StockOverReturnError)
|
||||
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)) > max_returnable_qty:
|
||||
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
|
||||
.format(args.idx, reference_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
|
||||
|
||||
@@ -41,7 +41,7 @@ class SellingController(StockController):
|
||||
|
||||
# set contact and address details for customer, if they are not mentioned
|
||||
self.set_missing_lead_customer_details()
|
||||
self.set_price_list_and_item_details()
|
||||
self.set_price_list_and_item_details(for_validate=for_validate)
|
||||
|
||||
def set_missing_lead_customer_details(self):
|
||||
if getattr(self, "customer", None):
|
||||
@@ -60,9 +60,9 @@ class SellingController(StockController):
|
||||
posting_date=self.get('transaction_date') or self.get('posting_date'),
|
||||
company=self.company))
|
||||
|
||||
def set_price_list_and_item_details(self):
|
||||
def set_price_list_and_item_details(self, for_validate=False):
|
||||
self.set_price_list_currency("Selling")
|
||||
self.set_missing_item_details()
|
||||
self.set_missing_item_details(for_validate=for_validate)
|
||||
|
||||
def apply_shipping_rule(self):
|
||||
if self.shipping_rule:
|
||||
@@ -203,7 +203,7 @@ class SellingController(StockController):
|
||||
if p.parent_detail_docname == d.name and p.parent_item == d.item_code:
|
||||
# the packing details table's qty is already multiplied with parent's qty
|
||||
il.append(frappe._dict({
|
||||
'warehouse': p.warehouse,
|
||||
'warehouse': p.warehouse or d.warehouse,
|
||||
'item_code': p.item_code,
|
||||
'qty': flt(p.qty),
|
||||
'uom': p.uom,
|
||||
|
||||
@@ -119,7 +119,7 @@ class StatusUpdater(Document):
|
||||
self.status = s[0]
|
||||
break
|
||||
elif s[1].startswith("eval:"):
|
||||
if eval(s[1][5:]):
|
||||
if frappe.safe_eval(s[1][5:], None, { "self": self.as_dict(), "getdate": getdate, "nowdate": nowdate }):
|
||||
self.status = s[0]
|
||||
break
|
||||
elif getattr(self, s[1])():
|
||||
|
||||
@@ -54,14 +54,14 @@ class StockController(AccountsController):
|
||||
|
||||
self.check_expense_account(item_row)
|
||||
|
||||
# If item is not a sample item
|
||||
# If the item does not have the allow zero valuation rate flag set
|
||||
# and ( valuation rate not mentioned in an incoming entry
|
||||
# or incoming entry not found while delivering the item),
|
||||
# try to pick valuation rate from previous sle or Item master and update in SLE
|
||||
# Otherwise, throw an exception
|
||||
|
||||
if not sle.stock_value_difference and self.doctype != "Stock Reconciliation" \
|
||||
and not item_row.get("is_sample_item"):
|
||||
and not item_row.get("allow_zero_valuation_rate"):
|
||||
|
||||
sle = self.update_stock_ledger_entries(sle)
|
||||
|
||||
@@ -177,6 +177,19 @@ class StockController(AccountsController):
|
||||
stock_ledger.setdefault(sle.voucher_detail_no, []).append(sle)
|
||||
return stock_ledger
|
||||
|
||||
def make_batches(self, warehouse_field):
|
||||
'''Create batches if required. Called before submit'''
|
||||
for d in self.items:
|
||||
if d.get(warehouse_field) and not d.batch_no:
|
||||
has_batch_no, create_new_batch = frappe.db.get_value('Item', d.item_code, ['has_batch_no', 'create_new_batch'])
|
||||
if has_batch_no and create_new_batch:
|
||||
d.batch_no = frappe.get_doc(dict(
|
||||
doctype='Batch',
|
||||
item=d.item_code,
|
||||
supplier=getattr(self, 'supplier', None),
|
||||
reference_doctype=self.doctype,
|
||||
reference_name=self.name)).insert().name
|
||||
|
||||
def make_adjustment_entry(self, expected_gle, voucher_obj):
|
||||
from erpnext.accounts.utils import get_stock_and_account_difference
|
||||
account_list = [d.account for d in expected_gle]
|
||||
|
||||
@@ -60,6 +60,7 @@ class calculate_taxes_and_totals(object):
|
||||
|
||||
if item.doctype in ['Quotation Item', 'Sales Order Item', 'Delivery Note Item', 'Sales Invoice Item']:
|
||||
item.total_margin = self.calculate_margin(item)
|
||||
|
||||
item.rate = flt(item.total_margin * (1.0 - (item.discount_percentage / 100.0)), item.precision("rate"))\
|
||||
if item.total_margin > 0 else item.rate
|
||||
|
||||
@@ -404,11 +405,14 @@ class calculate_taxes_and_totals(object):
|
||||
self.doc.total_advance = flt(total_allocated_amount, self.doc.precision("total_advance"))
|
||||
|
||||
if self.doc.party_account_currency == self.doc.currency:
|
||||
invoice_total = self.doc.grand_total
|
||||
else:
|
||||
invoice_total = flt(self.doc.grand_total * self.doc.conversion_rate,
|
||||
invoice_total = flt(self.doc.grand_total - flt(self.doc.write_off_amount),
|
||||
self.doc.precision("grand_total"))
|
||||
|
||||
else:
|
||||
base_write_off_amount = flt(flt(self.doc.write_off_amount) * self.doc.conversion_rate,
|
||||
self.doc.precision("base_write_off_amount"))
|
||||
invoice_total = flt(self.doc.grand_total * self.doc.conversion_rate,
|
||||
self.doc.precision("grand_total")) - base_write_off_amount
|
||||
|
||||
if invoice_total > 0 and self.doc.total_advance > invoice_total:
|
||||
frappe.throw(_("Advance amount cannot be greater than {0} {1}")
|
||||
.format(self.doc.party_account_currency, invoice_total))
|
||||
|
||||
@@ -18,7 +18,7 @@ def get_list_context(context=None):
|
||||
"get_list": get_transaction_list
|
||||
}
|
||||
|
||||
def get_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20):
|
||||
def get_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20, order_by="modified"):
|
||||
from frappe.www.list import get_list
|
||||
user = frappe.session.user
|
||||
key = None
|
||||
|
||||
@@ -574,7 +574,7 @@
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Territory",
|
||||
"length": 0,
|
||||
@@ -1152,7 +1152,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-03-12 21:55:21.598112",
|
||||
"modified": "2017-04-04 01:21:02.165730",
|
||||
"modified_by": "Administrator",
|
||||
"module": "CRM",
|
||||
"name": "Opportunity",
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
frappe.query_reports["Campaign Efficiency"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname": "from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.defaults.get_user_default("year_start_date"),
|
||||
},
|
||||
{
|
||||
"fieldname": "to_date",
|
||||
"label": __("To Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.defaults.get_user_default("year_end_date"),
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2017-04-17 00:20:27.248275",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"letter_head": "",
|
||||
"modified": "2017-04-17 00:20:27.248275",
|
||||
"modified_by": "Administrator",
|
||||
"module": "CRM",
|
||||
"name": "Campaign Efficiency",
|
||||
"owner": "Administrator",
|
||||
"ref_doctype": "Lead",
|
||||
"report_name": "Campaign Efficiency",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Sales User"
|
||||
},
|
||||
{
|
||||
"role": "Sales Manager"
|
||||
},
|
||||
{
|
||||
"role": "System Manager"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
|
||||
def execute(filters=None):
|
||||
columns, data = [], []
|
||||
columns=get_columns()
|
||||
data=get_lead_data(filters, "Campaign Name")
|
||||
return columns, data
|
||||
|
||||
def get_columns():
|
||||
return [
|
||||
_("Campaign Name") + ":data:130",
|
||||
_("Lead Count") + ":Int:80",
|
||||
_("Opp Count") + ":Int:80",
|
||||
_("Quot Count") + ":Int:80",
|
||||
_("Order Count") + ":Int:100",
|
||||
_("Order Value") + ":Float:100",
|
||||
_("Opp/Lead %") + ":Float:100",
|
||||
_("Quot/Lead %") + ":Float:100",
|
||||
_("Order/Quot %") + ":Float:100"
|
||||
]
|
||||
|
||||
def get_lead_data(filters, based_on):
|
||||
based_on_field = frappe.scrub(based_on)
|
||||
conditions = get_filter_conditions(filters)
|
||||
|
||||
lead_details = frappe.db.sql("""
|
||||
select {based_on_field}, name
|
||||
from `tabLead`
|
||||
where {based_on_field} is not null and {based_on_field} != '' {conditions}
|
||||
""".format(based_on_field=based_on_field, conditions=conditions), filters, as_dict=1)
|
||||
|
||||
lead_map = frappe._dict()
|
||||
for d in lead_details:
|
||||
lead_map.setdefault(d.get(based_on_field), []).append(d.name)
|
||||
|
||||
data = []
|
||||
for based_on_value, leads in lead_map.items():
|
||||
row = {
|
||||
based_on: based_on_value,
|
||||
"Lead Count": len(leads)
|
||||
}
|
||||
row["Quot Count"]= get_lead_quotation_count(leads)
|
||||
row["Opp Count"] = get_lead_opp_count(leads)
|
||||
row["Order Count"] = get_quotation_ordered_count(leads)
|
||||
row["Order Value"] = get_order_amount(leads)
|
||||
|
||||
row["Opp/Lead %"] = row["Opp Count"] / row["Lead Count"] * 100
|
||||
row["Quot/Lead %"] = row["Quot Count"] / row["Lead Count"] * 100
|
||||
|
||||
row["Order/Quot %"] = row["Order Count"] / (row["Quot Count"] or 1) * 100
|
||||
|
||||
data.append(row)
|
||||
|
||||
return data
|
||||
|
||||
def get_filter_conditions(filters):
|
||||
conditions=""
|
||||
if filters.from_date:
|
||||
conditions += " and date(creation) >= %(from_date)s"
|
||||
if filters.to_date:
|
||||
conditions += " and date(creation) <= %(to_date)s"
|
||||
|
||||
return conditions
|
||||
|
||||
def get_lead_quotation_count(leads):
|
||||
return frappe.db.sql("""select count(name) from `tabQuotation`
|
||||
where lead in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0]
|
||||
|
||||
def get_lead_opp_count(leads):
|
||||
return frappe.db.sql("""select count(name) from `tabOpportunity`
|
||||
where lead in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0]
|
||||
|
||||
def get_quotation_ordered_count(leads):
|
||||
return frappe.db.sql("""select count(name)
|
||||
from `tabQuotation` where status = 'Ordered'
|
||||
and lead in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0]
|
||||
|
||||
def get_order_amount(leads):
|
||||
return frappe.db.sql("""select sum(base_net_amount)
|
||||
from `tabSales Order Item`
|
||||
where prevdoc_docname in (
|
||||
select name from `tabQuotation` where status = 'Ordered'
|
||||
and lead in (%s)
|
||||
)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0]
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
frappe.query_reports["Lead Owner Efficiency"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname": "from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.defaults.get_user_default("year_start_date"),
|
||||
},
|
||||
{
|
||||
"fieldname": "to_date",
|
||||
"label": __("To Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.defaults.get_user_default("year_end_date"),
|
||||
}
|
||||
]};
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2017-04-17 00:39:39.885905",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"letter_head": "",
|
||||
"modified": "2017-04-17 00:45:10.139004",
|
||||
"modified_by": "Administrator",
|
||||
"module": "CRM",
|
||||
"name": "Lead Owner Efficiency",
|
||||
"owner": "Administrator",
|
||||
"ref_doctype": "Lead",
|
||||
"report_name": "Lead Owner Efficiency",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Sales User"
|
||||
},
|
||||
{
|
||||
"role": "Sales Manager"
|
||||
},
|
||||
{
|
||||
"role": "System Manager"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from erpnext.crm.report.campaign_efficiency.campaign_efficiency import get_lead_data
|
||||
|
||||
def execute(filters=None):
|
||||
columns, data = [], []
|
||||
columns=get_columns()
|
||||
data=get_lead_data(filters, "Lead Owner")
|
||||
return columns, data
|
||||
|
||||
def get_columns():
|
||||
return [
|
||||
_("Lead Owner") + ":Data:130",
|
||||
_("Lead Count") + ":Int:80",
|
||||
_("Opp Count") + ":Int:80",
|
||||
_("Quot Count") + ":Int:80",
|
||||
_("Order Count") + ":Int:100",
|
||||
_("Order Value") + ":Float:100",
|
||||
_("Opp/Lead %") + ":Float:100",
|
||||
_("Quot/Lead %") + ":Float:100",
|
||||
_("Order/Quot %") + ":Float:100"
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.query_reports["Prospects Engaged But Not Converted"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname": "lead",
|
||||
"label": __("Lead"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Lead"
|
||||
},
|
||||
{
|
||||
"fieldname": "no_of_interaction",
|
||||
"label": __("Number of Interaction"),
|
||||
"fieldtype": "Int",
|
||||
"default": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "lead_age",
|
||||
"label": __("Minimum Lead Age (Days)"),
|
||||
"fieldtype": "Int",
|
||||
"default": 60
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2017-04-04 08:25:40.491063",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-04-04 10:00:10.253224",
|
||||
"modified_by": "Administrator",
|
||||
"module": "CRM",
|
||||
"name": "Prospects Engaged But Not Converted",
|
||||
"owner": "Administrator",
|
||||
"ref_doctype": "Lead",
|
||||
"report_name": "Prospects Engaged But Not Converted",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Sales User"
|
||||
},
|
||||
{
|
||||
"role": "Sales Manager"
|
||||
},
|
||||
{
|
||||
"role": "System Manager"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import add_days, now
|
||||
|
||||
def execute(filters=None):
|
||||
columns, data = [], []
|
||||
set_defaut_value_for_filters(filters)
|
||||
columns = get_columns()
|
||||
data = get_data(filters)
|
||||
|
||||
return columns, data
|
||||
|
||||
def set_defaut_value_for_filters(filters):
|
||||
if not filters.get('no_of_interaction'): filters["no_of_interaction"] = 1
|
||||
if not filters.get('lead_age'): filters["lead_age"] = 60
|
||||
|
||||
def get_columns():
|
||||
return [
|
||||
_("Lead") + ":Link/Lead:100",
|
||||
_("Name") + "::100",
|
||||
_("Organization") + "::100",
|
||||
_("Reference Document") + "::150",
|
||||
_("Reference Name") + ":Dynamic Link/"+_("Reference Document")+":120",
|
||||
_("Last Communication") + ":Data:200",
|
||||
_("Last Communication Date") + ":Date:180"
|
||||
]
|
||||
|
||||
def get_data(filters):
|
||||
lead_details = []
|
||||
lead_filters = get_lead_filters(filters)
|
||||
|
||||
for lead in frappe.get_all('Lead', fields = ['name', 'lead_name', 'company_name'], filters=lead_filters):
|
||||
data = frappe.db.sql("""
|
||||
select
|
||||
`tabCommunication`.reference_doctype, `tabCommunication`.reference_name,
|
||||
`tabCommunication`.content, `tabCommunication`.communication_date
|
||||
from
|
||||
(
|
||||
(select name, lead from `tabOpportunity` where lead = %(lead)s)
|
||||
union
|
||||
(select name, lead from `tabQuotation` where lead = %(lead)s)
|
||||
union
|
||||
(select name, lead from `tabIssue` where lead = %(lead)s and status!='Closed')
|
||||
union
|
||||
(select %(lead)s, %(lead)s)
|
||||
)
|
||||
as ref_document, `tabCommunication`
|
||||
where
|
||||
`tabCommunication`.reference_name = ref_document.name and
|
||||
`tabCommunication`.sent_or_received = 'Received'
|
||||
order by
|
||||
ref_document.lead, `tabCommunication`.creation desc limit %(limit)s""",
|
||||
{'lead': lead.name, 'limit': filters.get('no_of_interaction')})
|
||||
|
||||
for lead_info in data:
|
||||
lead_data = [lead.name, lead.lead_name, lead.company_name] + list(lead_info)
|
||||
lead_details.append(lead_data)
|
||||
|
||||
return lead_details
|
||||
|
||||
def get_lead_filters(filters):
|
||||
lead_creation_date = get_creation_date_based_on_lead_age(filters)
|
||||
lead_filters = [["status", "!=", "Converted"], ["creation", ">", lead_creation_date]]
|
||||
|
||||
if filters.get('lead'):
|
||||
lead_filters.append(["name", "=", filters.get('lead')])
|
||||
return lead_filters
|
||||
|
||||
def get_creation_date_based_on_lead_age(filters):
|
||||
return add_days(now(), (filters.get('lead_age') * -1))
|
||||
@@ -64,8 +64,11 @@ def complete_setup(domain='Manufacturing'):
|
||||
})
|
||||
|
||||
company = erpnext.get_default_company()
|
||||
company.db_set('default_payroll_payable_account',
|
||||
frappe.db.get_value('Account', dict(account_name='Payroll Payable')))
|
||||
|
||||
if company:
|
||||
company_doc = frappe.get_doc("Company", company)
|
||||
company_doc.db_set('default_payroll_payable_account',
|
||||
frappe.db.get_value('Account', dict(account_name='Payroll Payable')))
|
||||
|
||||
def setup_demo_page():
|
||||
# home page should always be "start"
|
||||
|
||||
@@ -18,6 +18,9 @@ def work():
|
||||
# fixed_asset.work() already run
|
||||
return
|
||||
|
||||
# Enable booking asset depreciation entry automatically
|
||||
frappe.db.set_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically", 1)
|
||||
|
||||
# post depreciation entries as on today
|
||||
post_depreciation_entries()
|
||||
|
||||
|
||||
BIN
erpnext/docs/assets/img/accounts/bank-guarantee.png
Normal file
|
After Width: | Height: | Size: 210 KiB |
BIN
erpnext/docs/assets/img/accounts/exempted-item.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
erpnext/docs/assets/img/accounts/item-wise-tax.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
erpnext/docs/assets/img/accounts/tax-calulation.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
erpnext/docs/assets/img/accounts/tax-master.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
0
erpnext/docs/assets/img/crm/report/__init__.py
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
erpnext/docs/assets/img/crm/report/inactive_customers.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
erpnext/docs/assets/img/crm/report/lead.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
BIN
erpnext/docs/assets/img/crm/report/minutes_to_first_response.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 77 KiB |
BIN
erpnext/docs/assets/img/crm/report/sales_funnel.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 50 KiB |
BIN
erpnext/docs/assets/img/stock/batch_view.png
Normal file
|
After Width: | Height: | Size: 167 KiB |
BIN
erpnext/docs/assets/img/stock/item_setup_for_batch.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 11 KiB |
@@ -640,8 +640,8 @@ attach them to the start of each source file to most effectively state
|
||||
the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.</p>
|
||||
|
||||
<pre><code> <one line="" to="" give="" the="" program's="" name="" and="" a="" brief="" idea="" of="" what="" it="" does.="">
|
||||
Copyright (C) <year> <name of="" author="">
|
||||
<pre><code> <one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
40
erpnext/docs/user/manual/en/CRM/crm_reports.md
Normal file
@@ -0,0 +1,40 @@
|
||||
CRM module's reports helps users to get the information about the prospects. Using Following reports, user can analyze the data about prospect's history with a company and will helps user to build strong relationships with them.
|
||||
|
||||
###Lead Details
|
||||
It has data about the leads and their contact and address details.
|
||||
<img alt="Lead Details" class="screenshot"
|
||||
src="{{docs_base_url}}/assets/img/crm/report/lead.png">
|
||||
|
||||
###Sales Funnel
|
||||
By using the sales funnel report, and by quantifying the number of prospects at each stage of the process, you can get an idea of your potential customers.
|
||||
|
||||
More than this, by looking at the way these numbers change over time, you can identify problems in the sales pipeline and take any corrective action at the early stage.
|
||||
|
||||
For example, if you notice that very few communications with the prospects has taken place in a month which might indicate a decrease in the sales. From the next month, organization should make sure that more communications has to take place with the prospects.
|
||||
|
||||
<img alt="Lead Details" class="screenshot"
|
||||
src="{{docs_base_url}}/assets/img/crm/report/sales_funnel.png">
|
||||
|
||||
###Prospects Engaged But Not Converted
|
||||
Using this report, user gets the information about the leads who has shown interest in the business with you but due to some reason they were not converted into the customers.
|
||||
|
||||
<img alt="Lead Details" class="screenshot"
|
||||
src="{{docs_base_url}}/assets/img/crm/report/prospects_engaged_but_not_converted.png">
|
||||
|
||||
###Minutes to First Response for Opportunity
|
||||
Immediacy is so important – and so valued
|
||||
In this internet area, we all expect a quicker response time to any of our query. This report gives you the information about the first response time given to an opportunities or issues. Using this report, the organization can improve their first response time to the prospects which can help to the better sales in the future.
|
||||
|
||||
<img alt="Lead Details" class="screenshot"
|
||||
src="{{docs_base_url}}/assets/img/crm/report/minutes_to_first_response.png">
|
||||
|
||||
###Customer Addresses And Contacts
|
||||
It has data about the customers and their contact and address details.
|
||||
<img alt="Lead Details" class="screenshot"
|
||||
src="{{docs_base_url}}/assets/img/crm/report/customer_address_and_contact.png">
|
||||
|
||||
###Inactive Customers
|
||||
This report shows the list of customers who has not purchased since long time.
|
||||
|
||||
<img alt="Lead Details" class="screenshot"
|
||||
src="{{docs_base_url}}/assets/img/crm/report/inactive_customers.png">
|
||||
@@ -3,4 +3,5 @@ customer
|
||||
opportunity
|
||||
contact
|
||||
newsletter
|
||||
crm_reports
|
||||
setup
|
||||