Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6c396f176 | ||
|
|
93b5367485 | ||
|
|
5995010007 | ||
|
|
0d38a6b495 | ||
|
|
a85b68ee77 | ||
|
|
ca31425bb4 | ||
|
|
253c53cf53 | ||
|
|
ac3b2aa913 | ||
|
|
5d7e8d9e83 | ||
|
|
6a5cf672c1 | ||
|
|
5f7b88d9c3 | ||
|
|
465d8352aa | ||
|
|
38ada81487 | ||
|
|
e38c70c8bc | ||
|
|
157c334737 | ||
|
|
4b12896941 | ||
|
|
7b0c682635 | ||
|
|
d45a036b5e | ||
|
|
d7d9cd2938 | ||
|
|
7e7dc0f254 | ||
|
|
e9cf1aba77 | ||
|
|
c2bf50042f | ||
|
|
ca89b6f59c | ||
|
|
12ec71781d | ||
|
|
659a225f24 | ||
|
|
d0ebd7f7c2 | ||
|
|
adfe84b04f | ||
|
|
7916590528 | ||
|
|
fdce7a0dc3 | ||
|
|
b3d4326dcc | ||
|
|
54fcf85317 | ||
|
|
689da20e7b | ||
|
|
eb92d907bc | ||
|
|
0cd792ebb2 | ||
|
|
e4afab7fb0 | ||
|
|
bf4915b285 | ||
|
|
7e661437b1 | ||
|
|
818ad397c8 | ||
|
|
ce9ac7885e | ||
|
|
c320537e4c | ||
|
|
9283377f87 | ||
|
|
331566d612 | ||
|
|
ff70f38eac | ||
|
|
d1552f97e4 | ||
|
|
baa4afd67b | ||
|
|
2f0c34385b | ||
|
|
258f7da778 | ||
|
|
799a9cabe7 | ||
|
|
24f0b13b22 | ||
|
|
2d79a641c2 | ||
|
|
7a9bd41a72 | ||
|
|
cf1e0508af | ||
|
|
88906cfc63 | ||
|
|
e72c98dafb | ||
|
|
f8b412ba98 | ||
|
|
c8a25b6dac | ||
|
|
724cc35421 |
@@ -2,7 +2,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
__version__ = '8.0.35'
|
__version__ = '8.0.41'
|
||||||
|
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
|
|||||||
@@ -299,6 +299,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
this.calculate_write_off_amount()
|
this.calculate_write_off_amount()
|
||||||
}else {
|
}else {
|
||||||
this.frm.set_value("change_amount", 0.0)
|
this.frm.set_value("change_amount", 0.0)
|
||||||
|
this.frm.set_value("base_change_amount", 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.frm.refresh_fields();
|
this.frm.refresh_fields();
|
||||||
|
|||||||
@@ -411,10 +411,10 @@ class SalesInvoice(SellingController):
|
|||||||
throw(_("Customer {0} does not belong to project {1}").format(self.customer,self.project))
|
throw(_("Customer {0} does not belong to project {1}").format(self.customer,self.project))
|
||||||
|
|
||||||
def validate_pos(self):
|
def validate_pos(self):
|
||||||
if flt(self.paid_amount) + flt(self.write_off_amount) \
|
if self.is_return:
|
||||||
- flt(self.grand_total) > 1/(10**(self.precision("grand_total") + 1)) and self.is_return:
|
if flt(self.paid_amount) + flt(self.write_off_amount) - flt(self.grand_total) < \
|
||||||
frappe.throw(_("""Paid amount + Write Off Amount can not be greater than Grand Total"""))
|
1/(10**(self.precision("grand_total") + 1)):
|
||||||
|
frappe.throw(_("Paid amount + Write Off Amount can not be greater than Grand Total"))
|
||||||
|
|
||||||
def validate_item_code(self):
|
def validate_item_code(self):
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
|
|||||||
@@ -361,7 +361,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
print_settings: this.print_settings,
|
print_settings: this.print_settings,
|
||||||
header: this.letter_head.header,
|
header: this.letter_head.header,
|
||||||
footer: this.letter_head.footer,
|
footer: this.letter_head.footer,
|
||||||
landscape: false
|
landscape: false,
|
||||||
|
columns: []
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -708,7 +709,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
filter: function (item, input) {
|
filter: function (item, input) {
|
||||||
var value = item.value.toLowerCase();
|
var value = item.value.toLowerCase();
|
||||||
if (value.indexOf('is_action') !== -1 ||
|
if (value.indexOf('is_action') !== -1 ||
|
||||||
value.indexOf(input) !== -1) {
|
value.indexOf(input.toLowerCase()) !== -1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,10 +7,13 @@ import frappe
|
|||||||
import datetime
|
import datetime
|
||||||
from frappe import _, msgprint, scrub
|
from frappe import _, msgprint, scrub
|
||||||
from frappe.defaults import get_user_permissions
|
from frappe.defaults import get_user_permissions
|
||||||
from frappe.utils import add_days, getdate, formatdate, get_first_day, date_diff, add_years, get_timestamp
|
from frappe.utils import add_days, getdate, formatdate, get_first_day, date_diff, \
|
||||||
|
add_years, get_timestamp, nowdate, flt
|
||||||
from frappe.geo.doctype.address.address import get_address_display, get_default_address
|
from frappe.geo.doctype.address.address import get_address_display, get_default_address
|
||||||
from frappe.email.doctype.contact.contact import get_contact_details, get_default_contact
|
from frappe.email.doctype.contact.contact import get_contact_details, get_default_contact
|
||||||
from erpnext.exceptions import PartyFrozen, InvalidCurrency, PartyDisabled, InvalidAccountCurrency
|
from erpnext.exceptions import PartyFrozen, InvalidCurrency, PartyDisabled, InvalidAccountCurrency
|
||||||
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
|
from erpnext import get_default_currency
|
||||||
|
|
||||||
class DuplicatePartyAccountError(frappe.ValidationError): pass
|
class DuplicatePartyAccountError(frappe.ValidationError): pass
|
||||||
|
|
||||||
@@ -360,3 +363,38 @@ def get_timeline_data(doctype, name):
|
|||||||
out.update({ timestamp: count })
|
out.update({ timestamp: count })
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
def get_dashboard_info(party_type, party):
|
||||||
|
current_fiscal_year = get_fiscal_year(nowdate(), as_dict=True)
|
||||||
|
company = frappe.db.get_default("company") or frappe.get_all("Company")[0].name
|
||||||
|
party_account_currency = get_party_account_currency(party_type, party, company)
|
||||||
|
company_default_currency = get_default_currency() \
|
||||||
|
or frappe.db.get_value('Company', company, 'default_currency')
|
||||||
|
|
||||||
|
if party_account_currency==company_default_currency:
|
||||||
|
total_field = "base_grand_total"
|
||||||
|
else:
|
||||||
|
total_field = "grand_total"
|
||||||
|
|
||||||
|
doctype = "Sales Invoice" if party_type=="Customer" else "Purchase Invoice"
|
||||||
|
|
||||||
|
billing_this_year = frappe.db.sql("""
|
||||||
|
select sum({0})
|
||||||
|
from `tab{1}`
|
||||||
|
where {2}=%s and docstatus=1 and posting_date between %s and %s
|
||||||
|
""".format(total_field, doctype, party_type.lower()),
|
||||||
|
(party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date))
|
||||||
|
|
||||||
|
total_unpaid = frappe.db.sql("""
|
||||||
|
select sum(debit_in_account_currency) - sum(credit_in_account_currency)
|
||||||
|
from `tabGL Entry`
|
||||||
|
where party_type = %s and party=%s""", (party_type, party))
|
||||||
|
|
||||||
|
info = {}
|
||||||
|
info["billing_this_year"] = flt(billing_this_year[0][0]) if billing_this_year else 0
|
||||||
|
info["currency"] = party_account_currency
|
||||||
|
info["total_unpaid"] = flt(total_unpaid[0][0]) if total_unpaid else 0
|
||||||
|
if party_type == "Supplier":
|
||||||
|
info["total_unpaid"] = -1 * info["total_unpaid"]
|
||||||
|
|
||||||
|
return info
|
||||||
|
|||||||
@@ -6,11 +6,9 @@ import frappe
|
|||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from frappe import msgprint, _
|
from frappe import msgprint, _
|
||||||
from frappe.model.naming import make_autoname
|
from frappe.model.naming import make_autoname
|
||||||
from frappe.geo.address_and_contact import (load_address_and_contact,
|
from frappe.geo.address_and_contact import load_address_and_contact, delete_contact_and_address
|
||||||
delete_contact_and_address)
|
|
||||||
|
|
||||||
from erpnext.utilities.transaction_base import TransactionBase
|
from erpnext.utilities.transaction_base import TransactionBase
|
||||||
from erpnext.accounts.party import validate_party_accounts, get_timeline_data # keep this
|
from erpnext.accounts.party import validate_party_accounts, get_dashboard_info, get_timeline_data # keep this
|
||||||
|
|
||||||
class Supplier(TransactionBase):
|
class Supplier(TransactionBase):
|
||||||
def get_feed(self):
|
def get_feed(self):
|
||||||
@@ -22,22 +20,7 @@ class Supplier(TransactionBase):
|
|||||||
self.load_dashboard_info()
|
self.load_dashboard_info()
|
||||||
|
|
||||||
def load_dashboard_info(self):
|
def load_dashboard_info(self):
|
||||||
billing_this_year = frappe.db.sql("""
|
info = get_dashboard_info(self.doctype, self.name)
|
||||||
select sum(credit_in_account_currency) - sum(debit_in_account_currency)
|
|
||||||
from `tabGL Entry`
|
|
||||||
where voucher_type='Purchase Invoice' and party_type = 'Supplier'
|
|
||||||
and party=%s and fiscal_year = %s""",
|
|
||||||
(self.name, frappe.db.get_default("fiscal_year")))
|
|
||||||
|
|
||||||
total_unpaid = frappe.db.sql("""select sum(outstanding_amount)
|
|
||||||
from `tabPurchase Invoice`
|
|
||||||
where supplier=%s and docstatus = 1""", self.name)
|
|
||||||
|
|
||||||
|
|
||||||
info = {}
|
|
||||||
info["billing_this_year"] = billing_this_year[0][0] if billing_this_year else 0
|
|
||||||
info["total_unpaid"] = total_unpaid[0][0] if total_unpaid else 0
|
|
||||||
|
|
||||||
self.set_onload('dashboard_info', info)
|
self.set_onload('dashboard_info', info)
|
||||||
|
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ status_map = {
|
|||||||
["Converted", "has_customer"],
|
["Converted", "has_customer"],
|
||||||
],
|
],
|
||||||
"Opportunity": [
|
"Opportunity": [
|
||||||
["Quotation", "has_active_quotation"],
|
|
||||||
["Converted", "has_ordered_quotation"],
|
|
||||||
["Lost", "eval:self.status=='Lost'"],
|
["Lost", "eval:self.status=='Lost'"],
|
||||||
["Lost", "has_lost_quotation"],
|
["Lost", "has_lost_quotation"],
|
||||||
|
["Quotation", "has_active_quotation"],
|
||||||
|
["Converted", "has_ordered_quotation"],
|
||||||
["Closed", "eval:self.status=='Closed'"]
|
["Closed", "eval:self.status=='Closed'"]
|
||||||
],
|
],
|
||||||
"Quotation": [
|
"Quotation": [
|
||||||
|
|||||||
@@ -442,15 +442,15 @@ class calculate_taxes_and_totals(object):
|
|||||||
|
|
||||||
if self.doc.doctype == "Sales Invoice":
|
if self.doc.doctype == "Sales Invoice":
|
||||||
self.doc.round_floats_in(self.doc, ["paid_amount"])
|
self.doc.round_floats_in(self.doc, ["paid_amount"])
|
||||||
|
self.calculate_write_off_amount()
|
||||||
|
self.calculate_change_amount()
|
||||||
|
|
||||||
paid_amount = self.doc.paid_amount \
|
paid_amount = self.doc.paid_amount \
|
||||||
if self.doc.party_account_currency == self.doc.currency else self.doc.base_paid_amount
|
if self.doc.party_account_currency == self.doc.currency else self.doc.base_paid_amount
|
||||||
|
|
||||||
change_amount = self.doc.change_amount \
|
change_amount = self.doc.change_amount \
|
||||||
if self.doc.party_account_currency == self.doc.currency else self.doc.base_change_amount
|
if self.doc.party_account_currency == self.doc.currency else self.doc.base_change_amount
|
||||||
|
|
||||||
self.calculate_write_off_amount()
|
|
||||||
self.calculate_change_amount()
|
|
||||||
|
|
||||||
self.doc.outstanding_amount = flt(total_amount_to_pay - flt(paid_amount) +
|
self.doc.outstanding_amount = flt(total_amount_to_pay - flt(paid_amount) +
|
||||||
flt(change_amount), self.doc.precision("outstanding_amount"))
|
flt(change_amount), self.doc.precision("outstanding_amount"))
|
||||||
|
|
||||||
@@ -462,7 +462,8 @@ class calculate_taxes_and_totals(object):
|
|||||||
|
|
||||||
if self.doc.is_pos:
|
if self.doc.is_pos:
|
||||||
for payment in self.doc.get('payments'):
|
for payment in self.doc.get('payments'):
|
||||||
payment.base_amount = flt(payment.amount * self.doc.conversion_rate)
|
payment.amount = flt(payment.amount)
|
||||||
|
payment.base_amount = payment.amount * flt(self.doc.conversion_rate)
|
||||||
paid_amount += payment.amount
|
paid_amount += payment.amount
|
||||||
base_paid_amount += payment.base_amount
|
base_paid_amount += payment.base_amount
|
||||||
elif not self.doc.is_return:
|
elif not self.doc.is_return:
|
||||||
@@ -474,7 +475,9 @@ class calculate_taxes_and_totals(object):
|
|||||||
def calculate_change_amount(self):
|
def calculate_change_amount(self):
|
||||||
self.doc.change_amount = 0.0
|
self.doc.change_amount = 0.0
|
||||||
self.doc.base_change_amount = 0.0
|
self.doc.base_change_amount = 0.0
|
||||||
if self.doc.paid_amount > self.doc.grand_total:
|
if self.doc.paid_amount > self.doc.grand_total and not self.doc.is_return \
|
||||||
|
and any([d.type == "Cash" for d in self.doc.payments]):
|
||||||
|
|
||||||
self.doc.change_amount = flt(self.doc.paid_amount - self.doc.grand_total +
|
self.doc.change_amount = flt(self.doc.paid_amount - self.doc.grand_total +
|
||||||
self.doc.write_off_amount, self.doc.precision("change_amount"))
|
self.doc.write_off_amount, self.doc.precision("change_amount"))
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ frappe.ui.form.on("Opportunity", {
|
|||||||
var doc = frm.doc;
|
var doc = frm.doc;
|
||||||
frm.events.enquiry_from(frm);
|
frm.events.enquiry_from(frm);
|
||||||
frm.trigger('set_contact_link');
|
frm.trigger('set_contact_link');
|
||||||
|
erpnext.toggle_naming_series();
|
||||||
|
|
||||||
if(!doc.__islocal && doc.status!=="Lost") {
|
if(!doc.__islocal && doc.status!=="Lost") {
|
||||||
if(doc.with_items){
|
if(doc.with_items){
|
||||||
@@ -53,6 +54,20 @@ frappe.ui.form.on("Opportunity", {
|
|||||||
frm.add_custom_button(__('Lost'),
|
frm.add_custom_button(__('Lost'),
|
||||||
cur_frm.cscript['Declare Opportunity Lost']);
|
cur_frm.cscript['Declare Opportunity Lost']);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
if(!frm.doc.__islocal && frm.perm[0].write && frm.doc.docstatus==0) {
|
||||||
|
if(frm.doc.status==="Open") {
|
||||||
|
frm.add_custom_button(__("Close"), function() {
|
||||||
|
frm.set_value("status", "Closed");
|
||||||
|
frm.save();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
frm.add_custom_button(__("Reopen"), function() {
|
||||||
|
frm.set_value("status", "Open");
|
||||||
|
frm.save();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -122,25 +137,6 @@ erpnext.crm.Opportunity = frappe.ui.form.Controller.extend({
|
|||||||
|
|
||||||
$.extend(cur_frm.cscript, new erpnext.crm.Opportunity({frm: cur_frm}));
|
$.extend(cur_frm.cscript, new erpnext.crm.Opportunity({frm: cur_frm}));
|
||||||
|
|
||||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
|
||||||
erpnext.toggle_naming_series();
|
|
||||||
|
|
||||||
var frm = cur_frm;
|
|
||||||
if(!doc.__islocal && frm.perm[0].write && doc.docstatus==0) {
|
|
||||||
if(frm.doc.status==="Open") {
|
|
||||||
frm.add_custom_button(__("Close"), function() {
|
|
||||||
frm.set_value("status", "Closed");
|
|
||||||
frm.save();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
frm.add_custom_button(__("Reopen"), function() {
|
|
||||||
frm.set_value("status", "Open");
|
|
||||||
frm.save();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
|
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
|
||||||
if(doc.enquiry_from == 'Lead' && doc.lead)
|
if(doc.enquiry_from == 'Lead' && doc.lead)
|
||||||
cur_frm.cscript.lead(doc, cdt, cdn);
|
cur_frm.cscript.lead(doc, cdt, cdn);
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ class Opportunity(TransactionBase):
|
|||||||
if not self.enquiry_from:
|
if not self.enquiry_from:
|
||||||
frappe.throw(_("Opportunity From field is mandatory"))
|
frappe.throw(_("Opportunity From field is mandatory"))
|
||||||
|
|
||||||
self.set_status()
|
|
||||||
self.validate_item_details()
|
self.validate_item_details()
|
||||||
self.validate_uom_is_integer("uom", "qty")
|
self.validate_uom_is_integer("uom", "qty")
|
||||||
self.validate_lead_cust()
|
self.validate_lead_cust()
|
||||||
|
|||||||
@@ -178,7 +178,8 @@ scheduler_events = {
|
|||||||
"erpnext.hr.doctype.employee.employee.send_birthday_reminders",
|
"erpnext.hr.doctype.employee.employee.send_birthday_reminders",
|
||||||
"erpnext.projects.doctype.task.task.set_tasks_as_overdue",
|
"erpnext.projects.doctype.task.task.set_tasks_as_overdue",
|
||||||
"erpnext.accounts.doctype.asset.depreciation.post_depreciation_entries",
|
"erpnext.accounts.doctype.asset.depreciation.post_depreciation_entries",
|
||||||
'erpnext.hr.doctype.daily_work_summary_settings.daily_work_summary_settings.send_summary'
|
"erpnext.hr.doctype.daily_work_summary_settings.daily_work_summary_settings.send_summary",
|
||||||
|
"erpnext.stock.doctype.serial_no.serial_no.update_maintenance_status"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from erpnext.accounts.party import get_party_account
|
|||||||
from erpnext.accounts.general_ledger import make_gl_entries
|
from erpnext.accounts.general_ledger import make_gl_entries
|
||||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
|
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
|
||||||
from erpnext.controllers.accounts_controller import AccountsController
|
from erpnext.controllers.accounts_controller import AccountsController
|
||||||
|
from frappe.utils.csvutils import getlink
|
||||||
|
|
||||||
class InvalidExpenseApproverError(frappe.ValidationError): pass
|
class InvalidExpenseApproverError(frappe.ValidationError): pass
|
||||||
|
|
||||||
@@ -146,7 +147,7 @@ class ExpenseClaim(AccountsController):
|
|||||||
frappe.throw(_("Cost center is required to book an expense claim"))
|
frappe.throw(_("Cost center is required to book an expense claim"))
|
||||||
|
|
||||||
if not self.payable_account:
|
if not self.payable_account:
|
||||||
frappe.throw(_("Please set default payable account in the employee {0}").format(self.employee))
|
frappe.throw(_("Please set default payable account for the company {0}").format(getlink("Company",self.company)))
|
||||||
|
|
||||||
if self.is_paid:
|
if self.is_paid:
|
||||||
if not self.mode_of_payment:
|
if not self.mode_of_payment:
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class JobApplicant(Document):
|
|||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.check_email_id_is_unique()
|
self.check_email_id_is_unique()
|
||||||
|
if self.email_id:
|
||||||
validate_email_add(self.email_id, True)
|
validate_email_add(self.email_id, True)
|
||||||
|
|
||||||
if not self.applicant_name and self.email_id:
|
if not self.applicant_name and self.email_id:
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ frappe.provide("erpnext.offer_letter");
|
|||||||
|
|
||||||
frappe.ui.form.on("Offer Letter", {
|
frappe.ui.form.on("Offer Letter", {
|
||||||
select_terms: function(frm) {
|
select_terms: function(frm) {
|
||||||
frappe.model.get_value("Terms and Conditions", frm.doc.select_terms, "terms", function(value) {
|
erpnext.utils.get_terms(frm.doc.select_terms, frm.doc, function(r) {
|
||||||
frm.set_value("terms", value.terms);
|
if(!r.exc) {
|
||||||
|
me.frm.set_value("terms", r.message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "field:event_name",
|
"autoname": "field:event_name",
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -27,7 +29,7 @@
|
|||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Event Name",
|
"label": "Event Name",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 1,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@@ -41,6 +43,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -71,6 +74,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -99,6 +103,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -129,6 +134,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -157,6 +163,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -186,6 +193,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -216,6 +224,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -244,6 +253,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -274,6 +284,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -303,6 +314,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -331,6 +343,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -361,6 +374,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -390,6 +404,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -418,6 +433,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -447,6 +463,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -476,6 +493,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -504,6 +522,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -533,6 +552,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -562,6 +582,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -592,6 +613,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -622,6 +644,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -651,17 +674,17 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
"hide_toolbar": 0,
|
"hide_toolbar": 0,
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"image_view": 0,
|
"image_view": 0,
|
||||||
"in_create": 0,
|
"in_create": 0,
|
||||||
"in_dialog": 0,
|
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-02-17 16:51:35.141403",
|
"modified": "2017-05-29 06:13:38.411039",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Training Event",
|
"name": "Training Event",
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ class TrainingResult(Document):
|
|||||||
|
|
||||||
def send_result(self):
|
def send_result(self):
|
||||||
for emp in self.employees:
|
for emp in self.employees:
|
||||||
message = "Thank You for attending {0}. You grade is {1}".format(self.training_event, emp.grade)
|
message = "Thank You for attending {0}.".format(self.training_event)
|
||||||
|
if emp.grade:
|
||||||
|
message = message + "Your grade: {0}".format(emp.grade)
|
||||||
frappe.sendmail(frappe.db.get_value("Employee", emp.employee, "company_email"), \
|
frappe.sendmail(frappe.db.get_value("Employee", emp.employee, "company_email"), \
|
||||||
subject=_("{0} Results".format(self.training_event)), \
|
subject=_("{0} Results".format(self.training_event)), \
|
||||||
content=message)
|
content=message)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings
|
|||||||
from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
|
from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
|
||||||
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
|
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
|
||||||
from erpnext.stock.utils import get_bin
|
from erpnext.stock.utils import get_bin
|
||||||
|
from frappe.utils.csvutils import getlink
|
||||||
|
|
||||||
class OverProductionError(frappe.ValidationError): pass
|
class OverProductionError(frappe.ValidationError): pass
|
||||||
class StockOverProductionError(frappe.ValidationError): pass
|
class StockOverProductionError(frappe.ValidationError): pass
|
||||||
@@ -311,7 +312,7 @@ class ProductionOrder(Document):
|
|||||||
|
|
||||||
if timesheet and timesheet.get("time_logs"):
|
if timesheet and timesheet.get("time_logs"):
|
||||||
timesheet.save()
|
timesheet.save()
|
||||||
timesheets.append(timesheet.name)
|
timesheets.append(getlink("Timesheet", timesheet.name))
|
||||||
|
|
||||||
self.planned_end_date = self.operations[-1].planned_end_time
|
self.planned_end_date = self.operations[-1].planned_end_time
|
||||||
if timesheets:
|
if timesheets:
|
||||||
|
|||||||
@@ -396,3 +396,4 @@ erpnext.patches.v8_0.merge_student_batch_and_student_group
|
|||||||
erpnext.patches.v8_0.rename_total_margin_to_rate_with_margin # 11-05-2017
|
erpnext.patches.v8_0.rename_total_margin_to_rate_with_margin # 11-05-2017
|
||||||
erpnext.patches.v8_0.fix_status_for_invoices_with_negative_outstanding
|
erpnext.patches.v8_0.fix_status_for_invoices_with_negative_outstanding
|
||||||
erpnext.patches.v8_0.make_payments_table_blank_for_non_pos_invoice
|
erpnext.patches.v8_0.make_payments_table_blank_for_non_pos_invoice
|
||||||
|
erpnext.patches.v8_0.delete_schools_depricated_doctypes
|
||||||
|
|||||||
@@ -3,16 +3,21 @@ from frappe.model.utils.rename_field import rename_field
|
|||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
#Rename Grading Structure to Grading Scale
|
#Rename Grading Structure to Grading Scale
|
||||||
|
if not frappe.db.exists("DocType", "Grading Scale"):
|
||||||
frappe.rename_doc("DocType", "Grading Structure", "Grading Scale", force=True)
|
frappe.rename_doc("DocType", "Grading Structure", "Grading Scale", force=True)
|
||||||
|
if not frappe.db.exists("DocType", "Grading Scale Interval"):
|
||||||
frappe.rename_doc("DocType", "Grade Interval", "Grading Scale Interval", force=True)
|
frappe.rename_doc("DocType", "Grade Interval", "Grading Scale Interval", force=True)
|
||||||
|
|
||||||
frappe.reload_doc("schools", "doctype", "grading_scale_interval")
|
frappe.reload_doc("schools", "doctype", "grading_scale_interval")
|
||||||
|
if "to_score" in frappe.db.get_table_columns("Grading Scale Interval"):
|
||||||
rename_field("Grading Scale Interval", "to_score", "threshold")
|
rename_field("Grading Scale Interval", "to_score", "threshold")
|
||||||
|
|
||||||
|
if not frappe.db.exists("DocType", "Assessment Plan"):
|
||||||
frappe.rename_doc("DocType", "Assessment", "Assessment Plan", force=True)
|
frappe.rename_doc("DocType", "Assessment", "Assessment Plan", force=True)
|
||||||
|
|
||||||
#Rename Assessment Results
|
#Rename Assessment Results
|
||||||
frappe.reload_doc("schools", "doctype", "assessment_plan")
|
frappe.reload_doc("schools", "doctype", "assessment_plan")
|
||||||
|
if "grading_structure" in frappe.db.get_table_columns("Assessment Plan"):
|
||||||
rename_field("Assessment Plan", "grading_structure", "grading_scale")
|
rename_field("Assessment Plan", "grading_structure", "grading_scale")
|
||||||
|
|
||||||
frappe.reload_doc("schools", "doctype", "assessment_result")
|
frappe.reload_doc("schools", "doctype", "assessment_result")
|
||||||
@@ -20,9 +25,10 @@ def execute():
|
|||||||
frappe.reload_doc("schools", "doctype", "assessment_criteria")
|
frappe.reload_doc("schools", "doctype", "assessment_criteria")
|
||||||
|
|
||||||
|
|
||||||
for assessment in frappe.get_all("Assessment Plan", fields=["name", "grading_scale"], filters = [["docstatus", "!=", 2 ]]):
|
for assessment in frappe.get_all("Assessment Plan",
|
||||||
print assessment
|
fields=["name", "grading_scale"], filters = [["docstatus", "!=", 2 ]]):
|
||||||
for stud_result in frappe.db.sql("select * from `tabAssessment Result` where parent= %s", assessment.name, as_dict=True):
|
for stud_result in frappe.db.sql("select * from `tabAssessment Result` where parent= %s",
|
||||||
|
assessment.name, as_dict=True):
|
||||||
if stud_result.result:
|
if stud_result.result:
|
||||||
assessment_result = frappe.new_doc("Assessment Result")
|
assessment_result = frappe.new_doc("Assessment Result")
|
||||||
assessment_result.student = stud_result.student
|
assessment_result.student = stud_result.student
|
||||||
|
|||||||
14
erpnext/patches/v8_0/delete_schools_depricated_doctypes.py
Normal file
14
erpnext/patches/v8_0/delete_schools_depricated_doctypes.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Copyright (c) 2017, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
""" delete doctypes """
|
||||||
|
|
||||||
|
if frappe.db.exists("DocType", "Grading Structure"):
|
||||||
|
frappe.delete_doc("DocType", "Grading Structure", force=1)
|
||||||
|
|
||||||
|
if frappe.db.exists("DocType", "Grade Interval"):
|
||||||
|
frappe.delete_doc("DocType", "Grade Interval", force=1)
|
||||||
@@ -368,7 +368,8 @@ def get_events(start, end, filters=None):
|
|||||||
conditions = get_conditions(filters)
|
conditions = get_conditions(filters)
|
||||||
return frappe.db.sql("""select `tabTimesheet Detail`.name as name,
|
return frappe.db.sql("""select `tabTimesheet Detail`.name as name,
|
||||||
`tabTimesheet Detail`.docstatus as status, `tabTimesheet Detail`.parent as parent,
|
`tabTimesheet Detail`.docstatus as status, `tabTimesheet Detail`.parent as parent,
|
||||||
from_time as start_date, hours, activity_type, project, to_time as end_date,
|
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
|
CONCAT(`tabTimesheet Detail`.parent, ' (', ROUND(hours,2),' hrs)') as title
|
||||||
from `tabTimesheet Detail`, `tabTimesheet`
|
from `tabTimesheet Detail`, `tabTimesheet`
|
||||||
where `tabTimesheet Detail`.parent = `tabTimesheet`.name
|
where `tabTimesheet Detail`.parent = `tabTimesheet`.name
|
||||||
|
|||||||
@@ -604,11 +604,18 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
|||||||
|
|
||||||
calculate_change_amount: function(){
|
calculate_change_amount: function(){
|
||||||
this.frm.doc.change_amount = 0.0;
|
this.frm.doc.change_amount = 0.0;
|
||||||
|
this.frm.doc.base_change_amount = 0.0;
|
||||||
if(this.frm.doc.paid_amount > this.frm.doc.grand_total && !this.frm.doc.is_return) {
|
if(this.frm.doc.paid_amount > this.frm.doc.grand_total && !this.frm.doc.is_return) {
|
||||||
|
var payment_types = $.map(cur_frm.doc.payments, function(d) { return d.type });
|
||||||
|
if (in_list(payment_types, 'Cash')) {
|
||||||
this.frm.doc.change_amount = flt(this.frm.doc.paid_amount - this.frm.doc.grand_total +
|
this.frm.doc.change_amount = flt(this.frm.doc.paid_amount - this.frm.doc.grand_total +
|
||||||
this.frm.doc.write_off_amount, precision("change_amount"));
|
this.frm.doc.write_off_amount, precision("change_amount"));
|
||||||
this.frm.doc.base_change_amount = flt(this.frm.doc.base_paid_amount - this.frm.doc.base_grand_total +
|
|
||||||
this.frm.doc.base_write_off_amount, precision("base_change_amount"));
|
this.frm.doc.base_change_amount = flt(this.frm.doc.base_paid_amount -
|
||||||
|
this.frm.doc.base_grand_total + this.frm.doc.base_write_off_amount,
|
||||||
|
precision("base_change_amount"));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
// if rate is greater than price_list_rate, set margin
|
// if rate is greater than price_list_rate, set margin
|
||||||
// or set discount
|
// or set discount
|
||||||
item.discount_percentage = 0;
|
item.discount_percentage = 0;
|
||||||
item.margin_type = 'Percentage';
|
item.margin_type = 'Amount';
|
||||||
item.margin_rate_or_amount = flt(Math.abs(1 - item.rate / item.price_list_rate) * 100.0,
|
item.margin_rate_or_amount = flt(item.rate - item.price_list_rate,
|
||||||
precision("discount_percentage", item));
|
precision("margin_rate_or_amount", item));
|
||||||
item.rate_with_margin = item.rate;
|
item.rate_with_margin = item.rate;
|
||||||
} else {
|
} else {
|
||||||
item.discount_percentage = flt((1 - item.rate / item.price_list_rate) * 100.0,
|
item.discount_percentage = flt((1 - item.rate / item.price_list_rate) * 100.0,
|
||||||
@@ -993,20 +993,12 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
get_terms: function() {
|
get_terms: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
if(this.frm.doc.tc_name) {
|
|
||||||
return frappe.call({
|
erpnext.utils.get_terms(this.frm.doc.tc_name, this.frm.doc, function(r) {
|
||||||
method: 'erpnext.setup.doctype.terms_and_conditions.terms_and_conditions.get_terms_and_conditions',
|
|
||||||
args: {
|
|
||||||
template_name: this.frm.doc.tc_name,
|
|
||||||
doc: this.frm.doc
|
|
||||||
},
|
|
||||||
callback: function(r) {
|
|
||||||
if(!r.exc) {
|
if(!r.exc) {
|
||||||
me.frm.set_value("terms", r.message);
|
me.frm.set_value("terms", r.message);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
taxes_and_charges: function() {
|
taxes_and_charges: function() {
|
||||||
|
|||||||
@@ -68,12 +68,12 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-6 numeric_keypad hidden-xs" style="display:none">
|
<div class="col-xs-6 numeric_keypad hidden-xs" style="display:none">
|
||||||
{% var chartData = [__("Qty"), __("Disc"), __("Price")] %} {% for(var i=0; i
|
{% var chartData = ["Qty", "Disc", "Price"] %} {% for(var i=0; i
|
||||||
<3; i++) { %} <div class="row text-right">
|
<3; i++) { %} <div class="row text-right">
|
||||||
{% for(var j=i*3; j
|
{% for(var j=i*3; j
|
||||||
<(i+1)*3; j++) { %} <button type="button" class="btn btn-default numeric-keypad" val="{{j+1}}">{{j+1}}</button>
|
<(i+1)*3; j++) { %} <button type="button" class="btn btn-default numeric-keypad" val="{{j+1}}">{{j+1}}</button>
|
||||||
{% } %}
|
{% } %}
|
||||||
<button type="button" id="pos-item-{{ chartData[i].toLowerCase() }}" class="btn text-center btn-default numeric-keypad pos-operation">{{ chartData[i] }}</button>
|
<button type="button" id="pos-item-{{ chartData[i].toLowerCase() }}" class="btn text-center btn-default numeric-keypad pos-operation">{{ __(chartData[i]) }}</button>
|
||||||
</div>
|
</div>
|
||||||
{% } %}
|
{% } %}
|
||||||
<div class="row text-right">
|
<div class="row text-right">
|
||||||
|
|||||||
@@ -104,6 +104,21 @@ $.extend(erpnext.utils, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
refresh_field(table_fieldname);
|
refresh_field(table_fieldname);
|
||||||
|
},
|
||||||
|
|
||||||
|
get_terms: function(tc_name, doc, callback) {
|
||||||
|
if(tc_name) {
|
||||||
|
return frappe.call({
|
||||||
|
method: 'erpnext.setup.doctype.terms_and_conditions.terms_and_conditions.get_terms_and_conditions',
|
||||||
|
args: {
|
||||||
|
template_name: tc_name,
|
||||||
|
doc: doc
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
callback(r)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,122 +0,0 @@
|
|||||||
{
|
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2016-08-26 03:11:09.591049",
|
|
||||||
"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": "grade_code",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Grade Code",
|
|
||||||
"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": "min_score",
|
|
||||||
"fieldtype": "Percent",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Min Score",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "1",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "grade_description",
|
|
||||||
"fieldtype": "Small Text",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Grade Description",
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"in_dialog": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 1,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2016-12-14 12:54:56.902465",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Schools",
|
|
||||||
"name": "Grade Interval",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
from frappe.model.document import Document
|
|
||||||
|
|
||||||
class GradeInterval(Document):
|
|
||||||
def validate(self):
|
|
||||||
pass
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
frappe.ui.form.on('Grading Structure', {
|
|
||||||
refresh: function(frm) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
{
|
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 1,
|
|
||||||
"autoname": "field:grading_system_name",
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2016-08-26 03:06:53.922972",
|
|
||||||
"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": "grading_system_name",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Grading System Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_2",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 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": "description",
|
|
||||||
"fieldtype": "Text",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Description",
|
|
||||||
"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": "grading_intervals_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Grading Intervals",
|
|
||||||
"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": "grade_intervals",
|
|
||||||
"fieldtype": "Table",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Grade Intervals",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Grade Interval",
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"in_dialog": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2016-12-14 12:35:39.690256",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Schools",
|
|
||||||
"name": "Grading Structure",
|
|
||||||
"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,
|
|
||||||
"is_custom": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Academics User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"title_field": "grading_system_name",
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
from frappe.model.document import Document
|
|
||||||
from frappe import _
|
|
||||||
from frappe.utils import cstr
|
|
||||||
|
|
||||||
class GradingStructure(Document):
|
|
||||||
def validate(self):
|
|
||||||
grade_intervals = self.get("grade_intervals")
|
|
||||||
check_overlap(grade_intervals, self)
|
|
||||||
|
|
||||||
#Check if any of the grade intervals for this grading structure overlap
|
|
||||||
def check_overlap(grade_intervals, parent_doc):
|
|
||||||
for interval1 in grade_intervals:
|
|
||||||
for interval2 in grade_intervals:
|
|
||||||
if interval1.name == interval2.name:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
if (interval1.from_score <= interval2.from_score and interval1.to_score >= interval2.from_score) or (interval1.from_score <= interval2.to_score and interval1.to_score >= interval2.to_score):
|
|
||||||
frappe.throw(_("""The intervals for Grade Code {0} overlaps with the grade intervals for other grades.
|
|
||||||
Please check intervals {0} and {1} and try again""".format(interval1.grade_code, interval2.grade_code)))
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# See license.txt
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import frappe
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
# test_records = frappe.get_test_records('Grading Structure')
|
|
||||||
|
|
||||||
class TestGradingStructure(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
@@ -14,7 +14,7 @@ class StudentGroup(Document):
|
|||||||
self.validate_strength()
|
self.validate_strength()
|
||||||
if frappe.defaults.get_defaults().student_validation_setting:
|
if frappe.defaults.get_defaults().student_validation_setting:
|
||||||
self.validate_students()
|
self.validate_students()
|
||||||
self.validate_roll_no()
|
self.validate_and_set_child_table_fields()
|
||||||
validate_duplicate_student(self.students)
|
validate_duplicate_student(self.students)
|
||||||
|
|
||||||
def validate_mandatory_fields(self):
|
def validate_mandatory_fields(self):
|
||||||
@@ -38,9 +38,16 @@ class StudentGroup(Document):
|
|||||||
if not frappe.db.get_value("Student", d.student, "enabled") and d.active:
|
if not frappe.db.get_value("Student", d.student, "enabled") and d.active:
|
||||||
frappe.throw(_("{0} - {1} is inactive student".format(d.group_roll_number, d.student_name)))
|
frappe.throw(_("{0} - {1} is inactive student".format(d.group_roll_number, d.student_name)))
|
||||||
|
|
||||||
def validate_roll_no(self):
|
def validate_and_set_child_table_fields(self):
|
||||||
|
roll_numbers = [d.group_roll_number for d in self.students if d.group_roll_number]
|
||||||
|
max_roll_no = max(roll_numbers) if roll_numbers else 0
|
||||||
roll_no_list = []
|
roll_no_list = []
|
||||||
for d in self.students:
|
for d in self.students:
|
||||||
|
if not d.student_name:
|
||||||
|
d.student_name = frappe.db.get_value("Student", d.student, "title")
|
||||||
|
if not d.group_roll_number:
|
||||||
|
max_roll_no += 1
|
||||||
|
d.group_roll_number = max_roll_no
|
||||||
if d.group_roll_number in roll_no_list:
|
if d.group_roll_number in roll_no_list:
|
||||||
frappe.throw(_("Duplicate roll number for student {0}".format(d.student_name)))
|
frappe.throw(_("Duplicate roll number for student {0}".format(d.student_name)))
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -5,8 +5,23 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import unittest
|
import unittest
|
||||||
|
from frappe.utils.make_random import get_random
|
||||||
# test_records = frappe.get_test_records('Student Group')
|
|
||||||
|
|
||||||
class TestStudentGroup(unittest.TestCase):
|
class TestStudentGroup(unittest.TestCase):
|
||||||
pass
|
def test_student_roll_no(self):
|
||||||
|
doc = frappe.get_doc({
|
||||||
|
"doctype": "Student Group",
|
||||||
|
"student_group_name": "_Test Student Group R",
|
||||||
|
"group_based_on": "Activity"
|
||||||
|
}).insert()
|
||||||
|
|
||||||
|
student_list = []
|
||||||
|
while len(student_list) < 3:
|
||||||
|
s = get_random("Student")
|
||||||
|
if s not in student_list:
|
||||||
|
student_list.append(s)
|
||||||
|
|
||||||
|
doc.extend("students", [{"student":d} for d in student_list])
|
||||||
|
doc.save()
|
||||||
|
self.assertEquals(max([d.group_roll_number for d in doc.students]), 3)
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ from frappe.utils import flt, cint, cstr
|
|||||||
from frappe.desk.reportview import build_match_conditions
|
from frappe.desk.reportview import build_match_conditions
|
||||||
from erpnext.utilities.transaction_base import TransactionBase
|
from erpnext.utilities.transaction_base import TransactionBase
|
||||||
from frappe.geo.address_and_contact import load_address_and_contact, delete_contact_and_address
|
from frappe.geo.address_and_contact import load_address_and_contact, delete_contact_and_address
|
||||||
from erpnext.accounts.party import validate_party_accounts, get_timeline_data # keep this
|
from erpnext.accounts.party import validate_party_accounts, get_dashboard_info, get_timeline_data # keep this
|
||||||
from erpnext import get_default_currency
|
|
||||||
|
|
||||||
class Customer(TransactionBase):
|
class Customer(TransactionBase):
|
||||||
def get_feed(self):
|
def get_feed(self):
|
||||||
@@ -23,25 +22,9 @@ class Customer(TransactionBase):
|
|||||||
self.load_dashboard_info()
|
self.load_dashboard_info()
|
||||||
|
|
||||||
def load_dashboard_info(self):
|
def load_dashboard_info(self):
|
||||||
billing_this_year = frappe.db.sql("""
|
info = get_dashboard_info(self.doctype, self.name)
|
||||||
select sum(debit_in_account_currency) - sum(credit_in_account_currency), account_currency
|
|
||||||
from `tabGL Entry`
|
|
||||||
where voucher_type='Sales Invoice' and party_type = 'Customer'
|
|
||||||
and party=%s and fiscal_year = %s""",
|
|
||||||
(self.name, frappe.db.get_default("fiscal_year")))
|
|
||||||
|
|
||||||
total_unpaid = frappe.db.sql("""select sum(outstanding_amount)
|
|
||||||
from `tabSales Invoice`
|
|
||||||
where customer=%s and docstatus = 1""", self.name)
|
|
||||||
|
|
||||||
info = {}
|
|
||||||
info["billing_this_year"] = billing_this_year[0][0] if billing_this_year else 0
|
|
||||||
info["currency"] = billing_this_year[0][1] if billing_this_year else get_default_currency()
|
|
||||||
info["total_unpaid"] = total_unpaid[0][0] if total_unpaid else 0
|
|
||||||
|
|
||||||
self.set_onload('dashboard_info', info)
|
self.set_onload('dashboard_info', info)
|
||||||
|
|
||||||
|
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
cust_master_name = frappe.defaults.get_global_default('cust_master_name')
|
cust_master_name = frappe.defaults.get_global_default('cust_master_name')
|
||||||
if cust_master_name == 'Customer Name':
|
if cust_master_name == 'Customer Name':
|
||||||
|
|||||||
@@ -348,10 +348,14 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
|||||||
margin_type: function(doc, cdt, cdn){
|
margin_type: function(doc, cdt, cdn){
|
||||||
// calculate the revised total margin and rate on margin type changes
|
// calculate the revised total margin and rate on margin type changes
|
||||||
item = locals[cdt][cdn];
|
item = locals[cdt][cdn];
|
||||||
|
if(!item.margin_type) {
|
||||||
|
frappe.model.set_value(cdt, cdn, "margin_rate_or_amount", 0);
|
||||||
|
} else {
|
||||||
this.apply_pricing_rule_on_item(item, doc,cdt, cdn)
|
this.apply_pricing_rule_on_item(item, doc,cdt, cdn)
|
||||||
this.calculate_taxes_and_totals();
|
this.calculate_taxes_and_totals();
|
||||||
cur_frm.refresh_fields();
|
cur_frm.refresh_fields();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on(cur_frm.doctype,"project", function(frm) {
|
frappe.ui.form.on(cur_frm.doctype,"project", function(frm) {
|
||||||
|
|||||||
@@ -91,8 +91,7 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None):
|
|||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
value = response.json()["rates"][to_currency]
|
value = response.json()["rates"][to_currency]
|
||||||
cache.setex(key, value, 6 * 60 * 60)
|
cache.setex(key, value, 6 * 60 * 60)
|
||||||
|
|
||||||
return flt(value)
|
return flt(value)
|
||||||
except:
|
except:
|
||||||
frappe.msgprint(_("Unable to find exchange rate for {0} to {1} for key date {2}").format(from_currency, to_currency, transaction_date))
|
frappe.msgprint(_("Unable to find exchange rate for {0} to {1} for key date {2}. Please create a Currency Exchange record manually").format(from_currency, to_currency, transaction_date))
|
||||||
return 0.0
|
return 0.0
|
||||||
@@ -44,8 +44,6 @@ frappe.ui.form.on("Item", {
|
|||||||
}, __("View"));
|
}, __("View"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sensitive fields(has_serial_no, is_stock_item, valuation_method)
|
|
||||||
// read only if any stock ledger entry exists
|
|
||||||
if(!frm.doc.is_fixed_asset) {
|
if(!frm.doc.is_fixed_asset) {
|
||||||
erpnext.item.make_dashboard(frm);
|
erpnext.item.make_dashboard(frm);
|
||||||
}
|
}
|
||||||
@@ -77,6 +75,8 @@ frappe.ui.form.on("Item", {
|
|||||||
|
|
||||||
erpnext.item.edit_prices_button(frm);
|
erpnext.item.edit_prices_button(frm);
|
||||||
|
|
||||||
|
// make sensitive fields(has_serial_no, is_stock_item, valuation_method, has_batch_no)
|
||||||
|
// read only if any stock ledger entry exists
|
||||||
if (!frm.doc.__islocal && frm.doc.is_stock_item) {
|
if (!frm.doc.__islocal && frm.doc.is_stock_item) {
|
||||||
frm.toggle_enable(['has_serial_no', 'is_stock_item', 'valuation_method', 'has_batch_no'],
|
frm.toggle_enable(['has_serial_no', 'is_stock_item', 'valuation_method', 'has_batch_no'],
|
||||||
(frm.doc.__onload && frm.doc.__onload.sle_exists=="exists") ? false : true);
|
(frm.doc.__onload && frm.doc.__onload.sle_exists=="exists") ? false : true);
|
||||||
|
|||||||
@@ -102,9 +102,17 @@ erpnext.stock.LandedCostVoucher = erpnext.stock.StockController.extend({
|
|||||||
total_item_cost += flt(d[based_on])
|
total_item_cost += flt(d[based_on])
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var total_charges = 0.0;
|
||||||
$.each(this.frm.doc.items || [], function(i, item) {
|
$.each(this.frm.doc.items || [], function(i, item) {
|
||||||
item.applicable_charges = flt(item[based_on]) * flt(me.frm.doc.total_taxes_and_charges) / flt(total_item_cost)
|
item.applicable_charges = flt(item[based_on]) * flt(me.frm.doc.total_taxes_and_charges) / flt(total_item_cost)
|
||||||
|
item.applicable_charges = flt(item.applicable_charges, precision("applicable_charges", item))
|
||||||
|
total_charges += item.applicable_charges
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (total_charges != this.frm.doc.total_taxes_and_charges){
|
||||||
|
var diff = this.frm.doc.total_taxes_and_charges - flt(total_charges)
|
||||||
|
this.frm.doc.items.slice(-1)[0].applicable_charges += diff
|
||||||
|
}
|
||||||
refresh_field("items");
|
refresh_field("items");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
|
from frappe.model.meta import get_field_precision
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
|
|
||||||
@@ -71,7 +72,17 @@ class LandedCostVoucher(Document):
|
|||||||
if not total:
|
if not total:
|
||||||
frappe.throw(_("Total {0} for all items is zero, may be you should change 'Distribute Charges Based On'").format(based_on))
|
frappe.throw(_("Total {0} for all items is zero, may be you should change 'Distribute Charges Based On'").format(based_on))
|
||||||
|
|
||||||
if self.total_taxes_and_charges != sum([flt(d.applicable_charges) for d in self.get("items")]):
|
total_applicable_charges = sum([flt(d.applicable_charges) for d in self.get("items")])
|
||||||
|
|
||||||
|
precision = get_field_precision(frappe.get_meta("Landed Cost Item").get_field("applicable_charges"),
|
||||||
|
currency=frappe.db.get_value("Company", self.company, "default_currency", cache=True))
|
||||||
|
|
||||||
|
diff = flt(self.total_taxes_and_charges) - flt(total_applicable_charges)
|
||||||
|
diff = flt(diff, precision)
|
||||||
|
|
||||||
|
if abs(diff) < (2.0 / (10**precision)):
|
||||||
|
self.items[-1].applicable_charges += diff
|
||||||
|
else:
|
||||||
frappe.throw(_("Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges"))
|
frappe.throw(_("Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges"))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import unittest
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt \
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt \
|
||||||
import set_perpetual_inventory, get_gl_entries, test_records as pr_test_records
|
import set_perpetual_inventory, get_gl_entries, test_records as pr_test_records, make_purchase_receipt
|
||||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||||
|
|
||||||
class TestLandedCostVoucher(unittest.TestCase):
|
class TestLandedCostVoucher(unittest.TestCase):
|
||||||
@@ -133,7 +133,29 @@ class TestLandedCostVoucher(unittest.TestCase):
|
|||||||
|
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
def submit_landed_cost_voucher(receipt_document_type, receipt_document):
|
def test_landed_cost_voucher_for_odd_numbers (self):
|
||||||
|
set_perpetual_inventory(1)
|
||||||
|
|
||||||
|
pr = make_purchase_receipt(do_not_save=True)
|
||||||
|
pr.items[0].cost_center = "_Test Company - _TC"
|
||||||
|
for x in range(2):
|
||||||
|
pr.append("items", {
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
|
"cost_center": "_Test Company - _TC",
|
||||||
|
"qty": 5,
|
||||||
|
"rate": 50
|
||||||
|
})
|
||||||
|
pr.submit()
|
||||||
|
|
||||||
|
lcv = submit_landed_cost_voucher("Purchase Receipt", pr.name, 123.22)
|
||||||
|
|
||||||
|
self.assertEquals(lcv.items[0].applicable_charges, 41.07)
|
||||||
|
self.assertEquals(lcv.items[2].applicable_charges, 41.08)
|
||||||
|
|
||||||
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
|
def submit_landed_cost_voucher(receipt_document_type, receipt_document, charges=50):
|
||||||
ref_doc = frappe.get_doc(receipt_document_type, receipt_document)
|
ref_doc = frappe.get_doc(receipt_document_type, receipt_document)
|
||||||
|
|
||||||
lcv = frappe.new_doc("Landed Cost Voucher")
|
lcv = frappe.new_doc("Landed Cost Voucher")
|
||||||
@@ -151,7 +173,7 @@ def submit_landed_cost_voucher(receipt_document_type, receipt_document):
|
|||||||
lcv.set("taxes", [{
|
lcv.set("taxes", [{
|
||||||
"description": "Insurance Charges",
|
"description": "Insurance Charges",
|
||||||
"account": "_Test Account Insurance Charges - _TC",
|
"account": "_Test Account Insurance Charges - _TC",
|
||||||
"amount": 50
|
"amount": charges
|
||||||
}])
|
}])
|
||||||
|
|
||||||
lcv.insert()
|
lcv.insert()
|
||||||
@@ -160,10 +182,14 @@ def submit_landed_cost_voucher(receipt_document_type, receipt_document):
|
|||||||
|
|
||||||
lcv.submit()
|
lcv.submit()
|
||||||
|
|
||||||
|
return lcv
|
||||||
|
|
||||||
def distribute_landed_cost_on_items(lcv):
|
def distribute_landed_cost_on_items(lcv):
|
||||||
based_on = lcv.distribute_charges_based_on.lower()
|
based_on = lcv.distribute_charges_based_on.lower()
|
||||||
total = sum([flt(d.get(based_on)) for d in lcv.get("items")])
|
total = sum([flt(d.get(based_on)) for d in lcv.get("items")])
|
||||||
|
|
||||||
for item in lcv.get("items"):
|
for item in lcv.get("items"):
|
||||||
item.applicable_charges = flt(item.get(based_on)) * flt(lcv.total_taxes_and_charges) / flt(total)
|
item.applicable_charges = flt(item.get(based_on)) * flt(lcv.total_taxes_and_charges) / flt(total)
|
||||||
|
item.applicable_charges = flt(item.applicable_charges, lcv.precision("applicable_charges", item))
|
||||||
|
|
||||||
test_records = frappe.get_test_records('Landed Cost Voucher')
|
test_records = frappe.get_test_records('Landed Cost Voucher')
|
||||||
|
|||||||
@@ -74,7 +74,8 @@ class PurchaseReceipt(BuyingController):
|
|||||||
"Purchase Order Item": {
|
"Purchase Order Item": {
|
||||||
"ref_dn_field": "purchase_order_item",
|
"ref_dn_field": "purchase_order_item",
|
||||||
"compare_fields": [["project", "="], ["uom", "="], ["item_code", "="]],
|
"compare_fields": [["project", "="], ["uom", "="], ["item_code", "="]],
|
||||||
"is_child_table": True
|
"is_child_table": True,
|
||||||
|
"allow_duplicate_prev_row_id": True
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -324,3 +324,12 @@ def update_serial_nos_after_submit(controller, parentfield):
|
|||||||
update_rejected_serial_nos = False
|
update_rejected_serial_nos = False
|
||||||
if accepted_serial_nos_updated:
|
if accepted_serial_nos_updated:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
def update_maintenance_status():
|
||||||
|
serial_nos = frappe.db.sql('''select name from `tabSerial No` where (amc_expiry_date<%s or
|
||||||
|
warranty_expiry_date<%s) and maintenance_status not in ('Out of Warranty', 'Out of AMC')''',
|
||||||
|
(nowdate(), nowdate()))
|
||||||
|
for serial_no in serial_nos:
|
||||||
|
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)
|
||||||
|
|||||||
@@ -26,3 +26,19 @@ class StockSettings(Document):
|
|||||||
# show/hide barcode field
|
# show/hide barcode field
|
||||||
frappe.make_property_setter({'fieldname': 'barcode', 'property': 'hidden',
|
frappe.make_property_setter({'fieldname': 'barcode', 'property': 'hidden',
|
||||||
'value': 0 if self.show_barcode_field else 1})
|
'value': 0 if self.show_barcode_field else 1})
|
||||||
|
|
||||||
|
self.cant_change_valuation_method()
|
||||||
|
|
||||||
|
def cant_change_valuation_method(self):
|
||||||
|
db_valuation_method = frappe.db.get_single_value("Stock Settings", "valuation_method")
|
||||||
|
|
||||||
|
if db_valuation_method and db_valuation_method != self.valuation_method:
|
||||||
|
# check if there are any stock ledger entries against items
|
||||||
|
# which does not have it's own valuation method
|
||||||
|
sle = frappe.db.sql("""select name from `tabStock Ledger Entry` sle
|
||||||
|
where exists(select name from tabItem
|
||||||
|
where name=sle.item_code and (valuation_method is null or valuation_method=''))
|
||||||
|
""")
|
||||||
|
|
||||||
|
if sle:
|
||||||
|
frappe.throw(_("Can't change valuation method, as there are transactions against some items which does not have it's own valuation method"))
|
||||||
Reference in New Issue
Block a user