Compare commits
464 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d959463cbc | ||
|
|
e6d02ecd7f | ||
|
|
4770626bbd | ||
|
|
df045e9f6d | ||
|
|
c10c920914 | ||
|
|
fd99cc8494 | ||
|
|
9ea9ed4256 | ||
|
|
65eea97e0c | ||
|
|
bd57cbda03 | ||
|
|
31c8f8e795 | ||
|
|
ccfc005932 | ||
|
|
b4dfc8e1bf | ||
|
|
3635b17f22 | ||
|
|
5d3e211531 | ||
|
|
bde676ef74 | ||
|
|
18a04a24b3 | ||
|
|
64f053d583 | ||
|
|
1fc8de32f1 | ||
|
|
09f6199b36 | ||
|
|
b0f000b1c8 | ||
|
|
49b653b444 | ||
|
|
107229de04 | ||
|
|
1112bd0f23 | ||
|
|
8c931e4185 | ||
|
|
5771aabc49 | ||
|
|
954c6540fd | ||
|
|
4eea8bd2c0 | ||
|
|
335d35a988 | ||
|
|
2833db559e | ||
|
|
3d667bfe55 | ||
|
|
7841653a03 | ||
|
|
02a9b5a8a5 | ||
|
|
4b1d0d19fb | ||
|
|
8b31e3ec2a | ||
|
|
b2ba5dbd6a | ||
|
|
b2a9413c06 | ||
|
|
1b15734bd8 | ||
|
|
725d6b235f | ||
|
|
87c6b6d12f | ||
|
|
703e20df79 | ||
|
|
9d0af22b88 | ||
|
|
073d1c4c13 | ||
|
|
c4115c19e4 | ||
|
|
38896efd6d | ||
|
|
b225ffa003 | ||
|
|
c3bb5a97f8 | ||
|
|
cdd589a58a | ||
|
|
bf5c7fc4d3 | ||
|
|
27eba1fc61 | ||
|
|
95b6e8afda | ||
|
|
7c1f2ce4eb | ||
|
|
af64300c18 | ||
|
|
6668544b4c | ||
|
|
5e841b40f3 | ||
|
|
5e79f763b5 | ||
|
|
aebf0e47f3 | ||
|
|
645ef9db87 | ||
|
|
d76ecb960e | ||
|
|
d2da8bd6e2 | ||
|
|
a5fb07e475 | ||
|
|
bcf1897e60 | ||
|
|
044abbace8 | ||
|
|
36a763bdc5 | ||
|
|
2dd488f878 | ||
|
|
34288b0f38 | ||
|
|
d7389b1920 | ||
|
|
42eddbf89b | ||
|
|
8e206f55be | ||
|
|
4ea7df69b4 | ||
|
|
da6ef63bc4 | ||
|
|
5da9663ae4 | ||
|
|
322660c644 | ||
|
|
2378572e1b | ||
|
|
ab436d4147 | ||
|
|
18cd3a029d | ||
|
|
dba4bd6f26 | ||
|
|
7bc70758fb | ||
|
|
69e0700101 | ||
|
|
dfe4d36e8d | ||
|
|
55ded1379e | ||
|
|
64ed25abfb | ||
|
|
7b70679bf0 | ||
|
|
31fbafe16f | ||
|
|
878e4cb3ce | ||
|
|
73bc29c011 | ||
|
|
44dbd98d90 | ||
|
|
8b5693b77f | ||
|
|
76d2bd9633 | ||
|
|
83c7561a84 | ||
|
|
f8cb81c9f9 | ||
|
|
4a59b1d3b5 | ||
|
|
763aab3301 | ||
|
|
0bbc78cdbd | ||
|
|
29fc063764 | ||
|
|
a66da0ddf4 | ||
|
|
4fd447a31d | ||
|
|
122049a9b4 | ||
|
|
6a49ea5262 | ||
|
|
9f709aa64c | ||
|
|
702e0ac29e | ||
|
|
954276ff0e | ||
|
|
0541b2ee27 | ||
|
|
dc6a3ae99c | ||
|
|
2512435a7b | ||
|
|
7d8d351668 | ||
|
|
0126ef78c8 | ||
|
|
489a5d203f | ||
|
|
4716fc5eb8 | ||
|
|
437689371d | ||
|
|
798d532a11 | ||
|
|
c5a3bcca70 | ||
|
|
e4cb523181 | ||
|
|
b80213d65d | ||
|
|
d13e7d00b0 | ||
|
|
f492ba1e2d | ||
|
|
83111a4a2a | ||
|
|
5a482a6685 | ||
|
|
bda11e628b | ||
|
|
b8be73caea | ||
|
|
df151ad6fa | ||
|
|
7e7787c298 | ||
|
|
1dd0c8f54c | ||
|
|
dc04cbf9a9 | ||
|
|
77673f33db | ||
|
|
f4e7de3cef | ||
|
|
9b4ef1059c | ||
|
|
8ba661b8ed | ||
|
|
1125ed8830 | ||
|
|
58351de797 | ||
|
|
f9ce7c2e18 | ||
|
|
221189ab6e | ||
|
|
8f854c7d93 | ||
|
|
728edacfd4 | ||
|
|
9aa8cabf93 | ||
|
|
cf2ab9b129 | ||
|
|
2313d2d80a | ||
|
|
b03d1327a5 | ||
|
|
8110edbc62 | ||
|
|
d90f658163 | ||
|
|
0b8191d566 | ||
|
|
27f0d13bdd | ||
|
|
c944676bb5 | ||
|
|
ff49a2f0b6 | ||
|
|
8a5587749b | ||
|
|
3c378aaac7 | ||
|
|
72430e91b2 | ||
|
|
6b038bda0d | ||
|
|
01f80b239d | ||
|
|
b9f81d913b | ||
|
|
750985dc23 | ||
|
|
bcb9c28597 | ||
|
|
23891a918d | ||
|
|
4f1a3876ec | ||
|
|
43806f3e68 | ||
|
|
f4405246ed | ||
|
|
8cc507af53 | ||
|
|
6c8bbf9a1c | ||
|
|
ea470609fd | ||
|
|
ad44f52a26 | ||
|
|
1e7cba9dd3 | ||
|
|
87b3dbb214 | ||
|
|
243283eec8 | ||
|
|
b05922026d | ||
|
|
ed8e44b467 | ||
|
|
76e163a889 | ||
|
|
20ab2c1e20 | ||
|
|
3f7ea072c3 | ||
|
|
601db77801 | ||
|
|
93e72fdd21 | ||
|
|
e2bb2593db | ||
|
|
e53e96f01b | ||
|
|
794064db9f | ||
|
|
4c4a1aa56d | ||
|
|
84a5e34319 | ||
|
|
d1bbda6d71 | ||
|
|
8c56f8595e | ||
|
|
c2f6782658 | ||
|
|
7c0398c8e3 | ||
|
|
71e9f23d77 | ||
|
|
7b45ae1f2d | ||
|
|
bf0f9c5cb4 | ||
|
|
3f1682a4f3 | ||
|
|
4dd8f390e2 | ||
|
|
82661aa042 | ||
|
|
210a718a04 | ||
|
|
1d94f6c848 | ||
|
|
d21a9fa917 | ||
|
|
51cbfa6aa6 | ||
|
|
1ed5993ff6 | ||
|
|
e655648b18 | ||
|
|
da7c6b0d99 | ||
|
|
a5b836d3d4 | ||
|
|
8a7ecebc03 | ||
|
|
7cf245895e | ||
|
|
738517c6e8 | ||
|
|
a6cd666b10 | ||
|
|
bc8a881e64 | ||
|
|
224059e7ba | ||
|
|
6f454dce20 | ||
|
|
3528149329 | ||
|
|
6c148ef314 | ||
|
|
7f58f6af39 | ||
|
|
3ddcc2e5c7 | ||
|
|
756f47af04 | ||
|
|
b9e1d9ad7d | ||
|
|
169ba6f9b2 | ||
|
|
7c0e89d785 | ||
|
|
dd8059a3aa | ||
|
|
0dcd5a0f34 | ||
|
|
d2a2837034 | ||
|
|
22a069d4b0 | ||
|
|
281a9fdf07 | ||
|
|
e7a6a4b009 | ||
|
|
5c760175d1 | ||
|
|
11fb93d022 | ||
|
|
43a0011987 | ||
|
|
37886a72ef | ||
|
|
98573fb868 | ||
|
|
4d954f1a5f | ||
|
|
46053f6c8f | ||
|
|
6f3941c9cc | ||
|
|
cd71114c15 | ||
|
|
e2a31f221a | ||
|
|
97dfe2ac32 | ||
|
|
9c63b1d2c9 | ||
|
|
0f807bf7ee | ||
|
|
ee003495f6 | ||
|
|
08f0e9d6f3 | ||
|
|
4d6fb59bfb | ||
|
|
0317576434 | ||
|
|
b607963fba | ||
|
|
d08cff9efc | ||
|
|
2f2cef6c5f | ||
|
|
875e0f5fb2 | ||
|
|
d9ab412032 | ||
|
|
6c4cddccf6 | ||
|
|
69d3c4ff25 | ||
|
|
1f80c8dffe | ||
|
|
12cdf0fb52 | ||
|
|
b6a3a06c4b | ||
|
|
2728590471 | ||
|
|
7766530afc | ||
|
|
d7839eb8ac | ||
|
|
6a734ecd34 | ||
|
|
acd93b3bd1 | ||
|
|
94200b1179 | ||
|
|
a6bf96322b | ||
|
|
27163e60bb | ||
|
|
1041516e8e | ||
|
|
b7bbd827fd | ||
|
|
fda7cbeca4 | ||
|
|
2fc58b3327 | ||
|
|
3fcd575f53 | ||
|
|
0cee807dfb | ||
|
|
a51c56c4b3 | ||
|
|
d2f26e57d2 | ||
|
|
b7790c0394 | ||
|
|
d17e0b5aca | ||
|
|
f08b5e4866 | ||
|
|
78ae5e7721 | ||
|
|
5fb66a3953 | ||
|
|
d952e71d97 | ||
|
|
fe337dfb66 | ||
|
|
45329232b3 | ||
|
|
30ad21b7d8 | ||
|
|
4e3ad9c3f2 | ||
|
|
2a1e9b542e | ||
|
|
8f458feafc | ||
|
|
e116d8f819 | ||
|
|
f3674ccc6c | ||
|
|
6f35a63f2d | ||
|
|
acbc4f648d | ||
|
|
5475b5f562 | ||
|
|
39861c270c | ||
|
|
6eaa542709 | ||
|
|
2a8981929a | ||
|
|
0aa7aa5996 | ||
|
|
a20bd89c20 | ||
|
|
aa7af30382 | ||
|
|
9921d28ea7 | ||
|
|
b26fd04843 | ||
|
|
1b78d20d3c | ||
|
|
b203406d4c | ||
|
|
5a0017c61a | ||
|
|
df15c758f6 | ||
|
|
588a89f957 | ||
|
|
c74343531f | ||
|
|
a257189c77 | ||
|
|
355051bf75 | ||
|
|
ab8aa43ffb | ||
|
|
a6f56bbc3e | ||
|
|
4e2b9395b9 | ||
|
|
ae9159fbd8 | ||
|
|
8e80c17602 | ||
|
|
8903258362 | ||
|
|
1beeb28908 | ||
|
|
2d2aa7d664 | ||
|
|
cd6b60df70 | ||
|
|
b18790f5c2 | ||
|
|
f6d7090f07 | ||
|
|
017d280877 | ||
|
|
031d4092d0 | ||
|
|
0119d15adb | ||
|
|
df6cb3c43b | ||
|
|
1ed737cf64 | ||
|
|
c64e46fe67 | ||
|
|
f579b0e3de | ||
|
|
b63c041aa4 | ||
|
|
22f9a5f09f | ||
|
|
e47875340e | ||
|
|
6f28383531 | ||
|
|
95050702f1 | ||
|
|
ae8f717fe5 | ||
|
|
f95ac99baa | ||
|
|
660b4d1e2f | ||
|
|
5bfebaf1c0 | ||
|
|
980e54c5f4 | ||
|
|
efbfeb2d89 | ||
|
|
0676ed08b1 | ||
|
|
e9946672e0 | ||
|
|
6124f83e6e | ||
|
|
2b83debc72 | ||
|
|
fc4cc9ab42 | ||
|
|
cd19974d7a | ||
|
|
cde48a44cf | ||
|
|
57d33f9ce6 | ||
|
|
90a46acc0d | ||
|
|
60634cc829 | ||
|
|
a7c27596bb | ||
|
|
b4e3146665 | ||
|
|
495ab6c7f2 | ||
|
|
0e396a62b1 | ||
|
|
1343a4b755 | ||
|
|
ec45c096a0 | ||
|
|
c7e523cee4 | ||
|
|
9e436336e2 | ||
|
|
a9205adfbd | ||
|
|
f5bff5f15d | ||
|
|
bbeacb9acf | ||
|
|
7027584391 | ||
|
|
372d4e2e05 | ||
|
|
bdfa2ff33a | ||
|
|
787b31674a | ||
|
|
0eb9f7408e | ||
|
|
5c96415eb5 | ||
|
|
d9f8347fc8 | ||
|
|
2a48fe6ce6 | ||
|
|
3ed574532d | ||
|
|
9f58e59a2c | ||
|
|
23c6d6cf16 | ||
|
|
8e0a9e8748 | ||
|
|
67dbeee7b2 | ||
|
|
b4a0c773ae | ||
|
|
ce598530db | ||
|
|
694f57fbb4 | ||
|
|
0f90b870fb | ||
|
|
bd5b37dbb7 | ||
|
|
7e93e87244 | ||
|
|
02f4aa6db6 | ||
|
|
ade2c36123 | ||
|
|
3ef80f2d2e | ||
|
|
85c6480b41 | ||
|
|
f3c94315c3 | ||
|
|
a4219f1cfe | ||
|
|
831a7ddd6f | ||
|
|
43886ca016 | ||
|
|
61b4244837 | ||
|
|
6871979acc | ||
|
|
bb7cf81d52 | ||
|
|
9826291c52 | ||
|
|
08661250d2 | ||
|
|
814001a90f | ||
|
|
eef73a0d92 | ||
|
|
a1e3202054 | ||
|
|
bee017e17c | ||
|
|
a054508211 | ||
|
|
feaa82a8ea | ||
|
|
a175e06149 | ||
|
|
ba4d9469ff | ||
|
|
54c6f91dde | ||
|
|
e552e958de | ||
|
|
7524ecbc59 | ||
|
|
be2ca5f8cc | ||
|
|
d4d641a07e | ||
|
|
8e5b812a97 | ||
|
|
df94f0565e | ||
|
|
637915f295 | ||
|
|
f2838c4a13 | ||
|
|
fe56c7ce39 | ||
|
|
29ecbde445 | ||
|
|
611f212aa4 | ||
|
|
6fbafa1924 | ||
|
|
875bac8bb9 | ||
|
|
b4b410f1d2 | ||
|
|
eec0ee83e2 | ||
|
|
148951e6f3 | ||
|
|
612e3b77fd | ||
|
|
a60849f6ab | ||
|
|
6f27e97980 | ||
|
|
8d9145aaac | ||
|
|
25a7330db0 | ||
|
|
92c999afcb | ||
|
|
9e3dc25b1c | ||
|
|
2a3cd7d601 | ||
|
|
3ca67ceebb | ||
|
|
245fc49089 | ||
|
|
78199dbf0a | ||
|
|
2ac33c9ce9 | ||
|
|
34cd035d8c | ||
|
|
ba4f565ca3 | ||
|
|
5860427bc5 | ||
|
|
89f42eef49 | ||
|
|
eacbfa15c0 | ||
|
|
5d45c2c184 | ||
|
|
b24b0378ea | ||
|
|
144012a5de | ||
|
|
5fb4027375 | ||
|
|
3fa65f1363 | ||
|
|
79f630661a | ||
|
|
61b9fe6a81 | ||
|
|
f38d9d8f0d | ||
|
|
3a67daa1fd | ||
|
|
813726b415 | ||
|
|
87fe2143be | ||
|
|
c759b06f16 | ||
|
|
c32249a72f | ||
|
|
05f4be69f4 | ||
|
|
541881162a | ||
|
|
19c5e031a9 | ||
|
|
45be9fe416 | ||
|
|
1596352585 | ||
|
|
4b893b1d51 | ||
|
|
d85e144944 | ||
|
|
4dfff5a271 | ||
|
|
c2b9598966 | ||
|
|
d16e7c096b | ||
|
|
5511912251 | ||
|
|
514d3c37b9 | ||
|
|
7721954bbb | ||
|
|
0a50088a0e | ||
|
|
6ba6ba27bd | ||
|
|
611e23c149 | ||
|
|
89affd8d09 | ||
|
|
8dfd5535f1 | ||
|
|
8c45ae73b3 | ||
|
|
fed9e2861c | ||
|
|
6e115638a1 | ||
|
|
437be1162e | ||
|
|
e3b6a14ab1 | ||
|
|
eb7893768b | ||
|
|
6e1ef4f5c2 | ||
|
|
7d7027f47c | ||
|
|
7086ecb3b0 | ||
|
|
8508ace50e | ||
|
|
c52ef56875 | ||
|
|
4dfe8ab483 | ||
|
|
ea5e0a9d5b | ||
|
|
30111e6403 | ||
|
|
e5a572a4a8 | ||
|
|
83ed7df8cd | ||
|
|
97e93c6257 | ||
|
|
73089470b1 | ||
|
|
3798f8bd25 | ||
|
|
f805a76e79 |
@@ -63,6 +63,7 @@ install:
|
||||
- tar -xf /tmp/wkhtmltox.tar.xz -C /tmp
|
||||
- sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf
|
||||
- sudo chmod o+x /usr/local/bin/wkhtmltopdf
|
||||
- sudo apt-get install libcups2-dev
|
||||
|
||||
- cd ~/frappe-bench
|
||||
|
||||
@@ -76,5 +77,6 @@ install:
|
||||
- bench --site test_site reinstall --yes
|
||||
|
||||
after_script:
|
||||
- pip install coverage==4.5.4
|
||||
- pip install python-coveralls
|
||||
- coveralls -b apps/erpnext -d ../../sites/.coverage
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"baseUrl": "http://test_site_ui:8000"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
context('Form', () => {
|
||||
before(() => {
|
||||
cy.login('Administrator', 'qwe');
|
||||
cy.visit('/desk');
|
||||
});
|
||||
|
||||
it('create a new opportunity', () => {
|
||||
cy.visit('/desk#Form/Opportunity/New Opportunity 1');
|
||||
cy.get('.page-title').should('contain', 'Not Saved');
|
||||
cy.fill_field('opportunity_from', 'Customer', 'Select');
|
||||
cy.fill_field('party_name', 'Test Customer', 'Link').blur();
|
||||
cy.get('.primary-action').click();
|
||||
cy.get('.page-title').should('contain', 'Open');
|
||||
cy.get('.form-inner-toolbar button:contains("Lost")').click({ force: true });
|
||||
cy.get('.modal input[data-fieldname="lost_reason"]').as('input');
|
||||
cy.get('@input').focus().type('Higher', { delay: 200 });
|
||||
cy.get('.modal .awesomplete ul')
|
||||
.should('be.visible')
|
||||
.get('li:contains("Higher Price")')
|
||||
.click({ force: true });
|
||||
cy.get('@input').focus().type('No Followup', { delay: 200 });
|
||||
cy.get('.modal .awesomplete ul')
|
||||
.should('be.visible')
|
||||
.get('li:contains("No Followup")')
|
||||
.click();
|
||||
|
||||
cy.fill_field('detailed_reason', 'Test Detailed Reason', 'Text');
|
||||
cy.get('.modal button:contains("Declare Lost")').click({ force: true });
|
||||
cy.get('.page-title').should('contain', 'Lost');
|
||||
});
|
||||
});
|
||||
@@ -1,17 +0,0 @@
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
// module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
// }
|
||||
@@ -1,25 +0,0 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add("login", (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
@@ -1,22 +0,0 @@
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// import frappe commands
|
||||
import '../../../frappe/cypress/support/index';
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands';
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
@@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '12.4.2'
|
||||
__version__ = '12.7.0'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
from frappe import _
|
||||
from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day, formatdate
|
||||
from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day, formatdate, get_link_to_form
|
||||
from erpnext.accounts.report.general_ledger.general_ledger import execute
|
||||
from frappe.core.page.dashboard.dashboard import cache_source, get_from_date_from_timespan
|
||||
from frappe.desk.doctype.dashboard_chart.dashboard_chart import get_period_ending
|
||||
@@ -30,8 +30,13 @@ def get(chart_name = None, chart = None, no_cache = None, from_date = None, to_d
|
||||
account = filters.get("account")
|
||||
company = filters.get("company")
|
||||
|
||||
if not account and chart:
|
||||
frappe.throw(_("Account is not set for the dashboard chart {0}").format(chart))
|
||||
if not account and chart_name:
|
||||
frappe.throw(_("Account is not set for the dashboard chart {0}")
|
||||
.format(get_link_to_form("Dashboard Chart", chart_name)))
|
||||
|
||||
if not frappe.db.exists("Account", account) and chart_name:
|
||||
frappe.throw(_("Account {0} does not exists in the dashboard chart {1}")
|
||||
.format(account, get_link_to_form("Dashboard Chart", chart_name)))
|
||||
|
||||
if not to_date:
|
||||
to_date = nowdate()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_copy": 1,
|
||||
"allow_import": 1,
|
||||
"creation": "2013-01-30 12:49:46",
|
||||
@@ -196,10 +197,13 @@
|
||||
],
|
||||
"icon": "fa fa-money",
|
||||
"idx": 1,
|
||||
"modified": "2019-10-10 19:10:02.967554",
|
||||
"is_tree": 1,
|
||||
"links": [],
|
||||
"modified": "2020-03-18 18:26:03.992861",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Account",
|
||||
"nsm_parent_field": "parent_account",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
|
||||
@@ -95,29 +95,29 @@ class Account(NestedSet):
|
||||
# ignore validation while creating new compnay or while syncing to child companies
|
||||
if frappe.local.flags.ignore_root_company_validation or self.flags.ignore_root_company_validation:
|
||||
return
|
||||
|
||||
ancestors = get_root_company(self.company)
|
||||
if ancestors:
|
||||
if frappe.get_value("Company", self.company, "allow_account_creation_against_child_company"):
|
||||
return
|
||||
|
||||
if not frappe.db.get_value("Account",
|
||||
{'account_name': self.account_name, 'company': ancestors[0]}, 'name'):
|
||||
frappe.throw(_("Please add the account to root level Company - %s" % ancestors[0]))
|
||||
else:
|
||||
elif self.parent_account:
|
||||
descendants = get_descendants_of('Company', self.company)
|
||||
if not descendants: return
|
||||
|
||||
parent_acc_name_map = {}
|
||||
parent_acc_name, parent_acc_number = frappe.db.get_value('Account', self.parent_account, \
|
||||
["account_name", "account_number"])
|
||||
for d in frappe.db.get_values('Account',
|
||||
{ "company": ["in", descendants], "account_name": parent_acc_name,
|
||||
"account_number": parent_acc_number },
|
||||
["company", "name"], as_dict=True):
|
||||
filters = {
|
||||
"company": ["in", descendants],
|
||||
"account_name": parent_acc_name,
|
||||
}
|
||||
if parent_acc_number:
|
||||
filters["account_number"] = parent_acc_number
|
||||
|
||||
for d in frappe.db.get_values('Account', filters=filters, fieldname=["company", "name"], as_dict=True):
|
||||
parent_acc_name_map[d["company"]] = d["name"]
|
||||
if not parent_acc_name_map: return
|
||||
|
||||
self.create_account_for_child_company(parent_acc_name_map, descendants, parent_acc_name)
|
||||
|
||||
def validate_group_or_ledger(self):
|
||||
@@ -175,7 +175,6 @@ class Account(NestedSet):
|
||||
filters["account_number"] = self.account_number
|
||||
|
||||
child_account = frappe.db.get_value("Account", filters, 'name')
|
||||
|
||||
if not child_account:
|
||||
doc = frappe.copy_doc(self)
|
||||
doc.flags.ignore_root_company_validation = True
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
frappe.provide("frappe.treeview_settings")
|
||||
|
||||
frappe.treeview_settings["Account"] = {
|
||||
breadcrumbs: "Accounts",
|
||||
breadcrumb: "Accounts",
|
||||
title: __("Chart Of Accounts"),
|
||||
get_tree_root: false,
|
||||
filters: [
|
||||
|
||||
@@ -406,11 +406,11 @@
|
||||
"is_group": 1,
|
||||
"Bewertungskorrektur zu Forderungen aus Lieferungen und Leistungen": {
|
||||
"account_number": "9960"
|
||||
},
|
||||
"Debitoren": {
|
||||
"is_group": 1,
|
||||
"account_number": "10000"
|
||||
},
|
||||
},
|
||||
"Debitoren": {
|
||||
"is_group": 1,
|
||||
"account_number": "10000"
|
||||
},
|
||||
"Forderungen aus Lieferungen und Leistungen": {
|
||||
"account_number": "1200",
|
||||
"account_type": "Receivable"
|
||||
@@ -663,16 +663,22 @@
|
||||
"account_number": "1400"
|
||||
},
|
||||
"Abziehbare Vorsteuer 7 %": {
|
||||
"account_number": "1401"
|
||||
"account_number": "1401",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 7.0
|
||||
},
|
||||
"Abziehbare Vorsteuer aus innergem. Erwerb": {
|
||||
"account_number": "1402"
|
||||
},
|
||||
"Abziehbare Vorsteuer aus innergem. Erwerb 19%": {
|
||||
"account_number": "1404"
|
||||
"account_number": "1404",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 19.0
|
||||
},
|
||||
"Abziehbare Vorsteuer 19 %": {
|
||||
"account_number": "1406"
|
||||
"account_number": "1406",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 19.0
|
||||
},
|
||||
"Abziehbare Vorsteuer nach \u00a7 13b UStG 19 %": {
|
||||
"account_number": "1407"
|
||||
@@ -1197,15 +1203,15 @@
|
||||
"is_group": 1,
|
||||
"Bewertungskorrektur zu Verb. aus Lieferungen und Leistungen": {
|
||||
"account_number": "9964"
|
||||
},
|
||||
"Kreditoren": {
|
||||
"account_number": "70000",
|
||||
"is_group": 1,
|
||||
"Wareneingangs-Verrechnungskonto" : {
|
||||
"account_number": "70001",
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
}
|
||||
},
|
||||
},
|
||||
"Kreditoren": {
|
||||
"account_number": "70000",
|
||||
"is_group": 1,
|
||||
"Wareneingangs-Verrechnungskonto" : {
|
||||
"account_number": "70001",
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
}
|
||||
},
|
||||
"Verb. aus Lieferungen und Leistungen": {
|
||||
"account_number": "3300",
|
||||
"account_type": "Payable"
|
||||
@@ -1488,17 +1494,21 @@
|
||||
},
|
||||
"Umsatzsteuer 7 %": {
|
||||
"account_number": "3801",
|
||||
"account_type": "Tax"
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 7.0
|
||||
},
|
||||
"Umsatzsteuer aus innergem. Erwerb": {
|
||||
"account_number": "3802"
|
||||
},
|
||||
"Umsatzsteuer aus innergem. Erwerb 19 %": {
|
||||
"account_number": "3804"
|
||||
"account_number": "3804",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 19.0
|
||||
},
|
||||
"Umsatzsteuer 19 %": {
|
||||
"account_number": "3806",
|
||||
"account_type": "Tax"
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 19.0
|
||||
},
|
||||
"Umsatzsteuer aus im Inland steuerpfl. EU-Lieferungen": {
|
||||
"account_number": "3807"
|
||||
@@ -2295,49 +2305,49 @@
|
||||
},
|
||||
"6 - sonstige betriebliche Ertr\u00e4ge": {
|
||||
"root_type": "Income",
|
||||
"is_group": 1,
|
||||
"Erhaltene Boni (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Erhaltene Boni 7 % Vorsteuer": {
|
||||
"account_number": "5750"
|
||||
},
|
||||
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
|
||||
"account_number": "5753"
|
||||
},
|
||||
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
|
||||
"account_number": "5754"
|
||||
},
|
||||
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
|
||||
"account_number": "5755"
|
||||
},
|
||||
"Erhaltene Boni 19 % Vorsteuer": {
|
||||
"account_number": "5760"
|
||||
},
|
||||
"Erhaltene Boni": {
|
||||
"account_number": "5769"
|
||||
}
|
||||
},
|
||||
"Erhaltene Rabatte (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Erhaltene Rabatte": {
|
||||
"account_number": "5770"
|
||||
},
|
||||
"Erhaltene Rabatte 7 % Vorsteuer": {
|
||||
"account_number": "5780"
|
||||
},
|
||||
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
|
||||
"account_number": "5783"
|
||||
},
|
||||
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
|
||||
"account_number": "5784"
|
||||
},
|
||||
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
|
||||
"account_number": "5785"
|
||||
},
|
||||
"Erhaltene Rabatte 19 % Vorsteuer": {
|
||||
"account_number": "5790"
|
||||
}
|
||||
},
|
||||
"is_group": 1,
|
||||
"Erhaltene Boni (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Erhaltene Boni 7 % Vorsteuer": {
|
||||
"account_number": "5750"
|
||||
},
|
||||
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
|
||||
"account_number": "5753"
|
||||
},
|
||||
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
|
||||
"account_number": "5754"
|
||||
},
|
||||
"Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
|
||||
"account_number": "5755"
|
||||
},
|
||||
"Erhaltene Boni 19 % Vorsteuer": {
|
||||
"account_number": "5760"
|
||||
},
|
||||
"Erhaltene Boni": {
|
||||
"account_number": "5769"
|
||||
}
|
||||
},
|
||||
"Erhaltene Rabatte (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Erhaltene Rabatte": {
|
||||
"account_number": "5770"
|
||||
},
|
||||
"Erhaltene Rabatte 7 % Vorsteuer": {
|
||||
"account_number": "5780"
|
||||
},
|
||||
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
|
||||
"account_number": "5783"
|
||||
},
|
||||
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
|
||||
"account_number": "5784"
|
||||
},
|
||||
"Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
|
||||
"account_number": "5785"
|
||||
},
|
||||
"Erhaltene Rabatte 19 % Vorsteuer": {
|
||||
"account_number": "5790"
|
||||
}
|
||||
},
|
||||
"Andere aktivierte Eigenleistungen": {
|
||||
"account_number": "4820"
|
||||
},
|
||||
@@ -2407,29 +2417,26 @@
|
||||
"Erl\u00f6se aus Verk\u00e4ufen Sachanlageverm\u00f6gen (bei Buchgewinn)": {
|
||||
"account_number": "4849"
|
||||
},
|
||||
"Erl\u00f6se aus Verk\u00e4ufen immaterieller VG (bei Buchgewinn) (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Erl\u00f6se aus Verk\u00e4ufen immaterieller VG (bei Buchgewinn)": {
|
||||
"account_number": "4850"
|
||||
},
|
||||
"Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (bei Buchgewinn)": {
|
||||
"account_number": "4851"
|
||||
},
|
||||
"Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (inl\u00e4ndische Kap.Ges., bei Buchgewinn)": {
|
||||
"account_number": "4852"
|
||||
},
|
||||
"Anlagenabg\u00e4nge Sachanlagen (Restbuchwert bei Buchvergewinn)": {
|
||||
"account_number": "4855"
|
||||
},
|
||||
"Anlagenabg\u00e4nge immaterielle VG (Restbuchwert bei Buchgewinn)": {
|
||||
"account_number": "4856"
|
||||
},
|
||||
"Anlagenabg\u00e4nge Finanzanlagen (Restbuchwert bei Buchgewinn)": {
|
||||
"account_number": "4857"
|
||||
},
|
||||
"Anlagenabg\u00e4nge Finanzanlagen (inl\u00e4ndische Kap.Ges., Restbuchwert bei Buchgewinn)": {
|
||||
"account_number": "4858"
|
||||
}
|
||||
"Erl\u00f6se aus Verk\u00e4ufen immaterieller VG (bei Buchgewinn)": {
|
||||
"account_number": "4850"
|
||||
},
|
||||
"Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (bei Buchgewinn)": {
|
||||
"account_number": "4851"
|
||||
},
|
||||
"Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (inl\u00e4ndische Kap.Ges., bei Buchgewinn)": {
|
||||
"account_number": "4852"
|
||||
},
|
||||
"Anlagenabg\u00e4nge Sachanlagen (Restbuchwert bei Buchvergewinn)": {
|
||||
"account_number": "4855"
|
||||
},
|
||||
"Anlagenabg\u00e4nge immaterielle VG (Restbuchwert bei Buchgewinn)": {
|
||||
"account_number": "4856"
|
||||
},
|
||||
"Anlagenabg\u00e4nge Finanzanlagen (Restbuchwert bei Buchgewinn)": {
|
||||
"account_number": "4857"
|
||||
},
|
||||
"Anlagenabg\u00e4nge Finanzanlagen (inl\u00e4ndische Kap.Ges., Restbuchwert bei Buchgewinn)": {
|
||||
"account_number": "4858"
|
||||
},
|
||||
"Ertr\u00e4ge aus Zuschreibungen des Sachanlageverm\u00f6gens": {
|
||||
"account_number": "4910",
|
||||
@@ -2552,20 +2559,17 @@
|
||||
"Entnahme von Gegenst\u00e4nden ohne USt": {
|
||||
"account_number": "4605"
|
||||
},
|
||||
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 7 % USt (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 7 % USt": {
|
||||
"account_number": "4630"
|
||||
},
|
||||
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt": {
|
||||
"account_number": "4637"
|
||||
},
|
||||
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternnehmens ohne USt (Telefon-Nutzung)": {
|
||||
"account_number": "4638"
|
||||
},
|
||||
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt (Kfz-Nutzung)": {
|
||||
"account_number": "4639"
|
||||
}
|
||||
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 7 % USt": {
|
||||
"account_number": "4630"
|
||||
},
|
||||
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt": {
|
||||
"account_number": "4637"
|
||||
},
|
||||
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternnehmens ohne USt (Telefon-Nutzung)": {
|
||||
"account_number": "4638"
|
||||
},
|
||||
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt (Kfz-Nutzung)": {
|
||||
"account_number": "4639"
|
||||
},
|
||||
"Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 19 % USt (Gruppe)": {
|
||||
"is_group": 1,
|
||||
@@ -2603,14 +2607,11 @@
|
||||
"Unentgeltliche Zuwendung von Gegenst\u00e4nden ohne USt": {
|
||||
"account_number": "4689"
|
||||
},
|
||||
"Nicht steuerbare Ums\u00e4tze (Innenums\u00e4tze) (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Nicht steuerbare Ums\u00e4tze (Innenums\u00e4tze)": {
|
||||
"account_number": "4690"
|
||||
},
|
||||
"Umsatzsteuerverg\u00fctungen, z.B. nach \u00a7 24 UStG": {
|
||||
"account_number": "4695"
|
||||
}
|
||||
"Nicht steuerbare Ums\u00e4tze (Innenums\u00e4tze)": {
|
||||
"account_number": "4690"
|
||||
},
|
||||
"Umsatzsteuerverg\u00fctungen, z.B. nach \u00a7 24 UStG": {
|
||||
"account_number": "4695"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge (Gruppe)": {
|
||||
"is_group": 1,
|
||||
@@ -2620,48 +2621,42 @@
|
||||
"Au\u00dferordentliche Ertr\u00e4ge finanzwirksam": {
|
||||
"account_number": "7401"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge nicht finanzwirksam (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Au\u00dferordentliche Ertr\u00e4ge nicht finanzwirksam": {
|
||||
"account_number": "7450"
|
||||
},
|
||||
"Ertr\u00e4ge durch Verschmelzung und Umwandlung": {
|
||||
"account_number": "7451"
|
||||
},
|
||||
"Ertr\u00e4ge durch den Verkauf von bedeutenden Beteiligungen": {
|
||||
"account_number": "7452"
|
||||
},
|
||||
"Ert\u00e4ge durch den Verkauf von bedeutenden Grundst\u00fccken": {
|
||||
"account_number": "7453"
|
||||
},
|
||||
"Gewinn aus der Ver\u00e4u\u00dferung oder der Aufgabe von Gesch\u00e4ftsaktivit\u00e4ten nach Steuern": {
|
||||
"account_number": "7454"
|
||||
}
|
||||
"Au\u00dferordentliche Ertr\u00e4ge nicht finanzwirksam": {
|
||||
"account_number": "7450"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge aus der Anwendung von \u00dcbergangsvorschriften (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Au\u00dferordentliche Ertr\u00e4ge aus der Anwendung von \u00dcbergangsvorschriften": {
|
||||
"account_number": "7460"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Sachanlageverm\u00f6gen": {
|
||||
"account_number": "7461"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Finanzanlageverm\u00f6gen": {
|
||||
"account_number": "7462"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge: Wertpapiere im Umlaufverm\u00f6gen": {
|
||||
"account_number": "7463"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge: latente Steuern": {
|
||||
"account_number": "7464"
|
||||
}
|
||||
"Ertr\u00e4ge durch Verschmelzung und Umwandlung": {
|
||||
"account_number": "7451"
|
||||
},
|
||||
"Ertr\u00e4ge durch den Verkauf von bedeutenden Beteiligungen": {
|
||||
"account_number": "7452"
|
||||
},
|
||||
"Ert\u00e4ge durch den Verkauf von bedeutenden Grundst\u00fccken": {
|
||||
"account_number": "7453"
|
||||
},
|
||||
"Gewinn aus der Ver\u00e4u\u00dferung oder der Aufgabe von Gesch\u00e4ftsaktivit\u00e4ten nach Steuern": {
|
||||
"account_number": "7454"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge aus der Anwendung von \u00dcbergangsvorschriften": {
|
||||
"account_number": "7460"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Sachanlageverm\u00f6gen": {
|
||||
"account_number": "7461"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Finanzanlageverm\u00f6gen": {
|
||||
"account_number": "7462"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge: Wertpapiere im Umlaufverm\u00f6gen": {
|
||||
"account_number": "7463"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge: latente Steuern": {
|
||||
"account_number": "7464"
|
||||
}
|
||||
}
|
||||
},
|
||||
"7 - sonstige betriebliche Aufwendungen": {
|
||||
"root_type": "Expense",
|
||||
"is_group": 1,
|
||||
"Erl\u00f6sschm\u00e4lerungen (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Erl\u00f6sschm\u00e4lerungen (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Erl\u00f6sschm\u00e4lerungen": {
|
||||
"account_number": "4700"
|
||||
@@ -2692,40 +2687,43 @@
|
||||
},
|
||||
"Erl\u00f6sschm\u00e4lerungen aus im Inland steuerpfl. EU-Lieferungen 16 % USt": {
|
||||
"account_number": "4729"
|
||||
}
|
||||
},
|
||||
"Gew\u00e4hrte Skonti (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Gew. Skonti": {
|
||||
"account_number": "4730"
|
||||
},
|
||||
"Gew\u00e4hrte Skonti (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Gew. Skonti": {
|
||||
"account_number": "4730"
|
||||
},
|
||||
"Gew. Skonti 7 % USt": {
|
||||
"account_number": "4731"
|
||||
},
|
||||
"Gew. Skonti 19 % USt": {
|
||||
"account_number": "4736"
|
||||
},
|
||||
"Gew. Skonti aus Lieferungen von Mobilfunkger./Schaltkr., f. die der Leistungsempf. die Ust. schuldet": {
|
||||
"account_number": "4738"
|
||||
},
|
||||
"Gew. Skonti aus Leistungen, f. die der Leistungsempf. die Umsatzsteuer nach \u00a7 13b UStG schuldet": {
|
||||
"account_number": "4741"
|
||||
},
|
||||
"Gew. Skonti aus Erl\u00f6sen aus im anderen EU-Land steuerpfl. Leistungen, f. die der Leistungsempf. die Ust. schuldet": {
|
||||
"account_number": "4742"
|
||||
},
|
||||
"Gew. Skonti aus steuerfreien innergem. Lieferungen \u00a7 4 Nr. 1b UStG": {
|
||||
"account_number": "4743"
|
||||
},
|
||||
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen": {
|
||||
"account_number": "4745"
|
||||
},
|
||||
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 7% USt": {
|
||||
"account_number": "4746"
|
||||
},
|
||||
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 19% USt": {
|
||||
"account_number": "4748"
|
||||
}
|
||||
"Gew. Skonti 7 % USt": {
|
||||
"account_number": "4731"
|
||||
},
|
||||
"Gew. Skonti 19 % USt": {
|
||||
"account_number": "4736"
|
||||
},
|
||||
"Gew. Skonti aus Lieferungen von Mobilfunkger./Schaltkr., f. die der Leistungsempf. die Ust. schuldet": {
|
||||
"account_number": "4738"
|
||||
},
|
||||
"Gew. Skonti aus Leistungen, f. die der Leistungsempf. die Umsatzsteuer nach \u00a7 13b UStG schuldet": {
|
||||
"account_number": "4741"
|
||||
},
|
||||
"Gew. Skonti aus Erl\u00f6sen aus im anderen EU-Land steuerpfl. Leistungen, f. die der Leistungsempf. die Ust. schuldet": {
|
||||
"account_number": "4742"
|
||||
},
|
||||
"Gew. Skonti aus steuerfreien innergem. Lieferungen \u00a7 4 Nr. 1b UStG": {
|
||||
"account_number": "4743"
|
||||
},
|
||||
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen": {
|
||||
"account_number": "4745"
|
||||
},
|
||||
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 7% USt": {
|
||||
"account_number": "4746"
|
||||
},
|
||||
"Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 19% USt": {
|
||||
"account_number": "4748"
|
||||
}
|
||||
},
|
||||
"Gew\u00e4hrte Boni (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Gew\u00e4hrte Boni 7 % USt": {
|
||||
"account_number": "4750"
|
||||
},
|
||||
@@ -2744,7 +2742,7 @@
|
||||
"Gew\u00e4hrte Rabatte 19 % USt": {
|
||||
"account_number": "4790"
|
||||
}
|
||||
},
|
||||
},
|
||||
"Sonstige betriebliche Aufwendungen": {
|
||||
"account_number": "6300"
|
||||
},
|
||||
@@ -2838,103 +2836,79 @@
|
||||
"account_number": "6398"
|
||||
}
|
||||
},
|
||||
"Versicherungen (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Versicherungen": {
|
||||
"account_number": "6400"
|
||||
},
|
||||
"Versicherungen f. Geb\u00e4ude, die zum Betriebsverm\u00f6gen geh\u00f6ren": {
|
||||
"account_number": "6405"
|
||||
},
|
||||
"Netto-Pr\u00e4mie f. R\u00fcckdeckung k\u00fcnftiger Versorgungsleistungen": {
|
||||
"account_number": "6410"
|
||||
},
|
||||
"Beitr\u00e4ge": {
|
||||
"account_number": "6420"
|
||||
},
|
||||
"Sonstige Abgaben": {
|
||||
"account_number": "6430"
|
||||
},
|
||||
"Steuerlich abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": {
|
||||
"account_number": "6436"
|
||||
},
|
||||
"Steuerlich nicht abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": {
|
||||
"account_number": "6437"
|
||||
},
|
||||
"Ausgleichsabgabe i. S. d. Schwerbehindertengesetzes": {
|
||||
"account_number": "6440"
|
||||
},
|
||||
"Reparaturen und Instandhaltung von Bauten": {
|
||||
"account_number": "6450"
|
||||
},
|
||||
"Reparaturen und Instandhaltung von technischenAnlagen und Maschinen": {
|
||||
"account_number": "6460"
|
||||
},
|
||||
"Reparaturen und Instandhaltung von anderen Anlagen und Betriebs- und Gesch\u00e4ftsausstattung": {
|
||||
"account_number": "6470"
|
||||
},
|
||||
"Zuf\u00fchrung zu Aufwandsr\u00fcckstellungen": {
|
||||
"account_number": "6475"
|
||||
},
|
||||
"Reparaturen und Instandhaltung von anderen Anlagen": {
|
||||
"account_number": "6485"
|
||||
},
|
||||
"Sonstige Reparaturen und Instandhaltungen": {
|
||||
"account_number": "6490"
|
||||
},
|
||||
"Wartungskosten f. Hard- und Software": {
|
||||
"account_number": "6495"
|
||||
},
|
||||
"Mietleasing (bewegliche Wirtschaftsg\u00fcter)": {
|
||||
"account_number": "6498"
|
||||
}
|
||||
"Versicherungen": {
|
||||
"account_number": "6400"
|
||||
},
|
||||
"Versicherungen f. Geb\u00e4ude, die zum Betriebsverm\u00f6gen geh\u00f6ren": {
|
||||
"account_number": "6405"
|
||||
},
|
||||
"Netto-Pr\u00e4mie f. R\u00fcckdeckung k\u00fcnftiger Versorgungsleistungen": {
|
||||
"account_number": "6410"
|
||||
},
|
||||
"Beitr\u00e4ge": {
|
||||
"account_number": "6420"
|
||||
},
|
||||
"Sonstige Abgaben": {
|
||||
"account_number": "6430"
|
||||
},
|
||||
"Steuerlich abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": {
|
||||
"account_number": "6436"
|
||||
},
|
||||
"Steuerlich nicht abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": {
|
||||
"account_number": "6437"
|
||||
},
|
||||
"Ausgleichsabgabe i. S. d. Schwerbehindertengesetzes": {
|
||||
"account_number": "6440"
|
||||
},
|
||||
"Reparaturen und Instandhaltung von Bauten": {
|
||||
"account_number": "6450"
|
||||
},
|
||||
"Reparaturen und Instandhaltung von technischenAnlagen und Maschinen": {
|
||||
"account_number": "6460"
|
||||
},
|
||||
"Reparaturen und Instandhaltung von anderen Anlagen und Betriebs- und Gesch\u00e4ftsausstattung": {
|
||||
"account_number": "6470"
|
||||
},
|
||||
"Zuf\u00fchrung zu Aufwandsr\u00fcckstellungen": {
|
||||
"account_number": "6475"
|
||||
},
|
||||
"Reparaturen und Instandhaltung von anderen Anlagen": {
|
||||
"account_number": "6485"
|
||||
},
|
||||
"Sonstige Reparaturen und Instandhaltungen": {
|
||||
"account_number": "6490"
|
||||
},
|
||||
"Wartungskosten f. Hard- und Software": {
|
||||
"account_number": "6495"
|
||||
},
|
||||
"Mietleasing (bewegliche Wirtschaftsg\u00fcter)": {
|
||||
"account_number": "6498"
|
||||
},
|
||||
"Fahrzeugkosten (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Fahrzeugkosten": {
|
||||
"account_number": "6500"
|
||||
},
|
||||
"Kfz-Versicherungen (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Kfz-Versicherungen": {
|
||||
"account_number": "6520"
|
||||
}
|
||||
"Kfz-Versicherungen": {
|
||||
"account_number": "6520"
|
||||
},
|
||||
"Laufende Kfz-Betriebskosten (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Laufende Kfz-Betriebskosten": {
|
||||
"account_number": "6530"
|
||||
}
|
||||
"Laufende Kfz-Betriebskosten": {
|
||||
"account_number": "6530"
|
||||
},
|
||||
"Kfz-Reparaturen (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Kfz-Reparaturen": {
|
||||
"account_number": "6540"
|
||||
}
|
||||
"Kfz-Reparaturen": {
|
||||
"account_number": "6540"
|
||||
},
|
||||
"Garagenmiete (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Garagenmiete": {
|
||||
"account_number": "6550"
|
||||
}
|
||||
"Garagenmiete": {
|
||||
"account_number": "6550"
|
||||
},
|
||||
"Mietleasing Kfz (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Mietleasing Kfz": {
|
||||
"account_number": "6560"
|
||||
}
|
||||
"Mietleasing Kfz": {
|
||||
"account_number": "6560"
|
||||
},
|
||||
"Sonstige Kfz-Kosten (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Sonstige Kfz-Kosten": {
|
||||
"account_number": "6570"
|
||||
}
|
||||
"Sonstige Kfz-Kosten": {
|
||||
"account_number": "6570"
|
||||
},
|
||||
"Mautgeb\u00fchren (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Mautgeb\u00fchren": {
|
||||
"account_number": "6580"
|
||||
}
|
||||
"Mautgeb\u00fchren": {
|
||||
"account_number": "6580"
|
||||
},
|
||||
"Kfz-Kosten f. betrieblich genutzte zum Privatverm\u00f6gen geh\u00f6rende Kraftfahrzeuge": {
|
||||
"account_number": "6590"
|
||||
@@ -2996,20 +2970,23 @@
|
||||
"Nicht abzugsf\u00e4hige Betriebsausgaben aus Werbe- und Repr\u00e4sentationskosten": {
|
||||
"account_number": "6645"
|
||||
},
|
||||
"Reisekosten Arbeitnehmer": {
|
||||
"account_number": "6650"
|
||||
},
|
||||
"Reisekosten Arbeitnehmer \u00dcbernachtungsaufwand": {
|
||||
"account_number": "6660"
|
||||
},
|
||||
"Reisekosten Arbeitnehmer Fahrtkosten": {
|
||||
"account_number": "6663"
|
||||
},
|
||||
"Reisekosten Arbeitnehmer Verpflegungsmehraufwand": {
|
||||
"account_number": "6664"
|
||||
},
|
||||
"Kilometergelderstattung Arbeitnehmer": {
|
||||
"account_number": "6668"
|
||||
"Reisekosten Arbeitnehmer (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"Reisekosten Arbeitnehmer": {
|
||||
"account_number": "6650"
|
||||
},
|
||||
"Reisekosten Arbeitnehmer \u00dcbernachtungsaufwand": {
|
||||
"account_number": "6660"
|
||||
},
|
||||
"Reisekosten Arbeitnehmer Fahrtkosten": {
|
||||
"account_number": "6663"
|
||||
},
|
||||
"Reisekosten Arbeitnehmer Verpflegungsmehraufwand": {
|
||||
"account_number": "6664"
|
||||
},
|
||||
"Kilometergelderstattung Arbeitnehmer": {
|
||||
"account_number": "6668"
|
||||
}
|
||||
},
|
||||
"Reisekosten Unternehmer (Gruppe)": {
|
||||
"is_group": 1,
|
||||
|
||||
@@ -48,12 +48,6 @@ frappe.ui.form.on('Accounting Dimension', {
|
||||
frm.set_value('label', frm.doc.document_type);
|
||||
frm.set_value('fieldname', frappe.model.scrub(frm.doc.document_type));
|
||||
|
||||
if (frm.is_new()){
|
||||
let row = frappe.model.add_child(frm.doc, "Accounting Dimension Detail", "dimension_defaults");
|
||||
row.reference_document = frm.doc.document_type;
|
||||
frm.refresh_fields("dimension_defaults");
|
||||
}
|
||||
|
||||
frappe.db.get_value('Accounting Dimension', {'document_type': frm.doc.document_type}, 'document_type', (r) => {
|
||||
if (r && r.document_type) {
|
||||
frm.set_df_property('document_type', 'description', "Document type is already set as dimension");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "field:label",
|
||||
"creation": "2019-05-04 18:13:37.002352",
|
||||
"doctype": "DocType",
|
||||
@@ -46,7 +47,8 @@
|
||||
"options": "Accounting Dimension Detail"
|
||||
}
|
||||
],
|
||||
"modified": "2019-07-17 16:49:31.134385",
|
||||
"links": [],
|
||||
"modified": "2020-03-22 20:34:39.805728",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounting Dimension",
|
||||
@@ -63,9 +65,20 @@
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 1
|
||||
|
||||
@@ -172,7 +172,7 @@ def get_doctypes_with_dimensions():
|
||||
return doclist
|
||||
|
||||
def get_accounting_dimensions(as_list=True):
|
||||
accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "disabled"])
|
||||
accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "disabled", "document_type"])
|
||||
|
||||
if as_list:
|
||||
return [d.fieldname for d in accounting_dimensions]
|
||||
@@ -186,6 +186,18 @@ def get_checks_for_pl_and_bs_accounts():
|
||||
|
||||
return dimensions
|
||||
|
||||
def get_dimension_with_children(doctype, dimension):
|
||||
|
||||
if isinstance(dimension, list):
|
||||
dimension = dimension[0]
|
||||
|
||||
all_dimensions = []
|
||||
lft, rgt = frappe.db.get_value(doctype, dimension, ["lft", "rgt"])
|
||||
children = frappe.get_all(doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]}, order_by="lft")
|
||||
all_dimensions += [c.name for c in children]
|
||||
|
||||
return all_dimensions
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_dimension_filters():
|
||||
dimension_filters = frappe.db.sql("""
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
frappe.ui.form.on('Accounts Settings', {
|
||||
refresh: function(frm) {
|
||||
frm.set_df_property("acc_frozen_upto", "label", "Books Closed Through");
|
||||
frm.set_df_property("frozen_accounts_modifier", "label", "Role Allowed to Close Books & Make Changes to Closed Periods");
|
||||
frm.set_df_property("credit_controller", "label", "Credit Manager");
|
||||
}
|
||||
});
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"creation": "2017-05-29 21:35:13.136357",
|
||||
@@ -82,7 +83,7 @@
|
||||
"default": "0",
|
||||
"fieldname": "is_default",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is the Default Account"
|
||||
"label": "Is Default Account"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
@@ -211,7 +212,8 @@
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"modified": "2019-10-02 01:34:12.417601",
|
||||
"links": [],
|
||||
"modified": "2020-01-29 20:42:26.458316",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Account",
|
||||
|
||||
@@ -6,6 +6,7 @@ from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
from frappe.model.document import Document
|
||||
from frappe import _
|
||||
from frappe.desk.search import sanitize_searchfield
|
||||
|
||||
class BankGuarantee(Document):
|
||||
def validate(self):
|
||||
@@ -22,5 +23,8 @@ class BankGuarantee(Document):
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_vouchar_detials(column_list, doctype, docname):
|
||||
column_list = json.loads(column_list)
|
||||
for col in column_list:
|
||||
sanitize_searchfield(col)
|
||||
return frappe.db.sql(''' select {columns} from `tab{doctype}` where name=%s'''
|
||||
.format(columns=", ".join(json.loads(column_list)), doctype=doctype), docname, as_dict=1)[0]
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
|
||||
frappe.ui.form.on("Bank Reconciliation", {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch("bank_account", "account_currency", "account_currency");
|
||||
frm.add_fetch("account", "account_currency", "account_currency");
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
|
||||
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_value("account", default_bank_account);
|
||||
|
||||
frm.set_query("bank_account", function() {
|
||||
frm.set_query("account", function() {
|
||||
return {
|
||||
"filters": {
|
||||
"account_type": ["in",["Bank","Cash"]],
|
||||
|
||||
@@ -19,10 +19,9 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Select account head of the bank where cheque was deposited.",
|
||||
"fetch_from": "bank_account_no.account",
|
||||
"fetch_from": "bank_account.account",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "bank_account",
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -31,7 +30,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Account",
|
||||
"label": "Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
@@ -164,7 +163,6 @@
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
@@ -183,8 +181,9 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Select the Bank Account to reconcile.",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "bank_account_no",
|
||||
"fieldname": "bank_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -193,12 +192,11 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Account No",
|
||||
"label": "Bank Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
@@ -450,7 +448,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2019-04-09 18:41:06.110453",
|
||||
"modified": "2020-01-22 00:00:00.000000",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Reconciliation",
|
||||
@@ -483,4 +481,4 @@
|
||||
"track_changes": 0,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,17 +13,15 @@ form_grid_templates = {
|
||||
|
||||
class BankReconciliation(Document):
|
||||
def get_payment_entries(self):
|
||||
if not (self.bank_account and self.from_date and self.to_date):
|
||||
msgprint(_("Bank Account, From Date and To Date are Mandatory"))
|
||||
return
|
||||
if not (self.from_date and self.to_date):
|
||||
frappe.throw(_("From Date and To Date are Mandatory"))
|
||||
|
||||
if not self.account:
|
||||
frappe.throw(_("Account is mandatory to get payment entries"))
|
||||
|
||||
condition = ""
|
||||
if not self.include_reconciled_entries:
|
||||
condition = " and (clearance_date is null or clearance_date='0000-00-00')"
|
||||
|
||||
account_cond = ""
|
||||
if self.bank_account_no:
|
||||
account_cond = " and t2.bank_account_no = {0}".format(frappe.db.escape(self.bank_account_no))
|
||||
condition = "and (clearance_date IS NULL or clearance_date='0000-00-00')"
|
||||
|
||||
journal_entries = frappe.db.sql("""
|
||||
select
|
||||
@@ -34,15 +32,15 @@ class BankReconciliation(Document):
|
||||
from
|
||||
`tabJournal Entry` t1, `tabJournal Entry Account` t2
|
||||
where
|
||||
t2.parent = t1.name and t2.account = %s and t1.docstatus=1
|
||||
and t1.posting_date >= %s and t1.posting_date <= %s
|
||||
and ifnull(t1.is_opening, 'No') = 'No' {0} {1}
|
||||
t2.parent = t1.name and t2.account = %(account)s and t1.docstatus=1
|
||||
and t1.posting_date >= %(from)s and t1.posting_date <= %(to)s
|
||||
and ifnull(t1.is_opening, 'No') = 'No' {condition}
|
||||
group by t2.account, t1.name
|
||||
order by t1.posting_date ASC, t1.name DESC
|
||||
""".format(condition, account_cond), (self.bank_account, self.from_date, self.to_date), as_dict=1)
|
||||
""".format(condition=condition), {"account": self.account, "from": self.from_date, "to": self.to_date}, as_dict=1)
|
||||
|
||||
if self.bank_account_no:
|
||||
condition = " and bank_account = %(bank_account_no)s"
|
||||
if self.bank_account:
|
||||
condition += 'and bank_account = %(bank_account)s'
|
||||
|
||||
payment_entries = frappe.db.sql("""
|
||||
select
|
||||
@@ -55,12 +53,12 @@ class BankReconciliation(Document):
|
||||
from `tabPayment Entry`
|
||||
where
|
||||
(paid_from=%(account)s or paid_to=%(account)s) and docstatus=1
|
||||
and posting_date >= %(from)s and posting_date <= %(to)s {0}
|
||||
and posting_date >= %(from)s and posting_date <= %(to)s
|
||||
{condition}
|
||||
order by
|
||||
posting_date ASC, name DESC
|
||||
""".format(condition),
|
||||
{"account":self.bank_account, "from":self.from_date,
|
||||
"to":self.to_date, "bank_account_no": self.bank_account_no}, as_dict=1)
|
||||
""".format(condition=condition), {"account": self.account, "from":self.from_date,
|
||||
"to": self.to_date, "bank_account": self.bank_account}, as_dict=1)
|
||||
|
||||
pos_entries = []
|
||||
if self.include_pos_transactions:
|
||||
@@ -72,11 +70,10 @@ class BankReconciliation(Document):
|
||||
from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account
|
||||
where
|
||||
sip.account=%(account)s and si.docstatus=1 and sip.parent = si.name
|
||||
and account.name = sip.account and si.posting_date >= %(from)s and si.posting_date <= %(to)s {0}
|
||||
and account.name = sip.account and si.posting_date >= %(from)s and si.posting_date <= %(to)s
|
||||
order by
|
||||
si.posting_date ASC, si.name DESC
|
||||
""".format(condition),
|
||||
{"account":self.bank_account, "from":self.from_date, "to":self.to_date}, as_dict=1)
|
||||
""", {"account":self.account, "from":self.from_date, "to":self.to_date}, as_dict=1)
|
||||
|
||||
entries = sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
|
||||
key=lambda k: k['posting_date'] or getdate(nowdate()))
|
||||
|
||||
@@ -110,6 +110,15 @@
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.docstatus==1",
|
||||
"fieldname": "clearance_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Clearance Date",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
@@ -122,7 +131,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-12-06 10:57:02.635141",
|
||||
"modified": "2020-01-22 00:00:00.000000",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Transaction Payments",
|
||||
@@ -138,4 +147,4 @@
|
||||
"track_changes": 1,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,10 +210,10 @@ def get_requested_amount(args, budget):
|
||||
item_code = args.get('item_code')
|
||||
condition = get_other_condition(args, budget, 'Material Request')
|
||||
|
||||
data = frappe.db.sql(""" select ifnull((sum(mri.stock_qty - mri.ordered_qty) * rate), 0) as amount
|
||||
from `tabMaterial Request Item` mri, `tabMaterial Request` mr where mr.name = mri.parent and
|
||||
mri.item_code = %s and mr.docstatus = 1 and mri.stock_qty > mri.ordered_qty and {0} and
|
||||
mr.material_request_type = 'Purchase' and mr.status != 'Stopped'""".format(condition), item_code, as_list=1)
|
||||
data = frappe.db.sql(""" select ifnull((sum(child.stock_qty - child.ordered_qty) * rate), 0) as amount
|
||||
from `tabMaterial Request Item` child, `tabMaterial Request` parent where parent.name = child.parent and
|
||||
child.item_code = %s and parent.docstatus = 1 and child.stock_qty > child.ordered_qty and {0} and
|
||||
parent.material_request_type = 'Purchase' and parent.status != 'Stopped'""".format(condition), item_code, as_list=1)
|
||||
|
||||
return data[0][0] if data else 0
|
||||
|
||||
@@ -221,10 +221,10 @@ def get_ordered_amount(args, budget):
|
||||
item_code = args.get('item_code')
|
||||
condition = get_other_condition(args, budget, 'Purchase Order')
|
||||
|
||||
data = frappe.db.sql(""" select ifnull(sum(poi.amount - poi.billed_amt), 0) as amount
|
||||
from `tabPurchase Order Item` poi, `tabPurchase Order` po where
|
||||
po.name = poi.parent and poi.item_code = %s and po.docstatus = 1 and poi.amount > poi.billed_amt
|
||||
and po.status != 'Closed' and {0}""".format(condition), item_code, as_list=1)
|
||||
data = frappe.db.sql(""" select ifnull(sum(child.amount - child.billed_amt), 0) as amount
|
||||
from `tabPurchase Order Item` child, `tabPurchase Order` parent where
|
||||
parent.name = child.parent and child.item_code = %s and parent.docstatus = 1 and child.amount > child.billed_amt
|
||||
and parent.status != 'Closed' and {0}""".format(condition), item_code, as_list=1)
|
||||
|
||||
return data[0][0] if data else 0
|
||||
|
||||
@@ -233,16 +233,15 @@ def get_other_condition(args, budget, for_doc):
|
||||
budget_against_field = frappe.scrub(args.get("budget_against_field"))
|
||||
|
||||
if budget_against_field and args.get(budget_against_field):
|
||||
condition += " and %s = '%s'" %(budget_against_field, args.get(budget_against_field))
|
||||
condition += " and child.%s = '%s'" %(budget_against_field, args.get(budget_against_field))
|
||||
|
||||
if args.get('fiscal_year'):
|
||||
date_field = 'schedule_date' if for_doc == 'Material Request' else 'transaction_date'
|
||||
start_date, end_date = frappe.db.get_value('Fiscal Year', args.get('fiscal_year'),
|
||||
['year_start_date', 'year_end_date'])
|
||||
|
||||
alias = 'mr' if for_doc == 'Material Request' else 'po'
|
||||
condition += """ and %s.%s
|
||||
between '%s' and '%s' """ %(alias, date_field, start_date, end_date)
|
||||
condition += """ and parent.%s
|
||||
between '%s' and '%s' """ %(date_field, start_date, end_date)
|
||||
|
||||
return condition
|
||||
|
||||
|
||||
@@ -32,10 +32,12 @@ frappe.ui.form.on('C-Form Invoice Detail', {
|
||||
invoice_no(frm, cdt, cdn) {
|
||||
let d = frappe.get_doc(cdt, cdn);
|
||||
|
||||
frm.call('get_invoice_details', {
|
||||
invoice_no: d.invoice_no
|
||||
}).then(r => {
|
||||
frappe.model.set_value(cdt, cdn, r.message);
|
||||
});
|
||||
if (d.invoice_no) {
|
||||
frm.call('get_invoice_details', {
|
||||
invoice_no: d.invoice_no
|
||||
}).then(r => {
|
||||
frappe.model.set_value(cdt, cdn, r.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -96,7 +96,11 @@ def build_forest(data):
|
||||
if parent_account == account_name == child:
|
||||
return [parent_account]
|
||||
elif account_name == child:
|
||||
return [child] + return_parent(data, parent_account)
|
||||
parent_account_list = return_parent(data, parent_account)
|
||||
if not parent_account_list and parent_account:
|
||||
frappe.throw(_("The parent account {0} does not exists")
|
||||
.format(parent_account))
|
||||
return [child] + parent_account_list
|
||||
|
||||
charts_map, paths = {}, []
|
||||
|
||||
@@ -104,7 +108,7 @@ def build_forest(data):
|
||||
error_messages = []
|
||||
|
||||
for i in data:
|
||||
account_name, _, account_number, is_group, account_type, root_type = i
|
||||
account_name, dummy, account_number, is_group, account_type, root_type = i
|
||||
|
||||
if not account_name:
|
||||
error_messages.append("Row {0}: Please enter Account Name".format(line_no))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_copy": 1,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
@@ -123,10 +124,13 @@
|
||||
],
|
||||
"icon": "fa fa-money",
|
||||
"idx": 1,
|
||||
"modified": "2019-09-16 14:44:17.103548",
|
||||
"is_tree": 1,
|
||||
"links": [],
|
||||
"modified": "2020-03-18 18:26:01.540170",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Cost Center",
|
||||
"nsm_parent_field": "parent_cost_center",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
@@ -162,7 +166,6 @@
|
||||
"role": "Purchase User"
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"search_fields": "parent_cost_center, is_group",
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
frappe.treeview_settings["Cost Center"] = {
|
||||
breadcrumbs: "Accounts",
|
||||
breadcrumb: "Accounts",
|
||||
get_tree_root: false,
|
||||
filters: [{
|
||||
fieldname: "company",
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
"in_list_view": 1,
|
||||
"label": "Invoice",
|
||||
"options": "Sales Invoice",
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "sales_invoice.customer",
|
||||
@@ -60,7 +61,7 @@
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"modified": "2019-09-26 11:05:36.016772",
|
||||
"modified": "2020-02-20 16:16:20.724620",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Discounted Invoice",
|
||||
|
||||
@@ -7,4 +7,4 @@ from __future__ import unicode_literals
|
||||
from frappe.model.document import Document
|
||||
|
||||
class DiscountedInvoice(Document):
|
||||
pass
|
||||
pass
|
||||
File diff suppressed because it is too large
Load Diff
@@ -232,10 +232,13 @@ def update_outstanding_amt(account, party_type, party, against_voucher_type, aga
|
||||
if bal < 0 and not on_cancel:
|
||||
frappe.throw(_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal)))
|
||||
|
||||
# Update outstanding amt on against voucher
|
||||
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
|
||||
ref_doc = frappe.get_doc(against_voucher_type, against_voucher)
|
||||
ref_doc.db_set('outstanding_amount', bal)
|
||||
|
||||
# Didn't use db_set for optimisation purpose
|
||||
ref_doc.outstanding_amount = bal
|
||||
frappe.db.set_value(against_voucher_type, against_voucher, 'outstanding_amount', bal)
|
||||
|
||||
ref_doc.set_status(update=True)
|
||||
|
||||
def validate_frozen_account(account, adv_adj=None):
|
||||
@@ -274,6 +277,9 @@ def update_against_account(voucher_type, voucher_no):
|
||||
if d.against != new_against:
|
||||
frappe.db.set_value("GL Entry", d.name, "against", new_against)
|
||||
|
||||
def on_doctype_update():
|
||||
frappe.db.add_index("GL Entry", ["against_voucher_type", "against_voucher"])
|
||||
frappe.db.add_index("GL Entry", ["voucher_type", "voucher_no"])
|
||||
|
||||
def rename_gle_sle_docs():
|
||||
for doctype in ["GL Entry", "Stock Ledger Entry"]:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -456,11 +456,12 @@ class JournalEntry(AccountsController):
|
||||
def set_print_format_fields(self):
|
||||
bank_amount = party_amount = total_amount = 0.0
|
||||
currency = bank_account_currency = party_account_currency = pay_to_recd_from= None
|
||||
party_type = None
|
||||
for d in self.get('accounts'):
|
||||
if d.party_type in ['Customer', 'Supplier'] and d.party:
|
||||
party_type = d.party_type
|
||||
if not pay_to_recd_from:
|
||||
pay_to_recd_from = frappe.db.get_value(d.party_type, d.party,
|
||||
"customer_name" if d.party_type=="Customer" else "supplier_name")
|
||||
pay_to_recd_from = d.party
|
||||
|
||||
if pay_to_recd_from and pay_to_recd_from == d.party:
|
||||
party_amount += (d.debit_in_account_currency or d.credit_in_account_currency)
|
||||
@@ -470,8 +471,9 @@ class JournalEntry(AccountsController):
|
||||
bank_amount += (d.debit_in_account_currency or d.credit_in_account_currency)
|
||||
bank_account_currency = d.account_currency
|
||||
|
||||
if pay_to_recd_from:
|
||||
self.pay_to_recd_from = pay_to_recd_from
|
||||
if party_type and pay_to_recd_from:
|
||||
self.pay_to_recd_from = frappe.db.get_value(party_type, pay_to_recd_from,
|
||||
"customer_name" if party_type=="Customer" else "supplier_name")
|
||||
if bank_amount:
|
||||
total_amount = bank_amount
|
||||
currency = bank_account_currency
|
||||
|
||||
@@ -11,6 +11,7 @@ class ModeofPayment(Document):
|
||||
def validate(self):
|
||||
self.validate_accounts()
|
||||
self.validate_repeating_companies()
|
||||
self.validate_pos_mode_of_payment()
|
||||
|
||||
def validate_repeating_companies(self):
|
||||
"""Error when Same Company is entered multiple times in accounts"""
|
||||
@@ -27,3 +28,15 @@ class ModeofPayment(Document):
|
||||
if frappe.db.get_value("Account", entry.default_account, "company") != entry.company:
|
||||
frappe.throw(_("Account {0} does not match with Company {1} in Mode of Account: {2}")
|
||||
.format(entry.default_account, entry.company, self.name))
|
||||
|
||||
def validate_pos_mode_of_payment(self):
|
||||
if not self.enabled:
|
||||
pos_profiles = frappe.db.sql("""SELECT sip.parent FROM `tabSales Invoice Payment` sip
|
||||
WHERE sip.parenttype = 'POS Profile' and sip.mode_of_payment = %s""", (self.name))
|
||||
pos_profiles = list(map(lambda x: x[0], pos_profiles))
|
||||
|
||||
if pos_profiles:
|
||||
message = "POS Profile " + frappe.bold(", ".join(pos_profiles)) + " contains \
|
||||
Mode of Payment " + frappe.bold(str(self.name)) + ". Please remove them to disable this mode."
|
||||
frappe.throw(_(message), title="Not Allowed")
|
||||
|
||||
|
||||
@@ -154,8 +154,11 @@ frappe.ui.form.on('Payment Entry', {
|
||||
|
||||
frm.toggle_display("base_paid_amount", frm.doc.paid_from_account_currency != company_currency);
|
||||
|
||||
frm.toggle_display("base_received_amount", (frm.doc.paid_to_account_currency != company_currency &&
|
||||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
|
||||
frm.toggle_display("base_received_amount", (
|
||||
frm.doc.paid_to_account_currency != company_currency &&
|
||||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency
|
||||
&& frm.doc.base_paid_amount != frm.doc.base_received_amount
|
||||
));
|
||||
|
||||
frm.toggle_display("received_amount", (frm.doc.payment_type=="Internal Transfer" ||
|
||||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency))
|
||||
@@ -486,6 +489,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
paid_amount: function(frm) {
|
||||
frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
|
||||
frm.trigger("reset_received_amount");
|
||||
frm.events.hide_unhide_fields(frm);
|
||||
},
|
||||
|
||||
received_amount: function(frm) {
|
||||
@@ -509,6 +513,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.events.set_unallocated_amount(frm);
|
||||
|
||||
frm.set_paid_amount_based_on_received_amount = false;
|
||||
frm.events.hide_unhide_fields(frm);
|
||||
},
|
||||
|
||||
reset_received_amount: function(frm) {
|
||||
|
||||
@@ -81,7 +81,12 @@ class PaymentEntry(AccountsController):
|
||||
self.update_advance_paid()
|
||||
self.update_expense_claim()
|
||||
self.delink_advance_entry_references()
|
||||
self.set_payment_req_status()
|
||||
self.set_status()
|
||||
|
||||
def set_payment_req_status(self):
|
||||
from erpnext.accounts.doctype.payment_request.payment_request import update_payment_req_status
|
||||
update_payment_req_status(self, None)
|
||||
|
||||
def update_outstanding_amounts(self):
|
||||
self.set_missing_ref_details(force=True)
|
||||
@@ -102,7 +107,9 @@ class PaymentEntry(AccountsController):
|
||||
|
||||
self.bank = bank_data.bank
|
||||
self.bank_account_no = bank_data.bank_account_no
|
||||
self.set(field, bank_data.account)
|
||||
|
||||
if not self.get(field):
|
||||
self.set(field, bank_data.account)
|
||||
|
||||
def validate_allocated_amount(self):
|
||||
for d in self.get("references"):
|
||||
|
||||
@@ -149,6 +149,49 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", pi.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, 0)
|
||||
|
||||
|
||||
def test_payment_against_sales_invoice_to_check_status(self):
|
||||
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||
currency="USD", conversion_rate=50)
|
||||
|
||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
pe.target_exchange_rate = 50
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
outstanding_amount, status = frappe.db.get_value("Sales Invoice", si.name, ["outstanding_amount", "status"])
|
||||
self.assertEqual(flt(outstanding_amount), 0)
|
||||
self.assertEqual(status, 'Paid')
|
||||
|
||||
pe.cancel()
|
||||
|
||||
outstanding_amount, status = frappe.db.get_value("Sales Invoice", si.name, ["outstanding_amount", "status"])
|
||||
self.assertEqual(flt(outstanding_amount), 100)
|
||||
self.assertEqual(status, 'Unpaid')
|
||||
|
||||
def test_payment_against_purchase_invoice_to_check_status(self):
|
||||
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
|
||||
currency="USD", conversion_rate=50)
|
||||
|
||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank USD - _TC")
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
pe.source_exchange_rate = 50
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
outstanding_amount, status = frappe.db.get_value("Purchase Invoice", pi.name, ["outstanding_amount", "status"])
|
||||
self.assertEqual(flt(outstanding_amount), 0)
|
||||
self.assertEqual(status, 'Paid')
|
||||
|
||||
pe.cancel()
|
||||
|
||||
outstanding_amount, status = frappe.db.get_value("Purchase Invoice", pi.name, ["outstanding_amount", "status"])
|
||||
self.assertEqual(flt(outstanding_amount), 250)
|
||||
self.assertEqual(status, 'Unpaid')
|
||||
|
||||
def test_payment_entry_against_ec(self):
|
||||
|
||||
payable = frappe.get_cached_value('Company', "_Test Company", 'default_payable_account')
|
||||
@@ -566,4 +609,4 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
self.assertEqual(expected_party_account_balance, party_account_balance)
|
||||
|
||||
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
|
||||
accounts_settings.save()
|
||||
accounts_settings.save()
|
||||
@@ -15,11 +15,11 @@ frappe.ui.form.on('Payment Order', {
|
||||
if (frm.doc.docstatus == 0) {
|
||||
frm.add_custom_button(__('Payment Request'), function() {
|
||||
frm.trigger("get_from_payment_request");
|
||||
}, __("Get from"));
|
||||
}, __("Get Payments from"));
|
||||
|
||||
frm.add_custom_button(__('Payment Entry'), function() {
|
||||
frm.trigger("get_from_payment_entry");
|
||||
}, __("Get from"));
|
||||
}, __("Get Payments from"));
|
||||
|
||||
frm.trigger('remove_button');
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 1,
|
||||
"fieldname": "references",
|
||||
"fieldtype": "Table",
|
||||
"label": "Payment Order Reference",
|
||||
@@ -108,7 +107,7 @@
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"modified": "2019-05-14 17:12:24.912666",
|
||||
"modified": "2020-04-06 18:00:56.022642",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Order",
|
||||
|
||||
@@ -92,6 +92,7 @@ class PaymentReconciliation(Document):
|
||||
FROM `tab{doc}`, `tabGL Entry`
|
||||
WHERE
|
||||
(`tab{doc}`.name = `tabGL Entry`.against_voucher or `tab{doc}`.name = `tabGL Entry`.voucher_no)
|
||||
and `tab{doc}`.{party_type_field} = %(party)s
|
||||
and `tab{doc}`.is_return = 1 and `tab{doc}`.return_against IS NULL
|
||||
and `tabGL Entry`.against_voucher_type = %(voucher_type)s
|
||||
and `tab{doc}`.docstatus = 1 and `tabGL Entry`.party = %(party)s
|
||||
@@ -99,12 +100,17 @@ class PaymentReconciliation(Document):
|
||||
GROUP BY `tab{doc}`.name
|
||||
Having
|
||||
amount > 0
|
||||
""".format(doc=voucher_type, dr_or_cr=dr_or_cr, reconciled_dr_or_cr=reconciled_dr_or_cr), {
|
||||
'party': self.party,
|
||||
'party_type': self.party_type,
|
||||
'voucher_type': voucher_type,
|
||||
'account': self.receivable_payable_account
|
||||
}, as_dict=1)
|
||||
""".format(
|
||||
doc=voucher_type,
|
||||
dr_or_cr=dr_or_cr,
|
||||
reconciled_dr_or_cr=reconciled_dr_or_cr,
|
||||
party_type_field=frappe.scrub(self.party_type)),
|
||||
{
|
||||
'party': self.party,
|
||||
'party_type': self.party_type,
|
||||
'voucher_type': voucher_type,
|
||||
'account': self.receivable_payable_account
|
||||
}, as_dict=1)
|
||||
|
||||
def add_payment_entries(self, entries):
|
||||
self.set('payments', [])
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -66,6 +66,8 @@ class PaymentRequest(Document):
|
||||
if self.payment_request_type == 'Outward':
|
||||
self.db_set('status', 'Initiated')
|
||||
return
|
||||
elif self.payment_request_type == 'Inward':
|
||||
self.db_set('status', 'Requested')
|
||||
|
||||
send_mail = self.payment_gateway_validation()
|
||||
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||
@@ -88,6 +90,7 @@ class PaymentRequest(Document):
|
||||
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"):
|
||||
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
|
||||
si = make_sales_invoice(self.reference_name, ignore_permissions=True)
|
||||
si.allocate_advances_automatically = True
|
||||
si = si.insert(ignore_permissions=True)
|
||||
si.submit()
|
||||
|
||||
@@ -126,12 +129,12 @@ class PaymentRequest(Document):
|
||||
|
||||
return controller.get_payment_url(**{
|
||||
"amount": flt(self.grand_total, self.precision("grand_total")),
|
||||
"title": data.company.encode("utf-8"),
|
||||
"description": self.subject.encode("utf-8"),
|
||||
"title": frappe.as_unicode(data.company),
|
||||
"description": frappe.as_unicode(self.subject),
|
||||
"reference_doctype": "Payment Request",
|
||||
"reference_docname": self.name,
|
||||
"payer_email": self.email_to or frappe.session.user,
|
||||
"payer_name": frappe.safe_encode(data.customer_name),
|
||||
"payer_name": frappe.as_unicode(data.customer_name),
|
||||
"order_id": self.name,
|
||||
"currency": self.currency
|
||||
})
|
||||
@@ -317,13 +320,13 @@ def make_payment_request(**args):
|
||||
"payment_request_type": args.get("payment_request_type"),
|
||||
"currency": ref_doc.currency,
|
||||
"grand_total": grand_total,
|
||||
"email_to": args.recipient_id or "",
|
||||
"email_to": args.recipient_id or ref_doc.owner,
|
||||
"subject": _("Payment Request for {0}").format(args.dn),
|
||||
"message": gateway_account.get("message") or get_dummy_message(ref_doc),
|
||||
"reference_doctype": args.dt,
|
||||
"reference_name": args.dn,
|
||||
"party_type": args.get("party_type"),
|
||||
"party": args.get("party"),
|
||||
"party_type": args.get("party_type") or "Customer",
|
||||
"party": args.get("party") or ref_doc.customer,
|
||||
"bank_account": bank_account
|
||||
})
|
||||
|
||||
@@ -373,6 +376,7 @@ def get_existing_payment_request_amount(ref_dt, ref_dn):
|
||||
reference_doctype = %s
|
||||
and reference_name = %s
|
||||
and docstatus = 1
|
||||
and status != 'Paid'
|
||||
""", (ref_dt, ref_dn))
|
||||
return flt(existing_payment_request_amount[0][0]) if existing_payment_request_amount else 0
|
||||
|
||||
@@ -414,17 +418,31 @@ def make_payment_entry(docname):
|
||||
doc = frappe.get_doc("Payment Request", docname)
|
||||
return doc.create_payment_entry(submit=False).as_dict()
|
||||
|
||||
def make_status_as_paid(doc, method):
|
||||
def update_payment_req_status(doc, method):
|
||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_reference_details
|
||||
|
||||
for ref in doc.references:
|
||||
payment_request_name = frappe.db.get_value("Payment Request",
|
||||
{"reference_doctype": ref.reference_doctype, "reference_name": ref.reference_name,
|
||||
"docstatus": 1})
|
||||
|
||||
if payment_request_name:
|
||||
doc = frappe.get_doc("Payment Request", payment_request_name)
|
||||
if doc.status != "Paid":
|
||||
doc.db_set('status', 'Paid')
|
||||
frappe.db.commit()
|
||||
ref_details = get_reference_details(ref.reference_doctype, ref.reference_name, doc.party_account_currency)
|
||||
pay_req_doc = frappe.get_doc('Payment Request', payment_request_name)
|
||||
status = pay_req_doc.status
|
||||
|
||||
if status != "Paid" and not ref_details.outstanding_amount:
|
||||
status = 'Paid'
|
||||
elif status != "Partially Paid" and ref_details.outstanding_amount != ref_details.total_amount:
|
||||
status = 'Partially Paid'
|
||||
elif ref_details.outstanding_amount == ref_details.total_amount:
|
||||
if pay_req_doc.payment_request_type == 'Outward':
|
||||
status = 'Initiated'
|
||||
elif pay_req_doc.payment_request_type == 'Inward':
|
||||
status = 'Requested'
|
||||
|
||||
pay_req_doc.db_set('status', status)
|
||||
frappe.db.commit()
|
||||
|
||||
def get_dummy_message(doc):
|
||||
return frappe.render_template("""{% if doc.contact_person -%}
|
||||
@@ -474,4 +492,4 @@ def make_payment_order(source_name, target_doc=None):
|
||||
}
|
||||
}, target_doc, set_missing_values)
|
||||
|
||||
return doclist
|
||||
return doclist
|
||||
|
||||
@@ -4,14 +4,20 @@ frappe.listview_settings['Payment Request'] = {
|
||||
if(doc.status == "Draft") {
|
||||
return [__("Draft"), "darkgrey", "status,=,Draft"];
|
||||
}
|
||||
if(doc.status == "Requested") {
|
||||
return [__("Requested"), "green", "status,=,Requested"];
|
||||
}
|
||||
else if(doc.status == "Initiated") {
|
||||
return [__("Initiated"), "green", "status,=,Initiated"];
|
||||
}
|
||||
else if(doc.status == "Partially Paid") {
|
||||
return [__("Partially Paid"), "orange", "status,=,Partially Paid"];
|
||||
}
|
||||
else if(doc.status == "Paid") {
|
||||
return [__("Paid"), "blue", "status,=,Paid"];
|
||||
}
|
||||
else if(doc.status == "Cancelled") {
|
||||
return [__("Cancelled"), "orange", "status,=,Cancelled"];
|
||||
return [__("Cancelled"), "red", "status,=,Cancelled"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +101,23 @@ class TestPaymentRequest(unittest.TestCase):
|
||||
self.assertEqual(expected_gle[gle.account][2], gle.credit)
|
||||
self.assertEqual(expected_gle[gle.account][3], gle.against_voucher)
|
||||
|
||||
def test_status(self):
|
||||
si_usd = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||
currency="USD", conversion_rate=50)
|
||||
|
||||
pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com",
|
||||
mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1, return_doc=1)
|
||||
|
||||
pe = pr.create_payment_entry()
|
||||
pr.load_from_db()
|
||||
|
||||
self.assertEqual(pr.status, 'Paid')
|
||||
|
||||
pe.cancel()
|
||||
pr.load_from_db()
|
||||
|
||||
self.assertEqual(pr.status, 'Requested')
|
||||
|
||||
def test_multiple_payment_entries_against_sales_order(self):
|
||||
# Make Sales Order, grand_total = 1000
|
||||
so = make_sales_order()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"autoname": "Prompt",
|
||||
"creation": "2013-05-24 12:15:51",
|
||||
"doctype": "DocType",
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"disabled",
|
||||
"section_break_2",
|
||||
@@ -50,6 +51,7 @@
|
||||
"income_account",
|
||||
"expense_account",
|
||||
"taxes_and_charges",
|
||||
"tax_category",
|
||||
"apply_discount_on",
|
||||
"accounting_dimensions_section",
|
||||
"cost_center",
|
||||
@@ -381,11 +383,17 @@
|
||||
{
|
||||
"fieldname": "dimension_col_break",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "tax_category",
|
||||
"fieldtype": "Link",
|
||||
"label": "Tax Category",
|
||||
"options": "Tax Category"
|
||||
}
|
||||
],
|
||||
"icon": "icon-cog",
|
||||
"idx": 1,
|
||||
"modified": "2019-05-25 22:56:30.352693",
|
||||
"modified": "2020-01-24 15:52:03.797701",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Profile",
|
||||
|
||||
@@ -252,7 +252,7 @@ def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=Fa
|
||||
if pricing_rule.price_or_product_discount == "Price":
|
||||
apply_price_discount_rule(pricing_rule, item_details, args)
|
||||
else:
|
||||
get_product_discount_rule(pricing_rule, item_details, doc)
|
||||
get_product_discount_rule(pricing_rule, item_details, args, doc)
|
||||
|
||||
item_details.has_pricing_rule = 1
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_orde
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||
from erpnext.stock.get_item_details import get_item_details
|
||||
from frappe import MandatoryError
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.healthcare.doctype.lab_test_template.lab_test_template import make_item_price
|
||||
|
||||
class TestPricingRule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
@@ -145,6 +147,52 @@ class TestPricingRule(unittest.TestCase):
|
||||
self.assertEquals(details.get("margin_type"), "Percentage")
|
||||
self.assertEquals(details.get("margin_rate_or_amount"), 10)
|
||||
|
||||
def test_mixed_conditions_for_item_group(self):
|
||||
for item in ["Mixed Cond Item 1", "Mixed Cond Item 2"]:
|
||||
make_item(item, {"item_group": "Products"})
|
||||
make_item_price(item, "_Test Price List", 100)
|
||||
|
||||
test_record = {
|
||||
"doctype": "Pricing Rule",
|
||||
"title": "_Test Pricing Rule for Item Group",
|
||||
"apply_on": "Item Group",
|
||||
"item_groups": [
|
||||
{
|
||||
"item_group": "Products",
|
||||
},
|
||||
{
|
||||
"item_group": "Seed",
|
||||
},
|
||||
],
|
||||
"selling": 1,
|
||||
"mixed_conditions": 1,
|
||||
"currency": "USD",
|
||||
"rate_or_discount": "Discount Percentage",
|
||||
"discount_percentage": 10,
|
||||
"applicable_for": "Customer Group",
|
||||
"customer_group": "All Customer Groups",
|
||||
"company": "_Test Company"
|
||||
}
|
||||
frappe.get_doc(test_record.copy()).insert()
|
||||
|
||||
args = frappe._dict({
|
||||
"item_code": "Mixed Cond Item 1",
|
||||
"item_group": "Products",
|
||||
"company": "_Test Company",
|
||||
"price_list": "_Test Price List",
|
||||
"currency": "_Test Currency",
|
||||
"doctype": "Sales Order",
|
||||
"conversion_rate": 1,
|
||||
"price_list_currency": "_Test Currency",
|
||||
"plc_conversion_rate": 1,
|
||||
"order_type": "Sales",
|
||||
"customer": "_Test Customer",
|
||||
"customer_group": "_Test Customer Group",
|
||||
"name": None
|
||||
})
|
||||
details = get_item_details(args)
|
||||
self.assertEquals(details.get("discount_percentage"), 10)
|
||||
|
||||
def test_pricing_rule_for_variants(self):
|
||||
from erpnext.stock.get_item_details import get_item_details
|
||||
from frappe import MandatoryError
|
||||
@@ -278,6 +326,66 @@ class TestPricingRule(unittest.TestCase):
|
||||
self.assertEquals(item.discount_amount, 110)
|
||||
self.assertEquals(item.rate, 990)
|
||||
|
||||
def test_pricing_rule_for_product_discount_on_same_item(self):
|
||||
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
|
||||
test_record = {
|
||||
"doctype": "Pricing Rule",
|
||||
"title": "_Test Pricing Rule",
|
||||
"apply_on": "Item Code",
|
||||
"currency": "USD",
|
||||
"items": [{
|
||||
"item_code": "_Test Item",
|
||||
}],
|
||||
"selling": 1,
|
||||
"rate_or_discount": "Discount Percentage",
|
||||
"rate": 0,
|
||||
"min_qty": 0,
|
||||
"max_qty": 7,
|
||||
"discount_percentage": 17.5,
|
||||
"price_or_product_discount": "Product",
|
||||
"same_item": 1,
|
||||
"free_qty": 1,
|
||||
"company": "_Test Company"
|
||||
}
|
||||
frappe.get_doc(test_record.copy()).insert()
|
||||
|
||||
# With pricing rule
|
||||
so = make_sales_order(item_code="_Test Item", qty=1)
|
||||
so.load_from_db()
|
||||
self.assertEqual(so.items[1].is_free_item, 1)
|
||||
self.assertEqual(so.items[1].item_code, "_Test Item")
|
||||
|
||||
|
||||
def test_pricing_rule_for_product_discount_on_different_item(self):
|
||||
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
|
||||
test_record = {
|
||||
"doctype": "Pricing Rule",
|
||||
"title": "_Test Pricing Rule",
|
||||
"apply_on": "Item Code",
|
||||
"currency": "USD",
|
||||
"items": [{
|
||||
"item_code": "_Test Item",
|
||||
}],
|
||||
"selling": 1,
|
||||
"rate_or_discount": "Discount Percentage",
|
||||
"rate": 0,
|
||||
"min_qty": 0,
|
||||
"max_qty": 7,
|
||||
"discount_percentage": 17.5,
|
||||
"price_or_product_discount": "Product",
|
||||
"same_item": 0,
|
||||
"free_item": "_Test Item 2",
|
||||
"free_qty": 1,
|
||||
"company": "_Test Company"
|
||||
}
|
||||
frappe.get_doc(test_record.copy()).insert()
|
||||
|
||||
# With pricing rule
|
||||
so = make_sales_order(item_code="_Test Item", qty=1)
|
||||
so.load_from_db()
|
||||
self.assertEqual(so.items[1].is_free_item, 1)
|
||||
self.assertEqual(so.items[1].item_code, "_Test Item 2")
|
||||
|
||||
def make_pricing_rule(**args):
|
||||
args = frappe._dict(args)
|
||||
|
||||
|
||||
@@ -178,7 +178,8 @@ def filter_pricing_rules(args, pricing_rules, doc=None):
|
||||
|
||||
if pricing_rules[0].mixed_conditions and doc:
|
||||
stock_qty, amount, items = get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args)
|
||||
pricing_rules[0].apply_rule_on_other_items = items
|
||||
for pricing_rule_args in pricing_rules:
|
||||
pricing_rule_args.apply_rule_on_other_items = items
|
||||
|
||||
elif pricing_rules[0].is_cumulative:
|
||||
items = [args.get(frappe.scrub(pr_doc.get('apply_on')))]
|
||||
@@ -245,7 +246,7 @@ def filter_pricing_rules(args, pricing_rules, doc=None):
|
||||
|
||||
def validate_quantity_and_amount_for_suggestion(args, qty, amount, item_code, transaction_type):
|
||||
fieldname, msg = '', ''
|
||||
type_of_transaction = 'purcahse' if transaction_type == "buying" else "sale"
|
||||
type_of_transaction = 'purchase' if transaction_type == 'buying' else 'sale'
|
||||
|
||||
for field, value in {'min_qty': qty, 'min_amt': amount}.items():
|
||||
if (args.get(field) and value < args.get(field)
|
||||
@@ -329,9 +330,9 @@ def get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args):
|
||||
if pr_doc.mixed_conditions:
|
||||
amt = args.get('qty') * args.get("price_list_rate")
|
||||
if args.get("item_code") != row.get("item_code"):
|
||||
amt = row.get('qty') * row.get("price_list_rate")
|
||||
amt = row.get('qty') * (row.get("price_list_rate") or args.get("rate"))
|
||||
|
||||
sum_qty += row.get("stock_qty") or args.get("stock_qty")
|
||||
sum_qty += row.get("stock_qty") or args.get("stock_qty") or args.get("qty")
|
||||
sum_amt += amt
|
||||
|
||||
if pr_doc.is_cumulative:
|
||||
@@ -435,7 +436,7 @@ def apply_pricing_rule_on_transaction(doc):
|
||||
doc.calculate_taxes_and_totals()
|
||||
elif d.price_or_product_discount == 'Product':
|
||||
item_details = frappe._dict({'parenttype': doc.doctype})
|
||||
get_product_discount_rule(d, item_details, doc)
|
||||
get_product_discount_rule(d, item_details, doc=doc)
|
||||
apply_pricing_rule_for_free_items(doc, item_details.free_item_data)
|
||||
doc.set_missing_values()
|
||||
|
||||
@@ -443,9 +444,10 @@ def get_applied_pricing_rules(item_row):
|
||||
return (item_row.get("pricing_rules").split(',')
|
||||
if item_row.get("pricing_rules") else [])
|
||||
|
||||
def get_product_discount_rule(pricing_rule, item_details, doc=None):
|
||||
free_item = (pricing_rule.free_item
|
||||
if not pricing_rule.same_item or pricing_rule.apply_on == 'Transaction' else item_details.item_code)
|
||||
def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None):
|
||||
free_item = pricing_rule.free_item
|
||||
if pricing_rule.same_item:
|
||||
free_item = item_details.item_code or args.item_code
|
||||
|
||||
if not free_item:
|
||||
frappe.throw(_("Free item not set in the pricing rule {0}")
|
||||
@@ -464,7 +466,7 @@ def get_product_discount_rule(pricing_rule, item_details, doc=None):
|
||||
|
||||
item_details.free_item_data.update(item_data)
|
||||
item_details.free_item_data['uom'] = pricing_rule.free_item_uom or item_data.stock_uom
|
||||
item_details.free_item_data['conversion_factor'] = get_conversion_factor(free_item,
|
||||
item_details.free_item_data['conversion_factor'] = get_conversion_factor(free_item,
|
||||
item_details.free_item_data['uom']).get("conversion_factor", 1)
|
||||
|
||||
if item_details.get("parenttype") == 'Purchase Order':
|
||||
@@ -489,7 +491,7 @@ def get_pricing_rule_items(pr_doc):
|
||||
|
||||
for d in pr_doc.get(pricing_rule_apply_on):
|
||||
if apply_on == 'item_group':
|
||||
get_child_item_groups(d.get(apply_on))
|
||||
apply_on_data.extend(get_child_item_groups(d.get(apply_on)))
|
||||
else:
|
||||
apply_on_data.append(d.get(apply_on))
|
||||
|
||||
@@ -507,7 +509,7 @@ def validate_coupon_code(coupon_name):
|
||||
frappe.throw(_("Sorry,coupon code validity has not started"))
|
||||
elif coupon.valid_upto:
|
||||
if coupon.valid_upto < getdate(today()) :
|
||||
frappe.throw(_("Sorry,coupon code validity has expired"))
|
||||
frappe.throw(_("Sorry,coupon code validity has expired"))
|
||||
elif coupon.used>=coupon.maximum_use:
|
||||
frappe.throw(_("Sorry,coupon code are exhausted"))
|
||||
else:
|
||||
|
||||
@@ -167,8 +167,16 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
make_comment_dialog_and_block_invoice: function(){
|
||||
const me = this;
|
||||
|
||||
const title = __('Add Comment');
|
||||
const title = __('Block Invoice');
|
||||
const fields = [
|
||||
{
|
||||
fieldname: 'release_date',
|
||||
read_only: 0,
|
||||
fieldtype:'Date',
|
||||
label: __('Release Date'),
|
||||
default: me.frm.doc.release_date,
|
||||
reqd: 1
|
||||
},
|
||||
{
|
||||
fieldname: 'hold_comment',
|
||||
read_only: 0,
|
||||
@@ -187,7 +195,11 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
const dialog_data = me.dialog.get_values();
|
||||
frappe.call({
|
||||
'method': 'erpnext.accounts.doctype.purchase_invoice.purchase_invoice.block_invoice',
|
||||
'args': {'name': me.frm.doc.name, 'hold_comment': dialog_data.hold_comment},
|
||||
'args': {
|
||||
'name': me.frm.doc.name,
|
||||
'hold_comment': dialog_data.hold_comment,
|
||||
'release_date': dialog_data.release_date
|
||||
},
|
||||
'callback': (r) => me.frm.reload_doc()
|
||||
});
|
||||
me.dialog.hide();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, erpnext
|
||||
from frappe.utils import cint, cstr, formatdate, flt, getdate, nowdate
|
||||
from frappe.utils import cint, cstr, formatdate, flt, getdate, nowdate, get_link_to_form
|
||||
from frappe import _, throw
|
||||
import frappe.defaults
|
||||
|
||||
@@ -146,10 +146,14 @@ class PurchaseInvoice(BuyingController):
|
||||
["account_type", "report_type", "account_currency"], as_dict=True)
|
||||
|
||||
if account.report_type != "Balance Sheet":
|
||||
frappe.throw(_("Credit To account must be a Balance Sheet account"))
|
||||
frappe.throw(_("Please ensure {} account is a Balance Sheet account. \
|
||||
You can change the parent account to a Balance Sheet account or select a different account.")
|
||||
.format(frappe.bold("Credit To")), title=_("Invalid Account"))
|
||||
|
||||
if self.supplier and account.account_type != "Payable":
|
||||
frappe.throw(_("Credit To account must be a Payable account"))
|
||||
frappe.throw(_("Please ensure {} account is a Payable account. \
|
||||
Change the account type to Payable or select a different account.")
|
||||
.format(frappe.bold("Credit To")), title=_("Invalid Account"))
|
||||
|
||||
self.party_account_currency = account.account_currency
|
||||
|
||||
@@ -255,16 +259,30 @@ class PurchaseInvoice(BuyingController):
|
||||
|
||||
def po_required(self):
|
||||
if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes':
|
||||
|
||||
if frappe.get_value('Supplier', self.supplier, 'allow_purchase_invoice_creation_without_purchase_order'):
|
||||
return
|
||||
|
||||
for d in self.get('items'):
|
||||
if not d.purchase_order:
|
||||
throw(_("As per the Buying Settings if Purchase Order Required == 'YES', then for creating Purchase Invoice, user need to create Purchase Order first for item {0}").format(d.item_code))
|
||||
throw(_("""Purchase Order Required for item {0}
|
||||
To submit the invoice without purchase order please set
|
||||
{1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold(_('Purchase Order Required')),
|
||||
frappe.bold('No'), get_link_to_form('Buying Settings', 'Buying Settings', 'Buying Settings')))
|
||||
|
||||
def pr_required(self):
|
||||
stock_items = self.get_stock_items()
|
||||
if frappe.db.get_value("Buying Settings", None, "pr_required") == 'Yes':
|
||||
|
||||
if frappe.get_value('Supplier', self.supplier, 'allow_purchase_invoice_creation_without_purchase_receipt'):
|
||||
return
|
||||
|
||||
for d in self.get('items'):
|
||||
if not d.purchase_receipt and d.item_code in stock_items:
|
||||
throw(_("As per the Buying Settings if Purchase Reciept Required == 'YES', then for creating Purchase Invoice, user need to create Purchase Receipt first for item {0}").format(d.item_code))
|
||||
throw(_("""Purchase Receipt Required for item {0}
|
||||
To submit the invoice without purchase receipt please set
|
||||
{1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold(_('Purchase Receipt Required')),
|
||||
frappe.bold('No'), get_link_to_form('Buying Settings', 'Buying Settings', 'Buying Settings')))
|
||||
|
||||
def validate_write_off_account(self):
|
||||
if self.write_off_amount and not self.write_off_account:
|
||||
@@ -368,7 +386,7 @@ class PurchaseInvoice(BuyingController):
|
||||
update_outstanding_amt(self.credit_to, "Supplier", self.supplier,
|
||||
self.doctype, self.return_against if cint(self.is_return) and self.return_against else self.name)
|
||||
|
||||
if repost_future_gle and cint(self.update_stock) and self.auto_accounting_for_stock:
|
||||
if (repost_future_gle or self.flags.repost_future_gle) and cint(self.update_stock) and self.auto_accounting_for_stock:
|
||||
from erpnext.controllers.stock_controller import update_gl_entries_after
|
||||
items, warehouses = self.get_items_and_warehouses()
|
||||
update_gl_entries_after(self.posting_date, self.posting_time,
|
||||
@@ -866,6 +884,7 @@ class PurchaseInvoice(BuyingController):
|
||||
# because updating ordered qty in bin depends upon updated ordered qty in PO
|
||||
if self.update_stock == 1:
|
||||
self.update_stock_ledger()
|
||||
self.delete_auto_created_batches()
|
||||
|
||||
self.make_gl_entries_on_cancel()
|
||||
self.update_project()
|
||||
@@ -927,9 +946,10 @@ class PurchaseInvoice(BuyingController):
|
||||
def on_recurring(self, reference_doc, auto_repeat_doc):
|
||||
self.due_date = None
|
||||
|
||||
def block_invoice(self, hold_comment=None):
|
||||
def block_invoice(self, hold_comment=None, release_date=None):
|
||||
self.db_set('on_hold', 1)
|
||||
self.db_set('hold_comment', cstr(hold_comment))
|
||||
self.db_set('release_date', release_date)
|
||||
|
||||
def unblock_invoice(self):
|
||||
self.db_set('on_hold', 0)
|
||||
@@ -1013,12 +1033,15 @@ def unblock_invoice(name):
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def block_invoice(name, hold_comment):
|
||||
def block_invoice(name, release_date, hold_comment=None):
|
||||
if frappe.db.exists('Purchase Invoice', name):
|
||||
pi = frappe.get_doc('Purchase Invoice', name)
|
||||
pi.block_invoice(hold_comment)
|
||||
pi.block_invoice(hold_comment, release_date)
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_inter_company_sales_invoice(source_name, target_doc=None):
|
||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
|
||||
return make_inter_company_transaction("Purchase Invoice", source_name, target_doc)
|
||||
|
||||
def on_doctype_update():
|
||||
frappe.db.add_index("Purchase Invoice", ["supplier", "is_return", "return_against"])
|
||||
@@ -198,7 +198,6 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "UOM",
|
||||
"options": "UOM",
|
||||
"print_hide": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -754,14 +753,13 @@
|
||||
{
|
||||
"fieldname": "manufacturer_part_no",
|
||||
"fieldtype": "Data",
|
||||
"label": "Manufacturer Part Number",
|
||||
"read_only": 1
|
||||
"label": "Manufacturer Part Number"
|
||||
},
|
||||
{
|
||||
"depends_on": "is_fixed_asset",
|
||||
"fetch_from": "item_code.asset_category",
|
||||
"fieldname": "asset_category",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"in_preview": 1,
|
||||
"label": "Asset Category",
|
||||
"options": "Asset Category",
|
||||
@@ -771,7 +769,7 @@
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2019-12-04 12:23:17.046413",
|
||||
"modified": "2020-04-07 18:34:35.104178",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice Item",
|
||||
|
||||
@@ -152,8 +152,11 @@ def update_multi_mode_option(doc, pos_profile):
|
||||
|
||||
|
||||
def get_mode_of_payment(doc):
|
||||
return frappe.db.sql(""" select mpa.default_account, mpa.parent, mp.type as type from `tabMode of Payment Account` mpa, \
|
||||
`tabMode of Payment` mp where mpa.parent = mp.name and mpa.company = %(company)s""", {'company': doc.company}, as_dict=1)
|
||||
return frappe.db.sql("""
|
||||
select mpa.default_account, mpa.parent, mp.type as type
|
||||
from `tabMode of Payment Account` mpa,`tabMode of Payment` mp
|
||||
where mpa.parent = mp.name and mpa.company = %(company)s and mp.enabled = 1""",
|
||||
{'company': doc.company}, as_dict=1)
|
||||
|
||||
|
||||
def update_tax_table(doc):
|
||||
@@ -204,7 +207,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([d.name for d in get_child_nodes('Customer Group', d.customer_group)])
|
||||
customer_groups.extend([d.get('name') for d in get_child_nodes('Customer Group', d.get('customer_group'))])
|
||||
cond = "customer_group in (%s)" % (', '.join(['%s'] * len(customer_groups)))
|
||||
|
||||
return frappe.db.sql(""" select name, customer_name, customer_group,
|
||||
@@ -384,7 +387,9 @@ def get_pricing_rule_data(doc):
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_invoice(doc_list={}, email_queue_list={}, customers_list={}):
|
||||
def make_invoice(pos_profile, doc_list={}, email_queue_list={}, customers_list={}):
|
||||
import json
|
||||
|
||||
if isinstance(doc_list, string_types):
|
||||
doc_list = json.loads(doc_list)
|
||||
|
||||
@@ -418,7 +423,11 @@ def make_invoice(doc_list={}, email_queue_list={}, customers_list={}):
|
||||
name_list.append(name)
|
||||
|
||||
email_queue = make_email_queue(email_queue_list)
|
||||
customers = get_customers_list()
|
||||
|
||||
if isinstance(pos_profile, string_types):
|
||||
pos_profile = json.loads(pos_profile)
|
||||
|
||||
customers = get_customers_list(pos_profile)
|
||||
return {
|
||||
'invoice': name_list,
|
||||
'email_queue': email_queue,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-05-24 19:29:05",
|
||||
@@ -373,7 +372,8 @@
|
||||
"no_copy": 1,
|
||||
"options": "Sales Invoice",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_21",
|
||||
@@ -1568,8 +1568,7 @@
|
||||
"icon": "fa fa-file-text",
|
||||
"idx": 181,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2019-12-30 19:15:59.580414",
|
||||
"modified": "2020-02-10 04:57:11.221180",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
|
||||
@@ -413,6 +413,9 @@ class SalesInvoice(SellingController):
|
||||
if pos:
|
||||
self.allow_print_before_pay = pos.allow_print_before_pay
|
||||
|
||||
if not for_validate:
|
||||
self.tax_category = pos.get("tax_category")
|
||||
|
||||
if not for_validate and not self.customer:
|
||||
self.customer = pos.customer
|
||||
|
||||
@@ -426,13 +429,18 @@ class SalesInvoice(SellingController):
|
||||
if (not for_validate) or (for_validate and not self.get(fieldname)):
|
||||
self.set(fieldname, pos.get(fieldname))
|
||||
|
||||
customer_price_list = frappe.get_value("Customer", self.customer, 'default_price_list')
|
||||
|
||||
if pos.get("company_address"):
|
||||
self.company_address = pos.get("company_address")
|
||||
|
||||
if not customer_price_list:
|
||||
self.set('selling_price_list', pos.get('selling_price_list'))
|
||||
if self.customer:
|
||||
customer_price_list, customer_group = frappe.get_value("Customer", self.customer, ['default_price_list', 'customer_group'])
|
||||
customer_group_price_list = frappe.get_value("Customer Group", customer_group, 'default_price_list')
|
||||
selling_price_list = customer_price_list or customer_group_price_list or pos.get('selling_price_list')
|
||||
else:
|
||||
selling_price_list = pos.get('selling_price_list')
|
||||
|
||||
if selling_price_list:
|
||||
self.set('selling_price_list', selling_price_list)
|
||||
|
||||
if not for_validate:
|
||||
self.update_stock = cint(pos.get("update_stock"))
|
||||
@@ -463,13 +471,17 @@ class SalesInvoice(SellingController):
|
||||
["account_type", "report_type", "account_currency"], as_dict=True)
|
||||
|
||||
if not account:
|
||||
frappe.throw(_("Debit To is required"))
|
||||
frappe.throw(_("Debit To is required"), title=_("Account Missing"))
|
||||
|
||||
if account.report_type != "Balance Sheet":
|
||||
frappe.throw(_("Debit To account must be a Balance Sheet account"))
|
||||
frappe.throw(_("Please ensure {} account is a Balance Sheet account. \
|
||||
You can change the parent account to a Balance Sheet account or select a different account.")
|
||||
.format(frappe.bold("Debit To")), title=_("Invalid Account"))
|
||||
|
||||
if self.customer and account.account_type != "Receivable":
|
||||
frappe.throw(_("Debit To account must be a Receivable account"))
|
||||
frappe.throw(_("Please ensure {} account is a Receivable account. \
|
||||
Change the account type to Receivable or select a different account.")
|
||||
.format(frappe.bold("Debit To")), title=_("Invalid Account"))
|
||||
|
||||
self.party_account_currency = account.account_currency
|
||||
|
||||
@@ -531,14 +543,18 @@ class SalesInvoice(SellingController):
|
||||
"""check in manage account if sales order / delivery note required or not."""
|
||||
if self.is_return:
|
||||
return
|
||||
dic = {'Sales Order':['so_required', 'is_pos'],'Delivery Note':['dn_required', 'update_stock']}
|
||||
for i in dic:
|
||||
if frappe.db.get_single_value('Selling Settings', dic[i][0]) == 'Yes':
|
||||
|
||||
prev_doc_field_map = {'Sales Order': ['so_required', 'is_pos'],'Delivery Note': ['dn_required', 'update_stock']}
|
||||
for key, value in iteritems(prev_doc_field_map):
|
||||
if frappe.db.get_single_value('Selling Settings', value[0]) == 'Yes':
|
||||
|
||||
if frappe.get_value('Customer', self.customer, value[0]):
|
||||
continue
|
||||
|
||||
for d in self.get('items'):
|
||||
is_stock_item = frappe.get_cached_value('Item', d.item_code, 'is_stock_item')
|
||||
if (d.item_code and is_stock_item == 1\
|
||||
and not d.get(i.lower().replace(' ','_')) and not self.get(dic[i][1])):
|
||||
msgprint(_("{0} is mandatory for Item {1}").format(i,d.item_code), raise_exception=1)
|
||||
if (d.item_code and is_stock_item ==1 and not d.get(key.lower().replace(' ', '_')) and not self.get(value[1])):
|
||||
msgprint(_("{0} is mandatory for Item {1}").format(key, d.item_code), raise_exception=1)
|
||||
|
||||
|
||||
def validate_proj_cust(self):
|
||||
@@ -714,7 +730,7 @@ class SalesInvoice(SellingController):
|
||||
update_outstanding_amt(self.debit_to, "Customer", self.customer,
|
||||
self.doctype, self.return_against if cint(self.is_return) and self.return_against else self.name)
|
||||
|
||||
if repost_future_gle and cint(self.update_stock) \
|
||||
if (repost_future_gle or self.flags.repost_future_gle) and cint(self.update_stock) \
|
||||
and cint(auto_accounting_for_stock):
|
||||
items, warehouses = self.get_items_and_warehouses()
|
||||
update_gl_entries_after(self.posting_date, self.posting_time,
|
||||
@@ -1208,48 +1224,39 @@ class SalesInvoice(SellingController):
|
||||
|
||||
self.set_missing_values(for_validate = True)
|
||||
|
||||
def get_discounting_status(self):
|
||||
status = None
|
||||
if self.is_discounted:
|
||||
invoice_discounting_list = frappe.db.sql("""
|
||||
select status
|
||||
from `tabInvoice Discounting` id, `tabDiscounted Invoice` d
|
||||
where
|
||||
id.name = d.parent
|
||||
and d.sales_invoice=%s
|
||||
and id.docstatus=1
|
||||
and status in ('Disbursed', 'Settled')
|
||||
""", self.name)
|
||||
for d in invoice_discounting_list:
|
||||
status = d[0]
|
||||
if status == "Disbursed":
|
||||
break
|
||||
return status
|
||||
|
||||
def set_status(self, update=False, status=None, update_modified=True):
|
||||
if self.is_new():
|
||||
if self.get('amended_from'):
|
||||
self.status = 'Draft'
|
||||
return
|
||||
|
||||
precision = self.precision("outstanding_amount")
|
||||
outstanding_amount = flt(self.outstanding_amount, precision)
|
||||
due_date = getdate(self.due_date)
|
||||
nowdate = getdate()
|
||||
|
||||
discounting_status = None
|
||||
if self.is_discounted:
|
||||
discountng_status = get_discounting_status(self.name)
|
||||
|
||||
if not status:
|
||||
if self.docstatus == 2:
|
||||
status = "Cancelled"
|
||||
elif self.docstatus == 1:
|
||||
if flt(self.outstanding_amount) > 0 and getdate(self.due_date) < getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed':
|
||||
if outstanding_amount > 0 and due_date < nowdate and self.is_discounted and discountng_status=='Disbursed':
|
||||
self.status = "Overdue and Discounted"
|
||||
elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) < getdate(nowdate()):
|
||||
elif outstanding_amount > 0 and due_date < nowdate:
|
||||
self.status = "Overdue"
|
||||
elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed':
|
||||
elif outstanding_amount > 0 and due_date >= nowdate and self.is_discounted and discountng_status=='Disbursed':
|
||||
self.status = "Unpaid and Discounted"
|
||||
elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) >= getdate(nowdate()):
|
||||
elif outstanding_amount > 0 and due_date >= nowdate:
|
||||
self.status = "Unpaid"
|
||||
#Check if outstanding amount is 0 due to credit note issued against invoice
|
||||
elif flt(self.outstanding_amount) <= 0 and self.is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
|
||||
elif outstanding_amount <= 0 and self.is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
|
||||
self.status = "Credit Note Issued"
|
||||
elif self.is_return == 1:
|
||||
self.status = "Return"
|
||||
elif flt(self.outstanding_amount)<=0:
|
||||
elif outstanding_amount<=0:
|
||||
self.status = "Paid"
|
||||
else:
|
||||
self.status = "Submitted"
|
||||
@@ -1259,6 +1266,26 @@ class SalesInvoice(SellingController):
|
||||
if update:
|
||||
self.db_set('status', self.status, update_modified = update_modified)
|
||||
|
||||
def get_discounting_status(sales_invoice):
|
||||
status = None
|
||||
|
||||
invoice_discounting_list = frappe.db.sql("""
|
||||
select status
|
||||
from `tabInvoice Discounting` id, `tabDiscounted Invoice` d
|
||||
where
|
||||
id.name = d.parent
|
||||
and d.sales_invoice=%s
|
||||
and id.docstatus=1
|
||||
and status in ('Disbursed', 'Settled')
|
||||
""", sales_invoice)
|
||||
|
||||
for d in invoice_discounting_list:
|
||||
status = d[0]
|
||||
if status == "Disbursed":
|
||||
break
|
||||
|
||||
return status
|
||||
|
||||
def validate_inter_company_party(doctype, party, company, inter_company_reference):
|
||||
if not party:
|
||||
return
|
||||
@@ -1426,6 +1453,21 @@ def get_inter_company_details(doc, doctype):
|
||||
"company": company
|
||||
}
|
||||
|
||||
def get_internal_party(parties, link_doctype, doc):
|
||||
if len(parties) == 1:
|
||||
party = parties[0].name
|
||||
else:
|
||||
# If more than one Internal Supplier/Customer, get supplier/customer on basis of address
|
||||
if doc.get('company_address') or doc.get('shipping_address'):
|
||||
party = frappe.db.get_value("Dynamic Link", {"parent": doc.get('company_address') or doc.get('shipping_address'),
|
||||
"parenttype": "Address", "link_doctype": link_doctype}, "link_name")
|
||||
|
||||
if not party:
|
||||
party = parties[0].name
|
||||
else:
|
||||
party = parties[0].name
|
||||
|
||||
return party
|
||||
|
||||
def validate_inter_company_transaction(doc, doctype):
|
||||
|
||||
@@ -1514,6 +1556,9 @@ def get_loyalty_programs(customer):
|
||||
else:
|
||||
return lp_details
|
||||
|
||||
def on_doctype_update():
|
||||
frappe.db.add_index("Sales Invoice", ["customer", "is_return", "return_against"])
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_invoice_discounting(source_name, target_doc=None):
|
||||
invoice = frappe.get_doc("Sales Invoice", source_name)
|
||||
|
||||
@@ -728,7 +728,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
def test_make_pos_invoice(self):
|
||||
from erpnext.accounts.doctype.sales_invoice.pos import make_invoice
|
||||
|
||||
make_pos_profile()
|
||||
pos_profile = make_pos_profile()
|
||||
pr = make_purchase_receipt(company= "_Test Company with perpetual inventory",supplier_warehouse= "Work In Progress - TCP1", item_code= "_Test FG Item",warehouse= "Stores - TCP1",cost_center= "Main - TCP1")
|
||||
pos = create_sales_invoice(company= "_Test Company with perpetual inventory", debit_to="Debtors - TCP1", item_code= "_Test FG Item", warehouse="Stores - TCP1", income_account = "Sales - TCP1", expense_account = "Cost of Goods Sold - TCP1", cost_center = "Main - TCP1", do_not_save=True)
|
||||
|
||||
@@ -744,7 +744,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
pos.append("taxes", tax)
|
||||
|
||||
invoice_data = [{'09052016142': pos}]
|
||||
si = make_invoice(invoice_data).get('invoice')
|
||||
si = make_invoice(pos_profile, invoice_data).get('invoice')
|
||||
self.assertEqual(si[0], '09052016142')
|
||||
|
||||
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': '09052016142', 'docstatus': 1})
|
||||
@@ -762,7 +762,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
if allow_negative_stock:
|
||||
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 0)
|
||||
|
||||
make_pos_profile()
|
||||
pos_profile = make_pos_profile()
|
||||
timestamp = cint(time.time())
|
||||
|
||||
item = make_item("_Test POS Item")
|
||||
@@ -776,7 +776,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
{'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 330}]
|
||||
|
||||
invoice_data = [{timestamp: pos}]
|
||||
si = make_invoice(invoice_data).get('invoice')
|
||||
si = make_invoice(pos_profile, invoice_data).get('invoice')
|
||||
self.assertEqual(si[0], timestamp)
|
||||
|
||||
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
|
||||
@@ -785,7 +785,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
timestamp = cint(time.time())
|
||||
pos["offline_pos_name"] = timestamp
|
||||
invoice_data = [{timestamp: pos}]
|
||||
si1 = make_invoice(invoice_data).get('invoice')
|
||||
si1 = make_invoice(pos_profile, invoice_data).get('invoice')
|
||||
self.assertEqual(si1[0], timestamp)
|
||||
|
||||
sales_invoice1 = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
|
||||
@@ -1890,7 +1890,7 @@ def create_sales_invoice(**args):
|
||||
"gst_hsn_code": "999800",
|
||||
"warehouse": args.warehouse or "_Test Warehouse - _TC",
|
||||
"qty": args.qty or 1,
|
||||
"rate": args.rate or 100,
|
||||
"rate": args.rate if args.get("rate") is not None else 100,
|
||||
"income_account": args.income_account or "Sales - _TC",
|
||||
"expense_account": args.expense_account or "Cost of Goods Sold - _TC",
|
||||
"cost_center": args.cost_center or "_Test Cost Center - _TC",
|
||||
|
||||
@@ -82,7 +82,7 @@ class ShippingRule(Document):
|
||||
if not shipping_country:
|
||||
frappe.throw(_('Shipping Address does not have country, which is required for this Shipping Rule'))
|
||||
if shipping_country not in [d.country for d in self.countries]:
|
||||
frappe.throw(_('Shipping rule not applicable for country {0}'.format(shipping_country)))
|
||||
frappe.throw(_('Shipping rule not applicable for country {0} in Shipping Address').format(shipping_country))
|
||||
|
||||
def add_shipping_rule_to_tax_table(self, doc, shipping_amount):
|
||||
shipping_charge = {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "ACC-SUB-.YYYY.-.#####",
|
||||
"creation": "2017-07-18 17:50:43.967266",
|
||||
"doctype": "DocType",
|
||||
@@ -155,7 +156,7 @@
|
||||
"fieldname": "apply_additional_discount",
|
||||
"fieldtype": "Select",
|
||||
"label": "Apply Additional Discount On",
|
||||
"options": "\nGrand Total\nNet total"
|
||||
"options": "\nGrand Total\nNet Total"
|
||||
},
|
||||
{
|
||||
"fieldname": "cb_2",
|
||||
@@ -196,7 +197,8 @@
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"modified": "2019-07-25 18:45:38.579579",
|
||||
"links": [],
|
||||
"modified": "2020-01-27 14:37:32.845173",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Subscription",
|
||||
|
||||
@@ -280,7 +280,7 @@ class Subscription(Document):
|
||||
|
||||
if self.additional_discount_percentage or self.additional_discount_amount:
|
||||
discount_on = self.apply_additional_discount
|
||||
invoice.apply_additional_discount = discount_on if discount_on else 'Grand Total'
|
||||
invoice.apply_discount_on = discount_on if discount_on else 'Grand Total'
|
||||
|
||||
# Subscription period
|
||||
invoice.from_date = self.current_invoice_start
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2020-01-15 17:14:28.951793",
|
||||
"modified": "2020-01-15 17:14:28.951793",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Tax Category",
|
||||
|
||||
@@ -136,12 +136,14 @@ def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
|
||||
|
||||
|
||||
def make_entry(args, adv_adj, update_outstanding, from_repost=False):
|
||||
args.update({"doctype": "GL Entry"})
|
||||
gle = frappe.get_doc(args)
|
||||
gle = frappe.new_doc("GL Entry")
|
||||
gle.update(args)
|
||||
gle.flags.ignore_permissions = 1
|
||||
gle.flags.from_repost = from_repost
|
||||
gle.insert()
|
||||
gle.validate()
|
||||
gle.db_insert()
|
||||
gle.run_method("on_update_with_args", adv_adj, update_outstanding, from_repost)
|
||||
gle.flags.ignore_validate = True
|
||||
gle.submit()
|
||||
|
||||
def validate_account_for_perpetual_inventory(gl_map):
|
||||
|
||||
@@ -1769,6 +1769,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
|
||||
freeze: true,
|
||||
args: {
|
||||
pos_profile: me.pos_profile_data,
|
||||
doc_list: me.si_docs,
|
||||
email_queue_list: me.email_queue_list,
|
||||
customers_list: me.customers_list
|
||||
|
||||
@@ -163,8 +163,9 @@ def get_default_price_list(party):
|
||||
def set_price_list(party_details, party, party_type, given_price_list, pos=None):
|
||||
# price list
|
||||
price_list = get_permitted_documents('Price List')
|
||||
|
||||
if price_list:
|
||||
|
||||
# if there is only one permitted document based on user permissions, set it
|
||||
if price_list and len(price_list) == 1:
|
||||
price_list = price_list[0]
|
||||
elif pos and party_type == 'Customer':
|
||||
customer_price_list = frappe.get_value('Customer', party.name, 'default_price_list')
|
||||
|
||||
@@ -100,6 +100,11 @@ frappe.query_reports["Accounts Payable"] = {
|
||||
"fieldtype": "Link",
|
||||
"options": "Supplier Group"
|
||||
},
|
||||
{
|
||||
"fieldname": "group_by_party",
|
||||
"label": __("Group By Supplier"),
|
||||
"fieldtype": "Check"
|
||||
},
|
||||
{
|
||||
"fieldname":"based_on_payment_terms",
|
||||
"label": __("Based On Payment Terms"),
|
||||
@@ -112,6 +117,16 @@ frappe.query_reports["Accounts Payable"] = {
|
||||
"hidden": 1
|
||||
}
|
||||
],
|
||||
|
||||
"formatter": function(value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
if (data && data.bold) {
|
||||
value = value.bold();
|
||||
|
||||
}
|
||||
return value;
|
||||
},
|
||||
|
||||
onload: function(report) {
|
||||
report.page.add_inner_button(__("Accounts Payable Summary"), function() {
|
||||
var filters = report.get_values();
|
||||
|
||||
@@ -218,15 +218,15 @@
|
||||
<td></td>
|
||||
<td style="text-align: right"><b>{%= __("Total") %}</b></td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["invoiced"], data[i]["currency"] ) %}</td>
|
||||
{%= format_currency(data[i]["invoiced"], data[0]["currency"] ) %}</td>
|
||||
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} </td>
|
||||
{%= format_currency(data[i]["paid"], data[0]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[0]["currency"]) %} </td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["outstanding"], data[0]["currency"]) %}</td>
|
||||
|
||||
{% if(filters.show_future_payments) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
@@ -234,8 +234,8 @@
|
||||
{%= data[i]["po_no"] %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= data[i]["future_ref"] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["future_amount"], data[0]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["remaining_balance"], data[0]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
@@ -256,10 +256,10 @@
|
||||
{% } else { %}
|
||||
<td><b>{%= __("Total") %}</b></td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= format_currency(data[i]["invoiced"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["invoiced"], data[0]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["paid"], data[0]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[0]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["outstanding"], data[0]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } %}
|
||||
</tr>
|
||||
|
||||
@@ -87,7 +87,7 @@ frappe.query_reports["Accounts Receivable"] = {
|
||||
frappe.query_report.set_filter_value('payment_terms', value["payment_terms"]);
|
||||
});
|
||||
|
||||
frappe.db.get_value('Customer Credit Limit', {'parent': customer, 'company': company},
|
||||
frappe.db.get_value('Customer Credit Limit', {'parent': customer, 'company': company},
|
||||
["credit_limit"], function(value) {
|
||||
if (value) {
|
||||
frappe.query_report.set_filter_value('credit_limit', value["credit_limit"]);
|
||||
@@ -131,6 +131,11 @@ frappe.query_reports["Accounts Receivable"] = {
|
||||
"fieldtype": "Link",
|
||||
"options": "Sales Person"
|
||||
},
|
||||
{
|
||||
"fieldname": "group_by_party",
|
||||
"label": __("Group By Customer"),
|
||||
"fieldtype": "Check"
|
||||
},
|
||||
{
|
||||
"fieldname":"based_on_payment_terms",
|
||||
"label": __("Based On Payment Terms"),
|
||||
@@ -177,6 +182,15 @@ frappe.query_reports["Accounts Receivable"] = {
|
||||
}
|
||||
],
|
||||
|
||||
"formatter": function(value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
if (data && data.bold) {
|
||||
value = value.bold();
|
||||
|
||||
}
|
||||
return value;
|
||||
},
|
||||
|
||||
onload: function(report) {
|
||||
report.page.add_inner_button(__("Accounts Receivable Summary"), function() {
|
||||
var filters = report.get_values();
|
||||
|
||||
@@ -7,7 +7,7 @@ from frappe import _, scrub
|
||||
from frappe.utils import getdate, nowdate, flt, cint, formatdate, cstr, now, time_diff_in_seconds
|
||||
from collections import OrderedDict
|
||||
from erpnext.accounts.utils import get_currency_precision
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
|
||||
|
||||
# This report gives a summary of all Outstanding Invoices considering the following
|
||||
|
||||
@@ -46,7 +46,7 @@ class ReceivablePayableReport(object):
|
||||
self.get_columns()
|
||||
self.get_data()
|
||||
self.get_chart_data()
|
||||
return self.columns, self.data, None, self.chart
|
||||
return self.columns, self.data, None, self.chart, None, self.skip_total_row
|
||||
|
||||
def set_defaults(self):
|
||||
if not self.filters.get("company"):
|
||||
@@ -57,6 +57,12 @@ class ReceivablePayableReport(object):
|
||||
self.party_type = self.filters.party_type
|
||||
self.party_details = {}
|
||||
self.invoices = set()
|
||||
self.skip_total_row = 0
|
||||
|
||||
if self.filters.get('group_by_party'):
|
||||
self.previous_party=''
|
||||
self.total_row_map = {}
|
||||
self.skip_total_row = 1
|
||||
|
||||
def get_data(self):
|
||||
self.get_gl_entries()
|
||||
@@ -102,6 +108,12 @@ class ReceivablePayableReport(object):
|
||||
)
|
||||
self.get_invoices(gle)
|
||||
|
||||
if self.filters.get('group_by_party'):
|
||||
self.init_subtotal_row(gle.party)
|
||||
|
||||
if self.filters.get('group_by_party'):
|
||||
self.init_subtotal_row('Total')
|
||||
|
||||
def get_invoices(self, gle):
|
||||
if gle.voucher_type in ('Sales Invoice', 'Purchase Invoice'):
|
||||
if self.filters.get("sales_person"):
|
||||
@@ -111,6 +123,20 @@ class ReceivablePayableReport(object):
|
||||
else:
|
||||
self.invoices.add(gle.voucher_no)
|
||||
|
||||
def init_subtotal_row(self, party):
|
||||
if not self.total_row_map.get(party):
|
||||
self.total_row_map.setdefault(party, {
|
||||
'party': party,
|
||||
'bold': 1
|
||||
})
|
||||
|
||||
for field in self.get_currency_fields():
|
||||
self.total_row_map[party][field] = 0.0
|
||||
|
||||
def get_currency_fields(self):
|
||||
return ['invoiced', 'paid', 'credit_note', 'outstanding', 'range1',
|
||||
'range2', 'range3', 'range4', 'range5']
|
||||
|
||||
def update_voucher_balance(self, gle):
|
||||
# get the row where this balance needs to be updated
|
||||
# if its a payment, it will return the linked invoice or will be considered as advance
|
||||
@@ -135,6 +161,18 @@ class ReceivablePayableReport(object):
|
||||
# advance / unlinked payment or other adjustment
|
||||
row.paid -= gle_balance
|
||||
|
||||
def update_sub_total_row(self, row, party):
|
||||
total_row = self.total_row_map.get(party)
|
||||
|
||||
for field in self.get_currency_fields():
|
||||
total_row[field] += row.get(field, 0.0)
|
||||
|
||||
def append_subtotal_row(self, party):
|
||||
sub_total_row = self.total_row_map.get(party)
|
||||
self.data.append(sub_total_row)
|
||||
self.data.append({})
|
||||
self.update_sub_total_row(sub_total_row, 'Total')
|
||||
|
||||
def get_voucher_balance(self, gle):
|
||||
if self.filters.get("sales_person"):
|
||||
against_voucher = gle.against_voucher or gle.voucher_no
|
||||
@@ -192,11 +230,22 @@ class ReceivablePayableReport(object):
|
||||
else:
|
||||
self.append_row(row)
|
||||
|
||||
if self.filters.get('group_by_party'):
|
||||
self.append_subtotal_row(self.previous_party)
|
||||
self.data.append(self.total_row_map.get('Total'))
|
||||
|
||||
def append_row(self, row):
|
||||
self.allocate_future_payments(row)
|
||||
self.set_invoice_details(row)
|
||||
self.set_party_details(row)
|
||||
self.set_ageing(row)
|
||||
|
||||
if self.filters.get('group_by_party'):
|
||||
self.update_sub_total_row(row, row.party)
|
||||
if self.previous_party and (self.previous_party != row.party):
|
||||
self.append_subtotal_row(self.previous_party)
|
||||
self.previous_party = row.party
|
||||
|
||||
self.data.append(row)
|
||||
|
||||
def set_invoice_details(self, row):
|
||||
@@ -503,6 +552,7 @@ class ReceivablePayableReport(object):
|
||||
# get all the GL entries filtered by the given filters
|
||||
|
||||
conditions, values = self.prepare_conditions()
|
||||
order_by = self.get_order_by_condition()
|
||||
|
||||
if self.filters.get(scrub(self.party_type)):
|
||||
select_fields = "debit_in_account_currency as debit, credit_in_account_currency as credit"
|
||||
@@ -520,9 +570,8 @@ class ReceivablePayableReport(object):
|
||||
and party_type=%s
|
||||
and (party is not null and party != '')
|
||||
and posting_date <= %s
|
||||
{1}
|
||||
order by posting_date, party"""
|
||||
.format(select_fields, conditions), values, as_dict=True)
|
||||
{1} {2}"""
|
||||
.format(select_fields, conditions, order_by), values, as_dict=True)
|
||||
|
||||
def get_sales_invoices_or_customers_based_on_sales_person(self):
|
||||
if self.filters.get("sales_person"):
|
||||
@@ -554,9 +603,14 @@ class ReceivablePayableReport(object):
|
||||
self.add_supplier_filters(conditions, values)
|
||||
|
||||
self.add_accounting_dimensions_filters(conditions, values)
|
||||
|
||||
return " and ".join(conditions), values
|
||||
|
||||
def get_order_by_condition(self):
|
||||
if self.filters.get('group_by_party'):
|
||||
return "order by party, posting_date"
|
||||
else:
|
||||
return "order by posting_date, party"
|
||||
|
||||
def add_common_filters(self, conditions, values, party_type_field):
|
||||
if self.filters.company:
|
||||
conditions.append("company=%s")
|
||||
@@ -611,13 +665,16 @@ class ReceivablePayableReport(object):
|
||||
doctype=doctype, lft=lft, rgt=rgt, key=key)
|
||||
|
||||
def add_accounting_dimensions_filters(self, conditions, values):
|
||||
accounting_dimensions = get_accounting_dimensions()
|
||||
accounting_dimensions = get_accounting_dimensions(as_list=False)
|
||||
|
||||
if accounting_dimensions:
|
||||
for dimension in accounting_dimensions:
|
||||
if self.filters.get(dimension):
|
||||
conditions.append("{0} = %s".format(dimension))
|
||||
values.append(self.filters.get(dimension))
|
||||
if self.filters.get(dimension.fieldname):
|
||||
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
||||
self.filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
||||
self.filters.get(dimension.fieldname))
|
||||
conditions.append("{0} in %s".format(dimension.fieldname))
|
||||
values.append(tuple(self.filters.get(dimension.fieldname)))
|
||||
|
||||
def get_gle_balance(self, gle):
|
||||
# get the balance of the GL (debit - credit) or reverse balance based on report type
|
||||
@@ -736,11 +793,13 @@ class ReceivablePayableReport(object):
|
||||
def get_chart_data(self):
|
||||
rows = []
|
||||
for row in self.data:
|
||||
values = [row.range1, row.range2, row.range3, row.range4, row.range5]
|
||||
precision = cint(frappe.db.get_default("float_precision")) or 2
|
||||
rows.append({
|
||||
'values': [flt(val, precision) for val in values]
|
||||
})
|
||||
row = frappe._dict(row)
|
||||
if not cint(row.bold):
|
||||
values = [row.range1, row.range2, row.range3, row.range4, row.range5]
|
||||
precision = cint(frappe.db.get_default("float_precision")) or 2
|
||||
rows.append({
|
||||
'values': [flt(val, precision) for val in values]
|
||||
})
|
||||
|
||||
self.chart = {
|
||||
"data": {
|
||||
|
||||
@@ -4,126 +4,137 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import formatdate, getdate, flt, add_days
|
||||
from frappe.utils import formatdate, flt, add_days
|
||||
|
||||
|
||||
def execute(filters=None):
|
||||
filters.day_before_from_date = add_days(filters.from_date, -1)
|
||||
columns, data = get_columns(filters), get_data(filters)
|
||||
return columns, data
|
||||
|
||||
|
||||
|
||||
def get_data(filters):
|
||||
data = []
|
||||
|
||||
|
||||
asset_categories = get_asset_categories(filters)
|
||||
assets = get_assets(filters)
|
||||
asset_costs = get_asset_costs(assets, filters)
|
||||
asset_depreciations = get_accumulated_depreciations(assets, filters)
|
||||
|
||||
|
||||
for asset_category in asset_categories:
|
||||
row = frappe._dict()
|
||||
row.asset_category = asset_category
|
||||
row.update(asset_costs.get(asset_category))
|
||||
# row.asset_category = asset_category
|
||||
row.update(asset_category)
|
||||
|
||||
row.cost_as_on_to_date = (flt(row.cost_as_on_from_date) + flt(row.cost_of_new_purchase) -
|
||||
flt(row.cost_of_sold_asset) - flt(row.cost_of_scrapped_asset))
|
||||
|
||||
row.update(next(asset for asset in assets if asset["asset_category"] == asset_category.get("asset_category", "")))
|
||||
row.accumulated_depreciation_as_on_to_date = (flt(row.accumulated_depreciation_as_on_from_date) +
|
||||
flt(row.depreciation_amount_during_the_period) - flt(row.depreciation_eliminated_during_the_period))
|
||||
|
||||
row.net_asset_value_as_on_from_date = (flt(row.cost_as_on_from_date) -
|
||||
flt(row.accumulated_depreciation_as_on_from_date))
|
||||
|
||||
row.net_asset_value_as_on_to_date = (flt(row.cost_as_on_to_date) -
|
||||
flt(row.accumulated_depreciation_as_on_to_date))
|
||||
|
||||
row.cost_as_on_to_date = (flt(row.cost_as_on_from_date) + flt(row.cost_of_new_purchase)
|
||||
- flt(row.cost_of_sold_asset) - flt(row.cost_of_scrapped_asset))
|
||||
|
||||
row.update(asset_depreciations.get(asset_category))
|
||||
row.accumulated_depreciation_as_on_to_date = (flt(row.accumulated_depreciation_as_on_from_date) +
|
||||
flt(row.depreciation_amount_during_the_period) - flt(row.depreciation_eliminated))
|
||||
|
||||
row.net_asset_value_as_on_from_date = (flt(row.cost_as_on_from_date) -
|
||||
flt(row.accumulated_depreciation_as_on_from_date))
|
||||
|
||||
row.net_asset_value_as_on_to_date = (flt(row.cost_as_on_to_date) -
|
||||
flt(row.accumulated_depreciation_as_on_to_date))
|
||||
|
||||
data.append(row)
|
||||
|
||||
|
||||
return data
|
||||
|
||||
|
||||
|
||||
def get_asset_categories(filters):
|
||||
return frappe.db.sql_list("""
|
||||
select distinct asset_category from `tabAsset`
|
||||
where docstatus=1 and company=%s and purchase_date <= %s
|
||||
""", (filters.company, filters.to_date))
|
||||
|
||||
return frappe.db.sql("""
|
||||
SELECT asset_category,
|
||||
ifnull(sum(case when purchase_date < %(from_date)s then
|
||||
case when ifnull(disposal_date, 0) = 0 or disposal_date >= %(from_date)s then
|
||||
gross_purchase_amount
|
||||
else
|
||||
0
|
||||
end
|
||||
else
|
||||
0
|
||||
end), 0) as cost_as_on_from_date,
|
||||
ifnull(sum(case when purchase_date >= %(from_date)s then
|
||||
gross_purchase_amount
|
||||
else
|
||||
0
|
||||
end), 0) as cost_of_new_purchase,
|
||||
ifnull(sum(case when ifnull(disposal_date, 0) != 0
|
||||
and disposal_date >= %(from_date)s
|
||||
and disposal_date <= %(to_date)s then
|
||||
case when status = "Sold" then
|
||||
gross_purchase_amount
|
||||
else
|
||||
0
|
||||
end
|
||||
else
|
||||
0
|
||||
end), 0) as cost_of_sold_asset,
|
||||
ifnull(sum(case when ifnull(disposal_date, 0) != 0
|
||||
and disposal_date >= %(from_date)s
|
||||
and disposal_date <= %(to_date)s then
|
||||
case when status = "Scrapped" then
|
||||
gross_purchase_amount
|
||||
else
|
||||
0
|
||||
end
|
||||
else
|
||||
0
|
||||
end), 0) as cost_of_scrapped_asset
|
||||
from `tabAsset`
|
||||
where docstatus=1 and company=%(company)s and purchase_date <= %(to_date)s
|
||||
group by asset_category
|
||||
""", {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1)
|
||||
|
||||
def get_assets(filters):
|
||||
return frappe.db.sql("""
|
||||
select name, asset_category, purchase_date, gross_purchase_amount, disposal_date, status
|
||||
from `tabAsset`
|
||||
where docstatus=1 and company=%s and purchase_date <= %s""",
|
||||
(filters.company, filters.to_date), as_dict=1)
|
||||
|
||||
def get_asset_costs(assets, filters):
|
||||
asset_costs = frappe._dict()
|
||||
for d in assets:
|
||||
asset_costs.setdefault(d.asset_category, frappe._dict({
|
||||
"cost_as_on_from_date": 0,
|
||||
"cost_of_new_purchase": 0,
|
||||
"cost_of_sold_asset": 0,
|
||||
"cost_of_scrapped_asset": 0
|
||||
}))
|
||||
|
||||
costs = asset_costs[d.asset_category]
|
||||
|
||||
if getdate(d.purchase_date) < getdate(filters.from_date):
|
||||
if not d.disposal_date or getdate(d.disposal_date) >= getdate(filters.from_date):
|
||||
costs.cost_as_on_from_date += flt(d.gross_purchase_amount)
|
||||
else:
|
||||
costs.cost_of_new_purchase += flt(d.gross_purchase_amount)
|
||||
|
||||
if d.disposal_date and getdate(d.disposal_date) >= getdate(filters.from_date) \
|
||||
and getdate(d.disposal_date) <= getdate(filters.to_date):
|
||||
if d.status == "Sold":
|
||||
costs.cost_of_sold_asset += flt(d.gross_purchase_amount)
|
||||
elif d.status == "Scrapped":
|
||||
costs.cost_of_scrapped_asset += flt(d.gross_purchase_amount)
|
||||
|
||||
return asset_costs
|
||||
|
||||
def get_accumulated_depreciations(assets, filters):
|
||||
asset_depreciations = frappe._dict()
|
||||
for d in assets:
|
||||
asset = frappe.get_doc("Asset", d.name)
|
||||
|
||||
if d.asset_category in asset_depreciations:
|
||||
asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] += asset.opening_accumulated_depreciation
|
||||
else:
|
||||
asset_depreciations.setdefault(d.asset_category, frappe._dict({
|
||||
"accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
|
||||
"depreciation_amount_during_the_period": 0,
|
||||
"depreciation_eliminated_during_the_period": 0
|
||||
}))
|
||||
SELECT results.asset_category,
|
||||
sum(results.accumulated_depreciation_as_on_from_date) as accumulated_depreciation_as_on_from_date,
|
||||
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
|
||||
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
|
||||
from (SELECT a.asset_category,
|
||||
ifnull(sum(case when ds.schedule_date < %(from_date)s then
|
||||
ds.depreciation_amount
|
||||
else
|
||||
0
|
||||
end), 0) as accumulated_depreciation_as_on_from_date,
|
||||
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s
|
||||
and a.disposal_date <= %(to_date)s and ds.schedule_date <= a.disposal_date then
|
||||
ds.depreciation_amount
|
||||
else
|
||||
0
|
||||
end), 0) as depreciation_eliminated_during_the_period,
|
||||
ifnull(sum(case when ds.schedule_date >= %(from_date)s and ds.schedule_date <= %(to_date)s
|
||||
and (ifnull(a.disposal_date, 0) = 0 or ds.schedule_date <= a.disposal_date) then
|
||||
ds.depreciation_amount
|
||||
else
|
||||
0
|
||||
end), 0) as depreciation_amount_during_the_period
|
||||
from `tabAsset` a, `tabDepreciation Schedule` ds
|
||||
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and a.name = ds.parent
|
||||
group by a.asset_category
|
||||
union
|
||||
SELECT a.asset_category,
|
||||
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
|
||||
and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s)
|
||||
then
|
||||
0
|
||||
else
|
||||
a.opening_accumulated_depreciation
|
||||
end), 0) as accumulated_depreciation_as_on_from_date,
|
||||
ifnull(sum(case when a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then
|
||||
a.opening_accumulated_depreciation
|
||||
else
|
||||
0
|
||||
end), 0) as depreciation_eliminated_during_the_period,
|
||||
0 as depreciation_amount_during_the_period
|
||||
from `tabAsset` a
|
||||
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s
|
||||
group by a.asset_category) as results
|
||||
group by results.asset_category
|
||||
""", {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1)
|
||||
|
||||
depr = asset_depreciations[d.asset_category]
|
||||
|
||||
if not asset.schedules: # if no schedule,
|
||||
if asset.disposal_date:
|
||||
# and disposal is NOT within the period, then opening accumulated depreciation not included
|
||||
if getdate(asset.disposal_date) < getdate(filters.from_date) or getdate(asset.disposal_date) > getdate(filters.to_date):
|
||||
asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] = 0
|
||||
|
||||
# if no schedule, and disposal is within period, accumulated dep is the amount eliminated
|
||||
if getdate(asset.disposal_date) >= getdate(filters.from_date) and getdate(asset.disposal_date) <= getdate(filters.to_date):
|
||||
depr.depreciation_eliminated_during_the_period += asset.opening_accumulated_depreciation
|
||||
|
||||
for schedule in asset.get("schedules"):
|
||||
if getdate(schedule.schedule_date) < getdate(filters.from_date):
|
||||
if not asset.disposal_date or getdate(asset.disposal_date) >= getdate(filters.from_date):
|
||||
depr.accumulated_depreciation_as_on_from_date += flt(schedule.depreciation_amount)
|
||||
elif getdate(schedule.schedule_date) <= getdate(filters.to_date):
|
||||
if not asset.disposal_date:
|
||||
depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)
|
||||
else:
|
||||
if getdate(schedule.schedule_date) <= getdate(asset.disposal_date):
|
||||
depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)
|
||||
|
||||
if asset.disposal_date and getdate(asset.disposal_date) >= getdate(filters.from_date) and getdate(asset.disposal_date) <= getdate(filters.to_date):
|
||||
if getdate(schedule.schedule_date) <= getdate(asset.disposal_date):
|
||||
depr.depreciation_eliminated_during_the_period += flt(schedule.depreciation_amount)
|
||||
|
||||
return asset_depreciations
|
||||
|
||||
def get_columns(filters):
|
||||
return [
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
||||
frappe.query_reports["Balance Sheet"]["filters"].push({
|
||||
"fieldname": "include_default_book_entries",
|
||||
"label": __("Include Default Book Entries"),
|
||||
"fieldtype": "Check"
|
||||
"fieldtype": "Check",
|
||||
"default": 1
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,7 +20,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
||||
{
|
||||
"fieldname": "include_default_book_entries",
|
||||
"label": __("Include Default Book Entries"),
|
||||
"fieldtype": "Check"
|
||||
"fieldtype": "Check",
|
||||
"default": 1
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -4,7 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import cint
|
||||
from frappe.utils import cint, cstr
|
||||
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
|
||||
from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import get_net_profit_loss
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
@@ -129,13 +129,13 @@ def get_account_type_based_gl_data(company, start_date, end_date, account_type,
|
||||
cond = ""
|
||||
filters = frappe._dict(filters)
|
||||
|
||||
if filters.finance_book:
|
||||
cond = " and finance_book = %s" %(frappe.db.escape(filters.finance_book))
|
||||
if filters.include_default_book_entries:
|
||||
company_fb = frappe.db.get_value("Company", company, 'default_finance_book')
|
||||
if filters.include_default_book_entries:
|
||||
company_fb = frappe.db.get_value("Company", company, 'default_finance_book')
|
||||
cond = """ AND (finance_book in (%s, %s, '') OR finance_book IS NULL)
|
||||
""" %(frappe.db.escape(filters.finance_book), frappe.db.escape(company_fb))
|
||||
else:
|
||||
cond = " AND (finance_book in (%s, '') OR finance_book IS NULL)" %(frappe.db.escape(cstr(filters.finance_book)))
|
||||
|
||||
cond = """ and finance_book in (%s, %s)
|
||||
""" %(frappe.db.escape(filters.finance_book), frappe.db.escape(company_fb))
|
||||
|
||||
gl_sum = frappe.db.sql_list("""
|
||||
select sum(credit) - sum(debit)
|
||||
|
||||
@@ -58,7 +58,8 @@ frappe.query_reports["Consolidated Financial Statement"] = {
|
||||
{
|
||||
"fieldname": "include_default_book_entries",
|
||||
"label": __("Include Default Book Entries"),
|
||||
"fieldtype": "Check"
|
||||
"fieldtype": "Check",
|
||||
"default": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -387,11 +387,10 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
|
||||
if from_date:
|
||||
additional_conditions.append("gl.posting_date >= %(from_date)s")
|
||||
|
||||
if filters.get("finance_book"):
|
||||
if filters.get("include_default_book_entries"):
|
||||
additional_conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
|
||||
else:
|
||||
additional_conditions.append("finance_book in (%(finance_book)s)")
|
||||
if filters.get("include_default_book_entries"):
|
||||
additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)")
|
||||
else:
|
||||
additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)")
|
||||
|
||||
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
|
||||
|
||||
|
||||
@@ -13,10 +13,10 @@ import frappe, erpnext
|
||||
from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
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, add_months, add_days, formatdate, cstr)
|
||||
|
||||
from six import itervalues
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
|
||||
|
||||
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
|
||||
company=None, reset_period_on_fy_change=True):
|
||||
@@ -348,46 +348,48 @@ def set_gl_entries_by_account(
|
||||
additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters)
|
||||
|
||||
accounts = frappe.db.sql_list("""select name from `tabAccount`
|
||||
where lft >= %s and rgt <= %s""", (root_lft, root_rgt))
|
||||
additional_conditions += " and account in ({})"\
|
||||
.format(", ".join([frappe.db.escape(d) for d in accounts]))
|
||||
where lft >= %s and rgt <= %s and company = %s""", (root_lft, root_rgt, company))
|
||||
|
||||
gl_filters = {
|
||||
"company": company,
|
||||
"from_date": from_date,
|
||||
"to_date": to_date,
|
||||
"finance_book": filters.get("finance_book")
|
||||
}
|
||||
if accounts:
|
||||
additional_conditions += " and account in ({})"\
|
||||
.format(", ".join([frappe.db.escape(d) for d in accounts]))
|
||||
|
||||
if filters.get("include_default_book_entries"):
|
||||
gl_filters["company_fb"] = frappe.db.get_value("Company",
|
||||
company, 'default_finance_book')
|
||||
gl_filters = {
|
||||
"company": company,
|
||||
"from_date": from_date,
|
||||
"to_date": to_date,
|
||||
"finance_book": cstr(filters.get("finance_book"))
|
||||
}
|
||||
|
||||
for key, value in filters.items():
|
||||
if value:
|
||||
gl_filters.update({
|
||||
key: value
|
||||
})
|
||||
if filters.get("include_default_book_entries"):
|
||||
gl_filters["company_fb"] = frappe.db.get_value("Company",
|
||||
company, 'default_finance_book')
|
||||
|
||||
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year, debit_in_account_currency, credit_in_account_currency, account_currency from `tabGL Entry`
|
||||
where company=%(company)s
|
||||
{additional_conditions}
|
||||
and posting_date <= %(to_date)s
|
||||
order by account, posting_date""".format(additional_conditions=additional_conditions), gl_filters, as_dict=True) #nosec
|
||||
for key, value in filters.items():
|
||||
if value:
|
||||
gl_filters.update({
|
||||
key: value
|
||||
})
|
||||
|
||||
if filters and filters.get('presentation_currency'):
|
||||
convert_to_presentation_currency(gl_entries, get_currency(filters))
|
||||
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year, debit_in_account_currency, credit_in_account_currency, account_currency from `tabGL Entry`
|
||||
where company=%(company)s
|
||||
{additional_conditions}
|
||||
and posting_date <= %(to_date)s
|
||||
order by account, posting_date""".format(additional_conditions=additional_conditions), gl_filters, as_dict=True) #nosec
|
||||
|
||||
for entry in gl_entries:
|
||||
gl_entries_by_account.setdefault(entry.account, []).append(entry)
|
||||
if filters and filters.get('presentation_currency'):
|
||||
convert_to_presentation_currency(gl_entries, get_currency(filters))
|
||||
|
||||
return gl_entries_by_account
|
||||
for entry in gl_entries:
|
||||
gl_entries_by_account.setdefault(entry.account, []).append(entry)
|
||||
|
||||
return gl_entries_by_account
|
||||
|
||||
|
||||
def get_additional_conditions(from_date, ignore_closing_entries, filters):
|
||||
additional_conditions = []
|
||||
|
||||
accounting_dimensions = get_accounting_dimensions()
|
||||
accounting_dimensions = get_accounting_dimensions(as_list=False)
|
||||
|
||||
if ignore_closing_entries:
|
||||
additional_conditions.append("ifnull(voucher_type, '')!='Period Closing Voucher'")
|
||||
@@ -406,16 +408,20 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
|
||||
filters.cost_center = get_cost_centers_with_children(filters.cost_center)
|
||||
additional_conditions.append("cost_center in %(cost_center)s")
|
||||
|
||||
if filters.get("finance_book"):
|
||||
if filters.get("include_default_book_entries"):
|
||||
additional_conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
|
||||
else:
|
||||
additional_conditions.append("finance_book in (%(finance_book)s)")
|
||||
if filters.get("include_default_book_entries"):
|
||||
additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)")
|
||||
else:
|
||||
additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)")
|
||||
|
||||
if accounting_dimensions:
|
||||
for dimension in accounting_dimensions:
|
||||
if filters.get(dimension):
|
||||
additional_conditions.append("{0} in (%({0})s)".format(dimension))
|
||||
if filters.get(dimension.fieldname):
|
||||
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
||||
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
||||
filters.get(dimension.fieldname))
|
||||
additional_conditions.append("{0} in %({0})s".format(dimension.fieldname))
|
||||
else:
|
||||
additional_conditions.append("{0} in (%({0})s)".format(dimension.fieldname))
|
||||
|
||||
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<h4 class="text-center">
|
||||
{% if (filters.party_name) { %}
|
||||
{%= filters.party_name %}
|
||||
{% } else if (filters.party && filters.show_name) { %}
|
||||
{% } else if (filters.party) { %}
|
||||
{%= filters.party %}
|
||||
{% } else if (filters.account) { %}
|
||||
{%= filters.account %}
|
||||
|
||||
@@ -154,7 +154,8 @@ frappe.query_reports["General Ledger"] = {
|
||||
{
|
||||
"fieldname": "include_default_book_entries",
|
||||
"label": __("Include Default Book Entries"),
|
||||
"fieldtype": "Check"
|
||||
"fieldtype": "Check",
|
||||
"default": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ from frappe import _, _dict
|
||||
from erpnext.accounts.utils import get_account_currency
|
||||
from erpnext.accounts.report.financial_statements import get_cost_centers_with_children
|
||||
from six import iteritems
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
|
||||
from collections import OrderedDict
|
||||
|
||||
def execute(filters=None):
|
||||
@@ -119,7 +119,7 @@ def get_gl_entries(filters):
|
||||
select_fields = """, debit, credit, debit_in_account_currency,
|
||||
credit_in_account_currency """
|
||||
|
||||
order_by_statement = "order by posting_date, account"
|
||||
order_by_statement = "order by posting_date, account, creation"
|
||||
|
||||
if filters.get("group_by") == _("Group by Voucher"):
|
||||
order_by_statement = "order by posting_date, voucher_type, voucher_no"
|
||||
@@ -131,7 +131,7 @@ def get_gl_entries(filters):
|
||||
gl_entries = frappe.db.sql(
|
||||
"""
|
||||
select
|
||||
posting_date, account, party_type, party,
|
||||
name as gl_entry, posting_date, account, party_type, party,
|
||||
voucher_type, voucher_no, cost_center, project,
|
||||
against_voucher_type, against_voucher, account_currency,
|
||||
remarks, against, is_opening {select_fields}
|
||||
@@ -184,7 +184,7 @@ def get_conditions(filters):
|
||||
|
||||
if filters.get("finance_book"):
|
||||
if filters.get("include_default_book_entries"):
|
||||
conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
|
||||
conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)")
|
||||
else:
|
||||
conditions.append("finance_book in (%(finance_book)s)")
|
||||
|
||||
@@ -194,12 +194,17 @@ def get_conditions(filters):
|
||||
if match_conditions:
|
||||
conditions.append(match_conditions)
|
||||
|
||||
accounting_dimensions = get_accounting_dimensions()
|
||||
accounting_dimensions = get_accounting_dimensions(as_list=False)
|
||||
|
||||
if accounting_dimensions:
|
||||
for dimension in accounting_dimensions:
|
||||
if filters.get(dimension):
|
||||
conditions.append("{0} in (%({0})s)".format(dimension))
|
||||
if filters.get(dimension.fieldname):
|
||||
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
||||
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
||||
filters.get(dimension.fieldname))
|
||||
conditions.append("{0} in %({0})s".format(dimension.fieldname))
|
||||
else:
|
||||
conditions.append("{0} in (%({0})s)".format(dimension.fieldname))
|
||||
|
||||
return "and {}".format(" and ".join(conditions)) if conditions else ""
|
||||
|
||||
@@ -359,6 +364,12 @@ def get_columns(filters):
|
||||
currency = get_company_currency(company)
|
||||
|
||||
columns = [
|
||||
{
|
||||
"fieldname": "gl_entry",
|
||||
"fieldtype": "Link",
|
||||
"options": "GL Entry",
|
||||
"hidden": 1
|
||||
},
|
||||
{
|
||||
"label": _("Posting Date"),
|
||||
"fieldname": "posting_date",
|
||||
|
||||
@@ -34,6 +34,20 @@ frappe.query_reports["Item-wise Purchase Register"] = {
|
||||
"label": __("Mode of Payment"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Mode of Payment"
|
||||
},
|
||||
{
|
||||
"label": __("Group By"),
|
||||
"fieldname": "group_by",
|
||||
"fieldtype": "Select",
|
||||
"options": ["Supplier", "Item Group", "Item", "Invoice"]
|
||||
}
|
||||
]
|
||||
],
|
||||
"formatter": function(value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
if (data && data.bold) {
|
||||
value = value.bold();
|
||||
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ from __future__ import unicode_literals
|
||||
import frappe, erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import get_tax_accounts
|
||||
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import (get_tax_accounts,
|
||||
get_grand_total, add_total_row, get_display_value, get_group_by_and_display_fields, add_sub_total_row,
|
||||
get_group_by_conditions)
|
||||
|
||||
def execute(filters=None):
|
||||
return _execute(filters)
|
||||
@@ -13,7 +15,7 @@ def execute(filters=None):
|
||||
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
|
||||
if not filters: filters = {}
|
||||
filters.update({"from_date": filters.get("date_range")[0], "to_date": filters.get("date_range")[1]})
|
||||
columns = get_columns(additional_table_columns)
|
||||
columns = get_columns(additional_table_columns, filters)
|
||||
|
||||
company_currency = erpnext.get_company_currency(filters.company)
|
||||
|
||||
@@ -23,16 +25,16 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency,
|
||||
doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges")
|
||||
|
||||
columns.append({
|
||||
"fieldname": "currency",
|
||||
"label": _("Currency"),
|
||||
"fieldtype": "Data",
|
||||
"width": 80
|
||||
})
|
||||
|
||||
po_pr_map = get_purchase_receipts_against_purchase_order(item_list)
|
||||
|
||||
data = []
|
||||
total_row_map = {}
|
||||
skip_total_row = 0
|
||||
prev_group_by_value = ''
|
||||
|
||||
if filters.get('group_by'):
|
||||
grand_total = get_grand_total(filters, 'Purchase Invoice')
|
||||
|
||||
for d in item_list:
|
||||
if not d.stock_qty:
|
||||
continue
|
||||
@@ -44,51 +46,244 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, []))
|
||||
|
||||
expense_account = d.expense_account or aii_account_map.get(d.company)
|
||||
row = [d.item_code, d.item_name, d.item_group, d.description, d.parent, d.posting_date, d.supplier,
|
||||
d.supplier_name]
|
||||
|
||||
row = {
|
||||
'item_code': d.item_code,
|
||||
'item_name': d.item_name,
|
||||
'item_group': d.item_group,
|
||||
'description': d.description,
|
||||
'invoice': d.parent,
|
||||
'posting_date': d.posting_date,
|
||||
'supplier': d.supplier,
|
||||
'supplier_name': d.supplier_name
|
||||
}
|
||||
|
||||
if additional_query_columns:
|
||||
for col in additional_query_columns:
|
||||
row.append(d.get(col))
|
||||
row.update({
|
||||
col: d.get(col)
|
||||
})
|
||||
|
||||
row += [
|
||||
d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
|
||||
purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_amount / d.stock_qty, d.base_net_amount
|
||||
]
|
||||
row.update({
|
||||
'credit_to': d.credit_to,
|
||||
'mode_of_payment': d.mode_of_payment,
|
||||
'project': d.project,
|
||||
'company': d.company,
|
||||
'purchase_order': d.purchase_order,
|
||||
'purchase_receipt': d.purchase_receipt,
|
||||
'expense_account': expense_account,
|
||||
'stock_qty': d.stock_qty,
|
||||
'stock_uom': d.stock_uom,
|
||||
'rate': d.base_net_amount / d.stock_qty,
|
||||
'amount': d.base_net_amount
|
||||
})
|
||||
|
||||
total_tax = 0
|
||||
for tax in tax_columns:
|
||||
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
|
||||
row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
|
||||
row.update({
|
||||
frappe.scrub(tax + ' Rate'): item_tax.get("tax_rate", 0),
|
||||
frappe.scrub(tax + ' Amount'): item_tax.get("tax_amount", 0),
|
||||
})
|
||||
total_tax += flt(item_tax.get("tax_amount"))
|
||||
|
||||
row += [total_tax, d.base_net_amount + total_tax, company_currency]
|
||||
row.update({
|
||||
'total_tax': total_tax,
|
||||
'total': d.base_net_amount + total_tax,
|
||||
'currency': company_currency
|
||||
})
|
||||
|
||||
if filters.get('group_by'):
|
||||
row.update({'percent_gt': flt(row['total']/grand_total) * 100})
|
||||
group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters)
|
||||
data, prev_group_by_value = add_total_row(data, filters, prev_group_by_value, d, total_row_map,
|
||||
group_by_field, subtotal_display_field, grand_total, tax_columns)
|
||||
add_sub_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns)
|
||||
|
||||
data.append(row)
|
||||
|
||||
return columns, data
|
||||
if filters.get('group_by'):
|
||||
total_row = total_row_map.get(prev_group_by_value or d.get('item_name'))
|
||||
total_row['percent_gt'] = flt(total_row['total']/grand_total * 100)
|
||||
data.append(total_row)
|
||||
data.append({})
|
||||
add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns)
|
||||
data.append(total_row_map.get('total_row'))
|
||||
skip_total_row = 1
|
||||
|
||||
return columns, data, None, None, None, skip_total_row
|
||||
|
||||
|
||||
def get_columns(additional_table_columns):
|
||||
columns = [
|
||||
_("Item Code") + ":Link/Item:120", _("Item Name") + "::120",
|
||||
_("Item Group") + ":Link/Item Group:100", "Description::150", _("Invoice") + ":Link/Purchase Invoice:120",
|
||||
_("Posting Date") + ":Date:80", _("Supplier") + ":Link/Supplier:120",
|
||||
"Supplier Name::120"
|
||||
]
|
||||
def get_columns(additional_table_columns, filters):
|
||||
|
||||
columns = []
|
||||
|
||||
if filters.get('group_by') != ('Item'):
|
||||
columns.extend(
|
||||
[
|
||||
{
|
||||
'label': _('Item Code'),
|
||||
'fieldname': 'item_code',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Item',
|
||||
'width': 120
|
||||
},
|
||||
{
|
||||
'label': _('Item Name'),
|
||||
'fieldname': 'item_name',
|
||||
'fieldtype': 'Data',
|
||||
'width': 120
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
if filters.get('group_by') not in ('Item', 'Item Group'):
|
||||
columns.extend([
|
||||
{
|
||||
'label': _('Item Group'),
|
||||
'fieldname': 'item_group',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Item Group',
|
||||
'width': 120
|
||||
}
|
||||
])
|
||||
|
||||
columns.extend([
|
||||
{
|
||||
'label': _('Description'),
|
||||
'fieldname': 'description',
|
||||
'fieldtype': 'Data',
|
||||
'width': 150
|
||||
},
|
||||
{
|
||||
'label': _('Invoice'),
|
||||
'fieldname': 'invoice',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Purchase Invoice',
|
||||
'width': 120
|
||||
},
|
||||
{
|
||||
'label': _('Posting Date'),
|
||||
'fieldname': 'posting_date',
|
||||
'fieldtype': 'Date',
|
||||
'width': 120
|
||||
}
|
||||
])
|
||||
|
||||
if filters.get('group_by') != 'Supplier':
|
||||
columns.extend([
|
||||
{
|
||||
'label': _('Supplier'),
|
||||
'fieldname': 'supplier',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Supplier',
|
||||
'width': 120
|
||||
},
|
||||
{
|
||||
'label': _('Supplier Name'),
|
||||
'fieldname': 'supplier_name',
|
||||
'fieldtype': 'Data',
|
||||
'width': 120
|
||||
}
|
||||
])
|
||||
|
||||
if additional_table_columns:
|
||||
columns += additional_table_columns
|
||||
|
||||
columns += [
|
||||
"Payable Account:Link/Account:120",
|
||||
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
|
||||
_("Company") + ":Link/Company:100", _("Purchase Order") + ":Link/Purchase Order:100",
|
||||
_("Purchase Receipt") + ":Link/Purchase Receipt:100", _("Expense Account") + ":Link/Account:140",
|
||||
_("Stock Qty") + ":Float:120", _("Stock UOM") + "::100",
|
||||
_("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120"
|
||||
{
|
||||
'label': _('Payable Account'),
|
||||
'fieldname': 'credit_to',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Account',
|
||||
'width': 80
|
||||
},
|
||||
{
|
||||
'label': _('Mode Of Payment'),
|
||||
'fieldname': 'mode_of_payment',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Mode of Payment',
|
||||
'width': 120
|
||||
},
|
||||
{
|
||||
'label': _('Project'),
|
||||
'fieldname': 'project',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Project',
|
||||
'width': 80
|
||||
},
|
||||
{
|
||||
'label': _('Company'),
|
||||
'fieldname': 'company',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Company',
|
||||
'width': 80
|
||||
},
|
||||
{
|
||||
'label': _('Purchase Order'),
|
||||
'fieldname': 'purchase_order',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Purchase Order',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _("Purchase Receipt"),
|
||||
'fieldname': 'Purchase Receipt',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Purchase Receipt',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _('Expense Account'),
|
||||
'fieldname': 'expense_account',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Account',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _('Stock Qty'),
|
||||
'fieldname': 'stock_qty',
|
||||
'fieldtype': 'Float',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _('Stock UOM'),
|
||||
'fieldname': 'stock_uom',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'UOM',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _('Rate'),
|
||||
'fieldname': 'rate',
|
||||
'fieldtype': 'Float',
|
||||
'options': 'currency',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _('Amount'),
|
||||
'fieldname': 'amount',
|
||||
'fieldtype': 'Currency',
|
||||
'options': 'currency',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'fieldname': 'currency',
|
||||
'label': _('Currency'),
|
||||
'fieldtype': 'Currency',
|
||||
'width': 80,
|
||||
'hidden': 1
|
||||
}
|
||||
]
|
||||
|
||||
if filters.get('group_by'):
|
||||
columns.append({
|
||||
'label': _('% Of Grand Total'),
|
||||
'fieldname': 'percent_gt',
|
||||
'fieldtype': 'Float',
|
||||
'width': 80
|
||||
})
|
||||
|
||||
return columns
|
||||
|
||||
def get_conditions(filters):
|
||||
@@ -103,17 +298,20 @@ def get_conditions(filters):
|
||||
if filters.get(opts[0]):
|
||||
conditions += opts[1]
|
||||
|
||||
if not filters.get("group_by"):
|
||||
conditions += "ORDER BY `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc"
|
||||
else:
|
||||
conditions += get_group_by_conditions(filters, 'Purchase Invoice')
|
||||
|
||||
return conditions
|
||||
|
||||
def get_items(filters, additional_query_columns):
|
||||
conditions = get_conditions(filters)
|
||||
match_conditions = frappe.build_match_conditions("Purchase Invoice")
|
||||
|
||||
if match_conditions:
|
||||
match_conditions = " and {0} ".format(match_conditions)
|
||||
|
||||
if additional_query_columns:
|
||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||
else:
|
||||
additional_query_columns = ''
|
||||
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
@@ -125,12 +323,11 @@ def get_items(filters, additional_query_columns):
|
||||
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
|
||||
`tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`,
|
||||
`tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_amount`,
|
||||
`tabPurchase Invoice`.supplier_name, `tabPurchase Invoice`.mode_of_payment {0}
|
||||
`tabPurchase Invoice`.`supplier_name`, `tabPurchase Invoice`.`mode_of_payment` {0}
|
||||
from `tabPurchase Invoice`, `tabPurchase Invoice Item`
|
||||
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and
|
||||
`tabPurchase Invoice`.docstatus = 1 %s %s
|
||||
order by `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc
|
||||
""".format(additional_query_columns) % (conditions, match_conditions), filters, as_dict=1)
|
||||
`tabPurchase Invoice`.docstatus = 1 %s
|
||||
""".format(additional_query_columns) % (conditions), filters, as_dict=1)
|
||||
|
||||
def get_aii_accounts():
|
||||
return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))
|
||||
|
||||
@@ -4,48 +4,62 @@
|
||||
frappe.query_reports["Item-wise Sales Register"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname":"date_range",
|
||||
"fieldname": "date_range",
|
||||
"label": __("Date Range"),
|
||||
"fieldtype": "DateRange",
|
||||
"default": [frappe.datetime.add_months(frappe.datetime.get_today(),-1), frappe.datetime.get_today()],
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname":"customer",
|
||||
"fieldname": "customer",
|
||||
"label": __("Customer"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Customer"
|
||||
},
|
||||
{
|
||||
"fieldname":"company",
|
||||
"fieldname": "company",
|
||||
"label": __("Company"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"default": frappe.defaults.get_user_default("Company")
|
||||
},
|
||||
{
|
||||
"fieldname":"mode_of_payment",
|
||||
"fieldname": "mode_of_payment",
|
||||
"label": __("Mode of Payment"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Mode of Payment"
|
||||
},
|
||||
{
|
||||
"fieldname":"warehouse",
|
||||
"fieldname": "warehouse",
|
||||
"label": __("Warehouse"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname":"brand",
|
||||
"fieldname": "brand",
|
||||
"label": __("Brand"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Brand"
|
||||
},
|
||||
{
|
||||
"fieldname":"item_group",
|
||||
"fieldname": "item_group",
|
||||
"label": __("Item Group"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Item Group"
|
||||
},
|
||||
{
|
||||
"label": __("Group By"),
|
||||
"fieldname": "group_by",
|
||||
"fieldtype": "Select",
|
||||
"options": ["Customer Group", "Customer", "Item Group", "Item", "Territory", "Invoice"]
|
||||
}
|
||||
]
|
||||
],
|
||||
"formatter": function(value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
if (data && data.bold) {
|
||||
value = value.bold();
|
||||
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe, erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from frappe.utils import flt, cstr
|
||||
from frappe.model.meta import get_field_precision
|
||||
from frappe.utils.xlsxutils import handle_html
|
||||
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
|
||||
@@ -15,23 +15,25 @@ def execute(filters=None):
|
||||
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
|
||||
if not filters: filters = {}
|
||||
filters.update({"from_date": filters.get("date_range") and filters.get("date_range")[0], "to_date": filters.get("date_range") and filters.get("date_range")[1]})
|
||||
columns = get_columns(additional_table_columns)
|
||||
columns = get_columns(additional_table_columns, filters)
|
||||
|
||||
company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency")
|
||||
|
||||
item_list = get_items(filters, additional_query_columns)
|
||||
if item_list:
|
||||
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
|
||||
columns.append({
|
||||
"fieldname": "currency",
|
||||
"label": _("Currency"),
|
||||
"fieldtype": "Data",
|
||||
"width": 80
|
||||
})
|
||||
|
||||
mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list]))
|
||||
so_dn_map = get_delivery_notes_against_sales_order(item_list)
|
||||
|
||||
data = []
|
||||
total_row_map = {}
|
||||
skip_total_row = 0
|
||||
prev_group_by_value = ''
|
||||
|
||||
if filters.get('group_by'):
|
||||
grand_total = get_grand_total(filters, 'Sales Invoice')
|
||||
|
||||
for d in item_list:
|
||||
delivery_note = None
|
||||
if d.delivery_note:
|
||||
@@ -42,57 +44,285 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
if not delivery_note and d.update_stock:
|
||||
delivery_note = d.parent
|
||||
|
||||
row = [d.item_code, d.item_name, d.item_group, d.description, d.parent, d.posting_date, d.customer, d.customer_name]
|
||||
row = {
|
||||
'item_code': d.item_code,
|
||||
'item_name': d.item_name,
|
||||
'item_group': d.item_group,
|
||||
'description': d.description,
|
||||
'invoice': d.parent,
|
||||
'posting_date': d.posting_date,
|
||||
'customer': d.customer,
|
||||
'customer_name': d.customer_name,
|
||||
'customer_group': d.customer_group,
|
||||
}
|
||||
|
||||
if additional_query_columns:
|
||||
for col in additional_query_columns:
|
||||
row.append(d.get(col))
|
||||
row.update({
|
||||
col: d.get(col)
|
||||
})
|
||||
|
||||
row += [
|
||||
d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])),
|
||||
d.territory, d.project, d.company, d.sales_order,
|
||||
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom
|
||||
]
|
||||
row.update({
|
||||
'debit_to': d.debit_to,
|
||||
'mode_of_payment': ", ".join(mode_of_payments.get(d.parent, [])),
|
||||
'territory': d.territory,
|
||||
'project': d.project,
|
||||
'company': d.company,
|
||||
'sales_order': d.sales_order,
|
||||
'delivery_note': d.delivery_note,
|
||||
'income_account': d.income_account,
|
||||
'cost_center': d.cost_center,
|
||||
'stock_qty': d.stock_qty,
|
||||
'stock_uom': d.stock_uom
|
||||
})
|
||||
|
||||
if d.stock_uom != d.uom and d.stock_qty:
|
||||
row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount]
|
||||
row.update({
|
||||
'rate': (d.base_net_rate * d.qty)/d.stock_qty,
|
||||
'amount': d.base_net_amount
|
||||
})
|
||||
else:
|
||||
row += [d.base_net_rate, d.base_net_amount]
|
||||
row.update({
|
||||
'rate': d.base_net_rate,
|
||||
'amount': d.base_net_amount
|
||||
})
|
||||
|
||||
total_tax = 0
|
||||
for tax in tax_columns:
|
||||
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
|
||||
row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
|
||||
row.update({
|
||||
frappe.scrub(tax + ' Rate'): item_tax.get("tax_rate", 0),
|
||||
frappe.scrub(tax + ' Amount'): item_tax.get("tax_amount", 0),
|
||||
})
|
||||
total_tax += flt(item_tax.get("tax_amount"))
|
||||
|
||||
row += [total_tax, d.base_net_amount + total_tax, company_currency]
|
||||
row.update({
|
||||
'total_tax': total_tax,
|
||||
'total': d.base_net_amount + total_tax,
|
||||
'currency': company_currency
|
||||
})
|
||||
|
||||
if filters.get('group_by'):
|
||||
row.update({'percent_gt': flt(row['total']/grand_total) * 100})
|
||||
group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters)
|
||||
data, prev_group_by_value = add_total_row(data, filters, prev_group_by_value, d, total_row_map,
|
||||
group_by_field, subtotal_display_field, grand_total, tax_columns)
|
||||
add_sub_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns)
|
||||
|
||||
data.append(row)
|
||||
|
||||
return columns, data
|
||||
if filters.get('group_by'):
|
||||
total_row = total_row_map.get(prev_group_by_value or d.get('item_name'))
|
||||
total_row['percent_gt'] = flt(total_row['total']/grand_total * 100)
|
||||
data.append(total_row)
|
||||
data.append({})
|
||||
add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns)
|
||||
data.append(total_row_map.get('total_row'))
|
||||
skip_total_row = 1
|
||||
|
||||
def get_columns(additional_table_columns):
|
||||
columns = [
|
||||
_("Item Code") + ":Link/Item:120", _("Item Name") + "::120",
|
||||
_("Item Group") + ":Link/Item Group:100", "Description::150", _("Invoice") + ":Link/Sales Invoice:120",
|
||||
_("Posting Date") + ":Date:80", _("Customer") + ":Link/Customer:120",
|
||||
_("Customer Name") + "::120"]
|
||||
return columns, data, None, None, None, skip_total_row
|
||||
|
||||
def get_columns(additional_table_columns, filters):
|
||||
columns = []
|
||||
|
||||
if filters.get('group_by') != ('Item'):
|
||||
columns.extend(
|
||||
[
|
||||
{
|
||||
'label': _('Item Code'),
|
||||
'fieldname': 'item_code',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Item',
|
||||
'width': 120
|
||||
},
|
||||
{
|
||||
'label': _('Item Name'),
|
||||
'fieldname': 'item_name',
|
||||
'fieldtype': 'Data',
|
||||
'width': 120
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
if filters.get('group_by') not in ('Item', 'Item Group'):
|
||||
columns.extend([
|
||||
{
|
||||
'label': _('Item Group'),
|
||||
'fieldname': 'item_group',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Item Group',
|
||||
'width': 120
|
||||
}
|
||||
])
|
||||
|
||||
columns.extend([
|
||||
{
|
||||
'label': _('Description'),
|
||||
'fieldname': 'description',
|
||||
'fieldtype': 'Data',
|
||||
'width': 150
|
||||
},
|
||||
{
|
||||
'label': _('Invoice'),
|
||||
'fieldname': 'invoice',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Sales Invoice',
|
||||
'width': 120
|
||||
},
|
||||
{
|
||||
'label': _('Posting Date'),
|
||||
'fieldname': 'posting_date',
|
||||
'fieldtype': 'Date',
|
||||
'width': 120
|
||||
}
|
||||
])
|
||||
|
||||
if filters.get('group_by') != 'Customer':
|
||||
columns.extend([
|
||||
{
|
||||
'label': _('Customer Group'),
|
||||
'fieldname': 'customer_group',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Customer Group',
|
||||
'width': 120
|
||||
}
|
||||
])
|
||||
|
||||
if filters.get('group_by') not in ('Customer', 'Customer Group'):
|
||||
columns.extend([
|
||||
{
|
||||
'label': _('Customer'),
|
||||
'fieldname': 'customer',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Customer',
|
||||
'width': 120
|
||||
},
|
||||
{
|
||||
'label': _('Customer Name'),
|
||||
'fieldname': 'customer_name',
|
||||
'fieldtype': 'Data',
|
||||
'width': 120
|
||||
}
|
||||
])
|
||||
|
||||
if additional_table_columns:
|
||||
columns += additional_table_columns
|
||||
|
||||
columns += [
|
||||
_("Customer Group") + ":Link/Customer Group:120",
|
||||
_("Receivable Account") + ":Link/Account:120",
|
||||
_("Mode of Payment") + "::120", _("Territory") + ":Link/Territory:80",
|
||||
_("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100",
|
||||
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
|
||||
_("Income Account") + ":Link/Account:140", _("Cost Center") + ":Link/Cost Center:140",
|
||||
_("Stock Qty") + ":Float:120", _("Stock UOM") + "::100",
|
||||
_("Rate") + ":Currency/currency:120",
|
||||
_("Amount") + ":Currency/currency:120"
|
||||
{
|
||||
'label': _('Receivable Account'),
|
||||
'fieldname': 'debit_to',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Account',
|
||||
'width': 80
|
||||
},
|
||||
{
|
||||
'label': _('Mode Of Payment'),
|
||||
'fieldname': 'mode_of_payment',
|
||||
'fieldtype': 'Data',
|
||||
'width': 120
|
||||
}
|
||||
]
|
||||
|
||||
if filters.get('group_by') != 'Terriotory':
|
||||
columns.extend([
|
||||
{
|
||||
'label': _("Territory"),
|
||||
'fieldname': 'territory',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Territory',
|
||||
'width': 80
|
||||
}
|
||||
])
|
||||
|
||||
|
||||
columns += [
|
||||
{
|
||||
'label': _('Project'),
|
||||
'fieldname': 'project',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Project',
|
||||
'width': 80
|
||||
},
|
||||
{
|
||||
'label': _('Company'),
|
||||
'fieldname': 'company',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Company',
|
||||
'width': 80
|
||||
},
|
||||
{
|
||||
'label': _('Sales Order'),
|
||||
'fieldname': 'sales_order',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Sales Order',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _("Delivery Note"),
|
||||
'fieldname': 'delivery_note',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Delivery Note',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _('Income Account'),
|
||||
'fieldname': 'income_account',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Account',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _("Cost Center"),
|
||||
'fieldname': 'cost_center',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Cost Center',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _('Stock Qty'),
|
||||
'fieldname': 'stock_qty',
|
||||
'fieldtype': 'Float',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _('Stock UOM'),
|
||||
'fieldname': 'stock_uom',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'UOM',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _('Rate'),
|
||||
'fieldname': 'rate',
|
||||
'fieldtype': 'Float',
|
||||
'options': 'currency',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _('Amount'),
|
||||
'fieldname': 'amount',
|
||||
'fieldtype': 'Currency',
|
||||
'options': 'currency',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'fieldname': 'currency',
|
||||
'label': _('Currency'),
|
||||
'fieldtype': 'Currency',
|
||||
'width': 80,
|
||||
'hidden': 1
|
||||
}
|
||||
]
|
||||
|
||||
if filters.get('group_by'):
|
||||
columns.append({
|
||||
'label': _('% Of Grand Total'),
|
||||
'fieldname': 'percent_gt',
|
||||
'fieldtype': 'Float',
|
||||
'width': 80
|
||||
})
|
||||
|
||||
return columns
|
||||
|
||||
def get_conditions(filters):
|
||||
@@ -112,33 +342,39 @@ def get_conditions(filters):
|
||||
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
|
||||
|
||||
if filters.get("warehouse"):
|
||||
conditions += """ and exists(select name from `tabSales Invoice Item`
|
||||
where parent=`tabSales Invoice`.name
|
||||
and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s)"""
|
||||
conditions += """and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s"""
|
||||
|
||||
|
||||
if filters.get("brand"):
|
||||
conditions += """ and exists(select name from `tabSales Invoice Item`
|
||||
where parent=`tabSales Invoice`.name
|
||||
and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s)"""
|
||||
conditions += """and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s"""
|
||||
|
||||
if filters.get("item_group"):
|
||||
conditions += """ and exists(select name from `tabSales Invoice Item`
|
||||
where parent=`tabSales Invoice`.name
|
||||
and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)"""
|
||||
conditions += """and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s"""
|
||||
|
||||
if not filters.get("group_by"):
|
||||
conditions += "ORDER BY `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_group desc"
|
||||
else:
|
||||
conditions += get_group_by_conditions(filters, 'Sales Invoice')
|
||||
|
||||
return conditions
|
||||
|
||||
def get_group_by_conditions(filters, doctype):
|
||||
if filters.get("group_by") == 'Invoice':
|
||||
return "ORDER BY `tab{0} Item`.parent desc".format(doctype)
|
||||
elif filters.get("group_by") == 'Item':
|
||||
return "ORDER BY `tab{0} Item`.`item_code`".format(doctype)
|
||||
elif filters.get("group_by") == 'Item Group':
|
||||
return "ORDER BY `tab{0} Item`.{1}".format(doctype, frappe.scrub(filters.get('group_by')))
|
||||
elif filters.get("group_by") in ('Customer', 'Customer Group', 'Territory', 'Supplier'):
|
||||
return "ORDER BY `tab{0}`.{1}".format(doctype, frappe.scrub(filters.get('group_by')))
|
||||
|
||||
def get_items(filters, additional_query_columns):
|
||||
conditions = get_conditions(filters)
|
||||
match_conditions = frappe.build_match_conditions("Sales Invoice")
|
||||
|
||||
if match_conditions:
|
||||
match_conditions = " and {0} ".format(match_conditions)
|
||||
|
||||
if additional_query_columns:
|
||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||
else:
|
||||
additional_query_columns = ''
|
||||
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
@@ -156,9 +392,8 @@ def get_items(filters, additional_query_columns):
|
||||
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0}
|
||||
from `tabSales Invoice`, `tabSales Invoice Item`
|
||||
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
|
||||
and `tabSales Invoice`.docstatus = 1 %s %s
|
||||
order by `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_code desc
|
||||
""".format(additional_query_columns or '') % (conditions, match_conditions), filters, as_dict=1)
|
||||
and `tabSales Invoice`.docstatus = 1 {1}
|
||||
""".format(additional_query_columns or '', conditions), filters, as_dict=1) #nosec
|
||||
|
||||
def get_delivery_notes_against_sales_order(item_list):
|
||||
so_dn_map = frappe._dict()
|
||||
@@ -177,6 +412,15 @@ def get_delivery_notes_against_sales_order(item_list):
|
||||
|
||||
return so_dn_map
|
||||
|
||||
def get_grand_total(filters, doctype):
|
||||
|
||||
return frappe.db.sql(""" SELECT
|
||||
SUM(`tab{0}`.base_grand_total)
|
||||
FROM `tab{0}`
|
||||
WHERE `tab{0}`.docstatus = 1
|
||||
and posting_date between %s and %s
|
||||
""".format(doctype), (filters.get('from_date'), filters.get('to_date')))[0][0] #nosec
|
||||
|
||||
def get_deducted_taxes():
|
||||
return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'")
|
||||
|
||||
@@ -264,9 +508,117 @@ def get_tax_accounts(item_list, columns, company_currency,
|
||||
|
||||
tax_columns.sort()
|
||||
for desc in tax_columns:
|
||||
columns.append(desc + " Rate:Data:80")
|
||||
columns.append(desc + " Amount:Currency/currency:100")
|
||||
columns.append({
|
||||
'label': _(desc + ' Rate'),
|
||||
'fieldname': frappe.scrub(desc + ' Rate'),
|
||||
'fieldtype': 'Float',
|
||||
'width': 100
|
||||
})
|
||||
|
||||
columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:100"]
|
||||
columns.append({
|
||||
'label': _(desc + ' Amount'),
|
||||
'fieldname': frappe.scrub(desc + ' Amount'),
|
||||
'fieldtype': 'Currency',
|
||||
'options': 'currency',
|
||||
'width': 100
|
||||
})
|
||||
|
||||
columns += [
|
||||
{
|
||||
'label': _('Total Tax'),
|
||||
'fieldname': 'total_tax',
|
||||
'fieldtype': 'Currency',
|
||||
'options': 'currency',
|
||||
'width': 100
|
||||
},
|
||||
{
|
||||
'label': _('Total'),
|
||||
'fieldname': 'total',
|
||||
'fieldtype': 'Currency',
|
||||
'options': 'currency',
|
||||
'width': 100
|
||||
}
|
||||
]
|
||||
|
||||
return itemised_tax, tax_columns
|
||||
|
||||
def add_total_row(data, filters, prev_group_by_value, item, total_row_map,
|
||||
group_by_field, subtotal_display_field, grand_total, tax_columns):
|
||||
if prev_group_by_value != item.get(group_by_field, ''):
|
||||
if prev_group_by_value:
|
||||
total_row = total_row_map.get(prev_group_by_value)
|
||||
data.append(total_row)
|
||||
data.append({})
|
||||
add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns)
|
||||
|
||||
prev_group_by_value = item.get(group_by_field, '')
|
||||
|
||||
total_row_map.setdefault(item.get(group_by_field, ''), {
|
||||
subtotal_display_field: get_display_value(filters, group_by_field, item),
|
||||
'stock_qty': 0.0,
|
||||
'amount': 0.0,
|
||||
'bold': 1,
|
||||
'total_tax': 0.0,
|
||||
'total': 0.0,
|
||||
'percent_gt': 0.0
|
||||
})
|
||||
|
||||
total_row_map.setdefault('total_row', {
|
||||
subtotal_display_field: "Total",
|
||||
'stock_qty': 0.0,
|
||||
'amount': 0.0,
|
||||
'bold': 1,
|
||||
'total_tax': 0.0,
|
||||
'total': 0.0,
|
||||
'percent_gt': 0.0
|
||||
})
|
||||
|
||||
return data, prev_group_by_value
|
||||
|
||||
def get_display_value(filters, group_by_field, item):
|
||||
if filters.get('group_by') == 'Item':
|
||||
if item.get('item_code') != item.get('item_name'):
|
||||
value = cstr(item.get('item_code')) + "<br><br>" + \
|
||||
"<span style='font-weight: normal'>" + cstr(item.get('item_name')) + "</span>"
|
||||
else:
|
||||
value = item.get('item_code', '')
|
||||
elif filters.get('group_by') in ('Customer', 'Supplier'):
|
||||
party = frappe.scrub(filters.get('group_by'))
|
||||
if item.get(party) != item.get(party+'_name'):
|
||||
value = item.get(party) + "<br><br>" + \
|
||||
"<span style='font-weight: normal'>" + item.get(party+'_name') + "</span>"
|
||||
else:
|
||||
value = item.get(party)
|
||||
else:
|
||||
value = item.get(group_by_field)
|
||||
|
||||
return value
|
||||
|
||||
def get_group_by_and_display_fields(filters):
|
||||
if filters.get('group_by') == 'Item':
|
||||
group_by_field = 'item_code'
|
||||
subtotal_display_field = 'invoice'
|
||||
elif filters.get('group_by') == 'Invoice':
|
||||
group_by_field = 'parent'
|
||||
subtotal_display_field = 'item_code'
|
||||
else:
|
||||
group_by_field = frappe.scrub(filters.get('group_by'))
|
||||
subtotal_display_field = 'item_code'
|
||||
|
||||
return group_by_field, subtotal_display_field
|
||||
|
||||
def add_sub_total_row(item, total_row_map, group_by_value, tax_columns):
|
||||
total_row = total_row_map.get(group_by_value)
|
||||
total_row['stock_qty'] += item['stock_qty']
|
||||
total_row['amount'] += item['amount']
|
||||
total_row['total_tax'] += item['total_tax']
|
||||
total_row['total'] += item['total']
|
||||
total_row['percent_gt'] += item['percent_gt']
|
||||
|
||||
for tax in tax_columns:
|
||||
total_row.setdefault(frappe.scrub(tax + ' Amount'), 0.0)
|
||||
total_row[frappe.scrub(tax + ' Amount')] += flt(item[frappe.scrub(tax + ' Amount')])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
||||
{
|
||||
"fieldname": "include_default_book_entries",
|
||||
"label": __("Include Default Book Entries"),
|
||||
"fieldtype": "Check"
|
||||
"fieldtype": "Check",
|
||||
"default": 1
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -34,6 +34,33 @@ frappe.query_reports["Purchase Register"] = {
|
||||
"label": __("Mode of Payment"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Mode of Payment"
|
||||
},
|
||||
{
|
||||
"fieldname":"cost_center",
|
||||
"label": __("Cost Center"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Cost Center"
|
||||
},
|
||||
{
|
||||
"fieldname":"warehouse",
|
||||
"label": __("Warehouse"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname":"item_group",
|
||||
"label": __("Item Group"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Item Group"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
erpnext.dimension_filters.forEach((dimension) => {
|
||||
frappe.query_reports["Purchase Register"].filters.splice(7, 0 ,{
|
||||
"fieldname": dimension["fieldname"],
|
||||
"label": __(dimension["label"]),
|
||||
"fieldtype": "Link",
|
||||
"options": dimension["document_type"]
|
||||
});
|
||||
});
|
||||
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import flt
|
||||
from frappe import msgprint, _
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
|
||||
|
||||
def execute(filters=None):
|
||||
return _execute(filters)
|
||||
@@ -66,7 +67,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
total_tax += tax_amount
|
||||
row.append(tax_amount)
|
||||
|
||||
# total tax, grand total, rounded total & outstanding amount
|
||||
# total tax, grand total, rounded total & outstanding amount
|
||||
row += [total_tax, inv.base_grand_total, flt(inv.base_grand_total, 0), inv.outstanding_amount]
|
||||
data.append(row)
|
||||
|
||||
@@ -134,6 +135,38 @@ def get_conditions(filters):
|
||||
|
||||
if filters.get("mode_of_payment"): conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s"
|
||||
|
||||
if filters.get("cost_center"):
|
||||
conditions += """ and exists(select name from `tabPurchase Invoice Item`
|
||||
where parent=`tabPurchase Invoice`.name
|
||||
and ifnull(`tabPurchase Invoice Item`.cost_center, '') = %(cost_center)s)"""
|
||||
|
||||
if filters.get("warehouse"):
|
||||
conditions += """ and exists(select name from `tabPurchase Invoice Item`
|
||||
where parent=`tabPurchase Invoice`.name
|
||||
and ifnull(`tabPurchase Invoice Item`.warehouse, '') = %(warehouse)s)"""
|
||||
|
||||
if filters.get("item_group"):
|
||||
conditions += """ and exists(select name from `tabPurchase Invoice Item`
|
||||
where parent=`tabPurchase Invoice`.name
|
||||
and ifnull(`tabPurchase Invoice Item`.item_group, '') = %(item_group)s)"""
|
||||
|
||||
accounting_dimensions = get_accounting_dimensions(as_list=False)
|
||||
|
||||
if accounting_dimensions:
|
||||
common_condition = """
|
||||
and exists(select name from `tabPurchase Invoice Item`
|
||||
where parent=`tabPurchase Invoice`.name
|
||||
"""
|
||||
for dimension in accounting_dimensions:
|
||||
if filters.get(dimension.fieldname):
|
||||
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
||||
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
||||
filters.get(dimension.fieldname))
|
||||
|
||||
conditions += common_condition + "and ifnull(`tabPurchase Invoice Item`.{0}, '') in %({0})s)".format(dimension.fieldname)
|
||||
else:
|
||||
conditions += common_condition + "and ifnull(`tabPurchase Invoice Item`.{0}, '') in (%({0})s))".format(dimension.fieldname)
|
||||
|
||||
return conditions
|
||||
|
||||
def get_invoices(filters, additional_query_columns):
|
||||
|
||||
@@ -6,7 +6,7 @@ import frappe
|
||||
from frappe.utils import flt
|
||||
from frappe import msgprint, _
|
||||
from frappe.model.meta import get_field_precision
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
|
||||
|
||||
def execute(filters=None):
|
||||
return _execute(filters)
|
||||
@@ -139,7 +139,7 @@ def get_columns(invoice_list, additional_table_columns):
|
||||
|
||||
columns +=[
|
||||
{
|
||||
'label': _("Custmer Group"),
|
||||
'label': _("Customer Group"),
|
||||
'fieldname': 'customer_group',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Customer Group',
|
||||
@@ -175,7 +175,7 @@ def get_columns(invoice_list, additional_table_columns):
|
||||
'label': _("Project"),
|
||||
'fieldname': 'project',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'project',
|
||||
'options': 'Project',
|
||||
'width': 80
|
||||
},
|
||||
{
|
||||
@@ -341,15 +341,22 @@ def get_conditions(filters):
|
||||
where parent=`tabSales Invoice`.name
|
||||
and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)"""
|
||||
|
||||
accounting_dimensions = get_accounting_dimensions()
|
||||
accounting_dimensions = get_accounting_dimensions(as_list=False)
|
||||
|
||||
if accounting_dimensions:
|
||||
common_condition = """
|
||||
and exists(select name from `tabSales Invoice Item`
|
||||
where parent=`tabSales Invoice`.name
|
||||
"""
|
||||
for dimension in accounting_dimensions:
|
||||
if filters.get(dimension):
|
||||
conditions += """ and exists(select name from `tabSales Invoice Item`
|
||||
where parent=`tabSales Invoice`.name
|
||||
and ifnull(`tabSales Invoice Item`.{0}, '') = %({0})s)""".format(dimension)
|
||||
if filters.get(dimension.fieldname):
|
||||
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
||||
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
||||
filters.get(dimension.fieldname))
|
||||
|
||||
conditions += common_condition + "and ifnull(`tabSales Invoice Item`.{0}, '') in %({0})s)".format(dimension.fieldname)
|
||||
else:
|
||||
conditions += common_condition + "and ifnull(`tabSales Invoice Item`.{0}, '') in (%({0})s))".format(dimension.fieldname)
|
||||
|
||||
return conditions
|
||||
|
||||
|
||||
@@ -85,7 +85,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
||||
{
|
||||
"fieldname": "include_default_book_entries",
|
||||
"label": __("Include Default Book Entries"),
|
||||
"fieldtype": "Check"
|
||||
"fieldtype": "Check",
|
||||
"default": 1
|
||||
}
|
||||
],
|
||||
"formatter": erpnext.financial_statements.formatter,
|
||||
|
||||
@@ -7,7 +7,7 @@ from frappe import _
|
||||
from frappe.utils import flt, getdate, formatdate, cstr
|
||||
from erpnext.accounts.report.financial_statements \
|
||||
import filter_accounts, set_gl_entries_by_account, filter_out_zero_value_rows
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
|
||||
|
||||
value_fields = ("opening_debit", "opening_credit", "debit", "credit", "closing_debit", "closing_credit")
|
||||
|
||||
@@ -103,13 +103,13 @@ def get_rootwise_opening_balances(filters, report_type):
|
||||
where lft >= %s and rgt <= %s)""" % (lft, rgt)
|
||||
|
||||
if filters.finance_book:
|
||||
fb_conditions = " and finance_book = %(finance_book)s"
|
||||
fb_conditions = " AND finance_book = %(finance_book)s"
|
||||
if filters.include_default_book_entries:
|
||||
fb_conditions = " and (finance_book in (%(finance_book)s, %(company_fb)s))"
|
||||
fb_conditions = " AND (finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)"
|
||||
|
||||
additional_conditions += fb_conditions
|
||||
|
||||
accounting_dimensions = get_accounting_dimensions()
|
||||
accounting_dimensions = get_accounting_dimensions(as_list=False)
|
||||
|
||||
query_filters = {
|
||||
"company": filters.company,
|
||||
@@ -122,11 +122,16 @@ def get_rootwise_opening_balances(filters, report_type):
|
||||
|
||||
if accounting_dimensions:
|
||||
for dimension in accounting_dimensions:
|
||||
if filters.get(dimension):
|
||||
additional_conditions += """ and {0} in (%({0})s) """.format(dimension)
|
||||
if filters.get(dimension.fieldname):
|
||||
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
||||
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
||||
filters.get(dimension.fieldname))
|
||||
additional_conditions += "and {0} in %({0})s".format(dimension.fieldname)
|
||||
else:
|
||||
additional_conditions += "and {0} in (%({0})s)".format(dimension.fieldname)
|
||||
|
||||
query_filters.update({
|
||||
dimension: filters.get(dimension)
|
||||
dimension.fieldname: filters.get(dimension.fieldname)
|
||||
})
|
||||
|
||||
gle = frappe.db.sql("""
|
||||
|
||||
@@ -640,8 +640,9 @@ def get_outstanding_invoices(party_type, party, account, condition=None, filters
|
||||
precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
|
||||
|
||||
if account:
|
||||
root_type = frappe.get_cached_value("Account", account, "root_type")
|
||||
root_type, account_type = frappe.get_cached_value("Account", account, ["root_type", "account_type"])
|
||||
party_account_type = "Receivable" if root_type == "Asset" else "Payable"
|
||||
party_account_type = account_type or party_account_type
|
||||
else:
|
||||
party_account_type = erpnext.get_party_account_type(party_type)
|
||||
|
||||
|
||||
@@ -620,7 +620,7 @@ def get_asset_account(account_name, asset=None, asset_category=None, company=Non
|
||||
|
||||
if not account:
|
||||
if not asset_category:
|
||||
frappe.throw(_("Set {0} in company {2}").format(account_name.replace('_', ' ').title(), company))
|
||||
frappe.throw(_("Set {0} in company {1}").format(account_name.replace('_', ' ').title(), company))
|
||||
else:
|
||||
frappe.throw(_("Set {0} in asset category {1} or company {2}")
|
||||
.format(account_name.replace('_', ' ').title(), asset_category, company))
|
||||
|
||||
@@ -22,7 +22,7 @@ def post_depreciation_entries(date=None):
|
||||
def get_depreciable_assets(date):
|
||||
return frappe.db.sql_list("""select a.name
|
||||
from tabAsset a, `tabDepreciation Schedule` ds
|
||||
where a.name = ds.parent and a.docstatus=1 and ds.schedule_date<=%s
|
||||
where a.name = ds.parent and a.docstatus=1 and ds.schedule_date<=%s and a.calculate_depreciation = 1
|
||||
and a.status in ('Submitted', 'Partially Depreciated')
|
||||
and ifnull(ds.journal_entry, '')=''""", date)
|
||||
|
||||
|
||||
@@ -1,708 +1,227 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:location_name",
|
||||
"beta": 0,
|
||||
"creation": "2018-05-07 12:49:22.595974",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"location_name",
|
||||
"parent_location",
|
||||
"cb_details",
|
||||
"is_container",
|
||||
"is_group",
|
||||
"sb_location_details",
|
||||
"latitude",
|
||||
"longitude",
|
||||
"cb_latlong",
|
||||
"area",
|
||||
"area_uom",
|
||||
"sb_geolocation",
|
||||
"location",
|
||||
"tree_details",
|
||||
"lft",
|
||||
"rgt",
|
||||
"old_parent"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "location_name",
|
||||
"fieldtype": "Data",
|
||||
"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": "Location Name",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "parent_location",
|
||||
"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": "Parent Location",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Location",
|
||||
"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": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "cb_details",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"description": "Check if it is a hydroponic unit",
|
||||
"fieldname": "is_container",
|
||||
"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": "Is Container",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Is Container"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fieldname": "is_group",
|
||||
"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": "Is Group",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Is Group"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "sb_location_details",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Location Details",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Location Details"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_from": "parent_location.latitude",
|
||||
"fieldname": "latitude",
|
||||
"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": "Latitude",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Latitude"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_from": "parent_location.longitude",
|
||||
"fieldname": "longitude",
|
||||
"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": "Longitude",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Longitude"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "cb_latlong",
|
||||
"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,
|
||||
"label": "",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "area",
|
||||
"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": "Area",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.area",
|
||||
"fieldname": "area_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": "Area UOM",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "UOM",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "UOM"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "sb_geolocation",
|
||||
"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,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "location",
|
||||
"fieldtype": "Geolocation",
|
||||
"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": "Location",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Location"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "tree_details",
|
||||
"fieldtype": "Section Break",
|
||||
"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": "Tree Details",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Tree Details"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "lft",
|
||||
"fieldtype": "Int",
|
||||
"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": "lft",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rgt",
|
||||
"fieldtype": "Int",
|
||||
"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": "rgt",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "old_parent",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Old Parent",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-07-11 13:36:30.999405",
|
||||
"is_tree": 1,
|
||||
"links": [],
|
||||
"modified": "2020-03-18 18:25:59.283057",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Assets",
|
||||
"name": "Location",
|
||||
"name_case": "Title Case",
|
||||
"nsm_parent_field": "parent_location",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Stock User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Stock Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Agriculture Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Agriculture User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -20,6 +20,16 @@ frappe.query_reports["Fixed Asset Register"] = {
|
||||
default: 'In Location',
|
||||
reqd: 1
|
||||
},
|
||||
{
|
||||
fieldname:"purchase_date",
|
||||
label: __("Purchase Date"),
|
||||
fieldtype: "Date"
|
||||
},
|
||||
{
|
||||
fieldname:"available_for_use_date",
|
||||
label: __("Available For Use Date"),
|
||||
fieldtype: "Date"
|
||||
},
|
||||
{
|
||||
fieldname:"finance_book",
|
||||
label: __("Finance Book"),
|
||||
@@ -27,10 +37,15 @@ frappe.query_reports["Fixed Asset Register"] = {
|
||||
options: "Finance Book"
|
||||
},
|
||||
{
|
||||
fieldname:"date",
|
||||
label: __("Date"),
|
||||
fieldtype: "Date",
|
||||
default: frappe.datetime.get_today()
|
||||
fieldname:"asset_category",
|
||||
label: __("Asset Category"),
|
||||
fieldtype: "Link",
|
||||
options: "Asset Category"
|
||||
},
|
||||
{
|
||||
fieldname:"is_existing_asset",
|
||||
label: __("Is Existing Asset"),
|
||||
fieldtype: "Check"
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
@@ -40,6 +40,42 @@ def get_columns(filters):
|
||||
"fieldname": "status",
|
||||
"width": 90
|
||||
},
|
||||
{
|
||||
"label": _("Purchase Date"),
|
||||
"fieldtype": "Date",
|
||||
"fieldname": "purchase_date",
|
||||
"width": 90
|
||||
},
|
||||
{
|
||||
"label": _("Available For Use Date"),
|
||||
"fieldtype": "Date",
|
||||
"fieldname": "available_for_use_date",
|
||||
"width": 90
|
||||
},
|
||||
{
|
||||
"label": _("Gross Purchase Amount"),
|
||||
"fieldname": "gross_purchase_amount",
|
||||
"options": "Currency",
|
||||
"width": 90
|
||||
},
|
||||
{
|
||||
"label": _("Asset Value"),
|
||||
"fieldname": "asset_value",
|
||||
"options": "Currency",
|
||||
"width": 90
|
||||
},
|
||||
{
|
||||
"label": _("Opening Accumulated Depreciation"),
|
||||
"fieldname": "opening_accumulated_depreciation",
|
||||
"options": "Currency",
|
||||
"width": 90
|
||||
},
|
||||
{
|
||||
"label": _("Depreciated Amount"),
|
||||
"fieldname": "depreciated_amount",
|
||||
"options": "Currency",
|
||||
"width": 90
|
||||
},
|
||||
{
|
||||
"label": _("Cost Center"),
|
||||
"fieldtype": "Link",
|
||||
@@ -54,25 +90,6 @@ def get_columns(filters):
|
||||
"options": "Department",
|
||||
"width": 100
|
||||
},
|
||||
{
|
||||
"label": _("Location"),
|
||||
"fieldtype": "Link",
|
||||
"fieldname": "location",
|
||||
"options": "Location",
|
||||
"width": 100
|
||||
},
|
||||
{
|
||||
"label": _("Purchase Date"),
|
||||
"fieldtype": "Date",
|
||||
"fieldname": "purchase_date",
|
||||
"width": 90
|
||||
},
|
||||
{
|
||||
"label": _("Gross Purchase Amount"),
|
||||
"fieldname": "gross_purchase_amount",
|
||||
"options": "Currency",
|
||||
"width": 90
|
||||
},
|
||||
{
|
||||
"label": _("Vendor Name"),
|
||||
"fieldtype": "Data",
|
||||
@@ -80,25 +97,29 @@ def get_columns(filters):
|
||||
"width": 100
|
||||
},
|
||||
{
|
||||
"label": _("Available For Use Date"),
|
||||
"fieldtype": "Date",
|
||||
"fieldname": "available_for_use_date",
|
||||
"width": 90
|
||||
},
|
||||
{
|
||||
"label": _("Asset Value"),
|
||||
"fieldname": "asset_value",
|
||||
"options": "Currency",
|
||||
"width": 90
|
||||
"label": _("Location"),
|
||||
"fieldtype": "Link",
|
||||
"fieldname": "location",
|
||||
"options": "Location",
|
||||
"width": 100
|
||||
},
|
||||
]
|
||||
|
||||
def get_conditions(filters):
|
||||
conditions = {'docstatus': 1}
|
||||
conditions = { 'docstatus': 1 }
|
||||
status = filters.status
|
||||
date = filters.date
|
||||
|
||||
if filters.company:
|
||||
if filters.get('company'):
|
||||
conditions["company"] = filters.company
|
||||
if filters.get('purchase_date'):
|
||||
conditions["purchase_date"] = ('<=', filters.get('purchase_date'))
|
||||
if filters.get('available_for_use_date'):
|
||||
conditions["available_for_use_date"] = ('<=', filters.get('available_for_use_date'))
|
||||
if filters.get('is_existing_asset'):
|
||||
conditions["is_existing_asset"] = filters.get('is_existing_asset')
|
||||
if filters.get('asset_category'):
|
||||
conditions["asset_category"] = filters.get('asset_category')
|
||||
|
||||
# In Store assets are those that are not sold or scrapped
|
||||
operand = 'not in'
|
||||
@@ -114,7 +135,7 @@ def get_data(filters):
|
||||
data = []
|
||||
|
||||
conditions = get_conditions(filters)
|
||||
depreciation_amount_map = get_finance_book_value_map(filters.date, filters.finance_book)
|
||||
depreciation_amount_map = get_finance_book_value_map(filters)
|
||||
pr_supplier_map = get_purchase_receipt_supplier_map()
|
||||
pi_supplier_map = get_purchase_invoice_supplier_map()
|
||||
|
||||
@@ -136,6 +157,8 @@ def get_data(filters):
|
||||
"cost_center": asset.cost_center,
|
||||
"vendor_name": pr_supplier_map.get(asset.purchase_receipt) or pi_supplier_map.get(asset.purchase_invoice),
|
||||
"gross_purchase_amount": asset.gross_purchase_amount,
|
||||
"opening_accumulated_depreciation": asset.opening_accumulated_depreciation,
|
||||
"depreciated_amount": depreciation_amount_map.get(asset.name) or 0.0,
|
||||
"available_for_use_date": asset.available_for_use_date,
|
||||
"location": asset.location,
|
||||
"asset_category": asset.asset_category,
|
||||
@@ -146,9 +169,9 @@ def get_data(filters):
|
||||
|
||||
return data
|
||||
|
||||
def get_finance_book_value_map(date, finance_book=''):
|
||||
if not date:
|
||||
date = today()
|
||||
def get_finance_book_value_map(filters):
|
||||
date = filters.get('purchase_date') or filters.get('available_for_use_date') or today()
|
||||
|
||||
return frappe._dict(frappe.db.sql(''' Select
|
||||
parent, SUM(depreciation_amount)
|
||||
FROM `tabDepreciation Schedule`
|
||||
@@ -157,7 +180,7 @@ def get_finance_book_value_map(date, finance_book=''):
|
||||
AND schedule_date<=%s
|
||||
AND journal_entry IS NOT NULL
|
||||
AND ifnull(finance_book, '')=%s
|
||||
GROUP BY parent''', (date, cstr(finance_book))))
|
||||
GROUP BY parent''', (date, cstr(filters.finance_book or ''))))
|
||||
|
||||
def get_purchase_receipt_supplier_map():
|
||||
return frappe._dict(frappe.db.sql(''' Select
|
||||
|
||||
@@ -698,8 +698,7 @@
|
||||
{
|
||||
"fieldname": "manufacturer_part_no",
|
||||
"fieldtype": "Data",
|
||||
"label": "Manufacturer Part Number",
|
||||
"read_only": 1
|
||||
"label": "Manufacturer Part Number"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
@@ -712,7 +711,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2019-11-07 17:19:12.090355",
|
||||
"modified": "2020-04-07 18:35:17.558928",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Item",
|
||||
|
||||
@@ -9,7 +9,7 @@ cur_frm.add_fetch('contact', 'email_id', 'email_id')
|
||||
frappe.ui.form.on("Request for Quotation",{
|
||||
setup: function(frm) {
|
||||
frm.custom_make_buttons = {
|
||||
'Supplier Quotation': 'Supplier Quotation'
|
||||
'Supplier Quotation': 'Create'
|
||||
}
|
||||
|
||||
frm.fields_dict["suppliers"].grid.get_field("contact").get_query = function(doc, cdt, cdn) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,8 @@ def get_data():
|
||||
'heatmap_message': _('This is based on transactions against this Supplier. See timeline below for details'),
|
||||
'fieldname': 'supplier',
|
||||
'non_standard_fieldnames': {
|
||||
'Payment Entry': 'party_name'
|
||||
'Payment Entry': 'party_name',
|
||||
'Bank Account': 'party'
|
||||
},
|
||||
'transactions': [
|
||||
{
|
||||
@@ -24,6 +25,10 @@ def get_data():
|
||||
'label': _('Payments'),
|
||||
'items': ['Payment Entry']
|
||||
},
|
||||
{
|
||||
'label': _('Bank'),
|
||||
'items': ['Bank Account']
|
||||
},
|
||||
{
|
||||
'label': _('Pricing'),
|
||||
'items': ['Pricing Rule']
|
||||
|
||||
@@ -4,15 +4,17 @@
|
||||
// attach required files
|
||||
{% include 'erpnext/public/js/controllers/buying.js' %};
|
||||
|
||||
frappe.ui.form.on('Suppier Quotation', {
|
||||
setup: function(frm) {
|
||||
frm.custom_make_buttons = {
|
||||
'Purchase Order': 'Purchase Order'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.extend({
|
||||
setup: function() {
|
||||
this.frm.custom_make_buttons = {
|
||||
'Purchase Order': 'Purchase Order',
|
||||
'Quotation': 'Quotation',
|
||||
'Subscription': 'Subscription'
|
||||
}
|
||||
|
||||
this._super();
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
var me = this;
|
||||
this._super();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "hash",
|
||||
"creation": "2013-05-22 12:43:10",
|
||||
"doctype": "DocType",
|
||||
@@ -522,8 +523,7 @@
|
||||
{
|
||||
"fieldname": "manufacturer_part_no",
|
||||
"fieldtype": "Data",
|
||||
"label": "Manufacturer Part Number",
|
||||
"read_only": 1
|
||||
"label": "Manufacturer Part Number"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_15",
|
||||
@@ -532,7 +532,8 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2019-06-02 05:32:46.019237",
|
||||
"links": [],
|
||||
"modified": "2020-04-07 18:35:51.175947",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation Item",
|
||||
|
||||
@@ -141,13 +141,13 @@ def get_conditions(filters):
|
||||
conditions = ""
|
||||
|
||||
if filters.get("company"):
|
||||
conditions += " AND company='%s'"% filters.get('company')
|
||||
conditions += " AND company=%s"% frappe.db.escape(filters.get('company'))
|
||||
|
||||
if filters.get("cost_center") or filters.get("project"):
|
||||
conditions += """
|
||||
AND (cost_center='%s'
|
||||
OR project='%s')
|
||||
"""% (filters.get('cost_center'), filters.get('project'))
|
||||
AND (cost_center=%s
|
||||
OR project=%s)
|
||||
"""% (frappe.db.escape(filters.get('cost_center')), frappe.db.escape(filters.get('project')))
|
||||
|
||||
if filters.get("from_date"):
|
||||
conditions += " AND transaction_date>=%s"% filters.get('from_date')
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user