Merge branch 'develop' into healthcare_refactor
This commit is contained in:
commit
5eb42409c7
@ -21,7 +21,7 @@ class BankReconciliation(Document):
|
|||||||
|
|
||||||
condition = ""
|
condition = ""
|
||||||
if not self.include_reconciled_entries:
|
if not self.include_reconciled_entries:
|
||||||
condition = " and (clearance_date is null or clearance_date='0000-00-00')"
|
condition = "and (clearance_date IS NULL or clearance_date='0000-00-00')"
|
||||||
|
|
||||||
journal_entries = frappe.db.sql("""
|
journal_entries = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
@ -34,12 +34,10 @@ class BankReconciliation(Document):
|
|||||||
where
|
where
|
||||||
t2.parent = t1.name and t2.account = %(account)s and t1.docstatus=1
|
t2.parent = t1.name and t2.account = %(account)s and t1.docstatus=1
|
||||||
and t1.posting_date >= %(from)s and t1.posting_date <= %(to)s
|
and t1.posting_date >= %(from)s and t1.posting_date <= %(to)s
|
||||||
and ifnull(t1.is_opening, 'No') = 'No' %(condition)s
|
and ifnull(t1.is_opening, 'No') = 'No' {condition}
|
||||||
group by t2.account, t1.name
|
group by t2.account, t1.name
|
||||||
order by t1.posting_date ASC, t1.name DESC
|
order by t1.posting_date ASC, t1.name DESC
|
||||||
""", {"condition":condition, "account": self.account, "from": self.from_date, "to": self.to_date}, as_dict=1)
|
""".format(condition=condition), {"account": self.account, "from": self.from_date, "to": self.to_date}, as_dict=1)
|
||||||
|
|
||||||
condition = ''
|
|
||||||
|
|
||||||
if self.bank_account:
|
if self.bank_account:
|
||||||
condition += 'and bank_account = %(bank_account)s'
|
condition += 'and bank_account = %(bank_account)s'
|
||||||
|
|||||||
@ -17,17 +17,60 @@ frappe.ui.form.on('Chart of Accounts Importer', {
|
|||||||
if (frm.page && frm.page.show_import_button) {
|
if (frm.page && frm.page.show_import_button) {
|
||||||
create_import_button(frm);
|
create_import_button(frm);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// show download template button when company is properly selected
|
download_template: function(frm) {
|
||||||
if(frm.doc.company) {
|
var d = new frappe.ui.Dialog({
|
||||||
// download the csv template file
|
title: __("Download Template"),
|
||||||
frm.add_custom_button(__("Download template"), function () {
|
fields: [
|
||||||
let get_template_url = 'erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.download_template';
|
{
|
||||||
open_url_post(frappe.request.url, { cmd: get_template_url, doctype: frm.doc.doctype });
|
label : "File Type",
|
||||||
});
|
fieldname: "file_type",
|
||||||
} else {
|
fieldtype: "Select",
|
||||||
frm.set_value("import_file", "");
|
reqd: 1,
|
||||||
}
|
options: ["Excel", "CSV"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Template Type",
|
||||||
|
fieldname: "template_type",
|
||||||
|
fieldtype: "Select",
|
||||||
|
reqd: 1,
|
||||||
|
options: ["Sample Template", "Blank Template"],
|
||||||
|
change: () => {
|
||||||
|
let template_type = d.get_value('template_type');
|
||||||
|
|
||||||
|
if (template_type === "Sample Template") {
|
||||||
|
d.set_df_property('template_type', 'description',
|
||||||
|
`The Sample Template contains all the required accounts pre filled in the template.
|
||||||
|
You can add more accounts or change existing accounts in the template as per your choice.`);
|
||||||
|
} else {
|
||||||
|
d.set_df_property('template_type', 'description',
|
||||||
|
`The Blank Template contains just the account type and root type required to build the Chart
|
||||||
|
of Accounts. Please enter the account names and add more rows as per your requirement.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
primary_action: function() {
|
||||||
|
var data = d.get_values();
|
||||||
|
|
||||||
|
if (!data.template_type) {
|
||||||
|
frappe.throw(__('Please select <b>Template Type</b> to download template'));
|
||||||
|
}
|
||||||
|
|
||||||
|
open_url_post(
|
||||||
|
'/api/method/erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.download_template',
|
||||||
|
{
|
||||||
|
file_type: data.file_type,
|
||||||
|
template_type: data.template_type
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
d.hide();
|
||||||
|
},
|
||||||
|
primary_action_label: __('Download')
|
||||||
|
});
|
||||||
|
d.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
import_file: function (frm) {
|
import_file: function (frm) {
|
||||||
@ -41,21 +84,24 @@ frappe.ui.form.on('Chart of Accounts Importer', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
company: function (frm) {
|
company: function (frm) {
|
||||||
// validate that no Gl Entry record for the company exists.
|
if (frm.doc.company) {
|
||||||
frappe.call({
|
// validate that no Gl Entry record for the company exists.
|
||||||
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.validate_company",
|
frappe.call({
|
||||||
args: {
|
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.validate_company",
|
||||||
company: frm.doc.company
|
args: {
|
||||||
},
|
company: frm.doc.company
|
||||||
callback: function(r) {
|
},
|
||||||
if(r.message===false) {
|
callback: function(r) {
|
||||||
frm.set_value("company", "");
|
if(r.message===false) {
|
||||||
frappe.throw(__("Transactions against the company already exist! "));
|
frm.set_value("company", "");
|
||||||
} else {
|
frappe.throw(__(`Transactions against the company already exist!
|
||||||
frm.trigger("refresh");
|
Chart Of accounts can be imported for company with no transactions`));
|
||||||
|
} else {
|
||||||
|
frm.trigger("refresh");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -77,7 +123,7 @@ var validate_csv_data = function(frm) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var create_import_button = function(frm) {
|
var create_import_button = function(frm) {
|
||||||
frm.page.set_primary_action(__("Start Import"), function () {
|
frm.page.set_primary_action(__("Import"), function () {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.import_coa",
|
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.import_coa",
|
||||||
args: {
|
args: {
|
||||||
@ -118,7 +164,8 @@ var generate_tree_preview = function(frm) {
|
|||||||
args: {
|
args: {
|
||||||
file_name: frm.doc.import_file,
|
file_name: frm.doc.import_file,
|
||||||
parent: parent,
|
parent: parent,
|
||||||
doctype: 'Chart of Accounts Importer'
|
doctype: 'Chart of Accounts Importer',
|
||||||
|
file_type: frm.doc.file_type
|
||||||
},
|
},
|
||||||
onclick: function(node) {
|
onclick: function(node) {
|
||||||
parent = node.value;
|
parent = node.value;
|
||||||
|
|||||||
@ -1,226 +1,71 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_copy": 1,
|
"allow_copy": 1,
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2019-02-01 12:24:34.761380",
|
"creation": "2019-02-01 12:24:34.761380",
|
||||||
"custom": 0,
|
|
||||||
"description": "Import Chart of Accounts from a csv file",
|
"description": "Import Chart of Accounts from a csv file",
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Other",
|
"document_type": "Other",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"company",
|
||||||
|
"download_template",
|
||||||
|
"import_file",
|
||||||
|
"chart_preview",
|
||||||
|
"chart_tree"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"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": "Company",
|
"label": "Company",
|
||||||
"length": 0,
|
"options": "Company"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company",
|
|
||||||
"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,
|
"depends_on": "company",
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "import_file_section",
|
|
||||||
"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,
|
|
||||||
"depends_on": "",
|
|
||||||
"fieldname": "import_file",
|
"fieldname": "import_file",
|
||||||
"fieldtype": "Attach",
|
"fieldtype": "Attach",
|
||||||
"hidden": 0,
|
"label": "Attach custom Chart of Accounts file"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Attach custom Chart of Accounts file",
|
|
||||||
"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,
|
|
||||||
"fieldname": "chart_preview",
|
"fieldname": "chart_preview",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Chart Preview"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Chart Preview",
|
|
||||||
"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": "chart_tree",
|
"fieldname": "chart_tree",
|
||||||
"fieldtype": "HTML",
|
"fieldtype": "HTML",
|
||||||
"hidden": 0,
|
"label": "Chart Tree"
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
{
|
||||||
"in_filter": 0,
|
"depends_on": "company",
|
||||||
"in_global_search": 0,
|
"fieldname": "download_template",
|
||||||
"in_list_view": 0,
|
"fieldtype": "Button",
|
||||||
"in_standard_filter": 0,
|
"label": "Download Template"
|
||||||
"label": "Chart Tree",
|
|
||||||
"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": 1,
|
|
||||||
"hide_toolbar": 1,
|
"hide_toolbar": 1,
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 1,
|
"in_create": 1,
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"links": [],
|
||||||
"max_attachments": 0,
|
"modified": "2020-02-28 08:49:11.422846",
|
||||||
"modified": "2019-02-04 23:10:30.136807",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Chart of Accounts Importer",
|
"name": "Chart of Accounts Importer",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 0,
|
|
||||||
"email": 0,
|
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 0,
|
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 0,
|
|
||||||
"role": "Accounts Manager",
|
"role": "Accounts Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"read_only_onload": 0,
|
"sort_field": "modified",
|
||||||
"show_name_in_global_search": 0,
|
"sort_order": "DESC"
|
||||||
"sort_field": "",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
||||||
@ -4,18 +4,28 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
import frappe, csv
|
import frappe, csv, os
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import cstr
|
from frappe.utils import cstr, cint
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils.csvutils import UnicodeWriter
|
from frappe.utils.csvutils import UnicodeWriter
|
||||||
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts, build_tree_from_json
|
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts, build_tree_from_json
|
||||||
|
from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file, read_xls_file_from_attached_file
|
||||||
|
|
||||||
class ChartofAccountsImporter(Document):
|
class ChartofAccountsImporter(Document):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def validate_company(company):
|
def validate_company(company):
|
||||||
|
parent_company, allow_account_creation_against_child_company = frappe.db.get_value('Company',
|
||||||
|
{'name': company}, ['parent_company',
|
||||||
|
'allow_account_creation_against_child_company'])
|
||||||
|
|
||||||
|
if parent_company and (not allow_account_creation_against_child_company):
|
||||||
|
frappe.throw(_("""{0} is a child company. Please import accounts against parent company
|
||||||
|
or enable {1} in company master""").format(frappe.bold(company),
|
||||||
|
frappe.bold('Allow Account Creation Against Child Company')), title='Wrong Company')
|
||||||
|
|
||||||
if frappe.db.get_all('GL Entry', {"company": company}, "name", limit=1):
|
if frappe.db.get_all('GL Entry', {"company": company}, "name", limit=1):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -25,42 +35,85 @@ def import_coa(file_name, company):
|
|||||||
unset_existing_data(company)
|
unset_existing_data(company)
|
||||||
|
|
||||||
# create accounts
|
# create accounts
|
||||||
forest = build_forest(generate_data_from_csv(file_name))
|
file_doc, extension = get_file(file_name)
|
||||||
|
|
||||||
|
if extension == 'csv':
|
||||||
|
data = generate_data_from_csv(file_doc)
|
||||||
|
else:
|
||||||
|
data = generate_data_from_excel(file_doc, extension)
|
||||||
|
|
||||||
|
forest = build_forest(data)
|
||||||
create_charts(company, custom_chart=forest)
|
create_charts(company, custom_chart=forest)
|
||||||
|
|
||||||
# trigger on_update for company to reset default accounts
|
# trigger on_update for company to reset default accounts
|
||||||
set_default_accounts(company)
|
set_default_accounts(company)
|
||||||
|
|
||||||
def generate_data_from_csv(file_name, as_dict=False):
|
def get_file(file_name):
|
||||||
''' read csv file and return the generated nested tree '''
|
file_doc = frappe.get_doc("File", {"file_url": file_name})
|
||||||
if not file_name.endswith('.csv'):
|
parts = file_doc.get_extension()
|
||||||
frappe.throw("Only CSV files can be used to for importing data. Please check the file format you are trying to upload")
|
extension = parts[1]
|
||||||
|
extension = extension.lstrip(".")
|
||||||
|
|
||||||
|
if extension not in ('csv', 'xlsx', 'xls'):
|
||||||
|
frappe.throw("Only CSV and Excel files can be used to for importing data. Please check the file format you are trying to upload")
|
||||||
|
|
||||||
|
return file_doc, extension
|
||||||
|
|
||||||
|
def generate_data_from_csv(file_doc, as_dict=False):
|
||||||
|
''' read csv file and return the generated nested tree '''
|
||||||
|
|
||||||
file_doc = frappe.get_doc('File', {"file_url": file_name})
|
|
||||||
file_path = file_doc.get_full_path()
|
file_path = file_doc.get_full_path()
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
with open(file_path, 'r') as in_file:
|
with open(file_path, 'r') as in_file:
|
||||||
csv_reader = list(csv.reader(in_file))
|
csv_reader = list(csv.reader(in_file))
|
||||||
headers = csv_reader[1][1:]
|
headers = csv_reader[0]
|
||||||
del csv_reader[0:2] # delete top row and headers row
|
del csv_reader[0] # delete top row and headers row
|
||||||
|
|
||||||
for row in csv_reader:
|
for row in csv_reader:
|
||||||
if as_dict:
|
if as_dict:
|
||||||
data.append({frappe.scrub(header): row[index+1] for index, header in enumerate(headers)})
|
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
|
||||||
else:
|
else:
|
||||||
if not row[2]: row[2] = row[1]
|
if not row[1]: row[1] = row[0]
|
||||||
data.append(row[1:])
|
data.append(row)
|
||||||
|
|
||||||
# convert csv data
|
# convert csv data
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def generate_data_from_excel(file_doc, extension, as_dict=False):
|
||||||
|
content = file_doc.get_content()
|
||||||
|
|
||||||
|
if extension == "xlsx":
|
||||||
|
rows = read_xlsx_file_from_attached_file(fcontent=content)
|
||||||
|
elif extension == "xls":
|
||||||
|
rows = read_xls_file_from_attached_file(content)
|
||||||
|
|
||||||
|
data = []
|
||||||
|
headers = rows[0]
|
||||||
|
del rows[0]
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
if as_dict:
|
||||||
|
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
|
||||||
|
else:
|
||||||
|
if not row[1]: row[1] = row[0]
|
||||||
|
data.append(row)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_coa(doctype, parent, is_root=False, file_name=None):
|
def get_coa(doctype, parent, is_root=False, file_name=None):
|
||||||
''' called by tree view (to fetch node's children) '''
|
''' called by tree view (to fetch node's children) '''
|
||||||
|
|
||||||
|
file_doc, extension = get_file(file_name)
|
||||||
parent = None if parent==_('All Accounts') else parent
|
parent = None if parent==_('All Accounts') else parent
|
||||||
forest = build_forest(generate_data_from_csv(file_name))
|
|
||||||
|
if extension == 'csv':
|
||||||
|
data = generate_data_from_csv(file_doc)
|
||||||
|
else:
|
||||||
|
data = generate_data_from_excel(file_doc, extension)
|
||||||
|
|
||||||
|
forest = build_forest(data)
|
||||||
accounts = build_tree_from_json("", chart_data=forest) # returns alist of dict in a tree render-able form
|
accounts = build_tree_from_json("", chart_data=forest) # returns alist of dict in a tree render-able form
|
||||||
|
|
||||||
# filter out to show data for the selected node only
|
# filter out to show data for the selected node only
|
||||||
@ -91,6 +144,8 @@ def build_forest(data):
|
|||||||
|
|
||||||
# returns the path of any node in list format
|
# returns the path of any node in list format
|
||||||
def return_parent(data, child):
|
def return_parent(data, child):
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
for row in data:
|
for row in data:
|
||||||
account_name, parent_account = row[0:2]
|
account_name, parent_account = row[0:2]
|
||||||
if parent_account == account_name == child:
|
if parent_account == account_name == child:
|
||||||
@ -98,8 +153,9 @@ def build_forest(data):
|
|||||||
elif account_name == child:
|
elif account_name == child:
|
||||||
parent_account_list = return_parent(data, parent_account)
|
parent_account_list = return_parent(data, parent_account)
|
||||||
if not parent_account_list:
|
if not parent_account_list:
|
||||||
frappe.throw(_("The parent account {0} does not exists")
|
frappe.throw(_("The parent account {0} does not exists in the uploaded template").format(
|
||||||
.format(parent_account))
|
frappe.bold(parent_account)))
|
||||||
|
|
||||||
return [child] + parent_account_list
|
return [child] + parent_account_list
|
||||||
|
|
||||||
charts_map, paths = {}, []
|
charts_map, paths = {}, []
|
||||||
@ -114,7 +170,7 @@ def build_forest(data):
|
|||||||
error_messages.append("Row {0}: Please enter Account Name".format(line_no))
|
error_messages.append("Row {0}: Please enter Account Name".format(line_no))
|
||||||
|
|
||||||
charts_map[account_name] = {}
|
charts_map[account_name] = {}
|
||||||
if is_group == 1: charts_map[account_name]["is_group"] = is_group
|
if cint(is_group) == 1: charts_map[account_name]["is_group"] = is_group
|
||||||
if account_type: charts_map[account_name]["account_type"] = account_type
|
if account_type: charts_map[account_name]["account_type"] = account_type
|
||||||
if root_type: charts_map[account_name]["root_type"] = root_type
|
if root_type: charts_map[account_name]["root_type"] = root_type
|
||||||
if account_number: charts_map[account_name]["account_number"] = account_number
|
if account_number: charts_map[account_name]["account_number"] = account_number
|
||||||
@ -132,24 +188,94 @@ def build_forest(data):
|
|||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
def build_response_as_excel(writer):
|
||||||
|
filename = frappe.generate_hash("", 10)
|
||||||
|
with open(filename, 'wb') as f:
|
||||||
|
f.write(cstr(writer.getvalue()).encode('utf-8'))
|
||||||
|
f = open(filename)
|
||||||
|
reader = csv.reader(f)
|
||||||
|
|
||||||
|
from frappe.utils.xlsxutils import make_xlsx
|
||||||
|
xlsx_file = make_xlsx(reader, "Chart Of Accounts Importer Template")
|
||||||
|
|
||||||
|
f.close()
|
||||||
|
os.remove(filename)
|
||||||
|
|
||||||
|
# write out response as a xlsx type
|
||||||
|
frappe.response['filename'] = 'coa_importer_template.xlsx'
|
||||||
|
frappe.response['filecontent'] = xlsx_file.getvalue()
|
||||||
|
frappe.response['type'] = 'binary'
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def download_template():
|
def download_template(file_type, template_type):
|
||||||
data = frappe._dict(frappe.local.form_dict)
|
data = frappe._dict(frappe.local.form_dict)
|
||||||
|
|
||||||
|
writer = get_template(template_type)
|
||||||
|
|
||||||
|
if file_type == 'CSV':
|
||||||
|
# download csv file
|
||||||
|
frappe.response['result'] = cstr(writer.getvalue())
|
||||||
|
frappe.response['type'] = 'csv'
|
||||||
|
frappe.response['doctype'] = 'Chart of Accounts Importer'
|
||||||
|
else:
|
||||||
|
build_response_as_excel(writer)
|
||||||
|
|
||||||
|
def get_template(template_type):
|
||||||
|
|
||||||
fields = ["Account Name", "Parent Account", "Account Number", "Is Group", "Account Type", "Root Type"]
|
fields = ["Account Name", "Parent Account", "Account Number", "Is Group", "Account Type", "Root Type"]
|
||||||
writer = UnicodeWriter()
|
writer = UnicodeWriter()
|
||||||
|
writer.writerow(fields)
|
||||||
|
|
||||||
writer.writerow([_('Chart of Accounts Template')])
|
if template_type == 'Blank Template':
|
||||||
writer.writerow([_("Column Labels : ")] + fields)
|
for root_type in get_root_types():
|
||||||
writer.writerow([_("Start entering data from here : ")])
|
writer.writerow(['', '', '', 1, '', root_type])
|
||||||
|
|
||||||
|
for account in get_mandatory_group_accounts():
|
||||||
|
writer.writerow(['', '', '', 1, account, "Asset"])
|
||||||
|
|
||||||
|
for account_type in get_mandatory_account_types():
|
||||||
|
writer.writerow(['', '', '', 0, account_type.get('account_type'), account_type.get('root_type')])
|
||||||
|
else:
|
||||||
|
writer = get_sample_template(writer)
|
||||||
|
|
||||||
|
return writer
|
||||||
|
|
||||||
|
def get_sample_template(writer):
|
||||||
|
template = [
|
||||||
|
["Application Of Funds(Assets)", "", "", 1, "", "Asset"],
|
||||||
|
["Sources Of Funds(Liabilities)", "", "", 1, "", "Liability"],
|
||||||
|
["Equity", "", "", 1, "", "Equity"],
|
||||||
|
["Expenses", "", "", 1, "", "Expense"],
|
||||||
|
["Income", "", "", 1, "", "Income"],
|
||||||
|
["Bank Accounts", "Application Of Funds(Assets)", "", 1, "Bank", "Asset"],
|
||||||
|
["Cash In Hand", "Application Of Funds(Assets)", "", 1, "Cash", "Asset"],
|
||||||
|
["Stock Assets", "Application Of Funds(Assets)", "", 1, "Stock", "Asset"],
|
||||||
|
["Cost Of Goods Sold", "Expenses", "", 0, "Cost of Goods Sold", "Expense"],
|
||||||
|
["Asset Depreciation", "Expenses", "", 0, "Depreciation", "Expense"],
|
||||||
|
["Fixed Assets", "Application Of Funds(Assets)", "", 0, "Fixed Asset", "Asset"],
|
||||||
|
["Accounts Payable", "Sources Of Funds(Liabilities)", "", 0, "Payable", "Liability"],
|
||||||
|
["Accounts Receivable", "Application Of Funds(Assets)", "", 1, "Receivable", "Asset"],
|
||||||
|
["Stock Expenses", "Expenses", "", 0, "Stock Adjustment", "Expense"],
|
||||||
|
["Sample Bank", "Bank Accounts", "", 0, "Bank", "Asset"],
|
||||||
|
["Cash", "Cash In Hand", "", 0, "Cash", "Asset"],
|
||||||
|
["Stores", "Stock Assets", "", 0, "Stock", "Asset"],
|
||||||
|
]
|
||||||
|
|
||||||
|
for row in template:
|
||||||
|
writer.writerow(row)
|
||||||
|
|
||||||
|
return writer
|
||||||
|
|
||||||
# download csv file
|
|
||||||
frappe.response['result'] = cstr(writer.getvalue())
|
|
||||||
frappe.response['type'] = 'csv'
|
|
||||||
frappe.response['doctype'] = data.get('doctype')
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def validate_accounts(file_name):
|
def validate_accounts(file_name):
|
||||||
accounts = generate_data_from_csv(file_name, as_dict=True)
|
|
||||||
|
file_doc, extension = get_file(file_name)
|
||||||
|
|
||||||
|
if extension == 'csv':
|
||||||
|
accounts = generate_data_from_csv(file_doc, as_dict=True)
|
||||||
|
else:
|
||||||
|
accounts = generate_data_from_excel(file_doc, extension, as_dict=True)
|
||||||
|
|
||||||
accounts_dict = {}
|
accounts_dict = {}
|
||||||
for account in accounts:
|
for account in accounts:
|
||||||
@ -174,12 +300,38 @@ def validate_root(accounts):
|
|||||||
for account in roots:
|
for account in roots:
|
||||||
if not account.get("root_type") and account.get("account_name"):
|
if not account.get("root_type") and account.get("account_name"):
|
||||||
error_messages.append("Please enter Root Type for account- {0}".format(account.get("account_name")))
|
error_messages.append("Please enter Root Type for account- {0}".format(account.get("account_name")))
|
||||||
elif account.get("root_type") not in ("Asset", "Liability", "Expense", "Income", "Equity") and account.get("account_name"):
|
elif account.get("root_type") not in get_root_types() and account.get("account_name"):
|
||||||
error_messages.append("Root Type for {0} must be one of the Asset, Liability, Income, Expense and Equity".format(account.get("account_name")))
|
error_messages.append("Root Type for {0} must be one of the Asset, Liability, Income, Expense and Equity".format(account.get("account_name")))
|
||||||
|
|
||||||
if error_messages:
|
if error_messages:
|
||||||
return "<br>".join(error_messages)
|
return "<br>".join(error_messages)
|
||||||
|
|
||||||
|
def get_root_types():
|
||||||
|
return ('Asset', 'Liability', 'Expense', 'Income', 'Equity')
|
||||||
|
|
||||||
|
def get_report_type(root_type):
|
||||||
|
if root_type in ('Asset', 'Liability', 'Equity'):
|
||||||
|
return 'Balance Sheet'
|
||||||
|
else:
|
||||||
|
return 'Profit and Loss'
|
||||||
|
|
||||||
|
def get_mandatory_group_accounts():
|
||||||
|
return ('Bank', 'Cash', 'Stock')
|
||||||
|
|
||||||
|
def get_mandatory_account_types():
|
||||||
|
return [
|
||||||
|
{'account_type': 'Cost of Goods Sold', 'root_type': 'Expense'},
|
||||||
|
{'account_type': 'Depreciation', 'root_type': 'Expense'},
|
||||||
|
{'account_type': 'Fixed Asset', 'root_type': 'Asset'},
|
||||||
|
{'account_type': 'Payable', 'root_type': 'Liability'},
|
||||||
|
{'account_type': 'Receivable', 'root_type': 'Asset'},
|
||||||
|
{'account_type': 'Stock Adjustment', 'root_type': 'Expense'},
|
||||||
|
{'account_type': 'Bank', 'root_type': 'Asset'},
|
||||||
|
{'account_type': 'Cash', 'root_type': 'Asset'},
|
||||||
|
{'account_type': 'Stock', 'root_type': 'Asset'}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def validate_account_types(accounts):
|
def validate_account_types(accounts):
|
||||||
account_types_for_ledger = ["Cost of Goods Sold", "Depreciation", "Fixed Asset", "Payable", "Receivable", "Stock Adjustment"]
|
account_types_for_ledger = ["Cost of Goods Sold", "Depreciation", "Fixed Asset", "Payable", "Receivable", "Stock Adjustment"]
|
||||||
account_types = [accounts[d]["account_type"] for d in accounts if not accounts[d]['is_group'] == 1]
|
account_types = [accounts[d]["account_type"] for d in accounts if not accounts[d]['is_group'] == 1]
|
||||||
|
|||||||
@ -18,7 +18,8 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Invoice",
|
"label": "Invoice",
|
||||||
"options": "Sales Invoice",
|
"options": "Sales Invoice",
|
||||||
"reqd": 1
|
"reqd": 1,
|
||||||
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "sales_invoice.customer",
|
"fetch_from": "sales_invoice.customer",
|
||||||
@ -60,7 +61,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-09-26 11:05:36.016772",
|
"modified": "2020-02-20 16:16:20.724620",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Discounted Invoice",
|
"name": "Discounted Invoice",
|
||||||
|
|||||||
@ -232,11 +232,36 @@ def update_outstanding_amt(account, party_type, party, against_voucher_type, aga
|
|||||||
if bal < 0 and not on_cancel:
|
if bal < 0 and not on_cancel:
|
||||||
frappe.throw(_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal)))
|
frappe.throw(_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal)))
|
||||||
|
|
||||||
# Update outstanding amt on against voucher
|
|
||||||
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
|
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
|
||||||
|
update_outstanding_amt_in_ref(against_voucher, against_voucher_type, bal)
|
||||||
|
|
||||||
|
def update_outstanding_amt_in_ref(against_voucher, against_voucher_type, bal):
|
||||||
|
data = []
|
||||||
|
# Update outstanding amt on against voucher
|
||||||
|
if against_voucher_type == "Fees":
|
||||||
ref_doc = frappe.get_doc(against_voucher_type, against_voucher)
|
ref_doc = frappe.get_doc(against_voucher_type, against_voucher)
|
||||||
ref_doc.db_set('outstanding_amount', bal)
|
ref_doc.db_set('outstanding_amount', bal)
|
||||||
ref_doc.set_status(update=True)
|
ref_doc.set_status(update=True)
|
||||||
|
return
|
||||||
|
elif against_voucher_type == "Purchase Invoice":
|
||||||
|
from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import get_status
|
||||||
|
data = frappe.db.get_value(against_voucher_type, against_voucher,
|
||||||
|
["name as purchase_invoice", "outstanding_amount",
|
||||||
|
"is_return", "due_date", "docstatus"])
|
||||||
|
elif against_voucher_type == "Sales Invoice":
|
||||||
|
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_status
|
||||||
|
data = frappe.db.get_value(against_voucher_type, against_voucher,
|
||||||
|
["name as sales_invoice", "outstanding_amount", "is_discounted",
|
||||||
|
"is_return", "due_date", "docstatus"])
|
||||||
|
|
||||||
|
precision = frappe.get_precision(against_voucher_type, "outstanding_amount")
|
||||||
|
data = list(data)
|
||||||
|
data.append(precision)
|
||||||
|
status = get_status(data)
|
||||||
|
frappe.db.set_value(against_voucher_type, against_voucher, {
|
||||||
|
'outstanding_amount': bal,
|
||||||
|
'status': status
|
||||||
|
})
|
||||||
|
|
||||||
def validate_frozen_account(account, adv_adj=None):
|
def validate_frozen_account(account, adv_adj=None):
|
||||||
frozen_account = frappe.db.get_value("Account", account, "freeze_account")
|
frozen_account = frappe.db.get_value("Account", account, "freeze_account")
|
||||||
@ -274,6 +299,9 @@ def update_against_account(voucher_type, voucher_no):
|
|||||||
if d.against != new_against:
|
if d.against != new_against:
|
||||||
frappe.db.set_value("GL Entry", d.name, "against", new_against)
|
frappe.db.set_value("GL Entry", d.name, "against", new_against)
|
||||||
|
|
||||||
|
def on_doctype_update():
|
||||||
|
frappe.db.add_index("GL Entry", ["against_voucher_type", "against_voucher"])
|
||||||
|
frappe.db.add_index("GL Entry", ["voucher_type", "voucher_no"])
|
||||||
|
|
||||||
def rename_gle_sle_docs():
|
def rename_gle_sle_docs():
|
||||||
for doctype in ["GL Entry", "Stock Ledger Entry"]:
|
for doctype in ["GL Entry", "Stock Ledger Entry"]:
|
||||||
|
|||||||
@ -457,8 +457,7 @@ class JournalEntry(AccountsController):
|
|||||||
for d in self.get('accounts'):
|
for d in self.get('accounts'):
|
||||||
if d.party_type in ['Customer', 'Supplier'] and d.party:
|
if d.party_type in ['Customer', 'Supplier'] and d.party:
|
||||||
if not pay_to_recd_from:
|
if not pay_to_recd_from:
|
||||||
pay_to_recd_from = frappe.db.get_value(d.party_type, d.party,
|
pay_to_recd_from = d.party
|
||||||
"customer_name" if d.party_type=="Customer" else "supplier_name")
|
|
||||||
|
|
||||||
if pay_to_recd_from and pay_to_recd_from == d.party:
|
if pay_to_recd_from and pay_to_recd_from == d.party:
|
||||||
party_amount += (d.debit_in_account_currency or d.credit_in_account_currency)
|
party_amount += (d.debit_in_account_currency or d.credit_in_account_currency)
|
||||||
@ -469,7 +468,8 @@ class JournalEntry(AccountsController):
|
|||||||
bank_account_currency = d.account_currency
|
bank_account_currency = d.account_currency
|
||||||
|
|
||||||
if pay_to_recd_from:
|
if pay_to_recd_from:
|
||||||
self.pay_to_recd_from = pay_to_recd_from
|
self.pay_to_recd_from = frappe.db.get_value(d.party_type, pay_to_recd_from,
|
||||||
|
"customer_name" if d.party_type=="Customer" else "supplier_name")
|
||||||
if bank_amount:
|
if bank_amount:
|
||||||
total_amount = bank_amount
|
total_amount = bank_amount
|
||||||
currency = bank_account_currency
|
currency = bank_account_currency
|
||||||
|
|||||||
@ -149,6 +149,49 @@ class TestPaymentEntry(unittest.TestCase):
|
|||||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", pi.name, "outstanding_amount"))
|
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", pi.name, "outstanding_amount"))
|
||||||
self.assertEqual(outstanding_amount, 0)
|
self.assertEqual(outstanding_amount, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_payment_against_sales_invoice_to_check_status(self):
|
||||||
|
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||||
|
currency="USD", conversion_rate=50)
|
||||||
|
|
||||||
|
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
|
||||||
|
pe.reference_no = "1"
|
||||||
|
pe.reference_date = "2016-01-01"
|
||||||
|
pe.target_exchange_rate = 50
|
||||||
|
pe.insert()
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||||
|
self.assertEqual(outstanding_amount, 0)
|
||||||
|
self.assertEqual(si.status, 'Paid')
|
||||||
|
|
||||||
|
pe.cancel()
|
||||||
|
|
||||||
|
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||||
|
self.assertEqual(outstanding_amount, 100)
|
||||||
|
self.assertEqual(si.status, 'Unpaid')
|
||||||
|
|
||||||
|
def test_payment_against_purchase_invoice_to_check_status(self):
|
||||||
|
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
|
||||||
|
currency="USD", conversion_rate=50)
|
||||||
|
|
||||||
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank USD - _TC")
|
||||||
|
pe.reference_no = "1"
|
||||||
|
pe.reference_date = "2016-01-01"
|
||||||
|
pe.source_exchange_rate = 50
|
||||||
|
pe.insert()
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
outstanding_amount = flt(frappe.db.get_value("Purchase Invoice", pi.name, "outstanding_amount"))
|
||||||
|
self.assertEqual(outstanding_amount, 0)
|
||||||
|
self.assertEqual(pi.status, 'Paid')
|
||||||
|
|
||||||
|
pe.cancel()
|
||||||
|
|
||||||
|
outstanding_amount = flt(frappe.db.get_value("Purchase Invoice", pi.name, "outstanding_amount"))
|
||||||
|
self.assertEqual(outstanding_amount, 100)
|
||||||
|
self.assertEqual(pi.status, 'Unpaid')
|
||||||
|
|
||||||
def test_payment_entry_against_ec(self):
|
def test_payment_entry_against_ec(self):
|
||||||
|
|
||||||
payable = frappe.get_cached_value('Company', "_Test Company", 'default_payable_account')
|
payable = frappe.get_cached_value('Company', "_Test Company", 'default_payable_account')
|
||||||
|
|||||||
@ -245,7 +245,7 @@ def filter_pricing_rules(args, pricing_rules, doc=None):
|
|||||||
|
|
||||||
def validate_quantity_and_amount_for_suggestion(args, qty, amount, item_code, transaction_type):
|
def validate_quantity_and_amount_for_suggestion(args, qty, amount, item_code, transaction_type):
|
||||||
fieldname, msg = '', ''
|
fieldname, msg = '', ''
|
||||||
type_of_transaction = 'purcahse' if transaction_type == "buying" else "sale"
|
type_of_transaction = 'purchase' if transaction_type == 'buying' else 'sale'
|
||||||
|
|
||||||
for field, value in {'min_qty': qty, 'min_amt': amount}.items():
|
for field, value in {'min_qty': qty, 'min_amt': amount}.items():
|
||||||
if (args.get(field) and value < args.get(field)
|
if (args.get(field) and value < args.get(field)
|
||||||
|
|||||||
@ -125,6 +125,27 @@ class PurchaseInvoice(BuyingController):
|
|||||||
else:
|
else:
|
||||||
self.remarks = _("No Remarks")
|
self.remarks = _("No Remarks")
|
||||||
|
|
||||||
|
def set_status(self, update=False, status=None, update_modified=True):
|
||||||
|
if self.is_new():
|
||||||
|
if self.get('amended_from'):
|
||||||
|
self.status = 'Draft'
|
||||||
|
return
|
||||||
|
|
||||||
|
if not status:
|
||||||
|
precision = self.precision("outstanding_amount")
|
||||||
|
args = [
|
||||||
|
self.name,
|
||||||
|
self.outstanding_amount,
|
||||||
|
self.is_return,
|
||||||
|
self.due_date,
|
||||||
|
self.docstatus,
|
||||||
|
precision
|
||||||
|
]
|
||||||
|
self.status = get_status(args)
|
||||||
|
|
||||||
|
if update:
|
||||||
|
self.db_set('status', self.status, update_modified = update_modified)
|
||||||
|
|
||||||
def set_missing_values(self, for_validate=False):
|
def set_missing_values(self, for_validate=False):
|
||||||
if not self.credit_to:
|
if not self.credit_to:
|
||||||
self.credit_to = get_party_account("Supplier", self.supplier, self.company)
|
self.credit_to = get_party_account("Supplier", self.supplier, self.company)
|
||||||
@ -380,7 +401,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
update_outstanding_amt(self.credit_to, "Supplier", self.supplier,
|
update_outstanding_amt(self.credit_to, "Supplier", self.supplier,
|
||||||
self.doctype, self.return_against if cint(self.is_return) and self.return_against else self.name)
|
self.doctype, self.return_against if cint(self.is_return) and self.return_against else self.name)
|
||||||
|
|
||||||
if repost_future_gle and cint(self.update_stock) and self.auto_accounting_for_stock:
|
if (repost_future_gle or self.flags.repost_future_gle) and cint(self.update_stock) and self.auto_accounting_for_stock:
|
||||||
from erpnext.controllers.stock_controller import update_gl_entries_after
|
from erpnext.controllers.stock_controller import update_gl_entries_after
|
||||||
items, warehouses = self.get_items_and_warehouses()
|
items, warehouses = self.get_items_and_warehouses()
|
||||||
update_gl_entries_after(self.posting_date, self.posting_time,
|
update_gl_entries_after(self.posting_date, self.posting_time,
|
||||||
@ -1007,6 +1028,34 @@ class PurchaseInvoice(BuyingController):
|
|||||||
# calculate totals again after applying TDS
|
# calculate totals again after applying TDS
|
||||||
self.calculate_taxes_and_totals()
|
self.calculate_taxes_and_totals()
|
||||||
|
|
||||||
|
def get_status(*args):
|
||||||
|
purchase_invoice, outstanding_amount, is_return, due_date, docstatus, precision = args[0]
|
||||||
|
|
||||||
|
outstanding_amount = flt(outstanding_amount, precision)
|
||||||
|
due_date = getdate(due_date)
|
||||||
|
now_date = getdate()
|
||||||
|
|
||||||
|
if docstatus == 2:
|
||||||
|
status = "Cancelled"
|
||||||
|
elif docstatus == 1:
|
||||||
|
if outstanding_amount > 0 and due_date < now_date:
|
||||||
|
status = "Overdue"
|
||||||
|
elif outstanding_amount > 0 and due_date >= now_date:
|
||||||
|
status = "Unpaid"
|
||||||
|
#Check if outstanding amount is 0 due to debit note issued against invoice
|
||||||
|
elif outstanding_amount <= 0 and is_return == 0 and frappe.db.get_value('Purchase Invoice', {'is_return': 1, 'return_against': purchase_invoice, 'docstatus': 1}):
|
||||||
|
status = "Debit Note Issued"
|
||||||
|
elif is_return == 1:
|
||||||
|
status = "Return"
|
||||||
|
elif outstanding_amount <=0:
|
||||||
|
status = "Paid"
|
||||||
|
else:
|
||||||
|
status = "Submitted"
|
||||||
|
else:
|
||||||
|
status = "Draft"
|
||||||
|
|
||||||
|
return status
|
||||||
|
|
||||||
def get_list_context(context=None):
|
def get_list_context(context=None):
|
||||||
from erpnext.controllers.website_list_for_contact import get_list_context
|
from erpnext.controllers.website_list_for_contact import get_list_context
|
||||||
list_context = get_list_context(context)
|
list_context = get_list_context(context)
|
||||||
|
|||||||
@ -723,7 +723,7 @@ class SalesInvoice(SellingController):
|
|||||||
update_outstanding_amt(self.debit_to, "Customer", self.customer,
|
update_outstanding_amt(self.debit_to, "Customer", self.customer,
|
||||||
self.doctype, self.return_against if cint(self.is_return) and self.return_against else self.name)
|
self.doctype, self.return_against if cint(self.is_return) and self.return_against else self.name)
|
||||||
|
|
||||||
if repost_future_gle and cint(self.update_stock) \
|
if (repost_future_gle or self.flags.repost_future_gle) and cint(self.update_stock) \
|
||||||
and cint(auto_accounting_for_stock):
|
and cint(auto_accounting_for_stock):
|
||||||
items, warehouses = self.get_items_and_warehouses()
|
items, warehouses = self.get_items_and_warehouses()
|
||||||
update_gl_entries_after(self.posting_date, self.posting_time,
|
update_gl_entries_after(self.posting_date, self.posting_time,
|
||||||
@ -1217,63 +1217,84 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
self.set_missing_values(for_validate = True)
|
self.set_missing_values(for_validate = True)
|
||||||
|
|
||||||
def get_discounting_status(self):
|
|
||||||
status = None
|
|
||||||
if self.is_discounted:
|
|
||||||
invoice_discounting_list = frappe.db.sql("""
|
|
||||||
select status
|
|
||||||
from `tabInvoice Discounting` id, `tabDiscounted Invoice` d
|
|
||||||
where
|
|
||||||
id.name = d.parent
|
|
||||||
and d.sales_invoice=%s
|
|
||||||
and id.docstatus=1
|
|
||||||
and status in ('Disbursed', 'Settled')
|
|
||||||
""", self.name)
|
|
||||||
for d in invoice_discounting_list:
|
|
||||||
status = d[0]
|
|
||||||
if status == "Disbursed":
|
|
||||||
break
|
|
||||||
return status
|
|
||||||
|
|
||||||
def set_status(self, update=False, status=None, update_modified=True):
|
def set_status(self, update=False, status=None, update_modified=True):
|
||||||
if self.is_new():
|
if self.is_new():
|
||||||
if self.get('amended_from'):
|
if self.get('amended_from'):
|
||||||
self.status = 'Draft'
|
self.status = 'Draft'
|
||||||
return
|
return
|
||||||
|
|
||||||
precision = self.precision("outstanding_amount")
|
|
||||||
outstanding_amount = flt(self.outstanding_amount, precision)
|
|
||||||
due_date = getdate(self.due_date)
|
|
||||||
nowdate = getdate()
|
|
||||||
discountng_status = self.get_discounting_status()
|
|
||||||
|
|
||||||
if not status:
|
if not status:
|
||||||
if self.docstatus == 2:
|
precision = self.precision("outstanding_amount")
|
||||||
status = "Cancelled"
|
args = [
|
||||||
elif self.docstatus == 1:
|
self.name,
|
||||||
if outstanding_amount > 0 and due_date < nowdate and self.is_discounted and discountng_status=='Disbursed':
|
self.outstanding_amount,
|
||||||
self.status = "Overdue and Discounted"
|
self.is_discounted,
|
||||||
elif outstanding_amount > 0 and due_date < nowdate:
|
self.is_return,
|
||||||
self.status = "Overdue"
|
self.due_date,
|
||||||
elif outstanding_amount > 0 and due_date >= nowdate and self.is_discounted and discountng_status=='Disbursed':
|
self.docstatus,
|
||||||
self.status = "Unpaid and Discounted"
|
precision,
|
||||||
elif outstanding_amount > 0 and due_date >= nowdate:
|
]
|
||||||
self.status = "Unpaid"
|
self.status = get_status(args)
|
||||||
#Check if outstanding amount is 0 due to credit note issued against invoice
|
|
||||||
elif outstanding_amount <= 0 and self.is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
|
|
||||||
self.status = "Credit Note Issued"
|
|
||||||
elif self.is_return == 1:
|
|
||||||
self.status = "Return"
|
|
||||||
elif outstanding_amount<=0:
|
|
||||||
self.status = "Paid"
|
|
||||||
else:
|
|
||||||
self.status = "Submitted"
|
|
||||||
else:
|
|
||||||
self.status = "Draft"
|
|
||||||
|
|
||||||
if update:
|
if update:
|
||||||
self.db_set('status', self.status, update_modified = update_modified)
|
self.db_set('status', self.status, update_modified = update_modified)
|
||||||
|
|
||||||
|
def get_discounting_status(sales_invoice):
|
||||||
|
status = None
|
||||||
|
|
||||||
|
invoice_discounting_list = frappe.db.sql("""
|
||||||
|
select status
|
||||||
|
from `tabInvoice Discounting` id, `tabDiscounted Invoice` d
|
||||||
|
where
|
||||||
|
id.name = d.parent
|
||||||
|
and d.sales_invoice=%s
|
||||||
|
and id.docstatus=1
|
||||||
|
and status in ('Disbursed', 'Settled')
|
||||||
|
""", sales_invoice)
|
||||||
|
|
||||||
|
for d in invoice_discounting_list:
|
||||||
|
status = d[0]
|
||||||
|
if status == "Disbursed":
|
||||||
|
break
|
||||||
|
|
||||||
|
return status
|
||||||
|
|
||||||
|
def get_status(*args):
|
||||||
|
sales_invoice, outstanding_amount, is_discounted, is_return, due_date, docstatus, precision = args[0]
|
||||||
|
|
||||||
|
discounting_status = None
|
||||||
|
if is_discounted:
|
||||||
|
discounting_status = get_discounting_status(sales_invoice)
|
||||||
|
|
||||||
|
outstanding_amount = flt(outstanding_amount, precision)
|
||||||
|
due_date = getdate(due_date)
|
||||||
|
now_date = getdate()
|
||||||
|
|
||||||
|
if docstatus == 2:
|
||||||
|
status = "Cancelled"
|
||||||
|
elif docstatus == 1:
|
||||||
|
if outstanding_amount > 0 and due_date < now_date and is_discounted and discounting_status=='Disbursed':
|
||||||
|
status = "Overdue and Discounted"
|
||||||
|
elif outstanding_amount > 0 and due_date < now_date:
|
||||||
|
status = "Overdue"
|
||||||
|
elif outstanding_amount > 0 and due_date >= now_date and is_discounted and discounting_status=='Disbursed':
|
||||||
|
status = "Unpaid and Discounted"
|
||||||
|
elif outstanding_amount > 0 and due_date >= now_date:
|
||||||
|
status = "Unpaid"
|
||||||
|
#Check if outstanding amount is 0 due to credit note issued against invoice
|
||||||
|
elif outstanding_amount <= 0 and is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': sales_invoice, 'docstatus': 1}):
|
||||||
|
status = "Credit Note Issued"
|
||||||
|
elif is_return == 1:
|
||||||
|
status = "Return"
|
||||||
|
elif outstanding_amount <=0:
|
||||||
|
status = "Paid"
|
||||||
|
else:
|
||||||
|
status = "Submitted"
|
||||||
|
else:
|
||||||
|
status = "Draft"
|
||||||
|
|
||||||
|
return status
|
||||||
|
|
||||||
def validate_inter_company_party(doctype, party, company, inter_company_reference):
|
def validate_inter_company_party(doctype, party, company, inter_company_reference):
|
||||||
if not party:
|
if not party:
|
||||||
return
|
return
|
||||||
|
|||||||
@ -140,8 +140,11 @@ def make_entry(args, adv_adj, update_outstanding, from_repost=False):
|
|||||||
gle = frappe.get_doc(args)
|
gle = frappe.get_doc(args)
|
||||||
gle.flags.ignore_permissions = 1
|
gle.flags.ignore_permissions = 1
|
||||||
gle.flags.from_repost = from_repost
|
gle.flags.from_repost = from_repost
|
||||||
gle.insert()
|
gle.validate()
|
||||||
|
gle.flags.ignore_permissions = True
|
||||||
|
gle.db_insert()
|
||||||
gle.run_method("on_update_with_args", adv_adj, update_outstanding, from_repost)
|
gle.run_method("on_update_with_args", adv_adj, update_outstanding, from_repost)
|
||||||
|
gle.flags.ignore_validate = True
|
||||||
gle.submit()
|
gle.submit()
|
||||||
|
|
||||||
def validate_account_for_perpetual_inventory(gl_map):
|
def validate_account_for_perpetual_inventory(gl_map):
|
||||||
|
|||||||
@ -11,18 +11,18 @@ frappe.query_reports["Accounts Payable"] = {
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"default": frappe.defaults.get_user_default("Company")
|
"default": frappe.defaults.get_user_default("Company")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"report_date",
|
||||||
|
"label": __("Posting Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today()
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"ageing_based_on",
|
"fieldname":"ageing_based_on",
|
||||||
"label": __("Ageing Based On"),
|
"label": __("Ageing Based On"),
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"options": 'Posting Date\nDue Date\nSupplier Invoice Date',
|
"options": 'Posting Date\nDue Date\nSupplier Invoice Date',
|
||||||
"default": "Posting Date"
|
"default": "Due Date"
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname":"report_date",
|
|
||||||
"label": __("As on Date"),
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"default": frappe.datetime.get_today()
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"range1",
|
"fieldname":"range1",
|
||||||
|
|||||||
@ -10,18 +10,18 @@ frappe.query_reports["Accounts Payable Summary"] = {
|
|||||||
"options": "Company",
|
"options": "Company",
|
||||||
"default": frappe.defaults.get_user_default("Company")
|
"default": frappe.defaults.get_user_default("Company")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"report_date",
|
||||||
|
"label": __("Posting Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today()
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"ageing_based_on",
|
"fieldname":"ageing_based_on",
|
||||||
"label": __("Ageing Based On"),
|
"label": __("Ageing Based On"),
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"options": 'Posting Date\nDue Date',
|
"options": 'Posting Date\nDue Date',
|
||||||
"default": "Posting Date"
|
"default": "Due Date"
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname":"report_date",
|
|
||||||
"label": __("Date"),
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"default": frappe.datetime.get_today()
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"range1",
|
"fieldname":"range1",
|
||||||
|
|||||||
@ -11,18 +11,18 @@ frappe.query_reports["Accounts Receivable"] = {
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"default": frappe.defaults.get_user_default("Company")
|
"default": frappe.defaults.get_user_default("Company")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"report_date",
|
||||||
|
"label": __("Posting Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today()
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"ageing_based_on",
|
"fieldname":"ageing_based_on",
|
||||||
"label": __("Ageing Based On"),
|
"label": __("Ageing Based On"),
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"options": 'Posting Date\nDue Date',
|
"options": 'Posting Date\nDue Date',
|
||||||
"default": "Posting Date"
|
"default": "Due Date"
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname":"report_date",
|
|
||||||
"label": __("As on Date"),
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"default": frappe.datetime.get_today()
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"range1",
|
"fieldname":"range1",
|
||||||
@ -148,7 +148,7 @@ frappe.query_reports["Accounts Receivable"] = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"show_delivery_notes",
|
"fieldname":"show_delivery_notes",
|
||||||
"label": __("Show Delivery Notes"),
|
"label": __("Show Linked Delivery Notes"),
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,18 +10,18 @@ frappe.query_reports["Accounts Receivable Summary"] = {
|
|||||||
"options": "Company",
|
"options": "Company",
|
||||||
"default": frappe.defaults.get_user_default("Company")
|
"default": frappe.defaults.get_user_default("Company")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"report_date",
|
||||||
|
"label": __("Posting Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today()
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"ageing_based_on",
|
"fieldname":"ageing_based_on",
|
||||||
"label": __("Ageing Based On"),
|
"label": __("Ageing Based On"),
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"options": 'Posting Date\nDue Date',
|
"options": 'Posting Date\nDue Date',
|
||||||
"default": "Posting Date"
|
"default": "Due Date"
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname":"report_date",
|
|
||||||
"label": __("Date"),
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"default": frappe.datetime.get_today()
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"range1",
|
"fieldname":"range1",
|
||||||
|
|||||||
@ -29,7 +29,7 @@ def get_data(filters):
|
|||||||
|
|
||||||
row.update(next(asset for asset in assets if asset["asset_category"] == asset_category.get("asset_category", "")))
|
row.update(next(asset for asset in assets if asset["asset_category"] == asset_category.get("asset_category", "")))
|
||||||
row.accumulated_depreciation_as_on_to_date = (flt(row.accumulated_depreciation_as_on_from_date) +
|
row.accumulated_depreciation_as_on_to_date = (flt(row.accumulated_depreciation_as_on_from_date) +
|
||||||
flt(row.depreciation_amount_during_the_period) - flt(row.depreciation_eliminated))
|
flt(row.depreciation_amount_during_the_period) - flt(row.depreciation_eliminated_during_the_period))
|
||||||
|
|
||||||
row.net_asset_value_as_on_from_date = (flt(row.cost_as_on_from_date) -
|
row.net_asset_value_as_on_from_date = (flt(row.cost_as_on_from_date) -
|
||||||
flt(row.accumulated_depreciation_as_on_from_date))
|
flt(row.accumulated_depreciation_as_on_from_date))
|
||||||
@ -86,7 +86,6 @@ def get_asset_categories(filters):
|
|||||||
group by asset_category
|
group by asset_category
|
||||||
""", {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1)
|
""", {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1)
|
||||||
|
|
||||||
|
|
||||||
def get_assets(filters):
|
def get_assets(filters):
|
||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
SELECT results.asset_category,
|
SELECT results.asset_category,
|
||||||
@ -94,9 +93,7 @@ def get_assets(filters):
|
|||||||
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
|
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
|
||||||
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
|
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
|
||||||
from (SELECT a.asset_category,
|
from (SELECT a.asset_category,
|
||||||
ifnull(sum(a.opening_accumulated_depreciation +
|
ifnull(sum(case when ds.schedule_date < %(from_date)s then
|
||||||
case when ds.schedule_date < %(from_date)s and
|
|
||||||
(ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s) then
|
|
||||||
ds.depreciation_amount
|
ds.depreciation_amount
|
||||||
else
|
else
|
||||||
0
|
0
|
||||||
@ -107,7 +104,6 @@ def get_assets(filters):
|
|||||||
else
|
else
|
||||||
0
|
0
|
||||||
end), 0) as depreciation_eliminated_during_the_period,
|
end), 0) as depreciation_eliminated_during_the_period,
|
||||||
|
|
||||||
ifnull(sum(case when ds.schedule_date >= %(from_date)s and ds.schedule_date <= %(to_date)s
|
ifnull(sum(case when ds.schedule_date >= %(from_date)s and ds.schedule_date <= %(to_date)s
|
||||||
and (ifnull(a.disposal_date, 0) = 0 or ds.schedule_date <= a.disposal_date) then
|
and (ifnull(a.disposal_date, 0) = 0 or ds.schedule_date <= a.disposal_date) then
|
||||||
ds.depreciation_amount
|
ds.depreciation_amount
|
||||||
@ -120,7 +116,8 @@ def get_assets(filters):
|
|||||||
union
|
union
|
||||||
SELECT a.asset_category,
|
SELECT a.asset_category,
|
||||||
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
|
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
|
||||||
and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) then
|
and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s)
|
||||||
|
then
|
||||||
0
|
0
|
||||||
else
|
else
|
||||||
a.opening_accumulated_depreciation
|
a.opening_accumulated_depreciation
|
||||||
@ -133,7 +130,6 @@ def get_assets(filters):
|
|||||||
0 as depreciation_amount_during_the_period
|
0 as depreciation_amount_during_the_period
|
||||||
from `tabAsset` a
|
from `tabAsset` a
|
||||||
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s
|
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s
|
||||||
and not exists(select * from `tabDepreciation Schedule` ds where a.name = ds.parent)
|
|
||||||
group by a.asset_category) as results
|
group by a.asset_category) as results
|
||||||
group by results.asset_category
|
group by results.asset_category
|
||||||
""", {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1)
|
""", {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1)
|
||||||
|
|||||||
@ -306,10 +306,6 @@ def get_conditions(filters):
|
|||||||
|
|
||||||
def get_items(filters, additional_query_columns):
|
def get_items(filters, additional_query_columns):
|
||||||
conditions = get_conditions(filters)
|
conditions = get_conditions(filters)
|
||||||
match_conditions = frappe.build_match_conditions("Purchase Invoice")
|
|
||||||
|
|
||||||
if match_conditions:
|
|
||||||
match_conditions = " and {0} ".format(match_conditions)
|
|
||||||
|
|
||||||
if additional_query_columns:
|
if additional_query_columns:
|
||||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||||
@ -327,8 +323,8 @@ def get_items(filters, additional_query_columns):
|
|||||||
`tabPurchase Invoice`.supplier_name, `tabPurchase Invoice`.mode_of_payment {0}
|
`tabPurchase Invoice`.supplier_name, `tabPurchase Invoice`.mode_of_payment {0}
|
||||||
from `tabPurchase Invoice`, `tabPurchase Invoice Item`
|
from `tabPurchase Invoice`, `tabPurchase Invoice Item`
|
||||||
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and
|
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and
|
||||||
`tabPurchase Invoice`.docstatus = 1 %s %s
|
`tabPurchase Invoice`.docstatus = 1 %s
|
||||||
""".format(additional_query_columns) % (conditions, match_conditions), filters, as_dict=1)
|
""".format(additional_query_columns) % (conditions), filters, as_dict=1)
|
||||||
|
|
||||||
def get_aii_accounts():
|
def get_aii_accounts():
|
||||||
return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))
|
return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))
|
||||||
|
|||||||
@ -370,10 +370,6 @@ def get_group_by_conditions(filters, doctype):
|
|||||||
|
|
||||||
def get_items(filters, additional_query_columns):
|
def get_items(filters, additional_query_columns):
|
||||||
conditions = get_conditions(filters)
|
conditions = get_conditions(filters)
|
||||||
match_conditions = frappe.build_match_conditions("Sales Invoice")
|
|
||||||
|
|
||||||
if match_conditions:
|
|
||||||
match_conditions = " and {0} ".format(match_conditions)
|
|
||||||
|
|
||||||
if additional_query_columns:
|
if additional_query_columns:
|
||||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||||
@ -394,8 +390,8 @@ def get_items(filters, additional_query_columns):
|
|||||||
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0}
|
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0}
|
||||||
from `tabSales Invoice`, `tabSales Invoice Item`
|
from `tabSales Invoice`, `tabSales Invoice Item`
|
||||||
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
|
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
|
||||||
and `tabSales Invoice`.docstatus = 1 {1} {2}
|
and `tabSales Invoice`.docstatus = 1 {1}
|
||||||
""".format(additional_query_columns or '', conditions, match_conditions), filters, as_dict=1) #nosec
|
""".format(additional_query_columns or '', conditions), filters, as_dict=1) #nosec
|
||||||
|
|
||||||
def get_delivery_notes_against_sales_order(item_list):
|
def get_delivery_notes_against_sales_order(item_list):
|
||||||
so_dn_map = frappe._dict()
|
so_dn_map = frappe._dict()
|
||||||
|
|||||||
@ -12,7 +12,6 @@ from erpnext.stock.doctype.item.item import validate_end_of_life
|
|||||||
|
|
||||||
def update_last_purchase_rate(doc, is_submit):
|
def update_last_purchase_rate(doc, is_submit):
|
||||||
"""updates last_purchase_rate in item table for each item"""
|
"""updates last_purchase_rate in item table for each item"""
|
||||||
|
|
||||||
import frappe.utils
|
import frappe.utils
|
||||||
this_purchase_date = frappe.utils.getdate(doc.get('posting_date') or doc.get('transaction_date'))
|
this_purchase_date = frappe.utils.getdate(doc.get('posting_date') or doc.get('transaction_date'))
|
||||||
|
|
||||||
@ -23,7 +22,7 @@ def update_last_purchase_rate(doc, is_submit):
|
|||||||
# compare last purchase date and this transaction's date
|
# compare last purchase date and this transaction's date
|
||||||
last_purchase_rate = None
|
last_purchase_rate = None
|
||||||
if last_purchase_details and \
|
if last_purchase_details and \
|
||||||
(last_purchase_details.purchase_date > this_purchase_date):
|
(doc.get('docstatus') == 2 or last_purchase_details.purchase_date > this_purchase_date):
|
||||||
last_purchase_rate = last_purchase_details['base_net_rate']
|
last_purchase_rate = last_purchase_details['base_net_rate']
|
||||||
elif is_submit == 1:
|
elif is_submit == 1:
|
||||||
# even if this transaction is the latest one, it should be submitted
|
# even if this transaction is the latest one, it should be submitted
|
||||||
|
|||||||
@ -7,6 +7,13 @@ def get_data():
|
|||||||
"label": _("Purchasing"),
|
"label": _("Purchasing"),
|
||||||
"icon": "fa fa-star",
|
"icon": "fa fa-star",
|
||||||
"items": [
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Material Request",
|
||||||
|
"onboard": 1,
|
||||||
|
"dependencies": ["Item"],
|
||||||
|
"description": _("Request for purchase."),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Purchase Order",
|
"name": "Purchase Order",
|
||||||
@ -20,13 +27,6 @@ def get_data():
|
|||||||
"onboard": 1,
|
"onboard": 1,
|
||||||
"dependencies": ["Item", "Supplier"]
|
"dependencies": ["Item", "Supplier"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Material Request",
|
|
||||||
"onboard": 1,
|
|
||||||
"dependencies": ["Item"],
|
|
||||||
"description": _("Request for purchase."),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Request for Quotation",
|
"name": "Request for Quotation",
|
||||||
@ -63,6 +63,11 @@ def get_data():
|
|||||||
"name": "Price List",
|
"name": "Price List",
|
||||||
"description": _("Price List master.")
|
"description": _("Price List master.")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Pricing Rule",
|
||||||
|
"description": _("Rules for applying pricing and discount.")
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Product Bundle",
|
"name": "Product Bundle",
|
||||||
@ -80,11 +85,6 @@ def get_data():
|
|||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Promotional Scheme",
|
"name": "Promotional Scheme",
|
||||||
"description": _("Rules for applying different promotional schemes.")
|
"description": _("Rules for applying different promotional schemes.")
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Pricing Rule",
|
|
||||||
"description": _("Rules for applying pricing and discount.")
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -149,13 +149,6 @@ def get_data():
|
|||||||
"reference_doctype": "Purchase Order",
|
"reference_doctype": "Purchase Order",
|
||||||
"onboard": 1
|
"onboard": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "report",
|
|
||||||
"is_query_report": True,
|
|
||||||
"name": "Supplier-Wise Sales Analytics",
|
|
||||||
"reference_doctype": "Stock Ledger Entry",
|
|
||||||
"onboard": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "report",
|
"type": "report",
|
||||||
"is_query_report": True,
|
"is_query_report": True,
|
||||||
@ -177,6 +170,16 @@ def get_data():
|
|||||||
"reference_doctype": "Material Request",
|
"reference_doctype": "Material Request",
|
||||||
"onboard": 1,
|
"onboard": 1,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "report",
|
||||||
|
"is_query_report": True,
|
||||||
|
"name": "Address And Contacts",
|
||||||
|
"label": _("Supplier Addresses And Contacts"),
|
||||||
|
"reference_doctype": "Address",
|
||||||
|
"route_options": {
|
||||||
|
"party_type": "Supplier"
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -226,18 +229,15 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "report",
|
"type": "report",
|
||||||
"is_query_report": True,
|
"is_query_report": True,
|
||||||
"name": "Material Requests for which Supplier Quotations are not created",
|
"name": "Supplier-Wise Sales Analytics",
|
||||||
"reference_doctype": "Material Request"
|
"reference_doctype": "Stock Ledger Entry",
|
||||||
|
"onboard": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "report",
|
"type": "report",
|
||||||
"is_query_report": True,
|
"is_query_report": True,
|
||||||
"name": "Address And Contacts",
|
"name": "Material Requests for which Supplier Quotations are not created",
|
||||||
"label": _("Supplier Addresses And Contacts"),
|
"reference_doctype": "Material Request"
|
||||||
"reference_doctype": "Address",
|
|
||||||
"route_options": {
|
|
||||||
"party_type": "Supplier"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@ -44,17 +44,6 @@ status_map = {
|
|||||||
["Closed", "eval:self.status=='Closed'"],
|
["Closed", "eval:self.status=='Closed'"],
|
||||||
["On Hold", "eval:self.status=='On Hold'"],
|
["On Hold", "eval:self.status=='On Hold'"],
|
||||||
],
|
],
|
||||||
"Purchase Invoice": [
|
|
||||||
["Draft", None],
|
|
||||||
["Submitted", "eval:self.docstatus==1"],
|
|
||||||
["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
|
|
||||||
["Return", "eval:self.is_return==1 and self.docstatus==1"],
|
|
||||||
["Debit Note Issued",
|
|
||||||
"eval:self.outstanding_amount <= 0 and self.docstatus==1 and self.is_return==0 and get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1})"],
|
|
||||||
["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
|
|
||||||
["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
|
|
||||||
["Cancelled", "eval:self.docstatus==2"],
|
|
||||||
],
|
|
||||||
"Purchase Order": [
|
"Purchase Order": [
|
||||||
["Draft", None],
|
["Draft", None],
|
||||||
["To Receive and Bill", "eval:self.per_received < 100 and self.per_billed < 100 and self.docstatus == 1"],
|
["To Receive and Bill", "eval:self.per_received < 100 and self.per_billed < 100 and self.docstatus == 1"],
|
||||||
|
|||||||
@ -34,7 +34,7 @@ class StockController(AccountsController):
|
|||||||
gl_entries = self.get_gl_entries(warehouse_account)
|
gl_entries = self.get_gl_entries(warehouse_account)
|
||||||
make_gl_entries(gl_entries, from_repost=from_repost)
|
make_gl_entries(gl_entries, from_repost=from_repost)
|
||||||
|
|
||||||
if repost_future_gle:
|
if (repost_future_gle or self.flags.repost_future_gle):
|
||||||
items, warehouses = self.get_items_and_warehouses()
|
items, warehouses = self.get_items_and_warehouses()
|
||||||
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items,
|
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items,
|
||||||
warehouse_account, company=self.company)
|
warehouse_account, company=self.company)
|
||||||
@ -238,6 +238,10 @@ class StockController(AccountsController):
|
|||||||
for d in self.items:
|
for d in self.items:
|
||||||
if not d.batch_no: continue
|
if not d.batch_no: continue
|
||||||
|
|
||||||
|
serial_nos = [d.name for d in frappe.get_all("Serial No", {'batch_no': d.batch_no})]
|
||||||
|
if serial_nos:
|
||||||
|
frappe.db.set_value("Serial No", { 'name': ['in', serial_nos] }, "batch_no", None)
|
||||||
|
|
||||||
d.batch_no = None
|
d.batch_no = None
|
||||||
d.db_set("batch_no", None)
|
d.db_set("batch_no", None)
|
||||||
|
|
||||||
|
|||||||
@ -11,5 +11,12 @@ frappe.ui.form.on('Student Admission', {
|
|||||||
|
|
||||||
academic_year: function(frm) {
|
academic_year: function(frm) {
|
||||||
frm.trigger("program");
|
frm.trigger("program");
|
||||||
|
},
|
||||||
|
|
||||||
|
admission_end_date: function(frm) {
|
||||||
|
if(frm.doc.admission_end_date && frm.doc.admission_end_date <= frm.doc.admission_start_date){
|
||||||
|
frm.set_value("admission_end_date", "");
|
||||||
|
frappe.throw(__("Admission End Date should be greater than Admission Start Date."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -39,19 +39,21 @@ class AdditionalSalary(Document):
|
|||||||
return amount_per_day * no_of_days
|
return amount_per_day * no_of_days
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_additional_salary_component(employee, start_date, end_date):
|
def get_additional_salary_component(employee, start_date, end_date, component_type):
|
||||||
additional_components = frappe.db.sql("""
|
additional_components = frappe.db.sql("""
|
||||||
select salary_component, sum(amount) as amount, overwrite_salary_structure_amount, deduct_full_tax_on_selected_payroll_date
|
select salary_component, sum(amount) as amount, overwrite_salary_structure_amount, deduct_full_tax_on_selected_payroll_date
|
||||||
from `tabAdditional Salary`
|
from `tabAdditional Salary`
|
||||||
where employee=%(employee)s
|
where employee=%(employee)s
|
||||||
and docstatus = 1
|
and docstatus = 1
|
||||||
and payroll_date between %(from_date)s and %(to_date)s
|
and payroll_date between %(from_date)s and %(to_date)s
|
||||||
|
and type = %(component_type)s
|
||||||
group by salary_component, overwrite_salary_structure_amount
|
group by salary_component, overwrite_salary_structure_amount
|
||||||
order by salary_component, overwrite_salary_structure_amount
|
order by salary_component, overwrite_salary_structure_amount
|
||||||
""", {
|
""", {
|
||||||
'employee': employee,
|
'employee': employee,
|
||||||
'from_date': start_date,
|
'from_date': start_date,
|
||||||
'to_date': end_date
|
'to_date': end_date,
|
||||||
|
'component_type': "Earning" if component_type == "earnings" else "Deduction"
|
||||||
}, as_dict=1)
|
}, as_dict=1)
|
||||||
|
|
||||||
additional_components_list = []
|
additional_components_list = []
|
||||||
|
|||||||
@ -1,634 +1,151 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "HR-TAX-PRF-.YYYY.-.#####",
|
"autoname": "HR-TAX-PRF-.YYYY.-.#####",
|
||||||
"beta": 0,
|
|
||||||
"creation": "2018-04-13 17:24:11.456132",
|
"creation": "2018-04-13 17:24:11.456132",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"employee",
|
||||||
|
"employee_name",
|
||||||
|
"department",
|
||||||
|
"column_break_2",
|
||||||
|
"submission_date",
|
||||||
|
"payroll_period",
|
||||||
|
"company",
|
||||||
|
"section_break_5",
|
||||||
|
"tax_exemption_proofs",
|
||||||
|
"section_break_10",
|
||||||
|
"total_actual_amount",
|
||||||
|
"column_break_12",
|
||||||
|
"exemption_amount",
|
||||||
|
"other_incomes_section",
|
||||||
|
"income_from_other_sources",
|
||||||
|
"attachment_section",
|
||||||
|
"attachments",
|
||||||
|
"amended_from"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 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,
|
"in_standard_filter": 1,
|
||||||
"label": "Employee",
|
"label": "Employee",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Employee",
|
"options": "Employee",
|
||||||
"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,
|
|
||||||
"fetch_from": "employee.employee_name",
|
"fetch_from": "employee.employee_name",
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "employee_name",
|
"fieldname": "employee_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": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Employee Name",
|
"label": "Employee Name",
|
||||||
"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,
|
|
||||||
"fetch_from": "employee.department",
|
"fetch_from": "employee.department",
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "department",
|
"fieldname": "department",
|
||||||
"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": "Department",
|
"label": "Department",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Department",
|
"options": "Department",
|
||||||
"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,
|
|
||||||
"fetch_if_empty": 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,
|
|
||||||
"default": "Today",
|
"default": "Today",
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "submission_date",
|
"fieldname": "submission_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": "Submission Date",
|
"label": "Submission Date",
|
||||||
"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,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "payroll_period",
|
"fieldname": "payroll_period",
|
||||||
"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,
|
"in_standard_filter": 1,
|
||||||
"label": "Payroll Period",
|
"label": "Payroll Period",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Payroll Period",
|
"options": "Payroll Period",
|
||||||
"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,
|
|
||||||
"fetch_from": "employee.company",
|
"fetch_from": "employee.company",
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"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": "Company",
|
"label": "Company",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
"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,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 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,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "tax_exemption_proofs",
|
"fieldname": "tax_exemption_proofs",
|
||||||
"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": "Tax Exemption Proofs",
|
"label": "Tax Exemption Proofs",
|
||||||
"length": 0,
|
"options": "Employee Tax Exemption Proof Submission Detail"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Employee Tax Exemption Proof Submission Detail",
|
|
||||||
"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,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "section_break_10",
|
"fieldname": "section_break_10",
|
||||||
"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,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "total_actual_amount",
|
"fieldname": "total_actual_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": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Total Actual Amount",
|
"label": "Total Actual Amount",
|
||||||
"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,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "column_break_12",
|
"fieldname": "column_break_12",
|
||||||
"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,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "exemption_amount",
|
"fieldname": "exemption_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": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Total Exemption Amount",
|
"label": "Total Exemption Amount",
|
||||||
"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,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "other_incomes_section",
|
"fieldname": "other_incomes_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Other Incomes"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Other Incomes",
|
|
||||||
"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,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "income_from_other_sources",
|
"fieldname": "income_from_other_sources",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"label": "Income From Other Sources"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Income From Other Sources",
|
|
||||||
"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,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "attachment_section",
|
"fieldname": "attachment_section",
|
||||||
"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,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "attachments",
|
"fieldname": "attachments",
|
||||||
"fieldtype": "Attach",
|
"fieldtype": "Attach",
|
||||||
"hidden": 0,
|
"label": "Attachments"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Attachments",
|
|
||||||
"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,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
"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": "Amended From",
|
"label": "Amended From",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Employee Tax Exemption Proof Submission",
|
"options": "Employee Tax Exemption Proof Submission",
|
||||||
"permlevel": 0,
|
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"issingle": 0,
|
"links": [],
|
||||||
"istable": 0,
|
"modified": "2020-03-02 19:02:15.398486",
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2019-05-13 12:17:18.045171",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Employee Tax Exemption Proof Submission",
|
"name": "Employee Tax Exemption Proof Submission",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
@ -638,14 +155,10 @@
|
|||||||
"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": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
@ -657,14 +170,10 @@
|
|||||||
"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": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
@ -676,14 +185,10 @@
|
|||||||
"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": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
@ -695,26 +200,16 @@
|
|||||||
"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": "Employee",
|
"role": "Employee",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
"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,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
||||||
@ -299,9 +299,11 @@ class SalarySlip(TransactionBase):
|
|||||||
|
|
||||||
def calculate_net_pay(self):
|
def calculate_net_pay(self):
|
||||||
if self.salary_structure:
|
if self.salary_structure:
|
||||||
self.calculate_component_amounts()
|
self.calculate_component_amounts("earnings")
|
||||||
|
|
||||||
self.gross_pay = self.get_component_totals("earnings")
|
self.gross_pay = self.get_component_totals("earnings")
|
||||||
|
|
||||||
|
if self.salary_structure:
|
||||||
|
self.calculate_component_amounts("deductions")
|
||||||
self.total_deduction = self.get_component_totals("deductions")
|
self.total_deduction = self.get_component_totals("deductions")
|
||||||
|
|
||||||
self.set_loan_repayment()
|
self.set_loan_repayment()
|
||||||
@ -309,25 +311,27 @@ class SalarySlip(TransactionBase):
|
|||||||
self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
|
self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
|
||||||
self.rounded_total = rounded(self.net_pay)
|
self.rounded_total = rounded(self.net_pay)
|
||||||
|
|
||||||
def calculate_component_amounts(self):
|
def calculate_component_amounts(self, component_type):
|
||||||
if not getattr(self, '_salary_structure_doc', None):
|
if not getattr(self, '_salary_structure_doc', None):
|
||||||
self._salary_structure_doc = frappe.get_doc('Salary Structure', self.salary_structure)
|
self._salary_structure_doc = frappe.get_doc('Salary Structure', self.salary_structure)
|
||||||
|
|
||||||
payroll_period = get_payroll_period(self.start_date, self.end_date, self.company)
|
payroll_period = get_payroll_period(self.start_date, self.end_date, self.company)
|
||||||
|
|
||||||
self.add_structure_components()
|
self.add_structure_components(component_type)
|
||||||
self.add_employee_benefits(payroll_period)
|
self.add_additional_salary_components(component_type)
|
||||||
self.add_additional_salary_components()
|
if component_type == "earnings":
|
||||||
self.add_tax_components(payroll_period)
|
self.add_employee_benefits(payroll_period)
|
||||||
self.set_component_amounts_based_on_payment_days()
|
else:
|
||||||
|
self.add_tax_components(payroll_period)
|
||||||
|
|
||||||
def add_structure_components(self):
|
self.set_component_amounts_based_on_payment_days(component_type)
|
||||||
|
|
||||||
|
def add_structure_components(self, component_type):
|
||||||
data = self.get_data_for_eval()
|
data = self.get_data_for_eval()
|
||||||
for key in ('earnings', 'deductions'):
|
for struct_row in self._salary_structure_doc.get(component_type):
|
||||||
for struct_row in self._salary_structure_doc.get(key):
|
amount = self.eval_condition_and_formula(struct_row, data)
|
||||||
amount = self.eval_condition_and_formula(struct_row, data)
|
if amount and struct_row.statistical_component == 0:
|
||||||
if amount and struct_row.statistical_component == 0:
|
self.update_component_row(struct_row, amount, component_type)
|
||||||
self.update_component_row(struct_row, amount, key)
|
|
||||||
|
|
||||||
def get_data_for_eval(self):
|
def get_data_for_eval(self):
|
||||||
'''Returns data for evaluating formula'''
|
'''Returns data for evaluating formula'''
|
||||||
@ -400,14 +404,15 @@ class SalarySlip(TransactionBase):
|
|||||||
amount = last_benefit.amount
|
amount = last_benefit.amount
|
||||||
self.update_component_row(frappe._dict(last_benefit.struct_row), amount, "earnings")
|
self.update_component_row(frappe._dict(last_benefit.struct_row), amount, "earnings")
|
||||||
|
|
||||||
def add_additional_salary_components(self):
|
def add_additional_salary_components(self, component_type):
|
||||||
additional_components = get_additional_salary_component(self.employee, self.start_date, self.end_date)
|
additional_components = get_additional_salary_component(self.employee,
|
||||||
|
self.start_date, self.end_date, component_type)
|
||||||
if additional_components:
|
if additional_components:
|
||||||
for additional_component in additional_components:
|
for additional_component in additional_components:
|
||||||
amount = additional_component.amount
|
amount = additional_component.amount
|
||||||
overwrite = additional_component.overwrite
|
overwrite = additional_component.overwrite
|
||||||
key = "earnings" if additional_component.type == "Earning" else "deductions"
|
self.update_component_row(frappe._dict(additional_component.struct_row), amount,
|
||||||
self.update_component_row(frappe._dict(additional_component.struct_row), amount, key, overwrite=overwrite)
|
component_type, overwrite=overwrite)
|
||||||
|
|
||||||
def add_tax_components(self, payroll_period):
|
def add_tax_components(self, payroll_period):
|
||||||
# Calculate variable_based_on_taxable_salary after all components updated in salary slip
|
# Calculate variable_based_on_taxable_salary after all components updated in salary slip
|
||||||
@ -736,7 +741,7 @@ class SalarySlip(TransactionBase):
|
|||||||
total += d.amount
|
total += d.amount
|
||||||
return total
|
return total
|
||||||
|
|
||||||
def set_component_amounts_based_on_payment_days(self):
|
def set_component_amounts_based_on_payment_days(self, component_type):
|
||||||
joining_date, relieving_date = frappe.get_cached_value("Employee", self.employee,
|
joining_date, relieving_date = frappe.get_cached_value("Employee", self.employee,
|
||||||
["date_of_joining", "relieving_date"])
|
["date_of_joining", "relieving_date"])
|
||||||
|
|
||||||
@ -746,9 +751,8 @@ class SalarySlip(TransactionBase):
|
|||||||
if not joining_date:
|
if not joining_date:
|
||||||
frappe.throw(_("Please set the Date Of Joining for employee {0}").format(frappe.bold(self.employee_name)))
|
frappe.throw(_("Please set the Date Of Joining for employee {0}").format(frappe.bold(self.employee_name)))
|
||||||
|
|
||||||
for component_type in ("earnings", "deductions"):
|
for d in self.get(component_type):
|
||||||
for d in self.get(component_type):
|
d.amount = self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0]
|
||||||
d.amount = self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0]
|
|
||||||
|
|
||||||
def set_loan_repayment(self):
|
def set_loan_repayment(self):
|
||||||
self.set('loans', [])
|
self.set('loans', [])
|
||||||
|
|||||||
@ -25,7 +25,6 @@ class TestSalaryStructure(unittest.TestCase):
|
|||||||
make_employee("test_employee@salary.com")
|
make_employee("test_employee@salary.com")
|
||||||
make_employee("test_employee_2@salary.com")
|
make_employee("test_employee_2@salary.com")
|
||||||
|
|
||||||
|
|
||||||
def make_holiday_list(self):
|
def make_holiday_list(self):
|
||||||
if not frappe.db.get_value("Holiday List", "Salary Structure Test Holiday List"):
|
if not frappe.db.get_value("Holiday List", "Salary Structure Test Holiday List"):
|
||||||
holiday_list = frappe.get_doc({
|
holiday_list = frappe.get_doc({
|
||||||
@ -38,6 +37,29 @@ class TestSalaryStructure(unittest.TestCase):
|
|||||||
holiday_list.get_weekly_off_dates()
|
holiday_list.get_weekly_off_dates()
|
||||||
holiday_list.save()
|
holiday_list.save()
|
||||||
|
|
||||||
|
def test_salary_structure_deduction_based_on_gross_pay(self):
|
||||||
|
|
||||||
|
emp = make_employee("test_employee_3@salary.com")
|
||||||
|
|
||||||
|
sal_struct = make_salary_structure("Salary Structure 2", "Monthly", dont_submit = True)
|
||||||
|
|
||||||
|
sal_struct.earnings = [sal_struct.earnings[0]]
|
||||||
|
sal_struct.earnings[0].amount_based_on_formula = 1
|
||||||
|
sal_struct.earnings[0].formula = "base"
|
||||||
|
|
||||||
|
sal_struct.deductions = [sal_struct.deductions[0]]
|
||||||
|
|
||||||
|
sal_struct.deductions[0].amount_based_on_formula = 1
|
||||||
|
sal_struct.deductions[0].condition = "gross_pay > 100"
|
||||||
|
sal_struct.deductions[0].formula = "gross_pay * 0.2"
|
||||||
|
|
||||||
|
sal_struct.submit()
|
||||||
|
|
||||||
|
assignment = create_salary_structure_assignment(emp, "Salary Structure 2")
|
||||||
|
ss = make_salary_slip(sal_struct.name, employee = emp)
|
||||||
|
|
||||||
|
self.assertEqual(assignment.base * 0.2, ss.deductions[0].amount)
|
||||||
|
|
||||||
def test_amount_totals(self):
|
def test_amount_totals(self):
|
||||||
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
|
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
|
||||||
sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee_2@salary.com"})
|
sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee_2@salary.com"})
|
||||||
|
|||||||
@ -75,7 +75,7 @@ class ShiftType(Document):
|
|||||||
for date in dates:
|
for date in dates:
|
||||||
shift_details = get_employee_shift(employee, date, True)
|
shift_details = get_employee_shift(employee, date, True)
|
||||||
if shift_details and shift_details.shift_type.name == self.name:
|
if shift_details and shift_details.shift_type.name == self.name:
|
||||||
mark_attendance(employee, date, self.name, 'Absent')
|
mark_attendance(employee, date, 'Absent', self.name)
|
||||||
|
|
||||||
def get_assigned_employee(self, from_date=None, consider_default_shift=False):
|
def get_assigned_employee(self, from_date=None, consider_default_shift=False):
|
||||||
filters = {'date':('>=', from_date), 'shift_type': self.name, 'docstatus': '1'}
|
filters = {'date':('>=', from_date), 'shift_type': self.name, 'docstatus': '1'}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "ACC-LOAP-.YYYY.-.#####",
|
"autoname": "ACC-LOAP-.YYYY.-.#####",
|
||||||
"creation": "2019-08-29 17:46:49.201740",
|
"creation": "2019-08-29 17:46:49.201740",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -122,7 +123,6 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval: doc.is_term_loan == 1",
|
"depends_on": "eval: doc.is_term_loan == 1",
|
||||||
"fetch_from": "loan_type.repayment_method",
|
|
||||||
"fetch_if_empty": 1,
|
"fetch_if_empty": 1,
|
||||||
"fieldname": "repayment_method",
|
"fieldname": "repayment_method",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
@ -213,7 +213,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-10-24 10:32:03.740558",
|
"links": [],
|
||||||
|
"modified": "2020-03-01 10:21:44.413353",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Loan Management",
|
"module": "Loan Management",
|
||||||
"name": "Loan Application",
|
"name": "Loan Application",
|
||||||
|
|||||||
@ -55,7 +55,10 @@ def check_for_ltv_shortfall(process_loan_security_shortfall=None):
|
|||||||
"valid_upto": (">=", update_time)
|
"valid_upto": (">=", update_time)
|
||||||
}, as_list=1))
|
}, as_list=1))
|
||||||
|
|
||||||
loans = frappe.db.sql(""" SELECT l.name, l.loan_amount, l.total_principal_paid, lp.loan_security, lp.haircut, lp.qty
|
ltv_ratio_map = frappe._dict(frappe.get_all("Loan Security Type",
|
||||||
|
fields=["name", "loan_to_value_ratio"], as_list=1))
|
||||||
|
|
||||||
|
loans = frappe.db.sql(""" SELECT l.name, l.loan_amount, l.total_principal_paid, lp.loan_security, lp.haircut, lp.qty, lp.loan_security_type
|
||||||
FROM `tabLoan` l, `tabPledge` lp , `tabLoan Security Pledge`p WHERE lp.parent = p.name and p.loan = l.name and l.docstatus = 1
|
FROM `tabLoan` l, `tabPledge` lp , `tabLoan Security Pledge`p WHERE lp.parent = p.name and p.loan = l.name and l.docstatus = 1
|
||||||
and l.is_secured_loan and l.status = 'Disbursed' and p.status in ('Pledged', 'Partially Unpledged')""", as_dict=1)
|
and l.is_secured_loan and l.status = 'Disbursed' and p.status in ('Pledged', 'Partially Unpledged')""", as_dict=1)
|
||||||
|
|
||||||
@ -68,11 +71,12 @@ def check_for_ltv_shortfall(process_loan_security_shortfall=None):
|
|||||||
})
|
})
|
||||||
|
|
||||||
current_loan_security_amount = loan_security_price_map.get(loan.loan_security, 0) * loan.qty
|
current_loan_security_amount = loan_security_price_map.get(loan.loan_security, 0) * loan.qty
|
||||||
|
ltv_ratio = ltv_ratio_map.get(loan.loan_security_type)
|
||||||
|
|
||||||
loan_security_map[loan.name]['security_value'] += current_loan_security_amount - (current_loan_security_amount * loan.haircut/100)
|
loan_security_map[loan.name]['security_value'] += current_loan_security_amount - (current_loan_security_amount * loan.haircut/100)
|
||||||
|
|
||||||
for loan, value in iteritems(loan_security_map):
|
for loan, value in iteritems(loan_security_map):
|
||||||
if value["security_value"] < value["loan_amount"]:
|
if (value["security_value"]/value["loan_amount"]) < ltv_ratio:
|
||||||
create_loan_security_shortfall(loan, value, process_loan_security_shortfall)
|
create_loan_security_shortfall(loan, value, process_loan_security_shortfall)
|
||||||
|
|
||||||
def create_loan_security_shortfall(loan, value, process_loan_security_shortfall):
|
def create_loan_security_shortfall(loan, value, process_loan_security_shortfall):
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "field:loan_security_type",
|
"autoname": "field:loan_security_type",
|
||||||
"creation": "2019-08-29 18:46:07.322056",
|
"creation": "2019-08-29 18:46:07.322056",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -8,7 +9,9 @@
|
|||||||
"loan_security_type",
|
"loan_security_type",
|
||||||
"unit_of_measure",
|
"unit_of_measure",
|
||||||
"haircut",
|
"haircut",
|
||||||
"disabled"
|
"disabled",
|
||||||
|
"column_break_5",
|
||||||
|
"loan_to_value_ratio"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -33,9 +36,19 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Unit Of Measure",
|
"label": "Unit Of Measure",
|
||||||
"options": "UOM"
|
"options": "UOM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_5",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "loan_to_value_ratio",
|
||||||
|
"fieldtype": "Percent",
|
||||||
|
"label": "Loan To Value Ratio"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2019-10-10 03:05:37.912866",
|
"links": [],
|
||||||
|
"modified": "2020-02-28 12:43:20.364447",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Loan Management",
|
"module": "Loan Management",
|
||||||
"name": "Loan Security Type",
|
"name": "Loan Security Type",
|
||||||
|
|||||||
@ -1,189 +1,76 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2013-05-23 16:55:51",
|
"creation": "2013-05-23 16:55:51",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"item_code",
|
||||||
|
"qty",
|
||||||
|
"description",
|
||||||
|
"rate",
|
||||||
|
"uom"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item",
|
"label": "Item",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "item_code",
|
"oldfieldname": "item_code",
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Item",
|
"options": "Item",
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "qty",
|
"fieldname": "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,
|
|
||||||
"oldfieldname": "qty",
|
"oldfieldname": "qty",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"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,
|
|
||||||
"unique": 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": "description",
|
"oldfieldname": "description",
|
||||||
"oldfieldtype": "Text",
|
"oldfieldtype": "Text",
|
||||||
"permlevel": 0,
|
"print_width": "300px"
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"print_width": "300px",
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "rate",
|
"fieldname": "rate",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Rate",
|
"label": "Rate",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "rate",
|
"oldfieldname": "rate",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"permlevel": 0,
|
"print_hide": 1
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "uom",
|
"fieldname": "uom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"in_list_view": 1,
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "UOM",
|
"label": "UOM",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "uom",
|
"oldfieldname": "uom",
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "UOM",
|
"options": "UOM",
|
||||||
"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,
|
|
||||||
"unique": 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,
|
"links": [],
|
||||||
"modified": "2017-02-20 13:24:05.633546",
|
"modified": "2020-02-28 14:06:05.725655",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Product Bundle Item",
|
"name": "Product Bundle Item",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 0,
|
"sort_field": "modified",
|
||||||
"read_only": 0,
|
"sort_order": "DESC",
|
||||||
"read_only_onload": 0,
|
"track_changes": 1
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
||||||
@ -112,4 +112,4 @@ def delete_communications(doctype, company_name, company_fieldname):
|
|||||||
communications = frappe.get_all("Communication", filters={"reference_doctype":doctype,"reference_name":["in", reference_doc_names]})
|
communications = frappe.get_all("Communication", filters={"reference_doctype":doctype,"reference_name":["in", reference_doc_names]})
|
||||||
communication_names = [c.name for c in communications]
|
communication_names = [c.name for c in communications]
|
||||||
|
|
||||||
frappe.delete_doc("Communication", communication_names)
|
frappe.delete_doc("Communication", communication_names, ignore_permissions=True)
|
||||||
|
|||||||
@ -19,6 +19,11 @@ frappe.ui.form.on('Sales Person', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
frm.make_methods = {
|
||||||
|
'Sales Order': () => frappe.new_doc("Sales Order")
|
||||||
|
.then(() => frm.add_child("sales_team", {"sales_person": frm.doc.name}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -981,6 +981,7 @@ def _msgprint(msg, verbose):
|
|||||||
def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
|
def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
|
||||||
"""returns last purchase details in stock uom"""
|
"""returns last purchase details in stock uom"""
|
||||||
# get last purchase order item details
|
# get last purchase order item details
|
||||||
|
|
||||||
last_purchase_order = frappe.db.sql("""\
|
last_purchase_order = frappe.db.sql("""\
|
||||||
select po.name, po.transaction_date, po.conversion_rate,
|
select po.name, po.transaction_date, po.conversion_rate,
|
||||||
po_item.conversion_factor, po_item.base_price_list_rate,
|
po_item.conversion_factor, po_item.base_price_list_rate,
|
||||||
@ -991,6 +992,7 @@ def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
|
|||||||
order by po.transaction_date desc, po.name desc
|
order by po.transaction_date desc, po.name desc
|
||||||
limit 1""", (item_code, cstr(doc_name)), as_dict=1)
|
limit 1""", (item_code, cstr(doc_name)), as_dict=1)
|
||||||
|
|
||||||
|
|
||||||
# get last purchase receipt item details
|
# get last purchase receipt item details
|
||||||
last_purchase_receipt = frappe.db.sql("""\
|
last_purchase_receipt = frappe.db.sql("""\
|
||||||
select pr.name, pr.posting_date, pr.posting_time, pr.conversion_rate,
|
select pr.name, pr.posting_date, pr.posting_time, pr.conversion_rate,
|
||||||
@ -1002,19 +1004,20 @@ def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
|
|||||||
order by pr.posting_date desc, pr.posting_time desc, pr.name desc
|
order by pr.posting_date desc, pr.posting_time desc, pr.name desc
|
||||||
limit 1""", (item_code, cstr(doc_name)), as_dict=1)
|
limit 1""", (item_code, cstr(doc_name)), as_dict=1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
purchase_order_date = getdate(last_purchase_order and last_purchase_order[0].transaction_date
|
purchase_order_date = getdate(last_purchase_order and last_purchase_order[0].transaction_date
|
||||||
or "1900-01-01")
|
or "1900-01-01")
|
||||||
purchase_receipt_date = getdate(last_purchase_receipt and
|
purchase_receipt_date = getdate(last_purchase_receipt and
|
||||||
last_purchase_receipt[0].posting_date or "1900-01-01")
|
last_purchase_receipt[0].posting_date or "1900-01-01")
|
||||||
|
|
||||||
if (purchase_order_date > purchase_receipt_date) or \
|
if last_purchase_order and (purchase_order_date >= purchase_receipt_date or not last_purchase_receipt):
|
||||||
(last_purchase_order and not last_purchase_receipt):
|
|
||||||
# use purchase order
|
# use purchase order
|
||||||
|
|
||||||
last_purchase = last_purchase_order[0]
|
last_purchase = last_purchase_order[0]
|
||||||
purchase_date = purchase_order_date
|
purchase_date = purchase_order_date
|
||||||
|
|
||||||
elif (purchase_receipt_date > purchase_order_date) or \
|
elif last_purchase_receipt and (purchase_receipt_date > purchase_order_date or not last_purchase_order):
|
||||||
(last_purchase_receipt and not last_purchase_order):
|
|
||||||
# use purchase receipt
|
# use purchase receipt
|
||||||
last_purchase = last_purchase_receipt[0]
|
last_purchase = last_purchase_receipt[0]
|
||||||
purchase_date = purchase_receipt_date
|
purchase_date = purchase_receipt_date
|
||||||
@ -1026,11 +1029,12 @@ def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
|
|||||||
out = frappe._dict({
|
out = frappe._dict({
|
||||||
"base_price_list_rate": flt(last_purchase.base_price_list_rate) / conversion_factor,
|
"base_price_list_rate": flt(last_purchase.base_price_list_rate) / conversion_factor,
|
||||||
"base_rate": flt(last_purchase.base_rate) / conversion_factor,
|
"base_rate": flt(last_purchase.base_rate) / conversion_factor,
|
||||||
"base_net_rate": flt(last_purchase.net_rate) / conversion_factor,
|
"base_net_rate": flt(last_purchase.base_net_rate) / conversion_factor,
|
||||||
"discount_percentage": flt(last_purchase.discount_percentage),
|
"discount_percentage": flt(last_purchase.discount_percentage),
|
||||||
"purchase_date": purchase_date
|
"purchase_date": purchase_date
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
conversion_rate = flt(conversion_rate) or 1.0
|
conversion_rate = flt(conversion_rate) or 1.0
|
||||||
out.update({
|
out.update({
|
||||||
"price_list_rate": out.base_price_list_rate / conversion_rate,
|
"price_list_rate": out.base_price_list_rate / conversion_rate,
|
||||||
|
|||||||
@ -10,7 +10,6 @@
|
|||||||
"item_code",
|
"item_code",
|
||||||
"uom",
|
"uom",
|
||||||
"packing_unit",
|
"packing_unit",
|
||||||
"min_qty",
|
|
||||||
"column_break_17",
|
"column_break_17",
|
||||||
"item_name",
|
"item_name",
|
||||||
"brand",
|
"brand",
|
||||||
@ -63,13 +62,6 @@
|
|||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "Packing Unit"
|
"label": "Packing Unit"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"default": "1",
|
|
||||||
"fieldname": "min_qty",
|
|
||||||
"fieldtype": "Int",
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Minimum Qty "
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_17",
|
"fieldname": "column_break_17",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
@ -216,7 +208,7 @@
|
|||||||
"icon": "fa fa-flag",
|
"icon": "fa fa-flag",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2019-12-31 03:11:09.702250",
|
"modified": "2020-02-28 14:21:25.580331",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item Price",
|
"name": "Item Price",
|
||||||
@ -251,6 +243,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC",
|
"sort_order": "ASC",
|
||||||
"title_field": "item_name",
|
"title_field": "item_name",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
"item_code": "_Test Item",
|
"item_code": "_Test Item",
|
||||||
"price_list": "_Test Price List",
|
"price_list": "_Test Price List",
|
||||||
"price_list_rate": 100,
|
"price_list_rate": 100,
|
||||||
"min_qty": 2,
|
|
||||||
"valid_from": "2017-04-18",
|
"valid_from": "2017-04-18",
|
||||||
"valid_upto": "2017-04-26"
|
"valid_upto": "2017-04-26"
|
||||||
},
|
},
|
||||||
@ -12,8 +11,7 @@
|
|||||||
"doctype": "Item Price",
|
"doctype": "Item Price",
|
||||||
"item_code": "_Test Item",
|
"item_code": "_Test Item",
|
||||||
"price_list": "_Test Price List Rest of the World",
|
"price_list": "_Test Price List Rest of the World",
|
||||||
"price_list_rate": 10,
|
"price_list_rate": 10
|
||||||
"min_qty": 5
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Item Price",
|
"doctype": "Item Price",
|
||||||
@ -22,7 +20,6 @@
|
|||||||
"price_list_rate": 20,
|
"price_list_rate": 20,
|
||||||
"valid_from": "2017-04-18",
|
"valid_from": "2017-04-18",
|
||||||
"valid_upto": "2017-04-26",
|
"valid_upto": "2017-04-26",
|
||||||
"min_qty": 7,
|
|
||||||
"customer": "_Test Customer",
|
"customer": "_Test Customer",
|
||||||
"uom": "_Test UOM"
|
"uom": "_Test UOM"
|
||||||
},
|
},
|
||||||
@ -31,19 +28,15 @@
|
|||||||
"item_code": "_Test Item Home Desktop 100",
|
"item_code": "_Test Item Home Desktop 100",
|
||||||
"price_list": "_Test Price List",
|
"price_list": "_Test Price List",
|
||||||
"price_list_rate": 1000,
|
"price_list_rate": 1000,
|
||||||
"min_qty" : 10,
|
|
||||||
"valid_from": "2017-04-10",
|
"valid_from": "2017-04-10",
|
||||||
"valid_upto": "2017-04-17",
|
"valid_upto": "2017-04-17"
|
||||||
"min_qty": 2
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Item Price",
|
"doctype": "Item Price",
|
||||||
"item_code": "_Test Item Home Desktop Manufactured",
|
"item_code": "_Test Item Home Desktop Manufactured",
|
||||||
"price_list": "_Test Price List",
|
"price_list": "_Test Price List",
|
||||||
"price_list_rate": 1000,
|
"price_list_rate": 1000,
|
||||||
"min_qty" : 10,
|
|
||||||
"valid_from": "2017-04-10",
|
"valid_from": "2017-04-10",
|
||||||
"valid_upto": "2017-04-17",
|
"valid_upto": "2017-04-17"
|
||||||
"min_qty": 2
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import frappe, erpnext
|
|||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from frappe.utils import cint, flt, cstr, today, random_string
|
from frappe.utils import cint, flt, cstr, today, random_string
|
||||||
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice
|
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice
|
||||||
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
from erpnext import set_perpetual_inventory
|
from erpnext import set_perpetual_inventory
|
||||||
from erpnext.stock.doctype.serial_no.serial_no import SerialNoDuplicateError
|
from erpnext.stock.doctype.serial_no.serial_no import SerialNoDuplicateError
|
||||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
||||||
@ -51,6 +52,28 @@ class TestPurchaseReceipt(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertFalse(get_gl_entries("Purchase Receipt", pr.name))
|
self.assertFalse(get_gl_entries("Purchase Receipt", pr.name))
|
||||||
|
|
||||||
|
def test_batched_serial_no_purchase(self):
|
||||||
|
item = frappe.get_doc("Item", { 'item_name': 'Batched Serialized Item' })
|
||||||
|
if not item:
|
||||||
|
item = create_item("Batched Serialized Item")
|
||||||
|
item.has_batch_no = 1
|
||||||
|
item.create_new_batch = 1
|
||||||
|
item.has_serial_no = 1
|
||||||
|
item.batch_number_series = "BS-BATCH-.##"
|
||||||
|
item.serial_no_series = "BS-.####"
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
pr = make_purchase_receipt(item_code=item.name, qty=5, rate=500)
|
||||||
|
|
||||||
|
self.assertTrue(frappe.db.get_value('Batch', {'item': item.name, 'reference_name': pr.name}))
|
||||||
|
|
||||||
|
pr.load_from_db()
|
||||||
|
batch_no = pr.items[0].batch_no
|
||||||
|
pr.cancel()
|
||||||
|
|
||||||
|
self.assertFalse(frappe.db.get_value('Batch', {'item': item.name, 'reference_name': pr.name}))
|
||||||
|
self.assertFalse(frappe.db.get_all('Serial No', {'batch_no': batch_no}))
|
||||||
|
|
||||||
def test_purchase_receipt_gl_entry(self):
|
def test_purchase_receipt_gl_entry(self):
|
||||||
pr = make_purchase_receipt(company="_Test Company with perpetual inventory", warehouse = "Stores - TCP1", supplier_warehouse = "Work in Progress - TCP1", get_multiple_items = True, get_taxes_and_charges = True)
|
pr = make_purchase_receipt(company="_Test Company with perpetual inventory", warehouse = "Stores - TCP1", supplier_warehouse = "Work in Progress - TCP1", get_multiple_items = True, get_taxes_and_charges = True)
|
||||||
self.assertEqual(cint(erpnext.is_perpetual_inventory_enabled(pr.company)), 1)
|
self.assertEqual(cint(erpnext.is_perpetual_inventory_enabled(pr.company)), 1)
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
"description": "Distinct unit of an Item",
|
"description": "Distinct unit of an Item",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Setup",
|
"document_type": "Setup",
|
||||||
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"details",
|
"details",
|
||||||
"column_break0",
|
"column_break0",
|
||||||
@ -104,10 +105,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "batch_no",
|
"fieldname": "batch_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Batch No",
|
"label": "Batch No",
|
||||||
|
"options": "Batch",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -425,7 +427,7 @@
|
|||||||
],
|
],
|
||||||
"icon": "fa fa-barcode",
|
"icon": "fa fa-barcode",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"modified": "2019-08-07 17:28:32.243280",
|
"modified": "2020-02-28 19:31:09.357323",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Serial No",
|
"name": "Serial No",
|
||||||
|
|||||||
@ -205,6 +205,7 @@ def process_serial_no(sle):
|
|||||||
|
|
||||||
def validate_serial_no(sle, item_det):
|
def validate_serial_no(sle, item_det):
|
||||||
serial_nos = get_serial_nos(sle.serial_no) if sle.serial_no else []
|
serial_nos = get_serial_nos(sle.serial_no) if sle.serial_no else []
|
||||||
|
validate_material_transfer_entry(sle)
|
||||||
|
|
||||||
if item_det.has_serial_no==0:
|
if item_det.has_serial_no==0:
|
||||||
if serial_nos:
|
if serial_nos:
|
||||||
@ -224,7 +225,9 @@ def validate_serial_no(sle, item_det):
|
|||||||
|
|
||||||
for serial_no in serial_nos:
|
for serial_no in serial_nos:
|
||||||
if frappe.db.exists("Serial No", serial_no):
|
if frappe.db.exists("Serial No", serial_no):
|
||||||
sr = frappe.get_doc("Serial No", serial_no)
|
sr = frappe.db.get_value("Serial No", serial_no, ["name", "item_code", "batch_no", "sales_order",
|
||||||
|
"delivery_document_no", "delivery_document_type", "warehouse",
|
||||||
|
"purchase_document_no", "company"], as_dict=1)
|
||||||
|
|
||||||
if sr.item_code!=sle.item_code:
|
if sr.item_code!=sle.item_code:
|
||||||
if not allow_serial_nos_with_different_item(serial_no, sle):
|
if not allow_serial_nos_with_different_item(serial_no, sle):
|
||||||
@ -305,6 +308,19 @@ def validate_serial_no(sle, item_det):
|
|||||||
frappe.throw(_("Cannot cancel {0} {1} because Serial No {2} does not belong to the warehouse {3}")
|
frappe.throw(_("Cannot cancel {0} {1} because Serial No {2} does not belong to the warehouse {3}")
|
||||||
.format(sle.voucher_type, sle.voucher_no, serial_no, sle.warehouse))
|
.format(sle.voucher_type, sle.voucher_no, serial_no, sle.warehouse))
|
||||||
|
|
||||||
|
def validate_material_transfer_entry(sle_doc):
|
||||||
|
sle_doc.update({
|
||||||
|
"skip_update_serial_no": False,
|
||||||
|
"skip_serial_no_validaiton": False
|
||||||
|
})
|
||||||
|
|
||||||
|
if (sle_doc.voucher_type == "Stock Entry" and sle_doc.is_cancelled == "No" and
|
||||||
|
frappe.get_cached_value("Stock Entry", sle_doc.voucher_no, "purpose") == "Material Transfer"):
|
||||||
|
if sle_doc.actual_qty < 0:
|
||||||
|
sle_doc.skip_update_serial_no = True
|
||||||
|
else:
|
||||||
|
sle_doc.skip_serial_no_validaiton = True
|
||||||
|
|
||||||
def validate_so_serial_no(sr, sales_order,):
|
def validate_so_serial_no(sr, sales_order,):
|
||||||
if not sr.sales_order or sr.sales_order!= sales_order:
|
if not sr.sales_order or sr.sales_order!= sales_order:
|
||||||
frappe.throw(_("""Sales Order {0} has reservation for item {1}, you can
|
frappe.throw(_("""Sales Order {0} has reservation for item {1}, you can
|
||||||
@ -312,7 +328,8 @@ def validate_so_serial_no(sr, sales_order,):
|
|||||||
be delivered""").format(sales_order, sr.item_code, sr.name))
|
be delivered""").format(sales_order, sr.item_code, sr.name))
|
||||||
|
|
||||||
def has_duplicate_serial_no(sn, sle):
|
def has_duplicate_serial_no(sn, sle):
|
||||||
if sn.warehouse and sle.voucher_type != 'Stock Reconciliation':
|
if (sn.warehouse and not sle.skip_serial_no_validaiton
|
||||||
|
and sle.voucher_type != 'Stock Reconciliation'):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if sn.company != sle.company:
|
if sn.company != sle.company:
|
||||||
@ -337,7 +354,7 @@ def allow_serial_nos_with_different_item(sle_serial_no, sle):
|
|||||||
"""
|
"""
|
||||||
allow_serial_nos = False
|
allow_serial_nos = False
|
||||||
if sle.voucher_type=="Stock Entry" and cint(sle.actual_qty) > 0:
|
if sle.voucher_type=="Stock Entry" and cint(sle.actual_qty) > 0:
|
||||||
stock_entry = frappe.get_doc("Stock Entry", sle.voucher_no)
|
stock_entry = frappe.get_cached_doc("Stock Entry", sle.voucher_no)
|
||||||
if stock_entry.purpose in ("Repack", "Manufacture"):
|
if stock_entry.purpose in ("Repack", "Manufacture"):
|
||||||
for d in stock_entry.get("items"):
|
for d in stock_entry.get("items"):
|
||||||
if d.serial_no and (d.s_warehouse if sle.is_cancelled=="No" else d.t_warehouse):
|
if d.serial_no and (d.s_warehouse if sle.is_cancelled=="No" else d.t_warehouse):
|
||||||
@ -348,6 +365,7 @@ def allow_serial_nos_with_different_item(sle_serial_no, sle):
|
|||||||
return allow_serial_nos
|
return allow_serial_nos
|
||||||
|
|
||||||
def update_serial_nos(sle, item_det):
|
def update_serial_nos(sle, item_det):
|
||||||
|
if sle.skip_update_serial_no: return
|
||||||
if sle.is_cancelled == "No" and not sle.serial_no and cint(sle.actual_qty) > 0 \
|
if sle.is_cancelled == "No" and not sle.serial_no and cint(sle.actual_qty) > 0 \
|
||||||
and item_det.has_serial_no == 1 and item_det.serial_no_series:
|
and item_det.has_serial_no == 1 and item_det.serial_no_series:
|
||||||
serial_nos = get_auto_serial_nos(item_det.serial_no_series, sle.actual_qty)
|
serial_nos = get_auto_serial_nos(item_det.serial_no_series, sle.actual_qty)
|
||||||
@ -369,22 +387,16 @@ def auto_make_serial_nos(args):
|
|||||||
voucher_type = args.get('voucher_type')
|
voucher_type = args.get('voucher_type')
|
||||||
item_code = args.get('item_code')
|
item_code = args.get('item_code')
|
||||||
for serial_no in serial_nos:
|
for serial_no in serial_nos:
|
||||||
|
is_new = False
|
||||||
if frappe.db.exists("Serial No", serial_no):
|
if frappe.db.exists("Serial No", serial_no):
|
||||||
sr = frappe.get_doc("Serial No", serial_no)
|
sr = frappe.get_cached_doc("Serial No", serial_no)
|
||||||
sr.via_stock_ledger = True
|
|
||||||
sr.item_code = item_code
|
|
||||||
sr.warehouse = args.get('warehouse') if args.get('actual_qty', 0) > 0 else None
|
|
||||||
sr.batch_no = args.get('batch_no')
|
|
||||||
sr.location = args.get('location')
|
|
||||||
sr.company = args.get('company')
|
|
||||||
sr.supplier = args.get('supplier')
|
|
||||||
if sr.sales_order and voucher_type == "Stock Entry" \
|
|
||||||
and not args.get('actual_qty', 0) > 0:
|
|
||||||
sr.sales_order = None
|
|
||||||
sr.update_serial_no_reference()
|
|
||||||
sr.save(ignore_permissions=True)
|
|
||||||
elif args.get('actual_qty', 0) > 0:
|
elif args.get('actual_qty', 0) > 0:
|
||||||
created_numbers.append(make_serial_no(serial_no, args))
|
sr = frappe.new_doc("Serial No")
|
||||||
|
is_new = True
|
||||||
|
|
||||||
|
sr = update_args_for_serial_no(sr, serial_no, args, is_new=is_new)
|
||||||
|
if is_new:
|
||||||
|
created_numbers.append(sr.name)
|
||||||
|
|
||||||
form_links = list(map(lambda d: frappe.utils.get_link_to_form('Serial No', d), created_numbers))
|
form_links = list(map(lambda d: frappe.utils.get_link_to_form('Serial No', d), created_numbers))
|
||||||
|
|
||||||
@ -419,20 +431,34 @@ def get_serial_nos(serial_no):
|
|||||||
return [s.strip() for s in cstr(serial_no).strip().upper().replace(',', '\n').split('\n')
|
return [s.strip() for s in cstr(serial_no).strip().upper().replace(',', '\n').split('\n')
|
||||||
if s.strip()]
|
if s.strip()]
|
||||||
|
|
||||||
def make_serial_no(serial_no, args):
|
def update_args_for_serial_no(serial_no_doc, serial_no, args, is_new=False):
|
||||||
sr = frappe.new_doc("Serial No")
|
serial_no_doc.update({
|
||||||
sr.serial_no = serial_no
|
"item_code": args.get("item_code"),
|
||||||
sr.item_code = args.get('item_code')
|
"company": args.get("company"),
|
||||||
sr.company = args.get('company')
|
"batch_no": args.get("batch_no"),
|
||||||
sr.batch_no = args.get('batch_no')
|
"via_stock_ledger": args.get("via_stock_ledger") or True,
|
||||||
sr.via_stock_ledger = args.get('via_stock_ledger') or True
|
"supplier": args.get("supplier"),
|
||||||
sr.warehouse = args.get('warehouse')
|
"location": args.get("location"),
|
||||||
|
"warehouse": (args.get("warehouse")
|
||||||
|
if args.get("actual_qty", 0) > 0 else None)
|
||||||
|
})
|
||||||
|
|
||||||
sr.validate_item()
|
if is_new:
|
||||||
sr.update_serial_no_reference(serial_no)
|
serial_no_doc.serial_no = serial_no
|
||||||
sr.db_insert()
|
|
||||||
|
|
||||||
return sr.name
|
if (serial_no_doc.sales_order and args.get("voucher_type") == "Stock Entry"
|
||||||
|
and not args.get("actual_qty", 0) > 0):
|
||||||
|
serial_no_doc.sales_order = None
|
||||||
|
|
||||||
|
serial_no_doc.validate_item()
|
||||||
|
serial_no_doc.update_serial_no_reference(serial_no)
|
||||||
|
|
||||||
|
if is_new:
|
||||||
|
serial_no_doc.db_insert()
|
||||||
|
else:
|
||||||
|
serial_no_doc.db_update()
|
||||||
|
|
||||||
|
return serial_no_doc
|
||||||
|
|
||||||
def update_serial_nos_after_submit(controller, parentfield):
|
def update_serial_nos_after_submit(controller, parentfield):
|
||||||
stock_ledger_entries = frappe.db.sql("""select voucher_detail_no, serial_no, actual_qty, warehouse
|
stock_ledger_entries = frappe.db.sql("""select voucher_detail_no, serial_no, actual_qty, warehouse
|
||||||
|
|||||||
@ -240,6 +240,7 @@
|
|||||||
"options": "Company",
|
"options": "Company",
|
||||||
"print_width": "150px",
|
"print_width": "150px",
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
|
"search_index": 1,
|
||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -274,7 +275,7 @@
|
|||||||
"icon": "fa fa-list",
|
"icon": "fa fa-list",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"in_create": 1,
|
"in_create": 1,
|
||||||
"modified": "2019-11-27 12:17:31.522675",
|
"modified": "2020-02-25 22:53:33.504681",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Stock Ledger Entry",
|
"name": "Stock Ledger Entry",
|
||||||
|
|||||||
@ -136,7 +136,7 @@ def get_bin(item_code, warehouse):
|
|||||||
bin_obj.flags.ignore_permissions = 1
|
bin_obj.flags.ignore_permissions = 1
|
||||||
bin_obj.insert()
|
bin_obj.insert()
|
||||||
else:
|
else:
|
||||||
bin_obj = frappe.get_doc('Bin', bin)
|
bin_obj = frappe.get_cached_doc('Bin', bin)
|
||||||
bin_obj.flags.ignore_permissions = True
|
bin_obj.flags.ignore_permissions = True
|
||||||
return bin_obj
|
return bin_obj
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -27,7 +27,6 @@ apps/erpnext/erpnext/stock/doctype/material_request/material_request.py,{0} {1}
|
|||||||
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.py,Packing Slip(s) cancelled,Packing Slip(s) canceled
|
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.py,Packing Slip(s) cancelled,Packing Slip(s) canceled
|
||||||
DocType: Payment Entry,Cheque/Reference No,Check/Reference No
|
DocType: Payment Entry,Cheque/Reference No,Check/Reference No
|
||||||
apps/erpnext/erpnext/assets/doctype/asset/asset.py,"Asset cannot be cancelled, as it is already {0}","Asset cannot be canceled, as it is already {0}"
|
apps/erpnext/erpnext/assets/doctype/asset/asset.py,"Asset cannot be cancelled, as it is already {0}","Asset cannot be canceled, as it is already {0}"
|
||||||
DocType: Bank Reconciliation,Select account head of the bank where cheque was deposited.,Select account head of the bank where check was deposited.
|
|
||||||
DocType: Cheque Print Template,Cheque Print Template,Check Print Template
|
DocType: Cheque Print Template,Cheque Print Template,Check Print Template
|
||||||
apps/erpnext/erpnext/controllers/selling_controller.py,{0} {1} is cancelled or closed,{0} {1} is canceled or closed
|
apps/erpnext/erpnext/controllers/selling_controller.py,{0} {1} is cancelled or closed,{0} {1} is canceled or closed
|
||||||
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py,Quotation {0} is cancelled,Quotation {0} is canceled
|
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py,Quotation {0} is cancelled,Quotation {0} is canceled
|
||||||
|
|||||||
|
File diff suppressed because it is too large
Load Diff
@ -544,7 +544,7 @@ DocType: Journal Entry,Excise Entry,Entrada Impuestos Especiales
|
|||||||
DocType: Attendance,Leave Type,Tipo de Vacaciones
|
DocType: Attendance,Leave Type,Tipo de Vacaciones
|
||||||
DocType: Account,Round Off,Redondear
|
DocType: Account,Round Off,Redondear
|
||||||
DocType: BOM Item,Scrap %,Chatarra %
|
DocType: BOM Item,Scrap %,Chatarra %
|
||||||
,Requested,Requerido
|
DocType: Loan Security Pledge,Requested,Requerido
|
||||||
DocType: Account,Stock Received But Not Billed,Inventario Recibido pero no facturados
|
DocType: Account,Stock Received But Not Billed,Inventario Recibido pero no facturados
|
||||||
DocType: Monthly Distribution,Distribution Name,Nombre del Distribución
|
DocType: Monthly Distribution,Distribution Name,Nombre del Distribución
|
||||||
apps/erpnext/erpnext/buying/report/procurement_tracker/procurement_tracker.py,Material Request No,Nº de Solicitud de Material
|
apps/erpnext/erpnext/buying/report/procurement_tracker/procurement_tracker.py,Material Request No,Nº de Solicitud de Material
|
||||||
|
|||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -337,7 +337,7 @@ apps/erpnext/erpnext/config/manufacturing.py,Time Sheet for manufacturing.,זמ
|
|||||||
apps/erpnext/erpnext/accounts/report/trial_balance/trial_balance.py,Opening (Cr),פתיחה (Cr)
|
apps/erpnext/erpnext/accounts/report/trial_balance/trial_balance.py,Opening (Cr),פתיחה (Cr)
|
||||||
DocType: Tally Migration,Round Off Account,לעגל את החשבון
|
DocType: Tally Migration,Round Off Account,לעגל את החשבון
|
||||||
DocType: Payment Reconciliation Payment,Reference Row,הפניה Row
|
DocType: Payment Reconciliation Payment,Reference Row,הפניה Row
|
||||||
DocType: Employee,Job Applicant,עבודת מבקש
|
DocType: Appointment Letter,Job Applicant,עבודת מבקש
|
||||||
apps/erpnext/erpnext/setup/setup_wizard/data/industry_type.py,Entertainment & Leisure,בידור ופנאי
|
apps/erpnext/erpnext/setup/setup_wizard/data/industry_type.py,Entertainment & Leisure,בידור ופנאי
|
||||||
apps/erpnext/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py,Opening,פתיחה
|
apps/erpnext/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py,Opening,פתיחה
|
||||||
DocType: Bank Account,Party Type,סוג המפלגה
|
DocType: Bank Account,Party Type,סוג המפלגה
|
||||||
@ -662,7 +662,7 @@ DocType: Sales Invoice Item,References,אזכור
|
|||||||
DocType: Item,Synced With Hub,סונכרן עם רכזת
|
DocType: Item,Synced With Hub,סונכרן עם רכזת
|
||||||
apps/erpnext/erpnext/manufacturing/doctype/work_order/work_order.py,Sales Order {0} is not valid,להזמין מכירות {0} אינו חוקי
|
apps/erpnext/erpnext/manufacturing/doctype/work_order/work_order.py,Sales Order {0} is not valid,להזמין מכירות {0} אינו חוקי
|
||||||
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py,Warehouse not found in the system,מחסן לא נמצא במערכת
|
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py,Warehouse not found in the system,מחסן לא נמצא במערכת
|
||||||
apps/erpnext/erpnext/accounts/report/purchase_register/purchase_register.py,Total Tax,"מס סה""כ"
|
apps/erpnext/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py,Total Tax,"מס סה""כ"
|
||||||
apps/erpnext/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py,{0} payment entries can not be filtered by {1},לא יכולים להיות מסוננים {0} ערכי תשלום על ידי {1}
|
apps/erpnext/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py,{0} payment entries can not be filtered by {1},לא יכולים להיות מסוננים {0} ערכי תשלום על ידי {1}
|
||||||
DocType: Period Closing Voucher,Closing Account Head,סגירת חשבון ראש
|
DocType: Period Closing Voucher,Closing Account Head,סגירת חשבון ראש
|
||||||
apps/erpnext/erpnext/setup/setup_wizard/operations/install_fixtures.py,Stock Options,אופציות
|
apps/erpnext/erpnext/setup/setup_wizard/operations/install_fixtures.py,Stock Options,אופציות
|
||||||
@ -1044,7 +1044,7 @@ apps/erpnext/erpnext/controllers/buying_controller.py,Specified BOM {0} does not
|
|||||||
apps/erpnext/erpnext/manufacturing/doctype/work_order/work_order.js,{0} items produced,{0} פריטים המיוצרים
|
apps/erpnext/erpnext/manufacturing/doctype/work_order/work_order.js,{0} items produced,{0} פריטים המיוצרים
|
||||||
DocType: Communication Medium,Communication Medium,תקשורת בינונית
|
DocType: Communication Medium,Communication Medium,תקשורת בינונית
|
||||||
DocType: Department Approver,Approver,מאשר
|
DocType: Department Approver,Approver,מאשר
|
||||||
DocType: Job Applicant,Applicant Name,שם מבקש
|
DocType: Appointment Letter,Applicant Name,שם מבקש
|
||||||
DocType: Stock Entry,Including items for sub assemblies,כולל פריטים למכלולים תת
|
DocType: Stock Entry,Including items for sub assemblies,כולל פריטים למכלולים תת
|
||||||
DocType: Employee,Permanent Address Is,כתובת קבע
|
DocType: Employee,Permanent Address Is,כתובת קבע
|
||||||
DocType: Share Transfer,Issue,נושא
|
DocType: Share Transfer,Issue,נושא
|
||||||
@ -1774,7 +1774,7 @@ DocType: Item,Is Sales Item,האם פריט מכירות
|
|||||||
,Purchase Order Items To Be Received,פריטים הזמנת רכש שיתקבלו
|
,Purchase Order Items To Be Received,פריטים הזמנת רכש שיתקבלו
|
||||||
apps/erpnext/erpnext/accounts/report/trial_balance/trial_balance.py,Closing (Cr),סגירה (Cr)
|
apps/erpnext/erpnext/accounts/report/trial_balance/trial_balance.py,Closing (Cr),סגירה (Cr)
|
||||||
DocType: Account,Cash,מזומנים
|
DocType: Account,Cash,מזומנים
|
||||||
DocType: Certification Application,Payment Details,פרטי תשלום
|
DocType: Loan Repayment,Payment Details,פרטי תשלום
|
||||||
DocType: Fee Schedule,In Process,בתהליך
|
DocType: Fee Schedule,In Process,בתהליך
|
||||||
apps/erpnext/erpnext/setup/doctype/company/company.js,Wrong Password,סיסמא שגויה
|
apps/erpnext/erpnext/setup/doctype/company/company.js,Wrong Password,סיסמא שגויה
|
||||||
apps/erpnext/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py,Please click on 'Generate Schedule' to fetch Serial No added for Item {0},אנא לחץ על 'צור לוח זמנים' כדי להביא מספר סידורי הוסיפה לפריט {0}
|
apps/erpnext/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py,Please click on 'Generate Schedule' to fetch Serial No added for Item {0},אנא לחץ על 'צור לוח זמנים' כדי להביא מספר סידורי הוסיפה לפריט {0}
|
||||||
@ -1882,7 +1882,7 @@ apps/erpnext/erpnext/controllers/buying_controller.py,From {0} | {1} {2},מ {0}
|
|||||||
DocType: Naming Series,Current Value,ערך נוכחי
|
DocType: Naming Series,Current Value,ערך נוכחי
|
||||||
apps/erpnext/erpnext/public/js/account_tree_grid.js,Select Fiscal Year...,בחר שנת כספים ...
|
apps/erpnext/erpnext/public/js/account_tree_grid.js,Select Fiscal Year...,בחר שנת כספים ...
|
||||||
apps/erpnext/erpnext/controllers/trends.py,Amt,AMT
|
apps/erpnext/erpnext/controllers/trends.py,Amt,AMT
|
||||||
,Requested,ביקשתי
|
DocType: Loan Security Pledge,Requested,ביקשתי
|
||||||
DocType: BOM Update Tool,Current BOM,BOM הנוכחי
|
DocType: BOM Update Tool,Current BOM,BOM הנוכחי
|
||||||
DocType: Purchase Invoice,Advance Payments,תשלומים מראש
|
DocType: Purchase Invoice,Advance Payments,תשלומים מראש
|
||||||
DocType: Asset Maintenance,Manufacturing User,משתמש ייצור
|
DocType: Asset Maintenance,Manufacturing User,משתמש ייצור
|
||||||
@ -1974,6 +1974,7 @@ DocType: Purchase Invoice,Select Supplier Address,כתובת ספק בחר
|
|||||||
DocType: SMS Center,SMS Center,SMS מרכז
|
DocType: SMS Center,SMS Center,SMS מרכז
|
||||||
apps/erpnext/erpnext/accounts/report/cash_flow/cash_flow.py,Cash Flow from Investing,תזרים מזומנים מהשקעות
|
apps/erpnext/erpnext/accounts/report/cash_flow/cash_flow.py,Cash Flow from Investing,תזרים מזומנים מהשקעות
|
||||||
DocType: Stock Entry Detail,Basic Amount,סכום בסיסי
|
DocType: Stock Entry Detail,Basic Amount,סכום בסיסי
|
||||||
|
DocType: Loan Repayment,Amount Paid,הסכום ששולם
|
||||||
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py,Investments,השקעות
|
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py,Investments,השקעות
|
||||||
DocType: Serial No,Under Warranty,במסגרת אחריות
|
DocType: Serial No,Under Warranty,במסגרת אחריות
|
||||||
DocType: Price List,Price List Name,שם מחיר המחירון
|
DocType: Price List,Price List Name,שם מחיר המחירון
|
||||||
@ -2475,7 +2476,6 @@ DocType: Job Applicant,Applicant for a Job,מועמד לעבודה
|
|||||||
apps/erpnext/erpnext/accounts/doctype/payment_entry/payment_entry.py,Reference No and Reference Date is mandatory for Bank transaction,אסמכתא ותאריך ההפניה הוא חובה עבור עסקת הבנק
|
apps/erpnext/erpnext/accounts/doctype/payment_entry/payment_entry.py,Reference No and Reference Date is mandatory for Bank transaction,אסמכתא ותאריך ההפניה הוא חובה עבור עסקת הבנק
|
||||||
DocType: Cheque Print Template,Signatory Position,תפקיד החותם
|
DocType: Cheque Print Template,Signatory Position,תפקיד החותם
|
||||||
,Item-wise Sales Register,פריט חכם מכירות הרשמה
|
,Item-wise Sales Register,פריט חכם מכירות הרשמה
|
||||||
DocType: Bank Reconciliation,Select account head of the bank where cheque was deposited.,ראש בחר חשבון של הבנק שבו הופקד שיק.
|
|
||||||
DocType: Pricing Rule,Margin,Margin
|
DocType: Pricing Rule,Margin,Margin
|
||||||
apps/erpnext/erpnext/manufacturing/doctype/bom/bom.js,Qty To Manufacture,כמות לייצור
|
apps/erpnext/erpnext/manufacturing/doctype/bom/bom.js,Qty To Manufacture,כמות לייצור
|
||||||
DocType: Bank Statement Transaction Settings Item,Transaction,עסקה
|
DocType: Bank Statement Transaction Settings Item,Transaction,עסקה
|
||||||
@ -2658,7 +2658,7 @@ apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.js,Debit Accou
|
|||||||
apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py,Serial No {0} has already been received,מספר סידורי {0} כבר קיבל
|
apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py,Serial No {0} has already been received,מספר סידורי {0} כבר קיבל
|
||||||
,To Produce,כדי לייצר
|
,To Produce,כדי לייצר
|
||||||
DocType: Item Price,Multiple Item prices.,מחירי פריט מרובים.
|
DocType: Item Price,Multiple Item prices.,מחירי פריט מרובים.
|
||||||
DocType: Job Card,Production,הפקה
|
DocType: Plaid Settings,Production,הפקה
|
||||||
DocType: Appointment Booking Settings,Holiday List,רשימת החג
|
DocType: Appointment Booking Settings,Holiday List,רשימת החג
|
||||||
apps/erpnext/erpnext/accounts/doctype/account/account_tree.js,"Optional. Sets company's default currency, if not specified.","אופציונאלי. סטי ברירת מחדל המטבע של החברה, אם לא צוין."
|
apps/erpnext/erpnext/accounts/doctype/account/account_tree.js,"Optional. Sets company's default currency, if not specified.","אופציונאלי. סטי ברירת מחדל המטבע של החברה, אם לא צוין."
|
||||||
apps/erpnext/erpnext/public/js/setup_wizard.js,The name of the institute for which you are setting up this system.,שמו של המכון אשר אתה מגדיר מערכת זו.
|
apps/erpnext/erpnext/public/js/setup_wizard.js,The name of the institute for which you are setting up this system.,שמו של המכון אשר אתה מגדיר מערכת זו.
|
||||||
@ -3173,6 +3173,7 @@ DocType: Monthly Distribution,Name of the Monthly Distribution,שמו של הח
|
|||||||
,Item Shortage Report,דווח מחסור פריט
|
,Item Shortage Report,דווח מחסור פריט
|
||||||
apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py,Item {0} is not setup for Serial Nos. Check Item master,פריט {0} הוא לא התקנה למס סידורי. בדוק אדון פריט
|
apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py,Item {0} is not setup for Serial Nos. Check Item master,פריט {0} הוא לא התקנה למס סידורי. בדוק אדון פריט
|
||||||
apps/erpnext/erpnext/accounts/doctype/cheque_print_template/cheque_print_template.js,Print settings updated in respective print format,הגדרות הדפסה עודכנו מודפסות בהתאמה
|
apps/erpnext/erpnext/accounts/doctype/cheque_print_template/cheque_print_template.js,Print settings updated in respective print format,הגדרות הדפסה עודכנו מודפסות בהתאמה
|
||||||
|
apps/erpnext/erpnext/loan_management/doctype/loan_type/loan_type.py,Account {0} does not belong to Company {1},חשבון {0} אינו שייך לחברת {1}
|
||||||
apps/erpnext/erpnext/public/js/setup_wizard.js,The name of your company for which you are setting up this system.,שמה של החברה שלך שאתה מגדיר את המערכת הזאת.
|
apps/erpnext/erpnext/public/js/setup_wizard.js,The name of your company for which you are setting up this system.,שמה של החברה שלך שאתה מגדיר את המערכת הזאת.
|
||||||
apps/erpnext/erpnext/education/doctype/student_applicant/student_applicant.js,Approve,לְאַשֵׁר
|
apps/erpnext/erpnext/education/doctype/student_applicant/student_applicant.js,Approve,לְאַשֵׁר
|
||||||
apps/erpnext/erpnext/hr/doctype/holiday_list/holiday_list.py,The holiday on {0} is not between From Date and To Date,החג על {0} הוא לא בין מתאריך ו עד תאריך
|
apps/erpnext/erpnext/hr/doctype/holiday_list/holiday_list.py,The holiday on {0} is not between From Date and To Date,החג על {0} הוא לא בין מתאריך ו עד תאריך
|
||||||
|
|||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -251,7 +251,7 @@ DocType: Employee,Health Details,Detalhes sobre a Saúde
|
|||||||
DocType: Accounts Settings,"Accounting entry frozen up to this date, nobody can do / modify entry except role specified below.","Registros contábeis congelados até a presente data, ninguém pode criar/modificar registros com exceção do perfil especificado abaixo."
|
DocType: Accounts Settings,"Accounting entry frozen up to this date, nobody can do / modify entry except role specified below.","Registros contábeis congelados até a presente data, ninguém pode criar/modificar registros com exceção do perfil especificado abaixo."
|
||||||
apps/erpnext/erpnext/hr/doctype/expense_claim/expense_claim.py,Total advance amount cannot be greater than total sanctioned amount,O montante do adiantamento total não pode ser maior do que o montante liberado total
|
apps/erpnext/erpnext/hr/doctype/expense_claim/expense_claim.py,Total advance amount cannot be greater than total sanctioned amount,O montante do adiantamento total não pode ser maior do que o montante liberado total
|
||||||
,Payment Period Based On Invoice Date,Prazo Médio de Pagamento Baseado na Emissão da Nota
|
,Payment Period Based On Invoice Date,Prazo Médio de Pagamento Baseado na Emissão da Nota
|
||||||
apps/erpnext/erpnext/accounts/report/purchase_register/purchase_register.py,Total Tax,Total de Impostos
|
apps/erpnext/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py,Total Tax,Total de Impostos
|
||||||
DocType: Delivery Note,Return Against Delivery Note,Devolução contra Guia de Remessa
|
DocType: Delivery Note,Return Against Delivery Note,Devolução contra Guia de Remessa
|
||||||
apps/erpnext/erpnext/accounts/utils.py,Payment Entries {0} are un-linked,Os Registos de Pagamento {0} não estão relacionados
|
apps/erpnext/erpnext/accounts/utils.py,Payment Entries {0} are un-linked,Os Registos de Pagamento {0} não estão relacionados
|
||||||
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note_list.js,Cannot create a Delivery Trip from Draft documents.,Você não pode criar uma Viagem de Entrega para documentos em rascunho.
|
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note_list.js,Cannot create a Delivery Trip from Draft documents.,Você não pode criar uma Viagem de Entrega para documentos em rascunho.
|
||||||
@ -553,6 +553,7 @@ apps/erpnext/erpnext/controllers/selling_controller.py,Sales Order {0} is {1},Pe
|
|||||||
DocType: Patient,Married,Casado
|
DocType: Patient,Married,Casado
|
||||||
apps/erpnext/erpnext/setup/setup_wizard/data/industry_type.py,Executive Search,Executive Search
|
apps/erpnext/erpnext/setup/setup_wizard/data/industry_type.py,Executive Search,Executive Search
|
||||||
,Itemwise Recommended Reorder Level,Níves de Reposição Recomendados por Item
|
,Itemwise Recommended Reorder Level,Níves de Reposição Recomendados por Item
|
||||||
|
DocType: Loan Repayment,Amount Paid,Valor pago
|
||||||
DocType: Guardian,Guardian Of ,Responsável por
|
DocType: Guardian,Guardian Of ,Responsável por
|
||||||
DocType: Bank Statement Transaction Entry,Receivable Account,Contas a Receber
|
DocType: Bank Statement Transaction Entry,Receivable Account,Contas a Receber
|
||||||
DocType: Job Offer,Printing Details,Imprimir detalhes
|
DocType: Job Offer,Printing Details,Imprimir detalhes
|
||||||
@ -651,7 +652,7 @@ apps/erpnext/erpnext/manufacturing/doctype/production_plan/production_plan.js,"R
|
|||||||
DocType: Authorization Rule,Applicable To (User),Aplicável Para (Usuário)
|
DocType: Authorization Rule,Applicable To (User),Aplicável Para (Usuário)
|
||||||
apps/erpnext/erpnext/controllers/trends.py,Total(Amt),Total (Quantia)
|
apps/erpnext/erpnext/controllers/trends.py,Total(Amt),Total (Quantia)
|
||||||
apps/erpnext/erpnext/selling/doctype/installation_note/installation_note.py,Item {0} is not a serialized Item,Item {0} não é um item serializado
|
apps/erpnext/erpnext/selling/doctype/installation_note/installation_note.py,Item {0} is not a serialized Item,Item {0} não é um item serializado
|
||||||
apps/erpnext/erpnext/hr/doctype/loan/loan.js,Principal Amount,Valor Principal
|
DocType: Repayment Schedule,Principal Amount,Valor Principal
|
||||||
apps/erpnext/erpnext/config/projects.py,Timesheet for tasks.,Registros de Tempo para tarefas.
|
apps/erpnext/erpnext/config/projects.py,Timesheet for tasks.,Registros de Tempo para tarefas.
|
||||||
apps/erpnext/erpnext/selling/doctype/installation_note/installation_note.py,Installation date cannot be before delivery date for Item {0},Data de instalação não pode ser anterior à data de entrega de item {0}
|
apps/erpnext/erpnext/selling/doctype/installation_note/installation_note.py,Installation date cannot be before delivery date for Item {0},Data de instalação não pode ser anterior à data de entrega de item {0}
|
||||||
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py,{0} is mandatory for Item {1},{0} é obrigatório para o item {1}
|
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py,{0} is mandatory for Item {1},{0} é obrigatório para o item {1}
|
||||||
@ -771,7 +772,7 @@ apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standar
|
|||||||
apps/erpnext/erpnext/healthcare/doctype/lab_test/lab_test.js,Send SMS,Envie SMS
|
apps/erpnext/erpnext/healthcare/doctype/lab_test/lab_test.js,Send SMS,Envie SMS
|
||||||
apps/erpnext/erpnext/education/doctype/student_admission/templates/student_admission.html,Apply Now,Aplique agora
|
apps/erpnext/erpnext/education/doctype/student_admission/templates/student_admission.html,Apply Now,Aplique agora
|
||||||
apps/erpnext/erpnext/config/buying.py,Request for quotation.,Solicitação de orçamento.
|
apps/erpnext/erpnext/config/buying.py,Request for quotation.,Solicitação de orçamento.
|
||||||
DocType: Loan,Total Payment,Pagamento Total
|
DocType: Repayment Schedule,Total Payment,Pagamento Total
|
||||||
DocType: Work Order,Manufactured Qty,Qtde Fabricada
|
DocType: Work Order,Manufactured Qty,Qtde Fabricada
|
||||||
DocType: Leave Application,Leave Approver Name,Nome do Aprovador de Licenças
|
DocType: Leave Application,Leave Approver Name,Nome do Aprovador de Licenças
|
||||||
DocType: Employee Attendance Tool,Employees HTML,Colaboradores HTML
|
DocType: Employee Attendance Tool,Employees HTML,Colaboradores HTML
|
||||||
@ -842,7 +843,6 @@ DocType: Clinical Procedure,Inpatient Record,Registro de Internação
|
|||||||
DocType: Fee Schedule Program,Student Batch,Série de Alunos
|
DocType: Fee Schedule Program,Student Batch,Série de Alunos
|
||||||
apps/erpnext/erpnext/stock/doctype/material_request/material_request.js,Fetch exploded BOM (including sub-assemblies),Buscar LDM explodida (incluindo sub-conjuntos )
|
apps/erpnext/erpnext/stock/doctype/material_request/material_request.js,Fetch exploded BOM (including sub-assemblies),Buscar LDM explodida (incluindo sub-conjuntos )
|
||||||
DocType: Lead,Lead is an Organization,Cliente em Potencial é uma Empresa
|
DocType: Lead,Lead is an Organization,Cliente em Potencial é uma Empresa
|
||||||
DocType: Loan Application,Required by Date,Necessário até a data
|
|
||||||
DocType: Purchase Taxes and Charges,Reference Row #,Referência Linha #
|
DocType: Purchase Taxes and Charges,Reference Row #,Referência Linha #
|
||||||
DocType: Payroll Entry,Employee Details,Detalhes do Funcionário
|
DocType: Payroll Entry,Employee Details,Detalhes do Funcionário
|
||||||
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py,Customer {0} does not belong to project {1},Cliente {0} não pertence ao projeto {1}
|
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py,Customer {0} does not belong to project {1},Cliente {0} não pertence ao projeto {1}
|
||||||
@ -1650,7 +1650,7 @@ apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py,Total Debit
|
|||||||
apps/erpnext/erpnext/crm/report/prospects_engaged_but_not_converted/prospects_engaged_but_not_converted.py,Last Communication Date,Data do Último Contato
|
apps/erpnext/erpnext/crm/report/prospects_engaged_but_not_converted/prospects_engaged_but_not_converted.py,Last Communication Date,Data do Último Contato
|
||||||
DocType: Work Order,Manufacture against Material Request,Fabricação Vinculada a uma Requisição de Material
|
DocType: Work Order,Manufacture against Material Request,Fabricação Vinculada a uma Requisição de Material
|
||||||
DocType: Email Digest,Payables,Contas a Pagar
|
DocType: Email Digest,Payables,Contas a Pagar
|
||||||
DocType: Vehicle Log,Odometer,Odômetro
|
apps/erpnext/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py,Odometer,Odômetro
|
||||||
DocType: Employee Attendance Tool,Marked Attendance HTML,Presença marcante HTML
|
DocType: Employee Attendance Tool,Marked Attendance HTML,Presença marcante HTML
|
||||||
apps/erpnext/erpnext/setup/setup_wizard/data/industry_type.py,Department Stores,Lojas de Departamento
|
apps/erpnext/erpnext/setup/setup_wizard/data/industry_type.py,Department Stores,Lojas de Departamento
|
||||||
DocType: Issue,First Responded On,Primeira Resposta em
|
DocType: Issue,First Responded On,Primeira Resposta em
|
||||||
@ -1761,7 +1761,7 @@ apps/erpnext/erpnext/selling/page/point_of_sale/point_of_sale.js,POS Profile is
|
|||||||
DocType: Manufacturing Settings,Capacity Planning,Planejamento de capacidade
|
DocType: Manufacturing Settings,Capacity Planning,Planejamento de capacidade
|
||||||
apps/erpnext/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js,Please select {0},Por favor selecione {0}
|
apps/erpnext/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js,Please select {0},Por favor selecione {0}
|
||||||
DocType: Employee Tax Exemption Declaration Category,Employee Tax Exemption Declaration Category,Categoria de Declaração de Isenção de Imposto do Colaborador
|
DocType: Employee Tax Exemption Declaration Category,Employee Tax Exemption Declaration Category,Categoria de Declaração de Isenção de Imposto do Colaborador
|
||||||
DocType: Loan Application,Total Payable Amount,Total a Pagar
|
DocType: Loan,Total Payable Amount,Total a Pagar
|
||||||
apps/erpnext/erpnext/controllers/accounts_controller.py,Charge of type 'Actual' in row {0} cannot be included in Item Rate,Charge do tipo ' real ' na linha {0} não pode ser incluído no item Taxa
|
apps/erpnext/erpnext/controllers/accounts_controller.py,Charge of type 'Actual' in row {0} cannot be included in Item Rate,Charge do tipo ' real ' na linha {0} não pode ser incluído no item Taxa
|
||||||
DocType: Work Order,Work-in-Progress Warehouse,Armazén de Trabalho em Andamento
|
DocType: Work Order,Work-in-Progress Warehouse,Armazén de Trabalho em Andamento
|
||||||
apps/erpnext/erpnext/education/doctype/student/student.py,Date of Birth cannot be greater than today.,Data de nascimento não pode ser maior do que hoje.
|
apps/erpnext/erpnext/education/doctype/student/student.py,Date of Birth cannot be greater than today.,Data de nascimento não pode ser maior do que hoje.
|
||||||
@ -2527,7 +2527,7 @@ DocType: Pick List,Parent Warehouse,Armazén Pai
|
|||||||
apps/erpnext/erpnext/portal/doctype/homepage/homepage.py,This is an example website auto-generated from ERPNext,Este é um exemplo website auto- gerada a partir ERPNext
|
apps/erpnext/erpnext/portal/doctype/homepage/homepage.py,This is an example website auto-generated from ERPNext,Este é um exemplo website auto- gerada a partir ERPNext
|
||||||
DocType: Chapter Member,Leave Reason,Motivo da Saída
|
DocType: Chapter Member,Leave Reason,Motivo da Saída
|
||||||
DocType: Item Group,Show this slideshow at the top of the page,Mostrar esta apresentação de slides no topo da página
|
DocType: Item Group,Show this slideshow at the top of the page,Mostrar esta apresentação de slides no topo da página
|
||||||
DocType: Loan Type,Maximum Loan Amount,Valor Máximo de Empréstimo
|
DocType: Loan Application,Maximum Loan Amount,Valor Máximo de Empréstimo
|
||||||
DocType: Serial No,Creation Time,Horário de Criação
|
DocType: Serial No,Creation Time,Horário de Criação
|
||||||
DocType: Employee Incentive,Employee Incentive,Incentivo ao Colaborador
|
DocType: Employee Incentive,Employee Incentive,Incentivo ao Colaborador
|
||||||
DocType: Leave Allocation,Total Leaves Allocated,Total de licenças alocadas
|
DocType: Leave Allocation,Total Leaves Allocated,Total de licenças alocadas
|
||||||
@ -3006,11 +3006,10 @@ apps/erpnext/erpnext/controllers/accounts_controller.py,Due Date is mandatory,A
|
|||||||
DocType: Manufacturing Settings,Material Transferred for Manufacture,Material Transferido para Fabricação
|
DocType: Manufacturing Settings,Material Transferred for Manufacture,Material Transferido para Fabricação
|
||||||
,Employee Information,Informações do Colaborador
|
,Employee Information,Informações do Colaborador
|
||||||
DocType: Purchase Invoice,Start date of current invoice's period,Data de início do período de fatura atual
|
DocType: Purchase Invoice,Start date of current invoice's period,Data de início do período de fatura atual
|
||||||
DocType: Bank Reconciliation,Select account head of the bank where cheque was deposited.,Selecione a conta bancária onde o valor foi depositado.
|
|
||||||
DocType: Production Plan Item,Product Bundle Item,Item do Pacote de Produtos
|
DocType: Production Plan Item,Product Bundle Item,Item do Pacote de Produtos
|
||||||
apps/erpnext/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js,Please enter Purchase Receipt first,Digite Recibo de compra primeiro
|
apps/erpnext/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js,Please enter Purchase Receipt first,Digite Recibo de compra primeiro
|
||||||
DocType: Opportunity,Contact Info,Informações para Contato
|
DocType: Opportunity,Contact Info,Informações para Contato
|
||||||
DocType: Employee,Job Applicant,Candidato à Vaga
|
DocType: Appointment Letter,Job Applicant,Candidato à Vaga
|
||||||
apps/erpnext/erpnext/setup/setup_wizard/data/industry_type.py,Newspaper Publishers,Editor de Newsletter
|
apps/erpnext/erpnext/setup/setup_wizard/data/industry_type.py,Newspaper Publishers,Editor de Newsletter
|
||||||
DocType: Sales Order Item,Supplier delivers to Customer,O fornecedor entrega diretamente ao cliente
|
DocType: Sales Order Item,Supplier delivers to Customer,O fornecedor entrega diretamente ao cliente
|
||||||
apps/erpnext/erpnext/setup/setup_wizard/operations/install_fixtures.py,Extra Small,Muito Pequeno
|
apps/erpnext/erpnext/setup/setup_wizard/operations/install_fixtures.py,Extra Small,Muito Pequeno
|
||||||
|
|||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -302,6 +302,7 @@ apps/erpnext/erpnext/hr/doctype/compensatory_leave_request/compensatory_leave_re
|
|||||||
DocType: Shopping Cart Settings,Enable Shopping Cart,Omogući korpu
|
DocType: Shopping Cart Settings,Enable Shopping Cart,Omogući korpu
|
||||||
DocType: Purchase Invoice Item,Is Fixed Asset,Artikal je osnovno sredstvo
|
DocType: Purchase Invoice Item,Is Fixed Asset,Artikal je osnovno sredstvo
|
||||||
,POS,POS
|
,POS,POS
|
||||||
|
DocType: Loan Repayment,Amount Paid,Plaćeni iznos
|
||||||
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py,Timesheet {0} is already completed or cancelled,Potrošeno vrijeme {0} je već potvrđeno ili otkazano
|
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py,Timesheet {0} is already completed or cancelled,Potrošeno vrijeme {0} je već potvrđeno ili otkazano
|
||||||
apps/erpnext/erpnext/hr/doctype/leave_application/leave_application.py, (Half Day),(Pola dana)
|
apps/erpnext/erpnext/hr/doctype/leave_application/leave_application.py, (Half Day),(Pola dana)
|
||||||
DocType: Shipping Rule,Net Weight,Neto težina
|
DocType: Shipping Rule,Net Weight,Neto težina
|
||||||
@ -589,6 +590,7 @@ apps/erpnext/erpnext/stock/doctype/material_request/material_request_dashboard.p
|
|||||||
DocType: Warehouse,Warehouse Name,Naziv skladišta
|
DocType: Warehouse,Warehouse Name,Naziv skladišta
|
||||||
DocType: Authorization Rule,Customer / Item Name,Kupac / Naziv proizvoda
|
DocType: Authorization Rule,Customer / Item Name,Kupac / Naziv proizvoda
|
||||||
DocType: Timesheet,Total Billed Amount,Ukupno fakturisano
|
DocType: Timesheet,Total Billed Amount,Ukupno fakturisano
|
||||||
|
DocType: Student,Home Address,Kućna adresa
|
||||||
apps/erpnext/erpnext/stock/report/stock_balance/stock_balance.py,In Value,Prijem vrije.
|
apps/erpnext/erpnext/stock/report/stock_balance/stock_balance.py,In Value,Prijem vrije.
|
||||||
DocType: Expense Claim,Employees Email Id,ID email Zaposlenih
|
DocType: Expense Claim,Employees Email Id,ID email Zaposlenih
|
||||||
apps/erpnext/erpnext/healthcare/page/appointment_analytic/appointment_analytic.js,Tree Type,Tip stabla
|
apps/erpnext/erpnext/healthcare/page/appointment_analytic/appointment_analytic.js,Tree Type,Tip stabla
|
||||||
@ -789,7 +791,7 @@ DocType: Production Plan,For Warehouse,Za skladište
|
|||||||
apps/erpnext/erpnext/stock/report/item_prices/item_prices.py,Purchase Price List,Nabavni cjenovnik
|
apps/erpnext/erpnext/stock/report/item_prices/item_prices.py,Purchase Price List,Nabavni cjenovnik
|
||||||
apps/erpnext/erpnext/accounts/report/accounts_payable/accounts_payable.js,Accounts Payable Summary,Pregled obaveze prema dobavljačima
|
apps/erpnext/erpnext/accounts/report/accounts_payable/accounts_payable.js,Accounts Payable Summary,Pregled obaveze prema dobavljačima
|
||||||
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py,Delivery Notes {0} must be cancelled before cancelling this Sales Order,Otpremnice {0} moraju biti otkazane prije otkazivanja prodajnog naloga
|
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py,Delivery Notes {0} must be cancelled before cancelling this Sales Order,Otpremnice {0} moraju biti otkazane prije otkazivanja prodajnog naloga
|
||||||
DocType: Loan,Total Payment,Ukupno plaćeno
|
DocType: Repayment Schedule,Total Payment,Ukupno plaćeno
|
||||||
DocType: POS Settings,POS Settings,POS podešavanja
|
DocType: POS Settings,POS Settings,POS podešavanja
|
||||||
apps/erpnext/erpnext/accounts/report/gross_profit/gross_profit.py,Buying Amount,Iznos nabavke
|
apps/erpnext/erpnext/accounts/report/gross_profit/gross_profit.py,Buying Amount,Iznos nabavke
|
||||||
DocType: Purchase Invoice Item,Valuation Rate,Prosječna nab. cijena
|
DocType: Purchase Invoice Item,Valuation Rate,Prosječna nab. cijena
|
||||||
@ -916,7 +918,7 @@ DocType: Pick List,Material Transfer for Manufacture,Пренос robe za proizv
|
|||||||
apps/erpnext/erpnext/public/js/utils/customer_quick_entry.js,Primary Contact Details,Detalji o primarnom kontaktu
|
apps/erpnext/erpnext/public/js/utils/customer_quick_entry.js,Primary Contact Details,Detalji o primarnom kontaktu
|
||||||
apps/erpnext/erpnext/accounts/report/general_ledger/general_ledger.html,Ref,Vezni dokument
|
apps/erpnext/erpnext/accounts/report/general_ledger/general_ledger.html,Ref,Vezni dokument
|
||||||
DocType: Account,Accounts,Računi
|
DocType: Account,Accounts,Računi
|
||||||
,Requested,Tražena
|
DocType: Loan Security Pledge,Requested,Tražena
|
||||||
apps/erpnext/erpnext/controllers/selling_controller.py,{0} {1} is cancelled or closed,{0} {1} je otkazan ili zatvoren
|
apps/erpnext/erpnext/controllers/selling_controller.py,{0} {1} is cancelled or closed,{0} {1} je otkazan ili zatvoren
|
||||||
DocType: Request for Quotation Item,Request for Quotation Item,Zahtjev za stavku sa ponude
|
DocType: Request for Quotation Item,Request for Quotation Item,Zahtjev za stavku sa ponude
|
||||||
DocType: Homepage,Products,Proizvodi
|
DocType: Homepage,Products,Proizvodi
|
||||||
|
|||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user