Merge branch 'develop'
@ -53,4 +53,4 @@ script:
|
|||||||
- set -e
|
- set -e
|
||||||
- bench --verbose run-tests
|
- bench --verbose run-tests
|
||||||
- sleep 5
|
- sleep 5
|
||||||
- bench --verbose run-tests --ui-tests
|
- bench --verbose run-ui-tests --app erpnext
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
import inspect
|
||||||
import frappe
|
import frappe
|
||||||
|
from erpnext.hooks import regional_overrides
|
||||||
|
|
||||||
__version__ = '8.4.3'
|
__version__ = '8.5.0'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
@ -65,3 +67,34 @@ def is_perpetual_inventory_enabled(company):
|
|||||||
company, "enable_perpetual_inventory") or 0
|
company, "enable_perpetual_inventory") or 0
|
||||||
|
|
||||||
return frappe.local.enable_perpetual_inventory[company]
|
return frappe.local.enable_perpetual_inventory[company]
|
||||||
|
|
||||||
|
def get_region(company=None):
|
||||||
|
'''Return the default country based on flag, company or global settings
|
||||||
|
|
||||||
|
You can also set global company flag in `frappe.flags.company`
|
||||||
|
'''
|
||||||
|
if company or frappe.flags.company:
|
||||||
|
return frappe.db.get_value('Company',
|
||||||
|
company or frappe.flags.company, 'country')
|
||||||
|
elif frappe.flags.country:
|
||||||
|
return frappe.flags.country
|
||||||
|
else:
|
||||||
|
return frappe.get_system_settings('country')
|
||||||
|
|
||||||
|
def allow_regional(fn):
|
||||||
|
'''Decorator to make a function regionally overridable
|
||||||
|
|
||||||
|
Example:
|
||||||
|
@erpnext.allow_regional
|
||||||
|
def myfunction():
|
||||||
|
pass'''
|
||||||
|
def caller(*args, **kwargs):
|
||||||
|
region = get_region()
|
||||||
|
fn_name = inspect.getmodule(fn).__name__ + '.' + fn.__name__
|
||||||
|
if region in regional_overrides and fn_name in regional_overrides[region]:
|
||||||
|
return frappe.get_attr(regional_overrides[region][fn_name])(*args, **kwargs)
|
||||||
|
else:
|
||||||
|
return fn(*args, **kwargs)
|
||||||
|
|
||||||
|
return caller
|
||||||
|
|
||||||
|
|||||||
@ -1,94 +1,94 @@
|
|||||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Account', {
|
||||||
cur_frm.cscript.refresh = function (doc, cdt, cdn) {
|
setup: function(frm) {
|
||||||
if (doc.__islocal) {
|
frm.add_fetch('parent_account', 'report_type', 'report_type');
|
||||||
frappe.msgprint(__("Please create new account from Chart of Accounts."));
|
frm.add_fetch('parent_account', 'root_type', 'root_type');
|
||||||
throw "cannot create";
|
},
|
||||||
}
|
onload: function(frm) {
|
||||||
|
frm.set_query('parent_account', function(doc) {
|
||||||
cur_frm.toggle_display('account_name', doc.__islocal);
|
return {
|
||||||
|
filters: {
|
||||||
// hide fields if group
|
"is_group": 1,
|
||||||
cur_frm.toggle_display(['account_type', 'tax_rate'], cint(doc.is_group) == 0)
|
"company": doc.company
|
||||||
|
}
|
||||||
// disable fields
|
|
||||||
cur_frm.toggle_enable(['account_name', 'is_group', 'company'], false);
|
|
||||||
|
|
||||||
if (cint(doc.is_group) == 0) {
|
|
||||||
cur_frm.toggle_display('freeze_account', doc.__onload && doc.__onload.can_freeze_account);
|
|
||||||
}
|
|
||||||
|
|
||||||
// read-only for root accounts
|
|
||||||
if (!doc.parent_account) {
|
|
||||||
cur_frm.set_read_only();
|
|
||||||
cur_frm.set_intro(__("This is a root account and cannot be edited."));
|
|
||||||
} else {
|
|
||||||
// credit days and type if customer or supplier
|
|
||||||
cur_frm.set_intro(null);
|
|
||||||
|
|
||||||
cur_frm.cscript.account_type(doc, cdt, cdn);
|
|
||||||
|
|
||||||
// show / hide convert buttons
|
|
||||||
cur_frm.cscript.add_toolbar_buttons(doc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.add_fetch('parent_account', 'report_type', 'report_type');
|
|
||||||
cur_frm.add_fetch('parent_account', 'root_type', 'root_type');
|
|
||||||
|
|
||||||
cur_frm.cscript.account_type = function (doc, cdt, cdn) {
|
|
||||||
if (doc.is_group == 0) {
|
|
||||||
cur_frm.toggle_display(['tax_rate'], doc.account_type == 'Tax');
|
|
||||||
cur_frm.toggle_display('warehouse', doc.account_type == 'Stock');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.cscript.add_toolbar_buttons = function (doc) {
|
|
||||||
cur_frm.add_custom_button(__('Chart of Accounts'),
|
|
||||||
function () { frappe.set_route("Tree", "Account"); });
|
|
||||||
|
|
||||||
if (doc.is_group == 1) {
|
|
||||||
cur_frm.add_custom_button(__('Group to Non-Group'),
|
|
||||||
function () { cur_frm.cscript.convert_to_ledger(); }, 'fa fa-retweet', 'btn-default');
|
|
||||||
} else if (cint(doc.is_group) == 0) {
|
|
||||||
cur_frm.add_custom_button(__('Ledger'), function () {
|
|
||||||
frappe.route_options = {
|
|
||||||
"account": doc.name,
|
|
||||||
"from_date": frappe.sys_defaults.year_start_date,
|
|
||||||
"to_date": frappe.sys_defaults.year_end_date,
|
|
||||||
"company": doc.company
|
|
||||||
};
|
};
|
||||||
frappe.set_route("query-report", "General Ledger");
|
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
refresh: function(frm) {
|
||||||
|
if (frm.doc.__islocal) {
|
||||||
|
frappe.msgprint(__("Please create new account from Chart of Accounts."));
|
||||||
|
throw "cannot create";
|
||||||
|
}
|
||||||
|
|
||||||
|
frm.toggle_display('account_name', frm.doc.__islocal);
|
||||||
|
|
||||||
|
// hide fields if group
|
||||||
|
frm.toggle_display(['account_type', 'tax_rate'], cint(frm.doc.is_group) == 0);
|
||||||
|
|
||||||
|
// disable fields
|
||||||
|
frm.toggle_enable(['account_name', 'is_group', 'company'], false);
|
||||||
|
|
||||||
|
if (cint(frm.doc.is_group) == 0) {
|
||||||
|
frm.toggle_display('freeze_account', frm.doc.__onload
|
||||||
|
&& frm.doc.__onload.can_freeze_account);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read-only for root accounts
|
||||||
|
if (!frm.doc.parent_account) {
|
||||||
|
frm.set_read_only();
|
||||||
|
frm.set_intro(__("This is a root account and cannot be edited."));
|
||||||
|
} else {
|
||||||
|
// credit days and type if customer or supplier
|
||||||
|
frm.set_intro(null);
|
||||||
|
frm.trigger('account_type');
|
||||||
|
|
||||||
|
// show / hide convert buttons
|
||||||
|
frm.trigger('add_toolbar_buttons');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
account_type: function (frm) {
|
||||||
|
if (frm.doc.is_group == 0) {
|
||||||
|
frm.toggle_display(['tax_rate'], frm.doc.account_type == 'Tax');
|
||||||
|
frm.toggle_display('warehouse', frm.doc.account_type == 'Stock');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
add_toolbar_buttons: function(frm) {
|
||||||
|
frm.add_custom_button(__('Chart of Accounts'),
|
||||||
|
function () { frappe.set_route("Tree", "Account"); });
|
||||||
|
|
||||||
|
if (frm.doc.is_group == 1) {
|
||||||
|
frm.add_custom_button(__('Group to Non-Group'), function () {
|
||||||
|
return frappe.call({
|
||||||
|
doc: frm.doc,
|
||||||
|
method: 'convert_group_to_ledger',
|
||||||
|
callback: function() {
|
||||||
|
frm.refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (cint(frm.doc.is_group) == 0) {
|
||||||
|
cur_frm.add_custom_button(__('Ledger'), function () {
|
||||||
|
frappe.route_options = {
|
||||||
|
"account": frm.doc.name,
|
||||||
|
"from_date": frappe.sys_defaults.year_start_date,
|
||||||
|
"to_date": frappe.sys_defaults.year_end_date,
|
||||||
|
"company": frm.doc.company
|
||||||
|
};
|
||||||
|
frappe.set_route("query-report", "General Ledger");
|
||||||
|
});
|
||||||
|
|
||||||
|
frm.add_custom_button(__('Non-Group to Group'), function () {
|
||||||
|
return frappe.call({
|
||||||
|
doc: frm.doc,
|
||||||
|
method: 'convert_ledger_to_group',
|
||||||
|
callback: function() {
|
||||||
|
frm.refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
cur_frm.add_custom_button(__('Non-Group to Group'),
|
|
||||||
function () { cur_frm.cscript.convert_to_group(); }, 'fa fa-retweet', 'btn-default')
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
cur_frm.cscript.convert_to_ledger = function (doc, cdt, cdn) {
|
|
||||||
return $c_obj(cur_frm.doc, 'convert_group_to_ledger', '', function (r, rt) {
|
|
||||||
if (r.message == 1) {
|
|
||||||
cur_frm.refresh();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.cscript.convert_to_group = function (doc, cdt, cdn) {
|
|
||||||
return $c_obj(cur_frm.doc, 'convert_ledger_to_group', '', function (r, rt) {
|
|
||||||
if (r.message == 1) {
|
|
||||||
cur_frm.refresh();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.fields_dict['parent_account'].get_query = function (doc) {
|
|
||||||
return {
|
|
||||||
filters: {
|
|
||||||
"is_group": 1,
|
|
||||||
"company": doc.company
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -96,7 +96,14 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
|
|||||||
|
|
||||||
// expense claim
|
// expense claim
|
||||||
if(jvd.reference_type==="Expense Claim") {
|
if(jvd.reference_type==="Expense Claim") {
|
||||||
return {};
|
return {
|
||||||
|
filters: {
|
||||||
|
'approval_status': 'Approved',
|
||||||
|
'total_sanctioned_amount': ['>', 0],
|
||||||
|
'status': ['!=', 'Paid'],
|
||||||
|
'docstatus': 1
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// journal entry
|
// journal entry
|
||||||
|
|||||||
@ -98,6 +98,26 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
this.set_default_print_format();
|
this.set_default_print_format();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
on_submit: function(doc, dt, dn) {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
$.each(doc["items"], function(i, row) {
|
||||||
|
if(row.delivery_note) frappe.model.clear_doc("Delivery Note", row.delivery_note)
|
||||||
|
})
|
||||||
|
|
||||||
|
if(this.frm.doc.is_pos) {
|
||||||
|
this.frm.msgbox = frappe.msgprint(
|
||||||
|
`<a class="btn btn-primary" onclick="cur_frm.print_preview.printit(true)" style="margin-right: 5px;">
|
||||||
|
${__('Print')}</a>
|
||||||
|
<a class="btn btn-default" href="javascript:frappe.new_doc(cur_frm.doctype);">
|
||||||
|
${__('New')}</a>`
|
||||||
|
);
|
||||||
|
|
||||||
|
} else if(cint(frappe.boot.notification_settings.sales_invoice)) {
|
||||||
|
this.frm.email_doc(frappe.boot.notification_settings.sales_invoice_message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
set_default_print_format: function() {
|
set_default_print_format: function() {
|
||||||
// set default print format to POS type
|
// set default print format to POS type
|
||||||
if(cur_frm.doc.is_pos) {
|
if(cur_frm.doc.is_pos) {
|
||||||
@ -306,7 +326,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
|
|
||||||
this.frm.refresh_fields();
|
this.frm.refresh_fields();
|
||||||
},
|
},
|
||||||
|
|
||||||
company_address: function() {
|
company_address: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
if(this.frm.doc.company_address) {
|
if(this.frm.doc.company_address) {
|
||||||
@ -343,13 +363,6 @@ cur_frm.cscript.hide_fields = function(doc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var item_fields_stock = ['batch_no', 'actual_batch_qty', 'actual_qty', 'expense_account',
|
|
||||||
'warehouse', 'expense_account', 'quality_inspection']
|
|
||||||
cur_frm.fields_dict['items'].grid.set_column_disp(item_fields_stock,
|
|
||||||
(cint(doc.update_stock)==1 || cint(doc.is_return)==1 ? true : false));
|
|
||||||
|
|
||||||
|
|
||||||
// India related fields
|
// India related fields
|
||||||
if (frappe.boot.sysdefaults.country == 'India') unhide_field(['c_form_applicable', 'c_form_no']);
|
if (frappe.boot.sysdefaults.country == 'India') unhide_field(['c_form_applicable', 'c_form_no']);
|
||||||
else hide_field(['c_form_applicable', 'c_form_no']);
|
else hide_field(['c_form_applicable', 'c_form_no']);
|
||||||
@ -445,24 +458,6 @@ cur_frm.cscript.cost_center = function(doc, cdt, cdn) {
|
|||||||
erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "cost_center");
|
erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "cost_center");
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
|
|
||||||
$.each(doc["items"], function(i, row) {
|
|
||||||
if(row.delivery_note) frappe.model.clear_doc("Delivery Note", row.delivery_note)
|
|
||||||
})
|
|
||||||
|
|
||||||
if(cur_frm.doc.is_pos) {
|
|
||||||
cur_frm.msgbox = frappe.msgprint(
|
|
||||||
`<a class="btn btn-primary" onclick="cur_frm.print_preview.printit(true)" style="margin-right: 5px;">
|
|
||||||
${__('Print')}</a>
|
|
||||||
<a class="btn btn-default" href="javascript:frappe.new_doc(cur_frm.doctype);">
|
|
||||||
${__('New')}</a>`
|
|
||||||
);
|
|
||||||
|
|
||||||
} else if(cint(frappe.boot.notification_settings.sales_invoice)) {
|
|
||||||
cur_frm.email_doc(frappe.boot.notification_settings.sales_invoice_message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.set_query("debit_to", function(doc) {
|
cur_frm.set_query("debit_to", function(doc) {
|
||||||
// filter on Account
|
// filter on Account
|
||||||
if (doc.customer) {
|
if (doc.customer) {
|
||||||
|
|||||||
@ -18,6 +18,7 @@ from erpnext.projects.doctype.timesheet.timesheet import get_projectwise_timeshe
|
|||||||
from erpnext.accounts.doctype.asset.depreciation \
|
from erpnext.accounts.doctype.asset.depreciation \
|
||||||
import get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal
|
import get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal
|
||||||
from erpnext.stock.doctype.batch.batch import set_batch_nos
|
from erpnext.stock.doctype.batch.batch import set_batch_nos
|
||||||
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos, get_delivery_note_serial_no
|
||||||
|
|
||||||
form_grid_templates = {
|
form_grid_templates = {
|
||||||
"items": "templates/form_grid/item_grid.html"
|
"items": "templates/form_grid/item_grid.html"
|
||||||
@ -83,10 +84,10 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
if not self.is_opening:
|
if not self.is_opening:
|
||||||
self.is_opening = 'No'
|
self.is_opening = 'No'
|
||||||
|
|
||||||
if self._action != 'submit' and self.update_stock and not self.is_return:
|
if self._action != 'submit' and self.update_stock and not self.is_return:
|
||||||
set_batch_nos(self, 'warehouse', True)
|
set_batch_nos(self, 'warehouse', True)
|
||||||
|
|
||||||
|
|
||||||
self.set_against_income_account()
|
self.set_against_income_account()
|
||||||
self.validate_c_form()
|
self.validate_c_form()
|
||||||
@ -98,7 +99,7 @@ class SalesInvoice(SellingController):
|
|||||||
self.set_billing_hours_and_amount()
|
self.set_billing_hours_and_amount()
|
||||||
self.update_timesheet_billing_for_project()
|
self.update_timesheet_billing_for_project()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
def before_save(self):
|
def before_save(self):
|
||||||
set_account_for_mode_of_payment(self)
|
set_account_for_mode_of_payment(self)
|
||||||
|
|
||||||
@ -139,6 +140,8 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
self.update_time_sheet(self.name)
|
self.update_time_sheet(self.name)
|
||||||
|
|
||||||
|
frappe.enqueue('erpnext.setup.doctype.company.company.update_company_current_month_sales', company=self.company)
|
||||||
|
|
||||||
def validate_pos_paid_amount(self):
|
def validate_pos_paid_amount(self):
|
||||||
if len(self.payments) == 0 and self.is_pos:
|
if len(self.payments) == 0 and self.is_pos:
|
||||||
frappe.throw(_("At least one mode of payment is required for POS invoice."))
|
frappe.throw(_("At least one mode of payment is required for POS invoice."))
|
||||||
@ -812,11 +815,18 @@ class SalesInvoice(SellingController):
|
|||||||
"""
|
"""
|
||||||
validate serial number agains Delivery Note and Sales Invoice
|
validate serial number agains Delivery Note and Sales Invoice
|
||||||
"""
|
"""
|
||||||
|
self.set_serial_no_against_delivery_note()
|
||||||
self.validate_serial_against_delivery_note()
|
self.validate_serial_against_delivery_note()
|
||||||
self.validate_serial_against_sales_invoice()
|
self.validate_serial_against_sales_invoice()
|
||||||
|
|
||||||
|
def set_serial_no_against_delivery_note(self):
|
||||||
|
for item in self.items:
|
||||||
|
if item.serial_no and item.delivery_note and \
|
||||||
|
item.qty != len(get_serial_nos(item.serial_no)):
|
||||||
|
item.serial_no = get_delivery_note_serial_no(item.item_code, item.qty, item.delivery_note)
|
||||||
|
|
||||||
def validate_serial_against_delivery_note(self):
|
def validate_serial_against_delivery_note(self):
|
||||||
"""
|
"""
|
||||||
validate if the serial numbers in Sales Invoice Items are same as in
|
validate if the serial numbers in Sales Invoice Items are same as in
|
||||||
Delivery Note Item
|
Delivery Note Item
|
||||||
"""
|
"""
|
||||||
@ -826,14 +836,18 @@ class SalesInvoice(SellingController):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
serial_nos = frappe.db.get_value("Delivery Note Item", item.dn_detail, "serial_no") or ""
|
serial_nos = frappe.db.get_value("Delivery Note Item", item.dn_detail, "serial_no") or ""
|
||||||
dn_serial_nos = set(serial_nos.split("\n"))
|
dn_serial_nos = set(get_serial_nos(serial_nos))
|
||||||
|
|
||||||
serial_nos = item.serial_no or ""
|
serial_nos = item.serial_no or ""
|
||||||
si_serial_nos = set(serial_nos.split("\n"))
|
si_serial_nos = set(get_serial_nos(serial_nos))
|
||||||
|
|
||||||
if si_serial_nos - dn_serial_nos:
|
if si_serial_nos - dn_serial_nos:
|
||||||
frappe.throw(_("Serial Numbers in row {0} does not match with Delivery Note".format(item.idx)))
|
frappe.throw(_("Serial Numbers in row {0} does not match with Delivery Note".format(item.idx)))
|
||||||
|
|
||||||
|
if item.serial_no and cint(item.qty) != len(si_serial_nos):
|
||||||
|
frappe.throw(_("Row {0}: {1} Serial numbers required for Item {2}. You have provided {3}.".format(
|
||||||
|
item.idx, item.qty, item.item_code, len(si_serial_nos))))
|
||||||
|
|
||||||
def validate_serial_against_sales_invoice(self):
|
def validate_serial_against_sales_invoice(self):
|
||||||
""" check if serial number is already used in other sales invoice """
|
""" check if serial number is already used in other sales invoice """
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
@ -918,7 +932,6 @@ def make_delivery_note(source_name, target_doc=None):
|
|||||||
|
|
||||||
return doclist
|
return doclist
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_sales_return(source_name, target_doc=None):
|
def make_sales_return(source_name, target_doc=None):
|
||||||
from erpnext.controllers.sales_and_purchase_return import make_return_doc
|
from erpnext.controllers.sales_and_purchase_return import make_return_doc
|
||||||
|
|||||||
@ -13,6 +13,7 @@ from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
|
|||||||
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
|
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
|
||||||
from frappe.model.naming import make_autoname
|
from frappe.model.naming import make_autoname
|
||||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
||||||
|
from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
|
||||||
|
|
||||||
class TestSalesInvoice(unittest.TestCase):
|
class TestSalesInvoice(unittest.TestCase):
|
||||||
def make(self):
|
def make(self):
|
||||||
@ -1105,10 +1106,75 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
self.assertEquals(d.get(k), expected_values[d.item_code][i])
|
self.assertEquals(d.get(k), expected_values[d.item_code][i])
|
||||||
|
|
||||||
def test_item_wise_tax_breakup(self):
|
def test_item_wise_tax_breakup_india(self):
|
||||||
|
frappe.flags.country = "India"
|
||||||
|
|
||||||
|
si = self.create_si_to_test_tax_breakup()
|
||||||
|
itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(si)
|
||||||
|
|
||||||
|
expected_itemised_tax = {
|
||||||
|
"999800": {
|
||||||
|
"Service Tax": {
|
||||||
|
"tax_rate": 10.0,
|
||||||
|
"tax_amount": 1500.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expected_itemised_taxable_amount = {
|
||||||
|
"999800": 15000.0
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertEqual(itemised_tax, expected_itemised_tax)
|
||||||
|
self.assertEqual(itemised_taxable_amount, expected_itemised_taxable_amount)
|
||||||
|
|
||||||
|
frappe.flags.country = None
|
||||||
|
|
||||||
|
def test_item_wise_tax_breakup_outside_india(self):
|
||||||
|
frappe.flags.country = "United States"
|
||||||
|
|
||||||
|
si = self.create_si_to_test_tax_breakup()
|
||||||
|
|
||||||
|
itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(si)
|
||||||
|
|
||||||
|
expected_itemised_tax = {
|
||||||
|
"_Test Item": {
|
||||||
|
"Service Tax": {
|
||||||
|
"tax_rate": 10.0,
|
||||||
|
"tax_amount": 1000.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"_Test Item 2": {
|
||||||
|
"Service Tax": {
|
||||||
|
"tax_rate": 10.0,
|
||||||
|
"tax_amount": 500.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expected_itemised_taxable_amount = {
|
||||||
|
"_Test Item": 10000.0,
|
||||||
|
"_Test Item 2": 5000.0
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertEqual(itemised_tax, expected_itemised_tax)
|
||||||
|
self.assertEqual(itemised_taxable_amount, expected_itemised_taxable_amount)
|
||||||
|
|
||||||
|
frappe.flags.country = None
|
||||||
|
|
||||||
|
def create_si_to_test_tax_breakup(self):
|
||||||
si = create_sales_invoice(qty=100, rate=50, do_not_save=True)
|
si = create_sales_invoice(qty=100, rate=50, do_not_save=True)
|
||||||
si.append("items", {
|
si.append("items", {
|
||||||
"item_code": "_Test Item",
|
"item_code": "_Test Item",
|
||||||
|
"gst_hsn_code": "999800",
|
||||||
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
|
"qty": 100,
|
||||||
|
"rate": 50,
|
||||||
|
"income_account": "Sales - _TC",
|
||||||
|
"expense_account": "Cost of Goods Sold - _TC",
|
||||||
|
"cost_center": "_Test Cost Center - _TC"
|
||||||
|
})
|
||||||
|
si.append("items", {
|
||||||
|
"item_code": "_Test Item 2",
|
||||||
|
"gst_hsn_code": "999800",
|
||||||
"warehouse": "_Test Warehouse - _TC",
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
"qty": 100,
|
"qty": 100,
|
||||||
"rate": 50,
|
"rate": 50,
|
||||||
@ -1125,11 +1191,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
"rate": 10
|
"rate": 10
|
||||||
})
|
})
|
||||||
si.insert()
|
si.insert()
|
||||||
|
return si
|
||||||
tax_breakup_html = '''\n<div class="tax-break-up" style="overflow-x: auto;">\n\t<table class="table table-bordered table-hover">\n\t\t<thead><tr><th class="text-left" style="min-width: 120px;">Item Name</th><th class="text-right" style="min-width: 80px;">Taxable Amount</th><th class="text-right" style="min-width: 80px;">_Test Account Service Tax - _TC</th></tr></thead>\n\t\t<tbody><tr><td>_Test Item</td><td class="text-right">\u20b9 10,000.00</td><td class="text-right">(10.0%) \u20b9 1,000.00</td></tr></tbody>\n\t</table>\n</div>'''
|
|
||||||
|
|
||||||
self.assertEqual(si.other_charges_calculation, tax_breakup_html)
|
|
||||||
|
|
||||||
|
|
||||||
def create_sales_invoice(**args):
|
def create_sales_invoice(**args):
|
||||||
si = frappe.new_doc("Sales Invoice")
|
si = frappe.new_doc("Sales Invoice")
|
||||||
@ -1150,6 +1212,7 @@ def create_sales_invoice(**args):
|
|||||||
|
|
||||||
si.append("items", {
|
si.append("items", {
|
||||||
"item_code": args.item or args.item_code or "_Test Item",
|
"item_code": args.item or args.item_code or "_Test Item",
|
||||||
|
"gst_hsn_code": "999800",
|
||||||
"warehouse": args.warehouse or "_Test Warehouse - _TC",
|
"warehouse": args.warehouse or "_Test Warehouse - _TC",
|
||||||
"qty": args.qty or 1,
|
"qty": args.qty or 1,
|
||||||
"rate": args.rate or 100,
|
"rate": args.rate or 100,
|
||||||
|
|||||||
@ -1424,7 +1424,7 @@
|
|||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"collapsible_depends_on": "eval:doc.serial_no || doc.batch_no",
|
"collapsible_depends_on": "eval:doc.serial_no || doc.batch_no",
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"depends_on": "eval: parent.update_stock",
|
"depends_on": "",
|
||||||
"fieldname": "warehouse_and_reference",
|
"fieldname": "warehouse_and_reference",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -2166,7 +2166,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-07-06 17:54:03.347700",
|
"modified": "2017-07-17 17:54:48.246507",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice Item",
|
"name": "Sales Invoice Item",
|
||||||
|
|||||||
@ -1398,10 +1398,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
return erpnext.get_currency(this.frm.doc.company);
|
return erpnext.get_currency(this.frm.doc.company);
|
||||||
},
|
},
|
||||||
|
|
||||||
show_item_wise_taxes: function () {
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
show_items_in_item_cart: function () {
|
show_items_in_item_cart: function () {
|
||||||
var me = this;
|
var me = this;
|
||||||
var $items = this.wrapper.find(".items").empty();
|
var $items = this.wrapper.find(".items").empty();
|
||||||
|
|||||||
@ -11,3 +11,6 @@ from erpnext.controllers.print_settings import print_settings_for_item_table
|
|||||||
class PurchaseOrderItem(Document):
|
class PurchaseOrderItem(Document):
|
||||||
def __setup__(self):
|
def __setup__(self):
|
||||||
print_settings_for_item_table(self)
|
print_settings_for_item_table(self)
|
||||||
|
|
||||||
|
def on_doctype_update():
|
||||||
|
frappe.db.add_index("Purchase Order Item", ["item_code", "warehouse"])
|
||||||
@ -160,6 +160,7 @@ class AccountsController(TransactionBase):
|
|||||||
def set_missing_item_details(self, for_validate=False):
|
def set_missing_item_details(self, for_validate=False):
|
||||||
"""set missing item values"""
|
"""set missing item values"""
|
||||||
from erpnext.stock.get_item_details import get_item_details
|
from erpnext.stock.get_item_details import get_item_details
|
||||||
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
|
|
||||||
if hasattr(self, "items"):
|
if hasattr(self, "items"):
|
||||||
parent_dict = {}
|
parent_dict = {}
|
||||||
@ -196,7 +197,7 @@ class AccountsController(TransactionBase):
|
|||||||
|
|
||||||
elif fieldname == "serial_no":
|
elif fieldname == "serial_no":
|
||||||
stock_qty = item.get("stock_qty") * -1 if item.get("stock_qty") < 0 else item.get("stock_qty")
|
stock_qty = item.get("stock_qty") * -1 if item.get("stock_qty") < 0 else item.get("stock_qty")
|
||||||
if stock_qty != len(item.get('serial_no').split('\n')):
|
if stock_qty != len(get_serial_nos(item.get('serial_no'))):
|
||||||
item.set(fieldname, value)
|
item.set(fieldname, value)
|
||||||
|
|
||||||
elif fieldname == "conversion_factor" and not item.get("conversion_factor"):
|
elif fieldname == "conversion_factor" and not item.get("conversion_factor"):
|
||||||
|
|||||||
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import json
|
import json
|
||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
from frappe import _, scrub
|
from frappe import _, scrub
|
||||||
from frappe.utils import cint, flt, cstr, fmt_money, round_based_on_smallest_currency_fraction
|
from frappe.utils import cint, flt, round_based_on_smallest_currency_fraction
|
||||||
from erpnext.controllers.accounts_controller import validate_conversion_rate, \
|
from erpnext.controllers.accounts_controller import validate_conversion_rate, \
|
||||||
validate_taxes_and_charges, validate_inclusive_tax
|
validate_taxes_and_charges, validate_inclusive_tax
|
||||||
|
|
||||||
@ -509,108 +509,72 @@ class calculate_taxes_and_totals(object):
|
|||||||
return rate_with_margin
|
return rate_with_margin
|
||||||
|
|
||||||
def set_item_wise_tax_breakup(self):
|
def set_item_wise_tax_breakup(self):
|
||||||
item_tax = {}
|
if not self.doc.taxes:
|
||||||
tax_accounts = []
|
return
|
||||||
company_currency = erpnext.get_company_currency(self.doc.company)
|
frappe.flags.company = self.doc.company
|
||||||
|
|
||||||
item_tax, tax_accounts = self.get_item_tax(item_tax, tax_accounts, company_currency)
|
# get headers
|
||||||
|
tax_accounts = list(set([d.description for d in self.doc.taxes]))
|
||||||
|
headers = get_itemised_tax_breakup_header(self.doc.doctype + " Item", tax_accounts)
|
||||||
|
|
||||||
headings = get_table_column_headings(tax_accounts)
|
# get tax breakup data
|
||||||
|
itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(self.doc)
|
||||||
|
|
||||||
distinct_items, taxable_amount = self.get_distinct_items()
|
frappe.flags.company = None
|
||||||
|
|
||||||
rows = get_table_rows(distinct_items, item_tax, tax_accounts, company_currency, taxable_amount)
|
self.doc.other_charges_calculation = frappe.render_template(
|
||||||
|
"templates/includes/itemised_tax_breakup.html", dict(
|
||||||
if not rows:
|
headers=headers,
|
||||||
self.doc.other_charges_calculation = ""
|
itemised_tax=itemised_tax,
|
||||||
else:
|
itemised_taxable_amount=itemised_taxable_amount,
|
||||||
self.doc.other_charges_calculation = '''
|
tax_accounts=tax_accounts,
|
||||||
<div class="tax-break-up" style="overflow-x: auto;">
|
company_currency=erpnext.get_company_currency(self.doc.company)
|
||||||
<table class="table table-bordered table-hover">
|
)
|
||||||
<thead><tr>{headings}</tr></thead>
|
)
|
||||||
<tbody>{rows}</tbody>
|
|
||||||
</table>
|
|
||||||
</div>'''.format(**{
|
|
||||||
"headings": "".join(headings),
|
|
||||||
"rows": "".join(rows)
|
|
||||||
})
|
|
||||||
|
|
||||||
def get_item_tax(self, item_tax, tax_accounts, company_currency):
|
@erpnext.allow_regional
|
||||||
for tax in self.doc.taxes:
|
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
|
||||||
tax_amount_precision = tax.precision("tax_amount")
|
return [_("Item"), _("Taxable Amount")] + tax_accounts
|
||||||
tax_rate_precision = tax.precision("rate");
|
|
||||||
|
@erpnext.allow_regional
|
||||||
|
def get_itemised_tax_breakup_data(doc):
|
||||||
|
itemised_tax = get_itemised_tax(doc.taxes)
|
||||||
|
|
||||||
|
itemised_taxable_amount = get_itemised_taxable_amount(doc.items)
|
||||||
|
|
||||||
|
return itemised_tax, itemised_taxable_amount
|
||||||
|
|
||||||
|
def get_itemised_tax(taxes):
|
||||||
|
itemised_tax = {}
|
||||||
|
for tax in taxes:
|
||||||
|
tax_amount_precision = tax.precision("tax_amount")
|
||||||
|
tax_rate_precision = tax.precision("rate")
|
||||||
|
|
||||||
|
item_tax_map = json.loads(tax.item_wise_tax_detail) if tax.item_wise_tax_detail else {}
|
||||||
|
|
||||||
|
for item_code, tax_data in item_tax_map.items():
|
||||||
|
itemised_tax.setdefault(item_code, frappe._dict())
|
||||||
|
|
||||||
item_tax_map = self._load_item_tax_rate(tax.item_wise_tax_detail)
|
if isinstance(tax_data, list) and tax_data[0]:
|
||||||
for item_code, tax_data in item_tax_map.items():
|
precision = tax_amount_precision if tax.charge_type == "Actual" else tax_rate_precision
|
||||||
if not item_tax.get(item_code):
|
|
||||||
item_tax[item_code] = {}
|
|
||||||
|
|
||||||
if isinstance(tax_data, list):
|
|
||||||
tax_rate = ""
|
|
||||||
if tax_data[0]:
|
|
||||||
if tax.charge_type == "Actual":
|
|
||||||
tax_rate = fmt_money(flt(tax_data[0], tax_amount_precision),
|
|
||||||
tax_amount_precision, company_currency)
|
|
||||||
else:
|
|
||||||
tax_rate = cstr(flt(tax_data[0], tax_rate_precision)) + "%"
|
|
||||||
|
|
||||||
tax_amount = fmt_money(flt(tax_data[1], tax_amount_precision),
|
|
||||||
tax_amount_precision, company_currency)
|
|
||||||
|
|
||||||
item_tax[item_code][tax.name] = [tax_rate, tax_amount]
|
|
||||||
else:
|
|
||||||
item_tax[item_code][tax.name] = [cstr(flt(tax_data, tax_rate_precision)) + "%", "0.00"]
|
|
||||||
tax_accounts.append([tax.name, tax.account_head])
|
|
||||||
|
|
||||||
return item_tax, tax_accounts
|
|
||||||
|
|
||||||
|
|
||||||
def get_distinct_items(self):
|
|
||||||
distinct_item_names = []
|
|
||||||
distinct_items = []
|
|
||||||
taxable_amount = {}
|
|
||||||
for item in self.doc.items:
|
|
||||||
item_code = item.item_code or item.item_name
|
|
||||||
if item_code not in distinct_item_names:
|
|
||||||
distinct_item_names.append(item_code)
|
|
||||||
distinct_items.append(item)
|
|
||||||
taxable_amount[item_code] = item.net_amount
|
|
||||||
else:
|
|
||||||
taxable_amount[item_code] = taxable_amount.get(item_code, 0) + item.net_amount
|
|
||||||
|
|
||||||
return distinct_items, taxable_amount
|
itemised_tax[item_code][tax.description] = frappe._dict(dict(
|
||||||
|
tax_rate=flt(tax_data[0], precision),
|
||||||
def get_table_column_headings(tax_accounts):
|
tax_amount=flt(tax_data[1], tax_amount_precision)
|
||||||
headings_name = [_("Item Name"), _("Taxable Amount")] + [d[1] for d in tax_accounts]
|
))
|
||||||
headings = []
|
|
||||||
for head in headings_name:
|
|
||||||
if head == _("Item Name"):
|
|
||||||
headings.append('<th style="min-width: 120px;" class="text-left">' + (head or "") + "</th>")
|
|
||||||
else:
|
|
||||||
headings.append('<th style="min-width: 80px;" class="text-right">' + (head or "") + "</th>")
|
|
||||||
|
|
||||||
return headings
|
|
||||||
|
|
||||||
def get_table_rows(distinct_items, item_tax, tax_accounts, company_currency, taxable_amount):
|
|
||||||
rows = []
|
|
||||||
for item in distinct_items:
|
|
||||||
item_tax_record = item_tax.get(item.item_code or item.item_name)
|
|
||||||
if not item_tax_record:
|
|
||||||
continue
|
|
||||||
|
|
||||||
taxes = []
|
|
||||||
for head in tax_accounts:
|
|
||||||
if item_tax_record[head[0]]:
|
|
||||||
taxes.append("<td class='text-right'>(" + item_tax_record[head[0]][0] + ") "
|
|
||||||
+ item_tax_record[head[0]][1] + "</td>")
|
|
||||||
else:
|
else:
|
||||||
taxes.append("<td></td>")
|
itemised_tax[item_code][tax.description] = frappe._dict(dict(
|
||||||
|
tax_rate=flt(tax_data, tax_rate_precision),
|
||||||
|
tax_amount=0.0
|
||||||
|
))
|
||||||
|
|
||||||
|
return itemised_tax
|
||||||
|
|
||||||
|
def get_itemised_taxable_amount(items):
|
||||||
|
itemised_taxable_amount = frappe._dict()
|
||||||
|
for item in items:
|
||||||
item_code = item.item_code or item.item_name
|
item_code = item.item_code or item.item_name
|
||||||
rows.append("<tr><td>{item_name}</td><td class='text-right'>{taxable_amount}</td>{taxes}</tr>".format(**{
|
itemised_taxable_amount.setdefault(item_code, 0)
|
||||||
"item_name": item.item_name,
|
itemised_taxable_amount[item_code] += item.net_amount
|
||||||
"taxable_amount": fmt_money(taxable_amount.get(item_code, 0), item.precision("net_amount"), company_currency),
|
|
||||||
"taxes": "".join(taxes)
|
return itemised_taxable_amount
|
||||||
}))
|
|
||||||
|
|
||||||
return rows
|
|
||||||
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 215 KiB |
BIN
erpnext/docs/assets/img/sales_goal/sales_goal_notification.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
erpnext/docs/assets/img/sales_goal/sales_history_graph.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
erpnext/docs/assets/img/sales_goal/setting_sales_goal.gif
Normal file
|
After Width: | Height: | Size: 7.8 MiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 38 KiB |
@ -640,8 +640,8 @@ attach them to the start of each source file to most effectively state
|
|||||||
the exclusion of warranty; and each file should have at least the
|
the exclusion of warranty; and each file should have at least the
|
||||||
"copyright" line and a pointer to where the full notice is found.</p>
|
"copyright" line and a pointer to where the full notice is found.</p>
|
||||||
|
|
||||||
<pre><code> <one line to give the program's name and a brief idea of what it does.>
|
<pre><code> <one line="" to="" give="" the="" program's="" name="" and="" a="" brief="" idea="" of="" what="" it="" does.="">
|
||||||
Copyright (C) <year> <name of author>
|
Copyright (C) <year> <name of="" author="">
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@ -15,5 +15,6 @@ third-party-backups
|
|||||||
workflows
|
workflows
|
||||||
bar-code
|
bar-code
|
||||||
company-setup
|
company-setup
|
||||||
|
setting-company-sales-goal
|
||||||
calculate-incentive-for-sales-team
|
calculate-incentive-for-sales-team
|
||||||
articles
|
articles
|
||||||
|
|||||||
@ -0,0 +1,15 @@
|
|||||||
|
# Setting Company Sales Goal
|
||||||
|
|
||||||
|
Monthly sales targets can be set for a company via the Company master. By default, the Company master dashboard features past sales stats.
|
||||||
|
|
||||||
|
<img class="screenshot" alt="Sales Graph" src="{{docs_base_url}}/assets/img/sales_goal/sales_history_graph.png">
|
||||||
|
|
||||||
|
You can set the **Sales Target** field to track progress to track progress with respect to it.
|
||||||
|
|
||||||
|
<img class="screenshot" alt="Setting Sales Goal" src="{{docs_base_url}}/assets/img/sales_goal/setting_sales_goal.gif">
|
||||||
|
|
||||||
|
The target progress is also shown in notifications:
|
||||||
|
|
||||||
|
<img class="screenshot" alt="Sales Notification" src="{{docs_base_url}}/assets/img/sales_goal/sales_goal_notification.png">
|
||||||
|
|
||||||
|
{next}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from . import __version__ as app_version
|
|
||||||
|
|
||||||
app_name = "erpnext"
|
app_name = "erpnext"
|
||||||
app_title = "ERPNext"
|
app_title = "ERPNext"
|
||||||
@ -80,13 +79,7 @@ website_route_rules = [
|
|||||||
"parents": [{"title": _("Supplier Quotation"), "name": "quotations"}]
|
"parents": [{"title": _("Supplier Quotation"), "name": "quotations"}]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{"from_route": "/quotes", "to_route": "Quotation"},
|
{"from_route": "/quotation", "to_route": "Quotation"},
|
||||||
{"from_route": "/quotes/<path:name>", "to_route": "order",
|
|
||||||
"defaults": {
|
|
||||||
"doctype": "Quotation",
|
|
||||||
"parents": [{"title": _("Quotes"), "name": "quotes"}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{"from_route": "/shipments", "to_route": "Delivery Note"},
|
{"from_route": "/shipments", "to_route": "Delivery Note"},
|
||||||
{"from_route": "/shipments/<path:name>", "to_route": "order",
|
{"from_route": "/shipments/<path:name>", "to_route": "order",
|
||||||
"defaults": {
|
"defaults": {
|
||||||
@ -117,7 +110,7 @@ standard_portal_menu_items = [
|
|||||||
{"title": _("Projects"), "route": "/project", "reference_doctype": "Project"},
|
{"title": _("Projects"), "route": "/project", "reference_doctype": "Project"},
|
||||||
{"title": _("Request for Quotations"), "route": "/rfq", "reference_doctype": "Request for Quotation", "role": "Supplier"},
|
{"title": _("Request for Quotations"), "route": "/rfq", "reference_doctype": "Request for Quotation", "role": "Supplier"},
|
||||||
{"title": _("Supplier Quotation"), "route": "/quotations", "reference_doctype": "Supplier Quotation", "role": "Supplier"},
|
{"title": _("Supplier Quotation"), "route": "/quotations", "reference_doctype": "Supplier Quotation", "role": "Supplier"},
|
||||||
{"title": _("Quotes"), "route": "/quotes", "reference_doctype": "Quotation", "role":"Customer"},
|
{"title": _("Quotations"), "route": "/quotation", "reference_doctype": "Quotation", "role":"Customer"},
|
||||||
{"title": _("Orders"), "route": "/orders", "reference_doctype": "Sales Order", "role":"Customer"},
|
{"title": _("Orders"), "route": "/orders", "reference_doctype": "Sales Order", "role":"Customer"},
|
||||||
{"title": _("Invoices"), "route": "/invoices", "reference_doctype": "Sales Invoice", "role":"Customer"},
|
{"title": _("Invoices"), "route": "/invoices", "reference_doctype": "Sales Invoice", "role":"Customer"},
|
||||||
{"title": _("Shipments"), "route": "/shipments", "reference_doctype": "Delivery Note", "role":"Customer"},
|
{"title": _("Shipments"), "route": "/shipments", "reference_doctype": "Delivery Note", "role":"Customer"},
|
||||||
@ -190,10 +183,13 @@ scheduler_events = {
|
|||||||
"erpnext.projects.doctype.task.task.set_tasks_as_overdue",
|
"erpnext.projects.doctype.task.task.set_tasks_as_overdue",
|
||||||
"erpnext.accounts.doctype.asset.depreciation.post_depreciation_entries",
|
"erpnext.accounts.doctype.asset.depreciation.post_depreciation_entries",
|
||||||
"erpnext.hr.doctype.daily_work_summary_settings.daily_work_summary_settings.send_summary",
|
"erpnext.hr.doctype.daily_work_summary_settings.daily_work_summary_settings.send_summary",
|
||||||
"erpnext.stock.doctype.serial_no.serial_no.update_maintenance_status"
|
"erpnext.stock.doctype.serial_no.serial_no.update_maintenance_status",
|
||||||
|
"erpnext.setup.doctype.company.company.cache_companies_monthly_sales_history"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
email_brand_image = "assets/erpnext/images/erpnext-logo.jpg"
|
||||||
|
|
||||||
default_mail_footer = """<div style="text-align: center;">
|
default_mail_footer = """<div style="text-align: center;">
|
||||||
<a href="https://erpnext.com?source=via_email_footer" target="_blank" style="color: #8d99a6;">
|
<a href="https://erpnext.com?source=via_email_footer" target="_blank" style="color: #8d99a6;">
|
||||||
Sent via ERPNext
|
Sent via ERPNext
|
||||||
@ -211,3 +207,11 @@ bot_parsers = [
|
|||||||
get_site_info = 'erpnext.utilities.get_site_info'
|
get_site_info = 'erpnext.utilities.get_site_info'
|
||||||
|
|
||||||
payment_gateway_enabled = "erpnext.accounts.utils.create_payment_gateway_account"
|
payment_gateway_enabled = "erpnext.accounts.utils.create_payment_gateway_account"
|
||||||
|
|
||||||
|
regional_overrides = {
|
||||||
|
'India': {
|
||||||
|
'erpnext.tests.test_regional.test_method': 'erpnext.regional.india.utils.test_method',
|
||||||
|
'erpnext.controllers.taxes_and_totals.get_itemised_tax_breakup_header': 'erpnext.regional.india.utils.get_itemised_tax_breakup_header',
|
||||||
|
'erpnext.controllers.taxes_and_totals.get_itemised_tax_breakup_data': 'erpnext.regional.india.utils.get_itemised_tax_breakup_data'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ from frappe.model.document import Document
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from email_reply_parser import EmailReplyParser
|
from email_reply_parser import EmailReplyParser
|
||||||
from erpnext.hr.doctype.employee.employee import is_holiday
|
from erpnext.hr.doctype.employee.employee import is_holiday
|
||||||
from frappe.utils import formatdate
|
from frappe.utils import global_date_format
|
||||||
from markdown2 import markdown
|
from markdown2 import markdown
|
||||||
|
|
||||||
class DailyWorkSummary(Document):
|
class DailyWorkSummary(Document):
|
||||||
@ -24,17 +24,18 @@ class DailyWorkSummary(Document):
|
|||||||
|
|
||||||
def send_summary(self):
|
def send_summary(self):
|
||||||
'''Send summary of all replies. Called at midnight'''
|
'''Send summary of all replies. Called at midnight'''
|
||||||
message = self.get_summary_message()
|
args = self.get_message_details()
|
||||||
|
|
||||||
frappe.sendmail(recipients = get_employee_emails(self.company, False),
|
frappe.sendmail(recipients = get_employee_emails(self.company, False),
|
||||||
message = message,
|
template='daily_work_summary',
|
||||||
|
args=args,
|
||||||
subject = _('Daily Work Summary for {0}').format(self.company),
|
subject = _('Daily Work Summary for {0}').format(self.company),
|
||||||
reference_doctype=self.doctype, reference_name=self.name)
|
reference_doctype=self.doctype, reference_name=self.name)
|
||||||
|
|
||||||
self.db_set('status', 'Sent')
|
self.db_set('status', 'Sent')
|
||||||
|
|
||||||
def get_summary_message(self):
|
def get_message_details(self):
|
||||||
'''Return summary of replies as HTML'''
|
'''Return args for template'''
|
||||||
settings = frappe.get_doc('Daily Work Summary Settings')
|
settings = frappe.get_doc('Daily Work Summary Settings')
|
||||||
|
|
||||||
replies = frappe.get_all('Communication', fields=['content', 'text_content', 'sender'],
|
replies = frappe.get_all('Communication', fields=['content', 'text_content', 'sender'],
|
||||||
@ -45,8 +46,12 @@ class DailyWorkSummary(Document):
|
|||||||
did_not_reply = self.email_sent_to.split()
|
did_not_reply = self.email_sent_to.split()
|
||||||
|
|
||||||
for d in replies:
|
for d in replies:
|
||||||
d.sender_name = frappe.db.get_value("Employee", {"user_id": d.sender},
|
emp = frappe.db.get_values("Employee", {"user_id": d.sender},
|
||||||
"employee_name") or d.sender
|
["employee_name", "image"], as_dict=True)
|
||||||
|
|
||||||
|
d.sender_name = emp[0].employee_name if emp else d.sender
|
||||||
|
d.image = emp[0].image if emp and emp[0].image else None
|
||||||
|
|
||||||
if d.sender in did_not_reply:
|
if d.sender in did_not_reply:
|
||||||
did_not_reply.remove(d.sender)
|
did_not_reply.remove(d.sender)
|
||||||
if d.text_content:
|
if d.text_content:
|
||||||
@ -56,30 +61,12 @@ class DailyWorkSummary(Document):
|
|||||||
did_not_reply = [(frappe.db.get_value("Employee", {"user_id": email}, "employee_name") or email)
|
did_not_reply = [(frappe.db.get_value("Employee", {"user_id": email}, "employee_name") or email)
|
||||||
for email in did_not_reply]
|
for email in did_not_reply]
|
||||||
|
|
||||||
return frappe.render_template(self.get_summary_template(),
|
return dict(replies=replies,
|
||||||
dict(replies=replies,
|
original_message=settings.message,
|
||||||
original_message=settings.message,
|
title=_('Daily Work Summary for {0}'.format(global_date_format(self.creation))),
|
||||||
title=_('Daily Work Summary for {0}'.format(formatdate(self.creation))),
|
did_not_reply= ', '.join(did_not_reply) or '',
|
||||||
did_not_reply= ', '.join(did_not_reply) or '',
|
did_not_reply_title = _('No replies from'))
|
||||||
did_not_reply_title = _('No replies from')))
|
|
||||||
|
|
||||||
def get_summary_template(self):
|
|
||||||
return '''
|
|
||||||
<h3>{{ title }}</h3>
|
|
||||||
|
|
||||||
{% for reply in replies %}
|
|
||||||
<h4>{{ reply.sender_name }}</h4>
|
|
||||||
<p style="padding-bottom: 20px">
|
|
||||||
{{ reply.content }}
|
|
||||||
</p>
|
|
||||||
<hr>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if did_not_reply %}
|
|
||||||
<p>{{ did_not_reply_title }}: {{ did_not_reply }}</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
def get_employee_emails(company, only_working=True):
|
def get_employee_emails(company, only_working=True):
|
||||||
'''Returns list of Employee user ids for the given company who are working today
|
'''Returns list of Employee user ids for the given company who are working today
|
||||||
|
|||||||
@ -46,9 +46,9 @@ class TestDailyWorkSummary(unittest.TestCase):
|
|||||||
daily_work_summary = frappe.get_doc('Daily Work Summary',
|
daily_work_summary = frappe.get_doc('Daily Work Summary',
|
||||||
frappe.get_all('Daily Work Summary')[0].name)
|
frappe.get_all('Daily Work Summary')[0].name)
|
||||||
|
|
||||||
summary = daily_work_summary.get_summary_message()
|
args = daily_work_summary.get_message_details()
|
||||||
|
|
||||||
self.assertTrue('I built Daily Work Summary!' in summary)
|
self.assertTrue('I built Daily Work Summary!' in args.get('replies')[0].content)
|
||||||
|
|
||||||
def setup_and_prepare_test(self, hour=None):
|
def setup_and_prepare_test(self, hour=None):
|
||||||
frappe.db.sql('delete from `tabDaily Work Summary`')
|
frappe.db.sql('delete from `tabDaily Work Summary`')
|
||||||
|
|||||||
@ -230,7 +230,7 @@ frappe.ui.form.on("Expense Claim",{
|
|||||||
frm.fields_dict["payable_account"].get_query = function() {
|
frm.fields_dict["payable_account"].get_query = function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
"root_type": "Liability",
|
"report_type": "Balance Sheet",
|
||||||
"account_type": "Payable"
|
"account_type": "Payable"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -905,7 +905,7 @@
|
|||||||
"label": "Status",
|
"label": "Status",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Draft\nPaid\nUnpaid\nSubmitted\nCancelled",
|
"options": "Draft\nPaid\nUnpaid\nRejected\nSubmitted\nCancelled",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
@ -964,7 +964,7 @@
|
|||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"menu_index": 0,
|
"menu_index": 0,
|
||||||
"modified": "2017-06-13 14:29:16.914609",
|
"modified": "2017-07-17 15:47:23.255142",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Expense Claim",
|
"name": "Expense Claim",
|
||||||
|
|||||||
@ -39,10 +39,13 @@ class ExpenseClaim(AccountsController):
|
|||||||
"2": "Cancelled"
|
"2": "Cancelled"
|
||||||
}[cstr(self.docstatus or 0)]
|
}[cstr(self.docstatus or 0)]
|
||||||
|
|
||||||
if self.total_sanctioned_amount == self.total_amount_reimbursed and self.docstatus == 1:
|
if self.total_sanctioned_amount > 0 and self.total_sanctioned_amount == self.total_amount_reimbursed \
|
||||||
|
and self.docstatus == 1 and self.approval_status == 'Approved':
|
||||||
self.status = "Paid"
|
self.status = "Paid"
|
||||||
elif self.docstatus == 1:
|
elif self.total_sanctioned_amount > 0 and self.docstatus == 1 and self.approval_status == 'Approved':
|
||||||
self.status = "Unpaid"
|
self.status = "Unpaid"
|
||||||
|
elif self.docstatus == 1 and self.approval_status == 'Rejected':
|
||||||
|
self.status = 'Rejected'
|
||||||
|
|
||||||
def set_payable_account(self):
|
def set_payable_account(self):
|
||||||
if not self.payable_account and not self.is_paid:
|
if not self.payable_account and not self.is_paid:
|
||||||
@ -157,6 +160,9 @@ class ExpenseClaim(AccountsController):
|
|||||||
self.total_claimed_amount = 0
|
self.total_claimed_amount = 0
|
||||||
self.total_sanctioned_amount = 0
|
self.total_sanctioned_amount = 0
|
||||||
for d in self.get('expenses'):
|
for d in self.get('expenses'):
|
||||||
|
if self.approval_status == 'Rejected':
|
||||||
|
d.sanctioned_amount = 0.0
|
||||||
|
|
||||||
self.total_claimed_amount += flt(d.claim_amount)
|
self.total_claimed_amount += flt(d.claim_amount)
|
||||||
self.total_sanctioned_amount += flt(d.sanctioned_amount)
|
self.total_sanctioned_amount += flt(d.sanctioned_amount)
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,10 @@ frappe.listview_settings['Expense Claim'] = {
|
|||||||
get_indicator: function(doc) {
|
get_indicator: function(doc) {
|
||||||
if(doc.status == "Paid") {
|
if(doc.status == "Paid") {
|
||||||
return [__("Paid"), "green", "status,=,'Paid'"];
|
return [__("Paid"), "green", "status,=,'Paid'"];
|
||||||
} else {
|
}else if(doc.status == "Unpaid") {
|
||||||
return [__("Unpaid"), "orange"];
|
return [__("Unpaid"), "orange"];
|
||||||
|
} else if(doc.status == "Rejected") {
|
||||||
|
return [__("Rejected"), "grey"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -113,5 +113,23 @@ class TestExpenseClaim(unittest.TestCase):
|
|||||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
||||||
|
|
||||||
|
def test_rejected_expense_claim(self):
|
||||||
|
payable_account = get_payable_account("Wind Power LLC")
|
||||||
|
expense_claim = frappe.get_doc({
|
||||||
|
"doctype": "Expense Claim",
|
||||||
|
"employee": "_T-Employee-0001",
|
||||||
|
"payable_account": payable_account,
|
||||||
|
"approval_status": "Rejected",
|
||||||
|
"expenses":
|
||||||
|
[{ "expense_type": "Travel", "default_account": "Travel Expenses - WP", "claim_amount": 300, "sanctioned_amount": 200 }]
|
||||||
|
})
|
||||||
|
expense_claim.submit()
|
||||||
|
|
||||||
|
self.assertEquals(expense_claim.status, 'Rejected')
|
||||||
|
self.assertEquals(expense_claim.total_sanctioned_amount, 0.0)
|
||||||
|
|
||||||
|
gl_entry = frappe.get_all('GL Entry', {'voucher_type': 'Expense Claim', 'voucher_no': expense_claim.name})
|
||||||
|
self.assertEquals(len(gl_entry), 0)
|
||||||
|
|
||||||
def get_payable_account(company):
|
def get_payable_account(company):
|
||||||
return frappe.db.get_value('Company', company, 'default_payable_account')
|
return frappe.db.get_value('Company', company, 'default_payable_account')
|
||||||
|
|||||||
@ -69,27 +69,17 @@ def get_events(start, end, filters=None):
|
|||||||
:param end: End date-time.
|
:param end: End date-time.
|
||||||
:param filters: Filters (JSON).
|
:param filters: Filters (JSON).
|
||||||
"""
|
"""
|
||||||
condition = ''
|
|
||||||
values = {
|
|
||||||
"start_date": getdate(start),
|
|
||||||
"end_date": getdate(end)
|
|
||||||
}
|
|
||||||
|
|
||||||
if filters:
|
if filters:
|
||||||
if isinstance(filters, basestring):
|
filters = json.loads(filters)
|
||||||
filters = json.loads(filters)
|
else:
|
||||||
|
filters = []
|
||||||
|
|
||||||
if filters.get('holiday_list'):
|
if start:
|
||||||
condition = 'and hlist.name=%(holiday_list)s'
|
filters.append(['Holiday', 'holiday_date', '>', getdate(start)])
|
||||||
values['holiday_list'] = filters['holiday_list']
|
if end:
|
||||||
|
filters.append(['Holiday', 'holiday_date', '<', getdate(end)])
|
||||||
|
|
||||||
data = frappe.db.sql("""select hlist.name, h.holiday_date, h.description
|
return frappe.get_list('Holiday List',
|
||||||
from `tabHoliday List` hlist, tabHoliday h
|
fields=['name', '`tabHoliday`.holiday_date', '`tabHoliday`.description'],
|
||||||
where h.parent = hlist.name
|
filters = filters,
|
||||||
and h.holiday_date is not null
|
update={"allDay": 1})
|
||||||
and h.holiday_date >= %(start_date)s
|
|
||||||
and h.holiday_date <= %(end_date)s
|
|
||||||
{condition}""".format(condition=condition),
|
|
||||||
values, as_dict=True, update={"allDay": 1})
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|||||||
@ -63,13 +63,13 @@ class LeaveApplication(Document):
|
|||||||
def validate_dates(self):
|
def validate_dates(self):
|
||||||
if self.from_date and self.to_date and (getdate(self.to_date) < getdate(self.from_date)):
|
if self.from_date and self.to_date and (getdate(self.to_date) < getdate(self.from_date)):
|
||||||
frappe.throw(_("To date cannot be before from date"))
|
frappe.throw(_("To date cannot be before from date"))
|
||||||
|
|
||||||
if self.half_day and self.half_day_date \
|
if self.half_day and self.half_day_date \
|
||||||
and (getdate(self.half_day_date) < getdate(self.from_date)
|
and (getdate(self.half_day_date) < getdate(self.from_date)
|
||||||
or getdate(self.half_day_date) > getdate(self.to_date)):
|
or getdate(self.half_day_date) > getdate(self.to_date)):
|
||||||
|
|
||||||
frappe.throw(_("Half Day Date should be between From Date and To Date"))
|
frappe.throw(_("Half Day Date should be between From Date and To Date"))
|
||||||
|
|
||||||
if not is_lwp(self.leave_type):
|
if not is_lwp(self.leave_type):
|
||||||
self.validate_dates_acorss_allocation()
|
self.validate_dates_acorss_allocation()
|
||||||
self.validate_back_dated_application()
|
self.validate_back_dated_application()
|
||||||
@ -158,7 +158,7 @@ class LeaveApplication(Document):
|
|||||||
self.name = "New Leave Application"
|
self.name = "New Leave Application"
|
||||||
|
|
||||||
for d in frappe.db.sql("""
|
for d in frappe.db.sql("""
|
||||||
select
|
select
|
||||||
name, leave_type, posting_date, from_date, to_date, total_leave_days, half_day_date
|
name, leave_type, posting_date, from_date, to_date, total_leave_days, half_day_date
|
||||||
from `tabLeave Application`
|
from `tabLeave Application`
|
||||||
where employee = %(employee)s and docstatus < 2 and status in ("Open", "Approved")
|
where employee = %(employee)s and docstatus < 2 and status in ("Open", "Approved")
|
||||||
@ -169,12 +169,12 @@ class LeaveApplication(Document):
|
|||||||
"to_date": self.to_date,
|
"to_date": self.to_date,
|
||||||
"name": self.name
|
"name": self.name
|
||||||
}, as_dict = 1):
|
}, as_dict = 1):
|
||||||
|
|
||||||
if cint(self.half_day)==1 and getdate(self.half_day_date) == getdate(d.half_day_date) and (
|
if cint(self.half_day)==1 and getdate(self.half_day_date) == getdate(d.half_day_date) and (
|
||||||
flt(self.total_leave_days)==0.5
|
flt(self.total_leave_days)==0.5
|
||||||
or getdate(self.from_date) == getdate(d.to_date)
|
or getdate(self.from_date) == getdate(d.to_date)
|
||||||
or getdate(self.to_date) == getdate(d.from_date)):
|
or getdate(self.to_date) == getdate(d.from_date)):
|
||||||
|
|
||||||
total_leaves_on_half_day = self.get_total_leaves_on_half_day()
|
total_leaves_on_half_day = self.get_total_leaves_on_half_day()
|
||||||
if total_leaves_on_half_day >= 1:
|
if total_leaves_on_half_day >= 1:
|
||||||
self.throw_overlap_error(d)
|
self.throw_overlap_error(d)
|
||||||
@ -199,7 +199,7 @@ class LeaveApplication(Document):
|
|||||||
"half_day_date": self.half_day_date,
|
"half_day_date": self.half_day_date,
|
||||||
"name": self.name
|
"name": self.name
|
||||||
})[0][0]
|
})[0][0]
|
||||||
|
|
||||||
return leave_count_on_half_day_date * 0.5
|
return leave_count_on_half_day_date * 0.5
|
||||||
|
|
||||||
def validate_max_days(self):
|
def validate_max_days(self):
|
||||||
@ -400,7 +400,7 @@ def is_lwp(leave_type):
|
|||||||
return lwp and cint(lwp[0][0]) or 0
|
return lwp and cint(lwp[0][0]) or 0
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_events(start, end):
|
def get_events(start, end, filters=None):
|
||||||
events = []
|
events = []
|
||||||
|
|
||||||
employee = frappe.db.get_value("Employee", {"user_id": frappe.session.user}, ["name", "company"],
|
employee = frappe.db.get_value("Employee", {"user_id": frappe.session.user}, ["name", "company"],
|
||||||
@ -411,14 +411,14 @@ def get_events(start, end):
|
|||||||
employee=''
|
employee=''
|
||||||
company=frappe.db.get_value("Global Defaults", None, "default_company")
|
company=frappe.db.get_value("Global Defaults", None, "default_company")
|
||||||
|
|
||||||
from frappe.desk.reportview import build_match_conditions
|
from frappe.desk.reportview import get_filters_cond
|
||||||
match_conditions = build_match_conditions("Leave Application")
|
conditions = get_filters_cond("Leave Application")
|
||||||
|
|
||||||
# show department leaves for employee
|
# show department leaves for employee
|
||||||
if "Employee" in frappe.get_roles():
|
if "Employee" in frappe.get_roles():
|
||||||
add_department_leaves(events, start, end, employee, company)
|
add_department_leaves(events, start, end, employee, company)
|
||||||
|
|
||||||
add_leaves(events, start, end, match_conditions)
|
add_leaves(events, start, end, conditions)
|
||||||
|
|
||||||
add_block_dates(events, start, end, employee, company)
|
add_block_dates(events, start, end, employee, company)
|
||||||
add_holidays(events, start, end, employee, company)
|
add_holidays(events, start, end, employee, company)
|
||||||
|
|||||||
@ -8,3 +8,6 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
class ProductionOrderItem(Document):
|
class ProductionOrderItem(Document):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def on_doctype_update():
|
||||||
|
frappe.db.add_index("Production Order Item", ["item_code", "source_warehouse"])
|
||||||
@ -416,4 +416,9 @@ erpnext.patches.v8_0.update_production_orders
|
|||||||
erpnext.patches.v8_1.remove_sales_invoice_from_returned_serial_no
|
erpnext.patches.v8_1.remove_sales_invoice_from_returned_serial_no
|
||||||
erpnext.patches.v8_1.allow_invoice_copy_to_edit_after_submit
|
erpnext.patches.v8_1.allow_invoice_copy_to_edit_after_submit
|
||||||
erpnext.patches.v8_1.add_hsn_sac_codes
|
erpnext.patches.v8_1.add_hsn_sac_codes
|
||||||
erpnext.patches.v8_1.update_gst_state
|
erpnext.patches.v8_1.update_gst_state #17-07-2017
|
||||||
|
erpnext.patches.v8_1.removed_report_support_hours
|
||||||
|
erpnext.patches.v8_1.add_indexes_in_transaction_doctypes
|
||||||
|
erpnext.patches.v8_3.set_restrict_to_domain_for_module_def
|
||||||
|
erpnext.patches.v8_1.update_expense_claim_status
|
||||||
|
erpnext.patches.v8_3.update_company_total_sales
|
||||||
@ -11,6 +11,9 @@ def execute():
|
|||||||
for dt in ("assessment", "course", "fees"):
|
for dt in ("assessment", "course", "fees"):
|
||||||
frappe.reload_doc("schools", "doctype", dt)
|
frappe.reload_doc("schools", "doctype", dt)
|
||||||
|
|
||||||
|
for dt in ("domain", "has_domain", "domain_settings"):
|
||||||
|
frappe.reload_doc("core", "doctype", dt)
|
||||||
|
|
||||||
frappe.reload_doc('website', 'doctype', 'portal_menu_item')
|
frappe.reload_doc('website', 'doctype', 'portal_menu_item')
|
||||||
|
|
||||||
frappe.get_doc('Portal Settings').sync_menu()
|
frappe.get_doc('Portal Settings').sync_menu()
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
for dt in ("Sales Order Item", "Purchase Order Item",
|
||||||
|
"Material Request Item", "Production Order Item", "Packed Item"):
|
||||||
|
frappe.get_doc("DocType", dt).run_module_method("on_doctype_update")
|
||||||
14
erpnext/patches/v8_1/removed_report_support_hours.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Copyright (c) 2017, Frappe and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.db.sql(""" update `tabAuto Email Report` set report = %s
|
||||||
|
where name = %s""", ('Support Hour Distribution', 'Support Hours'))
|
||||||
|
|
||||||
|
frappe.db.sql(""" update `tabCustom Role` set report = %s
|
||||||
|
where report = %s""", ('Support Hour Distribution', 'Support Hours'))
|
||||||
|
|
||||||
|
frappe.delete_doc('Report', 'Support Hours')
|
||||||
23
erpnext/patches/v8_1/update_expense_claim_status.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Copyright (c) 2017, Frappe and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doctype('Expense Claim')
|
||||||
|
|
||||||
|
for data in frappe.db.sql(""" select name from `tabExpense Claim`
|
||||||
|
where (docstatus=1 and total_sanctioned_amount=0 and status = 'Paid') or
|
||||||
|
(docstatus = 1 and approval_status = 'Rejected' and total_sanctioned_amount > 0)""", as_dict=1):
|
||||||
|
doc = frappe.get_doc('Expense Claim', data.name)
|
||||||
|
if doc.approval_status == 'Rejected':
|
||||||
|
for d in doc.expenses:
|
||||||
|
d.db_set("sanctioned_amount", 0, update_modified = False)
|
||||||
|
doc.db_set("total_sanctioned_amount", 0, update_modified = False)
|
||||||
|
|
||||||
|
frappe.db.sql(""" delete from `tabGL Entry` where voucher_type = 'Expense Claim'
|
||||||
|
and voucher_no = %s""", (doc.name))
|
||||||
|
|
||||||
|
doc.set_status()
|
||||||
|
doc.db_set("status", doc.status, update_modified = False)
|
||||||
@ -11,3 +11,4 @@ def execute():
|
|||||||
|
|
||||||
frappe.db.sql("update `tabCustom Field` set options=%s where fieldname='gst_state'", '\n'.join(states))
|
frappe.db.sql("update `tabCustom Field` set options=%s where fieldname='gst_state'", '\n'.join(states))
|
||||||
frappe.db.sql("update `tabAddress` set gst_state='Chhattisgarh' where gst_state='Chattisgarh'")
|
frappe.db.sql("update `tabAddress` set gst_state='Chhattisgarh' where gst_state='Chattisgarh'")
|
||||||
|
frappe.db.sql("update `tabAddress` set gst_state_number='05' where gst_state='Uttarakhand'")
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
# Copyright (c) 2017, Frappe and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
from erpnext.setup.setup_wizard.domainify import update_module_def_restrict_to_domain
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
""" set the restrict to domain in module def """
|
||||||
|
|
||||||
|
frappe.reload_doc("core", "doctype", "module_def")
|
||||||
|
update_module_def_restrict_to_domain()
|
||||||
15
erpnext/patches/v8_3/update_company_total_sales.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright (c) 2017, Frappe and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from erpnext.setup.doctype.company.company import update_company_current_month_sales, update_company_monthly_sales
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
'''Update company monthly sales history based on sales invoices'''
|
||||||
|
frappe.reload_doctype("Company")
|
||||||
|
companies = [d['name'] for d in frappe.get_list("Company")]
|
||||||
|
|
||||||
|
for company in companies:
|
||||||
|
update_company_current_month_sales(company)
|
||||||
|
update_company_monthly_sales(company)
|
||||||
@ -9,9 +9,8 @@ from frappe import _
|
|||||||
import json
|
import json
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from erpnext.controllers.queries import get_match_cond
|
from erpnext.controllers.queries import get_match_cond
|
||||||
from frappe.utils import flt, time_diff_in_hours, get_datetime, getdate, cint, get_datetime_str
|
from frappe.utils import flt, time_diff_in_hours, get_datetime, getdate, cint
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.model.mapper import get_mapped_doc
|
|
||||||
from erpnext.manufacturing.doctype.workstation.workstation import (check_if_within_operating_hours,
|
from erpnext.manufacturing.doctype.workstation.workstation import (check_if_within_operating_hours,
|
||||||
WorkstationHolidayError)
|
WorkstationHolidayError)
|
||||||
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
|
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
|
||||||
@ -133,7 +132,7 @@ class Timesheet(Document):
|
|||||||
if data.name == timesheet.operation_id:
|
if data.name == timesheet.operation_id:
|
||||||
summary = self.get_actual_timesheet_summary(timesheet.operation_id)
|
summary = self.get_actual_timesheet_summary(timesheet.operation_id)
|
||||||
data.time_sheet = time_sheet
|
data.time_sheet = time_sheet
|
||||||
data.completed_qty = summary.completed_qty
|
data.completed_qty = summary.completed_qty
|
||||||
data.actual_operation_time = summary.mins
|
data.actual_operation_time = summary.mins
|
||||||
data.actual_start_time = summary.from_time
|
data.actual_start_time = summary.from_time
|
||||||
data.actual_end_time = summary.to_time
|
data.actual_end_time = summary.to_time
|
||||||
@ -148,7 +147,7 @@ class Timesheet(Document):
|
|||||||
"""Returns 'Actual Operating Time'. """
|
"""Returns 'Actual Operating Time'. """
|
||||||
return frappe.db.sql("""select
|
return frappe.db.sql("""select
|
||||||
sum(tsd.hours*60) as mins, sum(tsd.completed_qty) as completed_qty, min(tsd.from_time) as from_time,
|
sum(tsd.hours*60) as mins, sum(tsd.completed_qty) as completed_qty, min(tsd.from_time) as from_time,
|
||||||
max(tsd.to_time) as to_time from `tabTimesheet Detail` as tsd, `tabTimesheet` as ts where
|
max(tsd.to_time) as to_time from `tabTimesheet Detail` as tsd, `tabTimesheet` as ts where
|
||||||
ts.production_order = %s and tsd.operation_id = %s and ts.docstatus=1 and ts.name = tsd.parent""",
|
ts.production_order = %s and tsd.operation_id = %s and ts.docstatus=1 and ts.name = tsd.parent""",
|
||||||
(self.production_order, operation_id), as_dict=1)[0]
|
(self.production_order, operation_id), as_dict=1)[0]
|
||||||
|
|
||||||
@ -192,7 +191,7 @@ class Timesheet(Document):
|
|||||||
if fieldname == 'workstation':
|
if fieldname == 'workstation':
|
||||||
cond = "tsd.`{0}`".format(fieldname)
|
cond = "tsd.`{0}`".format(fieldname)
|
||||||
|
|
||||||
existing = frappe.db.sql("""select ts.name as name, tsd.from_time as from_time, tsd.to_time as to_time from
|
existing = frappe.db.sql("""select ts.name as name, tsd.from_time as from_time, tsd.to_time as to_time from
|
||||||
`tabTimesheet Detail` tsd, `tabTimesheet` ts where {0}=%(val)s and tsd.parent = ts.name and
|
`tabTimesheet Detail` tsd, `tabTimesheet` ts where {0}=%(val)s and tsd.parent = ts.name and
|
||||||
(
|
(
|
||||||
(%(from_time)s > tsd.from_time and %(from_time)s < tsd.to_time) or
|
(%(from_time)s > tsd.from_time and %(from_time)s < tsd.to_time) or
|
||||||
@ -211,8 +210,8 @@ class Timesheet(Document):
|
|||||||
# check internal overlap
|
# check internal overlap
|
||||||
for time_log in self.time_logs:
|
for time_log in self.time_logs:
|
||||||
if (fieldname != 'workstation' or args.get(fieldname) == time_log.get(fieldname)) and \
|
if (fieldname != 'workstation' or args.get(fieldname) == time_log.get(fieldname)) and \
|
||||||
args.idx != time_log.idx and ((args.from_time > time_log.from_time and args.from_time < time_log.to_time) or
|
args.idx != time_log.idx and ((args.from_time > time_log.from_time and args.from_time < time_log.to_time) or
|
||||||
(args.to_time > time_log.from_time and args.to_time < time_log.to_time) or
|
(args.to_time > time_log.from_time and args.to_time < time_log.to_time) or
|
||||||
(args.from_time <= time_log.from_time and args.to_time >= time_log.to_time)):
|
(args.from_time <= time_log.from_time and args.to_time >= time_log.to_time)):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@ -239,7 +238,7 @@ class Timesheet(Document):
|
|||||||
self.check_workstation_working_day(data)
|
self.check_workstation_working_day(data)
|
||||||
|
|
||||||
def get_last_working_slot(self, time_sheet, workstation):
|
def get_last_working_slot(self, time_sheet, workstation):
|
||||||
return frappe.db.sql(""" select max(from_time) as from_time, max(to_time) as to_time
|
return frappe.db.sql(""" select max(from_time) as from_time, max(to_time) as to_time
|
||||||
from `tabTimesheet Detail` where workstation = %(workstation)s""",
|
from `tabTimesheet Detail` where workstation = %(workstation)s""",
|
||||||
{'workstation': workstation}, as_dict=True)[0]
|
{'workstation': workstation}, as_dict=True)[0]
|
||||||
|
|
||||||
@ -277,7 +276,7 @@ def get_projectwise_timesheet_data(project, parent=None):
|
|||||||
if parent:
|
if parent:
|
||||||
cond = "and parent = %(parent)s"
|
cond = "and parent = %(parent)s"
|
||||||
|
|
||||||
return frappe.db.sql("""select name, parent, billing_hours, billing_amount as billing_amt
|
return frappe.db.sql("""select name, parent, billing_hours, billing_amount as billing_amt
|
||||||
from `tabTimesheet Detail` where docstatus=1 and project = %(project)s {0} and billable = 1
|
from `tabTimesheet Detail` where docstatus=1 and project = %(project)s {0} and billable = 1
|
||||||
and sales_invoice is null""".format(cond), {'project': project, 'parent': parent}, as_dict=1)
|
and sales_invoice is null""".format(cond), {'project': project, 'parent': parent}, as_dict=1)
|
||||||
|
|
||||||
@ -290,9 +289,9 @@ def get_timesheet(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
condition = "and tsd.project = %(project)s"
|
condition = "and tsd.project = %(project)s"
|
||||||
|
|
||||||
return frappe.db.sql("""select distinct tsd.parent from `tabTimesheet Detail` tsd,
|
return frappe.db.sql("""select distinct tsd.parent from `tabTimesheet Detail` tsd,
|
||||||
`tabTimesheet` ts where
|
`tabTimesheet` ts where
|
||||||
ts.status in ('Submitted', 'Payslip') and tsd.parent = ts.name and
|
ts.status in ('Submitted', 'Payslip') and tsd.parent = ts.name and
|
||||||
tsd.docstatus = 1 and ts.total_billable_amount > 0
|
tsd.docstatus = 1 and ts.total_billable_amount > 0
|
||||||
and tsd.parent LIKE %(txt)s {condition}
|
and tsd.parent LIKE %(txt)s {condition}
|
||||||
order by tsd.parent limit %(start)s, %(page_len)s"""
|
order by tsd.parent limit %(start)s, %(page_len)s"""
|
||||||
.format(condition=condition), {
|
.format(condition=condition), {
|
||||||
@ -305,7 +304,7 @@ def get_timesheet_data(name, project):
|
|||||||
if project and project!='':
|
if project and project!='':
|
||||||
data = get_projectwise_timesheet_data(project, name)
|
data = get_projectwise_timesheet_data(project, name)
|
||||||
else:
|
else:
|
||||||
data = frappe.get_all('Timesheet',
|
data = frappe.get_all('Timesheet',
|
||||||
fields = ["(total_billable_amount - total_billed_amount) as billing_amt", "total_billable_hours as billing_hours"], filters = {'name': name})
|
fields = ["(total_billable_amount - total_billed_amount) as billing_amt", "total_billable_hours as billing_hours"], filters = {'name': name})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -332,7 +331,7 @@ def make_sales_invoice(source_name, target=None):
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_salary_slip(source_name, target_doc=None):
|
def make_salary_slip(source_name, target_doc=None):
|
||||||
target = frappe.new_doc("Salary Slip")
|
target = frappe.new_doc("Salary Slip")
|
||||||
set_missing_values(source_name, target)
|
set_missing_values(source_name, target)
|
||||||
target.run_method("get_emp_and_leave_details")
|
target.run_method("get_emp_and_leave_details")
|
||||||
|
|
||||||
return target
|
return target
|
||||||
@ -364,32 +363,21 @@ def get_events(start, end, filters=None):
|
|||||||
:param filters: Filters (JSON).
|
:param filters: Filters (JSON).
|
||||||
"""
|
"""
|
||||||
filters = json.loads(filters)
|
filters = json.loads(filters)
|
||||||
|
from frappe.desk.calendar import get_event_conditions
|
||||||
|
conditions = get_event_conditions("Timesheet", filters)
|
||||||
|
|
||||||
conditions = get_conditions(filters)
|
return frappe.db.sql("""select `tabTimesheet Detail`.name as name,
|
||||||
return frappe.db.sql("""select `tabTimesheet Detail`.name as name,
|
|
||||||
`tabTimesheet Detail`.docstatus as status, `tabTimesheet Detail`.parent as parent,
|
`tabTimesheet Detail`.docstatus as status, `tabTimesheet Detail`.parent as parent,
|
||||||
from_time as start_date, hours, activity_type,
|
from_time as start_date, hours, activity_type,
|
||||||
`tabTimesheet Detail`.project, to_time as end_date,
|
`tabTimesheet Detail`.project, to_time as end_date,
|
||||||
CONCAT(`tabTimesheet Detail`.parent, ' (', ROUND(hours,2),' hrs)') as title
|
CONCAT(`tabTimesheet Detail`.parent, ' (', ROUND(hours,2),' hrs)') as title
|
||||||
from `tabTimesheet Detail`, `tabTimesheet`
|
from `tabTimesheet Detail`, `tabTimesheet`
|
||||||
where `tabTimesheet Detail`.parent = `tabTimesheet`.name
|
where `tabTimesheet Detail`.parent = `tabTimesheet`.name
|
||||||
and `tabTimesheet`.docstatus < 2
|
and `tabTimesheet`.docstatus < 2
|
||||||
and (from_time <= %(end)s and to_time >= %(start)s) {conditions} {match_cond}
|
and (from_time <= %(end)s and to_time >= %(start)s) {conditions} {match_cond}
|
||||||
""".format(conditions=conditions, match_cond = get_match_cond('Timesheet')),
|
""".format(conditions=conditions, match_cond = get_match_cond('Timesheet')),
|
||||||
{
|
{
|
||||||
"start": start,
|
"start": start,
|
||||||
"end": end
|
"end": end
|
||||||
}, as_dict=True, update={"allDay": 0})
|
}, as_dict=True, update={"allDay": 0})
|
||||||
|
|
||||||
def get_conditions(filters):
|
|
||||||
conditions = []
|
|
||||||
for key in filters:
|
|
||||||
if filters.get(key):
|
|
||||||
if frappe.get_meta("Timesheet").has_field(key):
|
|
||||||
dt = 'tabTimesheet'
|
|
||||||
elif frappe.get_meta("Timesheet Detail").has_field(key):
|
|
||||||
dt = 'tabTimesheet Detail'
|
|
||||||
|
|
||||||
conditions.append("`%s`.%s = '%s'"%(dt, key, filters.get(key)))
|
|
||||||
|
|
||||||
return " and {}".format(" and ".join(conditions)) if conditions else ""
|
|
||||||
|
|||||||
@ -54,7 +54,6 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
|||||||
this.manipulate_grand_total_for_inclusive_tax();
|
this.manipulate_grand_total_for_inclusive_tax();
|
||||||
this.calculate_totals();
|
this.calculate_totals();
|
||||||
this._cleanup();
|
this._cleanup();
|
||||||
this.show_item_wise_taxes();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
validate_conversion_rate: function() {
|
validate_conversion_rate: function() {
|
||||||
@ -634,99 +633,5 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.calculate_outstanding_amount(false)
|
this.calculate_outstanding_amount(false)
|
||||||
},
|
|
||||||
|
|
||||||
show_item_wise_taxes: function() {
|
|
||||||
if(this.frm.fields_dict.other_charges_calculation) {
|
|
||||||
this.frm.toggle_display("other_charges_calculation", this.frm.doc.other_charges_calculation);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
set_item_wise_tax_breakup: function() {
|
|
||||||
if(this.frm.fields_dict.other_charges_calculation) {
|
|
||||||
var html = this.get_item_wise_taxes_html();
|
|
||||||
// console.log(html);
|
|
||||||
this.frm.set_value("other_charges_calculation", html);
|
|
||||||
this.show_item_wise_taxes();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
get_item_wise_taxes_html: function() {
|
|
||||||
var item_tax = {};
|
|
||||||
var tax_accounts = [];
|
|
||||||
var company_currency = this.get_company_currency();
|
|
||||||
|
|
||||||
$.each(this.frm.doc["taxes"] || [], function(i, tax) {
|
|
||||||
var tax_amount_precision = precision("tax_amount", tax);
|
|
||||||
var tax_rate_precision = precision("rate", tax);
|
|
||||||
$.each(JSON.parse(tax.item_wise_tax_detail || '{}'),
|
|
||||||
function(item_code, tax_data) {
|
|
||||||
if(!item_tax[item_code]) item_tax[item_code] = {};
|
|
||||||
if($.isArray(tax_data)) {
|
|
||||||
var tax_rate = "";
|
|
||||||
if(tax_data[0] != null) {
|
|
||||||
tax_rate = (tax.charge_type === "Actual") ?
|
|
||||||
format_currency(flt(tax_data[0], tax_amount_precision),
|
|
||||||
company_currency, tax_amount_precision) :
|
|
||||||
(flt(tax_data[0], tax_rate_precision) + "%");
|
|
||||||
}
|
|
||||||
var tax_amount = format_currency(flt(tax_data[1], tax_amount_precision),
|
|
||||||
company_currency, tax_amount_precision);
|
|
||||||
|
|
||||||
item_tax[item_code][tax.name] = [tax_rate, tax_amount];
|
|
||||||
} else {
|
|
||||||
item_tax[item_code][tax.name] = [flt(tax_data, tax_rate_precision) + "%", "0.00"];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
tax_accounts.push([tax.name, tax.account_head]);
|
|
||||||
});
|
|
||||||
|
|
||||||
var headings = $.map([__("Item Name"), __("Taxable Amount")].concat($.map(tax_accounts,
|
|
||||||
function(head) { return head[1]; })), function(head) {
|
|
||||||
if(head==__("Item Name")) {
|
|
||||||
return '<th style="min-width: 100px;" class="text-left">' + (head || "") + "</th>";
|
|
||||||
} else {
|
|
||||||
return '<th style="min-width: 80px;" class="text-right">' + (head || "") + "</th>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
).join("");
|
|
||||||
|
|
||||||
var distinct_item_names = [];
|
|
||||||
var distinct_items = [];
|
|
||||||
var taxable_amount = {};
|
|
||||||
$.each(this.frm.doc["items"] || [], function(i, item) {
|
|
||||||
var item_code = item.item_code || item.item_name;
|
|
||||||
if(distinct_item_names.indexOf(item_code)===-1) {
|
|
||||||
distinct_item_names.push(item_code);
|
|
||||||
distinct_items.push(item);
|
|
||||||
taxable_amount[item_code] = item.net_amount;
|
|
||||||
} else {
|
|
||||||
taxable_amount[item_code] = taxable_amount[item_code] + item.net_amount;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var rows = $.map(distinct_items, function(item) {
|
|
||||||
var item_code = item.item_code || item.item_name;
|
|
||||||
var item_tax_record = item_tax[item_code];
|
|
||||||
if(!item_tax_record) { return null; }
|
|
||||||
|
|
||||||
return repl("<tr><td>%(item_name)s</td><td class='text-right'>%(taxable_amount)s</td>%(taxes)s</tr>", {
|
|
||||||
item_name: item.item_name,
|
|
||||||
taxable_amount: format_currency(taxable_amount[item_code],
|
|
||||||
company_currency, precision("net_amount", item)),
|
|
||||||
taxes: $.map(tax_accounts, function(head) {
|
|
||||||
return item_tax_record[head[0]] ?
|
|
||||||
"<td class='text-right'>(" + item_tax_record[head[0]][0] + ") " + item_tax_record[head[0]][1] + "</td>" :
|
|
||||||
"<td></td>";
|
|
||||||
}).join("")
|
|
||||||
});
|
|
||||||
}).join("");
|
|
||||||
|
|
||||||
if(!rows) return "";
|
|
||||||
return '<div class="tax-break-up" style="overflow-x: auto;">\
|
|
||||||
<table class="table table-bordered table-hover">\
|
|
||||||
<thead><tr>' + headings + '</tr></thead> \
|
|
||||||
<tbody>' + rows + '</tbody> \
|
|
||||||
</table></div>';
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -210,7 +210,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
refresh: function() {
|
refresh: function() {
|
||||||
erpnext.toggle_naming_series();
|
erpnext.toggle_naming_series();
|
||||||
erpnext.hide_company();
|
erpnext.hide_company();
|
||||||
this.show_item_wise_taxes();
|
|
||||||
this.set_dynamic_labels();
|
this.set_dynamic_labels();
|
||||||
this.setup_sms();
|
this.setup_sms();
|
||||||
},
|
},
|
||||||
@ -367,7 +366,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
validate: function() {
|
validate: function() {
|
||||||
this.calculate_taxes_and_totals(false);
|
this.calculate_taxes_and_totals(false);
|
||||||
this.set_item_wise_tax_breakup();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
company: function() {
|
company: function() {
|
||||||
|
|||||||
@ -104,7 +104,7 @@ var erpnext_slides = [
|
|||||||
options: "", fieldtype: 'Select'
|
options: "", fieldtype: 'Select'
|
||||||
},
|
},
|
||||||
|
|
||||||
{ fieldtype: "Section Break", label: "Financial Year" },
|
{ fieldtype: "Section Break", label: __('Financial Year') },
|
||||||
{ fieldname: 'fy_start_date', label: __('Start Date'), fieldtype: 'Date', reqd: 1 },
|
{ fieldname: 'fy_start_date', label: __('Start Date'), fieldtype: 'Date', reqd: 1 },
|
||||||
{ fieldtype: "Column Break" },
|
{ fieldtype: "Column Break" },
|
||||||
{ fieldname: 'fy_end_date', label: __('End Date'), fieldtype: 'Date', reqd: 1 },
|
{ fieldname: 'fy_end_date', label: __('End Date'), fieldtype: 'Date', reqd: 1 },
|
||||||
@ -216,6 +216,17 @@ var erpnext_slides = [
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
// Sales Target
|
||||||
|
name: 'Goals',
|
||||||
|
domains: ['manufacturing', 'services', 'retail', 'distribution'],
|
||||||
|
title: __("Set your Target"),
|
||||||
|
help: __("Set a sales target you'd like to achieve."),
|
||||||
|
fields: [
|
||||||
|
{fieldtype:"Currency", fieldname:"sales_target", label:__("Monthly Sales Target")},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
// Taxes
|
// Taxes
|
||||||
name: 'taxes',
|
name: 'taxes',
|
||||||
|
|||||||
@ -42,11 +42,15 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
|||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(r.message) {
|
if(r.message) {
|
||||||
frm.updating_party_details = true;
|
frm.updating_party_details = true;
|
||||||
frm.set_value(r.message);
|
frappe.run_serially([
|
||||||
frm.updating_party_details = false;
|
() => frm.set_value(r.message),
|
||||||
if(callback) callback();
|
() => {
|
||||||
frm.refresh();
|
frm.updating_party_details = false;
|
||||||
erpnext.utils.add_item(frm);
|
if(callback) callback();
|
||||||
|
frm.refresh();
|
||||||
|
erpnext.utils.add_item(frm);
|
||||||
|
}
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -66,7 +66,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
|||||||
fieldtype:'Float',
|
fieldtype:'Float',
|
||||||
read_only: 1,
|
read_only: 1,
|
||||||
label: __(me.has_batch ? 'Total Qty' : 'Qty'),
|
label: __(me.has_batch ? 'Total Qty' : 'Qty'),
|
||||||
default: me.qty
|
default: 0
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -155,14 +155,10 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
bind_qty: function() {
|
bind_qty: function() {
|
||||||
let serial_no_link = this.dialog.fields_dict.serial_no_select;
|
|
||||||
let serial_no_list_field = this.dialog.fields_dict.serial_no;
|
|
||||||
let batches_field = this.dialog.fields_dict.batches;
|
let batches_field = this.dialog.fields_dict.batches;
|
||||||
|
|
||||||
let qty_field = this.dialog.fields_dict.qty;
|
let qty_field = this.dialog.fields_dict.qty;
|
||||||
|
if(batches_field) {
|
||||||
let update_quantity = (batch) => {
|
batches_field.grid.wrapper.on('change', function() {
|
||||||
if(batch) {
|
|
||||||
let total_qty = 0;
|
let total_qty = 0;
|
||||||
batches_field.grid.wrapper.find(
|
batches_field.grid.wrapper.find(
|
||||||
'input[data-fieldname="selected_qty"]').each(function() {
|
'input[data-fieldname="selected_qty"]').each(function() {
|
||||||
@ -170,48 +166,6 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
|||||||
total_qty += Number($(this).val());
|
total_qty += Number($(this).val());
|
||||||
});
|
});
|
||||||
qty_field.set_input(total_qty);
|
qty_field.set_input(total_qty);
|
||||||
} else {
|
|
||||||
let serial_numbers = serial_no_list_field.get_value()
|
|
||||||
.replace(/\n/g, ' ').match(/\S+/g) || [];
|
|
||||||
qty_field.set_input(serial_numbers.length);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if(serial_no_link) {
|
|
||||||
let serial_list = [];
|
|
||||||
serial_no_link.$input.on('awesomplete-selectcomplete', function() {
|
|
||||||
if(serial_no_link.get_value().length > 0) {
|
|
||||||
let new_no = serial_no_link.get_value();
|
|
||||||
let list_value = serial_no_list_field.get_value();
|
|
||||||
let new_line = '\n';
|
|
||||||
if(!serial_no_list_field.get_value()) {
|
|
||||||
new_line = '';
|
|
||||||
} else {
|
|
||||||
serial_list = list_value.replace(/\s+/g, ' ').split(' ');
|
|
||||||
}
|
|
||||||
if(!serial_list.includes(new_no)) {
|
|
||||||
serial_no_link.set_new_description('');
|
|
||||||
serial_no_list_field.set_value(list_value + new_line + new_no);
|
|
||||||
update_quantity(0);
|
|
||||||
} else {
|
|
||||||
serial_no_link.set_new_description(new_no + ' is already selected.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should, but doesn't work
|
|
||||||
serial_no_link.set_input('');
|
|
||||||
serial_no_link.$input.blur();
|
|
||||||
});
|
|
||||||
|
|
||||||
serial_no_list_field.$input.on('input', function() {
|
|
||||||
serial_list = serial_no_list_field.get_value().replace(/\s+/g, ' ').split(' ');
|
|
||||||
update_quantity(0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if(batches_field) {
|
|
||||||
batches_field.grid.wrapper.on('change', function() {
|
|
||||||
update_quantity(1);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -319,6 +273,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
|||||||
|
|
||||||
get_serial_no_fields: function() {
|
get_serial_no_fields: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
this.serial_list = [];
|
||||||
return [
|
return [
|
||||||
{fieldtype: 'Section Break', label: __('Serial No')},
|
{fieldtype: 'Section Break', label: __('Serial No')},
|
||||||
{
|
{
|
||||||
@ -326,10 +281,46 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
|||||||
label: __('Select'),
|
label: __('Select'),
|
||||||
get_query: function() {
|
get_query: function() {
|
||||||
return { filters: {item_code: me.item_code}};
|
return { filters: {item_code: me.item_code}};
|
||||||
|
},
|
||||||
|
onchange: function(e) {
|
||||||
|
if(this.in_local_change) return;
|
||||||
|
this.in_local_change = 1;
|
||||||
|
|
||||||
|
let serial_no_list_field = this.layout.fields_dict.serial_no;
|
||||||
|
let qty_field = this.layout.fields_dict.qty;
|
||||||
|
|
||||||
|
let new_number = this.get_value();
|
||||||
|
let list_value = serial_no_list_field.get_value();
|
||||||
|
let new_line = '\n';
|
||||||
|
if(!list_value) {
|
||||||
|
new_line = '';
|
||||||
|
} else {
|
||||||
|
me.serial_list = list_value.replace(/\n/g, ' ').match(/\S+/g) || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!me.serial_list.includes(new_number)) {
|
||||||
|
this.set_new_description('');
|
||||||
|
serial_no_list_field.set_value(me.serial_list.join('\n') + new_line + new_number);
|
||||||
|
me.serial_list = serial_no_list_field.get_value().replace(/\n/g, ' ').match(/\S+/g) || [];
|
||||||
|
} else {
|
||||||
|
this.set_new_description(new_number + ' is already selected.');
|
||||||
|
}
|
||||||
|
|
||||||
|
qty_field.set_input(me.serial_list.length);
|
||||||
|
this.$input.val("");
|
||||||
|
this.in_local_change = 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{fieldtype: 'Column Break'},
|
{fieldtype: 'Column Break'},
|
||||||
{fieldname: 'serial_no', fieldtype: 'Small Text'}
|
{
|
||||||
|
fieldname: 'serial_no',
|
||||||
|
fieldtype: 'Small Text',
|
||||||
|
onchange: function() {
|
||||||
|
me.serial_list = this.get_value()
|
||||||
|
.replace(/\n/g, ' ').match(/\S+/g) || [];
|
||||||
|
this.layout.fields_dict.qty.set_input(me.serial_list.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -10,7 +10,7 @@
|
|||||||
"state_name": "Uttar Pradesh"
|
"state_name": "Uttar Pradesh"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"state_number": "36",
|
"state_number": "05",
|
||||||
"state_code": "UT",
|
"state_code": "UT",
|
||||||
"state_name": "Uttarakhand"
|
"state_name": "Uttarakhand"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -80,7 +80,7 @@ def add_print_formats():
|
|||||||
|
|
||||||
def make_custom_fields():
|
def make_custom_fields():
|
||||||
hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
|
hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
|
||||||
fieldtype='Data', options='item_code.gst_hsn_code', insert_after='description')
|
fieldtype='Data', options='item_code.gst_hsn_code', insert_after='description', print_hide=1)
|
||||||
|
|
||||||
custom_fields = {
|
custom_fields = {
|
||||||
'Address': [
|
'Address': [
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import frappe, re
|
import frappe, re
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from erpnext.regional.india import states, state_numbers
|
from erpnext.regional.india import states, state_numbers
|
||||||
|
from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount
|
||||||
|
|
||||||
def validate_gstin_for_india(doc, method):
|
def validate_gstin_for_india(doc, method):
|
||||||
if not hasattr(doc, 'gstin'):
|
if not hasattr(doc, 'gstin'):
|
||||||
@ -22,3 +23,44 @@ def validate_gstin_for_india(doc, method):
|
|||||||
if doc.gstin != "NA" and doc.gst_state_number != doc.gstin[:2]:
|
if doc.gstin != "NA" and doc.gst_state_number != doc.gstin[:2]:
|
||||||
frappe.throw(_("First 2 digits of GSTIN should match with State number {0}")
|
frappe.throw(_("First 2 digits of GSTIN should match with State number {0}")
|
||||||
.format(doc.gst_state_number))
|
.format(doc.gst_state_number))
|
||||||
|
|
||||||
|
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
|
||||||
|
if frappe.get_meta(item_doctype).has_field('gst_hsn_code'):
|
||||||
|
return [_("HSN/SAC"), _("Taxable Amount")] + tax_accounts
|
||||||
|
else:
|
||||||
|
return [_("Item"), _("Taxable Amount")] + tax_accounts
|
||||||
|
|
||||||
|
def get_itemised_tax_breakup_data(doc):
|
||||||
|
itemised_tax = get_itemised_tax(doc.taxes)
|
||||||
|
|
||||||
|
itemised_taxable_amount = get_itemised_taxable_amount(doc.items)
|
||||||
|
|
||||||
|
if not frappe.get_meta(doc.doctype + " Item").has_field('gst_hsn_code'):
|
||||||
|
return itemised_tax, itemised_taxable_amount
|
||||||
|
|
||||||
|
item_hsn_map = frappe._dict()
|
||||||
|
for d in doc.items:
|
||||||
|
item_hsn_map.setdefault(d.item_code or d.item_name, d.get("gst_hsn_code"))
|
||||||
|
|
||||||
|
hsn_tax = {}
|
||||||
|
for item, taxes in itemised_tax.items():
|
||||||
|
hsn_code = item_hsn_map.get(item)
|
||||||
|
hsn_tax.setdefault(hsn_code, frappe._dict())
|
||||||
|
for tax_account, tax_detail in taxes.items():
|
||||||
|
hsn_tax[hsn_code].setdefault(tax_account, {"tax_rate": 0, "tax_amount": 0})
|
||||||
|
hsn_tax[hsn_code][tax_account]["tax_rate"] = tax_detail.get("tax_rate")
|
||||||
|
hsn_tax[hsn_code][tax_account]["tax_amount"] += tax_detail.get("tax_amount")
|
||||||
|
|
||||||
|
# set taxable amount
|
||||||
|
hsn_taxable_amount = frappe._dict()
|
||||||
|
for item, taxable_amount in itemised_taxable_amount.items():
|
||||||
|
hsn_code = item_hsn_map.get(item)
|
||||||
|
hsn_taxable_amount.setdefault(hsn_code, 0)
|
||||||
|
hsn_taxable_amount[hsn_code] += itemised_taxable_amount.get(item)
|
||||||
|
|
||||||
|
return hsn_tax, hsn_taxable_amount
|
||||||
|
|
||||||
|
# don't remove this function it is used in tests
|
||||||
|
def test_method():
|
||||||
|
'''test function'''
|
||||||
|
return 'overridden'
|
||||||
@ -25,7 +25,7 @@
|
|||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Academic Year",
|
"label": "Academic Year",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
@ -148,7 +148,7 @@
|
|||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Program",
|
"label": "Program",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
@ -269,7 +269,7 @@
|
|||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-05-15 12:43:32.317942",
|
"modified": "2017-07-17 21:57:35.602091",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Schools",
|
"module": "Schools",
|
||||||
"name": "Student Group Creation Tool",
|
"name": "Student Group Creation Tool",
|
||||||
@ -300,6 +300,7 @@
|
|||||||
"quick_entry": 0,
|
"quick_entry": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
|
"restrict_to_domain": "Education",
|
||||||
"show_name_in_global_search": 0,
|
"show_name_in_global_search": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
|||||||
@ -1,346 +1,357 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
"allow_import": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_rename": 0,
|
"allow_import": 0,
|
||||||
"autoname": "SLA.######",
|
"allow_rename": 0,
|
||||||
"beta": 0,
|
"autoname": "SLA.######",
|
||||||
"creation": "2016-11-28 15:38:54.793854",
|
"beta": 0,
|
||||||
"custom": 0,
|
"creation": "2016-11-28 15:38:54.793854",
|
||||||
"docstatus": 0,
|
"custom": 0,
|
||||||
"doctype": "DocType",
|
"docstatus": 0,
|
||||||
"document_type": "",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"document_type": "",
|
||||||
"engine": "InnoDB",
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"bold": 0,
|
"allow_on_submit": 0,
|
||||||
"collapsible": 0,
|
"bold": 0,
|
||||||
"columns": 0,
|
"collapsible": 0,
|
||||||
"fieldname": "student",
|
"columns": 0,
|
||||||
"fieldtype": "Link",
|
"fieldname": "student",
|
||||||
"hidden": 0,
|
"fieldtype": "Link",
|
||||||
"ignore_user_permissions": 0,
|
"hidden": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_user_permissions": 0,
|
||||||
"in_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_global_search": 1,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_global_search": 1,
|
||||||
"in_standard_filter": 0,
|
"in_list_view": 0,
|
||||||
"label": "Student",
|
"in_standard_filter": 0,
|
||||||
"length": 0,
|
"label": "Student",
|
||||||
"no_copy": 0,
|
"length": 0,
|
||||||
"options": "Student",
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"options": "Student",
|
||||||
"precision": "",
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"precision": "",
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide": 0,
|
||||||
"read_only": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"remember_last_selected_value": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"remember_last_selected_value": 0,
|
||||||
"reqd": 1,
|
"report_hide": 0,
|
||||||
"search_index": 0,
|
"reqd": 1,
|
||||||
"set_only_once": 0,
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"bold": 0,
|
"allow_on_submit": 0,
|
||||||
"collapsible": 0,
|
"bold": 0,
|
||||||
"columns": 0,
|
"collapsible": 0,
|
||||||
"fieldname": "student_name",
|
"columns": 0,
|
||||||
"fieldtype": "Read Only",
|
"fieldname": "student_name",
|
||||||
"hidden": 0,
|
"fieldtype": "Read Only",
|
||||||
"ignore_user_permissions": 0,
|
"hidden": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_user_permissions": 0,
|
||||||
"in_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_global_search": 1,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_global_search": 1,
|
||||||
"in_standard_filter": 0,
|
"in_list_view": 0,
|
||||||
"label": "Student Name",
|
"in_standard_filter": 0,
|
||||||
"length": 0,
|
"label": "Student Name",
|
||||||
"no_copy": 0,
|
"length": 0,
|
||||||
"options": "student.title",
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"options": "student.title",
|
||||||
"precision": "",
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"precision": "",
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide": 0,
|
||||||
"read_only": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"remember_last_selected_value": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"remember_last_selected_value": 0,
|
||||||
"reqd": 0,
|
"report_hide": 0,
|
||||||
"search_index": 0,
|
"reqd": 0,
|
||||||
"set_only_once": 0,
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"bold": 0,
|
"allow_on_submit": 0,
|
||||||
"collapsible": 0,
|
"bold": 0,
|
||||||
"columns": 0,
|
"collapsible": 0,
|
||||||
"fieldname": "column_break_3",
|
"columns": 0,
|
||||||
"fieldtype": "Column Break",
|
"fieldname": "column_break_3",
|
||||||
"hidden": 0,
|
"fieldtype": "Column Break",
|
||||||
"ignore_user_permissions": 0,
|
"hidden": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_user_permissions": 0,
|
||||||
"in_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_global_search": 0,
|
||||||
"in_standard_filter": 0,
|
"in_list_view": 0,
|
||||||
"label": "",
|
"in_standard_filter": 0,
|
||||||
"length": 0,
|
"label": "",
|
||||||
"no_copy": 0,
|
"length": 0,
|
||||||
"permlevel": 0,
|
"no_copy": 0,
|
||||||
"precision": "",
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"precision": "",
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide": 0,
|
||||||
"read_only": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"remember_last_selected_value": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"remember_last_selected_value": 0,
|
||||||
"reqd": 0,
|
"report_hide": 0,
|
||||||
"search_index": 0,
|
"reqd": 0,
|
||||||
"set_only_once": 0,
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"bold": 0,
|
"allow_on_submit": 0,
|
||||||
"collapsible": 0,
|
"bold": 0,
|
||||||
"columns": 0,
|
"collapsible": 0,
|
||||||
"fieldname": "from_date",
|
"columns": 0,
|
||||||
"fieldtype": "Date",
|
"fieldname": "from_date",
|
||||||
"hidden": 0,
|
"fieldtype": "Date",
|
||||||
"ignore_user_permissions": 0,
|
"hidden": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_user_permissions": 0,
|
||||||
"in_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 1,
|
"in_global_search": 0,
|
||||||
"in_standard_filter": 1,
|
"in_list_view": 1,
|
||||||
"label": "From Date",
|
"in_standard_filter": 1,
|
||||||
"length": 0,
|
"label": "From Date",
|
||||||
"no_copy": 0,
|
"length": 0,
|
||||||
"permlevel": 0,
|
"no_copy": 0,
|
||||||
"precision": "",
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"precision": "",
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide": 0,
|
||||||
"read_only": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"remember_last_selected_value": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"remember_last_selected_value": 0,
|
||||||
"reqd": 1,
|
"report_hide": 0,
|
||||||
"search_index": 0,
|
"reqd": 1,
|
||||||
"set_only_once": 0,
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"bold": 0,
|
"allow_on_submit": 0,
|
||||||
"collapsible": 0,
|
"bold": 0,
|
||||||
"columns": 0,
|
"collapsible": 0,
|
||||||
"fieldname": "to_date",
|
"columns": 0,
|
||||||
"fieldtype": "Date",
|
"fieldname": "to_date",
|
||||||
"hidden": 0,
|
"fieldtype": "Date",
|
||||||
"ignore_user_permissions": 0,
|
"hidden": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_user_permissions": 0,
|
||||||
"in_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 1,
|
"in_global_search": 0,
|
||||||
"in_standard_filter": 0,
|
"in_list_view": 1,
|
||||||
"label": "To Date",
|
"in_standard_filter": 0,
|
||||||
"length": 0,
|
"label": "To Date",
|
||||||
"no_copy": 0,
|
"length": 0,
|
||||||
"permlevel": 0,
|
"no_copy": 0,
|
||||||
"precision": "",
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"precision": "",
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide": 0,
|
||||||
"read_only": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"remember_last_selected_value": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"remember_last_selected_value": 0,
|
||||||
"reqd": 1,
|
"report_hide": 0,
|
||||||
"search_index": 0,
|
"reqd": 1,
|
||||||
"set_only_once": 0,
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"bold": 0,
|
"allow_on_submit": 0,
|
||||||
"collapsible": 0,
|
"bold": 0,
|
||||||
"columns": 0,
|
"collapsible": 0,
|
||||||
"description": "Will show the student as Present in Student Monthly Attendance Report",
|
"columns": 0,
|
||||||
"fieldname": "mark_as_present",
|
"description": "Will show the student as Present in Student Monthly Attendance Report",
|
||||||
"fieldtype": "Check",
|
"fieldname": "mark_as_present",
|
||||||
"hidden": 0,
|
"fieldtype": "Check",
|
||||||
"ignore_user_permissions": 0,
|
"hidden": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_user_permissions": 0,
|
||||||
"in_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_global_search": 0,
|
||||||
"in_standard_filter": 0,
|
"in_list_view": 0,
|
||||||
"label": "Mark as Present",
|
"in_standard_filter": 0,
|
||||||
"length": 0,
|
"label": "Mark as Present",
|
||||||
"no_copy": 0,
|
"length": 0,
|
||||||
"permlevel": 0,
|
"no_copy": 0,
|
||||||
"precision": "",
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"precision": "",
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide": 0,
|
||||||
"read_only": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"remember_last_selected_value": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"remember_last_selected_value": 0,
|
||||||
"reqd": 0,
|
"report_hide": 0,
|
||||||
"search_index": 0,
|
"reqd": 0,
|
||||||
"set_only_once": 0,
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"bold": 0,
|
"allow_on_submit": 0,
|
||||||
"collapsible": 0,
|
"bold": 0,
|
||||||
"columns": 0,
|
"collapsible": 0,
|
||||||
"fieldname": "section_break_5",
|
"columns": 0,
|
||||||
"fieldtype": "Section Break",
|
"fieldname": "section_break_5",
|
||||||
"hidden": 0,
|
"fieldtype": "Section Break",
|
||||||
"ignore_user_permissions": 0,
|
"hidden": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_user_permissions": 0,
|
||||||
"in_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_global_search": 0,
|
||||||
"in_standard_filter": 0,
|
"in_list_view": 0,
|
||||||
"length": 0,
|
"in_standard_filter": 0,
|
||||||
"no_copy": 0,
|
"length": 0,
|
||||||
"permlevel": 0,
|
"no_copy": 0,
|
||||||
"precision": "",
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"precision": "",
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide": 0,
|
||||||
"read_only": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"remember_last_selected_value": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"remember_last_selected_value": 0,
|
||||||
"reqd": 0,
|
"report_hide": 0,
|
||||||
"search_index": 0,
|
"reqd": 0,
|
||||||
"set_only_once": 0,
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"bold": 0,
|
"allow_on_submit": 0,
|
||||||
"collapsible": 0,
|
"bold": 0,
|
||||||
"columns": 0,
|
"collapsible": 0,
|
||||||
"fieldname": "reason",
|
"columns": 0,
|
||||||
"fieldtype": "Text",
|
"fieldname": "reason",
|
||||||
"hidden": 0,
|
"fieldtype": "Text",
|
||||||
"ignore_user_permissions": 0,
|
"hidden": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_user_permissions": 0,
|
||||||
"in_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_global_search": 0,
|
||||||
"in_standard_filter": 0,
|
"in_list_view": 0,
|
||||||
"label": "Reason",
|
"in_standard_filter": 0,
|
||||||
"length": 0,
|
"label": "Reason",
|
||||||
"no_copy": 0,
|
"length": 0,
|
||||||
"permlevel": 0,
|
"no_copy": 0,
|
||||||
"precision": "",
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"precision": "",
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide": 0,
|
||||||
"read_only": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"remember_last_selected_value": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"remember_last_selected_value": 0,
|
||||||
"reqd": 0,
|
"report_hide": 0,
|
||||||
"search_index": 0,
|
"reqd": 0,
|
||||||
"set_only_once": 0,
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"bold": 0,
|
"allow_on_submit": 0,
|
||||||
"collapsible": 0,
|
"bold": 0,
|
||||||
"columns": 0,
|
"collapsible": 0,
|
||||||
"fieldname": "amended_from",
|
"columns": 0,
|
||||||
"fieldtype": "Link",
|
"fieldname": "amended_from",
|
||||||
"hidden": 0,
|
"fieldtype": "Link",
|
||||||
"ignore_user_permissions": 0,
|
"hidden": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_user_permissions": 0,
|
||||||
"in_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_global_search": 0,
|
||||||
"in_standard_filter": 0,
|
"in_list_view": 0,
|
||||||
"label": "Amended From",
|
"in_standard_filter": 0,
|
||||||
"length": 0,
|
"label": "Amended From",
|
||||||
"no_copy": 1,
|
"length": 0,
|
||||||
"options": "Student Leave Application",
|
"no_copy": 1,
|
||||||
"permlevel": 0,
|
"options": "Student Leave Application",
|
||||||
"print_hide": 1,
|
"permlevel": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide": 1,
|
||||||
"read_only": 1,
|
"print_hide_if_no_value": 0,
|
||||||
"remember_last_selected_value": 0,
|
"read_only": 1,
|
||||||
"report_hide": 0,
|
"remember_last_selected_value": 0,
|
||||||
"reqd": 0,
|
"report_hide": 0,
|
||||||
"search_index": 0,
|
"reqd": 0,
|
||||||
"set_only_once": 0,
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hide_heading": 0,
|
"has_web_view": 0,
|
||||||
"hide_toolbar": 0,
|
"hide_heading": 0,
|
||||||
"idx": 0,
|
"hide_toolbar": 0,
|
||||||
"image_view": 0,
|
"idx": 0,
|
||||||
"in_create": 0,
|
"image_view": 0,
|
||||||
"in_dialog": 0,
|
"in_create": 0,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-02-20 13:21:08.828872",
|
"modified": "2017-07-17 21:57:57.804413",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Schools",
|
"module": "Schools",
|
||||||
"name": "Student Leave Application",
|
"name": "Student Leave Application",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"apply_user_permissions": 0,
|
"apply_user_permissions": 0,
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 0,
|
"export": 0,
|
||||||
"if_owner": 0,
|
"if_owner": 0,
|
||||||
"import": 0,
|
"import": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Instructor",
|
"role": "Instructor",
|
||||||
"set_user_permissions": 0,
|
"set_user_permissions": 0,
|
||||||
"share": 0,
|
"share": 0,
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"apply_user_permissions": 0,
|
"apply_user_permissions": 0,
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"if_owner": 0,
|
||||||
"import": 0,
|
"import": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Academics User",
|
"role": "Academics User",
|
||||||
"set_user_permissions": 0,
|
"set_user_permissions": 0,
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
"show_name_in_global_search": 1,
|
"restrict_to_domain": "Education",
|
||||||
"sort_field": "modified",
|
"show_name_in_global_search": 1,
|
||||||
"sort_order": "DESC",
|
"sort_field": "modified",
|
||||||
"title_field": "student_name",
|
"sort_order": "DESC",
|
||||||
"track_changes": 0,
|
"title_field": "student_name",
|
||||||
|
"track_changes": 0,
|
||||||
"track_seen": 0
|
"track_seen": 0
|
||||||
}
|
}
|
||||||
@ -1,399 +1,400 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
"autoname": "SLog.####",
|
"autoname": "SLog.####",
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
"creation": "2016-07-29 03:27:22.451772",
|
"creation": "2016-07-29 03:27:22.451772",
|
||||||
"custom": 0,
|
"custom": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
"document_type": "",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "student",
|
"fieldname": "student",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Student",
|
"label": "Student",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Student",
|
"options": "Student",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "student_name",
|
"fieldname": "student_name",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Student Name",
|
"label": "Student Name",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "student.title",
|
"options": "student.title",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "type",
|
"fieldname": "type",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Type",
|
"label": "Type",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "General\nAcademic\nMedical\nAchievement",
|
"options": "General\nAcademic\nMedical\nAchievement",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "date",
|
"fieldname": "date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Date",
|
"label": "Date",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "column_break_3",
|
"fieldname": "column_break_3",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "academic_year",
|
"fieldname": "academic_year",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Academic Year",
|
"label": "Academic Year",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Academic Year",
|
"options": "Academic Year",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "academic_term",
|
"fieldname": "academic_term",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Academic Term",
|
"label": "Academic Term",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Academic Term",
|
"options": "Academic Term",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "program",
|
"fieldname": "program",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Program",
|
"label": "Program",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Program",
|
"options": "Program",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "student_batch",
|
"fieldname": "student_batch",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Student Batch",
|
"label": "Student Batch",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Student Batch Name",
|
"options": "Student Batch Name",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "section_break_5",
|
"fieldname": "section_break_5",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "log",
|
"fieldname": "log",
|
||||||
"fieldtype": "Text Editor",
|
"fieldtype": "Text Editor",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Log",
|
"label": "Log",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"has_web_view": 0,
|
||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
"hide_toolbar": 0,
|
"hide_toolbar": 0,
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"image_view": 0,
|
"image_view": 0,
|
||||||
"in_create": 0,
|
"in_create": 0,
|
||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-07-06 12:42:05.777673",
|
"modified": "2017-07-17 21:57:11.024049",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Schools",
|
"module": "Schools",
|
||||||
"name": "Student Log",
|
"name": "Student Log",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
"apply_user_permissions": 0,
|
"apply_user_permissions": 0,
|
||||||
"cancel": 0,
|
"cancel": 0,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"if_owner": 0,
|
||||||
"import": 0,
|
"import": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Academics User",
|
"role": "Academics User",
|
||||||
"set_user_permissions": 0,
|
"set_user_permissions": 0,
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
"submit": 0,
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"quick_entry": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
"show_name_in_global_search": 0,
|
"restrict_to_domain": "Education",
|
||||||
"sort_field": "modified",
|
"show_name_in_global_search": 0,
|
||||||
"sort_order": "DESC",
|
"sort_field": "modified",
|
||||||
"title_field": "student_name",
|
"sort_order": "DESC",
|
||||||
"track_changes": 0,
|
"title_field": "student_name",
|
||||||
|
"track_changes": 0,
|
||||||
"track_seen": 1
|
"track_seen": 1
|
||||||
}
|
}
|
||||||
@ -105,6 +105,10 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
|
|||||||
|
|
||||||
lead: function() {
|
lead: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
if(!this.frm.doc.lead) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.crm.doctype.lead.lead.get_lead_details",
|
method: "erpnext.crm.doctype.lead.lead.get_lead_details",
|
||||||
args: {
|
args: {
|
||||||
|
|||||||
@ -93,7 +93,7 @@ def get_list_context(context=None):
|
|||||||
'show_sidebar': True,
|
'show_sidebar': True,
|
||||||
'show_search': True,
|
'show_search': True,
|
||||||
'no_breadcrumbs': True,
|
'no_breadcrumbs': True,
|
||||||
'title': _('Quotes'),
|
'title': _('Quotations'),
|
||||||
})
|
})
|
||||||
|
|
||||||
return list_context
|
return list_context
|
||||||
|
|||||||
@ -10,3 +10,6 @@ from erpnext.controllers.print_settings import print_settings_for_item_table
|
|||||||
class SalesOrderItem(Document):
|
class SalesOrderItem(Document):
|
||||||
def __setup__(self):
|
def __setup__(self):
|
||||||
print_settings_for_item_table(self)
|
print_settings_for_item_table(self)
|
||||||
|
|
||||||
|
def on_doctype_update():
|
||||||
|
frappe.db.add_index("Sales Order Item", ["item_code", "warehouse"])
|
||||||
@ -89,7 +89,8 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
|||||||
|
|
||||||
customer: function() {
|
customer: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
erpnext.utils.get_party_details(this.frm, null, null, function(){me.apply_pricing_rule()});
|
erpnext.utils.get_party_details(this.frm, null, null,
|
||||||
|
function(){ me.apply_pricing_rule() });
|
||||||
},
|
},
|
||||||
|
|
||||||
customer_address: function() {
|
customer_address: function() {
|
||||||
|
|||||||
@ -147,7 +147,7 @@ class Company(Document):
|
|||||||
def validate_perpetual_inventory(self):
|
def validate_perpetual_inventory(self):
|
||||||
if not self.get("__islocal"):
|
if not self.get("__islocal"):
|
||||||
if cint(self.enable_perpetual_inventory) == 1 and not self.default_inventory_account:
|
if cint(self.enable_perpetual_inventory) == 1 and not self.default_inventory_account:
|
||||||
frappe.msgprint(_("Set default inventory account for perpetual inventory"),
|
frappe.msgprint(_("Set default inventory account for perpetual inventory"),
|
||||||
alert=True, indicator='orange')
|
alert=True, indicator='orange')
|
||||||
|
|
||||||
def set_default_accounts(self):
|
def set_default_accounts(self):
|
||||||
@ -310,3 +310,45 @@ def get_name_with_abbr(name, company):
|
|||||||
parts.append(company_abbr)
|
parts.append(company_abbr)
|
||||||
|
|
||||||
return " - ".join(parts)
|
return " - ".join(parts)
|
||||||
|
|
||||||
|
def update_company_current_month_sales(company):
|
||||||
|
from frappe.utils import today, formatdate
|
||||||
|
current_month_year = formatdate(today(), "MM-yyyy")
|
||||||
|
|
||||||
|
results = frappe.db.sql(('''
|
||||||
|
select
|
||||||
|
sum(grand_total) as total, date_format(posting_date, '%m-%Y') as month_year
|
||||||
|
from
|
||||||
|
`tabSales Invoice`
|
||||||
|
where
|
||||||
|
date_format(posting_date, '%m-%Y')="{0}" and
|
||||||
|
company = "{1}"
|
||||||
|
group by
|
||||||
|
month_year;
|
||||||
|
''').format(current_month_year, frappe.db.escape(company)), as_dict = True)
|
||||||
|
|
||||||
|
monthly_total = results[0]['total'] if len(results) > 0 else 0
|
||||||
|
|
||||||
|
frappe.db.sql(('''
|
||||||
|
update tabCompany set total_monthly_sales = %s where name=%s
|
||||||
|
'''), (monthly_total, frappe.db.escape(company)))
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def update_company_monthly_sales(company):
|
||||||
|
'''Cache past year monthly sales of every company based on sales invoices'''
|
||||||
|
from frappe.utils.goal import get_monthly_results
|
||||||
|
import json
|
||||||
|
filter_str = 'company = "'+ company +'" and status != "Draft"'
|
||||||
|
month_to_value_dict = get_monthly_results("Sales Invoice", "grand_total", "posting_date", filter_str, "sum")
|
||||||
|
|
||||||
|
frappe.db.sql(('''
|
||||||
|
update tabCompany set sales_monthly_history = %s where name=%s
|
||||||
|
'''), (json.dumps(month_to_value_dict), frappe.db.escape(company)))
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
|
def cache_companies_monthly_sales_history():
|
||||||
|
companies = [d['name'] for d in frappe.get_list("Company")]
|
||||||
|
for company in companies:
|
||||||
|
update_company_monthly_sales(company)
|
||||||
|
frappe.db.commit()
|
||||||
|
|||||||
42
erpnext/setup/doctype/company/company_dashboard.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
from frappe import _
|
||||||
|
|
||||||
|
def get_data():
|
||||||
|
return {
|
||||||
|
'heatmap': True,
|
||||||
|
'heatmap_message': _('This is based on transactions against this Company. See timeline below for details'),
|
||||||
|
|
||||||
|
'graph': True,
|
||||||
|
'graph_method': "frappe.utils.goal.get_monthly_goal_graph_data",
|
||||||
|
'graph_method_args': {
|
||||||
|
'title': 'Sales',
|
||||||
|
'goal_value_field': 'sales_target',
|
||||||
|
'goal_total_field': 'total_monthly_sales',
|
||||||
|
'goal_history_field': 'sales_monthly_history',
|
||||||
|
'goal_doctype': 'Sales Invoice',
|
||||||
|
'goal_doctype_link': 'company',
|
||||||
|
'goal_field': 'grand_total',
|
||||||
|
'date_field': 'posting_date',
|
||||||
|
'filter_str': 'status != "Draft"',
|
||||||
|
'aggregation': 'sum'
|
||||||
|
},
|
||||||
|
|
||||||
|
'fieldname': 'company',
|
||||||
|
'transactions': [
|
||||||
|
{
|
||||||
|
'label': _('Pre Sales'),
|
||||||
|
'items': ['Quotation']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _('Orders'),
|
||||||
|
'items': ['Sales Order', 'Delivery Note', 'Sales Invoice']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _('Support'),
|
||||||
|
'items': ['Issue']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _('Projects'),
|
||||||
|
'items': ['Project']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
def get_domain(domain):
|
def get_domain(domain):
|
||||||
'''Written as a function to prevent data mutation effects'''
|
'''Written as a function to prevent data mutation effects'''
|
||||||
@ -78,8 +79,11 @@ def setup_domain(domain):
|
|||||||
setup_properties(data)
|
setup_properties(data)
|
||||||
set_values(data)
|
set_values(data)
|
||||||
setup_sidebar_items(data)
|
setup_sidebar_items(data)
|
||||||
|
update_module_def_restrict_to_domain()
|
||||||
|
|
||||||
if data.get('default_portal_role'):
|
if data.get('default_portal_role'):
|
||||||
frappe.db.set_value('Portal Settings', None, 'default_role', data.get('default_portal_role'))
|
frappe.db.set_value('Portal Settings', None, 'default_role', data.get('default_portal_role'))
|
||||||
|
|
||||||
frappe.clear_cache()
|
frappe.clear_cache()
|
||||||
|
|
||||||
def setup_desktop_icons(data):
|
def setup_desktop_icons(data):
|
||||||
@ -137,9 +141,18 @@ def setup_sidebar_items(data):
|
|||||||
frappe.db.sql('''update `tabPortal Menu Item` set enabled=0
|
frappe.db.sql('''update `tabPortal Menu Item` set enabled=0
|
||||||
where route in ({0})'''.format(', '.join(['"{0}"'.format(d) for d in data.remove_sidebar_items])))
|
where route in ({0})'''.format(', '.join(['"{0}"'.format(d) for d in data.remove_sidebar_items])))
|
||||||
|
|
||||||
|
|
||||||
def reset():
|
def reset():
|
||||||
from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to
|
from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to
|
||||||
add_all_roles_to('Administrator')
|
add_all_roles_to('Administrator')
|
||||||
|
|
||||||
frappe.db.sql('delete from `tabProperty Setter`')
|
frappe.db.sql('delete from `tabProperty Setter`')
|
||||||
|
|
||||||
|
def update_module_def_restrict_to_domain():
|
||||||
|
""" set the restrict to domain for the module def """
|
||||||
|
|
||||||
|
module_def_restrict_to_domain_mapper = {
|
||||||
|
"Schools": _('Education')
|
||||||
|
}
|
||||||
|
|
||||||
|
for module, domain in module_def_restrict_to_domain_mapper.iteritems():
|
||||||
|
frappe.set_value("Module Def", module, "restrict_to_domain", domain)
|
||||||
|
|||||||
@ -91,7 +91,8 @@ def create_fiscal_year_and_company(args):
|
|||||||
'country': args.get('country'),
|
'country': args.get('country'),
|
||||||
'create_chart_of_accounts_based_on': 'Standard Template',
|
'create_chart_of_accounts_based_on': 'Standard Template',
|
||||||
'chart_of_accounts': args.get('chart_of_accounts'),
|
'chart_of_accounts': args.get('chart_of_accounts'),
|
||||||
'domain': args.get('domain')
|
'domain': args.get('domain'),
|
||||||
|
'sales_target': args.get('sales_target')
|
||||||
}).insert()
|
}).insert()
|
||||||
|
|
||||||
#Enable shopping cart
|
#Enable shopping cart
|
||||||
|
|||||||
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
def get_notification_config():
|
def get_notification_config():
|
||||||
notification_for_doctype = { "for_doctype":
|
notifications = { "for_doctype":
|
||||||
{
|
{
|
||||||
"Issue": {"status": "Open"},
|
"Issue": {"status": "Open"},
|
||||||
"Warranty Claim": {"status": "Open"},
|
"Warranty Claim": {"status": "Open"},
|
||||||
@ -56,12 +56,20 @@ def get_notification_config():
|
|||||||
"Production Order": { "status": ("in", ("Draft", "Not Started", "In Process")) },
|
"Production Order": { "status": ("in", ("Draft", "Not Started", "In Process")) },
|
||||||
"BOM": {"docstatus": 0},
|
"BOM": {"docstatus": 0},
|
||||||
"Timesheet": {"status": "Draft"}
|
"Timesheet": {"status": "Draft"}
|
||||||
|
},
|
||||||
|
|
||||||
|
"targets": {
|
||||||
|
"Company": {
|
||||||
|
"filters" : { "sales_target": ( ">", 0 ) },
|
||||||
|
"target_field" : "sales_target",
|
||||||
|
"value_field" : "total_monthly_sales"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doctype = [d for d in notification_for_doctype.get('for_doctype')]
|
doctype = [d for d in notifications.get('for_doctype')]
|
||||||
for doc in frappe.get_all('DocType',
|
for doc in frappe.get_all('DocType',
|
||||||
fields= ["name"], filters = {"name": ("not in", doctype), 'is_submittable': 1}):
|
fields= ["name"], filters = {"name": ("not in", doctype), 'is_submittable': 1}):
|
||||||
notification_for_doctype["for_doctype"][doc.name] = {"docstatus": 0}
|
notifications["for_doctype"][doc.name] = {"docstatus": 0}
|
||||||
|
|
||||||
return notification_for_doctype
|
return notifications
|
||||||
|
|||||||
@ -14,6 +14,7 @@ from erpnext.controllers.selling_controller import SellingController
|
|||||||
from frappe.desk.notifications import clear_doctype_notifications
|
from frappe.desk.notifications import clear_doctype_notifications
|
||||||
from erpnext.stock.doctype.batch.batch import set_batch_nos
|
from erpnext.stock.doctype.batch.batch import set_batch_nos
|
||||||
from frappe.contacts.doctype.address.address import get_company_address
|
from frappe.contacts.doctype.address.address import get_company_address
|
||||||
|
from erpnext.stock.doctype.serial_no.serial_no import get_delivery_note_serial_no
|
||||||
|
|
||||||
form_grid_templates = {
|
form_grid_templates = {
|
||||||
"items": "templates/form_grid/item_grid.html"
|
"items": "templates/form_grid/item_grid.html"
|
||||||
@ -390,6 +391,9 @@ def make_sales_invoice(source_name, target_doc=None):
|
|||||||
|
|
||||||
def update_item(source_doc, target_doc, source_parent):
|
def update_item(source_doc, target_doc, source_parent):
|
||||||
target_doc.qty = source_doc.qty - invoiced_qty_map.get(source_doc.name, 0)
|
target_doc.qty = source_doc.qty - invoiced_qty_map.get(source_doc.name, 0)
|
||||||
|
if source_doc.serial_no and source_parent.per_billed > 0:
|
||||||
|
target_doc.serial_no = get_delivery_note_serial_no(source_doc.item_code,
|
||||||
|
target_doc.qty, source_parent.name)
|
||||||
|
|
||||||
doc = get_mapped_doc("Delivery Note", source_name, {
|
doc = get_mapped_doc("Delivery Note", source_name, {
|
||||||
"Delivery Note": {
|
"Delivery Note": {
|
||||||
|
|||||||
@ -170,6 +170,10 @@ class TestDeliveryNote(unittest.TestCase):
|
|||||||
"delivery_document_no": dn.name
|
"delivery_document_no": dn.name
|
||||||
})
|
})
|
||||||
|
|
||||||
|
si = make_sales_invoice(dn.name)
|
||||||
|
si.insert(ignore_permissions=True)
|
||||||
|
self.assertEquals(dn.items[0].serial_no, si.items[0].serial_no)
|
||||||
|
|
||||||
dn.cancel()
|
dn.cancel()
|
||||||
|
|
||||||
self.check_serial_no_values(serial_no, {
|
self.check_serial_no_values(serial_no, {
|
||||||
@ -177,6 +181,22 @@ class TestDeliveryNote(unittest.TestCase):
|
|||||||
"delivery_document_no": ""
|
"delivery_document_no": ""
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def test_serialized_partial_sales_invoice(self):
|
||||||
|
se = make_serialized_item()
|
||||||
|
serial_no = get_serial_nos(se.get("items")[0].serial_no)
|
||||||
|
serial_no = '\n'.join(serial_no)
|
||||||
|
|
||||||
|
dn = create_delivery_note(item_code="_Test Serialized Item With Series", qty=2, serial_no=serial_no)
|
||||||
|
|
||||||
|
si = make_sales_invoice(dn.name)
|
||||||
|
si.items[0].qty = 1
|
||||||
|
si.submit()
|
||||||
|
self.assertEquals(si.items[0].qty, 1)
|
||||||
|
|
||||||
|
si = make_sales_invoice(dn.name)
|
||||||
|
si.submit()
|
||||||
|
self.assertEquals(si.items[0].qty, len(get_serial_nos(si.items[0].serial_no)))
|
||||||
|
|
||||||
def test_serialize_status(self):
|
def test_serialize_status(self):
|
||||||
from frappe.model.naming import make_autoname
|
from frappe.model.naming import make_autoname
|
||||||
serial_no = frappe.get_doc({
|
serial_no = frappe.get_doc({
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
"item_group": "_Test Item Group",
|
"item_group": "_Test Item Group",
|
||||||
"item_name": "_Test Item",
|
"item_name": "_Test Item",
|
||||||
"apply_warehouse_wise_reorder_level": 1,
|
"apply_warehouse_wise_reorder_level": 1,
|
||||||
|
"gst_hsn_code": "999800",
|
||||||
"valuation_rate": 100,
|
"valuation_rate": 100,
|
||||||
"reorder_levels": [
|
"reorder_levels": [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -9,4 +9,7 @@ import frappe
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class MaterialRequestItem(Document):
|
class MaterialRequestItem(Document):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def on_doctype_update():
|
||||||
|
frappe.db.add_index("Material Request Item", ["item_code", "warehouse"])
|
||||||
@ -103,4 +103,7 @@ def get_items_from_product_bundle(args):
|
|||||||
})
|
})
|
||||||
items.append(get_item_details(args))
|
items.append(get_item_details(args))
|
||||||
|
|
||||||
return items
|
return items
|
||||||
|
|
||||||
|
def on_doctype_update():
|
||||||
|
frappe.db.add_index("Packed Item", ["item_code", "warehouse"])
|
||||||
@ -337,3 +337,17 @@ def update_maintenance_status():
|
|||||||
doc = frappe.get_doc("Serial No", serial_no[0])
|
doc = frappe.get_doc("Serial No", serial_no[0])
|
||||||
doc.set_maintenance_status()
|
doc.set_maintenance_status()
|
||||||
frappe.db.set_value('Serial No', doc.name, 'maintenance_status', doc.maintenance_status)
|
frappe.db.set_value('Serial No', doc.name, 'maintenance_status', doc.maintenance_status)
|
||||||
|
|
||||||
|
def get_delivery_note_serial_no(item_code, qty, delivery_note):
|
||||||
|
serial_nos = ''
|
||||||
|
dn_serial_nos = frappe.db.sql_list(""" select name from `tabSerial No`
|
||||||
|
where item_code = %(item_code)s and delivery_document_no = %(delivery_note)s
|
||||||
|
and sales_invoice is null limit {0}""".format(cint(qty)), {
|
||||||
|
'item_code': item_code,
|
||||||
|
'delivery_note': delivery_note
|
||||||
|
})
|
||||||
|
|
||||||
|
if dn_serial_nos and len(dn_serial_nos)>0:
|
||||||
|
serial_nos = '\n'.join(dn_serial_nos)
|
||||||
|
|
||||||
|
return serial_nos
|
||||||
@ -13,11 +13,18 @@ def execute(filters=None):
|
|||||||
|
|
||||||
columns = get_columns()
|
columns = get_columns()
|
||||||
item_map = get_item_details(filters)
|
item_map = get_item_details(filters)
|
||||||
|
item_reorder_detail_map = get_item_reorder_details(filters)
|
||||||
iwb_map = get_item_warehouse_map(filters)
|
iwb_map = get_item_warehouse_map(filters)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
for (company, item, warehouse) in sorted(iwb_map):
|
for (company, item, warehouse) in sorted(iwb_map):
|
||||||
qty_dict = iwb_map[(company, item, warehouse)]
|
qty_dict = iwb_map[(company, item, warehouse)]
|
||||||
|
item_reorder_level = 0
|
||||||
|
item_reorder_qty = 0
|
||||||
|
if item + warehouse in item_reorder_detail_map:
|
||||||
|
item_reorder_level = item_reorder_detail_map[item + warehouse]["warehouse_reorder_level"]
|
||||||
|
item_reorder_qty = item_reorder_detail_map[item + warehouse]["warehouse_reorder_qty"]
|
||||||
|
|
||||||
data.append([item, item_map[item]["item_name"],
|
data.append([item, item_map[item]["item_name"],
|
||||||
item_map[item]["item_group"],
|
item_map[item]["item_group"],
|
||||||
item_map[item]["brand"],
|
item_map[item]["brand"],
|
||||||
@ -27,6 +34,8 @@ def execute(filters=None):
|
|||||||
qty_dict.in_val, qty_dict.out_qty,
|
qty_dict.in_val, qty_dict.out_qty,
|
||||||
qty_dict.out_val, qty_dict.bal_qty,
|
qty_dict.out_val, qty_dict.bal_qty,
|
||||||
qty_dict.bal_val, qty_dict.val_rate,
|
qty_dict.bal_val, qty_dict.val_rate,
|
||||||
|
item_reorder_level,
|
||||||
|
item_reorder_qty,
|
||||||
company
|
company
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -52,6 +61,8 @@ def get_columns():
|
|||||||
_("Balance Qty")+":Float:100",
|
_("Balance Qty")+":Float:100",
|
||||||
_("Balance Value")+":Float:100",
|
_("Balance Value")+":Float:100",
|
||||||
_("Valuation Rate")+":Float:90",
|
_("Valuation Rate")+":Float:90",
|
||||||
|
_("Reorder Level")+":Float:80",
|
||||||
|
_("Reorder Qty")+":Float:80",
|
||||||
_("Company")+":Link/Company:100"
|
_("Company")+":Link/Company:100"
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -180,7 +191,19 @@ def get_item_details(filters):
|
|||||||
items = frappe.db.sql("""select name, item_name, stock_uom, item_group, brand, description
|
items = frappe.db.sql("""select name, item_name, stock_uom, item_group, brand, description
|
||||||
from tabItem {condition}""".format(condition=condition), value, as_dict=1)
|
from tabItem {condition}""".format(condition=condition), value, as_dict=1)
|
||||||
|
|
||||||
return dict((d.name, d) for d in items)
|
return dict((d.name , d) for d in items)
|
||||||
|
|
||||||
|
def get_item_reorder_details(filters):
|
||||||
|
condition = ''
|
||||||
|
value = ()
|
||||||
|
if filters.get("item_code"):
|
||||||
|
condition = "where parent=%s"
|
||||||
|
value = (filters.get("item_code"),)
|
||||||
|
|
||||||
|
item_reorder_details = frappe.db.sql("""select parent,warehouse,warehouse_reorder_qty,warehouse_reorder_level
|
||||||
|
from `tabItem Reorder` {condition}""".format(condition=condition), value, as_dict=1)
|
||||||
|
|
||||||
|
return dict((d.parent + d.warehouse, d) for d in item_reorder_details)
|
||||||
|
|
||||||
def validate_filters(filters):
|
def validate_filters(filters):
|
||||||
if not (filters.get("item_code") or filters.get("warehouse")):
|
if not (filters.get("item_code") or filters.get("warehouse")):
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
frappe.query_reports["Support Hour Distribution"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
'lable': __("From Date"),
|
||||||
|
'fieldname': 'from_date',
|
||||||
|
'fieldtype': 'Date',
|
||||||
|
'default': frappe.datetime.nowdate(),
|
||||||
|
'reqd': 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'lable': __("To Date"),
|
||||||
|
'fieldname': 'to_date',
|
||||||
|
'fieldtype': 'Date',
|
||||||
|
'default': frappe.datetime.nowdate(),
|
||||||
|
'reqd': 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"add_total_row": 0,
|
"add_total_row": 0,
|
||||||
"apply_user_permissions": 1,
|
"apply_user_permissions": 1,
|
||||||
"creation": "2017-06-23 14:21:37.558691",
|
"creation": "2017-07-13 17:14:40.408706",
|
||||||
"disabled": 0,
|
"disabled": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Report",
|
"doctype": "Report",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": "Yes",
|
"is_standard": "Yes",
|
||||||
"letter_head": "",
|
"letter_head": "",
|
||||||
"modified": "2017-06-23 16:33:31.211390",
|
"modified": "2017-07-13 17:14:40.408706",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Support",
|
"module": "Support",
|
||||||
"name": "Support Hours",
|
"name": "Support Hour Distribution",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"ref_doctype": "Issue",
|
"ref_doctype": "Issue",
|
||||||
"report_name": "Support Hours",
|
"report_name": "Support Hour Distribution",
|
||||||
"report_type": "Script Report",
|
"report_type": "Script Report",
|
||||||
"roles": [
|
"roles": [
|
||||||
{
|
{
|
||||||
@ -23,12 +23,14 @@ def execute(filters=None):
|
|||||||
filters['periodicity'] = 'Daily'
|
filters['periodicity'] = 'Daily'
|
||||||
|
|
||||||
columns = get_columns()
|
columns = get_columns()
|
||||||
data = get_data(filters)
|
data, timeslot_wise_count = get_data(filters)
|
||||||
return columns, data
|
chart = get_chartdata(timeslot_wise_count)
|
||||||
|
return columns, data, None, chart
|
||||||
|
|
||||||
def get_data(filters):
|
def get_data(filters):
|
||||||
start_date = getdate(filters.from_date)
|
start_date = getdate(filters.from_date)
|
||||||
data = []
|
data = []
|
||||||
|
time_slot_wise_total_count = {}
|
||||||
while(start_date <= getdate(filters.to_date)):
|
while(start_date <= getdate(filters.to_date)):
|
||||||
hours_count = {'date': start_date}
|
hours_count = {'date': start_date}
|
||||||
for key, value in time_slots.items():
|
for key, value in time_slots.items():
|
||||||
@ -36,13 +38,14 @@ def get_data(filters):
|
|||||||
start_time = get_datetime("{0} {1}".format(start_date.strftime("%Y-%m-%d"), start_time))
|
start_time = get_datetime("{0} {1}".format(start_date.strftime("%Y-%m-%d"), start_time))
|
||||||
end_time = get_datetime("{0} {1}".format(start_date.strftime("%Y-%m-%d"), end_time))
|
end_time = get_datetime("{0} {1}".format(start_date.strftime("%Y-%m-%d"), end_time))
|
||||||
hours_count[key] = get_hours_count(start_time, end_time)
|
hours_count[key] = get_hours_count(start_time, end_time)
|
||||||
|
time_slot_wise_total_count[key] = time_slot_wise_total_count.get(key, 0) + hours_count[key]
|
||||||
|
|
||||||
if hours_count:
|
if hours_count:
|
||||||
data.append(hours_count)
|
data.append(hours_count)
|
||||||
|
|
||||||
start_date = add_to_date(start_date, days=1)
|
start_date = add_to_date(start_date, days=1)
|
||||||
|
|
||||||
return data
|
return data, time_slot_wise_total_count
|
||||||
|
|
||||||
def get_hours_count(start_time, end_time):
|
def get_hours_count(start_time, end_time):
|
||||||
data = frappe.db.sql(""" select count(*) from `tabIssue` where creation
|
data = frappe.db.sql(""" select count(*) from `tabIssue` where creation
|
||||||
@ -70,4 +73,25 @@ def get_columns():
|
|||||||
"width": 120
|
"width": 120
|
||||||
})
|
})
|
||||||
|
|
||||||
return columns
|
return columns
|
||||||
|
|
||||||
|
def get_chartdata(timeslot_wise_count):
|
||||||
|
x_interval = ['x']
|
||||||
|
total_count = ['Total']
|
||||||
|
timeslots = ['12AM - 3AM', '3AM - 6AM', '6AM - 9AM',
|
||||||
|
'9AM - 12PM', '12PM - 3PM', '3PM - 6PM', '6PM - 9PM', '9PM - 12AM']
|
||||||
|
|
||||||
|
x_interval.extend(timeslots)
|
||||||
|
columns = [x_interval]
|
||||||
|
for data in timeslots:
|
||||||
|
total_count.append(timeslot_wise_count.get(data, 0))
|
||||||
|
columns.append(total_count)
|
||||||
|
|
||||||
|
chart = {
|
||||||
|
"data": {
|
||||||
|
'x': 'x',
|
||||||
|
'columns': columns
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chart["chart_type"] = "line"
|
||||||
|
return chart
|
||||||
@ -1,39 +0,0 @@
|
|||||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
frappe.query_reports["Support Hours"] = {
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
'lable': __("From Date"),
|
|
||||||
'fieldname': 'from_date',
|
|
||||||
'fieldtype': 'Date',
|
|
||||||
'default': frappe.datetime.nowdate(),
|
|
||||||
'reqd': 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'lable': __("To Date"),
|
|
||||||
'fieldname': 'to_date',
|
|
||||||
'fieldtype': 'Date',
|
|
||||||
'default': frappe.datetime.nowdate(),
|
|
||||||
'reqd': 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
get_chart_data: function(columns, result) {
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
x: 'Date',
|
|
||||||
columns: [
|
|
||||||
['Date'].concat($.map(result, function(d) { return d.date; })),
|
|
||||||
[columns[3].label].concat($.map(result, function(d) { return d[columns[3].label]; })),
|
|
||||||
[columns[4].label].concat($.map(result, function(d) { return d[columns[4].label]; })),
|
|
||||||
[columns[5].label].concat($.map(result, function(d) { return d[columns[5].label]; })),
|
|
||||||
[columns[6].label].concat($.map(result, function(d) { return d[columns[6].label]; })),
|
|
||||||
[columns[7].label].concat($.map(result, function(d) { return d[columns[7].label]; }))
|
|
||||||
]
|
|
||||||
},
|
|
||||||
chart_type: 'bar',
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
59
erpnext/templates/emails/daily_work_summary.html
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<div style="color: #333; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; word-wrap: break-word; overflow-wrap: break-word;">
|
||||||
|
<h3>{{ title }}</h3>
|
||||||
|
</div>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
{% for reply in replies %}
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%"
|
||||||
|
style="background-color: #fafbfc; border: 1px solid #d1d8dd; border-radius: 3px 3px 0 0">
|
||||||
|
<tr height="10"></tr>
|
||||||
|
<tr>
|
||||||
|
<td width="15"></td>
|
||||||
|
<td valign="top" width="24">
|
||||||
|
{% if reply.image %}
|
||||||
|
<img width="24" height="24" embed="{{ reply.image }}" style="border-radius: 3px; vertical-align: middle;" />
|
||||||
|
{% else %}
|
||||||
|
<div style="width: 24px; height: 24px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;background: #fff; border-radius: 3px; border: 1px solid #d1d8dd; text-align: center; line-height: 24px; color: #d1d8dd;">
|
||||||
|
{{ reply.sender_name[0] }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td width="10"></td>
|
||||||
|
<td>
|
||||||
|
<div style="font-size: 12px; color: #8D99A6; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; word-wrap: break-word; line-height: 22px; overflow-wrap: break-word; text-decoration: none;">
|
||||||
|
<span>{{ reply.sender_name }}</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td width="15"></td>
|
||||||
|
</tr>
|
||||||
|
<tr height="10"></tr>
|
||||||
|
</table>
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%"
|
||||||
|
style="background-color: #fff; border: 1px solid #d1d8dd; border-top: none; border-radius: 0 0 3px 3px">
|
||||||
|
<tr height="10"></tr>
|
||||||
|
<tr>
|
||||||
|
<td width="15"></td>
|
||||||
|
<td>
|
||||||
|
<div style="font-size: 14px; color: #333; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; word-wrap: break-word; line-height: 22px; overflow-wrap: break-word; text-decoration: none;">
|
||||||
|
{{ reply.content }}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td width="15"></td>
|
||||||
|
</tr>
|
||||||
|
<tr height="10"></tr>
|
||||||
|
</table>
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||||
|
<tr height="20"></tr>
|
||||||
|
</table>
|
||||||
|
{% endfor %}
|
||||||
|
{% if did_not_reply %}
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<div style="font-size: 14px; color: #8D99A6; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; word-wrap: break-word; line-height: 22px; overflow-wrap: break-word; text-decoration: none;">
|
||||||
|
<p>{{ did_not_reply_title }}: {{ did_not_reply }}</p>
|
||||||
|
</div>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
11
erpnext/templates/emails/daily_work_summary.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{{ title }}
|
||||||
|
|
||||||
|
{% for reply in replies %}
|
||||||
|
{{ reply.sender_name }}:
|
||||||
|
{{ reply.content }}
|
||||||
|
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% if did_not_reply %}
|
||||||
|
{{ did_not_reply_title }}: {{ did_not_reply }}
|
||||||
|
{% endif %}
|
||||||
38
erpnext/templates/includes/itemised_tax_breakup.html
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<div class="tax-break-up" style="overflow-x: auto;">
|
||||||
|
<table class="table table-bordered table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{% set i = 0 %}
|
||||||
|
{% for key in headers %}
|
||||||
|
{% if i==0 %}
|
||||||
|
<th style="min-width: 120px;" class="text-left">{{ key }}</th>
|
||||||
|
{% else %}
|
||||||
|
<th style="min-width: 80px;" class="text-right">{{ key }}</th>
|
||||||
|
{% endif %}
|
||||||
|
{% set i = i + 1 %}
|
||||||
|
{% endfor%}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item, taxes in itemised_tax.items() %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ item }}</td>
|
||||||
|
<td class='text-right'>
|
||||||
|
{{ frappe.utils.fmt_money(itemised_taxable_amount.get(item), None, company_currency) }}
|
||||||
|
</td>
|
||||||
|
{% for tax_account in tax_accounts %}
|
||||||
|
{% set tax_details = taxes.get(tax_account) %}
|
||||||
|
{% if tax_details %}
|
||||||
|
<td class='text-right'>
|
||||||
|
({{ tax_details.tax_rate }})
|
||||||
|
{{ frappe.utils.fmt_money(tax_details.tax_amount, None, company_currency) }}
|
||||||
|
</td>
|
||||||
|
{% else %}
|
||||||
|
<td></td>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
46
erpnext/tests/test_notifications.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# MIT License. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from frappe.desk import notifications
|
||||||
|
from frappe.test_runner import make_test_objects
|
||||||
|
|
||||||
|
class TestNotifications(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
test_records = [
|
||||||
|
{
|
||||||
|
"abbr": "_TC6",
|
||||||
|
"company_name": "_Test Company 6",
|
||||||
|
"country": "India",
|
||||||
|
"default_currency": "INR",
|
||||||
|
"doctype": "Company",
|
||||||
|
"domain": "Manufacturing",
|
||||||
|
"sales_target": 2000,
|
||||||
|
"chart_of_accounts": "Standard"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"abbr": "_TC7",
|
||||||
|
"company_name": "_Test Company 7",
|
||||||
|
"country": "United States",
|
||||||
|
"default_currency": "USD",
|
||||||
|
"doctype": "Company",
|
||||||
|
"domain": "Retail",
|
||||||
|
"sales_target": 10000,
|
||||||
|
"total_monthly_sales": 1000,
|
||||||
|
"chart_of_accounts": "Standard"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
make_test_objects('Company', test_records=test_records, reset=True)
|
||||||
|
|
||||||
|
def test_get_notifications_for_targets(self):
|
||||||
|
'''
|
||||||
|
Test notification config entries for targets as percentages
|
||||||
|
'''
|
||||||
|
|
||||||
|
config = notifications.get_notification_config()
|
||||||
|
doc_target_percents = notifications.get_notifications_for_targets(config, {})
|
||||||
|
self.assertEquals(doc_target_percents['Company']['_Test Company 7'], 10)
|
||||||
|
self.assertEquals(doc_target_percents['Company']['_Test Company 6'], 0)
|
||||||
13
erpnext/tests/test_regional.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import unittest, frappe, erpnext
|
||||||
|
|
||||||
|
@erpnext.allow_regional
|
||||||
|
def test_method():
|
||||||
|
return 'original'
|
||||||
|
|
||||||
|
class TestInit(unittest.TestCase):
|
||||||
|
def test_regional_overrides(self):
|
||||||
|
frappe.flags.country = 'India'
|
||||||
|
self.assertEqual(test_method(), 'overridden')
|
||||||
|
|
||||||
|
frappe.flags.country = 'Nepal'
|
||||||
|
self.assertEqual(test_method(), 'original')
|
||||||
27
erpnext/tests/ui/accounts/test_account.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
QUnit.module('accounts');
|
||||||
|
|
||||||
|
QUnit.test("test account", function(assert) {
|
||||||
|
assert.expect(4);
|
||||||
|
let done = assert.async();
|
||||||
|
frappe.run_serially([
|
||||||
|
() => frappe.set_route('Tree', 'Account'),
|
||||||
|
() => frappe.tests.click_button('Expand All'),
|
||||||
|
() => frappe.tests.click_link('Debtors'),
|
||||||
|
() => frappe.tests.click_button('Edit'),
|
||||||
|
() => frappe.timeout(1),
|
||||||
|
() => {
|
||||||
|
assert.ok(cur_frm.doc.root_type=='Asset');
|
||||||
|
assert.ok(cur_frm.doc.report_type=='Balance Sheet');
|
||||||
|
assert.ok(cur_frm.doc.account_type=='Receivable');
|
||||||
|
},
|
||||||
|
() => frappe.tests.click_button('Ledger'),
|
||||||
|
() => frappe.timeout(1),
|
||||||
|
() => {
|
||||||
|
// check if general ledger report shown
|
||||||
|
assert.deepEqual(frappe.get_route(), ['query-report', 'General Ledger']);
|
||||||
|
window.history.back();
|
||||||
|
return frappe.timeout(1);
|
||||||
|
},
|
||||||
|
() => done()
|
||||||
|
]);
|
||||||
|
});
|
||||||
18
erpnext/tests/ui/selling/_test_lead.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
QUnit.module("sales");
|
||||||
|
|
||||||
|
QUnit.test("test: lead", function (assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
let done = assert.async();
|
||||||
|
let random = frappe.utils.get_random(10);
|
||||||
|
frappe.run_serially([
|
||||||
|
() => frappe.tests.setup_doctype("Lead"),
|
||||||
|
() => frappe.set_route("List", "Lead"),
|
||||||
|
() => frappe.new_doc("Lead"),
|
||||||
|
() => cur_frm.set_value("lead_name", random),
|
||||||
|
() => cur_frm.save(),
|
||||||
|
() => {
|
||||||
|
assert.ok(cur_frm.doc.lead_name.includes(random));
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
19
erpnext/tests/ui/selling/_test_opportunity.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
QUnit.test("test: opportunity", function (assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
let done = assert.async();
|
||||||
|
frappe.run_serially([
|
||||||
|
() => {
|
||||||
|
return frappe.tests.make("Opportunity", [{
|
||||||
|
enquiry_from: "Lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lead: "LEAD-00002"
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
assert.ok(cur_frm.doc.lead === "LEAD-00002");
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
@ -1,42 +1,3 @@
|
|||||||
QUnit.module("sales");
|
|
||||||
|
|
||||||
QUnit.test("test: lead", function (assert) {
|
|
||||||
assert.expect(1);
|
|
||||||
let done = assert.async();
|
|
||||||
let random = frappe.utils.get_random(10);
|
|
||||||
frappe.run_serially([
|
|
||||||
() => frappe.tests.setup_doctype("Lead"),
|
|
||||||
() => frappe.set_route("List", "Lead"),
|
|
||||||
() => frappe.new_doc("Lead"),
|
|
||||||
() => cur_frm.set_value("lead_name", random),
|
|
||||||
() => cur_frm.save(),
|
|
||||||
() => {
|
|
||||||
assert.ok(cur_frm.doc.lead_name.includes(random));
|
|
||||||
return done();
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
QUnit.test("test: opportunity", function (assert) {
|
|
||||||
assert.expect(1);
|
|
||||||
let done = assert.async();
|
|
||||||
frappe.run_serially([
|
|
||||||
() => {
|
|
||||||
return frappe.tests.make("Opportunity", [{
|
|
||||||
enquiry_from: "Lead"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lead: "LEAD-00002"
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
assert.ok(cur_frm.doc.lead === "LEAD-00002");
|
|
||||||
return done();
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
QUnit.test("test: quotation", function (assert) {
|
QUnit.test("test: quotation", function (assert) {
|
||||||
assert.expect(18);
|
assert.expect(18);
|
||||||
let done = assert.async();
|
let done = assert.async();
|
||||||
@ -5,15 +5,15 @@ apps/erpnext/erpnext/accounts/report/bank_reconciliation_statement/bank_reconcil
|
|||||||
DocType: Assessment Group,Parent Assessment Group,Grupo de Evaluación Padre
|
DocType: Assessment Group,Parent Assessment Group,Grupo de Evaluación Padre
|
||||||
DocType: Student,Guardians,Guardianes
|
DocType: Student,Guardians,Guardianes
|
||||||
DocType: Program,Fee Schedule,Programa de Tarifas
|
DocType: Program,Fee Schedule,Programa de Tarifas
|
||||||
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +658,Get Items from Product Bundle,Obtener Ítems de Paquete de Productos
|
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +666,Get Items from Product Bundle,Obtener Ítems de Paquete de Productos
|
||||||
apps/erpnext/erpnext/schools/doctype/fees/fees.js +26,Collect Fees,Cobrar Tarifas
|
apps/erpnext/erpnext/schools/doctype/fees/fees.js +26,Collect Fees,Cobrar Tarifas
|
||||||
apps/erpnext/erpnext/stock/doctype/material_request/material_request.js +874,BOM does not contain any stock item,BOM no contiene ningún ítem de stock
|
apps/erpnext/erpnext/stock/doctype/material_request/material_request.js +882,BOM does not contain any stock item,BOM no contiene ningún ítem de stock
|
||||||
DocType: Homepage,Company Tagline for website homepage,Lema de la empresa para la página de inicio del sitio web
|
DocType: Homepage,Company Tagline for website homepage,Lema de la empresa para la página de inicio del sitio web
|
||||||
DocType: Delivery Note,% Installed,% Instalado
|
DocType: Delivery Note,% Installed,% Instalado
|
||||||
DocType: Student,Guardian Details,Detalles del Guardián
|
DocType: Student,Guardian Details,Detalles del Guardián
|
||||||
apps/erpnext/erpnext/schools/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py +55,Guardian1 Name,Nombre de Guardián 1
|
apps/erpnext/erpnext/schools/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py +55,Guardian1 Name,Nombre de Guardián 1
|
||||||
DocType: Grading Scale Interval,Grade Code,Grado de Código
|
DocType: Grading Scale Interval,Grade Code,Grado de Código
|
||||||
apps/erpnext/erpnext/accounts/party.py +257,Billing currency must be equal to either default comapany's currency or party account currency,La moneda de facturación debe ser igual a la moneda por defecto de la compañía o la moneda de la cuenta de la parte
|
apps/erpnext/erpnext/accounts/party.py +259,Billing currency must be equal to either default comapany's currency or party account currency,La moneda de facturación debe ser igual a la moneda por defecto de la compañía o la moneda de la cuenta de la parte
|
||||||
DocType: Fee Structure,Fee Structure,Estructura de Tarifas
|
DocType: Fee Structure,Fee Structure,Estructura de Tarifas
|
||||||
apps/erpnext/erpnext/schools/doctype/course_scheduling_tool/course_scheduling_tool.py +50,Course Schedules created:,Calendario de Cursos creado:
|
apps/erpnext/erpnext/schools/doctype/course_scheduling_tool/course_scheduling_tool.py +50,Course Schedules created:,Calendario de Cursos creado:
|
||||||
DocType: Purchase Order,Get Items from Open Material Requests,Obtener Ítems de Solicitudes Abiertas de Materiales
|
DocType: Purchase Order,Get Items from Open Material Requests,Obtener Ítems de Solicitudes Abiertas de Materiales
|
||||||
|
|||||||
|
@ -1,6 +1,6 @@
|
|||||||
DocType: Delivery Note,% Installed,% Instalado
|
DocType: Delivery Note,% Installed,% Instalado
|
||||||
DocType: Sales Order,SO-,OV-
|
DocType: Sales Order,SO-,OV-
|
||||||
apps/erpnext/erpnext/hr/doctype/salary_structure/salary_structure.js +438,Show Salary Slip,Mostrar recibo de nómina
|
apps/erpnext/erpnext/hr/doctype/salary_structure/salary_structure.js +446,Show Salary Slip,Mostrar recibo de nómina
|
||||||
DocType: Purchase Taxes and Charges Template,"Standard tax template that can be applied to all Purchase Transactions. This template can contain list of tax heads and also other expense heads like ""Shipping"", ""Insurance"", ""Handling"" etc.
|
DocType: Purchase Taxes and Charges Template,"Standard tax template that can be applied to all Purchase Transactions. This template can contain list of tax heads and also other expense heads like ""Shipping"", ""Insurance"", ""Handling"" etc.
|
||||||
|
|
||||||
#### Note
|
#### Note
|
||||||
|
|||||||
|
@ -11,7 +11,7 @@ apps/erpnext/erpnext/accounts/doctype/tax_rule/tax_rule.py +86,Tax Rule Conflict
|
|||||||
DocType: Tax Rule,Billing County,Municipio de Facturación
|
DocType: Tax Rule,Billing County,Municipio de Facturación
|
||||||
DocType: Sales Invoice Timesheet,Billing Hours,Horas de Facturación
|
DocType: Sales Invoice Timesheet,Billing Hours,Horas de Facturación
|
||||||
DocType: Timesheet,Billing Details,Detalles de Facturación
|
DocType: Timesheet,Billing Details,Detalles de Facturación
|
||||||
apps/erpnext/erpnext/accounts/party.py +257,Billing currency must be equal to either default comapany's currency or party account currency,Moneda de facturación debe ser igual a la moneda de la empresa o moneda de cuenta de contraparte
|
apps/erpnext/erpnext/accounts/party.py +259,Billing currency must be equal to either default comapany's currency or party account currency,Moneda de facturación debe ser igual a la moneda de la empresa o moneda de cuenta de contraparte
|
||||||
DocType: Tax Rule,Billing State,Región de Facturación
|
DocType: Tax Rule,Billing State,Región de Facturación
|
||||||
DocType: Purchase Order Item,Billed Amt,Monto Facturado
|
DocType: Purchase Order Item,Billed Amt,Monto Facturado
|
||||||
DocType: Item Tax,Tax Rate,Tasa de Impuesto
|
DocType: Item Tax,Tax Rate,Tasa de Impuesto
|
||||||
|
|||||||
|
@ -59,7 +59,7 @@ DocType: Task,depends_on,depende de
|
|||||||
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +155,Secured Loans,Préstamos Garantizados
|
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +155,Secured Loans,Préstamos Garantizados
|
||||||
apps/erpnext/erpnext/hr/doctype/leave_application/leave_application.py +224,Only the selected Leave Approver can submit this Leave Application,Sólo el Supervisor de Vacaciones seleccionado puede presentar esta solicitud de permiso
|
apps/erpnext/erpnext/hr/doctype/leave_application/leave_application.py +224,Only the selected Leave Approver can submit this Leave Application,Sólo el Supervisor de Vacaciones seleccionado puede presentar esta solicitud de permiso
|
||||||
apps/erpnext/erpnext/setup/doctype/territory/territory.js +13,This is a root territory and cannot be edited.,Este es un territorio raíz y no se puede editar .
|
apps/erpnext/erpnext/setup/doctype/territory/territory.js +13,This is a root territory and cannot be edited.,Este es un territorio raíz y no se puede editar .
|
||||||
apps/erpnext/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js +788,Make Supplier Quotation,Crear cotización de proveedor
|
apps/erpnext/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js +796,Make Supplier Quotation,Crear cotización de proveedor
|
||||||
apps/erpnext/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py +61,Repeat Customer Revenue,Repita los ingresos de los clientes
|
apps/erpnext/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py +61,Repeat Customer Revenue,Repita los ingresos de los clientes
|
||||||
apps/erpnext/erpnext/accounts/doctype/cost_center/cost_center_tree.js +22,New Cost Center Name,Nombre de Nuevo Centro de Coste
|
apps/erpnext/erpnext/accounts/doctype/cost_center/cost_center_tree.js +22,New Cost Center Name,Nombre de Nuevo Centro de Coste
|
||||||
DocType: Purchase Taxes and Charges,"If checked, the tax amount will be considered as already included in the Print Rate / Print Amount","Si se selecciona, el importe del impuesto se considerará como ya incluido en el Monto a Imprimir"
|
DocType: Purchase Taxes and Charges,"If checked, the tax amount will be considered as already included in the Print Rate / Print Amount","Si se selecciona, el importe del impuesto se considerará como ya incluido en el Monto a Imprimir"
|
||||||
@ -113,7 +113,7 @@ apps/erpnext/erpnext/stock/doctype/packing_slip/packing_slip.py +65,Case No(s) a
|
|||||||
apps/erpnext/erpnext/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.js +27,Target On,Objetivo On
|
apps/erpnext/erpnext/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.js +27,Target On,Objetivo On
|
||||||
apps/erpnext/erpnext/accounts/doctype/pricing_rule/pricing_rule.js +23,"To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled.","Para no aplicar la Regla de Precios en una transacción en particular, todas las Reglas de Precios aplicables deben ser desactivadas."
|
apps/erpnext/erpnext/accounts/doctype/pricing_rule/pricing_rule.js +23,"To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled.","Para no aplicar la Regla de Precios en una transacción en particular, todas las Reglas de Precios aplicables deben ser desactivadas."
|
||||||
apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py +162,"Sorry, Serial Nos cannot be merged","Lo sentimos , Nos de serie no se puede fusionar"
|
apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py +162,"Sorry, Serial Nos cannot be merged","Lo sentimos , Nos de serie no se puede fusionar"
|
||||||
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +766,Make ,Hacer
|
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +774,Make ,Hacer
|
||||||
DocType: Manufacturing Settings,Manufacturing Settings,Ajustes de Manufactura
|
DocType: Manufacturing Settings,Manufacturing Settings,Ajustes de Manufactura
|
||||||
DocType: Appraisal Template,Appraisal Template Title,Titulo de la Plantilla deEvaluación
|
DocType: Appraisal Template,Appraisal Template Title,Titulo de la Plantilla deEvaluación
|
||||||
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +130,Row {0}: Please check 'Is Advance' against Account {1} if this is an advance entry.,"Fila {0}: Por favor, consulte ""¿Es Avance 'contra la Cuenta {1} si se trata de una entrada con antelación."
|
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +130,Row {0}: Please check 'Is Advance' against Account {1} if this is an advance entry.,"Fila {0}: Por favor, consulte ""¿Es Avance 'contra la Cuenta {1} si se trata de una entrada con antelación."
|
||||||
@ -129,7 +129,7 @@ DocType: Project,Default Cost Center,Centro de coste por defecto
|
|||||||
DocType: Employee,Employee Number,Número del Empleado
|
DocType: Employee,Employee Number,Número del Empleado
|
||||||
DocType: Opportunity,Customer / Lead Address,Cliente / Dirección de Oportunidad
|
DocType: Opportunity,Customer / Lead Address,Cliente / Dirección de Oportunidad
|
||||||
DocType: Quotation,In Words will be visible once you save the Quotation.,En palabras serán visibles una vez que guarde la cotización.
|
DocType: Quotation,In Words will be visible once you save the Quotation.,En palabras serán visibles una vez que guarde la cotización.
|
||||||
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.py +270,Installation Note {0} has already been submitted,La nota de instalación {0} ya se ha presentado
|
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.py +272,Installation Note {0} has already been submitted,La nota de instalación {0} ya se ha presentado
|
||||||
DocType: Employee,The first Leave Approver in the list will be set as the default Leave Approver,El primer Administrador de Vacaciones in la lista sera definido como el Administrador de Vacaciones predeterminado.
|
DocType: Employee,The first Leave Approver in the list will be set as the default Leave Approver,El primer Administrador de Vacaciones in la lista sera definido como el Administrador de Vacaciones predeterminado.
|
||||||
apps/erpnext/erpnext/config/selling.py +105,Manage Territory Tree.,Vista en árbol para la administración de los territorios
|
apps/erpnext/erpnext/config/selling.py +105,Manage Territory Tree.,Vista en árbol para la administración de los territorios
|
||||||
apps/erpnext/erpnext/stock/utils.py +200,Serial number {0} entered more than once,Número de serie {0} entraron más de una vez
|
apps/erpnext/erpnext/stock/utils.py +200,Serial number {0} entered more than once,Número de serie {0} entraron más de una vez
|
||||||
@ -148,7 +148,7 @@ apps/erpnext/erpnext/accounts/doctype/cost_center/cost_center.py +24,Root cannot
|
|||||||
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +397,Accounting Entry for Stock,Asiento contable de inventario
|
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +397,Accounting Entry for Stock,Asiento contable de inventario
|
||||||
DocType: Project,Total Purchase Cost (via Purchase Invoice),Coste total de compra (mediante compra de la factura)
|
DocType: Project,Total Purchase Cost (via Purchase Invoice),Coste total de compra (mediante compra de la factura)
|
||||||
apps/erpnext/erpnext/controllers/buying_controller.py +287,Row {0}: Conversion Factor is mandatory,Fila {0}: Factor de conversión es obligatoria
|
apps/erpnext/erpnext/controllers/buying_controller.py +287,Row {0}: Conversion Factor is mandatory,Fila {0}: Factor de conversión es obligatoria
|
||||||
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +795,Purchase Receipt,Recibos de Compra
|
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +803,Purchase Receipt,Recibos de Compra
|
||||||
DocType: Pricing Rule,Disable,Inhabilitar
|
DocType: Pricing Rule,Disable,Inhabilitar
|
||||||
DocType: Item Website Specification,Table for Item that will be shown in Web Site,Tabla de Artículo que se muestra en el Sitio Web
|
DocType: Item Website Specification,Table for Item that will be shown in Web Site,Tabla de Artículo que se muestra en el Sitio Web
|
||||||
DocType: Attendance,Leave Type,Tipo de Vacaciones
|
DocType: Attendance,Leave Type,Tipo de Vacaciones
|
||||||
@ -182,7 +182,7 @@ apps/erpnext/erpnext/setup/doctype/sales_person/sales_person.py +16,Either targe
|
|||||||
apps/erpnext/erpnext/controllers/sales_and_purchase_return.py +80,Row # {0}: Returned Item {1} does not exists in {2} {3},Fila # {0}: El artículo vuelto {1} no existe en {2} {3}
|
apps/erpnext/erpnext/controllers/sales_and_purchase_return.py +80,Row # {0}: Returned Item {1} does not exists in {2} {3},Fila # {0}: El artículo vuelto {1} no existe en {2} {3}
|
||||||
DocType: Production Order,Not Started,Sin comenzar
|
DocType: Production Order,Not Started,Sin comenzar
|
||||||
DocType: Company,Default Currency,Moneda Predeterminada
|
DocType: Company,Default Currency,Moneda Predeterminada
|
||||||
apps/erpnext/erpnext/accounts/doctype/account/account.js +26,This is a root account and cannot be edited.,Esta es una cuenta raíz y no se puede editar .
|
apps/erpnext/erpnext/accounts/doctype/account/account.js +41,This is a root account and cannot be edited.,Esta es una cuenta raíz y no se puede editar .
|
||||||
,Requested Items To Be Transferred,Artículos solicitados para ser transferido
|
,Requested Items To Be Transferred,Artículos solicitados para ser transferido
|
||||||
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +230,Purchase Receipt {0} is not submitted,Recibo de Compra {0} no se presenta
|
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +230,Purchase Receipt {0} is not submitted,Recibo de Compra {0} no se presenta
|
||||||
apps/erpnext/erpnext/controllers/accounts_controller.py +689,Account: {0} with currency: {1} can not be selected,Cuenta: {0} con moneda: {1} no puede ser seleccionada
|
apps/erpnext/erpnext/controllers/accounts_controller.py +689,Account: {0} with currency: {1} can not be selected,Cuenta: {0} con moneda: {1} no puede ser seleccionada
|
||||||
@ -190,7 +190,7 @@ DocType: Tax Rule,Sales,Venta
|
|||||||
DocType: Purchase Invoice,Additional Discount Amount (Company Currency),Monto adicional de descuento (Moneda de la compañía)
|
DocType: Purchase Invoice,Additional Discount Amount (Company Currency),Monto adicional de descuento (Moneda de la compañía)
|
||||||
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +132,Row {0}: Payment against Sales/Purchase Order should always be marked as advance,Fila {0}: El pago de Compra/Venta siempre debe estar marcado como anticipo
|
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +132,Row {0}: Payment against Sales/Purchase Order should always be marked as advance,Fila {0}: El pago de Compra/Venta siempre debe estar marcado como anticipo
|
||||||
DocType: Employee,Leave Approvers,Supervisores de Vacaciones
|
DocType: Employee,Leave Approvers,Supervisores de Vacaciones
|
||||||
apps/erpnext/erpnext/accounts/doctype/payment_entry/payment_entry.js +149,Please specify a valid Row ID for row {0} in table {1},"Por favor, especifique un ID de fila válida para la fila {0} en la tabla {1}"
|
apps/erpnext/erpnext/accounts/doctype/payment_entry/payment_entry.js +157,Please specify a valid Row ID for row {0} in table {1},"Por favor, especifique un ID de fila válida para la fila {0} en la tabla {1}"
|
||||||
DocType: Customer Group,Parent Customer Group,Categoría de cliente principal
|
DocType: Customer Group,Parent Customer Group,Categoría de cliente principal
|
||||||
apps/erpnext/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +25,Total Outstanding Amount,Total Monto Pendiente
|
apps/erpnext/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +25,Total Outstanding Amount,Total Monto Pendiente
|
||||||
DocType: Sales Partner,Select Monthly Distribution to unevenly distribute targets across months.,Seleccione Distribución Mensual de distribuir de manera desigual a través de objetivos meses.
|
DocType: Sales Partner,Select Monthly Distribution to unevenly distribute targets across months.,Seleccione Distribución Mensual de distribuir de manera desigual a través de objetivos meses.
|
||||||
@ -209,11 +209,11 @@ DocType: BOM,Raw Material Cost,Costo de la Materia Prima
|
|||||||
apps/erpnext/erpnext/selling/doctype/customer/customer.py +115,A Customer Group exists with same name please change the Customer name or rename the Customer Group,"Existe una categoría de cliente con el mismo nombre, por favor cambie el nombre del cliente o cambie el nombre de la categoría"
|
apps/erpnext/erpnext/selling/doctype/customer/customer.py +115,A Customer Group exists with same name please change the Customer name or rename the Customer Group,"Existe una categoría de cliente con el mismo nombre, por favor cambie el nombre del cliente o cambie el nombre de la categoría"
|
||||||
apps/erpnext/erpnext/config/hr.py +147,Template for performance appraisals.,Plantilla para las evaluaciones de desempeño .
|
apps/erpnext/erpnext/config/hr.py +147,Template for performance appraisals.,Plantilla para las evaluaciones de desempeño .
|
||||||
DocType: SMS Settings,"Enter static url parameters here (Eg. sender=ERPNext, username=ERPNext, password=1234 etc.)","Introduzca los parámetros de URL estáticas aquí (Ej. sender = ERPNext , nombre de usuario = ERPNext , contraseña = 1234 etc )"
|
DocType: SMS Settings,"Enter static url parameters here (Eg. sender=ERPNext, username=ERPNext, password=1234 etc.)","Introduzca los parámetros de URL estáticas aquí (Ej. sender = ERPNext , nombre de usuario = ERPNext , contraseña = 1234 etc )"
|
||||||
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +149,Quotation {0} is cancelled,Cotización {0} se cancela
|
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +150,Quotation {0} is cancelled,Cotización {0} se cancela
|
||||||
apps/erpnext/erpnext/controllers/stock_controller.py +331,Quality Inspection required for Item {0},Inspección de la calidad requerida para el articulo {0}
|
apps/erpnext/erpnext/controllers/stock_controller.py +331,Quality Inspection required for Item {0},Inspección de la calidad requerida para el articulo {0}
|
||||||
apps/erpnext/erpnext/public/js/setup_wizard.js +94,What does it do?,¿Qué hace?
|
apps/erpnext/erpnext/public/js/setup_wizard.js +94,What does it do?,¿Qué hace?
|
||||||
DocType: Task,Actual Time (in Hours),Tiempo actual (En horas)
|
DocType: Task,Actual Time (in Hours),Tiempo actual (En horas)
|
||||||
apps/erpnext/erpnext/selling/doctype/quotation/quotation.js +707,Make Sales Order,Hacer Orden de Venta
|
apps/erpnext/erpnext/selling/doctype/quotation/quotation.js +716,Make Sales Order,Hacer Orden de Venta
|
||||||
apps/erpnext/erpnext/public/js/setup_wizard.js +244,List a few of your customers. They could be organizations or individuals.,Enumere algunos de sus clientes. Pueden ser organizaciones o individuos.
|
apps/erpnext/erpnext/public/js/setup_wizard.js +244,List a few of your customers. They could be organizations or individuals.,Enumere algunos de sus clientes. Pueden ser organizaciones o individuos.
|
||||||
DocType: Item Customer Detail,Ref Code,Código Referencia
|
DocType: Item Customer Detail,Ref Code,Código Referencia
|
||||||
DocType: Item,Default Selling Cost Center,Centros de coste por defecto
|
DocType: Item,Default Selling Cost Center,Centros de coste por defecto
|
||||||
@ -262,7 +262,7 @@ apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +534,Row No
|
|||||||
DocType: Offer Letter Term,Offer Letter Term,Término de carta de oferta
|
DocType: Offer Letter Term,Offer Letter Term,Término de carta de oferta
|
||||||
DocType: Item,Synced With Hub,Sincronizado con Hub
|
DocType: Item,Synced With Hub,Sincronizado con Hub
|
||||||
apps/erpnext/erpnext/accounts/doctype/cost_center/cost_center.py +30,Cost Center with existing transactions can not be converted to ledger,Centro de Costos de las transacciones existentes no se puede convertir en el libro mayor
|
apps/erpnext/erpnext/accounts/doctype/cost_center/cost_center.py +30,Cost Center with existing transactions can not be converted to ledger,Centro de Costos de las transacciones existentes no se puede convertir en el libro mayor
|
||||||
apps/erpnext/erpnext/public/js/controllers/transaction.js +1086,Please enter Item Code to get batch no,"Por favor, ingrese el código del producto para obtener el No. de lote"
|
apps/erpnext/erpnext/public/js/controllers/transaction.js +1085,Please enter Item Code to get batch no,"Por favor, ingrese el código del producto para obtener el No. de lote"
|
||||||
apps/erpnext/erpnext/selling/doctype/customer/customer.py +34,Series is mandatory,Serie es obligatorio
|
apps/erpnext/erpnext/selling/doctype/customer/customer.py +34,Series is mandatory,Serie es obligatorio
|
||||||
,Item Shortage Report,Reportar carencia de producto
|
,Item Shortage Report,Reportar carencia de producto
|
||||||
DocType: Sales Invoice,Rate at which Price list currency is converted to customer's base currency,Grado en el que la lista de precios en moneda se convierte en la moneda base del cliente
|
DocType: Sales Invoice,Rate at which Price list currency is converted to customer's base currency,Grado en el que la lista de precios en moneda se convierte en la moneda base del cliente
|
||||||
@ -280,7 +280,7 @@ apps/erpnext/erpnext/config/hr.py +234,"Employee designation (e.g. CEO, Director
|
|||||||
DocType: Item,Copy From Item Group,Copiar de Grupo de Elementos
|
DocType: Item,Copy From Item Group,Copiar de Grupo de Elementos
|
||||||
apps/erpnext/erpnext/stock/get_item_details.py +526,No default BOM exists for Item {0},No existe una Solicitud de Materiales por defecto para el elemento {0}
|
apps/erpnext/erpnext/stock/get_item_details.py +526,No default BOM exists for Item {0},No existe una Solicitud de Materiales por defecto para el elemento {0}
|
||||||
apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order.py +163,{0} ({1}) cannot be greater than planned quanitity ({2}) in Production Order {3},{0} ({1}) no puede ser mayor que cantidad planificada ({2}) en la Orden de Producción {3}
|
apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order.py +163,{0} ({1}) cannot be greater than planned quanitity ({2}) in Production Order {3},{0} ({1}) no puede ser mayor que cantidad planificada ({2}) en la Orden de Producción {3}
|
||||||
apps/erpnext/erpnext/buying/doctype/purchase_order/purchase_order.js +847,Select Item for Transfer,Seleccionar elemento de Transferencia
|
apps/erpnext/erpnext/buying/doctype/purchase_order/purchase_order.js +855,Select Item for Transfer,Seleccionar elemento de Transferencia
|
||||||
apps/erpnext/erpnext/hr/doctype/employee/employee.py +110,Date of Joining must be greater than Date of Birth,Fecha de acceso debe ser mayor que Fecha de Nacimiento
|
apps/erpnext/erpnext/hr/doctype/employee/employee.py +110,Date of Joining must be greater than Date of Birth,Fecha de acceso debe ser mayor que Fecha de Nacimiento
|
||||||
DocType: Buying Settings,Settings for Buying Module,Ajustes para la compra de módulo
|
DocType: Buying Settings,Settings for Buying Module,Ajustes para la compra de módulo
|
||||||
DocType: Sales Person,Sales Person Targets,Metas de Vendedor
|
DocType: Sales Person,Sales Person Targets,Metas de Vendedor
|
||||||
@ -301,7 +301,7 @@ apps/erpnext/erpnext/hr/doctype/job_applicant/job_applicant.py +25,Name or Email
|
|||||||
apps/erpnext/erpnext/setup/doctype/company/delete_company_transactions.py +17,Transactions can only be deleted by the creator of the Company,Las transacciones sólo pueden ser borrados por el creador de la Compañía
|
apps/erpnext/erpnext/setup/doctype/company/delete_company_transactions.py +17,Transactions can only be deleted by the creator of the Company,Las transacciones sólo pueden ser borrados por el creador de la Compañía
|
||||||
DocType: Cost Center,Parent Cost Center,Centro de Costo Principal
|
DocType: Cost Center,Parent Cost Center,Centro de Costo Principal
|
||||||
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +26,Loans and Advances (Assets),Préstamos y anticipos (Activos)
|
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +26,Loans and Advances (Assets),Préstamos y anticipos (Activos)
|
||||||
apps/erpnext/erpnext/hooks.py +94,Shipments,Los envíos
|
apps/erpnext/erpnext/hooks.py +87,Shipments,Los envíos
|
||||||
apps/erpnext/erpnext/public/js/setup_wizard.js +301,We buy this Item,Compramos este artículo
|
apps/erpnext/erpnext/public/js/setup_wizard.js +301,We buy this Item,Compramos este artículo
|
||||||
apps/erpnext/erpnext/controllers/buying_controller.py +149,Please enter 'Is Subcontracted' as Yes or No,"Por favor, introduzca si 'Es Subcontratado' o no"
|
apps/erpnext/erpnext/controllers/buying_controller.py +149,Please enter 'Is Subcontracted' as Yes or No,"Por favor, introduzca si 'Es Subcontratado' o no"
|
||||||
apps/erpnext/erpnext/setup/doctype/company/company.py +51,Abbreviation already used for another company,La Abreviación ya está siendo utilizada para otra compañía
|
apps/erpnext/erpnext/setup/doctype/company/company.py +51,Abbreviation already used for another company,La Abreviación ya está siendo utilizada para otra compañía
|
||||||
@ -318,12 +318,12 @@ apps/erpnext/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +89,Purc
|
|||||||
apps/erpnext/erpnext/config/setup.py +83,Create rules to restrict transactions based on values.,Crear reglas para restringir las transacciones basadas en valores .
|
apps/erpnext/erpnext/config/setup.py +83,Create rules to restrict transactions based on values.,Crear reglas para restringir las transacciones basadas en valores .
|
||||||
DocType: Process Payroll,Creates salary slip for above mentioned criteria.,Crea nómina para los criterios antes mencionados.
|
DocType: Process Payroll,Creates salary slip for above mentioned criteria.,Crea nómina para los criterios antes mencionados.
|
||||||
DocType: Purchase Order Item Supplied,Raw Material Item Code,Materia Prima Código del Artículo
|
DocType: Purchase Order Item Supplied,Raw Material Item Code,Materia Prima Código del Artículo
|
||||||
apps/erpnext/erpnext/buying/doctype/purchase_order/purchase_order.js +900,Supplier Quotation,Cotizaciónes a Proveedores
|
apps/erpnext/erpnext/buying/doctype/purchase_order/purchase_order.js +908,Supplier Quotation,Cotizaciónes a Proveedores
|
||||||
apps/erpnext/erpnext/projects/doctype/activity_cost/activity_cost.py +29,Activity Cost exists for Employee {0} against Activity Type - {1},Existe un costo de actividad para el empleado {0} contra el tipo de actividad - {1}
|
apps/erpnext/erpnext/projects/doctype/activity_cost/activity_cost.py +29,Activity Cost exists for Employee {0} against Activity Type - {1},Existe un costo de actividad para el empleado {0} contra el tipo de actividad - {1}
|
||||||
DocType: Sales Person,Set targets Item Group-wise for this Sales Person.,Establecer objetivos artículo grupo que tienen para este vendedor.
|
DocType: Sales Person,Set targets Item Group-wise for this Sales Person.,Establecer objetivos artículo grupo que tienen para este vendedor.
|
||||||
DocType: Stock Entry,Total Value Difference (Out - In),Diferencia (Salidas - Entradas)
|
DocType: Stock Entry,Total Value Difference (Out - In),Diferencia (Salidas - Entradas)
|
||||||
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.js +320,BOM and Manufacturing Quantity are required,Se requiere la lista de materiales (LdM) y cantidad a fabricar.
|
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.js +319,BOM and Manufacturing Quantity are required,Se requiere la lista de materiales (LdM) y cantidad a fabricar.
|
||||||
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +558,Product Bundle,Conjunto/Paquete de productos
|
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +566,Product Bundle,Conjunto/Paquete de productos
|
||||||
DocType: Material Request,Requested For,Solicitados para
|
DocType: Material Request,Requested For,Solicitados para
|
||||||
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +360,{0} against Sales Invoice {1},{0} contra Factura de Ventas {1}
|
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +360,{0} against Sales Invoice {1},{0} contra Factura de Ventas {1}
|
||||||
DocType: Production Planning Tool,Select Items,Seleccione Artículos
|
DocType: Production Planning Tool,Select Items,Seleccione Artículos
|
||||||
@ -352,7 +352,7 @@ DocType: Shipping Rule,Shipping Account,cuenta Envíos
|
|||||||
DocType: Item Group,Parent Item Group,Grupo Principal de Artículos
|
DocType: Item Group,Parent Item Group,Grupo Principal de Artículos
|
||||||
DocType: Serial No,Warranty Period (Days),Período de garantía ( Días)
|
DocType: Serial No,Warranty Period (Days),Período de garantía ( Días)
|
||||||
DocType: Selling Settings,Campaign Naming By,Nombramiento de la Campaña Por
|
DocType: Selling Settings,Campaign Naming By,Nombramiento de la Campaña Por
|
||||||
apps/erpnext/erpnext/hr/doctype/expense_claim/expense_claim.js +124,You are the Expense Approver for this record. Please Update the 'Status' and Save,Usted es el Supervisor de Gastos para este registro. Actualice el 'Estado' y Guarde
|
apps/erpnext/erpnext/hr/doctype/expense_claim/expense_claim.js +128,You are the Expense Approver for this record. Please Update the 'Status' and Save,Usted es el Supervisor de Gastos para este registro. Actualice el 'Estado' y Guarde
|
||||||
DocType: Material Request,Terms and Conditions Content,Términos y Condiciones Contenido
|
DocType: Material Request,Terms and Conditions Content,Términos y Condiciones Contenido
|
||||||
apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py +222,Serial No {0} does not belong to Warehouse {1},Número de orden {0} no pertenece al Almacén {1}
|
apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py +222,Serial No {0} does not belong to Warehouse {1},Número de orden {0} no pertenece al Almacén {1}
|
||||||
DocType: Shopping Cart Shipping Rule,Shopping Cart Shipping Rule,Compras Regla de envío
|
DocType: Shopping Cart Shipping Rule,Shopping Cart Shipping Rule,Compras Regla de envío
|
||||||
@ -378,7 +378,7 @@ DocType: Item,Has Variants,Tiene Variantes
|
|||||||
DocType: Purchase Invoice,Taxes and Charges Added (Company Currency),Impuestos y Cargos Añadidos (Moneda Local)
|
DocType: Purchase Invoice,Taxes and Charges Added (Company Currency),Impuestos y Cargos Añadidos (Moneda Local)
|
||||||
DocType: Customer,Buyer of Goods and Services.,Compradores de Productos y Servicios.
|
DocType: Customer,Buyer of Goods and Services.,Compradores de Productos y Servicios.
|
||||||
DocType: Quotation Item,Stock Balance,Balance de Inventarios
|
DocType: Quotation Item,Stock Balance,Balance de Inventarios
|
||||||
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +675,Cost Center For Item with Item Code ',Centro de Costos para artículo con Código del artículo '
|
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +684,Cost Center For Item with Item Code ',Centro de Costos para artículo con Código del artículo '
|
||||||
DocType: POS Profile,Write Off Cost Center,Centro de costos de desajuste
|
DocType: POS Profile,Write Off Cost Center,Centro de costos de desajuste
|
||||||
apps/erpnext/erpnext/selling/doctype/customer/customer.py +167,Please contact to the user who have Sales Master Manager {0} role,"Por favor, póngase en contacto con el usuario con función de Gerente de Ventas {0}"
|
apps/erpnext/erpnext/selling/doctype/customer/customer.py +167,Please contact to the user who have Sales Master Manager {0} role,"Por favor, póngase en contacto con el usuario con función de Gerente de Ventas {0}"
|
||||||
DocType: Leave Block List,Allow the following users to approve Leave Applications for block days.,Permitir a los usuarios siguientes aprobar Solicitudes de ausencia en bloques de días.
|
DocType: Leave Block List,Allow the following users to approve Leave Applications for block days.,Permitir a los usuarios siguientes aprobar Solicitudes de ausencia en bloques de días.
|
||||||
@ -407,8 +407,8 @@ apps/erpnext/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sa
|
|||||||
apps/erpnext/erpnext/accounts/doctype/cost_center/cost_center_tree.js +16,New Company,Nueva Empresa
|
apps/erpnext/erpnext/accounts/doctype/cost_center/cost_center_tree.js +16,New Company,Nueva Empresa
|
||||||
DocType: Employee,Permanent Address Is,Dirección permanente es
|
DocType: Employee,Permanent Address Is,Dirección permanente es
|
||||||
,Issued Items Against Production Order,Productos emitidos con una orden de producción
|
,Issued Items Against Production Order,Productos emitidos con una orden de producción
|
||||||
apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order.js +349,Max: {0},Max: {0}
|
apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order.js +351,Max: {0},Max: {0}
|
||||||
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +231,{0} {1} has been modified. Please refresh.,{0} {1} ha sido modificado. Por favor actualizar.
|
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +232,{0} {1} has been modified. Please refresh.,{0} {1} ha sido modificado. Por favor actualizar.
|
||||||
DocType: Item,Item Tax,Impuesto del artículo
|
DocType: Item,Item Tax,Impuesto del artículo
|
||||||
,Item Prices,Precios de los Artículos
|
,Item Prices,Precios de los Artículos
|
||||||
DocType: Account,Balance must be,Balance debe ser
|
DocType: Account,Balance must be,Balance debe ser
|
||||||
@ -421,7 +421,7 @@ DocType: Target Detail,Target Qty,Cantidad Objetivo
|
|||||||
apps/erpnext/erpnext/stock/doctype/item/item.js +265,"Weight is mentioned,\nPlease mention ""Weight UOM"" too","Se menciona Peso, \n ¡Por favor indique ""Peso Unidad de Medida"" también"
|
apps/erpnext/erpnext/stock/doctype/item/item.js +265,"Weight is mentioned,\nPlease mention ""Weight UOM"" too","Se menciona Peso, \n ¡Por favor indique ""Peso Unidad de Medida"" también"
|
||||||
apps/erpnext/erpnext/manufacturing/doctype/bom/bom.js +165,You can not change rate if BOM mentioned agianst any item,No se puede cambiar la tasa si hay una Solicitud de Materiales contra cualquier artículo
|
apps/erpnext/erpnext/manufacturing/doctype/bom/bom.js +165,You can not change rate if BOM mentioned agianst any item,No se puede cambiar la tasa si hay una Solicitud de Materiales contra cualquier artículo
|
||||||
DocType: Account,Accounts,Contabilidad
|
DocType: Account,Accounts,Contabilidad
|
||||||
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +61,Expected Delivery Date cannot be before Purchase Order Date,Fecha prevista de entrega no puede ser anterior Fecha de Orden de Compra
|
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +62,Expected Delivery Date cannot be before Purchase Order Date,Fecha prevista de entrega no puede ser anterior Fecha de Orden de Compra
|
||||||
DocType: Workstation,per hour,por horas
|
DocType: Workstation,per hour,por horas
|
||||||
apps/erpnext/erpnext/crm/doctype/opportunity/opportunity_list.js +17,Set as Closed,Establecer como Cerrada
|
apps/erpnext/erpnext/crm/doctype/opportunity/opportunity_list.js +17,Set as Closed,Establecer como Cerrada
|
||||||
DocType: Production Order Operation,Work In Progress,Trabajos en Curso
|
DocType: Production Order Operation,Work In Progress,Trabajos en Curso
|
||||||
@ -470,14 +470,14 @@ DocType: Payment Gateway Account,Payment Account,Pago a cuenta
|
|||||||
DocType: Journal Entry,Cash Entry,Entrada de Efectivo
|
DocType: Journal Entry,Cash Entry,Entrada de Efectivo
|
||||||
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +105,Row {0}: Party Type and Party is only applicable against Receivable / Payable account,Fila {0}: el tipo de entidad es aplicable únicamente contra las cuentas de cobrar/pagar
|
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +105,Row {0}: Party Type and Party is only applicable against Receivable / Payable account,Fila {0}: el tipo de entidad es aplicable únicamente contra las cuentas de cobrar/pagar
|
||||||
apps/erpnext/erpnext/public/js/account_tree_grid.js +66,Select Fiscal Year...,Seleccione el año fiscal ...
|
apps/erpnext/erpnext/public/js/account_tree_grid.js +66,Select Fiscal Year...,Seleccione el año fiscal ...
|
||||||
apps/erpnext/erpnext/accounts/doctype/payment_entry/payment_entry.js +171,"For row {0} in {1}. To include {2} in Item rate, rows {3} must also be included","Para la fila {0} en {1}. e incluir {2} en la tasa del producto, las filas {3} también deben ser incluidas"
|
apps/erpnext/erpnext/accounts/doctype/payment_entry/payment_entry.js +179,"For row {0} in {1}. To include {2} in Item rate, rows {3} must also be included","Para la fila {0} en {1}. e incluir {2} en la tasa del producto, las filas {3} también deben ser incluidas"
|
||||||
apps/erpnext/erpnext/manufacturing/doctype/workstation/workstation.py +83,Workstation is closed on the following dates as per Holiday List: {0},La estación de trabajo estará cerrada en las siguientes fechas según la lista de vacaciones: {0}
|
apps/erpnext/erpnext/manufacturing/doctype/workstation/workstation.py +83,Workstation is closed on the following dates as per Holiday List: {0},La estación de trabajo estará cerrada en las siguientes fechas según la lista de vacaciones: {0}
|
||||||
DocType: Sales Person,Select company name first.,Seleccionar nombre de la empresa en primer lugar.
|
DocType: Sales Person,Select company name first.,Seleccionar nombre de la empresa en primer lugar.
|
||||||
DocType: Opportunity,With Items,Con artículos
|
DocType: Opportunity,With Items,Con artículos
|
||||||
apps/erpnext/erpnext/selling/doctype/installation_note/installation_note.py +49,Serial No {0} does not exist,Número de orden {0} no existe
|
apps/erpnext/erpnext/selling/doctype/installation_note/installation_note.py +49,Serial No {0} does not exist,Número de orden {0} no existe
|
||||||
DocType: Purchase Receipt Item,Required By,Requerido por
|
DocType: Purchase Receipt Item,Required By,Requerido por
|
||||||
DocType: Purchase Invoice Item,Purchase Invoice Item,Factura de Compra del artículo
|
DocType: Purchase Invoice Item,Purchase Invoice Item,Factura de Compra del artículo
|
||||||
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +101,Quotation {0} not of type {1},Cotización {0} no es de tipo {1}
|
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +102,Quotation {0} not of type {1},Cotización {0} no es de tipo {1}
|
||||||
apps/erpnext/erpnext/config/hr.py +24,Attendance record.,Registro de Asistencia .
|
apps/erpnext/erpnext/config/hr.py +24,Attendance record.,Registro de Asistencia .
|
||||||
apps/erpnext/erpnext/buying/doctype/purchase_order/purchase_order.py +134,Material Request {0} is cancelled or stopped,Solicitud de Material {0} cancelada o detenida
|
apps/erpnext/erpnext/buying/doctype/purchase_order/purchase_order.py +134,Material Request {0} is cancelled or stopped,Solicitud de Material {0} cancelada o detenida
|
||||||
DocType: Purchase Invoice,Supplied Items,Artículos suministrados
|
DocType: Purchase Invoice,Supplied Items,Artículos suministrados
|
||||||
@ -487,7 +487,7 @@ apps/erpnext/erpnext/config/accounts.py +327,"e.g. Bank, Cash, Credit Card","por
|
|||||||
DocType: Production Order,Material Transferred for Manufacturing,Material transferido para fabricación
|
DocType: Production Order,Material Transferred for Manufacturing,Material transferido para fabricación
|
||||||
DocType: Item Reorder,Item Reorder,Reordenar productos
|
DocType: Item Reorder,Item Reorder,Reordenar productos
|
||||||
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +111,Credit To account must be a Payable account,Crédito a la cuenta debe ser una cuenta por pagar
|
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +111,Credit To account must be a Payable account,Crédito a la cuenta debe ser una cuenta por pagar
|
||||||
apps/erpnext/erpnext/hr/doctype/expense_claim/expense_claim.js +126,Expense Claim is pending approval. Only the Expense Approver can update status.,El reembolso de gastos está pendiente de aprobación. Sólo el supervisor de gastos puede actualizar el estado.
|
apps/erpnext/erpnext/hr/doctype/expense_claim/expense_claim.js +130,Expense Claim is pending approval. Only the Expense Approver can update status.,El reembolso de gastos está pendiente de aprobación. Sólo el supervisor de gastos puede actualizar el estado.
|
||||||
,Lead Id,Iniciativa ID
|
,Lead Id,Iniciativa ID
|
||||||
apps/erpnext/erpnext/config/hr.py +104,Generate Salary Slips,Generar etiquetas salariales
|
apps/erpnext/erpnext/config/hr.py +104,Generate Salary Slips,Generar etiquetas salariales
|
||||||
apps/erpnext/erpnext/config/buying.py +23,Quotations received from Suppliers.,Cotizaciones recibidas de los proveedores.
|
apps/erpnext/erpnext/config/buying.py +23,Quotations received from Suppliers.,Cotizaciones recibidas de los proveedores.
|
||||||
@ -495,14 +495,14 @@ DocType: Sales Partner,Sales Partner Target,Socio de Ventas Objetivo
|
|||||||
apps/erpnext/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js +47,Make Maintenance Visit,Hacer Visita de Mantenimiento
|
apps/erpnext/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js +47,Make Maintenance Visit,Hacer Visita de Mantenimiento
|
||||||
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +442,Stock cannot be updated against Delivery Note {0},Inventario no puede actualizarse contra Nota de Envio {0}
|
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +442,Stock cannot be updated against Delivery Note {0},Inventario no puede actualizarse contra Nota de Envio {0}
|
||||||
DocType: Workstation,Rent Cost,Renta Costo
|
DocType: Workstation,Rent Cost,Renta Costo
|
||||||
apps/erpnext/erpnext/hooks.py +124,Issues,Problemas
|
apps/erpnext/erpnext/hooks.py +117,Issues,Problemas
|
||||||
DocType: BOM Replace Tool,Current BOM,Lista de materiales actual
|
DocType: BOM Replace Tool,Current BOM,Lista de materiales actual
|
||||||
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +75,Row # {0}:,Fila # {0}:
|
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +75,Row # {0}:,Fila # {0}:
|
||||||
DocType: Timesheet,% Amount Billed,% Monto Facturado
|
DocType: Timesheet,% Amount Billed,% Monto Facturado
|
||||||
DocType: BOM,Manage cost of operations,Administrar el costo de las operaciones
|
DocType: BOM,Manage cost of operations,Administrar el costo de las operaciones
|
||||||
DocType: Employee,Company Email,Correo de la compañía
|
DocType: Employee,Company Email,Correo de la compañía
|
||||||
apps/erpnext/erpnext/config/support.py +32,Single unit of an Item.,Números de serie únicos para cada producto
|
apps/erpnext/erpnext/config/support.py +32,Single unit of an Item.,Números de serie únicos para cada producto
|
||||||
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +197,Delivery Notes {0} must be cancelled before cancelling this Sales Order,Nota de Entrega {0} debe ser cancelado antes de cancelar esta Orden Ventas
|
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +198,Delivery Notes {0} must be cancelled before cancelling this Sales Order,Nota de Entrega {0} debe ser cancelado antes de cancelar esta Orden Ventas
|
||||||
DocType: Item Tax,Tax Rate,Tasa de Impuesto
|
DocType: Item Tax,Tax Rate,Tasa de Impuesto
|
||||||
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +120,Utility Expenses,Los gastos de servicios públicos
|
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +120,Utility Expenses,Los gastos de servicios públicos
|
||||||
DocType: Account,Parent Account,Cuenta Primaria
|
DocType: Account,Parent Account,Cuenta Primaria
|
||||||
@ -630,7 +630,7 @@ DocType: Production Planning Tool,Production Planning Tool,Herramienta de planif
|
|||||||
DocType: Maintenance Schedule,Schedules,Horarios
|
DocType: Maintenance Schedule,Schedules,Horarios
|
||||||
DocType: Purchase Taxes and Charges,Tax Amount After Discount Amount,Total de Impuestos Después Cantidad de Descuento
|
DocType: Purchase Taxes and Charges,Tax Amount After Discount Amount,Total de Impuestos Después Cantidad de Descuento
|
||||||
DocType: Item,Has Serial No,Tiene No de Serie
|
DocType: Item,Has Serial No,Tiene No de Serie
|
||||||
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.py +94,Sales Order required for Item {0},Orden de Venta requerida para el punto {0}
|
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.py +96,Sales Order required for Item {0},Orden de Venta requerida para el punto {0}
|
||||||
DocType: Hub Settings,Sync Now,Sincronizar ahora
|
DocType: Hub Settings,Sync Now,Sincronizar ahora
|
||||||
DocType: Serial No,Out of AMC,Fuera de AMC
|
DocType: Serial No,Out of AMC,Fuera de AMC
|
||||||
DocType: Leave Application,Apply / Approve Leaves,Aplicar / Aprobar Vacaciones
|
DocType: Leave Application,Apply / Approve Leaves,Aplicar / Aprobar Vacaciones
|
||||||
@ -699,7 +699,7 @@ apps/erpnext/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliat
|
|||||||
,Open Production Orders,Abrir Ordenes de Producción
|
,Open Production Orders,Abrir Ordenes de Producción
|
||||||
DocType: Sales Taxes and Charges,Tax Amount After Discount Amount (Company Currency),Monto de impuestos Después Cantidad de Descuento (Compañía moneda)
|
DocType: Sales Taxes and Charges,Tax Amount After Discount Amount (Company Currency),Monto de impuestos Después Cantidad de Descuento (Compañía moneda)
|
||||||
DocType: Holiday List,Holiday List Name,Lista de nombres de vacaciones
|
DocType: Holiday List,Holiday List Name,Lista de nombres de vacaciones
|
||||||
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.js +780,Sales Return,Volver Ventas
|
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.js +787,Sales Return,Volver Ventas
|
||||||
apps/erpnext/erpnext/setup/setup_wizard/industry_type.py +11,Automotive,Automotor
|
apps/erpnext/erpnext/setup/setup_wizard/industry_type.py +11,Automotive,Automotor
|
||||||
DocType: Purchase Order Item Supplied,Supplied Qty,Suministrado Cantidad
|
DocType: Purchase Order Item Supplied,Supplied Qty,Suministrado Cantidad
|
||||||
apps/erpnext/erpnext/hr/doctype/employee/employee.py +154,Employee cannot report to himself.,Empleado no puede informar a sí mismo.
|
apps/erpnext/erpnext/hr/doctype/employee/employee.py +154,Employee cannot report to himself.,Empleado no puede informar a sí mismo.
|
||||||
@ -840,7 +840,7 @@ apps/erpnext/erpnext/stock/get_item_details.py +151,Item {0} must be a Sub-contr
|
|||||||
DocType: Supplier,Is Frozen,Está Inactivo
|
DocType: Supplier,Is Frozen,Está Inactivo
|
||||||
apps/erpnext/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py +191,Serial No {0} is under warranty upto {1},Número de orden {0} está en garantía hasta {1}
|
apps/erpnext/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py +191,Serial No {0} is under warranty upto {1},Número de orden {0} está en garantía hasta {1}
|
||||||
apps/erpnext/erpnext/config/manufacturing.py +84,Global settings for all manufacturing processes.,Configuración global para todos los procesos de fabricación.
|
apps/erpnext/erpnext/config/manufacturing.py +84,Global settings for all manufacturing processes.,Configuración global para todos los procesos de fabricación.
|
||||||
apps/erpnext/erpnext/accounts/doctype/payment_entry/payment_entry.js +166,Actual type tax cannot be included in Item rate in row {0},"El tipo de impuesto actual, no puede ser incluido en el precio del producto de la linea {0}"
|
apps/erpnext/erpnext/accounts/doctype/payment_entry/payment_entry.js +174,Actual type tax cannot be included in Item rate in row {0},"El tipo de impuesto actual, no puede ser incluido en el precio del producto de la linea {0}"
|
||||||
DocType: Stock Settings,Role Allowed to edit frozen stock,Función Permitida para editar Inventario Congelado
|
DocType: Stock Settings,Role Allowed to edit frozen stock,Función Permitida para editar Inventario Congelado
|
||||||
DocType: Pricing Rule,"Higher the number, higher the priority","Mayor es el número, mayor es la prioridad"
|
DocType: Pricing Rule,"Higher the number, higher the priority","Mayor es el número, mayor es la prioridad"
|
||||||
apps/erpnext/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +84,Stock cannot exist for Item {0} since has variants,Inventario no puede existir para el punto {0} ya tiene variantes
|
apps/erpnext/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +84,Stock cannot exist for Item {0} since has variants,Inventario no puede existir para el punto {0} ya tiene variantes
|
||||||
@ -859,7 +859,7 @@ DocType: BOM,Materials Required (Exploded),Materiales necesarios ( despiece )
|
|||||||
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +137,Source of Funds (Liabilities),Fuente de los fondos ( Pasivo )
|
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +137,Source of Funds (Liabilities),Fuente de los fondos ( Pasivo )
|
||||||
DocType: BOM,Exploded_items,Vista detallada
|
DocType: BOM,Exploded_items,Vista detallada
|
||||||
apps/erpnext/erpnext/config/hr.py +214,Settings for HR Module,Ajustes para el Módulo de Recursos Humanos
|
apps/erpnext/erpnext/config/hr.py +214,Settings for HR Module,Ajustes para el Módulo de Recursos Humanos
|
||||||
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +205,Sales Invoice {0} must be cancelled before cancelling this Sales Order,Factura {0} debe ser cancelado antes de cancelar esta Orden Ventas
|
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +206,Sales Invoice {0} must be cancelled before cancelling this Sales Order,Factura {0} debe ser cancelado antes de cancelar esta Orden Ventas
|
||||||
DocType: GL Entry,Is Opening,Es apertura
|
DocType: GL Entry,Is Opening,Es apertura
|
||||||
apps/erpnext/erpnext/stock/doctype/warehouse/warehouse.py +72,Warehouse {0} does not exist,Almacén {0} no existe
|
apps/erpnext/erpnext/stock/doctype/warehouse/warehouse.py +72,Warehouse {0} does not exist,Almacén {0} no existe
|
||||||
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.py +94,{0} is not a stock Item,{0} no es un producto de stock
|
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.py +94,{0} is not a stock Item,{0} no es un producto de stock
|
||||||
@ -888,7 +888,7 @@ DocType: Packing Slip,Gross Weight UOM,Peso Bruto de la Unidad de Medida
|
|||||||
DocType: BOM,Item to be manufactured or repacked,Artículo a fabricar o embalados de nuevo
|
DocType: BOM,Item to be manufactured or repacked,Artículo a fabricar o embalados de nuevo
|
||||||
DocType: Purchase Order,Supply Raw Materials,Suministro de Materias Primas
|
DocType: Purchase Order,Supply Raw Materials,Suministro de Materias Primas
|
||||||
apps/erpnext/erpnext/buying/page/purchase_analytics/purchase_analytics.js +31,Supplier Type / Supplier,Tipo de Proveedor / Proveedor
|
apps/erpnext/erpnext/buying/page/purchase_analytics/purchase_analytics.js +31,Supplier Type / Supplier,Tipo de Proveedor / Proveedor
|
||||||
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +108,Please enter 'Expected Delivery Date',"Por favor, introduzca 'la fecha estimada de llegada'"
|
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +109,Please enter 'Expected Delivery Date',"Por favor, introduzca 'la fecha estimada de llegada'"
|
||||||
apps/erpnext/erpnext/stock/doctype/warehouse/warehouse.py +51,Warehouse can not be deleted as stock ledger entry exists for this warehouse.,Almacén no se puede suprimir porque hay una entrada en registro de inventario para este almacén.
|
apps/erpnext/erpnext/stock/doctype/warehouse/warehouse.py +51,Warehouse can not be deleted as stock ledger entry exists for this warehouse.,Almacén no se puede suprimir porque hay una entrada en registro de inventario para este almacén.
|
||||||
apps/erpnext/erpnext/manufacturing/doctype/bom_replace_tool/bom_replace_tool.py +25,Current BOM and New BOM can not be same,Solicitud de Materiales actual y Nueva Solicitud de Materiales no pueden ser iguales
|
apps/erpnext/erpnext/manufacturing/doctype/bom_replace_tool/bom_replace_tool.py +25,Current BOM and New BOM can not be same,Solicitud de Materiales actual y Nueva Solicitud de Materiales no pueden ser iguales
|
||||||
DocType: Account,Stock,Existencias
|
DocType: Account,Stock,Existencias
|
||||||
@ -977,14 +977,14 @@ apps/erpnext/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_
|
|||||||
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +163,Capital Stock,Capital Social
|
apps/erpnext/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py +163,Capital Stock,Capital Social
|
||||||
DocType: HR Settings,Employee Records to be created by,Registros de empleados a ser creados por
|
DocType: HR Settings,Employee Records to be created by,Registros de empleados a ser creados por
|
||||||
DocType: Account,Expense Account,Cuenta de gastos
|
DocType: Account,Expense Account,Cuenta de gastos
|
||||||
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +212,Maintenance Schedule {0} must be cancelled before cancelling this Sales Order,Programa de mantenimiento {0} debe ser cancelado antes de cancelar esta orden de venta
|
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +213,Maintenance Schedule {0} must be cancelled before cancelling this Sales Order,Programa de mantenimiento {0} debe ser cancelado antes de cancelar esta orden de venta
|
||||||
DocType: Stock Ledger Entry,Actual Qty After Transaction,Cantidad actual después de la transacción
|
DocType: Stock Ledger Entry,Actual Qty After Transaction,Cantidad actual después de la transacción
|
||||||
DocType: Hub Settings,Seller Email,Correo Electrónico del Vendedor
|
DocType: Hub Settings,Seller Email,Correo Electrónico del Vendedor
|
||||||
apps/erpnext/erpnext/setup/doctype/territory/territory.py +19,Either target qty or target amount is mandatory,Cualquiera Cantidad Meta o Monto Meta es obligatoria
|
apps/erpnext/erpnext/setup/doctype/territory/territory.py +19,Either target qty or target amount is mandatory,Cualquiera Cantidad Meta o Monto Meta es obligatoria
|
||||||
DocType: Authorization Rule,Applicable To (Role),Aplicable a (Rol )
|
DocType: Authorization Rule,Applicable To (Role),Aplicable a (Rol )
|
||||||
DocType: Purchase Invoice Item,Amount (Company Currency),Importe (Moneda Local)
|
DocType: Purchase Invoice Item,Amount (Company Currency),Importe (Moneda Local)
|
||||||
apps/erpnext/erpnext/projects/doctype/project/project.js +45,Gantt Chart,Diagrama de Gantt
|
apps/erpnext/erpnext/projects/doctype/project/project.js +45,Gantt Chart,Diagrama de Gantt
|
||||||
apps/erpnext/erpnext/stock/doctype/material_request/material_request.js +761,Warning: Material Requested Qty is less than Minimum Order Qty,Advertencia: Cantidad de Material Solicitado es menor que Cantidad Mínima Establecida
|
apps/erpnext/erpnext/stock/doctype/material_request/material_request.js +769,Warning: Material Requested Qty is less than Minimum Order Qty,Advertencia: Cantidad de Material Solicitado es menor que Cantidad Mínima Establecida
|
||||||
DocType: Manufacturing Settings,Plan time logs outside Workstation Working Hours.,Planear bitácora de trabajo para las horas fuera de la estación.
|
DocType: Manufacturing Settings,Plan time logs outside Workstation Working Hours.,Planear bitácora de trabajo para las horas fuera de la estación.
|
||||||
DocType: Employee,"Here you can maintain height, weight, allergies, medical concerns etc","Aquí usted puede mantener la altura , el peso, alergias , problemas médicos , etc"
|
DocType: Employee,"Here you can maintain height, weight, allergies, medical concerns etc","Aquí usted puede mantener la altura , el peso, alergias , problemas médicos , etc"
|
||||||
apps/erpnext/erpnext/accounts/doctype/payment_entry/payment_entry.py +237,Against Journal Entry {0} does not have any unmatched {1} entry,Contra la Entrada de Diario {0} no tiene ninguna {1} entrada que vincular
|
apps/erpnext/erpnext/accounts/doctype/payment_entry/payment_entry.py +237,Against Journal Entry {0} does not have any unmatched {1} entry,Contra la Entrada de Diario {0} no tiene ninguna {1} entrada que vincular
|
||||||
@ -995,10 +995,10 @@ apps/erpnext/erpnext/stock/doctype/item/item.py +530,"To merge, following proper
|
|||||||
apps/erpnext/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py +195,Serial No {0} is under maintenance contract upto {1},Número de orden {0} tiene un contrato de mantenimiento hasta {1}
|
apps/erpnext/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py +195,Serial No {0} is under maintenance contract upto {1},Número de orden {0} tiene un contrato de mantenimiento hasta {1}
|
||||||
apps/erpnext/erpnext/selling/doctype/installation_note/installation_note.py +83,Please pull items from Delivery Note,"Por favor, extraiga los productos desde la nota de entrega--"
|
apps/erpnext/erpnext/selling/doctype/installation_note/installation_note.py +83,Please pull items from Delivery Note,"Por favor, extraiga los productos desde la nota de entrega--"
|
||||||
apps/erpnext/erpnext/config/hr.py +75,Allocate leaves for a period.,Asignar las vacaciones para un período .
|
apps/erpnext/erpnext/config/hr.py +75,Allocate leaves for a period.,Asignar las vacaciones para un período .
|
||||||
apps/erpnext/erpnext/stock/doctype/material_request/material_request.js +861,Fetch exploded BOM (including sub-assemblies),Mezclar Solicitud de Materiales (incluyendo subconjuntos )
|
apps/erpnext/erpnext/stock/doctype/material_request/material_request.js +869,Fetch exploded BOM (including sub-assemblies),Mezclar Solicitud de Materiales (incluyendo subconjuntos )
|
||||||
DocType: BOM Item,"See ""Rate Of Materials Based On"" in Costing Section","Consulte "" Cambio de materiales a base On"" en la sección Cálculo del coste"
|
DocType: BOM Item,"See ""Rate Of Materials Based On"" in Costing Section","Consulte "" Cambio de materiales a base On"" en la sección Cálculo del coste"
|
||||||
DocType: Stock Settings,Auto Material Request,Solicitud de Materiales Automatica
|
DocType: Stock Settings,Auto Material Request,Solicitud de Materiales Automatica
|
||||||
apps/erpnext/erpnext/stock/doctype/material_request/material_request.js +785,Get Items from BOM,Obtener elementos de la Solicitud de Materiales
|
apps/erpnext/erpnext/stock/doctype/material_request/material_request.js +793,Get Items from BOM,Obtener elementos de la Solicitud de Materiales
|
||||||
apps/erpnext/erpnext/config/selling.py +229,Customer Addresses And Contacts,Las direcciones de clientes y contactos
|
apps/erpnext/erpnext/config/selling.py +229,Customer Addresses And Contacts,Las direcciones de clientes y contactos
|
||||||
apps/erpnext/erpnext/accounts/doctype/account/account.py +50,Account {0}: You can not assign itself as parent account,Cuenta {0}: no puede asignar la misma cuenta como su cuenta Padre.
|
apps/erpnext/erpnext/accounts/doctype/account/account.py +50,Account {0}: You can not assign itself as parent account,Cuenta {0}: no puede asignar la misma cuenta como su cuenta Padre.
|
||||||
DocType: Item Price,Item Price,Precios de Productos
|
DocType: Item Price,Item Price,Precios de Productos
|
||||||
@ -1009,7 +1009,7 @@ DocType: Production Plan Sales Order,Production Plan Sales Order,Plan de producc
|
|||||||
DocType: Purchase Invoice,Return,Retorno
|
DocType: Purchase Invoice,Return,Retorno
|
||||||
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +99,Please enter default currency in Company Master,"Por favor, ingrese la moneda por defecto en la compañía principal"
|
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +99,Please enter default currency in Company Master,"Por favor, ingrese la moneda por defecto en la compañía principal"
|
||||||
DocType: Lead,Middle Income,Ingresos Medio
|
DocType: Lead,Middle Income,Ingresos Medio
|
||||||
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.py +263,Sales Invoice {0} has already been submitted,Factura {0} ya se ha presentado
|
apps/erpnext/erpnext/stock/doctype/delivery_note/delivery_note.py +265,Sales Invoice {0} has already been submitted,Factura {0} ya se ha presentado
|
||||||
DocType: Employee Education,Year of Passing,Año de Fallecimiento
|
DocType: Employee Education,Year of Passing,Año de Fallecimiento
|
||||||
DocType: Quotation,Rate at which customer's currency is converted to company's base currency,Tasa a la cual la Moneda del Cliente se convierte a la moneda base de la compañía
|
DocType: Quotation,Rate at which customer's currency is converted to company's base currency,Tasa a la cual la Moneda del Cliente se convierte a la moneda base de la compañía
|
||||||
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.py +555,Manufacturing Quantity is mandatory,Cantidad de Fabricación es obligatoria
|
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.py +555,Manufacturing Quantity is mandatory,Cantidad de Fabricación es obligatoria
|
||||||
@ -1044,10 +1044,10 @@ DocType: Employee Leave Approver,Users who can approve a specific employee's lea
|
|||||||
apps/erpnext/erpnext/config/manufacturing.py +18,Generate Material Requests (MRP) and Production Orders.,Generar Solicitudes de Material ( MRP ) y Órdenes de Producción .
|
apps/erpnext/erpnext/config/manufacturing.py +18,Generate Material Requests (MRP) and Production Orders.,Generar Solicitudes de Material ( MRP ) y Órdenes de Producción .
|
||||||
apps/erpnext/erpnext/config/stock.py +27,Requests for items.,Listado de solicitudes de productos
|
apps/erpnext/erpnext/config/stock.py +27,Requests for items.,Listado de solicitudes de productos
|
||||||
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.py +177,For Quantity (Manufactured Qty) is mandatory,Por Cantidad (Cantidad fabricada) es obligatorio
|
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.py +177,For Quantity (Manufactured Qty) is mandatory,Por Cantidad (Cantidad fabricada) es obligatorio
|
||||||
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +546,cannot be greater than 100,No puede ser mayor que 100
|
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +555,cannot be greater than 100,No puede ser mayor que 100
|
||||||
DocType: Maintenance Visit,Customer Feedback,Comentarios del cliente
|
DocType: Maintenance Visit,Customer Feedback,Comentarios del cliente
|
||||||
DocType: Purchase Receipt Item Supplied,Required Qty,Cant. Necesaria
|
DocType: Purchase Receipt Item Supplied,Required Qty,Cant. Necesaria
|
||||||
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +815,Delivery Note,Notas de Entrega
|
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +824,Delivery Note,Notas de Entrega
|
||||||
DocType: Bin,Stock Value,Valor de Inventario
|
DocType: Bin,Stock Value,Valor de Inventario
|
||||||
DocType: Purchase Invoice,In Words (Company Currency),En palabras (Moneda Local)
|
DocType: Purchase Invoice,In Words (Company Currency),En palabras (Moneda Local)
|
||||||
DocType: Website Item Group,Website Item Group,Grupo de Artículos del Sitio Web
|
DocType: Website Item Group,Website Item Group,Grupo de Artículos del Sitio Web
|
||||||
@ -1068,10 +1068,10 @@ apps/erpnext/erpnext/accounts/report/accounts_receivable/accounts_receivable.htm
|
|||||||
apps/erpnext/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py +39,Outstanding Amt,Monto Sobrepasado
|
apps/erpnext/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py +39,Outstanding Amt,Monto Sobrepasado
|
||||||
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +199,Row {0}: Credit entry can not be linked with a {1},Fila {0}: Crédito no puede vincularse con {1}
|
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +199,Row {0}: Credit entry can not be linked with a {1},Fila {0}: Crédito no puede vincularse con {1}
|
||||||
apps/erpnext/erpnext/setup/setup_wizard/install_fixtures.py +149,Credit Card,Tarjeta de Crédito
|
apps/erpnext/erpnext/setup/setup_wizard/install_fixtures.py +149,Credit Card,Tarjeta de Crédito
|
||||||
apps/erpnext/erpnext/accounts/party.py +253,Accounting entries have already been made in currency {0} for company {1}. Please select a receivable or payable account with currency {0}.,Partidas contables ya han sido realizadas en {0} para la empresa {1}. Por favor seleccione una cuenta por cobrar o pagar con moneda {0}
|
apps/erpnext/erpnext/accounts/party.py +255,Accounting entries have already been made in currency {0} for company {1}. Please select a receivable or payable account with currency {0}.,Partidas contables ya han sido realizadas en {0} para la empresa {1}. Por favor seleccione una cuenta por cobrar o pagar con moneda {0}
|
||||||
apps/erpnext/erpnext/utilities/transaction_base.py +81,Duplicate row {0} with same {1},Duplicar fila {0} con el mismo {1}
|
apps/erpnext/erpnext/utilities/transaction_base.py +81,Duplicate row {0} with same {1},Duplicar fila {0} con el mismo {1}
|
||||||
DocType: Leave Application,Leave Application,Solicitud de Vacaciones
|
DocType: Leave Application,Leave Application,Solicitud de Vacaciones
|
||||||
apps/erpnext/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js +782,For Supplier,Por proveedor
|
apps/erpnext/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js +790,For Supplier,Por proveedor
|
||||||
DocType: Hub Settings,Seller Description,Descripción del Vendedor
|
DocType: Hub Settings,Seller Description,Descripción del Vendedor
|
||||||
apps/erpnext/erpnext/config/maintenance.py +17,Visit report for maintenance call.,Informe de visita por llamada de mantenimiento .
|
apps/erpnext/erpnext/config/maintenance.py +17,Visit report for maintenance call.,Informe de visita por llamada de mantenimiento .
|
||||||
apps/erpnext/erpnext/config/selling.py +118,Manage Sales Person Tree.,Vista en árbol para la administración de las categoría de vendedores
|
apps/erpnext/erpnext/config/selling.py +118,Manage Sales Person Tree.,Vista en árbol para la administración de las categoría de vendedores
|
||||||
@ -1121,7 +1121,7 @@ DocType: Purchase Invoice Item,Net Rate (Company Currency),Tasa neta (Moneda Loc
|
|||||||
DocType: Period Closing Voucher,Closing Account Head,Cuenta de cierre principal
|
DocType: Period Closing Voucher,Closing Account Head,Cuenta de cierre principal
|
||||||
apps/erpnext/erpnext/selling/report/inactive_customers/inactive_customers.py +72,Days Since Last Order,Días desde el último pedido
|
apps/erpnext/erpnext/selling/report/inactive_customers/inactive_customers.py +72,Days Since Last Order,Días desde el último pedido
|
||||||
DocType: Item,Default Buying Cost Center,Centro de Costos Por Defecto
|
DocType: Item,Default Buying Cost Center,Centro de Costos Por Defecto
|
||||||
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +218,Maintenance Visit {0} must be cancelled before cancelling this Sales Order,Visita de Mantenimiento {0} debe ser cancelado antes de cancelar la Orden de Ventas
|
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +219,Maintenance Visit {0} must be cancelled before cancelling this Sales Order,Visita de Mantenimiento {0} debe ser cancelado antes de cancelar la Orden de Ventas
|
||||||
DocType: Rename Tool,"Attach .csv file with two columns, one for the old name and one for the new name","Adjuntar archivo .csv con dos columnas, una para el nombre antiguo y otro para el nombre nuevo"
|
DocType: Rename Tool,"Attach .csv file with two columns, one for the old name and one for the new name","Adjuntar archivo .csv con dos columnas, una para el nombre antiguo y otro para el nombre nuevo"
|
||||||
DocType: Depreciation Schedule,Schedule Date,Horario Fecha
|
DocType: Depreciation Schedule,Schedule Date,Horario Fecha
|
||||||
DocType: UOM,UOM Name,Nombre Unidad de Medida
|
DocType: UOM,UOM Name,Nombre Unidad de Medida
|
||||||
|
|||||||
|