Merge branch 'develop' into develop-customer-item-price-report

This commit is contained in:
Rohan 2019-08-01 17:51:03 +05:30 committed by GitHub
commit fc04d334da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
190 changed files with 17642 additions and 10788 deletions

View File

@ -1,51 +1,80 @@
language: python
dist: trusty dist: trusty
python: language: python
- "2.7"
- "3.6"
env: git:
- TEST_TYPE="Server Side Test" depth: 1
- TEST_TYPE="Patch Test"
services: cache:
- mysql - pip
addons:
hosts: test_site
mariadb: 10.3
jobs:
include:
- name: "Python 2.7 Server Side Test"
python: 2.7
script: bench --site test_site run-tests --app erpnext --coverage
- name: "Python 3.6 Server Side Test"
python: 3.6
script: bench --site test_site run-tests --app erpnext --coverage
- name: "Python 2.7 Patch Test"
python: 2.7
before_script:
- wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
- bench --site test_site --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz
script: bench --site test_site migrate
- name: "Python 3.6 Patch Test"
python: 3.6
before_script:
- wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
- bench --site test_site --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz
script: bench --site test_site migrate
install: install:
# fix mongodb travis error - cd ~
- sudo rm /etc/apt/sources.list.d/mongodb*.list
- pip install flake8==3.3.0
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
- sudo rm /etc/apt/sources.list.d/docker.list
- sudo apt-get install hhvm && rm -rf /home/travis/.kiex/
- sudo apt-get purge -y mysql-common mysql-server mysql-client
- nvm install 10 - nvm install 10
- pip install python-coveralls
- wget https://raw.githubusercontent.com/frappe/bench/master/playbooks/install.py
- sudo python install.py --develop --user travis --without-bench-setup
- sudo pip install -e ~/bench
- rm $TRAVIS_BUILD_DIR/.git/shallow - git clone https://github.com/frappe/bench --depth 1
- bash $TRAVIS_BUILD_DIR/travis/bench_init.sh - pip install -e ./bench
- cp -r $TRAVIS_BUILD_DIR/test_sites/test_site ~/frappe-bench/sites/
before_script: - git clone https://github.com/frappe/frappe --branch $TRAVIS_BRANCH --depth 1
- mysql -u root -ptravis -e 'create database test_frappe' - bench init --skip-assets --frappe-path ~/frappe --python $(which python) frappe-bench
- echo "USE mysql;\nCREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe';\nFLUSH PRIVILEGES;\n" | mysql -u root -ptravis
- echo "USE mysql;\nGRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost';\n" | mysql -u root -ptravis - mkdir ~/frappe-bench/sites/test_site
- cp -r $TRAVIS_BUILD_DIR/.travis/site_config.json ~/frappe-bench/sites/test_site/
- mysql -u root -e "SET GLOBAL character_set_server = 'utf8mb4'"
- mysql -u root -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"
- mysql -u root -e "CREATE DATABASE test_frappe"
- mysql -u root -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
- mysql -u root -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"
- mysql -u root -e "UPDATE mysql.user SET Password=PASSWORD('travis') WHERE User='root'"
- mysql -u root -e "FLUSH PRIVILEGES"
- wget -O /tmp/wkhtmltox.tar.xz https://github.com/frappe/wkhtmltopdf/raw/master/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
- 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
- cd ~/frappe-bench - cd ~/frappe-bench
- bench get-app erpnext $TRAVIS_BUILD_DIR
- bench use test_site
- bench reinstall --mariadb-root-username root --mariadb-root-password travis --yes
- bench scheduler disable
- sed -i 's/9000/9001/g' sites/common_site_config.json
- bench start &
- sleep 10
script: - sed -i 's/watch:/# watch:/g' Procfile
- bash $TRAVIS_BUILD_DIR/travis/run-tests.sh - sed -i 's/schedule:/# schedule:/g' Procfile
- sed -i 's/socketio:/# socketio:/g' Procfile
- sed -i 's/redis_socketio:/# redis_socketio:/g' Procfile
- bench get-app erpnext $TRAVIS_BUILD_DIR
- bench start &
- bench --site test_site reinstall --yes
after_script: after_script:
- pip install python-coveralls
- coveralls -b apps/erpnext -d ../../sites/.coverage - coveralls -b apps/erpnext -d ../../sites/.coverage

View File

@ -6,8 +6,8 @@
"mail_login": "test@example.com", "mail_login": "test@example.com",
"mail_password": "test", "mail_password": "test",
"admin_password": "admin", "admin_password": "admin",
"run_selenium_tests": 1, "root_login": "root",
"root_password": "travis", "root_password": "travis",
"host_name": "http://localhost:8000", "host_name": "http://test_site:8000",
"install_apps": ["erpnext"] "install_apps": ["erpnext"]
} }

View File

@ -123,7 +123,9 @@ class Account(NestedSet):
doc.flags.ignore_root_company_validation = True doc.flags.ignore_root_company_validation = True
doc.update({ doc.update({
"company": company, "company": company,
"account_currency": None, # parent account's currency should be passed down to child account's curreny
# if it is None, it picks it up from default company currency, which might be unintended
"account_currency": self.account_currency,
"parent_account": parent_acc_name_map[company] "parent_account": parent_acc_name_map[company]
}) })
doc.save() doc.save()

View File

@ -4,45 +4,52 @@
frappe.ui.form.on('Accounting Dimension', { frappe.ui.form.on('Accounting Dimension', {
refresh: function(frm) { refresh: function(frm) {
if (!frm.is_new()) {
frm.add_custom_button(__('Show {0}', [frm.doc.document_type]), function () {
frappe.set_route("List", frm.doc.document_type);
});
}
frm.set_query('document_type', () => { frm.set_query('document_type', () => {
return { return {
filters: { filters: {
name: ['not in', ['Accounting Dimension', 'Project', 'Cost Center']] name: ['not in', ['Accounting Dimension', 'Project', 'Cost Center', 'Accounting Dimension Detail']]
} }
}; };
}); });
let button = frm.doc.disabled ? "Enable" : "Disable"; if (!frm.is_new()) {
frm.add_custom_button(__('Show {0}', [frm.doc.document_type]), function () {
frm.add_custom_button(__(button), function() { frappe.set_route("List", frm.doc.document_type);
frm.set_value('disabled', 1 - frm.doc.disabled);
frappe.call({
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.disable_dimension",
args: {
doc: frm.doc
},
freeze: true,
callback: function(r) {
let message = frm.doc.disabled ? "Dimension Disabled" : "Dimension Enabled";
frm.save();
frappe.show_alert({message:__(message), indicator:'green'});
}
}); });
});
let button = frm.doc.disabled ? "Enable" : "Disable";
frm.add_custom_button(__(button), function() {
frm.set_value('disabled', 1 - frm.doc.disabled);
frappe.call({
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.disable_dimension",
args: {
doc: frm.doc
},
freeze: true,
callback: function(r) {
let message = frm.doc.disabled ? "Dimension Disabled" : "Dimension Enabled";
frm.save();
frappe.show_alert({message:__(message), indicator:'green'});
}
});
});
}
}, },
document_type: function(frm) { document_type: function(frm) {
frm.set_value('label', frm.doc.document_type); frm.set_value('label', frm.doc.document_type);
frm.set_value('fieldname', frappe.model.scrub(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) => { frappe.db.get_value('Accounting Dimension', {'document_type': frm.doc.document_type}, 'document_type', (r) => {
if (r && r.document_type) { if (r && r.document_type) {
frm.set_df_property('document_type', 'description', "Document type is already set as dimension"); frm.set_df_property('document_type', 'description', "Document type is already set as dimension");
@ -50,3 +57,10 @@ frappe.ui.form.on('Accounting Dimension', {
}); });
}, },
}); });
frappe.ui.form.on('Accounting Dimension Detail', {
dimension_defaults_add: function(frm, cdt, cdn) {
let row = locals[cdt][cdn];
row.reference_document = frm.doc.document_type;
}
});

View File

@ -1,6 +1,4 @@
{ {
"_comments": "[]",
"_liked_by": "[]",
"autoname": "field:label", "autoname": "field:label",
"creation": "2019-05-04 18:13:37.002352", "creation": "2019-05-04 18:13:37.002352",
"doctype": "DocType", "doctype": "DocType",
@ -9,8 +7,7 @@
"document_type", "document_type",
"label", "label",
"fieldname", "fieldname",
"mandatory_for_bs", "dimension_defaults",
"mandatory_for_pl",
"disabled" "disabled"
], ],
"fields": [ "fields": [
@ -43,19 +40,13 @@
"read_only": 1 "read_only": 1
}, },
{ {
"default": "0", "fieldname": "dimension_defaults",
"fieldname": "mandatory_for_bs", "fieldtype": "Table",
"fieldtype": "Check", "label": "Dimension Defaults",
"label": "Mandatory For Balance Sheet" "options": "Accounting Dimension Detail"
},
{
"default": "0",
"fieldname": "mandatory_for_pl",
"fieldtype": "Check",
"label": "Mandatory For Profit and Loss Account"
} }
], ],
"modified": "2019-07-14 17:25:01.307948", "modified": "2019-07-17 16:49:31.134385",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Accounting Dimension", "name": "Accounting Dimension",

View File

@ -96,13 +96,13 @@ def delete_accounting_dimension(doc):
frappe.db.sql(""" frappe.db.sql("""
DELETE FROM `tabCustom Field` DELETE FROM `tabCustom Field`
WHERE fieldname = %s WHERE fieldname = %s
AND dt IN (%s)""" % #nosec AND dt IN (%s)""" % #nosec
('%s', ', '.join(['%s']* len(doclist))), tuple([doc.fieldname] + doclist)) ('%s', ', '.join(['%s']* len(doclist))), tuple([doc.fieldname] + doclist))
frappe.db.sql(""" frappe.db.sql("""
DELETE FROM `tabProperty Setter` DELETE FROM `tabProperty Setter`
WHERE field_name = %s WHERE field_name = %s
AND doc_type IN (%s)""" % #nosec AND doc_type IN (%s)""" % #nosec
('%s', ', '.join(['%s']* len(doclist))), tuple([doc.fieldname] + doclist)) ('%s', ', '.join(['%s']* len(doclist))), tuple([doc.fieldname] + doclist))
@ -150,14 +150,40 @@ def get_doctypes_with_dimensions():
"Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item", "Purchase Receipt Item", "Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item", "Purchase Receipt Item",
"Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule", "Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule",
"Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation", "Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation",
"Travel Request", "Fees", "POS Profile"] "Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item", "Subscription",
"Subscription Plan"]
return doclist return doclist
def get_accounting_dimensions(as_list=True): def get_accounting_dimensions(as_list=True):
accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "mandatory_for_pl", "mandatory_for_bs", "disabled"], filters={"disabled": 0}) accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "disabled"])
if as_list: if as_list:
return [d.fieldname for d in accounting_dimensions] return [d.fieldname for d in accounting_dimensions]
else: else:
return accounting_dimensions return accounting_dimensions
def get_checks_for_pl_and_bs_accounts():
dimensions = frappe.db.sql("""SELECT p.label, p.disabled, p.fieldname, c.company, c.mandatory_for_pl, c.mandatory_for_bs
FROM `tabAccounting Dimension`p ,`tabAccounting Dimension Detail` c
WHERE p.name = c.parent""", as_dict=1)
return dimensions
@frappe.whitelist()
def get_dimension_filters():
dimension_filters = frappe.db.sql("""
SELECT label, fieldname, document_type
FROM `tabAccounting Dimension`
WHERE disabled = 0
""", as_dict=1)
default_dimensions = frappe.db.sql("""SELECT parent, company, default_dimension
FROM `tabAccounting Dimension Detail`""", as_dict=1)
default_dimensions_map = {}
for dimension in default_dimensions:
default_dimensions_map.setdefault(dimension['company'], {})
default_dimensions_map[dimension['company']][dimension['parent']] = dimension['default_dimension']
return dimension_filters, default_dimensions_map

View File

@ -27,12 +27,20 @@ class TestAccountingDimension(unittest.TestCase):
dimension1 = frappe.get_doc({ dimension1 = frappe.get_doc({
"doctype": "Accounting Dimension", "doctype": "Accounting Dimension",
"document_type": "Location", "document_type": "Location",
"mandatory_for_pl": 1 })
}).insert()
dimension1.append("dimension_defaults", {
"company": "_Test Company",
"reference_document": "Location",
"default_dimension": "Block 1",
"mandatory_for_bs": 1
})
dimension1.insert()
dimension1.save()
else: else:
dimension1 = frappe.get_doc("Accounting Dimension", "Location") dimension1 = frappe.get_doc("Accounting Dimension", "Location")
dimension1.disabled = 0 dimension1.disabled = 0
dimension1.mandatory_for_pl = 1
dimension1.save() dimension1.save()
def test_dimension_against_sales_invoice(self): def test_dimension_against_sales_invoice(self):
@ -100,7 +108,6 @@ def disable_dimension():
dimension1.save() dimension1.save()
dimension2 = frappe.get_doc("Accounting Dimension", "Location") dimension2 = frappe.get_doc("Accounting Dimension", "Location")
dimension2.mandatory_for_pl = 0
dimension2.disabled = 1 dimension2.disabled = 1
dimension2.save() dimension2.save()

View File

@ -0,0 +1,67 @@
{
"creation": "2019-07-16 17:53:18.718831",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"company",
"reference_document",
"default_dimension",
"mandatory_for_bs",
"mandatory_for_pl"
],
"fields": [
{
"columns": 2,
"fieldname": "company",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Company",
"options": "Company",
"reqd": 1
},
{
"fieldname": "reference_document",
"fieldtype": "Link",
"hidden": 1,
"label": "Reference Document",
"options": "DocType",
"read_only": 1
},
{
"columns": 2,
"fieldname": "default_dimension",
"fieldtype": "Dynamic Link",
"in_list_view": 1,
"label": "Default Dimension",
"options": "reference_document",
"reqd": 1
},
{
"columns": 3,
"default": "0",
"fieldname": "mandatory_for_bs",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Mandatory For Balance Sheet"
},
{
"columns": 3,
"default": "0",
"fieldname": "mandatory_for_pl",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Mandatory For Profit and Loss Account"
}
],
"istable": 1,
"modified": "2019-07-17 23:34:33.026883",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounting Dimension Detail",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
# import frappe
from frappe.model.document import Document
class AccountingDimensionDetail(Document):
pass

View File

@ -6,6 +6,9 @@ from frappe import _
def get_data(): def get_data():
return { return {
'fieldname': 'bank', 'fieldname': 'bank',
'non_standard_fieldnames': {
'Paymnet Order': 'company_bank'
},
'transactions': [ 'transactions': [
{ {
'label': _('Bank Deatils'), 'label': _('Bank Deatils'),

View File

@ -48,7 +48,10 @@ class BankAccount(Document):
# Encode characters as numbers # Encode characters as numbers
encoded = [encode_char(c) if ord(c) >= 65 and ord(c) <= 90 else c for c in flipped] encoded = [encode_char(c) if ord(c) >= 65 and ord(c) <= 90 else c for c in flipped]
to_check = int(''.join(encoded)) try:
to_check = int(''.join(encoded))
except ValueError:
frappe.throw(_('IBAN is not valid'))
if to_check % 97 != 1: if to_check % 97 != 1:
frappe.throw(_('IBAN is not valid')) frappe.throw(_('IBAN is not valid'))

View File

@ -12,7 +12,7 @@ from erpnext.accounts.party import validate_party_gle_currency, validate_party_f
from erpnext.accounts.utils import get_account_currency from erpnext.accounts.utils import get_account_currency
from erpnext.accounts.utils import get_fiscal_year from erpnext.accounts.utils import get_fiscal_year
from erpnext.exceptions import InvalidAccountCurrency from erpnext.exceptions import InvalidAccountCurrency
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_checks_for_pl_and_bs_accounts
exclude_from_linked_with = True exclude_from_linked_with = True
class GLEntry(Document): class GLEntry(Document):
@ -86,16 +86,16 @@ class GLEntry(Document):
account_type = frappe.db.get_value("Account", self.account, "report_type") account_type = frappe.db.get_value("Account", self.account, "report_type")
for dimension in get_accounting_dimensions(as_list=False): for dimension in get_checks_for_pl_and_bs_accounts():
if account_type == "Profit and Loss" \ if account_type == "Profit and Loss" \
and dimension.mandatory_for_pl and not dimension.disabled: and self.company == dimension.company and dimension.mandatory_for_pl and not dimension.disabled:
if not self.get(dimension.fieldname): if not self.get(dimension.fieldname):
frappe.throw(_("Accounting Dimension <b>{0}</b> is required for 'Profit and Loss' account {1}.") frappe.throw(_("Accounting Dimension <b>{0}</b> is required for 'Profit and Loss' account {1}.")
.format(dimension.label, self.account)) .format(dimension.label, self.account))
if account_type == "Balance Sheet" \ if account_type == "Balance Sheet" \
and dimension.mandatory_for_bs and not dimension.disabled: and self.company == dimension.company and dimension.mandatory_for_bs and not dimension.disabled:
if not self.get(dimension.fieldname): if not self.get(dimension.fieldname):
frappe.throw(_("Accounting Dimension <b>{0}</b> is required for 'Balance Sheet' account {1}.") frappe.throw(_("Accounting Dimension <b>{0}</b> is required for 'Balance Sheet' account {1}.")
.format(dimension.label, self.account)) .format(dimension.label, self.account))

View File

@ -223,7 +223,10 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
if(in_list(["Sales Invoice", "Purchase Invoice"], jvd.reference_type)) { if(in_list(["Sales Invoice", "Purchase Invoice"], jvd.reference_type)) {
out.filters.push([jvd.reference_type, "outstanding_amount", "!=", 0]); out.filters.push([jvd.reference_type, "outstanding_amount", "!=", 0]);
// Filter by cost center
if(jvd.cost_center) {
out.filters.push([jvd.reference_type, "cost_center", "in", ["", jvd.cost_center]]);
}
// account filter // account filter
frappe.model.validate_missing(jvd, "account"); frappe.model.validate_missing(jvd, "account");
var party_account_field = jvd.reference_type==="Sales Invoice" ? "debit_to": "credit_to"; var party_account_field = jvd.reference_type==="Sales Invoice" ? "debit_to": "credit_to";

View File

@ -258,6 +258,7 @@
"print_hide": 1 "print_hide": 1
}, },
{ {
"collapsible": 1,
"fieldname": "accounting_dimensions_section", "fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Accounting Dimensions" "label": "Accounting Dimensions"
@ -269,12 +270,13 @@
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"modified": "2019-05-25 22:14:02.715509", "modified": "2019-07-16 17:12:08.238334",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Journal Entry Account", "name": "Journal Entry Account",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],
"sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"track_changes": 1 "track_changes": 1
} }

View File

@ -10,7 +10,9 @@
"create_missing_party", "create_missing_party",
"column_break_3", "column_break_3",
"invoice_type", "invoice_type",
"accounting_dimensions_section",
"cost_center", "cost_center",
"dimension_col_break",
"section_break_4", "section_break_4",
"invoices" "invoices"
], ],
@ -59,11 +61,21 @@
"fieldtype": "Link", "fieldtype": "Link",
"label": "Cost Center", "label": "Cost Center",
"options": "Cost Center" "options": "Cost Center"
},
{
"collapsible": 1,
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions"
},
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
} }
], ],
"hide_toolbar": 1, "hide_toolbar": 1,
"issingle": 1, "issingle": 1,
"modified": "2019-06-13 11:45:31.405267", "modified": "2019-07-25 14:57:33.187689",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Opening Invoice Creation Tool", "name": "Opening Invoice Creation Tool",

View File

@ -7,6 +7,7 @@ import frappe
from frappe import _, scrub from frappe import _, scrub
from frappe.utils import flt, nowdate from frappe.utils import flt, nowdate
from frappe.model.document import Document from frappe.model.document import Document
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
class OpeningInvoiceCreationTool(Document): class OpeningInvoiceCreationTool(Document):
@ -173,6 +174,13 @@ class OpeningInvoiceCreationTool(Document):
"currency": frappe.get_cached_value('Company', self.company, "default_currency") "currency": frappe.get_cached_value('Company', self.company, "default_currency")
}) })
accounting_dimension = get_accounting_dimensions()
for dimension in accounting_dimension:
args.update({
dimension: item.get(dimension)
})
if self.invoice_type == "Sales": if self.invoice_type == "Sales":
args["is_pos"] = 0 args["is_pos"] = 0

View File

@ -15,7 +15,9 @@
"outstanding_amount", "outstanding_amount",
"column_break_4", "column_break_4",
"qty", "qty",
"cost_center" "accounting_dimensions_section",
"cost_center",
"dimension_col_break"
], ],
"fields": [ "fields": [
{ {
@ -92,10 +94,19 @@
"fieldtype": "Link", "fieldtype": "Link",
"label": "Cost Center", "label": "Cost Center",
"options": "Cost Center" "options": "Cost Center"
},
{
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions"
},
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
} }
], ],
"istable": 1, "istable": 1,
"modified": "2019-06-13 11:48:08.324063", "modified": "2019-07-25 15:00:00.460695",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Opening Invoice Creation Tool Item", "name": "Opening Invoice Creation Tool Item",

View File

@ -1,751 +1,166 @@
{ {
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2019-03-24 14:48:59.649168", "creation": "2019-03-24 14:48:59.649168",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"disable",
"column_break_2",
"rule_description",
"section_break_1",
"min_qty",
"max_qty",
"column_break_3",
"min_amount",
"max_amount",
"section_break_6",
"same_item",
"free_item",
"free_qty",
"column_break_9",
"free_item_uom",
"free_item_rate",
"section_break_12",
"warehouse",
"threshold_percentage",
"column_break_15",
"priority",
"apply_multiple_pricing_rules"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0, "default": "0",
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "disable", "fieldname": "disable",
"fieldtype": "Data", "fieldtype": "Check",
"hidden": 0, "label": "Disable"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Disable",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_2", "fieldname": "column_break_2",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "rule_description", "fieldname": "rule_description",
"fieldtype": "Small Text", "fieldtype": "Small Text",
"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": "Rule Description", "label": "Rule Description",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "reqd": 1
"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": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_1", "fieldname": "section_break_1",
"fieldtype": "Section Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0", "default": "0",
"fieldname": "min_qty", "fieldname": "min_qty",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "label": "Min Qty"
"label": "Min Qty",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0", "default": "0",
"fieldname": "max_qty", "fieldname": "max_qty",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "label": "Max Qty"
"label": "Max Qty",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3", "fieldname": "column_break_3",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0", "default": "0",
"fieldname": "min_amount", "fieldname": "min_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "label": "Min Amount"
"label": "Min Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0", "default": "0",
"fieldname": "max_amount", "fieldname": "max_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "label": "Max Amount"
"label": "Max Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_6", "fieldname": "section_break_6",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "Free Item"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Free Item",
"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
}, },
{ {
"allow_bulk_edit": 0, "default": "0",
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!parent.mixed_conditions", "depends_on": "eval:!parent.mixed_conditions",
"fieldname": "same_item", "fieldname": "same_item",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "label": "Same Item"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Same Item",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.same_item || parent.mixed_conditions", "depends_on": "eval:!doc.same_item || parent.mixed_conditions",
"fieldname": "free_item", "fieldname": "free_item",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Item Code", "label": "Item Code",
"length": 0, "options": "Item"
"no_copy": 0,
"options": "Item",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "free_qty", "fieldname": "free_qty",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "label": "Qty"
"label": "Qty",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_9", "fieldname": "column_break_9",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "free_item_uom", "fieldname": "free_item_uom",
"fieldtype": "Link", "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": "UOM", "label": "UOM",
"length": 0, "options": "UOM"
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "free_item_rate", "fieldname": "free_item_rate",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0, "label": "Rate"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Rate",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_12", "fieldname": "section_break_12",
"fieldtype": "Section Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "warehouse", "fieldname": "warehouse",
"fieldtype": "Link", "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": "Warehouse", "label": "Warehouse",
"length": 0, "options": "Warehouse"
"no_copy": 0,
"options": "Warehouse",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "threshold_percentage", "fieldname": "threshold_percentage",
"fieldtype": "Percent", "fieldtype": "Percent",
"hidden": 0, "label": "Threshold for Suggestion"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Threshold for Suggestion",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_15", "fieldname": "column_break_15",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "priority", "fieldname": "priority",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Priority", "label": "Priority",
"length": 0, "options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20"
"no_copy": 0,
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20",
"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
}, },
{ {
"allow_bulk_edit": 0, "default": "0",
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "apply_multiple_pricing_rules", "fieldname": "apply_multiple_pricing_rules",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "label": "Apply Multiple Pricing Rules"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Apply Multiple Pricing Rules",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
} }
], ],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "modified": "2019-07-21 00:00:56.674284",
"modified": "2019-03-24 14:48:59.649168",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Promotional Scheme Product Discount", "name": "Promotional Scheme Product Discount",
"name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC"
"track_changes": 0,
"track_seen": 0,
"track_views": 0
} }

View File

@ -336,6 +336,7 @@ class PurchaseInvoice(BuyingController):
if not self.is_return: if not self.is_return:
self.update_against_document_in_jv() self.update_against_document_in_jv()
self.update_billing_status_for_zero_amount_refdoc("Purchase Receipt")
self.update_billing_status_for_zero_amount_refdoc("Purchase Order") self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
self.update_billing_status_in_pr() self.update_billing_status_in_pr()
@ -774,6 +775,7 @@ class PurchaseInvoice(BuyingController):
self.update_prevdoc_status() self.update_prevdoc_status()
if not self.is_return: if not self.is_return:
self.update_billing_status_for_zero_amount_refdoc("Purchase Receipt")
self.update_billing_status_for_zero_amount_refdoc("Purchase Order") self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
self.update_billing_status_in_pr() self.update_billing_status_in_pr()

View File

@ -20,11 +20,13 @@ test_dependencies = ["Item", "Cost Center", "Payment Term", "Payment Terms Templ
test_ignore = ["Serial No"] test_ignore = ["Serial No"]
class TestPurchaseInvoice(unittest.TestCase): class TestPurchaseInvoice(unittest.TestCase):
def setUp(self): @classmethod
def setUpClass(self):
unlink_payment_on_cancel_of_invoice() unlink_payment_on_cancel_of_invoice()
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1) frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
def tearDown(self): @classmethod
def tearDownClass(self):
unlink_payment_on_cancel_of_invoice(0) unlink_payment_on_cancel_of_invoice(0)
def test_gl_entries_without_perpetual_inventory(self): def test_gl_entries_without_perpetual_inventory(self):
@ -91,6 +93,7 @@ class TestPurchaseInvoice(unittest.TestCase):
pi_doc = frappe.get_doc('Purchase Invoice', pi_doc.name) pi_doc = frappe.get_doc('Purchase Invoice', pi_doc.name)
self.assertRaises(frappe.LinkExistsError, pi_doc.cancel) self.assertRaises(frappe.LinkExistsError, pi_doc.cancel)
unlink_payment_on_cancel_of_invoice()
def test_purchase_invoice_for_blocked_supplier(self): def test_purchase_invoice_for_blocked_supplier(self):
supplier = frappe.get_doc('Supplier', '_Test Supplier') supplier = frappe.get_doc('Supplier', '_Test Supplier')

View File

@ -44,6 +44,10 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
this.frm.toggle_reqd("due_date", !this.frm.doc.is_return); this.frm.toggle_reqd("due_date", !this.frm.doc.is_return);
if (this.frm.doc.is_return) {
this.frm.return_print_format = "Sales Invoice Return";
}
this.show_general_ledger(); this.show_general_ledger();
if(doc.update_stock) this.show_stock_ledger(); if(doc.update_stock) this.show_stock_ledger();
@ -148,16 +152,24 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
}, },
set_default_print_format: function() { set_default_print_format: function() {
// set default print format to POS type // set default print format to POS type or Credit Note
if(cur_frm.doc.is_pos) { if(cur_frm.doc.is_pos) {
if(cur_frm.pos_print_format) { if(cur_frm.pos_print_format) {
cur_frm.meta._default_print_format = cur_frm.meta.default_print_format; cur_frm.meta._default_print_format = cur_frm.meta.default_print_format;
cur_frm.meta.default_print_format = cur_frm.pos_print_format; cur_frm.meta.default_print_format = cur_frm.pos_print_format;
} }
} else if(cur_frm.doc.is_return) {
if(cur_frm.return_print_format) {
cur_frm.meta._default_print_format = cur_frm.meta.default_print_format;
cur_frm.meta.default_print_format = cur_frm.return_print_format;
}
} else { } else {
if(cur_frm.meta._default_print_format) { if(cur_frm.meta._default_print_format) {
cur_frm.meta.default_print_format = cur_frm.meta._default_print_format; cur_frm.meta.default_print_format = cur_frm.meta._default_print_format;
cur_frm.meta._default_print_format = null; cur_frm.meta._default_print_format = null;
} else if(in_list([cur_frm.pos_print_format, cur_frm.return_print_format], cur_frm.meta.default_print_format)) {
cur_frm.meta.default_print_format = null;
cur_frm.meta._default_print_format = null;
} }
} }
}, },

View File

@ -166,6 +166,7 @@ class SalesInvoice(SellingController):
self.make_gl_entries() self.make_gl_entries()
if not self.is_return: if not self.is_return:
self.update_billing_status_for_zero_amount_refdoc("Delivery Note")
self.update_billing_status_for_zero_amount_refdoc("Sales Order") self.update_billing_status_for_zero_amount_refdoc("Sales Order")
self.check_credit_limit() self.check_credit_limit()
@ -220,6 +221,7 @@ class SalesInvoice(SellingController):
self.update_billing_status_in_dn() self.update_billing_status_in_dn()
if not self.is_return: if not self.is_return:
self.update_billing_status_for_zero_amount_refdoc("Delivery Note")
self.update_billing_status_for_zero_amount_refdoc("Sales Order") self.update_billing_status_for_zero_amount_refdoc("Sales Order")
self.update_serial_no(in_cancel=True) self.update_serial_no(in_cancel=True)
@ -395,14 +397,17 @@ class SalesInvoice(SellingController):
if pos.get('account_for_change_amount'): if pos.get('account_for_change_amount'):
self.account_for_change_amount = pos.get('account_for_change_amount') self.account_for_change_amount = pos.get('account_for_change_amount')
for fieldname in ('territory', 'naming_series', 'currency', 'taxes_and_charges', 'letter_head', 'tc_name', for fieldname in ('territory', 'naming_series', 'currency', 'letter_head', 'tc_name',
'company', 'select_print_heading', 'cash_bank_account', 'company_address', 'company', 'select_print_heading', 'cash_bank_account', 'write_off_account', 'taxes_and_charges',
'write_off_account', 'write_off_cost_center', 'apply_discount_on', 'cost_center'): 'write_off_cost_center', 'apply_discount_on', 'cost_center'):
if (not for_validate) or (for_validate and not self.get(fieldname)): if (not for_validate) or (for_validate and not self.get(fieldname)):
self.set(fieldname, pos.get(fieldname)) self.set(fieldname, pos.get(fieldname))
customer_price_list = frappe.get_value("Customer", self.customer, 'default_price_list') 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: if not customer_price_list:
self.set('selling_price_list', pos.get('selling_price_list')) self.set('selling_price_list', pos.get('selling_price_list'))
@ -1255,9 +1260,8 @@ def validate_inter_company_party(doctype, party, company, inter_company_referenc
frappe.throw(_("Invalid Company for Inter Company Transaction.")) frappe.throw(_("Invalid Company for Inter Company Transaction."))
elif frappe.db.get_value(partytype, {"name": party, internal: 1}, "name") == party: elif frappe.db.get_value(partytype, {"name": party, internal: 1}, "name") == party:
companies = frappe.db.sql("""select company from `tabAllowed To Transact With` companies = frappe.get_all("Allowed To Transact With", fields=["company"], filters={"parenttype": partytype, "parent": party})
where parenttype = '{0}' and parent = '{1}'""".format(partytype, party), as_list = 1) companies = [d.company for d in companies]
companies = [d[0] for d in companies]
if not company in companies: if not company in companies:
frappe.throw(_("{0} not allowed to transact with {1}. Please change the Company.").format(partytype, company)) frappe.throw(_("{0} not allowed to transact with {1}. Please change the Company.").format(partytype, company))

View File

@ -29,10 +29,12 @@ class TestSalesInvoice(unittest.TestCase):
w.submit() w.submit()
return w return w
def setUp(self): @classmethod
def setUpClass(self):
unlink_payment_on_cancel_of_invoice() unlink_payment_on_cancel_of_invoice()
def tearDown(self): @classmethod
def tearDownClass(self):
unlink_payment_on_cancel_of_invoice(0) unlink_payment_on_cancel_of_invoice(0)
def test_timestamp_change(self): def test_timestamp_change(self):
@ -135,6 +137,7 @@ class TestSalesInvoice(unittest.TestCase):
unlink_payment_on_cancel_of_invoice(0) unlink_payment_on_cancel_of_invoice(0)
si = frappe.get_doc('Sales Invoice', si.name) si = frappe.get_doc('Sales Invoice', si.name)
self.assertRaises(frappe.LinkExistsError, si.cancel) self.assertRaises(frappe.LinkExistsError, si.cancel)
unlink_payment_on_cancel_of_invoice()
def test_sales_invoice_calculation_export_currency(self): def test_sales_invoice_calculation_export_currency(self):
si = frappe.copy_doc(test_records[2]) si = frappe.copy_doc(test_records[2])

View File

@ -764,6 +764,7 @@
"label": "Image" "label": "Image"
}, },
{ {
"collapsible": 1,
"fieldname": "accounting_dimensions_section", "fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Accounting Dimensions" "label": "Accounting Dimensions"
@ -782,7 +783,7 @@
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"modified": "2019-06-28 17:30:12.156086", "modified": "2019-07-16 16:36:46.527606",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Sales Invoice Item", "name": "Sales Invoice Item",

View File

@ -1,926 +1,245 @@
{ {
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "ACC-SUB-.YYYY.-.#####", "autoname": "ACC-SUB-.YYYY.-.#####",
"beta": 0,
"creation": "2017-07-18 17:50:43.967266", "creation": "2017-07-18 17:50:43.967266",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"customer",
"cb_1",
"status",
"subscription_period",
"start",
"cancelation_date",
"trial_period_start",
"trial_period_end",
"column_break_11",
"current_invoice_start",
"current_invoice_end",
"days_until_due",
"cancel_at_period_end",
"generate_invoice_at_period_start",
"sb_4",
"plans",
"sb_1",
"tax_template",
"sb_2",
"apply_additional_discount",
"cb_2",
"additional_discount_percentage",
"additional_discount_amount",
"sb_3",
"invoices",
"accounting_dimensions_section",
"dimension_col_break"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "customer", "fieldname": "customer",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Customer", "label": "Customer",
"length": 0,
"no_copy": 0,
"options": "Customer", "options": "Customer",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1, "reqd": 1,
"search_index": 0, "set_only_once": 1
"set_only_once": 1,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 1, "allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cb_1", "fieldname": "cb_1",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "status", "fieldname": "status",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Status", "label": "Status",
"length": 0,
"no_copy": 0,
"options": "\nTrialling\nActive\nPast Due Date\nCancelled\nUnpaid", "options": "\nTrialling\nActive\nPast Due Date\nCancelled\nUnpaid",
"permlevel": 0, "read_only": 1
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "subscription_period", "fieldname": "subscription_period",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "Subscription Period"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Subscription Period",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "start", "fieldname": "start",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Subscription Start Date", "label": "Subscription Start Date",
"length": 0, "set_only_once": 1
"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": 1,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cancelation_date", "fieldname": "cancelation_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Cancelation Date", "label": "Cancelation Date",
"length": 0, "read_only": 1
"no_copy": 0,
"options": "",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 1, "allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "trial_period_start", "fieldname": "trial_period_start",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Trial Period Start Date", "label": "Trial Period Start Date",
"length": 0, "set_only_once": 1
"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": 1,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.trial_period_start", "depends_on": "eval:doc.trial_period_start",
"fieldname": "trial_period_end", "fieldname": "trial_period_end",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Trial Period End Date", "label": "Trial Period End Date",
"length": 0, "set_only_once": 1
"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": 1,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_11", "fieldname": "column_break_11",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "current_invoice_start", "fieldname": "current_invoice_start",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Current Invoice Start Date", "label": "Current Invoice Start Date",
"length": 0, "read_only": 1
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "current_invoice_end", "fieldname": "current_invoice_end",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Current Invoice End Date", "label": "Current Invoice End Date",
"length": 0, "read_only": 1
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0", "default": "0",
"description": "Number of days that the subscriber has to pay invoices generated by this subscription", "description": "Number of days that the subscriber has to pay invoices generated by this subscription",
"fieldname": "days_until_due", "fieldname": "days_until_due",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 0, "label": "Days Until Due"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Days Until Due",
"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
}, },
{ {
"allow_bulk_edit": 0, "default": "0",
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cancel_at_period_end", "fieldname": "cancel_at_period_end",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "label": "Cancel At End Of Period"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Cancel At End Of Period",
"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
}, },
{ {
"allow_bulk_edit": 0, "default": "0",
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "generate_invoice_at_period_start", "fieldname": "generate_invoice_at_period_start",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "label": "Generate Invoice At Beginning Of Period"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Generate Invoice At Beginning Of Period",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 1, "allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "sb_4", "fieldname": "sb_4",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "Plans"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Plans",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 1, "allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "plans", "fieldname": "plans",
"fieldtype": "Table", "fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Plans", "label": "Plans",
"length": 0,
"no_copy": 0,
"options": "Subscription Plan Detail", "options": "Subscription Plan Detail",
"permlevel": 0, "reqd": 1
"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": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sb_1", "fieldname": "sb_1",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "Taxes"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Taxes",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "tax_template", "fieldname": "tax_template",
"fieldtype": "Link", "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": "Sales Taxes and Charges Template", "label": "Sales Taxes and Charges Template",
"length": 0, "options": "Sales Taxes and Charges Template"
"no_copy": 0,
"options": "Sales Taxes and Charges Template",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"description": "",
"fieldname": "sb_2", "fieldname": "sb_2",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "Discounts"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Discounts",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "apply_additional_discount", "fieldname": "apply_additional_discount",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Apply Additional Discount On", "label": "Apply Additional Discount On",
"length": 0, "options": "\nGrand Total\nNet total"
"no_copy": 0,
"options": "\nGrand Total\nNet total",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "cb_2", "fieldname": "cb_2",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "additional_discount_percentage", "fieldname": "additional_discount_percentage",
"fieldtype": "Percent", "fieldtype": "Percent",
"hidden": 0, "label": "Additional DIscount Percentage"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Additional DIscount Percentage",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1, "collapsible": 1,
"columns": 0,
"depends_on": "",
"fieldname": "additional_discount_amount", "fieldname": "additional_discount_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0, "label": "Additional DIscount Amount"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Additional DIscount Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"depends_on": "eval:doc.invoices", "depends_on": "eval:doc.invoices",
"fieldname": "sb_3", "fieldname": "sb_3",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "Invoices"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Invoices",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1, "collapsible": 1,
"columns": 0,
"depends_on": "",
"fieldname": "invoices", "fieldname": "invoices",
"fieldtype": "Table", "fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Invoices", "label": "Invoices",
"length": 0, "options": "Subscription Invoice"
"no_copy": 0, },
"options": "Subscription Invoice", {
"permlevel": 0, "collapsible": 1,
"precision": "", "fieldname": "accounting_dimensions_section",
"print_hide": 0, "fieldtype": "Section Break",
"print_hide_if_no_value": 0, "label": "Accounting Dimensions"
"read_only": 0, },
"remember_last_selected_value": 0, {
"report_hide": 0, "fieldname": "dimension_col_break",
"reqd": 0, "fieldtype": "Column Break"
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
} }
], ],
"has_web_view": 0, "modified": "2019-07-25 18:45:38.579579",
"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-10-14 10:38:55.545540",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Subscription", "name": "Subscription",
"name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "System Manager", "role": "System Manager",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Accounts User", "role": "Accounts User",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Accounts Manager", "role": "Accounts Manager",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
} }
], ],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "",
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"title_field": "", "track_changes": 1
"track_changes": 1,
"track_seen": 0,
"track_views": 0
} }

View File

@ -9,6 +9,7 @@ from frappe import _
from frappe.model.document import Document from frappe.model.document import Document
from frappe.utils.data import nowdate, getdate, cint, add_days, date_diff, get_last_day, add_to_date, flt from frappe.utils.data import nowdate, getdate, cint, add_days, date_diff, get_last_day, add_to_date, flt
from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_plan_rate from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_plan_rate
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
class Subscription(Document): class Subscription(Document):
@ -241,6 +242,15 @@ class Subscription(Document):
invoice.posting_date = self.current_invoice_start invoice.posting_date = self.current_invoice_start
invoice.customer = self.customer invoice.customer = self.customer
## Add dimesnions in invoice for subscription:
accounting_dimensions = get_accounting_dimensions()
for dimension in accounting_dimensions:
if self.get(dimension):
invoice.update({
dimension: self.get(dimension)
})
# Subscription is better suited for service items. I won't update `update_stock` # Subscription is better suited for service items. I won't update `update_stock`
# for that reason # for that reason
items_list = self.get_items_from_plans(self.plans, prorate) items_list = self.get_items_from_plans(self.plans, prorate)

View File

@ -1,612 +1,163 @@
{ {
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 1, "allow_rename": 1,
"autoname": "field:plan_name", "autoname": "field:plan_name",
"beta": 0,
"creation": "2018-02-24 11:31:23.066506", "creation": "2018-02-24 11:31:23.066506",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"plan_name",
"currency",
"column_break_3",
"item",
"section_break_5",
"price_determination",
"column_break_7",
"cost",
"price_list",
"section_break_11",
"billing_interval",
"column_break_13",
"billing_interval_count",
"payment_plan_section",
"payment_plan_id",
"column_break_16",
"payment_gateway",
"accounting_dimensions_section",
"dimension_col_break"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "plan_name", "fieldname": "plan_name",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Plan Name", "label": "Plan Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1, "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 1 "unique": 1
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "currency", "fieldname": "currency",
"fieldtype": "Link", "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": "Currency", "label": "Currency",
"length": 0, "options": "Currency"
"no_copy": 0,
"options": "Currency",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3", "fieldname": "column_break_3",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "item", "fieldname": "item",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Item", "label": "Item",
"length": 0,
"no_copy": 0,
"options": "Item", "options": "Item",
"permlevel": 0, "reqd": 1
"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": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_5", "fieldname": "section_break_5",
"fieldtype": "Section Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "price_determination", "fieldname": "price_determination",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Price Determination", "label": "Price Determination",
"length": 0,
"no_copy": 0,
"options": "\nFixed rate\nBased on price list", "options": "\nFixed rate\nBased on price list",
"permlevel": 0, "reqd": 1
"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": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_7", "fieldname": "column_break_7",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.price_determination==\"Fixed rate\"", "depends_on": "eval:doc.price_determination==\"Fixed rate\"",
"fieldname": "cost", "fieldname": "cost",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "label": "Cost"
"label": "Cost",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.price_determination==\"Based on price list\"", "depends_on": "eval:doc.price_determination==\"Based on price list\"",
"fieldname": "price_list", "fieldname": "price_list",
"fieldtype": "Link", "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": "Price List", "label": "Price List",
"length": 0, "options": "Price List"
"no_copy": 0,
"options": "Price List",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_11", "fieldname": "section_break_11",
"fieldtype": "Section Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Day", "default": "Day",
"fieldname": "billing_interval", "fieldname": "billing_interval",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Billing Interval", "label": "Billing Interval",
"length": 0,
"no_copy": 0,
"options": "Day\nWeek\nMonth\nYear", "options": "Day\nWeek\nMonth\nYear",
"permlevel": 0, "reqd": 1
"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": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_13", "fieldname": "column_break_13",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "1", "default": "1",
"description": "Number of intervals for the interval field e.g if Interval is 'Days' and Billing Interval Count is 3, invoices will be generated every 3 days", "description": "Number of intervals for the interval field e.g if Interval is 'Days' and Billing Interval Count is 3, invoices will be generated every 3 days",
"fieldname": "billing_interval_count", "fieldname": "billing_interval_count",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Billing Interval Count", "label": "Billing Interval Count",
"length": 0, "reqd": 1
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "payment_plan_section", "fieldname": "payment_plan_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "Payment Plan"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payment Plan",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "payment_plan_id", "fieldname": "payment_plan_id",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0, "label": "Payment Plan"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payment Plan",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_16", "fieldname": "column_break_16",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "payment_gateway", "fieldname": "payment_gateway",
"fieldtype": "Link", "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": "Payment Gateway", "label": "Payment Gateway",
"length": 0, "options": "Payment Gateway Account"
"no_copy": 0, },
"options": "Payment Gateway Account", {
"permlevel": 0, "collapsible": 1,
"precision": "", "fieldname": "accounting_dimensions_section",
"print_hide": 0, "fieldtype": "Section Break",
"print_hide_if_no_value": 0, "label": "Accounting Dimensions"
"read_only": 0, },
"remember_last_selected_value": 0, {
"report_hide": 0, "fieldname": "dimension_col_break",
"reqd": 0, "fieldtype": "Column Break"
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
} }
], ],
"has_web_view": 0, "modified": "2019-07-25 18:35:04.362556",
"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-06-20 16:59:54.082358",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Subscription Plan", "name": "Subscription Plan",
"name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "System Manager", "role": "System Manager",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
} }
], ],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"track_changes": 1, "track_changes": 1
"track_seen": 0
} }

View File

@ -0,0 +1,129 @@
{%- from "templates/print_formats/standard_macros.html" import add_header, render_field, print_value, fieldmeta,
get_width, get_align_class -%}
{%- macro render_currency(df, doc) -%}
<div class="row {% if df.bold %}important{% endif %} data-field">
<div class="col-xs-{{ "9" if df.fieldtype=="Check" else "5" }}
{%- if doc._align_labels_right %} text-right{%- endif -%}">
<label>{{ _(df.label) }}</label>
</div>
<div class="col-xs-{{ "3" if df.fieldtype=="Check" else "7" }} value">
{% if doc.get(df.fieldname) != None -%}
{{ frappe.utils.fmt_money((doc[df.fieldname])|int|abs, currency=doc.currency) }}
{% endif %}
</div>
</div>
{%- endmacro -%}
{%- macro render_taxes(df, doc) -%}
{%- set data = doc.get(df.fieldname)[df.start:df.end] -%}
<div class="row">
<div class="col-xs-6"></div>
<div class="col-xs-6">
{%- for charge in data -%}
{%- if (charge.tax_amount or doc.flags.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}
<div class="row">
<div class="col-xs-5 {%- if doc._align_labels_right %} text-right{%- endif -%}">
<label>{{ charge.get_formatted("description") }}</label></div>
<div class="col-xs-7 text-right">
{{ frappe.utils.fmt_money((charge.tax_amount)|int|abs, currency=doc.currency) }}
</div>
</div>
{%- endif -%}
{%- endfor -%}
</div>
</div>
{%- endmacro -%}
{%- macro render_table(df, doc) -%}
{%- set table_meta = frappe.get_meta(df.options) -%}
{%- set data = doc.get(df.fieldname)[df.start:df.end] -%}
{%- if doc.print_templates and
doc.print_templates.get(df.fieldname) -%}
{% include doc.print_templates[df.fieldname] %}
{%- else -%}
{%- if data -%}
{%- set visible_columns = get_visible_columns(doc.get(df.fieldname),
table_meta, df) -%}
<div {{ fieldmeta(df) }}>
<table class="table table-bordered table-condensed">
<thead>
<tr>
<th style="width: 40px" class="table-sr">{{ _("Sr") }}</th>
{% for tdf in visible_columns %}
{% if (data and not data[0].flags.compact_item_print) or tdf.fieldname in doc.get(df.fieldname)[0].flags.compact_item_fields %}
<th style="width: {{ get_width(tdf) }};" class="{{ get_align_class(tdf) }}" {{ fieldmeta(df) }}>
{{ _(tdf.label) }}</th>
{% endif %}
{% endfor %}
</tr>
</thead>
<tbody>
{% for d in data %}
<tr>
<td class="table-sr">{{ d.idx }}</td>
{% for tdf in visible_columns %}
{% if not d.flags.compact_item_print or tdf.fieldname in doc.get(df.fieldname)[0].flags.compact_item_fields %}
<td class="{{ get_align_class(tdf) }}" {{ fieldmeta(df) }}>
{% if tdf.fieldtype == 'Currency' %}
<div class="value">{{ frappe.utils.fmt_money((d[tdf.fieldname])|int|abs, currency=doc.currency) }}</div></td>
{% else %}
<div class="value">{{ print_value(tdf, d, doc, visible_columns) }}</div></td>
{% endif %}
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{%- endif -%}
{%- endif -%}
{%- endmacro -%}
{% for page in layout %}
<div class="page-break">
<div {% if print_settings.repeat_header_footer %} id="header-html" class="hidden-pdf" {% endif %}>
{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings) }}
</div>
{% if print_settings.repeat_header_footer %}
<div id="footer-html" class="visible-pdf">
{% if not no_letterhead and footer %}
<div class="letter-head-footer">
{{ footer }}
</div>
{% endif %}
<p class="text-center small page-number visible-pdf">
{{ _("Page {0} of {1}").format('<span class="page"></span>', '<span class="topage"></span>') }}
</p>
</div>
{% endif %}
{% for section in page %}
<div class="row section-break">
{% if section.columns.fields %}
{%- if doc._line_breaks and loop.index != 1 -%}<hr>{%- endif -%}
{%- if doc._show_section_headings and section.label and section.has_data -%}
<h4 class='col-sm-12'>{{ _(section.label) }}</h4>
{% endif %}
{%- endif -%}
{% for column in section.columns %}
<div class="col-xs-{{ (12 / section.columns|len)|int }} column-break">
{% for df in column.fields %}
{% if df.fieldname == 'taxes' %}
{{ render_taxes(df, doc) }}
{% elif df.fieldtype == 'Currency' %}
{{ render_currency(df, doc) }}
{% elif df.fieldtype =='Table' %}
{{ render_table(df, doc)}}
{% elif doc[df.fieldname] %}
{{ render_field(df, doc) }}
{% endif %}
{% endfor %}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
{% endfor %}

View File

@ -0,0 +1,24 @@
{
"align_labels_right": 1,
"creation": "2019-07-24 20:13:30.259953",
"custom_format": 0,
"default_print_language": "en-US",
"disabled": 0,
"doc_type": "Sales Invoice",
"docstatus": 0,
"doctype": "Print Format",
"font": "Default",
"html": "",
"idx": 0,
"line_breaks": 1,
"modified": "2019-07-24 20:13:30.259953",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Return",
"owner": "Administrator",
"print_format_builder": 0,
"print_format_type": "Jinja",
"raw_printing": 0,
"show_section_headings": 1,
"standard": "Yes"
}

View File

@ -115,13 +115,12 @@ frappe.query_reports["Accounts Payable"] = {
} }
} }
erpnext.dimension_filters.then((dimensions) => { erpnext.dimension_filters.forEach((dimension) => {
dimensions.forEach((dimension) => { frappe.query_reports["Accounts Payable"].filters.splice(9, 0 ,{
frappe.query_reports["Accounts Payable"].filters.splice(9, 0 ,{ "fieldname": dimension["fieldname"],
"fieldname": dimension["fieldname"], "label": __(dimension["label"]),
"label": __(dimension["label"]), "fieldtype": "Link",
"fieldtype": "Link", "options": dimension["document_type"]
"options": dimension["document_type"]
});
}); });
}); });

View File

@ -99,13 +99,12 @@ frappe.query_reports["Accounts Payable Summary"] = {
} }
} }
erpnext.dimension_filters.then((dimensions) => { erpnext.dimension_filters.forEach((dimension) => {
dimensions.forEach((dimension) => { frappe.query_reports["Accounts Payable Summary"].filters.splice(9, 0 ,{
frappe.query_reports["Accounts Payable Summary"].filters.splice(9, 0 ,{ "fieldname": dimension["fieldname"],
"fieldname": dimension["fieldname"], "label": __(dimension["label"]),
"label": __(dimension["label"]), "fieldtype": "Link",
"fieldtype": "Link", "options": dimension["document_type"]
"options": dimension["document_type"]
});
}); });
}); });

View File

@ -173,13 +173,12 @@ frappe.query_reports["Accounts Receivable"] = {
} }
} }
erpnext.dimension_filters.then((dimensions) => { erpnext.dimension_filters.forEach((dimension) => {
dimensions.forEach((dimension) => { frappe.query_reports["Accounts Receivable"].filters.splice(9, 0 ,{
frappe.query_reports["Accounts Receivable"].filters.splice(9, 0 ,{ "fieldname": dimension["fieldname"],
"fieldname": dimension["fieldname"], "label": __(dimension["label"]),
"label": __(dimension["label"]), "fieldtype": "Link",
"fieldtype": "Link", "options": dimension["document_type"]
"options": dimension["document_type"]
});
}); });
}); });

View File

@ -117,13 +117,11 @@ frappe.query_reports["Accounts Receivable Summary"] = {
} }
} }
erpnext.dimension_filters.then((dimensions) => { erpnext.dimension_filters.forEach((dimension) => {
dimensions.forEach((dimension) => { frappe.query_reports["Accounts Receivable Summary"].filters.splice(9, 0 ,{
frappe.query_reports["Accounts Receivable Summary"].filters.splice(9, 0 ,{ "fieldname": dimension["fieldname"],
"fieldname": dimension["fieldname"], "label": __(dimension["label"]),
"label": __(dimension["label"]), "fieldtype": "Link",
"fieldtype": "Link", "options": dimension["document_type"]
"options": dimension["document_type"]
});
}); });
}); });

View File

@ -55,9 +55,15 @@ def get_columns():
"fieldtype": "Date", "fieldtype": "Date",
"width": 90 "width": 90
}, },
{
"fieldname": "payment_document",
"label": _("Payment Document Type"),
"fieldtype": "Data",
"width": 220
},
{ {
"fieldname": "payment_entry", "fieldname": "payment_entry",
"label": _("Payment Entry"), "label": _("Payment Document"),
"fieldtype": "Dynamic Link", "fieldtype": "Dynamic Link",
"options": "payment_document", "options": "payment_document",
"width": 220 "width": 220

View File

@ -63,8 +63,7 @@ frappe.query_reports["Budget Variance Report"] = {
] ]
} }
erpnext.dimension_filters.then((dimensions) => { erpnext.dimension_filters.forEach((dimension) => {
dimensions.forEach((dimension) => { frappe.query_reports["Budget Variance Report"].filters[4].options.push(dimension["document_type"]);
frappe.query_reports["Budget Variance Report"].filters[4].options.push(dimension["document_type"]);
});
}); });

View File

@ -125,8 +125,9 @@ def get_account_type_based_data(company, account_type, period_list, accumulated_
data["total"] = total data["total"] = total
return data return data
def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters): def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters={}):
cond = "" cond = ""
filters = frappe._dict(filters)
if filters.finance_book: if filters.finance_book:
cond = " and finance_book = %s" %(frappe.db.escape(filters.finance_book)) cond = " and finance_book = %s" %(frappe.db.escape(filters.finance_book))

View File

@ -130,7 +130,7 @@ def get_cash_flow_data(fiscal_year, companies, filters):
section_data.append(net_profit_loss) section_data.append(net_profit_loss)
for account in cash_flow_account['account_types']: for account in cash_flow_account['account_types']:
account_data = get_account_type_based_data(account['account_type'], companies, fiscal_year) account_data = get_account_type_based_data(account['account_type'], companies, fiscal_year, filters)
account_data.update({ account_data.update({
"account_name": account['label'], "account_name": account['label'],
"account": account['label'], "account": account['label'],
@ -148,12 +148,12 @@ def get_cash_flow_data(fiscal_year, companies, filters):
return data return data
def get_account_type_based_data(account_type, companies, fiscal_year): def get_account_type_based_data(account_type, companies, fiscal_year, filters):
data = {} data = {}
total = 0 total = 0
for company in companies: for company in companies:
amount = get_account_type_based_gl_data(company, amount = get_account_type_based_gl_data(company,
fiscal_year.year_start_date, fiscal_year.year_end_date, account_type) fiscal_year.year_start_date, fiscal_year.year_end_date, account_type, filters)
if amount and account_type == "Depreciation": if amount and account_type == "Depreciation":
amount *= -1 amount *= -1

View File

@ -159,13 +159,12 @@ frappe.query_reports["General Ledger"] = {
] ]
} }
erpnext.dimension_filters.then((dimensions) => { erpnext.dimension_filters.forEach((dimension) => {
dimensions.forEach((dimension) => { frappe.query_reports["General Ledger"].filters.splice(15, 0 ,{
frappe.query_reports["General Ledger"].filters.splice(15, 0 ,{ "fieldname": dimension["fieldname"],
"fieldname": dimension["fieldname"], "label": __(dimension["label"]),
"label": __(dimension["label"]), "fieldtype": "Link",
"fieldtype": "Link", "options": dimension["document_type"]
"options": dimension["document_type"]
});
}); });
}); });

View File

@ -105,9 +105,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"initial_depth": 3 "initial_depth": 3
} }
erpnext.dimension_filters.then((dimensions) => { erpnext.dimension_filters.forEach((dimension) => {
dimensions.forEach((dimension) => { frappe.query_reports["Profitability Analysis"].filters[1].options.push(dimension["document_type"]);
frappe.query_reports["Profitability Analysis"].filters[1].options.push(dimension["document_type"]);
});
}); });
}); });

View File

@ -68,13 +68,12 @@ frappe.query_reports["Sales Register"] = {
] ]
} }
erpnext.dimension_filters.then((dimensions) => { erpnext.dimension_filters.forEach((dimension) => {
dimensions.forEach((dimension) => { frappe.query_reports["Sales Register"].filters.splice(7, 0 ,{
frappe.query_reports["Sales Register"].filters.splice(7, 0 ,{ "fieldname": dimension["fieldname"],
"fieldname": dimension["fieldname"], "label": __(dimension["label"]),
"label": __(dimension["label"]), "fieldtype": "Link",
"fieldtype": "Link", "options": dimension["document_type"]
"options": dimension["document_type"]
});
}); });
}); });

View File

@ -94,10 +94,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"parent_field": "parent_account", "parent_field": "parent_account",
"initial_depth": 3 "initial_depth": 3
} }
});
erpnext.dimension_filters.then((dimensions) => { erpnext.dimension_filters.forEach((dimension) => {
dimensions.forEach((dimension) => {
frappe.query_reports["Trial Balance"].filters.splice(5, 0 ,{ frappe.query_reports["Trial Balance"].filters.splice(5, 0 ,{
"fieldname": dimension["fieldname"], "fieldname": dimension["fieldname"],
"label": __(dimension["label"]), "label": __(dimension["label"]),
@ -107,3 +105,5 @@ erpnext.dimension_filters.then((dimensions) => {
}); });
}); });

View File

@ -123,11 +123,12 @@ def get_rootwise_opening_balances(filters, report_type):
if accounting_dimensions: if accounting_dimensions:
for dimension in accounting_dimensions: for dimension in accounting_dimensions:
additional_conditions += """ and {0} in (%({0})s) """.format(dimension) if filters.get(dimension):
additional_conditions += """ and {0} in (%({0})s) """.format(dimension)
query_filters.update({ query_filters.update({
dimension: filters.get(dimension) dimension: filters.get(dimension)
}) })
gle = frappe.db.sql(""" gle = frappe.db.sql("""
select select

View File

@ -121,7 +121,12 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
allow_cost_center_in_entry_of_bs_account = get_allow_cost_center_in_entry_of_bs_account() allow_cost_center_in_entry_of_bs_account = get_allow_cost_center_in_entry_of_bs_account()
if cost_center and (allow_cost_center_in_entry_of_bs_account or acc.report_type =='Profit and Loss'): if account:
report_type = acc.report_type
else:
report_type = ""
if cost_center and (allow_cost_center_in_entry_of_bs_account or report_type =='Profit and Loss'):
cc = frappe.get_doc("Cost Center", cost_center) cc = frappe.get_doc("Cost Center", cost_center)
if cc.is_group: if cc.is_group:
cond.append(""" exists ( cond.append(""" exists (
@ -138,7 +143,7 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
if not frappe.flags.ignore_account_permission: if not frappe.flags.ignore_account_permission:
acc.check_permission("read") acc.check_permission("read")
if acc.report_type == 'Profit and Loss': if report_type == 'Profit and Loss':
# for pl accounts, get balance within a fiscal year # for pl accounts, get balance within a fiscal year
cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \ cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
% year_start_date) % year_start_date)
@ -685,7 +690,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None, filters
payment_amount = pe_map.get((d.voucher_type, d.voucher_no), 0) payment_amount = pe_map.get((d.voucher_type, d.voucher_no), 0)
outstanding_amount = flt(d.invoice_amount - payment_amount, precision) outstanding_amount = flt(d.invoice_amount - payment_amount, precision)
if outstanding_amount > 0.5 / (10**precision): if outstanding_amount > 0.5 / (10**precision):
if (filters.get("outstanding_amt_greater_than") and if (filters and filters.get("outstanding_amt_greater_than") and
not (outstanding_amount >= filters.get("outstanding_amt_greater_than") and not (outstanding_amount >= filters.get("outstanding_amt_greater_than") and
outstanding_amount <= filters.get("outstanding_amt_less_than"))): outstanding_amount <= filters.get("outstanding_amt_less_than"))):
continue continue

View File

@ -388,7 +388,8 @@ class Asset(AccountsController):
"remarks": self.get("remarks") or _("Accounting Entry for Asset"), "remarks": self.get("remarks") or _("Accounting Entry for Asset"),
"posting_date": self.available_for_use_date, "posting_date": self.available_for_use_date,
"credit": self.purchase_receipt_amount, "credit": self.purchase_receipt_amount,
"credit_in_account_currency": self.purchase_receipt_amount "credit_in_account_currency": self.purchase_receipt_amount,
"cost_center": self.cost_center
})) }))
gl_entries.append(self.get_gl_dict({ gl_entries.append(self.get_gl_dict({
@ -397,7 +398,8 @@ class Asset(AccountsController):
"remarks": self.get("remarks") or _("Accounting Entry for Asset"), "remarks": self.get("remarks") or _("Accounting Entry for Asset"),
"posting_date": self.available_for_use_date, "posting_date": self.available_for_use_date,
"debit": self.purchase_receipt_amount, "debit": self.purchase_receipt_amount,
"debit_in_account_currency": self.purchase_receipt_amount "debit_in_account_currency": self.purchase_receipt_amount,
"cost_center": self.cost_center
})) }))
if gl_entries: if gl_entries:

View File

@ -7,7 +7,7 @@
"doctype": "Report", "doctype": "Report",
"idx": 0, "idx": 0,
"is_standard": "Yes", "is_standard": "Yes",
"modified": "2019-03-29 17:18:06.678728", "modified": "2019-07-21 23:24:21.094269",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Buying", "module": "Buying",
"name": "Procurement Tracker", "name": "Procurement Tracker",
@ -16,5 +16,12 @@
"ref_doctype": "Purchase Order", "ref_doctype": "Purchase Order",
"report_name": "Procurement Tracker", "report_name": "Procurement Tracker",
"report_type": "Script Report", "report_type": "Script Report",
"roles": [] "roles": [
{
"role": "Purchase Manager"
},
{
"role": "Purchase User"
}
]
} }

View File

@ -150,10 +150,10 @@ def get_conditions(filters):
"""% (filters.get('cost_center'), filters.get('project')) """% (filters.get('cost_center'), filters.get('project'))
if filters.get("from_date"): if filters.get("from_date"):
conditions += "AND transaction_date>=%s"% filters.get('from_date') conditions += " AND transaction_date>=%s"% filters.get('from_date')
if filters.get("to_date"): if filters.get("to_date"):
conditions += "AND transaction_date<=%s"% filters.get('to_date') conditions += " AND transaction_date<=%s"% filters.get('to_date')
return conditions return conditions
def get_data(filters): def get_data(filters):

View File

@ -30,7 +30,7 @@ class TestProcurementTracker(unittest.TestCase):
company_name="_Test Procurement Company", company_name="_Test Procurement Company",
abbr="_TPC", abbr="_TPC",
default_currency="INR", default_currency="INR",
country="India" country="Pakistan"
)).insert() )).insert()
warehouse = create_warehouse("_Test Procurement Warehouse", company="_Test Procurement Company") warehouse = create_warehouse("_Test Procurement Warehouse", company="_Test Procurement Company")
mr = make_material_request(company="_Test Procurement Company", warehouse=warehouse) mr = make_material_request(company="_Test Procurement Company", warehouse=warehouse)

View File

@ -157,6 +157,13 @@ def get_data():
"reference_doctype": "Purchase Order", "reference_doctype": "Purchase Order",
"onboard": 1, "onboard": 1,
}, },
{
"type": "report",
"is_query_report": True,
"name": "Procurement Tracker",
"reference_doctype": "Purchase Order",
"onboard": 1,
},
{ {
"type": "report", "type": "report",
"is_query_report": True, "is_query_report": True,

View File

@ -141,6 +141,11 @@ def get_data():
"name": "Campaign", "name": "Campaign",
"description": _("Sales campaigns."), "description": _("Sales campaigns."),
}, },
{
"type": "doctype",
"name": "Email Campaign",
"description": _("Sends Mails to lead or contact based on a Campaign schedule"),
},
{ {
"type": "doctype", "type": "doctype",
"name": "SMS Center", "name": "SMS Center",

View File

@ -219,6 +219,11 @@ def get_data():
"name": "Employee Onboarding", "name": "Employee Onboarding",
"dependencies": ["Job Applicant"], "dependencies": ["Job Applicant"],
}, },
{
"type": "doctype",
"name": "Employee Skill Map",
"dependencies": ["Employee"],
},
{ {
"type": "doctype", "type": "doctype",
"name": "Employee Promotion", "name": "Employee Promotion",

View File

@ -60,7 +60,9 @@ class AccountsController(TransactionBase):
def validate(self): def validate(self):
self.validate_qty_is_not_zero() if not self.get('is_return'):
self.validate_qty_is_not_zero()
if self.get("_action") and self._action != "update_after_submit": if self.get("_action") and self._action != "update_after_submit":
self.set_missing_values(for_validate=True) self.set_missing_values(for_validate=True)
@ -861,7 +863,7 @@ class AccountsController(TransactionBase):
if self.doctype in ("Sales Invoice", "Purchase Invoice"): if self.doctype in ("Sales Invoice", "Purchase Invoice"):
grand_total = grand_total - flt(self.write_off_amount) grand_total = grand_total - flt(self.write_off_amount)
if total != grand_total: if total != flt(grand_total, self.precision("grand_total")):
frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total")) frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total"))
def is_rounded_total_disabled(self): def is_rounded_total_disabled(self):

View File

@ -636,7 +636,8 @@ class BuyingController(StockController):
asset.set_missing_values() asset.set_missing_values()
asset.insert() asset.insert()
frappe.msgprint(_("Asset {0} created").format(asset.name)) asset_link = frappe.utils.get_link_to_form('Asset', asset.name)
frappe.msgprint(_("Asset {0} created").format(asset_link))
return asset.name return asset.name
def make_asset_movement(self, row): def make_asset_movement(self, row):

View File

@ -207,10 +207,10 @@ def bom(doctype, txt, searchfield, start, page_len, filters):
idx desc, name idx desc, name
limit %(start)s, %(page_len)s """.format( limit %(start)s, %(page_len)s """.format(
fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'), fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'),
mcond=get_match_cond(doctype), mcond=get_match_cond(doctype).replace('%', '%%'),
key=frappe.db.escape(searchfield)), key=searchfield),
{ {
'txt': "%"+frappe.db.escape(txt)+"%", 'txt': '%' + txt + '%',
'_txt': txt.replace("%", ""), '_txt': txt.replace("%", ""),
'start': start or 0, 'start': start or 0,
'page_len': page_len or 20 'page_len': page_len or 20

View File

@ -40,7 +40,6 @@ status_map = {
["To Bill", "eval:self.per_delivered == 100 and self.per_billed < 100 and self.docstatus == 1"], ["To Bill", "eval:self.per_delivered == 100 and self.per_billed < 100 and self.docstatus == 1"],
["To Deliver", "eval:self.per_delivered < 100 and self.per_billed == 100 and self.docstatus == 1"], ["To Deliver", "eval:self.per_delivered < 100 and self.per_billed == 100 and self.docstatus == 1"],
["Completed", "eval:self.per_delivered == 100 and self.per_billed == 100 and self.docstatus == 1"], ["Completed", "eval:self.per_delivered == 100 and self.per_billed == 100 and self.docstatus == 1"],
["Completed", "eval:self.order_type == 'Maintenance' and self.per_billed == 100 and self.docstatus == 1"],
["Cancelled", "eval:self.docstatus==2"], ["Cancelled", "eval:self.docstatus==2"],
["Closed", "eval:self.status=='Closed'"], ["Closed", "eval:self.status=='Closed'"],
["On Hold", "eval:self.status=='On Hold'"], ["On Hold", "eval:self.status=='On Hold'"],
@ -90,7 +89,8 @@ status_map = {
["Transferred", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Transfer'"], ["Transferred", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Transfer'"],
["Issued", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Issue'"], ["Issued", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Issue'"],
["Received", "eval:self.status != 'Stopped' and self.per_received == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"], ["Received", "eval:self.status != 'Stopped' and self.per_received == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
["Partially Received", "eval:self.status != 'Stopped' and self.per_received > 0 and self.per_received < 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"] ["Partially Received", "eval:self.status != 'Stopped' and self.per_received > 0 and self.per_received < 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
["Manufactured", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Manufacture'"]
], ],
"Bank Transaction": [ "Bank Transaction": [
["Unreconciled", "eval:self.docstatus == 1 and self.unallocated_amount>0"], ["Unreconciled", "eval:self.docstatus == 1 and self.unallocated_amount>0"],

View File

@ -81,7 +81,12 @@ class calculate_taxes_and_totals(object):
item.discount_amount = item.price_list_rate - item.rate item.discount_amount = item.price_list_rate - item.rate
item.net_rate = item.rate item.net_rate = item.rate
item.amount = flt(item.rate * item.qty, item.precision("amount"))
if not item.qty and self.doc.is_return:
item.amount = flt(-1 * item.rate, item.precision("amount"))
else:
item.amount = flt(item.rate * item.qty, item.precision("amount"))
item.net_amount = item.amount item.net_amount = item.amount
self._set_in_company_currency(item, ["price_list_rate", "rate", "net_rate", "amount", "net_amount"]) self._set_in_company_currency(item, ["price_list_rate", "rate", "net_rate", "amount", "net_amount"])

View File

@ -0,0 +1,38 @@
{
"creation": "2019-06-30 15:56:20.306901",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"email_template",
"send_after_days"
],
"fields": [
{
"fieldname": "send_after_days",
"fieldtype": "Int",
"in_list_view": 1,
"label": "Send After (days)",
"reqd": 1
},
{
"fieldname": "email_template",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Email Template",
"options": "Email Template",
"reqd": 1
}
],
"istable": 1,
"modified": "2019-07-12 11:46:43.184123",
"modified_by": "Administrator",
"module": "CRM",
"name": "Campaign Email Schedule",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
# import frappe
from frappe.model.document import Document
class CampaignEmailSchedule(Document):
pass

View File

@ -0,0 +1,8 @@
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Email Campaign', {
email_campaign_for: function(frm) {
frm.set_value('recipient', '');
}
});

View File

@ -0,0 +1,95 @@
{
"autoname": "format:MAIL-CAMP-{YYYY}-{#####}",
"creation": "2019-06-30 16:05:30.015615",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"campaign_name",
"email_campaign_for",
"recipient",
"sender",
"column_break_4",
"start_date",
"end_date",
"status"
],
"fields": [
{
"fieldname": "campaign_name",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Campaign",
"options": "Campaign",
"reqd": 1
},
{
"fieldname": "status",
"fieldtype": "Select",
"label": "Status",
"options": "\nScheduled\nIn Progress\nCompleted\nUnsubscribed",
"read_only": 1
},
{
"fieldname": "column_break_4",
"fieldtype": "Column Break"
},
{
"fieldname": "start_date",
"fieldtype": "Date",
"label": "Start Date",
"reqd": 1
},
{
"fieldname": "end_date",
"fieldtype": "Date",
"label": "End Date",
"read_only": 1
},
{
"default": "Lead",
"fieldname": "email_campaign_for",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Email Campaign For ",
"options": "\nLead\nContact"
},
{
"fieldname": "recipient",
"fieldtype": "Dynamic Link",
"label": "Recipient",
"options": "email_campaign_for",
"reqd": 1
},
{
"default": "__user",
"fieldname": "sender",
"fieldtype": "Link",
"label": "Sender",
"options": "User"
}
],
"modified": "2019-07-12 13:47:37.261213",
"modified_by": "Administrator",
"module": "CRM",
"name": "Email Campaign",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@ -0,0 +1,102 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import getdate, add_days, today, nowdate, cstr
from frappe.model.document import Document
from frappe.core.doctype.communication.email import make
class EmailCampaign(Document):
def validate(self):
self.set_date()
#checking if email is set for lead. Not checking for contact as email is a mandatory field for contact.
if self.email_campaign_for == "Lead":
self.validate_lead()
self.validate_email_campaign_already_exists()
self.update_status()
def set_date(self):
if getdate(self.start_date) < getdate(today()):
frappe.throw(_("Start Date cannot be before the current date"))
#set the end date as start date + max(send after days) in campaign schedule
send_after_days = []
campaign = frappe.get_doc("Campaign", self.campaign_name)
for entry in campaign.get("campaign_schedules"):
send_after_days.append(entry.send_after_days)
try:
end_date = add_days(getdate(self.start_date), max(send_after_days))
except ValueError:
frappe.throw(_("Please set up the Campaign Schedule in the Campaign {0}").format(self.campaign_name))
def validate_lead(self):
lead_email_id = frappe.db.get_value("Lead", self.recipient, 'email_id')
if not lead_email_id:
lead_name = frappe.db.get_value("Lead", self.recipient, 'lead_name')
frappe.throw(_("Please set an email id for the Lead {0}").format(lead_name))
def validate_email_campaign_already_exists(self):
email_campaign_exists = frappe.db.exists("Email Campaign", {
"campaign_name": self.campaign_name,
"recipient": self.recipient,
"status": ("in", ["In Progress", "Scheduled"])
})
if email_campaign_exists:
frappe.throw(_("The Campaign '{0}' already exists for the {1} '{2}'").format(self.campaign_name, self.email_campaign_for, self.recipient))
def update_status(self):
start_date = getdate(self.start_date)
end_date = getdate(self.end_date)
today_date = getdate(today())
if start_date > today_date:
self.status = "Scheduled"
elif end_date >= today_date:
self.status = "In Progress"
elif end_date < today_date:
self.status = "Completed"
#called through hooks to send campaign mails to leads
def send_email_to_leads_or_contacts():
email_campaigns = frappe.get_all("Email Campaign", filters = { 'status': ('not in', ['Unsubscribed', 'Completed', 'Scheduled']) })
for camp in email_campaigns:
email_campaign = frappe.get_doc("Email Campaign", camp.name)
campaign = frappe.get_cached_doc("Campaign", email_campaign.campaign_name)
for entry in campaign.get("campaign_schedules"):
scheduled_date = add_days(email_campaign.get('start_date'), entry.get('send_after_days'))
if scheduled_date == getdate(today()):
send_mail(entry, email_campaign)
def send_mail(entry, email_campaign):
recipient = frappe.db.get_value(email_campaign.email_campaign_for, email_campaign.get("recipient"), 'email_id')
email_template = frappe.get_doc("Email Template", entry.get("email_template"))
sender = frappe.db.get_value("User", email_campaign.get("sender"), 'email')
# send mail and link communication to document
comm = make(
doctype = "Email Campaign",
name = email_campaign.name,
subject = email_template.get("subject"),
content = email_template.get("response"),
sender = sender,
recipients = recipient,
communication_medium = "Email",
sent_or_received = "Sent",
send_email = True,
email_template = email_template.name
)
return comm
#called from hooks on doc_event Email Unsubscribe
def unsubscribe_recipient(unsubscribe, method):
if unsubscribe.reference_doctype == 'Email Campaign':
frappe.db.set_value("Email Campaign", unsubscribe.reference_name, "status", "Unsubscribed")
#called through hooks to update email campaign status daily
def set_email_campaign_status():
email_campaigns = frappe.get_all("Email Campaign", filters = { 'status': ('!=', 'Unsubscribed')})
for entry in email_campaigns:
email_campaign = frappe.get_doc("Email Campaign", entry.name)
email_campaign.update_status()

View File

@ -0,0 +1,11 @@
frappe.listview_settings['Email Campaign'] = {
get_indicator: function(doc) {
var colors = {
"Unsubscribed": "red",
"Scheduled": "blue",
"In Progress": "orange",
"Completed": "green"
};
return [__(doc.status), colors[doc.status], "status,=," + doc.status];
}
};

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals
# import frappe
import unittest
class TestEmailCampaign(unittest.TestCase):
pass

View File

@ -7,14 +7,8 @@ cur_frm.email_field = "email_id";
erpnext.LeadController = frappe.ui.form.Controller.extend({ erpnext.LeadController = frappe.ui.form.Controller.extend({
setup: function () { setup: function () {
this.frm.make_methods = { this.frm.make_methods = {
'Quotation': () => erpnext.utils.create_new_doc('Quotation', { 'Quotation': this.make_quotation,
'quotation_to': this.frm.doc.doctype, 'Opportunity': this.create_opportunity
'party_name': this.frm.doc.name
}),
'Opportunity': () => erpnext.utils.create_new_doc('Opportunity', {
'opportunity_from': this.frm.doc.doctype,
'party_name': this.frm.doc.name
})
} }
this.frm.fields_dict.customer.get_query = function (doc, cdt, cdn) { this.frm.fields_dict.customer.get_query = function (doc, cdt, cdn) {

View File

@ -296,7 +296,9 @@ class TallyMigration(Document):
else: else:
function = voucher_to_journal_entry function = voucher_to_journal_entry
try: try:
vouchers.append(function(voucher)) processed_voucher = function(voucher)
if processed_voucher:
vouchers.append(processed_voucher)
except: except:
self.log(voucher) self.log(voucher)
return vouchers return vouchers
@ -342,6 +344,10 @@ class TallyMigration(Document):
account_field = "credit_to" account_field = "credit_to"
account_name = encode_company_abbr(self.tally_creditors_account, self.erpnext_company) account_name = encode_company_abbr(self.tally_creditors_account, self.erpnext_company)
price_list_field = "buying_price_list" price_list_field = "buying_price_list"
else:
# Do not handle vouchers other than "Purchase", "Debit Note", "Sales" and "Credit Note"
# Do not handle Custom Vouchers either
return
invoice = { invoice = {
"doctype": doctype, "doctype": doctype,

View File

@ -233,6 +233,9 @@ doc_events = {
}, },
"Contact":{ "Contact":{
"on_trash": "erpnext.support.doctype.issue.issue.update_issue" "on_trash": "erpnext.support.doctype.issue.issue.update_issue"
},
"Email Unsubscribe": {
"after_insert": "erpnext.crm.doctype.email_campaign.email_campaign.unsubscribe_recipient"
} }
} }
@ -272,6 +275,8 @@ scheduler_events = {
"erpnext.projects.doctype.project.project.send_project_status_email_to_users", "erpnext.projects.doctype.project.project.send_project_status_email_to_users",
"erpnext.quality_management.doctype.quality_review.quality_review.review", "erpnext.quality_management.doctype.quality_review.quality_review.review",
"erpnext.support.doctype.service_level_agreement.service_level_agreement.check_agreement_status", "erpnext.support.doctype.service_level_agreement.service_level_agreement.check_agreement_status",
"erpnext.crm.doctype.email_campaign.email_campaign.send_email_to_leads_or_contacts",
"erpnext.crm.doctype.email_campaign.email_campaign.set_email_campaign_status"
], ],
"daily_long": [ "daily_long": [
"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms" "erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms"

View File

@ -4,4 +4,17 @@ from __future__ import unicode_literals
import frappe import frappe
test_records = frappe.get_test_records('Designation') # test_records = frappe.get_test_records('Designation')
def create_designation(**args):
args = frappe._dict(args)
if frappe.db.exists("Designation", args.designation_name or "_Test designation"):
return frappe.get_doc("Designation", args.designation_name or "_Test designation")
designation = frappe.get_doc({
"doctype": "Designation",
"designation_name": args.designation_name or "_Test designation",
"description": args.description or "_Test description"
})
designation.save()
return designation

View File

@ -1,516 +1,124 @@
{ {
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 1, "allow_import": 1,
"allow_rename": 1, "allow_rename": 1,
"autoname": "naming_series:", "autoname": "naming_series:",
"beta": 0,
"creation": "2017-10-17 08:21:50.489773", "creation": "2017-10-17 08:21:50.489773",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "Setup", "document_type": "Setup",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"naming_series",
"full_name",
"status",
"transporter",
"column_break_2",
"employee",
"cell_number",
"address",
"license_details",
"license_number",
"column_break_8",
"issuing_date",
"column_break_10",
"expiry_date",
"driving_license_categories",
"driving_license_category"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "naming_series", "fieldname": "naming_series",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Series", "label": "Series",
"length": 0, "options": "HR-DRI-.YYYY.-"
"no_copy": 0,
"options": "HR-DRI-.YYYY.-",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "full_name", "fieldname": "full_name",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Full Name", "label": "Full Name",
"length": 0, "reqd": 1
"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": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "status", "fieldname": "status",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Status", "label": "Status",
"length": 0,
"no_copy": 0,
"options": "Active\nSuspended\nLeft", "options": "Active\nSuspended\nLeft",
"permlevel": 0, "reqd": 1
"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": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 1, "allow_in_quick_entry": 1,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Applicable for external driver", "description": "Applicable for external driver",
"fieldname": "transporter", "fieldname": "transporter",
"fieldtype": "Link", "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": "Transporter", "label": "Transporter",
"length": 0, "options": "Supplier"
"no_copy": 0,
"options": "Supplier",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_2", "fieldname": "column_break_2",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "employee", "fieldname": "employee",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Employee", "label": "Employee",
"length": 0, "options": "Employee"
"no_copy": 0,
"options": "Employee",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cell_number", "fieldname": "cell_number",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0, "label": "Cellphone Number"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Cellphone Number",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "license_details", "fieldname": "license_details",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "License Details"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "License 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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "license_number", "fieldname": "license_number",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0, "label": "License Number"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "License Number",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_8", "fieldname": "column_break_8",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "issuing_date", "fieldname": "issuing_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "label": "Issuing Date"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Issuing Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_10", "fieldname": "column_break_10",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "expiry_date", "fieldname": "expiry_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "label": "Expiry Date"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Expiry Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "driving_license_categories", "fieldname": "driving_license_categories",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "Driving License Categories"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Driving License Categories",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "driving_license_category", "fieldname": "driving_license_category",
"fieldtype": "Table", "fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Driving License Category", "label": "Driving License Category",
"length": 0, "options": "Driving License Category"
"no_copy": 0, },
"options": "Driving License Category", {
"permlevel": 0, "fieldname": "address",
"precision": "", "fieldtype": "Link",
"print_hide": 0, "label": "Address",
"print_hide_if_no_value": 0, "options": "Address"
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
} }
], ],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-user", "icon": "fa fa-user",
"idx": 0, "modified": "2019-07-18 16:29:14.151380",
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-10-03 19:53:50.924391",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Driver", "name": "Driver",
@ -518,72 +126,44 @@
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Fleet Manager", "role": "Fleet Manager",
"set_user_permissions": 0, "share": 1
"share": 1,
"submit": 0,
"write": 0
}, },
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "HR User", "role": "HR User",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "HR Manager", "role": "HR Manager",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
} }
], ],
"quick_entry": 1, "quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "full_name", "search_fields": "full_name",
"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": "full_name", "title_field": "full_name",
"track_changes": 1, "track_changes": 1
"track_seen": 0,
"track_views": 0
} }

View File

@ -12,6 +12,7 @@ from frappe.permissions import add_user_permission, remove_user_permission, \
from frappe.model.document import Document from frappe.model.document import Document
from erpnext.utilities.transaction_base import delete_events from erpnext.utilities.transaction_base import delete_events
from frappe.utils.nestedset import NestedSet from frappe.utils.nestedset import NestedSet
from erpnext.hr.doctype.job_offer.job_offer import get_staffing_plan_detail
class EmployeeUserDisabledError(frappe.ValidationError): pass class EmployeeUserDisabledError(frappe.ValidationError): pass
class EmployeeLeftValidationError(frappe.ValidationError): pass class EmployeeLeftValidationError(frappe.ValidationError): pass

View File

@ -3,6 +3,7 @@
"doctype": "DocType", "doctype": "DocType",
"document_type": "Other", "document_type": "Other",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB",
"field_order": [ "field_order": [
"employee_settings", "employee_settings",
"retirement_age", "retirement_age",
@ -22,7 +23,9 @@
"leave_status_notification_template", "leave_status_notification_template",
"column_break_18", "column_break_18",
"leave_approver_mandatory_in_leave_application", "leave_approver_mandatory_in_leave_application",
"show_leaves_of_all_department_members_in_calendar" "show_leaves_of_all_department_members_in_calendar",
"hiring_settings",
"check_vacancies"
], ],
"fields": [ "fields": [
{ {
@ -44,18 +47,6 @@
"label": "Employee Records to be created by", "label": "Employee Records to be created by",
"options": "Naming Series\nEmployee Number\nFull Name" "options": "Naming Series\nEmployee Number\nFull Name"
}, },
{
"fieldname": "leave_approval_notification_template",
"fieldtype": "Link",
"label": "Leave Approval Notification Template",
"options": "Email Template"
},
{
"fieldname": "leave_status_notification_template",
"fieldtype": "Link",
"label": "Leave Status Notification Template",
"options": "Email Template"
},
{ {
"fieldname": "column_break_4", "fieldname": "column_break_4",
"fieldtype": "Column Break" "fieldtype": "Column Break"
@ -67,12 +58,6 @@
"fieldtype": "Check", "fieldtype": "Check",
"label": "Stop Birthday Reminders" "label": "Stop Birthday Reminders"
}, },
{
"default": "1",
"fieldname": "leave_approver_mandatory_in_leave_application",
"fieldtype": "Check",
"label": "Leave Approver Mandatory In Leave Application"
},
{ {
"default": "1", "default": "1",
"fieldname": "expense_approver_mandatory_in_expense_claim", "fieldname": "expense_approver_mandatory_in_expense_claim",
@ -91,6 +76,15 @@
"fieldtype": "Check", "fieldtype": "Check",
"label": "Include holidays in Total no. of Working Days" "label": "Include holidays in Total no. of Working Days"
}, },
{
"fieldname": "max_working_hours_against_timesheet",
"fieldtype": "Float",
"label": "Max working hours against Timesheet"
},
{
"fieldname": "column_break_11",
"fieldtype": "Column Break"
},
{ {
"default": "1", "default": "1",
"description": "Emails salary slip to employee based on preferred email selected in Employee", "description": "Emails salary slip to employee based on preferred email selected in Employee",
@ -115,15 +109,33 @@
"label": "Password Policy" "label": "Password Policy"
}, },
{ {
"fieldname": "max_working_hours_against_timesheet", "collapsible": 1,
"fieldtype": "Float",
"label": "Max working hours against Timesheet"
},
{
"fieldname": "leave_settings", "fieldname": "leave_settings",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Leave Settings" "label": "Leave Settings"
}, },
{
"fieldname": "leave_approval_notification_template",
"fieldtype": "Link",
"label": "Leave Approval Notification Template",
"options": "Email Template"
},
{
"fieldname": "leave_status_notification_template",
"fieldtype": "Link",
"label": "Leave Status Notification Template",
"options": "Email Template"
},
{
"fieldname": "column_break_18",
"fieldtype": "Column Break"
},
{
"default": "1",
"fieldname": "leave_approver_mandatory_in_leave_application",
"fieldtype": "Check",
"label": "Leave Approver Mandatory In Leave Application"
},
{ {
"default": "0", "default": "0",
"fieldname": "show_leaves_of_all_department_members_in_calendar", "fieldname": "show_leaves_of_all_department_members_in_calendar",
@ -131,18 +143,22 @@
"label": "Show Leaves Of All Department Members In Calendar" "label": "Show Leaves Of All Department Members In Calendar"
}, },
{ {
"fieldname": "column_break_11", "collapsible": 1,
"fieldtype": "Column Break" "fieldname": "hiring_settings",
"fieldtype": "Section Break",
"label": "Hiring Settings"
}, },
{ {
"fieldname": "column_break_18", "default": "0",
"fieldtype": "Column Break" "fieldname": "check_vacancies",
"fieldtype": "Check",
"label": "Check Vacancies On Job Offer Creation"
} }
], ],
"icon": "fa fa-cog", "icon": "fa fa-cog",
"idx": 1, "idx": 1,
"issingle": 1, "issingle": 1,
"modified": "2019-05-31 16:18:50.245872", "modified": "2019-07-01 18:59:55.256878",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "HR Settings", "name": "HR Settings",
@ -158,5 +174,6 @@
"write": 1 "write": 1
} }
], ],
"sort_field": "modified",
"sort_order": "ASC" "sort_order": "ASC"
} }

View File

@ -39,7 +39,7 @@
"read_only": 0, "read_only": 0,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 1,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0, "translatable": 0,
@ -71,7 +71,7 @@
"read_only": 0, "read_only": 0,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 1,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0, "translatable": 0,
@ -96,7 +96,7 @@
"label": "Status", "label": "Status",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Open\nReplied\nRejected\nHold", "options": "Open\nReplied\nRejected\nHold\nAccepted",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
@ -346,7 +346,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-08-21 16:15:43.552049", "modified": "2019-06-21 16:15:43.552049",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Job Applicant", "name": "Job Applicant",

View File

@ -10,3 +10,14 @@ import unittest
class TestJobApplicant(unittest.TestCase): class TestJobApplicant(unittest.TestCase):
pass pass
def create_job_applicant(**args):
args = frappe._dict(args)
job_applicant = frappe.get_doc({
"doctype": "Job Applicant",
"applicant_name": args.applicant_name or "_Test Applicant",
"email_id": args.email_id or "test_applicant@example.com",
"status": args.status or "Open"
})
job_applicant.save()
return job_applicant

View File

@ -5,12 +5,56 @@ from __future__ import unicode_literals
import frappe import frappe
from frappe.model.document import Document from frappe.model.document import Document
from frappe.model.mapper import get_mapped_doc from frappe.model.mapper import get_mapped_doc
from frappe import _
from frappe.utils.data import get_link_to_form
class JobOffer(Document): class JobOffer(Document):
def onload(self): def onload(self):
employee = frappe.db.get_value("Employee", {"job_applicant": self.job_applicant}, "name") or "" employee = frappe.db.get_value("Employee", {"job_applicant": self.job_applicant}, "name") or ""
self.set_onload("employee", employee) self.set_onload("employee", employee)
def validate(self):
self.validate_vacancies()
def validate_vacancies(self):
staffing_plan = get_staffing_plan_detail(self.designation, self.company, self.offer_date)
check_vacancies = frappe.get_single("HR Settings").check_vacancies
if staffing_plan and check_vacancies:
vacancies = frappe.db.get_value("Staffing Plan Detail", filters={"name": staffing_plan.name}, fieldname=['vacancies'])
job_offers = len(self.get_job_offer(staffing_plan.from_date, staffing_plan.to_date))
if vacancies - job_offers <= 0:
frappe.throw(_("There are no vacancies under staffing plan {0}").format(get_link_to_form("Staffing Plan", staffing_plan.parent)))
def on_change(self):
update_job_applicant(self.status, self.job_applicant)
def get_job_offer(self, from_date, to_date):
''' Returns job offer created during a time period '''
return frappe.get_all("Job Offer", filters={
"offer_date": ['between', (from_date, to_date)],
"designation": self.designation,
"company": self.company
}, fields=['name'])
def update_job_applicant(status, job_applicant):
if status in ("Accepted", "Rejected"):
frappe.set_value("Job Applicant", job_applicant, "status", status)
def get_staffing_plan_detail(designation, company, offer_date):
detail = frappe.db.sql("""
SELECT spd.name as name,
sp.from_date as from_date,
sp.to_date as to_date,
sp.name as parent
FROM `tabStaffing Plan Detail` spd, `tabStaffing Plan` sp
WHERE
sp.docstatus=1
AND spd.designation=%s
AND sp.company=%s
AND %s between sp.from_date and sp.to_date
""", (designation, company, offer_date), as_dict=1)
return detail[0] if detail else None
@frappe.whitelist() @frappe.whitelist()
def make_employee(source_name, target_doc=None): def make_employee(source_name, target_doc=None):
def set_missing_values(source, target): def set_missing_values(source, target):
@ -23,4 +67,3 @@ def make_employee(source_name, target_doc=None):
}} }}
}, target_doc, set_missing_values) }, target_doc, set_missing_values)
return doc return doc

View File

@ -4,8 +4,78 @@ from __future__ import unicode_literals
import frappe import frappe
import unittest import unittest
from frappe.utils import nowdate, add_days
from erpnext.hr.doctype.job_applicant.test_job_applicant import create_job_applicant
from erpnext.hr.doctype.designation.test_designation import create_designation
from erpnext.hr.doctype.staffing_plan.test_staffing_plan import make_company
# test_records = frappe.get_test_records('Job Offer') # test_records = frappe.get_test_records('Job Offer')
class TestJobOffer(unittest.TestCase): class TestJobOffer(unittest.TestCase):
pass def test_job_offer_creation_against_vacancies(self):
create_staffing_plan(staffing_details=[{
"designation": "Designer",
"vacancies": 0,
"estimated_cost_per_position": 5000
}])
frappe.db.set_value("HR Settings", None, "check_vacancies", 1)
job_applicant = create_job_applicant(email_id="test_job_offer@example.com")
job_offer = create_job_offer(job_applicant=job_applicant.name, designation="Researcher")
self.assertRaises(frappe.ValidationError, job_offer.submit)
# test creation of job offer when vacancies are not present
frappe.db.set_value("HR Settings", None, "check_vacancies", 0)
job_offer.submit()
self.assertTrue(frappe.db.exists("Job Offer", job_offer.name))
def test_job_applicant_update(self):
create_staffing_plan()
job_applicant = create_job_applicant(email_id="test_job_applicants@example.com")
job_offer = create_job_offer(job_applicant=job_applicant.name)
job_offer.submit()
job_applicant.reload()
self.assertEquals(job_applicant.status, "Accepted")
# status update after rejection
job_offer.status = "Rejected"
job_offer.submit()
job_applicant.reload()
self.assertEquals(job_applicant.status, "Rejected")
def create_job_offer(**args):
args = frappe._dict(args)
if not args.job_applicant:
job_applicant = create_job_applicant()
if not frappe.db.exists("Designation", args.designation):
designation = create_designation(designation_name=args.designation)
job_offer = frappe.get_doc({
"doctype": "Job Offer",
"job_applicant": args.job_applicant or job_applicant.name,
"offer_date": args.offer_date or nowdate(),
"designation": args.designation or "Researcher",
"status": args.status or "Accepted"
})
return job_offer
def create_staffing_plan(**args):
args = frappe._dict(args)
make_company()
frappe.db.set_value("Company", "_Test Company", "is_group", 1)
if frappe.db.exists("Staffing Plan", args.name or "Test"):
return
staffing_plan = frappe.get_doc({
"doctype": "Staffing Plan",
"name": args.name or "Test",
"from_date": args.from_date or nowdate(),
"to_date": args.to_date or add_days(nowdate(), 10),
"staffing_details": args.staffing_details or [{
"designation": "Researcher",
"vacancies": 1,
"estimated_cost_per_position": 50000
}]
})
staffing_plan.insert()
staffing_plan.submit()
return staffing_plan

View File

@ -30,11 +30,11 @@ class LoanApplication(Document):
monthly_interest_rate = flt(self.rate_of_interest) / (12 *100) monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
if monthly_interest_rate: if monthly_interest_rate:
min_repayment_amount = self.loan_amount*monthly_interest_rate min_repayment_amount = self.loan_amount*monthly_interest_rate
if self.repayment_amount - min_repayment_amount < 0: if self.repayment_amount - min_repayment_amount <= 0:
frappe.throw(_("Repayment Amount must be greater than " \ frappe.throw(_("Repayment Amount must be greater than " \
+ str(flt(min_repayment_amount, 2)))) + str(flt(min_repayment_amount, 2))))
self.repayment_periods = math.ceil(math.log(self.repayment_amount) - self.repayment_periods = math.ceil((math.log(self.repayment_amount) -
math.log(self.repayment_amount - min_repayment_amount) /(math.log(1 + monthly_interest_rate))) math.log(self.repayment_amount - min_repayment_amount)) /(math.log(1 + monthly_interest_rate)))
else: else:
self.repayment_periods = self.loan_amount / self.repayment_amount self.repayment_periods = self.loan_amount / self.repayment_amount

View File

@ -119,6 +119,8 @@ class PayrollEntry(Document):
frappe.enqueue(create_salary_slips_for_employees, timeout=600, employees=emp_list, args=args) frappe.enqueue(create_salary_slips_for_employees, timeout=600, employees=emp_list, args=args)
else: else:
create_salary_slips_for_employees(emp_list, args, publish_progress=False) create_salary_slips_for_employees(emp_list, args, publish_progress=False)
# since this method is called via frm.call this doc needs to be updated manually
self.reload()
def get_sal_slip_list(self, ss_status, as_dict=False): def get_sal_slip_list(self, ss_status, as_dict=False):
""" """

View File

@ -5,7 +5,7 @@ frappe.ui.form.on('Staffing Plan', {
setup: function(frm) { setup: function(frm) {
frm.set_query("designation", "staffing_details", function() { frm.set_query("designation", "staffing_details", function() {
let designations = []; let designations = [];
$.each(frm.doc.staffing_details, function(index, staff_detail) { (frm.doc.staffing_details || []).forEach(function(staff_detail) {
if(staff_detail.designation){ if(staff_detail.designation){
designations.push(staff_detail.designation) designations.push(staff_detail.designation)
} }
@ -25,69 +25,63 @@ frappe.ui.form.on('Staffing Plan', {
} }
}; };
}); });
} },
}); });
frappe.ui.form.on('Staffing Plan Detail', { frappe.ui.form.on('Staffing Plan Detail', {
designation: function(frm, cdt, cdn) { designation: function(frm, cdt, cdn) {
let child = locals[cdt][cdn] let child = locals[cdt][cdn];
if(frm.doc.company && child.designation){ if(frm.doc.company && child.designation) {
frappe.call({ set_number_of_positions(frm, cdt, cdn);
"method": "erpnext.hr.doctype.staffing_plan.staffing_plan.get_designation_counts",
args: {
designation: child.designation,
company: frm.doc.company
},
callback: function (data) {
if(data.message){
frappe.model.set_value(cdt, cdn, 'current_count', data.message.employee_count);
frappe.model.set_value(cdt, cdn, 'current_openings', data.message.job_openings);
if (child.number_of_positions < (data.message.employee_count + data.message.job_openings)){
frappe.model.set_value(cdt, cdn, 'number_of_positions', data.message.employee_count + data.message.job_openings);
}
}
else{ // No employees for this designation
frappe.model.set_value(cdt, cdn, 'current_count', 0);
frappe.model.set_value(cdt, cdn, 'current_openings', 0);
}
}
});
} }
}, },
number_of_positions: function(frm, cdt, cdn) { vacancies: function(frm, cdt, cdn) {
set_vacancies(frm, cdt, cdn); let child = locals[cdt][cdn];
if(child.vacancies < child.current_openings) {
frappe.throw(__("Vacancies cannot be lower than the current openings"));
}
set_number_of_positions(frm, cdt, cdn);
}, },
current_count: function(frm, cdt, cdn) { current_count: function(frm, cdt, cdn) {
set_vacancies(frm, cdt, cdn); set_number_of_positions(frm, cdt, cdn);
}, },
estimated_cost_per_position: function(frm, cdt, cdn) { estimated_cost_per_position: function(frm, cdt, cdn) {
let child = locals[cdt][cdn];
set_total_estimated_cost(frm, cdt, cdn); set_total_estimated_cost(frm, cdt, cdn);
} }
}); });
var set_vacancies = function(frm, cdt, cdn) { var set_number_of_positions = function(frm, cdt, cdn) {
let child = locals[cdt][cdn] let child = locals[cdt][cdn];
if (child.number_of_positions < (child.current_count + child.current_openings)){ if (!child.designation) frappe.throw(__("Please enter the designation"));
frappe.throw(__("Number of positions cannot be less then current count of employees")) frappe.call({
} "method": "erpnext.hr.doctype.staffing_plan.staffing_plan.get_designation_counts",
args: {
if(child.number_of_positions > 0) { designation: child.designation,
frappe.model.set_value(cdt, cdn, 'vacancies', child.number_of_positions - (child.current_count + child.current_openings)); company: frm.doc.company
} },
else{ callback: function (data) {
frappe.model.set_value(cdt, cdn, 'vacancies', 0); if(data.message){
} frappe.model.set_value(cdt, cdn, 'current_count', data.message.employee_count);
frappe.model.set_value(cdt, cdn, 'current_openings', data.message.job_openings);
let total_positions = cint(data.message.employee_count) + cint(child.vacancies);
if (cint(child.number_of_positions) < total_positions){
frappe.model.set_value(cdt, cdn, 'number_of_positions', total_positions);
}
}
else{ // No employees for this designation
frappe.model.set_value(cdt, cdn, 'current_count', 0);
frappe.model.set_value(cdt, cdn, 'current_openings', 0);
}
}
});
refresh_field("staffing_details");
set_total_estimated_cost(frm, cdt, cdn); set_total_estimated_cost(frm, cdt, cdn);
} }
// Note: Estimated Cost is calculated on number of Vacancies // Note: Estimated Cost is calculated on number of Vacancies
// Validate for > 0 ?
var set_total_estimated_cost = function(frm, cdt, cdn) { var set_total_estimated_cost = function(frm, cdt, cdn) {
let child = locals[cdt][cdn] let child = locals[cdt][cdn]
if(child.vacancies > 0 && child.estimated_cost_per_position) { if(child.vacancies > 0 && child.estimated_cost_per_position) {
@ -102,7 +96,7 @@ var set_total_estimated_cost = function(frm, cdt, cdn) {
var set_total_estimated_budget = function(frm) { var set_total_estimated_budget = function(frm) {
let estimated_budget = 0.0 let estimated_budget = 0.0
if(frm.doc.staffing_details) { if(frm.doc.staffing_details) {
$.each(frm.doc.staffing_details, function(index, staff_detail) { (frm.doc.staffing_details || []).forEach(function(staff_detail) {
if(staff_detail.total_estimated_cost){ if(staff_detail.total_estimated_cost){
estimated_budget += staff_detail.total_estimated_cost estimated_budget += staff_detail.total_estimated_cost
} }

View File

@ -13,41 +13,39 @@ class ParentCompanyError(frappe.ValidationError): pass
class StaffingPlan(Document): class StaffingPlan(Document):
def validate(self): def validate(self):
self.validate_period()
self.validate_details()
self.set_total_estimated_budget()
def validate_period(self):
# Validate Dates # Validate Dates
if self.from_date and self.to_date and self.from_date > self.to_date: if self.from_date and self.to_date and self.from_date > self.to_date:
frappe.throw(_("From Date cannot be greater than To Date")) frappe.throw(_("From Date cannot be greater than To Date"))
self.total_estimated_budget = 0 def validate_details(self):
for detail in self.get("staffing_details"): for detail in self.get("staffing_details"):
self.set_vacancies(detail)
self.validate_overlap(detail) self.validate_overlap(detail)
self.validate_with_subsidiary_plans(detail) self.validate_with_subsidiary_plans(detail)
self.validate_with_parent_plan(detail) self.validate_with_parent_plan(detail)
def set_total_estimated_budget(self):
self.total_estimated_budget = 0
for detail in self.get("staffing_details"):
#Set readonly fields #Set readonly fields
self.set_number_of_positions(detail)
designation_counts = get_designation_counts(detail.designation, self.company) designation_counts = get_designation_counts(detail.designation, self.company)
detail.current_count = designation_counts['employee_count'] detail.current_count = designation_counts['employee_count']
detail.current_openings = designation_counts['job_openings'] detail.current_openings = designation_counts['job_openings']
if detail.number_of_positions < (detail.current_count + detail.current_openings): if detail.number_of_positions > 0:
frappe.throw(_("Number of positions cannot be less then current count of employees"))
elif detail.number_of_positions > 0:
detail.vacancies = detail.number_of_positions - (detail.current_count + detail.current_openings)
if detail.vacancies > 0 and detail.estimated_cost_per_position: if detail.vacancies > 0 and detail.estimated_cost_per_position:
detail.total_estimated_cost = detail.vacancies * detail.estimated_cost_per_position detail.total_estimated_cost = cint(detail.vacancies) * flt(detail.estimated_cost_per_position)
else: detail.total_estimated_cost = 0
else: detail.vacancies = detail.number_of_positions = detail.total_estimated_cost = 0
self.total_estimated_budget += detail.total_estimated_cost self.total_estimated_budget += detail.total_estimated_cost
def set_vacancies(self, row): def set_number_of_positions(self, detail):
if not row.vacancies: detail.number_of_positions = cint(detail.vacancies) + cint(detail.current_count)
current_openings = 0
for field in ['current_count', 'current_openings']:
if row.get(field):
current_openings += row.get(field)
row.vacancies = row.number_of_positions - current_openings
def validate_overlap(self, staffing_plan_detail): def validate_overlap(self, staffing_plan_detail):
# Validate if any submitted Staffing Plan exist for any Designations in this plan # Validate if any submitted Staffing Plan exist for any Designations in this plan
@ -132,19 +130,24 @@ def get_designation_counts(designation, company):
if not designation: if not designation:
return False return False
employee_counts_dict = {} employee_counts = {}
lft, rgt = frappe.get_cached_value('Company', company, ["lft", "rgt"]) company_set = get_company_set(company)
employee_counts_dict["employee_count"] = frappe.db.sql("""select count(*) from `tabEmployee`
where designation = %s and status='Active'
and company in (select name from tabCompany where lft>=%s and rgt<=%s)
""", (designation, lft, rgt))[0][0]
employee_counts_dict['job_openings'] = frappe.db.sql("""select count(*) from `tabJob Opening` \ employee_counts["employee_count"] = frappe.db.get_value("Employee",
where designation=%s and status='Open' filters={
and company in (select name from tabCompany where lft>=%s and rgt<=%s) 'designation': designation,
""", (designation, lft, rgt))[0][0] 'status': 'Active',
'company': ('in', company_set)
}, fieldname=['count(name)'])
return employee_counts_dict employee_counts['job_openings'] = frappe.db.get_value("Job Opening",
filters={
'designation': designation,
'status': 'Open',
'company': ('in', company_set)
}, fieldname=['count(name)'])
return employee_counts
@frappe.whitelist() @frappe.whitelist()
def get_active_staffing_plan_details(company, designation, from_date=getdate(nowdate()), to_date=getdate(nowdate())): def get_active_staffing_plan_details(company, designation, from_date=getdate(nowdate()), to_date=getdate(nowdate())):
@ -165,3 +168,13 @@ def get_active_staffing_plan_details(company, designation, from_date=getdate(now
# Only a single staffing plan can be active for a designation on given date # Only a single staffing plan can be active for a designation on given date
return staffing_plan if staffing_plan else None return staffing_plan if staffing_plan else None
def get_company_set(company):
return frappe.db.sql_list("""
SELECT
name
FROM `tabCompany`
WHERE
parent_company=%(company)s
OR name=%(company)s
""", (dict(company=company)))

View File

@ -24,7 +24,7 @@ class TestStaffingPlan(unittest.TestCase):
staffing_plan.to_date = add_days(nowdate(), 10) staffing_plan.to_date = add_days(nowdate(), 10)
staffing_plan.append("staffing_details", { staffing_plan.append("staffing_details", {
"designation": "Designer", "designation": "Designer",
"number_of_positions": 6, "vacancies": 6,
"estimated_cost_per_position": 50000 "estimated_cost_per_position": 50000
}) })
staffing_plan.insert() staffing_plan.insert()
@ -42,7 +42,7 @@ class TestStaffingPlan(unittest.TestCase):
staffing_plan.to_date = add_days(nowdate(), 10) staffing_plan.to_date = add_days(nowdate(), 10)
staffing_plan.append("staffing_details", { staffing_plan.append("staffing_details", {
"designation": "Designer", "designation": "Designer",
"number_of_positions": 3, "vacancies": 3,
"estimated_cost_per_position": 45000 "estimated_cost_per_position": 45000
}) })
self.assertRaises(SubsidiaryCompanyError, staffing_plan.insert) self.assertRaises(SubsidiaryCompanyError, staffing_plan.insert)
@ -58,7 +58,7 @@ class TestStaffingPlan(unittest.TestCase):
staffing_plan.to_date = add_days(nowdate(), 10) staffing_plan.to_date = add_days(nowdate(), 10)
staffing_plan.append("staffing_details", { staffing_plan.append("staffing_details", {
"designation": "Designer", "designation": "Designer",
"number_of_positions": 7, "vacancies": 7,
"estimated_cost_per_position": 50000 "estimated_cost_per_position": 50000
}) })
staffing_plan.insert() staffing_plan.insert()
@ -73,7 +73,7 @@ class TestStaffingPlan(unittest.TestCase):
staffing_plan.to_date = add_days(nowdate(), 10) staffing_plan.to_date = add_days(nowdate(), 10)
staffing_plan.append("staffing_details", { staffing_plan.append("staffing_details", {
"designation": "Designer", "designation": "Designer",
"number_of_positions": 7, "vacancies": 7,
"estimated_cost_per_position": 60000 "estimated_cost_per_position": 60000
}) })
staffing_plan.insert() staffing_plan.insert()
@ -92,5 +92,5 @@ def make_company():
company.abbr = "_TC10" company.abbr = "_TC10"
company.parent_company = "_Test Company" company.parent_company = "_Test Company"
company.default_currency = "INR" company.default_currency = "INR"
company.country = "India" company.country = "Pakistan"
company.insert() company.insert()

View File

@ -1,297 +1,79 @@
{ {
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2018-04-13 18:04:20.978931", "creation": "2018-04-13 18:04:20.978931",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"designation",
"vacancies",
"estimated_cost_per_position",
"total_estimated_cost",
"column_break_5",
"current_count",
"current_openings",
"number_of_positions"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "designation", "fieldname": "designation",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Designation", "label": "Designation",
"length": 0,
"no_copy": 0,
"options": "Designation", "options": "Designation",
"permlevel": 0, "reqd": 1
"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": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "number_of_positions", "fieldname": "number_of_positions",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Number Of Positions", "label": "Number Of Positions",
"length": 0, "read_only": 1
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "estimated_cost_per_position", "fieldname": "estimated_cost_per_position",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "label": "Estimated Cost Per Position"
"label": "Estimated Cost Per Position",
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_5", "fieldname": "column_break_5",
"fieldtype": "Column Break", "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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "current_count", "fieldname": "current_count",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Current Count", "label": "Current Count",
"length": 0, "read_only": 1
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "current_openings", "fieldname": "current_openings",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Current Openings", "label": "Current Openings",
"length": 0, "read_only": 1
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "vacancies", "fieldname": "vacancies",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "label": "Vacancies"
"label": "Vacancies", },
"length": 0, {
"no_copy": 0, "fieldname": "total_estimated_cost",
"permlevel": 0, "fieldtype": "Currency",
"precision": "", "in_list_view": 1,
"print_hide": 0, "label": "Total Estimated Cost",
"print_hide_if_no_value": 0, "read_only": 1
"read_only": 1, }
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_estimated_cost",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Total Estimated Cost",
"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
}
], ],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "modified": "2019-06-24 18:40:37.140178",
"modified": "2018-06-01 17:03:38.020993",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Staffing Plan Detail", "name": "Staffing Plan Detail",
"name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],
"quick_entry": 1, "quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"track_changes": 1, "track_changes": 1
"track_seen": 0
} }

View File

@ -73,7 +73,7 @@ def create_columns():
def get_record(): def get_record():
data = [] data = []
loans = frappe.get_all("Loan", loans = frappe.get_all("Loan",
filters=[("status", "=", "Fully Disbursed")], filters=[("status", "=", "Disbursed")],
fields=["applicant", "applicant_name", "name", "loan_amount", "rate_of_interest", fields=["applicant", "applicant_name", "name", "loan_amount", "rate_of_interest",
"total_payment", "monthly_repayment_amount", "total_amount_paid"] "total_payment", "monthly_repayment_amount", "total_amount_paid"]
) )

View File

@ -578,6 +578,8 @@ class BOM(WebsiteGenerator):
for d in self.operations: for d in self.operations:
if not d.description: if not d.description:
d.description = frappe.db.get_value('Operation', d.operation, 'description') d.description = frappe.db.get_value('Operation', d.operation, 'description')
if not d.batch_size > 0:
d.batch_size = 1
def get_list_context(context): def get_list_context(context):
context.title = _("Bill of Materials") context.title = _("Bill of Materials")

View File

@ -1,361 +1,119 @@
{ {
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2013-02-22 01:27:49", "creation": "2013-02-22 01:27:49",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "Setup", "document_type": "Setup",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"operation",
"workstation",
"description",
"col_break1",
"hour_rate",
"time_in_mins",
"batch_size",
"operating_cost",
"base_hour_rate",
"base_operating_cost",
"image"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "operation", "fieldname": "operation",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Operation", "label": "Operation",
"length": 0,
"no_copy": 0,
"oldfieldname": "operation_no", "oldfieldname": "operation_no",
"oldfieldtype": "Data", "oldfieldtype": "Data",
"options": "Operation", "options": "Operation",
"permlevel": 0, "reqd": 1
"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": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "workstation", "fieldname": "workstation",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Workstation", "label": "Workstation",
"length": 0,
"no_copy": 0,
"oldfieldname": "workstation", "oldfieldname": "workstation",
"oldfieldtype": "Link", "oldfieldtype": "Link",
"options": "Workstation", "options": "Workstation"
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "description", "fieldname": "description",
"fieldtype": "Text Editor", "fieldtype": "Text Editor",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Description", "label": "Description",
"length": 0,
"no_copy": 0,
"oldfieldname": "opn_description", "oldfieldname": "opn_description",
"oldfieldtype": "Text", "oldfieldtype": "Text"
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "col_break1", "fieldname": "col_break1",
"fieldtype": "Column Break", "fieldtype": "Column Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "hour_rate", "fieldname": "hour_rate",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Hour Rate", "label": "Hour Rate",
"length": 0,
"no_copy": 0,
"oldfieldname": "hour_rate", "oldfieldname": "hour_rate",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
"options": "currency", "options": "currency"
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "In minutes", "description": "In minutes",
"fieldname": "time_in_mins", "fieldname": "time_in_mins",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Operation Time ", "label": "Operation Time ",
"length": 0,
"no_copy": 0,
"oldfieldname": "time_in_mins", "oldfieldname": "time_in_mins",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
"options": "", "reqd": 1
"permlevel": 0,
"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": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "operating_cost", "fieldname": "operating_cost",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Operating Cost", "label": "Operating Cost",
"length": 0,
"no_copy": 0,
"oldfieldname": "operating_cost", "oldfieldname": "operating_cost",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
"options": "currency", "options": "currency",
"permlevel": 0, "read_only": 1
"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
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "base_hour_rate", "fieldname": "base_hour_rate",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Base Hour Rate(Company Currency)", "label": "Base Hour Rate(Company Currency)",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 1, "print_hide": 1,
"print_hide_if_no_value": 0, "read_only": 1
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "5", "default": "5",
"fieldname": "base_operating_cost", "fieldname": "base_operating_cost",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Operating Cost(Company Currency)", "label": "Operating Cost(Company Currency)",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 1, "print_hide": 1,
"print_hide_if_no_value": 0, "read_only": 1
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "image", "fieldname": "image",
"fieldtype": "Attach", "fieldtype": "Attach",
"hidden": 0, "label": "Image"
"ignore_user_permissions": 0, },
"ignore_xss_filter": 0, {
"in_filter": 0, "default": "1",
"in_global_search": 0, "fieldname": "batch_size",
"in_list_view": 0, "fieldtype": "Int",
"in_standard_filter": 0, "label": "Batch Size"
"label": "Image",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
} }
], ],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1, "idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "modified": "2019-07-16 22:35:55.374037",
"modified": "2018-03-26 09:55:28.107451", "modified_by": "govindsmenokee@gmail.com",
"modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "BOM Operation", "name": "BOM Operation",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],
"quick_entry": 0, "sort_field": "modified",
"read_only": 0, "sort_order": "DESC"
"read_only_onload": 0,
"show_name_in_global_search": 0,
"track_changes": 0,
"track_seen": 0
} }

View File

@ -505,7 +505,7 @@ def get_material_request_items(row, sales_order,
total_qty = row['qty'] total_qty = row['qty']
required_qty = 0 required_qty = 0
if ignore_existing_ordered_qty or bin_dict.get("projected_qty") < 0: if ignore_existing_ordered_qty or bin_dict.get("projected_qty", 0) < 0:
required_qty = total_qty required_qty = total_qty
elif total_qty > bin_dict.get("projected_qty"): elif total_qty > bin_dict.get("projected_qty"):
required_qty = total_qty - bin_dict.get("projected_qty") required_qty = total_qty - bin_dict.get("projected_qty")

View File

@ -4,6 +4,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
import json import json
import math
from frappe import _ from frappe import _
from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate
from frappe.model.document import Document from frappe.model.document import Document
@ -323,7 +324,7 @@ class WorkOrder(Document):
select select
operation, description, workstation, idx, operation, description, workstation, idx,
base_hour_rate as hour_rate, time_in_mins, base_hour_rate as hour_rate, time_in_mins,
"Pending" as status, parent as bom "Pending" as status, parent as bom, batch_size
from from
`tabBOM Operation` `tabBOM Operation`
where where
@ -348,7 +349,7 @@ class WorkOrder(Document):
bom_qty = frappe.db.get_value("BOM", self.bom_no, "quantity") bom_qty = frappe.db.get_value("BOM", self.bom_no, "quantity")
for d in self.get("operations"): for d in self.get("operations"):
d.time_in_mins = flt(d.time_in_mins) / flt(bom_qty) * flt(self.qty) d.time_in_mins = flt(d.time_in_mins) / flt(bom_qty) * math.ceil(flt(self.qty) / flt(d.batch_size))
self.calculate_operating_cost() self.calculate_operating_cost()

View File

@ -1,690 +1,200 @@
{ {
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2014-10-16 14:35:41.950175", "creation": "2014-10-16 14:35:41.950175",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"details",
"operation",
"bom",
"description",
"col_break1",
"completed_qty",
"status",
"workstation",
"estimated_time_and_cost",
"planned_start_time",
"planned_end_time",
"column_break_10",
"time_in_mins",
"hour_rate",
"batch_size",
"planned_operating_cost",
"section_break_9",
"actual_start_time",
"actual_end_time",
"column_break_11",
"actual_operation_time",
"actual_operating_cost"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "details", "fieldname": "details",
"fieldtype": "Section Break", "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": "",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "operation", "fieldname": "operation",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Operation", "label": "Operation",
"length": 0,
"no_copy": 0,
"oldfieldname": "operation_no", "oldfieldname": "operation_no",
"oldfieldtype": "Data", "oldfieldtype": "Data",
"options": "Operation", "options": "Operation",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1, "read_only": 1,
"remember_last_selected_value": 0, "reqd": 1
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "bom", "fieldname": "bom",
"fieldtype": "Link", "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": "BOM", "label": "BOM",
"length": 0,
"no_copy": 1, "no_copy": 1,
"options": "BOM", "options": "BOM",
"permlevel": 0,
"precision": "",
"print_hide": 1, "print_hide": 1,
"print_hide_if_no_value": 0, "read_only": 1
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "description", "fieldname": "description",
"fieldtype": "Text Editor", "fieldtype": "Text Editor",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Operation Description", "label": "Operation Description",
"length": 0,
"no_copy": 0,
"oldfieldname": "opn_description", "oldfieldname": "opn_description",
"oldfieldtype": "Text", "oldfieldtype": "Text",
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "col_break1", "fieldname": "col_break1",
"fieldtype": "Column Break", "fieldtype": "Column Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Operation completed for how many finished goods?", "description": "Operation completed for how many finished goods?",
"fieldname": "completed_qty", "fieldname": "completed_qty",
"fieldtype": "Float", "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": "Completed Qty", "label": "Completed Qty",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Pending", "default": "Pending",
"fieldname": "status", "fieldname": "status",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Status", "label": "Status",
"length": 0,
"no_copy": 1, "no_copy": 1,
"options": "Pending\nWork in Progress\nCompleted", "options": "Pending\nWork in Progress\nCompleted",
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "workstation", "fieldname": "workstation",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Workstation", "label": "Workstation",
"length": 0,
"no_copy": 0,
"oldfieldname": "workstation", "oldfieldname": "workstation",
"oldfieldtype": "Link", "oldfieldtype": "Link",
"options": "Workstation", "options": "Workstation"
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "estimated_time_and_cost", "fieldname": "estimated_time_and_cost",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "Estimated Time and Cost"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Estimated Time and Cost",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "planned_start_time", "fieldname": "planned_start_time",
"fieldtype": "Datetime", "fieldtype": "Datetime",
"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": "Planned Start Time", "label": "Planned Start Time",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "planned_end_time", "fieldname": "planned_end_time",
"fieldtype": "Datetime", "fieldtype": "Datetime",
"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": "Planned End Time", "label": "Planned End Time",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_10", "fieldname": "column_break_10",
"fieldtype": "Column Break", "fieldtype": "Column Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "in Minutes", "description": "in Minutes",
"fieldname": "time_in_mins", "fieldname": "time_in_mins",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Operation Time", "label": "Operation Time",
"length": 0,
"no_copy": 0,
"oldfieldname": "time_in_mins", "oldfieldname": "time_in_mins",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "hour_rate", "fieldname": "hour_rate",
"fieldtype": "Float", "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": "Hour Rate", "label": "Hour Rate",
"length": 0,
"no_copy": 0,
"oldfieldname": "hour_rate", "oldfieldname": "hour_rate",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "planned_operating_cost", "fieldname": "planned_operating_cost",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Planned Operating Cost", "label": "Planned Operating Cost",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_9", "fieldname": "section_break_9",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "Actual Time and Cost"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Actual Time and Cost",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "actual_start_time", "fieldname": "actual_start_time",
"fieldtype": "Datetime", "fieldtype": "Datetime",
"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": "Actual Start Time", "label": "Actual Start Time",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Updated via 'Time Log'", "description": "Updated via 'Time Log'",
"fieldname": "actual_end_time", "fieldname": "actual_end_time",
"fieldtype": "Datetime", "fieldtype": "Datetime",
"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": "Actual End Time", "label": "Actual End Time",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_11", "fieldname": "column_break_11",
"fieldtype": "Column Break", "fieldtype": "Column Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "in Minutes\nUpdated via 'Time Log'", "description": "in Minutes\nUpdated via 'Time Log'",
"fieldname": "actual_operation_time", "fieldname": "actual_operation_time",
"fieldtype": "Float", "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": "Actual Operation Time", "label": "Actual Operation Time",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "(Hour Rate / 60) * Actual Operation Time", "description": "(Hour Rate / 60) * Actual Operation Time",
"fieldname": "actual_operating_cost", "fieldname": "actual_operating_cost",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Actual Operating Cost", "label": "Actual Operating Cost",
"length": 0,
"no_copy": 1, "no_copy": 1,
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
"permlevel": 0, "read_only": 1
"precision": "", },
"print_hide": 0, {
"print_hide_if_no_value": 0, "fieldname": "batch_size",
"read_only": 1, "fieldtype": "Int",
"remember_last_selected_value": 0, "label": "Batch Size",
"report_hide": 0, "read_only": 1
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
} }
], ],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "modified": "2019-07-16 23:01:07.720337",
"modified": "2018-02-13 02:58:11.328693", "modified_by": "govindsmenokee@gmail.com",
"modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "Work Order Operation", "name": "Work Order Operation",
"name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"track_changes": 1, "track_changes": 1
"track_seen": 0
} }

View File

@ -618,8 +618,11 @@ erpnext.patches.v11_1.set_missing_opportunity_from
erpnext.patches.v12_0.set_quotation_status erpnext.patches.v12_0.set_quotation_status
erpnext.patches.v12_0.set_priority_for_support erpnext.patches.v12_0.set_priority_for_support
erpnext.patches.v12_0.delete_priority_property_setter erpnext.patches.v12_0.delete_priority_property_setter
erpnext.patches.v12_0.set_default_batch_size
execute:frappe.delete_doc("DocType", "Project Task") execute:frappe.delete_doc("DocType", "Project Task")
erpnext.patches.v11_1.update_default_supplier_in_item_defaults erpnext.patches.v11_1.update_default_supplier_in_item_defaults
erpnext.patches.v12_0.update_due_date_in_gle erpnext.patches.v12_0.update_due_date_in_gle
erpnext.patches.v12_0.add_default_buying_selling_terms_in_company erpnext.patches.v12_0.add_default_buying_selling_terms_in_company
erpnext.patches.v12_0.update_ewaybill_field_position erpnext.patches.v12_0.update_ewaybill_field_position
erpnext.patches.v12_0.create_accounting_dimensions_in_missing_doctypes
erpnext.patches.v11_1.set_status_for_material_request_type_manufacture

View File

@ -0,0 +1,9 @@
from __future__ import unicode_literals
import frappe
def execute():
frappe.db.sql("""
update `tabMaterial Request`
set status='Manufactured'
where docstatus=1 and material_request_type='Manufacture' and per_ordered=100 and status != 'Stopped'
""")

View File

@ -0,0 +1,41 @@
from __future__ import unicode_literals
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
def execute():
frappe.reload_doc('accounts', 'doctype', 'accounting_dimension')
accounting_dimensions = frappe.db.sql("""select fieldname, label, document_type, disabled from
`tabAccounting Dimension`""", as_dict=1)
if not accounting_dimensions:
return
count = 1
for d in accounting_dimensions:
if count%2 == 0:
insert_after_field = 'dimension_col_break'
else:
insert_after_field = 'accounting_dimensions_section'
for doctype in ["Subscription Plan", "Subscription", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item"]:
field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": d.fieldname})
if field:
continue
df = {
"fieldname": d.fieldname,
"label": d.label,
"fieldtype": "Link",
"options": d.document_type,
"insert_after": insert_after_field
}
create_custom_field(doctype, df)
frappe.clear_cache(doctype=doctype)
count += 1

View File

@ -0,0 +1,19 @@
import frappe
def execute():
frappe.reload_doc("manufacturing", "doctype", "bom_operation")
frappe.reload_doc("manufacturing", "doctype", "work_order_operation")
frappe.db.sql("""
UPDATE
`tabBOM Operation` bo
SET
bo.batch_size = 1
""")
frappe.db.sql("""
UPDATE
`tabWork Order Operation` wop
SET
wop.batch_size = 1
""")

View File

@ -10,18 +10,19 @@ def execute():
field = frappe.db.get_value("Custom Field", {"dt": "Sales Invoice", "fieldname": "ewaybill"}) field = frappe.db.get_value("Custom Field", {"dt": "Sales Invoice", "fieldname": "ewaybill"})
ewaybill_field = frappe.get_doc("Custom Field", field) if field:
ewaybill_field = frappe.get_doc("Custom Field", field)
ewaybill_field.flags.ignore_validate = True ewaybill_field.flags.ignore_validate = True
ewaybill_field.update({ ewaybill_field.update({
'fieldname': 'ewaybill', 'fieldname': 'ewaybill',
'label': 'e-Way Bill No.', 'label': 'e-Way Bill No.',
'fieldtype': 'Data', 'fieldtype': 'Data',
'depends_on': 'eval:(doc.docstatus === 1)', 'depends_on': 'eval:(doc.docstatus === 1)',
'allow_on_submit': 1, 'allow_on_submit': 1,
'insert_after': 'tax_id', 'insert_after': 'tax_id',
'translatable': 0 'translatable': 0
}) })
ewaybill_field.save() ewaybill_field.save()

View File

@ -1,6 +1,23 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt // License: GNU General Public License v3. See license.txt
frappe.ui.form.on("Project", { frappe.ui.form.on("Project", {
setup(frm) {
frm.make_methods = {
'Timesheet': () => {
let doctype = 'Timesheet';
frappe.model.with_doctype(doctype, () => {
let new_doc = frappe.model.get_new_doc(doctype);
// add a new row and set the project
let time_log = frappe.model.get_new_doc('Timesheet Detail');
time_log.project = frm.doc.name;
new_doc.time_logs = [time_log];
frappe.ui.form.make_quick_entry(doctype, null, null, new_doc);
});
},
}
},
onload: function (frm) { onload: function (frm) {
var so = frappe.meta.get_docfield("Project", "sales_order"); var so = frappe.meta.get_docfield("Project", "sales_order");
so.get_route_options_for_new_doc = function (field) { so.get_route_options_for_new_doc = function (field) {

View File

@ -92,7 +92,13 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
$.each(this.frm.doc["items"] || [], function(i, item) { $.each(this.frm.doc["items"] || [], function(i, item) {
frappe.model.round_floats_in(item); frappe.model.round_floats_in(item);
item.net_rate = item.rate; item.net_rate = item.rate;
item.amount = flt(item.rate * item.qty, precision("amount", item));
if ((!item.qty) && me.frm.doc.is_return) {
item.amount = flt(item.rate * -1, precision("amount", item));
} else {
item.amount = flt(item.rate * item.qty, precision("amount", item));
}
item.net_amount = item.amount; item.net_amount = item.amount;
item.item_tax_amount = 0.0; item.item_tax_amount = 0.0;
item.total_weight = flt(item.weight_per_unit * item.stock_qty); item.total_weight = flt(item.weight_per_unit * item.stock_qty);

View File

@ -129,14 +129,12 @@ function get_filters(){
} }
] ]
erpnext.dimension_filters.then((dimensions) => { erpnext.dimension_filters.forEach((dimension) => {
dimensions.forEach((dimension) => { filters.push({
filters.push({ "fieldname": dimension["fieldname"],
"fieldname": dimension["fieldname"], "label": __(dimension["label"]),
"label": __(dimension["label"]), "fieldtype": "Link",
"fieldtype": "Link", "options": dimension["document_type"]
"options": dimension["document_type"]
});
}); });
}); });

View File

@ -63,20 +63,6 @@ $.extend(erpnext, {
me.show_serial_batch_selector(grid_row.frm, grid_row.doc); me.show_serial_batch_selector(grid_row.frm, grid_row.doc);
}); });
}, },
get_dimension_filters: async function() {
if (!frappe.model.can_read('Accounting Dimension')) {
return [];
}
let dimensions = await frappe.db.get_list('Accounting Dimension', {
fields: ['label', 'fieldname', 'document_type'],
filters: {
disabled: 0
}
});
return dimensions;
}
}); });

View File

@ -5,24 +5,54 @@ erpnext.doctypes_with_dimensions = ["GL Entry", "Sales Invoice", "Purchase Invoi
"Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item", "Purchase Receipt Item", "Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item", "Purchase Receipt Item",
"Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule", "Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule",
"Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation", "Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation",
"Travel Request", "Fees", "POS Profile"]; "Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item", "Subscription",
"Subscription Plan"];
erpnext.dimension_filters = erpnext.get_dimension_filters(); frappe.call({
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.get_dimension_filters",
callback: function(r){
erpnext.dimension_filters = r.message[0];
erpnext.default_dimensions = r.message[1];
}
});
erpnext.doctypes_with_dimensions.forEach((doctype) => { erpnext.doctypes_with_dimensions.forEach((doctype) => {
frappe.ui.form.on(doctype, { frappe.ui.form.on(doctype, {
onload: function(frm) { onload: function(frm) {
erpnext.dimension_filters.then((dimensions) => { erpnext.dimension_filters.forEach((dimension) => {
dimensions.forEach((dimension) => { frappe.model.with_doctype(dimension['document_type'], () => {
frappe.model.with_doctype(dimension['document_type'], () => { if (frappe.meta.has_field(dimension['document_type'], 'is_group')) {
if (frappe.meta.has_field(dimension['document_type'], 'is_group')) { frm.set_query(dimension['fieldname'], {
frm.set_query(dimension['fieldname'], { "is_group": 0
"is_group": 0 });
}); }
} if (frm.is_new() && frappe.meta.has_field(doctype, 'company') && frm.doc.company) {
}); frm.set_value(dimension['fieldname'], erpnext.default_dimensions[frm.doc.company][dimension['document_type']]);
}
}); });
}); });
},
company: function(frm) {
if(frm.doc.company) {
erpnext.dimension_filters.forEach((dimension) => {
frm.set_value(dimension['fieldname'], erpnext.default_dimensions[frm.doc.company][dimension['document_type']]);
});
}
},
items_add: function(frm, cdt, cdn) {
erpnext.dimension_filters.forEach((dimension) => {
var row = frappe.get_doc(cdt, cdn);
frm.script_manager.copy_from_first_row("items", row, [dimension['fieldname']]);
});
},
accounts_add: function(frm, cdt, cdn) {
erpnext.dimension_filters.forEach((dimension) => {
var row = frappe.get_doc(cdt, cdn);
frm.script_manager.copy_from_first_row("accounts", row, [dimension['fieldname']]);
});
} }
}); });
}); });

View File

@ -161,8 +161,9 @@ class Gstr1Report(object):
"gst_category": ["in", ["Registered Regular", "Deemed Export", "SEZ"]] "gst_category": ["in", ["Registered Regular", "Deemed Export", "SEZ"]]
}) })
conditions += """ and ifnull(gst_category, '') != 'Overseas' and is_return != 1 if customers:
and customer in ({0})""".format(", ".join([frappe.db.escape(c.name) for c in customers])) conditions += """ and ifnull(gst_category, '') != 'Overseas' and is_return != 1
and customer in ({0})""".format(", ".join([frappe.db.escape(c.name) for c in customers]))
if self.filters.get("type_of_business") in ("B2C Large", "B2C Small"): if self.filters.get("type_of_business") in ("B2C Large", "B2C Small"):
b2c_limit = frappe.db.get_single_value('GST Settings', 'b2c_limit') b2c_limit = frappe.db.get_single_value('GST Settings', 'b2c_limit')
@ -174,11 +175,11 @@ class Gstr1Report(object):
"gst_category": ["in", ["Unregistered"]] "gst_category": ["in", ["Unregistered"]]
}) })
if self.filters.get("type_of_business") == "B2C Large": if self.filters.get("type_of_business") == "B2C Large" and customers:
conditions += """ and SUBSTR(place_of_supply, 1, 2) != SUBSTR(company_gstin, 1, 2) conditions += """ and SUBSTR(place_of_supply, 1, 2) != SUBSTR(company_gstin, 1, 2)
and grand_total > {0} and is_return != 1 and customer in ({1})""".\ and grand_total > {0} and is_return != 1 and customer in ({1})""".\
format(flt(b2c_limit), ", ".join([frappe.db.escape(c.name) for c in customers])) format(flt(b2c_limit), ", ".join([frappe.db.escape(c.name) for c in customers]))
elif self.filters.get("type_of_business") == "B2C Small": elif self.filters.get("type_of_business") == "B2C Small" and customers:
conditions += """ and ( conditions += """ and (
SUBSTR(place_of_supply, 1, 2) = SUBSTR(company_gstin, 1, 2) SUBSTR(place_of_supply, 1, 2) = SUBSTR(company_gstin, 1, 2)
or grand_total <= {0}) and is_return != 1 and customer in ({1})""".\ or grand_total <= {0}) and is_return != 1 and customer in ({1})""".\

Some files were not shown because too many files have changed in this diff Show More