Merge branch 'develop'
@ -53,4 +53,4 @@ script:
|
||||
- set -e
|
||||
- bench --verbose run-tests
|
||||
- sleep 5
|
||||
- bench --verbose run-tests --ui-tests
|
||||
- bench --verbose run-ui-tests --app erpnext
|
||||
|
@ -1,8 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
import inspect
|
||||
import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
|
||||
__version__ = '8.4.3'
|
||||
__version__ = '8.5.0'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
@ -65,3 +67,34 @@ def is_perpetual_inventory_enabled(company):
|
||||
company, "enable_perpetual_inventory") or 0
|
||||
|
||||
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
|
||||
|
||||
|
||||
cur_frm.cscript.refresh = function (doc, cdt, cdn) {
|
||||
if (doc.__islocal) {
|
||||
frappe.msgprint(__("Please create new account from Chart of Accounts."));
|
||||
throw "cannot create";
|
||||
}
|
||||
|
||||
cur_frm.toggle_display('account_name', doc.__islocal);
|
||||
|
||||
// hide fields if group
|
||||
cur_frm.toggle_display(['account_type', 'tax_rate'], cint(doc.is_group) == 0)
|
||||
|
||||
// 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.ui.form.on('Account', {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch('parent_account', 'report_type', 'report_type');
|
||||
frm.add_fetch('parent_account', 'root_type', 'root_type');
|
||||
},
|
||||
onload: function(frm) {
|
||||
frm.set_query('parent_account', function(doc) {
|
||||
return {
|
||||
filters: {
|
||||
"is_group": 1,
|
||||
"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
|
||||
if(jvd.reference_type==="Expense Claim") {
|
||||
return {};
|
||||
return {
|
||||
filters: {
|
||||
'approval_status': 'Approved',
|
||||
'total_sanctioned_amount': ['>', 0],
|
||||
'status': ['!=', 'Paid'],
|
||||
'docstatus': 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// journal entry
|
||||
|
@ -98,6 +98,26 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
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 to POS type
|
||||
if(cur_frm.doc.is_pos) {
|
||||
@ -306,7 +326,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
|
||||
this.frm.refresh_fields();
|
||||
},
|
||||
|
||||
|
||||
company_address: function() {
|
||||
var me = this;
|
||||
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
|
||||
if (frappe.boot.sysdefaults.country == 'India') unhide_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");
|
||||
}
|
||||
|
||||
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) {
|
||||
// filter on Account
|
||||
if (doc.customer) {
|
||||
|
@ -18,6 +18,7 @@ from erpnext.projects.doctype.timesheet.timesheet import get_projectwise_timeshe
|
||||
from erpnext.accounts.doctype.asset.depreciation \
|
||||
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.serial_no.serial_no import get_serial_nos, get_delivery_note_serial_no
|
||||
|
||||
form_grid_templates = {
|
||||
"items": "templates/form_grid/item_grid.html"
|
||||
@ -83,10 +84,10 @@ class SalesInvoice(SellingController):
|
||||
|
||||
if not self.is_opening:
|
||||
self.is_opening = 'No'
|
||||
|
||||
|
||||
if self._action != 'submit' and self.update_stock and not self.is_return:
|
||||
set_batch_nos(self, 'warehouse', True)
|
||||
|
||||
|
||||
|
||||
self.set_against_income_account()
|
||||
self.validate_c_form()
|
||||
@ -98,7 +99,7 @@ class SalesInvoice(SellingController):
|
||||
self.set_billing_hours_and_amount()
|
||||
self.update_timesheet_billing_for_project()
|
||||
self.set_status()
|
||||
|
||||
|
||||
def before_save(self):
|
||||
set_account_for_mode_of_payment(self)
|
||||
|
||||
@ -139,6 +140,8 @@ class SalesInvoice(SellingController):
|
||||
|
||||
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):
|
||||
if len(self.payments) == 0 and self.is_pos:
|
||||
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
|
||||
"""
|
||||
self.set_serial_no_against_delivery_note()
|
||||
self.validate_serial_against_delivery_note()
|
||||
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):
|
||||
"""
|
||||
"""
|
||||
validate if the serial numbers in Sales Invoice Items are same as in
|
||||
Delivery Note Item
|
||||
"""
|
||||
@ -826,14 +836,18 @@ class SalesInvoice(SellingController):
|
||||
continue
|
||||
|
||||
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 ""
|
||||
si_serial_nos = set(serial_nos.split("\n"))
|
||||
si_serial_nos = set(get_serial_nos(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)))
|
||||
|
||||
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):
|
||||
""" check if serial number is already used in other sales invoice """
|
||||
for item in self.items:
|
||||
@ -918,7 +932,6 @@ def make_delivery_note(source_name, target_doc=None):
|
||||
|
||||
return doclist
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_sales_return(source_name, target_doc=None):
|
||||
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 frappe.model.naming import make_autoname
|
||||
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):
|
||||
def make(self):
|
||||
@ -1105,10 +1106,75 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
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.append("items", {
|
||||
"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",
|
||||
"qty": 100,
|
||||
"rate": 50,
|
||||
@ -1125,11 +1191,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"rate": 10
|
||||
})
|
||||
si.insert()
|
||||
|
||||
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)
|
||||
|
||||
return si
|
||||
|
||||
def create_sales_invoice(**args):
|
||||
si = frappe.new_doc("Sales Invoice")
|
||||
@ -1150,6 +1212,7 @@ def create_sales_invoice(**args):
|
||||
|
||||
si.append("items", {
|
||||
"item_code": args.item or args.item_code or "_Test Item",
|
||||
"gst_hsn_code": "999800",
|
||||
"warehouse": args.warehouse or "_Test Warehouse - _TC",
|
||||
"qty": args.qty or 1,
|
||||
"rate": args.rate or 100,
|
||||
|
@ -1424,7 +1424,7 @@
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "eval:doc.serial_no || doc.batch_no",
|
||||
"columns": 0,
|
||||
"depends_on": "eval: parent.update_stock",
|
||||
"depends_on": "",
|
||||
"fieldname": "warehouse_and_reference",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -2166,7 +2166,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-06 17:54:03.347700",
|
||||
"modified": "2017-07-17 17:54:48.246507",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
|
@ -1398,10 +1398,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
return erpnext.get_currency(this.frm.doc.company);
|
||||
},
|
||||
|
||||
show_item_wise_taxes: function () {
|
||||
return null;
|
||||
},
|
||||
|
||||
show_items_in_item_cart: function () {
|
||||
var me = this;
|
||||
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):
|
||||
def __setup__(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):
|
||||
"""set missing item values"""
|
||||
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"):
|
||||
parent_dict = {}
|
||||
@ -196,7 +197,7 @@ class AccountsController(TransactionBase):
|
||||
|
||||
elif fieldname == "serial_no":
|
||||
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)
|
||||
|
||||
elif fieldname == "conversion_factor" and not item.get("conversion_factor"):
|
||||
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
||||
import json
|
||||
import frappe, erpnext
|
||||
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, \
|
||||
validate_taxes_and_charges, validate_inclusive_tax
|
||||
|
||||
@ -509,108 +509,72 @@ class calculate_taxes_and_totals(object):
|
||||
return rate_with_margin
|
||||
|
||||
def set_item_wise_tax_breakup(self):
|
||||
item_tax = {}
|
||||
tax_accounts = []
|
||||
company_currency = erpnext.get_company_currency(self.doc.company)
|
||||
if not self.doc.taxes:
|
||||
return
|
||||
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)
|
||||
|
||||
if not rows:
|
||||
self.doc.other_charges_calculation = ""
|
||||
else:
|
||||
self.doc.other_charges_calculation = '''
|
||||
<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>'''.format(**{
|
||||
"headings": "".join(headings),
|
||||
"rows": "".join(rows)
|
||||
})
|
||||
self.doc.other_charges_calculation = frappe.render_template(
|
||||
"templates/includes/itemised_tax_breakup.html", dict(
|
||||
headers=headers,
|
||||
itemised_tax=itemised_tax,
|
||||
itemised_taxable_amount=itemised_taxable_amount,
|
||||
tax_accounts=tax_accounts,
|
||||
company_currency=erpnext.get_company_currency(self.doc.company)
|
||||
)
|
||||
)
|
||||
|
||||
def get_item_tax(self, item_tax, tax_accounts, company_currency):
|
||||
for tax in self.doc.taxes:
|
||||
tax_amount_precision = tax.precision("tax_amount")
|
||||
tax_rate_precision = tax.precision("rate");
|
||||
@erpnext.allow_regional
|
||||
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
|
||||
return [_("Item"), _("Taxable Amount")] + tax_accounts
|
||||
|
||||
@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)
|
||||
for item_code, tax_data in item_tax_map.items():
|
||||
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
|
||||
if isinstance(tax_data, list) and tax_data[0]:
|
||||
precision = tax_amount_precision if tax.charge_type == "Actual" else tax_rate_precision
|
||||
|
||||
return distinct_items, taxable_amount
|
||||
|
||||
def get_table_column_headings(tax_accounts):
|
||||
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>")
|
||||
itemised_tax[item_code][tax.description] = frappe._dict(dict(
|
||||
tax_rate=flt(tax_data[0], precision),
|
||||
tax_amount=flt(tax_data[1], tax_amount_precision)
|
||||
))
|
||||
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
|
||||
rows.append("<tr><td>{item_name}</td><td class='text-right'>{taxable_amount}</td>{taxes}</tr>".format(**{
|
||||
"item_name": item.item_name,
|
||||
"taxable_amount": fmt_money(taxable_amount.get(item_code, 0), item.precision("net_amount"), company_currency),
|
||||
"taxes": "".join(taxes)
|
||||
}))
|
||||
|
||||
return rows
|
||||
itemised_taxable_amount.setdefault(item_code, 0)
|
||||
itemised_taxable_amount[item_code] += item.net_amount
|
||||
|
||||
return itemised_taxable_amount
|
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
|
||||
"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.>
|
||||
Copyright (C) <year> <name of author>
|
||||
<pre><code> <one line="" to="" give="" the="" program's="" name="" and="" a="" brief="" idea="" of="" what="" it="" does.="">
|
||||
Copyright (C) <year> <name of="" author="">
|
||||
|
||||
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
|
||||
|
@ -15,5 +15,6 @@ third-party-backups
|
||||
workflows
|
||||
bar-code
|
||||
company-setup
|
||||
setting-company-sales-goal
|
||||
calculate-incentive-for-sales-team
|
||||
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 frappe import _
|
||||
from . import __version__ as app_version
|
||||
|
||||
app_name = "erpnext"
|
||||
app_title = "ERPNext"
|
||||
@ -80,13 +79,7 @@ website_route_rules = [
|
||||
"parents": [{"title": _("Supplier Quotation"), "name": "quotations"}]
|
||||
}
|
||||
},
|
||||
{"from_route": "/quotes", "to_route": "Quotation"},
|
||||
{"from_route": "/quotes/<path:name>", "to_route": "order",
|
||||
"defaults": {
|
||||
"doctype": "Quotation",
|
||||
"parents": [{"title": _("Quotes"), "name": "quotes"}]
|
||||
}
|
||||
},
|
||||
{"from_route": "/quotation", "to_route": "Quotation"},
|
||||
{"from_route": "/shipments", "to_route": "Delivery Note"},
|
||||
{"from_route": "/shipments/<path:name>", "to_route": "order",
|
||||
"defaults": {
|
||||
@ -117,7 +110,7 @@ standard_portal_menu_items = [
|
||||
{"title": _("Projects"), "route": "/project", "reference_doctype": "Project"},
|
||||
{"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": _("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": _("Invoices"), "route": "/invoices", "reference_doctype": "Sales Invoice", "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.accounts.doctype.asset.depreciation.post_depreciation_entries",
|
||||
"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;">
|
||||
<a href="https://erpnext.com?source=via_email_footer" target="_blank" style="color: #8d99a6;">
|
||||
Sent via ERPNext
|
||||
@ -211,3 +207,11 @@ bot_parsers = [
|
||||
get_site_info = 'erpnext.utilities.get_site_info'
|
||||
|
||||
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 email_reply_parser import EmailReplyParser
|
||||
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
|
||||
|
||||
class DailyWorkSummary(Document):
|
||||
@ -24,17 +24,18 @@ class DailyWorkSummary(Document):
|
||||
|
||||
def send_summary(self):
|
||||
'''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),
|
||||
message = message,
|
||||
template='daily_work_summary',
|
||||
args=args,
|
||||
subject = _('Daily Work Summary for {0}').format(self.company),
|
||||
reference_doctype=self.doctype, reference_name=self.name)
|
||||
|
||||
self.db_set('status', 'Sent')
|
||||
|
||||
def get_summary_message(self):
|
||||
'''Return summary of replies as HTML'''
|
||||
def get_message_details(self):
|
||||
'''Return args for template'''
|
||||
settings = frappe.get_doc('Daily Work Summary Settings')
|
||||
|
||||
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()
|
||||
|
||||
for d in replies:
|
||||
d.sender_name = frappe.db.get_value("Employee", {"user_id": d.sender},
|
||||
"employee_name") or d.sender
|
||||
emp = frappe.db.get_values("Employee", {"user_id": 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:
|
||||
did_not_reply.remove(d.sender)
|
||||
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)
|
||||
for email in did_not_reply]
|
||||
|
||||
return frappe.render_template(self.get_summary_template(),
|
||||
dict(replies=replies,
|
||||
original_message=settings.message,
|
||||
title=_('Daily Work Summary for {0}'.format(formatdate(self.creation))),
|
||||
did_not_reply= ', '.join(did_not_reply) or '',
|
||||
did_not_reply_title = _('No replies from')))
|
||||
return dict(replies=replies,
|
||||
original_message=settings.message,
|
||||
title=_('Daily Work Summary for {0}'.format(global_date_format(self.creation))),
|
||||
did_not_reply= ', '.join(did_not_reply) or '',
|
||||
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):
|
||||
'''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',
|
||||
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):
|
||||
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() {
|
||||
return {
|
||||
filters: {
|
||||
"root_type": "Liability",
|
||||
"report_type": "Balance Sheet",
|
||||
"account_type": "Payable"
|
||||
}
|
||||
}
|
||||
|
@ -905,7 +905,7 @@
|
||||
"label": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Draft\nPaid\nUnpaid\nSubmitted\nCancelled",
|
||||
"options": "Draft\nPaid\nUnpaid\nRejected\nSubmitted\nCancelled",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
@ -964,7 +964,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-06-13 14:29:16.914609",
|
||||
"modified": "2017-07-17 15:47:23.255142",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Expense Claim",
|
||||
|
@ -39,10 +39,13 @@ class ExpenseClaim(AccountsController):
|
||||
"2": "Cancelled"
|
||||
}[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"
|
||||
elif self.docstatus == 1:
|
||||
elif self.total_sanctioned_amount > 0 and self.docstatus == 1 and self.approval_status == 'Approved':
|
||||
self.status = "Unpaid"
|
||||
elif self.docstatus == 1 and self.approval_status == 'Rejected':
|
||||
self.status = 'Rejected'
|
||||
|
||||
def set_payable_account(self):
|
||||
if not self.payable_account and not self.is_paid:
|
||||
@ -157,6 +160,9 @@ class ExpenseClaim(AccountsController):
|
||||
self.total_claimed_amount = 0
|
||||
self.total_sanctioned_amount = 0
|
||||
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_sanctioned_amount += flt(d.sanctioned_amount)
|
||||
|
||||
|
@ -4,8 +4,10 @@ frappe.listview_settings['Expense Claim'] = {
|
||||
get_indicator: function(doc) {
|
||||
if(doc.status == "Paid") {
|
||||
return [__("Paid"), "green", "status,=,'Paid'"];
|
||||
} else {
|
||||
}else if(doc.status == "Unpaid") {
|
||||
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][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):
|
||||
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 filters: Filters (JSON).
|
||||
"""
|
||||
condition = ''
|
||||
values = {
|
||||
"start_date": getdate(start),
|
||||
"end_date": getdate(end)
|
||||
}
|
||||
|
||||
if filters:
|
||||
if isinstance(filters, basestring):
|
||||
filters = json.loads(filters)
|
||||
filters = json.loads(filters)
|
||||
else:
|
||||
filters = []
|
||||
|
||||
if filters.get('holiday_list'):
|
||||
condition = 'and hlist.name=%(holiday_list)s'
|
||||
values['holiday_list'] = filters['holiday_list']
|
||||
if start:
|
||||
filters.append(['Holiday', 'holiday_date', '>', getdate(start)])
|
||||
if end:
|
||||
filters.append(['Holiday', 'holiday_date', '<', getdate(end)])
|
||||
|
||||
data = frappe.db.sql("""select hlist.name, h.holiday_date, h.description
|
||||
from `tabHoliday List` hlist, tabHoliday h
|
||||
where h.parent = hlist.name
|
||||
and h.holiday_date is not null
|
||||
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
|
||||
return frappe.get_list('Holiday List',
|
||||
fields=['name', '`tabHoliday`.holiday_date', '`tabHoliday`.description'],
|
||||
filters = filters,
|
||||
update={"allDay": 1})
|
||||
|
@ -63,13 +63,13 @@ class LeaveApplication(Document):
|
||||
def validate_dates(self):
|
||||
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"))
|
||||
|
||||
|
||||
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)):
|
||||
|
||||
|
||||
frappe.throw(_("Half Day Date should be between From Date and To Date"))
|
||||
|
||||
|
||||
if not is_lwp(self.leave_type):
|
||||
self.validate_dates_acorss_allocation()
|
||||
self.validate_back_dated_application()
|
||||
@ -158,7 +158,7 @@ class LeaveApplication(Document):
|
||||
self.name = "New Leave Application"
|
||||
|
||||
for d in frappe.db.sql("""
|
||||
select
|
||||
select
|
||||
name, leave_type, posting_date, from_date, to_date, total_leave_days, half_day_date
|
||||
from `tabLeave Application`
|
||||
where employee = %(employee)s and docstatus < 2 and status in ("Open", "Approved")
|
||||
@ -169,12 +169,12 @@ class LeaveApplication(Document):
|
||||
"to_date": self.to_date,
|
||||
"name": self.name
|
||||
}, as_dict = 1):
|
||||
|
||||
|
||||
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
|
||||
or getdate(self.from_date) == getdate(d.to_date)
|
||||
flt(self.total_leave_days)==0.5
|
||||
or getdate(self.from_date) == getdate(d.to_date)
|
||||
or getdate(self.to_date) == getdate(d.from_date)):
|
||||
|
||||
|
||||
total_leaves_on_half_day = self.get_total_leaves_on_half_day()
|
||||
if total_leaves_on_half_day >= 1:
|
||||
self.throw_overlap_error(d)
|
||||
@ -199,7 +199,7 @@ class LeaveApplication(Document):
|
||||
"half_day_date": self.half_day_date,
|
||||
"name": self.name
|
||||
})[0][0]
|
||||
|
||||
|
||||
return leave_count_on_half_day_date * 0.5
|
||||
|
||||
def validate_max_days(self):
|
||||
@ -400,7 +400,7 @@ def is_lwp(leave_type):
|
||||
return lwp and cint(lwp[0][0]) or 0
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_events(start, end):
|
||||
def get_events(start, end, filters=None):
|
||||
events = []
|
||||
|
||||
employee = frappe.db.get_value("Employee", {"user_id": frappe.session.user}, ["name", "company"],
|
||||
@ -411,14 +411,14 @@ def get_events(start, end):
|
||||
employee=''
|
||||
company=frappe.db.get_value("Global Defaults", None, "default_company")
|
||||
|
||||
from frappe.desk.reportview import build_match_conditions
|
||||
match_conditions = build_match_conditions("Leave Application")
|
||||
from frappe.desk.reportview import get_filters_cond
|
||||
conditions = get_filters_cond("Leave Application")
|
||||
|
||||
# show department leaves for employee
|
||||
if "Employee" in frappe.get_roles():
|
||||
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_holidays(events, start, end, employee, company)
|
||||
|
@ -8,3 +8,6 @@ from frappe.model.document import Document
|
||||
|
||||
class ProductionOrderItem(Document):
|
||||
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.allow_invoice_copy_to_edit_after_submit
|
||||
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"):
|
||||
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.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 `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
|
||||
from datetime import timedelta
|
||||
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.mapper import get_mapped_doc
|
||||
from erpnext.manufacturing.doctype.workstation.workstation import (check_if_within_operating_hours,
|
||||
WorkstationHolidayError)
|
||||
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:
|
||||
summary = self.get_actual_timesheet_summary(timesheet.operation_id)
|
||||
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_start_time = summary.from_time
|
||||
data.actual_end_time = summary.to_time
|
||||
@ -148,7 +147,7 @@ class Timesheet(Document):
|
||||
"""Returns 'Actual Operating Time'. """
|
||||
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,
|
||||
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""",
|
||||
(self.production_order, operation_id), as_dict=1)[0]
|
||||
|
||||
@ -192,7 +191,7 @@ class Timesheet(Document):
|
||||
if fieldname == 'workstation':
|
||||
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
|
||||
(
|
||||
(%(from_time)s > tsd.from_time and %(from_time)s < tsd.to_time) or
|
||||
@ -211,8 +210,8 @@ class Timesheet(Document):
|
||||
# check internal overlap
|
||||
for time_log in self.time_logs:
|
||||
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.to_time > time_log.from_time and args.to_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.from_time <= time_log.from_time and args.to_time >= time_log.to_time)):
|
||||
return self
|
||||
|
||||
@ -239,7 +238,7 @@ class Timesheet(Document):
|
||||
self.check_workstation_working_day(data)
|
||||
|
||||
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""",
|
||||
{'workstation': workstation}, as_dict=True)[0]
|
||||
|
||||
@ -277,7 +276,7 @@ def get_projectwise_timesheet_data(project, parent=None):
|
||||
if parent:
|
||||
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
|
||||
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"
|
||||
|
||||
return frappe.db.sql("""select distinct tsd.parent from `tabTimesheet Detail` tsd,
|
||||
`tabTimesheet` ts where
|
||||
ts.status in ('Submitted', 'Payslip') and tsd.parent = ts.name and
|
||||
tsd.docstatus = 1 and ts.total_billable_amount > 0
|
||||
`tabTimesheet` ts where
|
||||
ts.status in ('Submitted', 'Payslip') and tsd.parent = ts.name and
|
||||
tsd.docstatus = 1 and ts.total_billable_amount > 0
|
||||
and tsd.parent LIKE %(txt)s {condition}
|
||||
order by tsd.parent limit %(start)s, %(page_len)s"""
|
||||
.format(condition=condition), {
|
||||
@ -305,7 +304,7 @@ def get_timesheet_data(name, project):
|
||||
if project and project!='':
|
||||
data = get_projectwise_timesheet_data(project, name)
|
||||
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})
|
||||
|
||||
return {
|
||||
@ -332,7 +331,7 @@ def make_sales_invoice(source_name, target=None):
|
||||
@frappe.whitelist()
|
||||
def make_salary_slip(source_name, target_doc=None):
|
||||
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")
|
||||
|
||||
return target
|
||||
@ -364,32 +363,21 @@ def get_events(start, end, filters=None):
|
||||
:param filters: Filters (JSON).
|
||||
"""
|
||||
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,
|
||||
from_time as start_date, hours, activity_type,
|
||||
`tabTimesheet Detail`.project, to_time as end_date,
|
||||
CONCAT(`tabTimesheet Detail`.parent, ' (', ROUND(hours,2),' hrs)') as title
|
||||
from `tabTimesheet Detail`, `tabTimesheet`
|
||||
where `tabTimesheet Detail`.parent = `tabTimesheet`.name
|
||||
and `tabTimesheet`.docstatus < 2
|
||||
from_time as start_date, hours, activity_type,
|
||||
`tabTimesheet Detail`.project, to_time as end_date,
|
||||
CONCAT(`tabTimesheet Detail`.parent, ' (', ROUND(hours,2),' hrs)') as title
|
||||
from `tabTimesheet Detail`, `tabTimesheet`
|
||||
where `tabTimesheet Detail`.parent = `tabTimesheet`.name
|
||||
and `tabTimesheet`.docstatus < 2
|
||||
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,
|
||||
"end": end
|
||||
}, 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.calculate_totals();
|
||||
this._cleanup();
|
||||
this.show_item_wise_taxes();
|
||||
},
|
||||
|
||||
validate_conversion_rate: function() {
|
||||
@ -634,99 +633,5 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
}
|
||||
|
||||
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() {
|
||||
erpnext.toggle_naming_series();
|
||||
erpnext.hide_company();
|
||||
this.show_item_wise_taxes();
|
||||
this.set_dynamic_labels();
|
||||
this.setup_sms();
|
||||
},
|
||||
@ -367,7 +366,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
|
||||
validate: function() {
|
||||
this.calculate_taxes_and_totals(false);
|
||||
this.set_item_wise_tax_breakup();
|
||||
},
|
||||
|
||||
company: function() {
|
||||
|
@ -104,7 +104,7 @@ var erpnext_slides = [
|
||||
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 },
|
||||
{ fieldtype: "Column Break" },
|
||||
{ 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
|
||||
name: 'taxes',
|
||||
|
@ -42,11 +42,15 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.updating_party_details = true;
|
||||
frm.set_value(r.message);
|
||||
frm.updating_party_details = false;
|
||||
if(callback) callback();
|
||||
frm.refresh();
|
||||
erpnext.utils.add_item(frm);
|
||||
frappe.run_serially([
|
||||
() => frm.set_value(r.message),
|
||||
() => {
|
||||
frm.updating_party_details = false;
|
||||
if(callback) callback();
|
||||
frm.refresh();
|
||||
erpnext.utils.add_item(frm);
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -66,7 +66,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
fieldtype:'Float',
|
||||
read_only: 1,
|
||||
label: __(me.has_batch ? 'Total Qty' : 'Qty'),
|
||||
default: me.qty
|
||||
default: 0
|
||||
},
|
||||
];
|
||||
|
||||
@ -155,14 +155,10 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
},
|
||||
|
||||
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 qty_field = this.dialog.fields_dict.qty;
|
||||
|
||||
let update_quantity = (batch) => {
|
||||
if(batch) {
|
||||
if(batches_field) {
|
||||
batches_field.grid.wrapper.on('change', function() {
|
||||
let total_qty = 0;
|
||||
batches_field.grid.wrapper.find(
|
||||
'input[data-fieldname="selected_qty"]').each(function() {
|
||||
@ -170,48 +166,6 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
total_qty += Number($(this).val());
|
||||
});
|
||||
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() {
|
||||
var me = this;
|
||||
this.serial_list = [];
|
||||
return [
|
||||
{fieldtype: 'Section Break', label: __('Serial No')},
|
||||
{
|
||||
@ -326,10 +281,46 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
label: __('Select'),
|
||||
get_query: function() {
|
||||
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'},
|
||||
{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_number": "36",
|
||||
"state_number": "05",
|
||||
"state_code": "UT",
|
||||
"state_name": "Uttarakhand"
|
||||
},
|
||||
|
@ -80,7 +80,7 @@ def add_print_formats():
|
||||
|
||||
def make_custom_fields():
|
||||
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 = {
|
||||
'Address': [
|
||||
|
@ -1,6 +1,7 @@
|
||||
import frappe, re
|
||||
from frappe import _
|
||||
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):
|
||||
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]:
|
||||
frappe.throw(_("First 2 digits of GSTIN should match with State number {0}")
|
||||
.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,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Academic Year",
|
||||
"length": 0,
|
||||
@ -148,7 +148,7 @@
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Program",
|
||||
"length": 0,
|
||||
@ -269,7 +269,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-05-15 12:43:32.317942",
|
||||
"modified": "2017-07-17 21:57:35.602091",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Student Group Creation Tool",
|
||||
@ -300,6 +300,7 @@
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
|
@ -1,346 +1,357 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "SLA.######",
|
||||
"beta": 0,
|
||||
"creation": "2016-11-28 15:38:54.793854",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "SLA.######",
|
||||
"beta": 0,
|
||||
"creation": "2016-11-28 15:38:54.793854",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "student",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Student",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Student",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "student",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Student",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Student",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "student_name",
|
||||
"fieldtype": "Read Only",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Student Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "student.title",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "student_name",
|
||||
"fieldtype": "Read Only",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Student Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "student.title",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "From Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "From Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "To Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "To Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Will show the student as Present in Student Monthly Attendance Report",
|
||||
"fieldname": "mark_as_present",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mark as Present",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Will show the student as Present in Student Monthly Attendance Report",
|
||||
"fieldname": "mark_as_present",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mark as Present",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reason",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reason",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reason",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reason",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amended From",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Student Leave Application",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amended From",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Student Leave Application",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-20 13:21:08.828872",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Student Leave Application",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-17 21:57:57.804413",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Student Leave Application",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Instructor",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 1,
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Instructor",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Academics User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Academics User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "student_name",
|
||||
"track_changes": 0,
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "student_name",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,399 +1,400 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "SLog.####",
|
||||
"beta": 0,
|
||||
"creation": "2016-07-29 03:27:22.451772",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "SLog.####",
|
||||
"beta": 0,
|
||||
"creation": "2016-07-29 03:27:22.451772",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "student",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Student",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Student",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "student",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Student",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Student",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "student_name",
|
||||
"fieldtype": "Read Only",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Student Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "student.title",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "student_name",
|
||||
"fieldtype": "Read Only",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Student Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "student.title",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "General\nAcademic\nMedical\nAchievement",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "General\nAcademic\nMedical\nAchievement",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "academic_year",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Academic Year",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Academic Year",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "academic_year",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Academic Year",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Academic Year",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "academic_term",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Academic Term",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Academic Term",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "academic_term",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Academic Term",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Academic Term",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "program",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Program",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Program",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "program",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Program",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Program",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "student_batch",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Student Batch",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Student Batch Name",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "student_batch",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Student Batch",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Student Batch Name",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "log",
|
||||
"fieldtype": "Text Editor",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Log",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "log",
|
||||
"fieldtype": "Text Editor",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Log",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-06 12:42:05.777673",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Student Log",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-17 21:57:11.024049",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Student Log",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Academics User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Academics User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "student_name",
|
||||
"track_changes": 0,
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "student_name",
|
||||
"track_changes": 0,
|
||||
"track_seen": 1
|
||||
}
|
@ -105,6 +105,10 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
|
||||
|
||||
lead: function() {
|
||||
var me = this;
|
||||
if(!this.frm.doc.lead) {
|
||||
return;
|
||||
}
|
||||
|
||||
frappe.call({
|
||||
method: "erpnext.crm.doctype.lead.lead.get_lead_details",
|
||||
args: {
|
||||
|
@ -93,7 +93,7 @@ def get_list_context(context=None):
|
||||
'show_sidebar': True,
|
||||
'show_search': True,
|
||||
'no_breadcrumbs': True,
|
||||
'title': _('Quotes'),
|
||||
'title': _('Quotations'),
|
||||
})
|
||||
|
||||
return list_context
|
||||
|
@ -10,3 +10,6 @@ from erpnext.controllers.print_settings import print_settings_for_item_table
|
||||
class SalesOrderItem(Document):
|
||||
def __setup__(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() {
|
||||
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() {
|
||||
|
@ -147,7 +147,7 @@ class Company(Document):
|
||||
def validate_perpetual_inventory(self):
|
||||
if not self.get("__islocal"):
|
||||
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')
|
||||
|
||||
def set_default_accounts(self):
|
||||
@ -310,3 +310,45 @@ def get_name_with_abbr(name, company):
|
||||
parts.append(company_abbr)
|
||||
|
||||
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
|
||||
import frappe
|
||||
from frappe import _
|
||||
|
||||
def get_domain(domain):
|
||||
'''Written as a function to prevent data mutation effects'''
|
||||
@ -78,8 +79,11 @@ def setup_domain(domain):
|
||||
setup_properties(data)
|
||||
set_values(data)
|
||||
setup_sidebar_items(data)
|
||||
update_module_def_restrict_to_domain()
|
||||
|
||||
if data.get('default_portal_role'):
|
||||
frappe.db.set_value('Portal Settings', None, 'default_role', data.get('default_portal_role'))
|
||||
|
||||
frappe.clear_cache()
|
||||
|
||||
def setup_desktop_icons(data):
|
||||
@ -137,9 +141,18 @@ def setup_sidebar_items(data):
|
||||
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])))
|
||||
|
||||
|
||||
def reset():
|
||||
from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to
|
||||
add_all_roles_to('Administrator')
|
||||
|
||||
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'),
|
||||
'create_chart_of_accounts_based_on': 'Standard Template',
|
||||
'chart_of_accounts': args.get('chart_of_accounts'),
|
||||
'domain': args.get('domain')
|
||||
'domain': args.get('domain'),
|
||||
'sales_target': args.get('sales_target')
|
||||
}).insert()
|
||||
|
||||
#Enable shopping cart
|
||||
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def get_notification_config():
|
||||
notification_for_doctype = { "for_doctype":
|
||||
notifications = { "for_doctype":
|
||||
{
|
||||
"Issue": {"status": "Open"},
|
||||
"Warranty Claim": {"status": "Open"},
|
||||
@ -56,12 +56,20 @@ def get_notification_config():
|
||||
"Production Order": { "status": ("in", ("Draft", "Not Started", "In Process")) },
|
||||
"BOM": {"docstatus": 0},
|
||||
"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',
|
||||
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 erpnext.stock.doctype.batch.batch import set_batch_nos
|
||||
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 = {
|
||||
"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):
|
||||
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, {
|
||||
"Delivery Note": {
|
||||
|
@ -170,6 +170,10 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
"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()
|
||||
|
||||
self.check_serial_no_values(serial_no, {
|
||||
@ -177,6 +181,22 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
"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):
|
||||
from frappe.model.naming import make_autoname
|
||||
serial_no = frappe.get_doc({
|
||||
|
@ -15,6 +15,7 @@
|
||||
"item_group": "_Test Item Group",
|
||||
"item_name": "_Test Item",
|
||||
"apply_warehouse_wise_reorder_level": 1,
|
||||
"gst_hsn_code": "999800",
|
||||
"valuation_rate": 100,
|
||||
"reorder_levels": [
|
||||
{
|
||||
|
@ -9,4 +9,7 @@ import frappe
|
||||
from frappe.model.document import 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))
|
||||
|
||||
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.set_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()
|
||||
item_map = get_item_details(filters)
|
||||
item_reorder_detail_map = get_item_reorder_details(filters)
|
||||
iwb_map = get_item_warehouse_map(filters)
|
||||
|
||||
data = []
|
||||
for (company, item, warehouse) in sorted(iwb_map):
|
||||
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"],
|
||||
item_map[item]["item_group"],
|
||||
item_map[item]["brand"],
|
||||
@ -27,6 +34,8 @@ def execute(filters=None):
|
||||
qty_dict.in_val, qty_dict.out_qty,
|
||||
qty_dict.out_val, qty_dict.bal_qty,
|
||||
qty_dict.bal_val, qty_dict.val_rate,
|
||||
item_reorder_level,
|
||||
item_reorder_qty,
|
||||
company
|
||||
])
|
||||
|
||||
@ -52,6 +61,8 @@ def get_columns():
|
||||
_("Balance Qty")+":Float:100",
|
||||
_("Balance Value")+":Float:100",
|
||||
_("Valuation Rate")+":Float:90",
|
||||
_("Reorder Level")+":Float:80",
|
||||
_("Reorder Qty")+":Float:80",
|
||||
_("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
|
||||
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):
|
||||
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,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2017-06-23 14:21:37.558691",
|
||||
"creation": "2017-07-13 17:14:40.408706",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"letter_head": "",
|
||||
"modified": "2017-06-23 16:33:31.211390",
|
||||
"modified": "2017-07-13 17:14:40.408706",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Support",
|
||||
"name": "Support Hours",
|
||||
"name": "Support Hour Distribution",
|
||||
"owner": "Administrator",
|
||||
"ref_doctype": "Issue",
|
||||
"report_name": "Support Hours",
|
||||
"report_name": "Support Hour Distribution",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
@ -23,12 +23,14 @@ def execute(filters=None):
|
||||
filters['periodicity'] = 'Daily'
|
||||
|
||||
columns = get_columns()
|
||||
data = get_data(filters)
|
||||
return columns, data
|
||||
data, timeslot_wise_count = get_data(filters)
|
||||
chart = get_chartdata(timeslot_wise_count)
|
||||
return columns, data, None, chart
|
||||
|
||||
def get_data(filters):
|
||||
start_date = getdate(filters.from_date)
|
||||
data = []
|
||||
time_slot_wise_total_count = {}
|
||||
while(start_date <= getdate(filters.to_date)):
|
||||
hours_count = {'date': start_date}
|
||||
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))
|
||||
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)
|
||||
time_slot_wise_total_count[key] = time_slot_wise_total_count.get(key, 0) + hours_count[key]
|
||||
|
||||
if hours_count:
|
||||
data.append(hours_count)
|
||||
|
||||
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):
|
||||
data = frappe.db.sql(""" select count(*) from `tabIssue` where creation
|
||||
@ -70,4 +73,25 @@ def get_columns():
|
||||
"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) {
|
||||
assert.expect(18);
|
||||
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: Student,Guardians,Guardianes
|
||||
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/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: Delivery Note,% Installed,% Instalado
|
||||
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
|
||||
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
|
||||
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
|
||||
|
|
@ -1,6 +1,6 @@
|
||||
DocType: Delivery Note,% Installed,% Instalado
|
||||
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.
|
||||
|
||||
#### 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: Sales Invoice Timesheet,Billing Hours,Horas 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: Purchase Order Item,Billed Amt,Monto Facturado
|
||||
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/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/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/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"
|
||||
@ -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/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/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: 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."
|
||||
@ -129,7 +129,7 @@ DocType: Project,Default Cost Center,Centro de coste por defecto
|
||||
DocType: Employee,Employee Number,Número del Empleado
|
||||
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.
|
||||
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.
|
||||
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
|
||||
@ -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
|
||||
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/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: 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
|
||||
@ -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}
|
||||
DocType: Production Order,Not Started,Sin comenzar
|
||||
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
|
||||
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
|
||||
@ -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)
|
||||
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
|
||||
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
|
||||
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.
|
||||
@ -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/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 )"
|
||||
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/public/js/setup_wizard.js +94,What does it do?,¿Qué hace?
|
||||
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.
|
||||
DocType: Item Customer Detail,Ref Code,Código Referencia
|
||||
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: 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/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
|
||||
,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
|
||||
@ -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
|
||||
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/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
|
||||
DocType: Buying Settings,Settings for Buying Module,Ajustes para la compra de módulo
|
||||
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
|
||||
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/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/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
|
||||
@ -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 .
|
||||
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
|
||||
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}
|
||||
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)
|
||||
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/accounts/doctype/purchase_invoice/purchase_invoice.js +558,Product Bundle,Conjunto/Paquete de productos
|
||||
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 +566,Product Bundle,Conjunto/Paquete de productos
|
||||
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}
|
||||
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: Serial No,Warranty Period (Days),Período de garantía ( Días)
|
||||
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
|
||||
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
|
||||
@ -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: Customer,Buyer of Goods and Services.,Compradores de Productos y Servicios.
|
||||
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
|
||||
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.
|
||||
@ -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
|
||||
DocType: Employee,Permanent Address Is,Dirección permanente es
|
||||
,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/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/manufacturing/doctype/production_order/production_order.js +351,Max: {0},Max: {0}
|
||||
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
|
||||
,Item Prices,Precios de los Artículos
|
||||
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/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
|
||||
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
|
||||
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
|
||||
@ -470,14 +470,14 @@ DocType: Payment Gateway Account,Payment Account,Pago a cuenta
|
||||
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/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}
|
||||
DocType: Sales Person,Select company name first.,Seleccionar nombre de la empresa en primer lugar.
|
||||
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
|
||||
DocType: Purchase Receipt Item,Required By,Requerido por
|
||||
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/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
|
||||
@ -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: 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/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
|
||||
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.
|
||||
@ -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/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
|
||||
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
|
||||
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +75,Row # {0}:,Fila # {0}:
|
||||
DocType: Timesheet,% Amount Billed,% Monto Facturado
|
||||
DocType: BOM,Manage cost of operations,Administrar el costo de las operaciones
|
||||
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/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
|
||||
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
|
||||
@ -630,7 +630,7 @@ DocType: Production Planning Tool,Production Planning Tool,Herramienta de planif
|
||||
DocType: Maintenance Schedule,Schedules,Horarios
|
||||
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
|
||||
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: Serial No,Out of AMC,Fuera de AMC
|
||||
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
|
||||
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
|
||||
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
|
||||
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.
|
||||
@ -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
|
||||
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/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: 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
|
||||
@ -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 )
|
||||
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/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
|
||||
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
|
||||
@ -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: 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/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/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
|
||||
@ -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
|
||||
DocType: HR Settings,Employee Records to be created by,Registros de empleados a ser creados por
|
||||
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: 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
|
||||
DocType: Authorization Rule,Applicable To (Role),Aplicable a (Rol )
|
||||
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/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: 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
|
||||
@ -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/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/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: 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/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
|
||||
@ -1009,7 +1009,7 @@ DocType: Production Plan Sales Order,Production Plan Sales Order,Plan de producc
|
||||
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"
|
||||
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: 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
|
||||
@ -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/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/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: 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: Purchase Invoice,In Words (Company Currency),En palabras (Moneda Local)
|
||||
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/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/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}
|
||||
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
|
||||
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
|
||||
@ -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
|
||||
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
|
||||
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: Depreciation Schedule,Schedule Date,Horario Fecha
|
||||
DocType: UOM,UOM Name,Nombre Unidad de Medida
|
||||
|
|