mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-25 16:04:46 +00:00
Merge branch 'develop' into payment_entry_validations_and_trigger_develop
This commit is contained in:
@@ -154,7 +154,8 @@
|
|||||||
"before": true,
|
"before": true,
|
||||||
"beforeEach": true,
|
"beforeEach": true,
|
||||||
"onScan": true,
|
"onScan": true,
|
||||||
|
"html2canvas": true,
|
||||||
"extend_cscript": true,
|
"extend_cscript": true,
|
||||||
"localforage": true,
|
"localforage": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,3 +13,6 @@
|
|||||||
|
|
||||||
# This commit just changes spaces to tabs for indentation in some files
|
# This commit just changes spaces to tabs for indentation in some files
|
||||||
5f473611bd6ed57703716244a054d3fb5ba9cd23
|
5f473611bd6ed57703716244a054d3fb5ba9cd23
|
||||||
|
|
||||||
|
# Whitespace fix throughout codebase
|
||||||
|
4551d7d6029b6f587f6c99d4f8df5519241c6a86
|
||||||
|
|||||||
12
.github/helper/documentation.py
vendored
12
.github/helper/documentation.py
vendored
@@ -32,11 +32,15 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
if response.ok:
|
if response.ok:
|
||||||
payload = response.json()
|
payload = response.json()
|
||||||
title = payload.get("title", "").lower()
|
title = (payload.get("title") or "").lower().strip()
|
||||||
head_sha = payload.get("head", {}).get("sha")
|
head_sha = (payload.get("head") or {}).get("sha")
|
||||||
body = payload.get("body", "").lower()
|
body = (payload.get("body") or "").lower()
|
||||||
|
|
||||||
if title.startswith("feat") and head_sha and "no-docs" not in body:
|
if (title.startswith("feat")
|
||||||
|
and head_sha
|
||||||
|
and "no-docs" not in body
|
||||||
|
and "backport" not in body
|
||||||
|
):
|
||||||
if docs_link_exists(body):
|
if docs_link_exists(body):
|
||||||
print("Documentation Link Found. You're Awesome! 🎉")
|
print("Documentation Link Found. You're Awesome! 🎉")
|
||||||
|
|
||||||
|
|||||||
8
.github/workflows/patch.yml
vendored
8
.github/workflows/patch.yml
vendored
@@ -1,6 +1,12 @@
|
|||||||
name: Patch
|
name: Patch
|
||||||
|
|
||||||
on: [pull_request, workflow_dispatch]
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.js'
|
||||||
|
- '**.md'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
|
|||||||
6
.github/workflows/server-tests.yml
vendored
6
.github/workflows/server-tests.yml
vendored
@@ -2,9 +2,15 @@ name: Server
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.js'
|
||||||
|
- '**.md'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ develop ]
|
branches: [ develop ]
|
||||||
|
paths-ignore:
|
||||||
|
- '**.js'
|
||||||
|
- '**.md'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
|
|||||||
4
.github/workflows/ui-tests.yml
vendored
4
.github/workflows/ui-tests.yml
vendored
@@ -2,6 +2,8 @@ name: UI
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -102,7 +104,7 @@ jobs:
|
|||||||
- name: UI Tests
|
- name: UI Tests
|
||||||
run: cd ~/frappe-bench/ && bench --site test_site run-ui-tests erpnext --headless
|
run: cd ~/frappe-bench/ && bench --site test_site run-ui-tests erpnext --headless
|
||||||
env:
|
env:
|
||||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
CYPRESS_RECORD_KEY: 60a8e3bf-08f5-45b1-9269-2b207d7d30cd
|
||||||
|
|
||||||
- name: Show bench console if tests failed
|
- name: Show bench console if tests failed
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
|
|||||||
113
cypress/integration/test_organizational_chart_desktop.js
Normal file
113
cypress/integration/test_organizational_chart_desktop.js
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
context('Organizational Chart', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.login();
|
||||||
|
cy.visit('/app/website');
|
||||||
|
cy.awesomebar('Organizational Chart');
|
||||||
|
cy.wait(500);
|
||||||
|
cy.url().should('include', '/organizational-chart');
|
||||||
|
|
||||||
|
cy.window().its('frappe.csrf_token').then(csrf_token => {
|
||||||
|
return cy.request({
|
||||||
|
url: `/api/method/erpnext.tests.ui_test_helpers.create_employee_records`,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Frappe-CSRF-Token': csrf_token
|
||||||
|
},
|
||||||
|
timeout: 60000
|
||||||
|
}).then(res => {
|
||||||
|
expect(res.status).eq(200);
|
||||||
|
cy.get('.frappe-control[data-fieldname=company] input').focus().as('input');
|
||||||
|
cy.get('@input')
|
||||||
|
.clear({ force: true })
|
||||||
|
.type('Test Org Chart{enter}', { force: true })
|
||||||
|
.blur({ force: true });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders root nodes and loads children for the first expandable node', () => {
|
||||||
|
// check rendered root nodes and the node name, title, connections
|
||||||
|
cy.get('.hierarchy').find('.root-level ul.node-children').children()
|
||||||
|
.should('have.length', 2)
|
||||||
|
.first()
|
||||||
|
.as('first-child');
|
||||||
|
|
||||||
|
cy.get('@first-child').get('.node-name').contains('Test Employee 1');
|
||||||
|
cy.get('@first-child').get('.node-info').find('.node-title').contains('CEO');
|
||||||
|
cy.get('@first-child').get('.node-info').find('.node-connections').contains('· 2 Connections');
|
||||||
|
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(employee_records => {
|
||||||
|
// children of 1st root visible
|
||||||
|
cy.get(`div[data-parent="${employee_records.message[0]}"]`).as('child-node');
|
||||||
|
cy.get('@child-node')
|
||||||
|
.should('have.length', 1)
|
||||||
|
.should('be.visible');
|
||||||
|
cy.get('@child-node').get('.node-name').contains('Test Employee 3');
|
||||||
|
|
||||||
|
// connectors between first root node and immediate child
|
||||||
|
cy.get(`path[data-parent="${employee_records.message[0]}"]`)
|
||||||
|
.should('be.visible')
|
||||||
|
.invoke('attr', 'data-child')
|
||||||
|
.should('equal', employee_records.message[2]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('hides active nodes children and connectors on expanding sibling node', () => {
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(employee_records => {
|
||||||
|
// click sibling
|
||||||
|
cy.get(`#${employee_records.message[1]}`)
|
||||||
|
.click()
|
||||||
|
.should('have.class', 'active');
|
||||||
|
|
||||||
|
// child nodes and connectors hidden
|
||||||
|
cy.get(`[data-parent="${employee_records.message[0]}"]`).should('not.be.visible');
|
||||||
|
cy.get(`path[data-parent="${employee_records.message[0]}"]`).should('not.be.visible');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('collapses previous level nodes and refreshes connectors on expanding child node', () => {
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(employee_records => {
|
||||||
|
// click child node
|
||||||
|
cy.get(`#${employee_records.message[3]}`)
|
||||||
|
.click()
|
||||||
|
.should('have.class', 'active');
|
||||||
|
|
||||||
|
// previous level nodes: parent should be on active-path; other nodes should be collapsed
|
||||||
|
cy.get(`#${employee_records.message[0]}`).should('have.class', 'collapsed');
|
||||||
|
cy.get(`#${employee_records.message[1]}`).should('have.class', 'active-path');
|
||||||
|
|
||||||
|
// previous level connectors refreshed
|
||||||
|
cy.get(`path[data-parent="${employee_records.message[1]}"]`)
|
||||||
|
.should('have.class', 'collapsed-connector');
|
||||||
|
|
||||||
|
// child node's children and connectors rendered
|
||||||
|
cy.get(`[data-parent="${employee_records.message[3]}"]`).should('be.visible');
|
||||||
|
cy.get(`path[data-parent="${employee_records.message[3]}"]`).should('be.visible');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('expands previous level nodes', () => {
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(employee_records => {
|
||||||
|
cy.get(`#${employee_records.message[0]}`)
|
||||||
|
.click()
|
||||||
|
.should('have.class', 'active');
|
||||||
|
|
||||||
|
cy.get(`[data-parent="${employee_records.message[0]}"]`)
|
||||||
|
.should('be.visible');
|
||||||
|
|
||||||
|
cy.get('ul.hierarchy').children().should('have.length', 2);
|
||||||
|
cy.get(`#connectors`).children().should('have.length', 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('edit node navigates to employee master', () => {
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(employee_records => {
|
||||||
|
cy.get(`#${employee_records.message[0]}`).find('.btn-edit-node')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.url().should('include', `/employee/${employee_records.message[0]}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
190
cypress/integration/test_organizational_chart_mobile.js
Normal file
190
cypress/integration/test_organizational_chart_mobile.js
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
context('Organizational Chart Mobile', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.login();
|
||||||
|
cy.viewport(375, 667);
|
||||||
|
cy.visit('/app/website');
|
||||||
|
cy.awesomebar('Organizational Chart');
|
||||||
|
|
||||||
|
cy.window().its('frappe.csrf_token').then(csrf_token => {
|
||||||
|
return cy.request({
|
||||||
|
url: `/api/method/erpnext.tests.ui_test_helpers.create_employee_records`,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Frappe-CSRF-Token': csrf_token
|
||||||
|
},
|
||||||
|
timeout: 60000
|
||||||
|
}).then(res => {
|
||||||
|
expect(res.status).eq(200);
|
||||||
|
cy.get('.frappe-control[data-fieldname=company] input').focus().as('input');
|
||||||
|
cy.get('@input')
|
||||||
|
.clear({ force: true })
|
||||||
|
.type('Test Org Chart{enter}', { force: true })
|
||||||
|
.blur({ force: true });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders root nodes', () => {
|
||||||
|
// check rendered root nodes and the node name, title, connections
|
||||||
|
cy.get('.hierarchy-mobile').find('.root-level').children()
|
||||||
|
.should('have.length', 2)
|
||||||
|
.first()
|
||||||
|
.as('first-child');
|
||||||
|
|
||||||
|
cy.get('@first-child').get('.node-name').contains('Test Employee 1');
|
||||||
|
cy.get('@first-child').get('.node-info').find('.node-title').contains('CEO');
|
||||||
|
cy.get('@first-child').get('.node-info').find('.node-connections').contains('· 2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('expands root node', () => {
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(employee_records => {
|
||||||
|
cy.get(`#${employee_records.message[1]}`)
|
||||||
|
.click()
|
||||||
|
.should('have.class', 'active');
|
||||||
|
|
||||||
|
// other root node removed
|
||||||
|
cy.get(`#${employee_records.message[0]}`).should('not.exist');
|
||||||
|
|
||||||
|
// children of active root node
|
||||||
|
cy.get('.hierarchy-mobile').find('.level').first().find('ul.node-children').children()
|
||||||
|
.should('have.length', 2);
|
||||||
|
|
||||||
|
cy.get(`div[data-parent="${employee_records.message[1]}"]`).first().as('child-node');
|
||||||
|
cy.get('@child-node').should('be.visible');
|
||||||
|
|
||||||
|
cy.get('@child-node')
|
||||||
|
.get('.node-name')
|
||||||
|
.contains('Test Employee 4');
|
||||||
|
|
||||||
|
// connectors between root node and immediate children
|
||||||
|
cy.get(`path[data-parent="${employee_records.message[1]}"]`).as('connectors');
|
||||||
|
cy.get('@connectors')
|
||||||
|
.should('have.length', 2)
|
||||||
|
.should('be.visible');
|
||||||
|
|
||||||
|
cy.get('@connectors')
|
||||||
|
.first()
|
||||||
|
.invoke('attr', 'data-child')
|
||||||
|
.should('eq', employee_records.message[3]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('expands child node', () => {
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(employee_records => {
|
||||||
|
cy.get(`#${employee_records.message[3]}`)
|
||||||
|
.click()
|
||||||
|
.should('have.class', 'active')
|
||||||
|
.as('expanded_node');
|
||||||
|
|
||||||
|
// 2 levels on screen; 1 on active path; 1 collapsed
|
||||||
|
cy.get('.hierarchy-mobile').children().should('have.length', 2);
|
||||||
|
cy.get(`#${employee_records.message[1]}`).should('have.class', 'active-path');
|
||||||
|
|
||||||
|
// children of expanded node visible
|
||||||
|
cy.get('@expanded_node')
|
||||||
|
.next()
|
||||||
|
.should('have.class', 'node-children')
|
||||||
|
.as('node-children');
|
||||||
|
|
||||||
|
cy.get('@node-children').children().should('have.length', 1);
|
||||||
|
cy.get('@node-children')
|
||||||
|
.first()
|
||||||
|
.get('.node-card')
|
||||||
|
.should('have.class', 'active-child')
|
||||||
|
.contains('Test Employee 7');
|
||||||
|
|
||||||
|
// orphan connectors removed
|
||||||
|
cy.get(`#connectors`).children().should('have.length', 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders sibling group', () => {
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(employee_records => {
|
||||||
|
// sibling group visible for parent
|
||||||
|
cy.get(`#${employee_records.message[1]}`)
|
||||||
|
.next()
|
||||||
|
.as('sibling_group');
|
||||||
|
|
||||||
|
cy.get('@sibling_group')
|
||||||
|
.should('have.attr', 'data-parent', 'undefined')
|
||||||
|
.should('have.class', 'node-group')
|
||||||
|
.and('have.class', 'collapsed');
|
||||||
|
|
||||||
|
cy.get('@sibling_group').get('.avatar-group').children().as('siblings');
|
||||||
|
cy.get('@siblings').should('have.length', 1);
|
||||||
|
cy.get('@siblings')
|
||||||
|
.first()
|
||||||
|
.should('have.attr', 'title', 'Test Employee 1');
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('expands previous level nodes', () => {
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(employee_records => {
|
||||||
|
cy.get(`#${employee_records.message[6]}`)
|
||||||
|
.click()
|
||||||
|
.should('have.class', 'active');
|
||||||
|
|
||||||
|
// clicking on previous level node should remove all the nodes ahead
|
||||||
|
// and expand that node
|
||||||
|
cy.get(`#${employee_records.message[3]}`).click();
|
||||||
|
cy.get(`#${employee_records.message[3]}`)
|
||||||
|
.should('have.class', 'active')
|
||||||
|
.should('not.have.class', 'active-path');
|
||||||
|
|
||||||
|
cy.get(`#${employee_records.message[6]}`).should('have.class', 'active-child');
|
||||||
|
cy.get('.hierarchy-mobile').children().should('have.length', 2);
|
||||||
|
cy.get(`#connectors`).children().should('have.length', 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('expands sibling group', () => {
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(employee_records => {
|
||||||
|
// sibling group visible for parent
|
||||||
|
cy.get(`#${employee_records.message[6]}`).click();
|
||||||
|
|
||||||
|
cy.get(`#${employee_records.message[3]}`)
|
||||||
|
.next()
|
||||||
|
.click();
|
||||||
|
|
||||||
|
// siblings of parent should be visible
|
||||||
|
cy.get('.hierarchy-mobile').prev().as('sibling_group');
|
||||||
|
cy.get('@sibling_group')
|
||||||
|
.should('exist')
|
||||||
|
.should('have.class', 'sibling-group')
|
||||||
|
.should('not.have.class', 'collapsed');
|
||||||
|
|
||||||
|
cy.get(`#${employee_records.message[1]}`)
|
||||||
|
.should('be.visible')
|
||||||
|
.should('have.class', 'active');
|
||||||
|
|
||||||
|
cy.get(`[data-parent="${employee_records.message[1]}"]`)
|
||||||
|
.should('be.visible')
|
||||||
|
.should('have.length', 2)
|
||||||
|
.should('have.class', 'active-child');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('goes to the respective level after clicking on non-collapsed sibling group', () => {
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(() => {
|
||||||
|
// click on non-collapsed sibling group
|
||||||
|
cy.get('.hierarchy-mobile')
|
||||||
|
.prev()
|
||||||
|
.click();
|
||||||
|
|
||||||
|
// should take you to that level
|
||||||
|
cy.get('.hierarchy-mobile').find('li.level .node-card').should('have.length', 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('edit node navigates to employee master', () => {
|
||||||
|
cy.call('erpnext.tests.ui_test_helpers.get_employee_records').then(employee_records => {
|
||||||
|
cy.get(`#${employee_records.message[0]}`).find('.btn-edit-node')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.url().should('include', `/employee/${employee_records.message[0]}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -6,4 +6,4 @@
|
|||||||
"scss/at-rule-no-unknown": true,
|
"scss/at-rule-no-unknown": true,
|
||||||
"no-descending-specificity": null
|
"no-descending-specificity": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import frappe
|
|||||||
from erpnext.hooks import regional_overrides
|
from erpnext.hooks import regional_overrides
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
|
|
||||||
__version__ = '13.8.0'
|
__version__ = '13.9.0'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
|||||||
@@ -19,4 +19,4 @@ frappe.dashboards.chart_sources["Account Balance Timeline"] = {
|
|||||||
reqd: 1
|
reqd: 1
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -450,5 +450,3 @@ def get_deferred_booking_accounts(doctype, voucher_detail_no, dr_or_cr):
|
|||||||
return debit_account
|
return debit_account
|
||||||
else:
|
else:
|
||||||
return credit_account
|
return credit_account
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -60,4 +60,4 @@ frappe.ui.form.on('Accounting Dimension Detail', {
|
|||||||
let row = locals[cdt][cdn];
|
let row = locals[cdt][cdn];
|
||||||
row.reference_document = frm.doc.document_type;
|
row.reference_document = frm.doc.document_type;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -113,5 +113,3 @@ def disable_dimension():
|
|||||||
dimension2 = frappe.get_doc("Accounting Dimension", "Location")
|
dimension2 = frappe.get_doc("Accounting Dimension", "Location")
|
||||||
dimension2.disabled = 1
|
dimension2.disabled = 1
|
||||||
dimension2.save()
|
dimension2.save()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -79,4 +79,4 @@ frappe.ui.form.on('Allowed Dimension', {
|
|||||||
row.accounting_dimension = frm.doc.accounting_dimension;
|
row.accounting_dimension = frm.doc.accounting_dimension;
|
||||||
frm.refresh_field("dimensions");
|
frm.refresh_field("dimensions");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -56,4 +56,4 @@ class AccountingPeriod(Document):
|
|||||||
self.append('closed_documents', {
|
self.append('closed_documents', {
|
||||||
"document_type": doctype_for_closing.document_type,
|
"document_type": doctype_for_closing.document_type,
|
||||||
"closed": doctype_for_closing.closed
|
"closed": doctype_for_closing.closed
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -48,4 +48,4 @@ frappe.tour['Accounts Settings'] = [
|
|||||||
title: "Unlink Advance Payment on Cancellation of Order",
|
title: "Unlink Advance Payment on Cancellation of Order",
|
||||||
description: __("Similar to the previous option, this unlinks any advance payments made against Purchase/Sales Orders.")
|
description: __("Similar to the previous option, this unlinks any advance payments made against Purchase/Sales Orders.")
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
"book_asset_depreciation_entry_automatically",
|
"book_asset_depreciation_entry_automatically",
|
||||||
"unlink_advance_payment_on_cancelation_of_order",
|
"unlink_advance_payment_on_cancelation_of_order",
|
||||||
"post_change_gl_entries",
|
"post_change_gl_entries",
|
||||||
|
"enable_discount_accounting",
|
||||||
"tax_settings_section",
|
"tax_settings_section",
|
||||||
"determine_address_tax_category_from",
|
"determine_address_tax_category_from",
|
||||||
"column_break_19",
|
"column_break_19",
|
||||||
@@ -260,6 +261,13 @@
|
|||||||
"fieldname": "post_change_gl_entries",
|
"fieldname": "post_change_gl_entries",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Create Ledger Entries for Change Amount"
|
"label": "Create Ledger Entries for Change Amount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"description": "If enabled, additional ledger entries will be made for discounts in a separate Discount Account",
|
||||||
|
"fieldname": "enable_discount_accounting",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Enable Discount Accounting"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "icon-cog",
|
"icon": "icon-cog",
|
||||||
@@ -267,7 +275,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-08-09 13:08:01.335416",
|
"modified": "2021-08-09 13:08:04.335416",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class AccountsSettings(Document):
|
|||||||
|
|
||||||
self.validate_stale_days()
|
self.validate_stale_days()
|
||||||
self.enable_payment_schedule_in_print()
|
self.enable_payment_schedule_in_print()
|
||||||
|
self.toggle_discount_accounting_fields()
|
||||||
|
|
||||||
def validate_stale_days(self):
|
def validate_stale_days(self):
|
||||||
if not self.allow_stale and cint(self.stale_days) <= 0:
|
if not self.allow_stale and cint(self.stale_days) <= 0:
|
||||||
@@ -33,3 +34,22 @@ class AccountsSettings(Document):
|
|||||||
for doctype in ("Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"):
|
for doctype in ("Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"):
|
||||||
make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check", validate_fields_for_doctype=False)
|
make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check", validate_fields_for_doctype=False)
|
||||||
make_property_setter(doctype, "payment_schedule", "print_hide", 0 if show_in_print else 1, "Check", validate_fields_for_doctype=False)
|
make_property_setter(doctype, "payment_schedule", "print_hide", 0 if show_in_print else 1, "Check", validate_fields_for_doctype=False)
|
||||||
|
|
||||||
|
def toggle_discount_accounting_fields(self):
|
||||||
|
enable_discount_accounting = cint(self.enable_discount_accounting)
|
||||||
|
|
||||||
|
for doctype in ["Sales Invoice Item", "Purchase Invoice Item"]:
|
||||||
|
make_property_setter(doctype, "discount_account", "hidden", not(enable_discount_accounting), "Check", validate_fields_for_doctype=False)
|
||||||
|
if enable_discount_accounting:
|
||||||
|
make_property_setter(doctype, "discount_account", "mandatory_depends_on", "eval: doc.discount_amount", "Code", validate_fields_for_doctype=False)
|
||||||
|
else:
|
||||||
|
make_property_setter(doctype, "discount_account", "mandatory_depends_on", "", "Code", validate_fields_for_doctype=False)
|
||||||
|
|
||||||
|
for doctype in ["Sales Invoice", "Purchase Invoice"]:
|
||||||
|
make_property_setter(doctype, "additional_discount_account", "hidden", not(enable_discount_accounting), "Check", validate_fields_for_doctype=False)
|
||||||
|
if enable_discount_accounting:
|
||||||
|
make_property_setter(doctype, "additional_discount_account", "mandatory_depends_on", "eval: doc.discount_amount", "Code", validate_fields_for_doctype=False)
|
||||||
|
else:
|
||||||
|
make_property_setter(doctype, "additional_discount_account", "mandatory_depends_on", "", "Code", validate_fields_for_doctype=False)
|
||||||
|
|
||||||
|
make_property_setter("Item", "default_discount_account", "hidden", not(enable_discount_accounting), "Check", validate_fields_for_doctype=False)
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ frappe.ui.form.on('Accounts Settings', {
|
|||||||
frm.set_df_property("frozen_accounts_modifier", "label", "Role Allowed to Close Books & Make Changes to Closed Periods");
|
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");
|
frm.set_df_property("credit_controller", "label", "Credit Manager");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -120,4 +120,4 @@ erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {
|
|||||||
plaid_success(token, response) {
|
plaid_success(token, response) {
|
||||||
frappe.show_alert({ message: __('Plaid Link Updated'), indicator: 'green' });
|
frappe.show_alert({ message: __('Plaid Link Updated'), indicator: 'green' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ class Bank(Document):
|
|||||||
load_address_and_contact(self)
|
load_address_and_contact(self)
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
delete_contact_and_address('Bank', self.name)
|
delete_contact_and_address('Bank', self.name)
|
||||||
|
|||||||
@@ -26,4 +26,4 @@ def get_data():
|
|||||||
'items': ['Journal Entry']
|
'items': ['Journal Entry']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ frappe.ui.form.on("Bank Clearance", {
|
|||||||
|
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
|
|
||||||
let default_bank_account = frappe.defaults.get_user_default("Company")?
|
let default_bank_account = frappe.defaults.get_user_default("Company")?
|
||||||
locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"]: "";
|
locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"]: "";
|
||||||
frm.set_value("account", default_bank_account);
|
frm.set_value("account", default_bank_account);
|
||||||
|
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ import frappe
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class BankClearanceDetail(Document):
|
class BankClearanceDetail(Document):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -25,6 +25,6 @@ class BankGuarantee(Document):
|
|||||||
def get_vouchar_detials(column_list, doctype, docname):
|
def get_vouchar_detials(column_list, doctype, docname):
|
||||||
column_list = json.loads(column_list)
|
column_list = json.loads(column_list)
|
||||||
for col in column_list:
|
for col in column_list:
|
||||||
sanitize_searchfield(col)
|
sanitize_searchfield(col)
|
||||||
return frappe.db.sql(''' select {columns} from `tab{doctype}` where name=%s'''
|
return frappe.db.sql(''' select {columns} from `tab{doctype}` where name=%s'''
|
||||||
.format(columns=", ".join(column_list), doctype=doctype), docname, as_dict=1)[0]
|
.format(columns=", ".join(column_list), doctype=doctype), docname, as_dict=1)[0]
|
||||||
|
|||||||
@@ -105,4 +105,3 @@ def unclear_reference_payment(doctype, docname):
|
|||||||
frappe.db.set_value(doc.payment_document, doc.payment_entry, "clearance_date", None)
|
frappe.db.set_value(doc.payment_document, doc.payment_entry, "clearance_date", None)
|
||||||
|
|
||||||
return doc.payment_entry
|
return doc.payment_entry
|
||||||
|
|
||||||
|
|||||||
@@ -10,4 +10,4 @@ frappe.listview_settings['Bank Transaction'] = {
|
|||||||
return [__("Reconciled"), "green", "unallocated_amount,=,0"];
|
return [__("Reconciled"), "green", "unallocated_amount,=,0"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -77,4 +77,4 @@ def get_bank_mapping(bank_account):
|
|||||||
|
|
||||||
mapping = {row.file_field:row.bank_transaction_field for row in bank.bank_transaction_mapping}
|
mapping = {row.file_field:row.bank_transaction_field for row in bank.bank_transaction_mapping}
|
||||||
|
|
||||||
return mapping
|
return mapping
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ import frappe
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class CFormInvoiceDetail(Document):
|
class CFormInvoiceDetail(Document):
|
||||||
pass
|
pass
|
||||||
|
|||||||
31
erpnext/accounts/doctype/campaign_item/campaign_item.json
Normal file
31
erpnext/accounts/doctype/campaign_item/campaign_item.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"creation": "2021-05-06 16:18:25.410476",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"campaign"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "campaign",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Campaign",
|
||||||
|
"options": "Campaign"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2021-05-07 10:43:49.717633",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Campaign Item",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
||||||
8
erpnext/accounts/doctype/campaign_item/campaign_item.py
Normal file
8
erpnext/accounts/doctype/campaign_item/campaign_item.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class CampaignItem(Document):
|
||||||
|
pass
|
||||||
@@ -18,5 +18,3 @@ class CashFlowMapping(Document):
|
|||||||
frappe._('You can only select a maximum of one option from the list of check boxes.'),
|
frappe._('You can only select a maximum of one option from the list of check boxes.'),
|
||||||
title='Error'
|
title='Error'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,4 +33,4 @@ class CashierClosing(Document):
|
|||||||
|
|
||||||
def validate_time(self):
|
def validate_time(self):
|
||||||
if self.from_time >= self.time:
|
if self.from_time >= self.time:
|
||||||
frappe.throw(_("From Time Should Be Less Than To Time"))
|
frappe.throw(_("From Time Should Be Less Than To Time"))
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ frappe.ui.form.on('Cheque Print Template', {
|
|||||||
function() {
|
function() {
|
||||||
erpnext.cheque_print.view_cheque_print(frm);
|
erpnext.cheque_print.view_cheque_print(frm);
|
||||||
}).addClass("btn-primary");
|
}).addClass("btn-primary");
|
||||||
|
|
||||||
$(frm.fields_dict.cheque_print_preview.wrapper).empty()
|
$(frm.fields_dict.cheque_print_preview.wrapper).empty()
|
||||||
|
|
||||||
|
|
||||||
var template = '<div style="position: relative; overflow-x: scroll;">\
|
var template = '<div style="position: relative; overflow-x: scroll;">\
|
||||||
<div id="cheque_preview" style="width: {{ cheque_width }}cm; \
|
<div id="cheque_preview" style="width: {{ cheque_width }}cm; \
|
||||||
height: {{ cheque_height }}cm;\
|
height: {{ cheque_height }}cm;\
|
||||||
@@ -47,9 +47,9 @@ frappe.ui.form.on('Cheque Print Template', {
|
|||||||
position: absolute;"> Signatory Name </span>\
|
position: absolute;"> Signatory Name </span>\
|
||||||
</div>\
|
</div>\
|
||||||
</div>';
|
</div>';
|
||||||
|
|
||||||
$(frappe.render(template, frm.doc)).appendTo(frm.fields_dict.cheque_print_preview.wrapper)
|
$(frappe.render(template, frm.doc)).appendTo(frm.fields_dict.cheque_print_preview.wrapper)
|
||||||
|
|
||||||
if (frm.doc.scanned_cheque) {
|
if (frm.doc.scanned_cheque) {
|
||||||
$(frm.fields_dict.cheque_print_preview.wrapper).find("#cheque_preview").css('background-image', 'url(' + frm.doc.scanned_cheque + ')');
|
$(frm.fields_dict.cheque_print_preview.wrapper).find("#cheque_preview").css('background-image', 'url(' + frm.doc.scanned_cheque + ')');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,4 +129,4 @@ def get_name_with_number(new_account, account_number):
|
|||||||
|
|
||||||
def check_if_distributed_cost_center_enabled(cost_center_list):
|
def check_if_distributed_cost_center_enabled(cost_center_list):
|
||||||
value_list = frappe.get_list("Cost Center", {"name": ["in", cost_center_list]}, "enable_distributed_cost_center", as_list=1)
|
value_list = frappe.get_list("Cost Center", {"name": ["in", cost_center_list]}, "enable_distributed_cost_center", as_list=1)
|
||||||
return next((True for x in value_list if x[0]), False)
|
return next((True for x in value_list if x[0]), False)
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ def get_data():
|
|||||||
'items': ['Budget Variance Report', 'General Ledger']
|
'items': ['Budget Variance Report', 'General Ledger']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,4 +51,4 @@ frappe.treeview_settings["Cost Center"] = {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,3 @@ def create_cost_center(**args):
|
|||||||
cc.is_group = args.is_group or 0
|
cc.is_group = args.is_group or 0
|
||||||
cc.parent_cost_center = args.parent_cost_center or "_Test Company - _TC"
|
cc.parent_cost_center = args.parent_cost_center or "_Test Company - _TC"
|
||||||
cc.insert()
|
cc.insert()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class CouponCode(Document):
|
|||||||
self.coupon_code =''.join(i for i in self.coupon_name if not i.isdigit())[0:8].upper()
|
self.coupon_code =''.join(i for i in self.coupon_name if not i.isdigit())[0:8].upper()
|
||||||
elif self.coupon_type == "Gift Card":
|
elif self.coupon_type == "Gift Card":
|
||||||
self.coupon_code = frappe.generate_hash()[:10].upper()
|
self.coupon_code = frappe.generate_hash()[:10].upper()
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if self.coupon_type == "Gift Card":
|
if self.coupon_type == "Gift Card":
|
||||||
self.maximum_use = 1
|
self.maximum_use = 1
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ def test_create_test_data():
|
|||||||
})
|
})
|
||||||
item_price.insert()
|
item_price.insert()
|
||||||
# create test item pricing rule
|
# create test item pricing rule
|
||||||
if not frappe.db.exists("Pricing Rule","_Test Pricing Rule for _Test Item"):
|
if not frappe.db.exists("Pricing Rule", {"title": "_Test Pricing Rule for _Test Item"}):
|
||||||
item_pricing_rule = frappe.get_doc({
|
item_pricing_rule = frappe.get_doc({
|
||||||
"doctype": "Pricing Rule",
|
"doctype": "Pricing Rule",
|
||||||
"title": "_Test Pricing Rule for _Test Item",
|
"title": "_Test Pricing Rule for _Test Item",
|
||||||
@@ -86,14 +86,15 @@ def test_create_test_data():
|
|||||||
sales_partner.insert()
|
sales_partner.insert()
|
||||||
# create test item coupon code
|
# create test item coupon code
|
||||||
if not frappe.db.exists("Coupon Code", "SAVE30"):
|
if not frappe.db.exists("Coupon Code", "SAVE30"):
|
||||||
|
pricing_rule = frappe.db.get_value("Pricing Rule", {"title": "_Test Pricing Rule for _Test Item"}, ['name'])
|
||||||
coupon_code = frappe.get_doc({
|
coupon_code = frappe.get_doc({
|
||||||
"doctype": "Coupon Code",
|
"doctype": "Coupon Code",
|
||||||
"coupon_name":"SAVE30",
|
"coupon_name":"SAVE30",
|
||||||
"coupon_code":"SAVE30",
|
"coupon_code":"SAVE30",
|
||||||
"pricing_rule": "_Test Pricing Rule for _Test Item",
|
"pricing_rule": pricing_rule,
|
||||||
"valid_from": "2014-01-01",
|
"valid_from": "2014-01-01",
|
||||||
"maximum_use":1,
|
"maximum_use":1,
|
||||||
"used":0
|
"used":0
|
||||||
})
|
})
|
||||||
coupon_code.insert()
|
coupon_code.insert()
|
||||||
|
|
||||||
@@ -102,7 +103,7 @@ class TestCouponCode(unittest.TestCase):
|
|||||||
test_create_test_data()
|
test_create_test_data()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
frappe.set_user("Administrator")
|
frappe.set_user("Administrator")
|
||||||
|
|
||||||
def test_sales_order_with_coupon_code(self):
|
def test_sales_order_with_coupon_code(self):
|
||||||
frappe.db.set_value("Coupon Code", "SAVE30", "used", 0)
|
frappe.db.set_value("Coupon Code", "SAVE30", "used", 0)
|
||||||
@@ -123,6 +124,3 @@ class TestCouponCode(unittest.TestCase):
|
|||||||
|
|
||||||
so.submit()
|
so.submit()
|
||||||
self.assertEqual(frappe.db.get_value("Coupon Code", "SAVE30", "used"), 1)
|
self.assertEqual(frappe.db.get_value("Coupon Code", "SAVE30", "used"), 1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"creation": "2021-05-06 16:12:42.558878",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"customer_group"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "customer_group",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Customer Group",
|
||||||
|
"options": "Customer Group"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2021-05-07 10:39:21.563506",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Customer Group Item",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class CustomerGroupItem(Document):
|
||||||
|
pass
|
||||||
31
erpnext/accounts/doctype/customer_item/customer_item.json
Normal file
31
erpnext/accounts/doctype/customer_item/customer_item.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"creation": "2021-05-05 14:04:54.266353",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"customer"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "customer",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Customer ",
|
||||||
|
"options": "Customer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2021-05-06 10:02:32.967841",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Customer Item",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
||||||
8
erpnext/accounts/doctype/customer_item/customer_item.py
Normal file
8
erpnext/accounts/doctype/customer_item/customer_item.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class CustomerItem(Document):
|
||||||
|
pass
|
||||||
@@ -7,4 +7,4 @@ from __future__ import unicode_literals
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class DiscountedInvoice(Document):
|
class DiscountedInvoice(Document):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ def get_data():
|
|||||||
'items': ['Payment Entry', 'Journal Entry']
|
'items': ['Payment Entry', 'Journal Entry']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,4 +143,4 @@ def create_dunning_type_with_zero_interest_rate():
|
|||||||
'closing_text': 'We kindly request that you pay the outstanding amount immediately, and late fees.'
|
'closing_text': 'We kindly request that you pay the outstanding amount immediately, and late fees.'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
dunning_type.save()
|
dunning_type.save()
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ frappe.ui.form.on('Exchange Rate Revaluation', {
|
|||||||
}, __('Create'));
|
}, __('Create'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -128,4 +128,4 @@ var get_account_details = function(frm, cdt, cdn) {
|
|||||||
frm.events.get_total_gain_loss(frm);
|
frm.events.get_total_gain_loss(frm);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class ExchangeRateRevaluation(Document):
|
|||||||
|
|
||||||
if total_amt != total_debit:
|
if total_amt != total_debit:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@@ -205,4 +205,4 @@ def get_account_details(account, company, posting_date, party_type=None, party=N
|
|||||||
"new_balance_in_base_currency": new_balance_in_base_currency
|
"new_balance_in_base_currency": new_balance_in_base_currency
|
||||||
}
|
}
|
||||||
|
|
||||||
return account_details
|
return account_details
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class TestFinanceBook(unittest.TestCase):
|
|||||||
finance_book = frappe.get_doc("Finance Book", "_Test Finance Book")
|
finance_book = frappe.get_doc("Finance Book", "_Test Finance Book")
|
||||||
|
|
||||||
return finance_book
|
return finance_book
|
||||||
|
|
||||||
def test_finance_book(self):
|
def test_finance_book(self):
|
||||||
finance_book = self.create_finance_book()
|
finance_book = self.create_finance_book()
|
||||||
|
|
||||||
|
|||||||
@@ -17,4 +17,4 @@ def get_data():
|
|||||||
'items': ['Payment Entry', 'Journal Entry']
|
'items': ['Payment Entry', 'Journal Entry']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,4 +18,4 @@ frappe.listview_settings['Invoice Discounting'] = {
|
|||||||
return [__("Canceled"), "red", "status,=,Canceled"];
|
return [__("Canceled"), "red", "status,=,Canceled"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ frappe.ui.form.on("Journal Entry", {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class TestJournalEntry(unittest.TestCase):
|
|||||||
"debit_in_account_currency": 0 if diff > 0 else abs(diff),
|
"debit_in_account_currency": 0 if diff > 0 else abs(diff),
|
||||||
"credit_in_account_currency": diff if diff > 0 else 0
|
"credit_in_account_currency": diff if diff > 0 else 0
|
||||||
})
|
})
|
||||||
|
|
||||||
jv.append("accounts", {
|
jv.append("accounts", {
|
||||||
"account": "Stock Adjustment - TCP1",
|
"account": "Stock Adjustment - TCP1",
|
||||||
"cost_center": "Main - TCP1",
|
"cost_center": "Main - TCP1",
|
||||||
|
|||||||
@@ -88,4 +88,4 @@ frappe.ui.form.on("Journal Entry Template", {
|
|||||||
frappe.model.clear_table(frm.doc, "accounts");
|
frappe.model.clear_table(frm.doc, "accounts");
|
||||||
frm.refresh_field("accounts");
|
frm.refresh_field("accounts");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ frappe.ui.form.on('Mode of Payment', {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -39,4 +39,3 @@ class ModeofPayment(Document):
|
|||||||
message = "POS Profile " + frappe.bold(", ".join(pos_profiles)) + " contains \
|
message = "POS Profile " + frappe.bold(", ".join(pos_profiles)) + " contains \
|
||||||
Mode of Payment " + frappe.bold(str(self.name)) + ". Please remove them to disable this mode."
|
Mode of Payment " + frappe.bold(str(self.name)) + ". Please remove them to disable this mode."
|
||||||
frappe.throw(_(message), title="Not Allowed")
|
frappe.throw(_(message), title="Not Allowed")
|
||||||
|
|
||||||
|
|||||||
@@ -55,4 +55,4 @@ def get_percentage(doc, start_date, period):
|
|||||||
if d.month in months:
|
if d.month in months:
|
||||||
percentage += d.percentage_allocation
|
percentage += d.percentage_allocation
|
||||||
|
|
||||||
return percentage
|
return percentage
|
||||||
|
|||||||
@@ -20,4 +20,4 @@ def get_data():
|
|||||||
'items': ['Budget']
|
'items': ['Budget']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,4 +162,4 @@ frappe.ui.form.on('Opening Invoice Creation Tool Item', {
|
|||||||
invoices_add: (frm) => {
|
invoices_add: (frm) => {
|
||||||
frm.trigger('update_invoice_table');
|
frm.trigger('update_invoice_table');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -241,4 +241,3 @@ def get_temporary_opening_account(company=None):
|
|||||||
frappe.throw(_("Please add a Temporary Opening account in Chart of Accounts"))
|
frappe.throw(_("Please add a Temporary Opening account in Chart of Accounts"))
|
||||||
|
|
||||||
return accounts[0].name
|
return accounts[0].name
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ class PaymentEntry(AccountsController):
|
|||||||
for field, value in iteritems(ref_details):
|
for field, value in iteritems(ref_details):
|
||||||
if d.exchange_gain_loss:
|
if d.exchange_gain_loss:
|
||||||
# for cases where gain/loss is booked into invoice
|
# for cases where gain/loss is booked into invoice
|
||||||
# exchange_gain_loss is calculated from invoice & populated
|
# exchange_gain_loss is calculated from invoice & populated
|
||||||
# and row.exchange_rate is already set to payment entry's exchange rate
|
# and row.exchange_rate is already set to payment entry's exchange rate
|
||||||
# refer -> `update_reference_in_payment_entry()` in utils.py
|
# refer -> `update_reference_in_payment_entry()` in utils.py
|
||||||
continue
|
continue
|
||||||
@@ -427,7 +427,7 @@ class PaymentEntry(AccountsController):
|
|||||||
net_total_for_tds = 0
|
net_total_for_tds = 0
|
||||||
if reference.reference_doctype == 'Purchase Order':
|
if reference.reference_doctype == 'Purchase Order':
|
||||||
net_total_for_tds += flt(frappe.db.get_value('Purchase Order', reference.reference_name, 'net_total'))
|
net_total_for_tds += flt(frappe.db.get_value('Purchase Order', reference.reference_name, 'net_total'))
|
||||||
|
|
||||||
if net_total_for_tds:
|
if net_total_for_tds:
|
||||||
net_total = net_total_for_tds
|
net_total = net_total_for_tds
|
||||||
|
|
||||||
@@ -548,7 +548,7 @@ class PaymentEntry(AccountsController):
|
|||||||
if self.payment_type == "Receive" \
|
if self.payment_type == "Receive" \
|
||||||
and self.base_total_allocated_amount < self.base_received_amount + total_deductions \
|
and self.base_total_allocated_amount < self.base_received_amount + total_deductions \
|
||||||
and self.total_allocated_amount < self.paid_amount + (total_deductions / self.source_exchange_rate):
|
and self.total_allocated_amount < self.paid_amount + (total_deductions / self.source_exchange_rate):
|
||||||
self.unallocated_amount = (self.received_amount + total_deductions -
|
self.unallocated_amount = (self.base_received_amount + total_deductions -
|
||||||
self.base_total_allocated_amount) / self.source_exchange_rate
|
self.base_total_allocated_amount) / self.source_exchange_rate
|
||||||
self.unallocated_amount -= included_taxes
|
self.unallocated_amount -= included_taxes
|
||||||
elif self.payment_type == "Pay" \
|
elif self.payment_type == "Pay" \
|
||||||
@@ -860,7 +860,7 @@ class PaymentEntry(AccountsController):
|
|||||||
|
|
||||||
if account_details:
|
if account_details:
|
||||||
row.update(account_details)
|
row.update(account_details)
|
||||||
|
|
||||||
if not row.get('amount'):
|
if not row.get('amount'):
|
||||||
# if no difference amount
|
# if no difference amount
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -11,4 +11,4 @@ frappe.listview_settings['Payment Entry'] = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -295,6 +295,34 @@ class TestPaymentEntry(unittest.TestCase):
|
|||||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||||
self.assertEqual(outstanding_amount, 80)
|
self.assertEqual(outstanding_amount, 80)
|
||||||
|
|
||||||
|
def test_payment_entry_against_si_usd_to_usd_with_deduction_in_base_currency (self):
|
||||||
|
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||||
|
currency="USD", conversion_rate=50, do_not_save=1)
|
||||||
|
|
||||||
|
si.plc_conversion_rate = 50
|
||||||
|
si.save()
|
||||||
|
si.submit()
|
||||||
|
|
||||||
|
pe = get_payment_entry("Sales Invoice", si.name, party_amount=20,
|
||||||
|
bank_account="_Test Bank USD - _TC", bank_amount=900)
|
||||||
|
|
||||||
|
pe.source_exchange_rate = 45.263
|
||||||
|
pe.target_exchange_rate = 45.263
|
||||||
|
pe.reference_no = "1"
|
||||||
|
pe.reference_date = "2016-01-01"
|
||||||
|
|
||||||
|
|
||||||
|
pe.append("deductions", {
|
||||||
|
"account": "_Test Exchange Gain/Loss - _TC",
|
||||||
|
"cost_center": "_Test Cost Center - _TC",
|
||||||
|
"amount": 94.80
|
||||||
|
})
|
||||||
|
|
||||||
|
pe.save()
|
||||||
|
|
||||||
|
self.assertEqual(flt(pe.difference_amount, 2), 0.0)
|
||||||
|
self.assertEqual(flt(pe.unallocated_amount, 2), 0.0)
|
||||||
|
|
||||||
def test_payment_entry_retrieves_last_exchange_rate(self):
|
def test_payment_entry_retrieves_last_exchange_rate(self):
|
||||||
from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records, save_new_records
|
from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records, save_new_records
|
||||||
|
|
||||||
|
|||||||
@@ -57,4 +57,4 @@ QUnit.test("test payment entry", function(assert) {
|
|||||||
() => frappe.timeout(3),
|
() => frappe.timeout(3),
|
||||||
() => done()
|
() => done()
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -25,4 +25,4 @@ QUnit.test("test payment entry", function(assert) {
|
|||||||
() => frappe.timeout(0.3),
|
() => frappe.timeout(0.3),
|
||||||
() => done()
|
() => done()
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -64,4 +64,4 @@ QUnit.test("test payment entry", function(assert) {
|
|||||||
},
|
},
|
||||||
() => done()
|
() => done()
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,19 +9,19 @@ from frappe.model.document import Document
|
|||||||
class PaymentGatewayAccount(Document):
|
class PaymentGatewayAccount(Document):
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
self.name = self.payment_gateway + " - " + self.currency
|
self.name = self.payment_gateway + " - " + self.currency
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.currency = frappe.db.get_value("Account", self.payment_account, "account_currency")
|
self.currency = frappe.db.get_value("Account", self.payment_account, "account_currency")
|
||||||
|
|
||||||
self.update_default_payment_gateway()
|
self.update_default_payment_gateway()
|
||||||
self.set_as_default_if_not_set()
|
self.set_as_default_if_not_set()
|
||||||
|
|
||||||
def update_default_payment_gateway(self):
|
def update_default_payment_gateway(self):
|
||||||
if self.is_default:
|
if self.is_default:
|
||||||
frappe.db.sql("""update `tabPayment Gateway Account` set is_default = 0
|
frappe.db.sql("""update `tabPayment Gateway Account` set is_default = 0
|
||||||
where is_default = 1 """)
|
where is_default = 1 """)
|
||||||
|
|
||||||
def set_as_default_if_not_set(self):
|
def set_as_default_if_not_set(self):
|
||||||
if not frappe.db.get_value("Payment Gateway Account",
|
if not frappe.db.get_value("Payment Gateway Account",
|
||||||
{"is_default": 1, "name": ("!=", self.name)}, "name"):
|
{"is_default": 1, "name": ("!=", self.name)}, "name"):
|
||||||
self.is_default = 1
|
self.is_default = 1
|
||||||
|
|||||||
@@ -136,4 +136,4 @@ frappe.ui.form.on('Payment Order', {
|
|||||||
|
|
||||||
dialog.show();
|
dialog.show();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ def get_data():
|
|||||||
'items': ['Payment Entry', 'Journal Entry']
|
'items': ['Payment Entry', 'Journal Entry']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,4 +46,4 @@ def create_payment_order_against_payment_entry(ref_doc, order_type):
|
|||||||
doc = make_payment_order(ref_doc.name, payment_order)
|
doc = make_payment_order(ref_doc.name, payment_order)
|
||||||
doc.save()
|
doc.save()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
return doc
|
return doc
|
||||||
|
|||||||
@@ -307,4 +307,4 @@ def reconcile_dr_cr_note(dr_cr_notes, company):
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
jv.flags.ignore_mandatory = True
|
jv.flags.ignore_mandatory = True
|
||||||
jv.submit()
|
jv.submit()
|
||||||
|
|||||||
@@ -541,4 +541,4 @@ def make_payment_order(source_name, target_doc=None):
|
|||||||
}
|
}
|
||||||
}, target_doc, set_missing_values)
|
}, target_doc, set_missing_values)
|
||||||
|
|
||||||
return doclist
|
return doclist
|
||||||
|
|||||||
@@ -138,4 +138,4 @@ class TestPaymentRequest(unittest.TestCase):
|
|||||||
|
|
||||||
# Try to make Payment Request more than SO amount, should give validation
|
# Try to make Payment Request more than SO amount, should give validation
|
||||||
pr2.grand_total = 900
|
pr2.grand_total = 900
|
||||||
self.assertRaises(frappe.ValidationError, pr2.save)
|
self.assertRaises(frappe.ValidationError, pr2.save)
|
||||||
|
|||||||
@@ -19,4 +19,4 @@ frappe.ui.form.on('Payment Term', {
|
|||||||
frm.set_df_property("discount", "description", description);
|
frm.set_df_property("discount", "description", description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
|
|
||||||
frappe.ui.form.on('Payment Terms Template', {
|
frappe.ui.form.on('Payment Terms Template', {
|
||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -30,4 +30,4 @@ def get_data():
|
|||||||
'items': ['Customer Group', 'Supplier Group']
|
'items': ['Customer Group', 'Supplier Group']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class PeriodClosingVoucher(AccountsController):
|
|||||||
|
|
||||||
def make_gl_entries(self):
|
def make_gl_entries(self):
|
||||||
gl_entries = []
|
gl_entries = []
|
||||||
net_pl_balance = 0
|
net_pl_balance = 0
|
||||||
|
|
||||||
pl_accounts = self.get_pl_balances()
|
pl_accounts = self.get_pl_balances()
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ class PeriodClosingVoucher(AccountsController):
|
|||||||
|
|
||||||
from erpnext.accounts.general_ledger import make_gl_entries
|
from erpnext.accounts.general_ledger import make_gl_entries
|
||||||
make_gl_entries(gl_entries)
|
make_gl_entries(gl_entries)
|
||||||
|
|
||||||
def get_pnl_gl_entry(self, net_pl_balance):
|
def get_pnl_gl_entry(self, net_pl_balance):
|
||||||
cost_center = frappe.db.get_value("Company", self.company, "cost_center")
|
cost_center = frappe.db.get_value("Company", self.company, "cost_center")
|
||||||
gl_entry = self.get_gl_dict({
|
gl_entry = self.get_gl_dict({
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ def create_company():
|
|||||||
'company_name': "Test PCV Company",
|
'company_name': "Test PCV Company",
|
||||||
'country': 'United States',
|
'country': 'United States',
|
||||||
'default_currency': 'USD'
|
'default_currency': 'USD'
|
||||||
})
|
})
|
||||||
company.insert(ignore_if_duplicate = True)
|
company.insert(ignore_if_duplicate = True)
|
||||||
return company.name
|
return company.name
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ frappe.ui.form.on('POS Closing Entry', {
|
|||||||
frm.set_query("pos_opening_entry", function(doc) {
|
frm.set_query("pos_opening_entry", function(doc) {
|
||||||
return { filters: { 'status': 'Open', 'docstatus': 1 } };
|
return { filters: { 'status': 'Open', 'docstatus': 1 } };
|
||||||
});
|
});
|
||||||
|
|
||||||
if (frm.doc.docstatus === 0 && !frm.doc.amended_from) frm.set_value("period_end_date", frappe.datetime.now_datetime());
|
if (frm.doc.docstatus === 0 && !frm.doc.amended_from) frm.set_value("period_end_date", frappe.datetime.now_datetime());
|
||||||
|
|
||||||
frappe.realtime.on('closing_process_complete', async function(data) {
|
frappe.realtime.on('closing_process_complete', async function(data) {
|
||||||
await frm.reload_doc();
|
await frm.reload_doc();
|
||||||
if (frm.doc.status == 'Failed' && frm.doc.error_message && data.user == frappe.session.user) {
|
if (frm.doc.status == 'Failed' && frm.doc.error_message && data.user == frappe.session.user) {
|
||||||
@@ -43,7 +43,7 @@ frappe.ui.form.on('POS Closing Entry', {
|
|||||||
const issue = '<a id="jump_to_error" style="text-decoration: underline;">issue</a>';
|
const issue = '<a id="jump_to_error" style="text-decoration: underline;">issue</a>';
|
||||||
frm.dashboard.set_headline(
|
frm.dashboard.set_headline(
|
||||||
__('POS Closing failed while running in a background process. You can resolve the {0} and retry the process again.', [issue]));
|
__('POS Closing failed while running in a background process. You can resolve the {0} and retry the process again.', [issue]));
|
||||||
|
|
||||||
$('#jump_to_error').on('click', (e) => {
|
$('#jump_to_error').on('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
frappe.utils.scroll_to(
|
frappe.utils.scroll_to(
|
||||||
|
|||||||
@@ -595,7 +595,8 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "scan_barcode",
|
"fieldname": "scan_barcode",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Scan Barcode"
|
"label": "Scan Barcode",
|
||||||
|
"options": "Barcode"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 1,
|
"allow_bulk_edit": 1,
|
||||||
@@ -1553,7 +1554,7 @@
|
|||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-07-29 13:37:20.636171",
|
"modified": "2021-08-17 20:13:44.255437",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "POS Invoice",
|
"name": "POS Invoice",
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ frappe.ui.form.on('POS Invoice Merge Log', {
|
|||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
frm.set_query("pos_invoice", "pos_invoices", doc => {
|
frm.set_query("pos_invoice", "pos_invoices", doc => {
|
||||||
return{
|
return{
|
||||||
filters: {
|
filters: {
|
||||||
'docstatus': 1,
|
'docstatus': 1,
|
||||||
'customer': doc.customer,
|
'customer': doc.customer,
|
||||||
'consolidated_invoice': ''
|
'consolidated_invoice': ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -354,4 +354,4 @@ def safe_load_json(message):
|
|||||||
except Exception:
|
except Exception:
|
||||||
json_message = message
|
json_message = message
|
||||||
|
|
||||||
return json_message
|
return json_message
|
||||||
|
|||||||
@@ -147,4 +147,3 @@ class TestPOSInvoiceMergeLog(unittest.TestCase):
|
|||||||
frappe.set_user("Administrator")
|
frappe.set_user("Administrator")
|
||||||
frappe.db.sql("delete from `tabPOS Profile`")
|
frappe.db.sql("delete from `tabPOS Profile`")
|
||||||
frappe.db.sql("delete from `tabPOS Invoice`")
|
frappe.db.sql("delete from `tabPOS Invoice`")
|
||||||
|
|
||||||
|
|||||||
@@ -53,4 +53,4 @@ frappe.ui.form.on('POS Opening Entry', {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -38,4 +38,4 @@ class POSOpeningEntry(StatusUpdater):
|
|||||||
frappe.throw(msg.format(", ".join(invalid_modes)), title=_("Missing Account"))
|
frappe.throw(msg.format(", ".join(invalid_modes)), title=_("Missing Account"))
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.set_status(update=True)
|
self.set_status(update=True)
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ def create_opening_entry(pos_profile, user):
|
|||||||
balance_details.append(frappe._dict({
|
balance_details.append(frappe._dict({
|
||||||
'mode_of_payment': d.mode_of_payment
|
'mode_of_payment': d.mode_of_payment
|
||||||
}))
|
}))
|
||||||
|
|
||||||
entry.set("balance_details", balance_details)
|
entry.set("balance_details", balance_details)
|
||||||
entry.submit()
|
entry.submit()
|
||||||
|
|
||||||
return entry.as_dict()
|
return entry.as_dict()
|
||||||
|
|||||||
@@ -8,4 +8,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
class POSSettings(Document):
|
class POSSettings(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
"actions": [],
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "field:title",
|
"autoname": "naming_series:",
|
||||||
"creation": "2014-02-21 15:02:51",
|
"creation": "2014-02-21 15:02:51",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"applicability_section",
|
"applicability_section",
|
||||||
|
"naming_series",
|
||||||
"title",
|
"title",
|
||||||
"disable",
|
"disable",
|
||||||
"apply_on",
|
"apply_on",
|
||||||
@@ -95,8 +96,7 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Title",
|
"label": "Title",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"reqd": 1,
|
"reqd": 1
|
||||||
"unique": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
@@ -571,6 +571,13 @@
|
|||||||
"fieldname": "is_recursive",
|
"fieldname": "is_recursive",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Recursive"
|
"label": "Is Recursive"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "PRLE-.####",
|
||||||
|
"fieldname": "naming_series",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Naming Series",
|
||||||
|
"options": "PRLE-.####"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-gift",
|
"icon": "fa fa-gift",
|
||||||
@@ -634,5 +641,6 @@
|
|||||||
],
|
],
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC"
|
"sort_order": "DESC",
|
||||||
}
|
"title_field": "title"
|
||||||
|
}
|
||||||
|
|||||||
@@ -615,4 +615,4 @@ def delete_existing_pricing_rules():
|
|||||||
for doctype in ["Pricing Rule", "Pricing Rule Item Code",
|
for doctype in ["Pricing Rule", "Pricing Rule Item Code",
|
||||||
"Pricing Rule Item Group", "Pricing Rule Brand"]:
|
"Pricing Rule Item Group", "Pricing Rule Brand"]:
|
||||||
|
|
||||||
frappe.db.sql("delete from `tab{0}`".format(doctype))
|
frappe.db.sql("delete from `tab{0}`".format(doctype))
|
||||||
|
|||||||
@@ -26,4 +26,3 @@ QUnit.test("test pricing rule", function(assert) {
|
|||||||
() => done()
|
() => done()
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -31,4 +31,4 @@ class ProcessDeferredAccounting(Document):
|
|||||||
'against_voucher': self.name
|
'against_voucher': self.name
|
||||||
})
|
})
|
||||||
|
|
||||||
make_reverse_gl_entries(gl_entries=gl_entries)
|
make_reverse_gl_entries(gl_entries=gl_entries)
|
||||||
|
|||||||
@@ -45,4 +45,4 @@ class TestProcessDeferredAccounting(unittest.TestCase):
|
|||||||
["Sales - _TC", 0.0, 33.85, "2019-01-31"]
|
["Sales - _TC", 0.0, 33.85, "2019-01-31"]
|
||||||
]
|
]
|
||||||
|
|
||||||
check_gl_entries(self, si.name, expected_gle, "2019-01-10")
|
check_gl_entries(self, si.name, expected_gle, "2019-01-10")
|
||||||
|
|||||||
@@ -284,4 +284,4 @@ def send_auto_email():
|
|||||||
selected = frappe.get_list('Process Statement Of Accounts', filters={'to_date': format_date(today()), 'enable_auto_email': 1})
|
selected = frappe.get_list('Process Statement Of Accounts', filters={'to_date': format_date(today()), 'enable_auto_email': 1})
|
||||||
for entry in selected:
|
for entry in selected:
|
||||||
send_emails(entry.name, from_scheduler=True)
|
send_emails(entry.name, from_scheduler=True)
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -48,4 +48,4 @@ frappe.ui.form.on('Promotional Scheme', {
|
|||||||
frm.doc.apply_on === key ? 1 : 0);
|
frm.doc.apply_on === key ? 1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user