Merge branch 'develop' into exchange_rate_modifications

This commit is contained in:
Chude Osiegbu 2016-09-18 21:47:55 +01:00
commit 3c6a937a7c
162 changed files with 6244 additions and 1902 deletions

View File

@ -57,7 +57,7 @@ class GLEntry(Document):
def pl_must_have_cost_center(self):
if frappe.db.get_value("Account", self.account, "report_type") == "Profit and Loss":
if not self.cost_center and self.voucher_type != 'Period Closing Voucher':
frappe.throw(_("Cost Center is required for 'Profit and Loss' account {0}")
frappe.throw(_("Cost Center is required for 'Profit and Loss' account {0}. Please set up a default Cost Center for the Company.")
.format(self.account))
else:
if self.cost_center:

View File

@ -259,7 +259,6 @@ cur_frm.cscript.voucher_type = function(doc, cdt, cdn) {
if(!doc.company) return;
var update_jv_details = function(doc, r) {
var jvdetail = frappe.model.add_child(doc, "Journal Entry Account", "accounts");
$.each(r, function(i, d) {
var row = frappe.model.add_child(doc, "Journal Entry Account", "accounts");
row.account = d.account;
@ -267,8 +266,8 @@ cur_frm.cscript.voucher_type = function(doc, cdt, cdn) {
});
refresh_field("accounts");
}
if(!(doc.accounts || []).length) {
if((!(doc.accounts || []).length) || ((doc.accounts || []).length==1 && !doc.accounts[0].account)) {
if(in_list(["Bank Entry", "Cash Entry"], doc.voucher_type)) {
return frappe.call({
type: "GET",

View File

@ -219,6 +219,12 @@ frappe.ui.form.on('Payment Entry', {
party: function(frm) {
if(frm.doc.payment_type && frm.doc.party_type && frm.doc.party) {
if(!frm.doc.posting_date) {
frappe.msgprint(__("Please select Posting Date before selecting Party"))
frm.set_value("party", "");
return ;
}
frm.set_party_account_based_on_party = true;
return frappe.call({

View File

@ -75,7 +75,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_list_view": 1,
"label": "Payment Type",
"length": 0,
"no_copy": 0,
@ -1426,7 +1426,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-09-02 11:34:14.817383",
"modified": "2016-09-05 11:06:18.183458",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",

View File

@ -1,6 +0,0 @@
frappe.listview_settings['Payment Entry'] = {
add_fields: ["payment_type"],
get_indicator: function(doc) {
return [__(doc.payment_type), (doc.docstatus==0 ? 'red' : 'blue'), 'status=' + doc.payment_type]
}
}

View File

@ -178,7 +178,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_list_view": 1,
"label": "Allocated",
"length": 0,
"no_copy": 0,

View File

@ -2,7 +2,7 @@
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "PR.######",
"autoname": "naming_series:",
"beta": 0,
"creation": "2015-12-15 22:23:24.745065",
"custom": 0,
@ -15,6 +15,34 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Series",
"length": 0,
"no_copy": 1,
"options": "PR",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 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": "recipient_and_message",
"fieldtype": "Section Break",
"hidden": 0,
@ -40,6 +68,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "print_format",
"fieldtype": "Select",
@ -67,6 +96,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "email_to",
"fieldtype": "Data",
"hidden": 0,
@ -92,6 +122,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "subject",
"fieldtype": "Data",
"hidden": 0,
@ -117,6 +148,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_9",
"fieldtype": "Column Break",
"hidden": 0,
@ -141,6 +173,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "payment_gateway_account",
"fieldtype": "Link",
"hidden": 0,
@ -167,6 +200,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
@ -193,6 +227,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Amount in customer's currency",
"fieldname": "grand_total",
"fieldtype": "Currency",
@ -220,6 +255,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Draft",
"fieldname": "status",
"fieldtype": "Select",
@ -247,6 +283,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.reference_doctype==\"Sales Order\"",
"fieldname": "make_sales_invoice",
"fieldtype": "Check",
@ -273,6 +310,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_10",
"fieldtype": "Section Break",
"hidden": 0,
@ -297,6 +335,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "message",
"fieldtype": "Small Text",
"hidden": 0,
@ -322,6 +361,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "message_examples",
"fieldtype": "HTML",
"hidden": 0,
@ -348,6 +388,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "mute_email",
"fieldtype": "Check",
"hidden": 1,
@ -373,6 +414,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "payment_url",
"fieldtype": "Data",
"hidden": 1,
@ -399,6 +441,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "doc.payment_gateway_account",
"columns": 0,
"fieldname": "section_break_7",
"fieldtype": "Section Break",
"hidden": 0,
@ -424,6 +467,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "payment_gateway",
"fieldtype": "Read Only",
"hidden": 0,
@ -450,6 +494,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "payment_account",
"fieldtype": "Read Only",
"hidden": 0,
@ -476,6 +521,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "reference_details",
"fieldtype": "Section Break",
"hidden": 0,
@ -501,6 +547,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "reference_doctype",
"fieldtype": "Link",
"hidden": 0,
@ -527,6 +574,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "reference_name",
"fieldtype": "Dynamic Link",
"hidden": 0,
@ -553,6 +601,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@ -585,7 +634,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-07-25 01:34:44.372161",
"modified": "2016-09-02 04:07:15.279949",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",

View File

@ -6,10 +6,11 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import flt, get_url, nowdate
from frappe.utils import flt, nowdate, get_url
from erpnext.accounts.party import get_party_account
from erpnext.accounts.utils import get_account_currency
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, get_company_defaults
from frappe.integration_broker.doctype.integration_service.integration_service import get_integration_controller
class PaymentRequest(Document):
def validate(self):
@ -25,7 +26,7 @@ class PaymentRequest(Document):
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
if self.payment_account and ref_doc.currency != frappe.db.get_value("Account", self.payment_account, "account_currency"):
frappe.throw(_("Transaction currency must be same as Payment Gateway currency"))
def on_submit(self):
send_mail = True
self.make_communication_entry()
@ -35,17 +36,13 @@ class PaymentRequest(Document):
send_mail = False
if send_mail and not self.flags.mute_email:
self.send_payment_request()
self.set_payment_request_url()
self.send_email()
def on_cancel(self):
self.check_if_payment_entry_exists()
self.set_as_cancelled()
def get_payment_url(self):
""" This is blanck method to trigger hooks call from individual payment gateway app
which will return respective payment gateway"""
pass
def make_invoice(self):
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
@ -54,20 +51,39 @@ class PaymentRequest(Document):
si = si.insert(ignore_permissions=True)
si.submit()
def send_payment_request(self):
def set_payment_request_url(self):
if self.payment_account:
self.payment_url = get_url("/api/method/erpnext.accounts.doctype.payment_request.payment_request.generate_payment_request?name={0}".format(self.name))
self.payment_url = self.get_payment_url()
if self.payment_url:
self.db_set('payment_url', self.payment_url)
if self.payment_url or not self.payment_gateway_account:
self.db_set('status', 'Initiated')
def get_payment_url(self):
data = frappe.db.get_value(self.reference_doctype, self.reference_name,
["company", "customer_name"], as_dict=1)
controller = get_integration_controller(self.payment_gateway, setup=False)
controller.validate_transaction_currency(self.currency)
return controller.get_payment_url(**{
"amount": self.grand_total,
"title": data.company,
"description": self.subject,
"reference_doctype": "Payment Request",
"reference_docname": self.name,
"payer_email": self.email_to or frappe.session.user,
"payer_name": data.customer_name,
"order_id": self.name,
"currency": self.currency
})
def set_as_paid(self):
if frappe.session.user == "Guest":
frappe.set_user("Administrator")
payment_entry = self.create_payment_entry()
self.make_invoice()
@ -141,6 +157,13 @@ class PaymentRequest(Document):
def set_as_cancelled(self):
self.db_set("status", "Cancelled")
def check_if_payment_entry_exists(self):
if self.status == "Paid":
payment_entry = frappe.db.sql_list("""select parent from `tabPayment Entry Reference`
where reference_name=%s""", self.reference_name)
if payment_entry:
frappe.throw(_("Payment Entry already exists"), title=_('Error'))
def make_communication_entry(self):
"""Make communication entry"""
@ -156,7 +179,33 @@ class PaymentRequest(Document):
def get_payment_success_url(self):
return self.payment_success_url
def on_payment_authorized(self, status=None):
if not status:
return
shopping_cart_settings = frappe.get_doc("Shopping Cart Settings")
if status in ["Authorized", "Completed"]:
redirect_to = None
self.run_method("set_as_paid")
# if shopping cart enabled and in session
if (shopping_cart_settings.enabled and hasattr(frappe.local, "session")
and frappe.local.session.user != "Guest"):
success_url = shopping_cart_settings.payment_success_url
if success_url:
redirect_to = ({
"Orders": "orders",
"Invoices": "invoices",
"My Account": "me"
}).get(success_url, "me")
else:
redirect_to = get_url("/orders/{0}".format(self.reference_name))
return redirect_to
@frappe.whitelist(allow_guest=True)
def make_payment_request(**args):
"""Make payment request"""
@ -201,8 +250,9 @@ def make_payment_request(**args):
pr.submit()
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
generate_payment_request(pr.name)
frappe.db.commit()
frappe.local.response["type"] = "redirect"
frappe.local.response["location"] = pr.get_payment_url()
if not args.cart:
return pr
@ -255,10 +305,6 @@ def get_print_format_list(ref_doctype):
"print_format": print_format_list
}
@frappe.whitelist(allow_guest=True)
def generate_payment_request(name):
frappe.get_doc("Payment Request", name).run_method("get_payment_url")
@frappe.whitelist(allow_guest=True)
def resend_payment_email(docname):
return frappe.get_doc("Payment Request", docname).send_email()
@ -278,6 +324,7 @@ def make_status_as_paid(doc, method):
doc = frappe.get_doc("Payment Request", payment_request_name)
if doc.status != "Paid":
doc.db_set('status', 'Paid')
frappe.db.commit()
def get_dummy_message(use_dummy_message=True):
return """

View File

@ -302,6 +302,9 @@ class PurchaseInvoice(BuyingController):
asset.save()
def make_gl_entries(self, repost_future_gle=True):
if not self.grand_total:
return
self.auto_accounting_for_stock = \
cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))

View File

@ -19,9 +19,6 @@ def get_pos_data():
if pos_profile.get('name'):
pos_profile = frappe.get_doc('POS Profile', pos_profile.get('name'))
else:
frappe.msgprint('<a href="#List/POS Profile">'
+ _("Welcome to POS: Create your POS Profile") + '</a>');
company_data = get_company_data(doc.company)
update_pos_profile_data(doc, pos_profile, company_data)

View File

@ -462,26 +462,41 @@ cur_frm.set_query("asset", "items", function(doc, cdt, cdn) {
frappe.ui.form.on('Sales Invoice', {
setup: function(frm){
frm.fields_dict["timesheets"].grid.get_field("time_sheet").get_query = function(doc, cdt, cdn){
return {
filters: [
["Timesheet", "status", "in", ["Submitted", "Payslip"]]
]
return{
query: "erpnext.projects.doctype.timesheet.timesheet.get_timesheet",
filters: {'project': doc.project}
}
}
}
})
},
frappe.ui.form.on('Sales Invoice Timesheet', {
time_sheet: function(frm){
project: function(frm){
frm.call({
method: "calculate_billing_amount_from_timesheet",
method: "add_timesheet_data",
doc: frm.doc,
callback: function(r, rt) {
refresh_field('total_billing_amount')
refresh_field(['timesheets'])
}
})
}
})
cur_frm.add_fetch("time_sheet", "total_billing_hours", "billing_hours");
cur_frm.add_fetch("time_sheet", "total_billing_amount", "billing_amount");
frappe.ui.form.on('Sales Invoice Timesheet', {
time_sheet: function(frm, cdt, cdn){
var d = locals[cdt][cdn];
frappe.call({
method: "erpnext.projects.doctype.timesheet.timesheet.get_timesheet_data",
args: {
'name': d.time_sheet,
'project': frm.doc.project || null
},
callback: function(r, rt) {
if(r.message){
data = r.message;
frappe.model.set_value(cdt, cdn, "billing_hours", data.billing_hours);
frappe.model.set_value(cdt, cdn, "billing_amount", data.billing_amount);
frappe.model.set_value(cdt, cdn, "timesheet_detail", data.timesheet_detail);
}
}
})
}
})

View File

@ -2931,7 +2931,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.source == 'Campaign'",
"depends_on": "",
"fieldname": "campaign",
"fieldtype": "Link",
"hidden": 0,
@ -2961,7 +2961,7 @@
"collapsible": 0,
"columns": 0,
"fieldname": "source",
"fieldtype": "Select",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -2972,7 +2972,7 @@
"no_copy": 0,
"oldfieldname": "source",
"oldfieldtype": "Select",
"options": "\nExisting Customer\nReference\nAdvertisement\nCold Calling\nExhibition\nSupplier Reference\nMass Mailing\nCustomer's Vendor\nCampaign",
"options": "Lead Source",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@ -3867,7 +3867,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2016-08-31 15:47:32.064861",
"modified": "2016-09-16 06:09:01.246951",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@ -14,6 +14,7 @@ from erpnext.accounts.doctype.sales_invoice.pos import update_multi_mode_option
from erpnext.controllers.selling_controller import SellingController
from erpnext.accounts.utils import get_account_currency
from erpnext.stock.doctype.delivery_note.delivery_note import update_billed_amount_based_on_so
from erpnext.projects.doctype.timesheet.timesheet import get_projectwise_timesheet_data
from erpnext.accounts.doctype.asset.depreciation \
import get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal
@ -84,7 +85,7 @@ class SalesInvoice(SellingController):
self.validate_multiple_billing("Delivery Note", "dn_detail", "amount", "items")
self.update_packing_list()
self.set_billing_hours_and_amount()
self.calculate_billing_amount_from_timesheet()
self.update_timesheet_billing_for_project()
def before_save(self):
set_account_for_mode_of_payment(self)
@ -221,11 +222,21 @@ class SalesInvoice(SellingController):
for d in self.timesheets:
if d.time_sheet:
timesheet = frappe.get_doc("Timesheet", d.time_sheet)
timesheet.sales_invoice = sales_invoice
self.update_time_sheet_detail(timesheet, d, sales_invoice)
timesheet.calculate_total_amounts()
timesheet.calculate_percentage_billed()
timesheet.flags.ignore_validate_update_after_submit = True
timesheet.set_status()
timesheet.save()
def update_time_sheet_detail(self, timesheet, args, sales_invoice):
for data in timesheet.time_logs:
if (self.project and args.timesheet_detail == data.name) or \
(not self.project and not data.sales_invoice) or \
(not sales_invoice and data.sales_invoice == self.name):
data.sales_invoice = sales_invoice
if self.project: return
def on_update(self):
self.set_paid_amount()
@ -357,12 +368,12 @@ class SalesInvoice(SellingController):
def so_dn_required(self):
"""check in manage account if sales order / delivery note required or not."""
dic = {'Sales Order':'so_required','Delivery Note':'dn_required'}
dic = {'Sales Order':['so_required', 'is_pos'],'Delivery Note':['dn_required', 'update_stock']}
for i in dic:
if frappe.db.get_value('Selling Settings', None, dic[i]) == 'Yes':
if frappe.db.get_value('Selling Settings', None, dic[i][0]) == 'Yes':
for d in self.get('items'):
if frappe.db.get_value('Item', d.item_code, 'is_stock_item') == 1 \
and not d.get(i.lower().replace(' ','_')):
and not d.get(i.lower().replace(' ','_')) and not self.get(dic[i][1]):
msgprint(_("{0} is mandatory for Item {1}").format(i,d.item_code), raise_exception=1)
@ -450,13 +461,32 @@ class SalesInvoice(SellingController):
def set_billing_hours_and_amount(self):
for timesheet in self.timesheets:
ts_doc = frappe.get_doc('Timesheet', timesheet.time_sheet)
if not timesheet.billing_hours and ts_doc.total_billing_hours:
timesheet.billing_hours = ts_doc.total_billing_hours
if not timesheet.billing_hours and ts_doc.total_billable_hours:
timesheet.billing_hours = ts_doc.total_billable_hours
if not timesheet.billing_amount and ts_doc.total_billing_amount:
timesheet.billing_amount = ts_doc.total_billing_amount
if not timesheet.billing_amount and ts_doc.total_billable_amount:
timesheet.billing_amount = ts_doc.total_billable_amount
def calculate_billing_amount_from_timesheet(self):
def update_timesheet_billing_for_project(self):
if not self.timesheets and self.project:
self.add_timesheet_data()
else:
self.calculate_billing_amount_for_timesheet()
def add_timesheet_data(self):
self.set('timesheets', [])
if self.project:
for data in get_projectwise_timesheet_data(self.project):
self.append('timesheets', {
'time_sheet': data.parent,
'billing_hours': data.billing_hours,
'billing_amount': data.billing_amt,
'timesheet_detail': data.name
})
self.calculate_billing_amount_for_timesheet()
def calculate_billing_amount_for_timesheet(self):
total_billing_amount = 0.0
for data in self.timesheets:
if data.billing_amount:
@ -500,6 +530,8 @@ class SalesInvoice(SellingController):
throw(_("Delivery Note {0} is not submitted").format(d.delivery_note))
def make_gl_entries(self, repost_future_gle=True):
if not self.grand_total:
return
gl_entries = self.get_gl_entries()
if gl_entries:

View File

@ -14,6 +14,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "time_sheet",
"fieldtype": "Link",
"hidden": 0,
@ -40,6 +41,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "billing_hours",
"fieldtype": "Float",
"hidden": 0,
@ -65,6 +67,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "billing_amount",
"fieldtype": "Currency",
"hidden": 0,
@ -85,6 +88,32 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "timesheet_detail",
"fieldtype": "Data",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Timesheet Detail",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"hide_heading": 0,
@ -97,7 +126,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-08-22 21:32:55.504103",
"modified": "2016-09-09 14:01:04.095775",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Timesheet",

View File

@ -128,10 +128,11 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.list_body = this.list_dialog.body;
if(this.si_docs.length > 0){
$(this.list_body).append('<div class="row list-row list-row-head pos-invoice-list">\
<div class="col-xs-2">Sr</div>\
<div class="col-xs-4">Customer</div>\
<div class="col-xs-1">Sr</div>\
<div class="col-xs-3">Customer</div>\
<div class="col-xs-2 text-left">Status</div>\
<div class="col-xs-4 text-right">Grand Total</div>\
<div class="col-xs-3 text-right">Paid Amount</div>\
<div class="col-xs-3 text-right">Grand Total</div>\
</div>')
$.each(this.si_docs, function(index, data){
@ -140,6 +141,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
sr: index + 1,
name: key,
customer: data[key].customer,
paid_amount: format_currency(data[key].paid_amount, me.frm.doc.currency),
grand_total: format_currency(data[key].grand_total, me.frm.doc.currency),
data: me.get_doctype_status(data[key])
})).appendTo($(me.list_body));
@ -163,12 +165,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
},
get_doctype_status: function(doc){
if(doc.outstanding_amount == 0){
return {status: "Paid", indicator: "green"}
}else if(doc.docstatus == 0){
if(doc.docstatus == 0) {
return {status: "Draft", indicator: "red"}
}else if(doc.paid_amount >= 0){
return {status: "Unpaid", indicator: "orange"}
}else if(doc.outstanding_amount == 0) {
return {status: "Paid", indicator: "green"}
}else {
return {status: "Submitted", indicator: "blue"}
}
},
@ -313,6 +315,15 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
});
this.party_field.make_input();
this.set_focus()
},
set_focus: function(){
if(this.default_customer){
this.search.$input.focus();
}else{
this.party_field.$input.focus();
}
},
make_customer: function() {
@ -614,6 +625,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.child.batch_no = this.item_batch_no[this.child.item_code];
this.child.serial_no = (this.item_serial_no[this.child.item_code]
? this.item_serial_no[this.child.item_code][0] : '');
this.child.item_tax_rate = this.items[0].taxes;
},
update_paid_amount_status: function(update_paid_amount){
@ -727,6 +739,26 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}, "octicon octicon-plus").addClass("btn-primary");
},
print_dialog: function(){
var me = this;
msgprint = frappe.msgprint(format('<a class="btn btn-primary print_doc" \
style="margin-right: 5px;">{0}</a>\
<a class="btn btn-default new_doc">{1}</a>', [
__('Print'), __('New')
]));
$('.print_doc').click(function(){
html = frappe.render(me.print_template, me.frm.doc)
me.print_document(html)
})
$('.new_doc').click(function(){
msgprint.hide()
me.create_new();
})
},
print_document: function(html){
var w = window.open();
w.document.write(html);
@ -739,10 +771,10 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
submit_invoice: function(){
var me = this;
frappe.confirm(__("Do you really want to submit the invoice?"), function () {
me.change_status();
frappe.msgprint(__("Sales invoice submitted sucessfully."))
})
this.change_status();
if(this.frm.doc.docstatus == 1){
this.print_dialog()
}
},
change_status: function(){
@ -775,6 +807,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.update_invoice()
}else{
this.name = $.now();
this.frm.doc.offline_pos_name = this.name;
this.frm.doc.posting_date = frappe.datetime.get_today();
this.frm.doc.posting_time = frappe.datetime.now_time();
invoice_data[this.name] = this.frm.doc

View File

@ -2,7 +2,7 @@
<div class="page-break">
{%- if not doc.get("print_heading") and not doc.get("select_print_heading")
and doc.set("select_print_heading", _("Payment Receipt Note")) -%}{%- endif -%}
{{ add_header(0, 1, doc, letter_head, no_letterhead) }}
{{ add_header(0, 1, doc, letter_head, no_letterhead, print_settings) }}
{%- for label, value in (
(_("Received On"), frappe.utils.formatdate(doc.voucher_date)),

View File

@ -6,9 +6,9 @@
"docstatus": 0,
"doctype": "Print Format",
"font": "Default",
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ company }}<br>\n\t{{ __(\"Invoice\") }}<br>\n</p>\n<p>\n\t<b>{{ __(\"Date\") }}:</b> {{ dateutil.global_date_format(posting_date) }}<br>\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ __(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{% for item in items %}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_name }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ format_number(item.qty, precision(\"difference\")) }}<br>@ {{ format_currency(item.rate, currency) }}</td>\n\t\t\t<td class=\"text-right\">{{ format_currency(item.amount, currency) }}</td>\n\t\t</tr>\n\t\t{% endfor %}\n\t</tbody>\n</table>\n\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ __(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% for row in taxes %}\n\t\t{% if not row.included_in_print_rate %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(row.tax_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t{% endfor %}\n\t\t{% if discount_amount %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ __(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(discount_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(grand_total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n\n\n<hr>\n<p class=\"text-center\">{{ __(\"Thank you, please visit again.\") }}</p>",
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ company }}<br>\n\t{{ __(\"POS No : \") }}{{offline_pos_name}}<br>\n</p>\n<p>\n\t<b>{{ __(\"Date\") }}:</b> {{ dateutil.global_date_format(posting_date) }}<br>\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ __(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{% for item in items %}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_name }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ format_number(item.qty, precision(\"difference\")) }}<br>@ {{ format_currency(item.rate, currency) }}</td>\n\t\t\t<td class=\"text-right\">{{ format_currency(item.amount, currency) }}</td>\n\t\t</tr>\n\t\t{% endfor %}\n\t</tbody>\n</table>\n\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ __(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% for row in taxes %}\n\t\t{% if not row.included_in_print_rate %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(row.tax_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t{% endfor %}\n\t\t{% if discount_amount %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ __(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(discount_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(grand_total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n\n\n<hr>\n<p class=\"text-center\">{{ __(\"Thank you, please visit again.\") }}</p>",
"idx": 0,
"modified": "2016-08-11 07:23:04.530676",
"modified": "2016-09-05 08:28:42.308782",
"modified_by": "Administrator",
"name": "Point of Sale",
"owner": "Administrator",

View File

@ -70,7 +70,7 @@ def check_opening_balance(asset, liability, equity):
if liability:
opening_balance -= flt(liability[0].get("opening_balance", 0))
if equity:
opening_balance -= flt(asset[0].get("opening_balance", 0))
opening_balance -= flt(equity[0].get("opening_balance", 0))
if opening_balance:
return _("Previous Financial Year is not closed")
@ -101,4 +101,4 @@ def get_chart_data(columns, asset, liability, equity):
'x': 'x',
'columns': columns
}
}
}

View File

@ -7,12 +7,12 @@
"doctype": "Report",
"idx": 1,
"is_standard": "Yes",
"modified": "2016-05-17 08:40:18.711626",
"modified": "2016-08-18 14:29:50.680329",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Delivered Items To Be Billed",
"owner": "Administrator",
"query": "select\n `tabDelivery Note`.`name` as \"Delivery Note:Link/Delivery Note:120\",\n\t`tabDelivery Note`.`customer` as \"Customer:Link/Customer:120\",\n\t`tabDelivery Note`.`posting_date` as \"Date:Date\",\n\t`tabDelivery Note`.`project` as \"Project\",\n\t`tabDelivery Note Item`.`item_code` as \"Item:Link/Item:120\",\n\t(`tabDelivery Note Item`.`base_amount` - `tabDelivery Note Item`.`billed_amt`*ifnull(`tabDelivery Note`.conversion_rate, 1)) as \"Pending Amount:Currency:110\",\n\t`tabDelivery Note Item`.`item_name` as \"Item Name::150\",\n\t`tabDelivery Note Item`.`description` as \"Description::200\",\n\t`tabDelivery Note`.`company` as \"Company:Link/Company:\"\nfrom `tabDelivery Note`, `tabDelivery Note Item`\nwhere \n `tabDelivery Note`.name = `tabDelivery Note Item`.parent \n and `tabDelivery Note`.docstatus = 1 \n and `tabDelivery Note`.`status` not in (\"Stopped\", \"Closed\") \n and `tabDelivery Note Item`.amount > 0\n and `tabDelivery Note Item`.billed_amt < `tabDelivery Note Item`.amount\norder by `tabDelivery Note`.`name` desc",
"query": "select\n `tabDelivery Note`.`name` as \"Delivery Note:Link/Delivery Note:120\",\n\t`tabDelivery Note`.`customer` as \"Customer:Link/Customer:120\",\n\t`tabDelivery Note`.`customer_name` as \"Customer Name::150\",\n\t`tabDelivery Note`.`posting_date` as \"Date:Date\",\n\t`tabDelivery Note`.`project` as \"Project\",\n\t`tabDelivery Note Item`.`item_code` as \"Item:Link/Item:120\",\n\t(`tabDelivery Note Item`.`base_amount` - `tabDelivery Note Item`.`billed_amt`*ifnull(`tabDelivery Note`.conversion_rate, 1)) as \"Pending Amount:Currency:110\",\n\t`tabDelivery Note Item`.`item_name` as \"Item Name::150\",\n\t`tabDelivery Note Item`.`description` as \"Description::200\",\n\t`tabDelivery Note`.`company` as \"Company:Link/Company:\"\nfrom `tabDelivery Note`, `tabDelivery Note Item`\nwhere \n `tabDelivery Note`.name = `tabDelivery Note Item`.parent \n and `tabDelivery Note`.docstatus = 1 \n and `tabDelivery Note`.`status` not in (\"Stopped\", \"Closed\") \n and `tabDelivery Note Item`.amount > 0\n and `tabDelivery Note Item`.billed_amt < `tabDelivery Note Item`.amount\norder by `tabDelivery Note`.`name` desc",
"ref_doctype": "Sales Invoice",
"report_name": "Delivered Items To Be Billed",
"report_type": "Query Report"

View File

@ -12,20 +12,12 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity):
"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
Periodicity can be (Yearly, Quarterly, Monthly)"""
from_fy_start_end_date = frappe.db.get_value("Fiscal Year", from_fiscal_year, ["year_start_date", "year_end_date"])
to_fy_start_end_date = frappe.db.get_value("Fiscal Year", to_fiscal_year, ["year_start_date", "year_end_date"])
if not from_fy_start_end_date:
frappe.throw(_("Start Year {0} not found.").format(from_fiscal_year))
if not to_fy_start_end_date:
frappe.throw(_("End Year {0} not found.").format(to_fiscal_year))
fiscal_year = get_fiscal_year_data(from_fiscal_year, to_fiscal_year)
validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year)
# start with first day, so as to avoid year to_dates like 2-April if ever they occur]
year_start_date = getdate(from_fy_start_end_date[0])
year_end_date = getdate(to_fy_start_end_date[1])
validate_fiscal_year(year_start_date, year_end_date)
year_start_date = getdate(fiscal_year.year_start_date)
year_end_date = getdate(fiscal_year.year_end_date)
months_to_add = {
"Yearly": 12,
@ -46,7 +38,7 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity):
to_date = add_months(start_date, months_to_add)
start_date = to_date
if to_date == get_first_day(to_date):
# if to_date is the first day, get the last day of previous month
to_date = add_days(to_date, -1)
@ -85,8 +77,16 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity):
return period_list
def validate_fiscal_year(start_date, end_date):
if date_diff(end_date, start_date) <= 0:
def get_fiscal_year_data(from_fiscal_year, to_fiscal_year):
fiscal_year = frappe.db.sql("""select min(year_start_date) as year_start_date,
max(year_end_date) as year_end_date from `tabFiscal Year` where
name between %(from_fiscal_year)s and %(to_fiscal_year)s""",
{'from_fiscal_year': from_fiscal_year, 'to_fiscal_year': to_fiscal_year}, as_dict=1)
return fiscal_year[0] if fiscal_year else {}
def validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year):
if not fiscal_year.get('year_start_date') and not fiscal_year.get('year_end_date'):
frappe.throw(_("End Year cannot be before Start Year"))
def get_months(start_date, end_date):
@ -142,10 +142,9 @@ def calculate_values(accounts_by_name, gl_entries_by_account, period_list, accum
for period in period_list:
# check if posting date is within the period
fiscal_year = get_date_fiscal_year(entry.posting_date)
if entry.posting_date <= period.to_date:
if (accumulated_values or entry.posting_date >= period.from_date) and \
(fiscal_year == period.to_date_fiscal_year or not ignore_accumulated_values_for_fy):
(entry.fiscal_year == period.to_date_fiscal_year or not ignore_accumulated_values_for_fy):
d[period.key] = d.get(period.key, 0.0) + flt(entry.debit) - flt(entry.credit)
if entry.posting_date < period_list[0].year_start_date:
@ -294,7 +293,7 @@ def set_gl_entries_by_account(company, from_date, to_date, root_lft, root_rgt, f
additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters)
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening from `tabGL Entry`
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year from `tabGL Entry`
where company=%(company)s
{additional_conditions}
and posting_date <= %(to_date)s

View File

@ -30,6 +30,8 @@ def execute(filters=None):
elif d.so_detail:
delivery_note = ", ".join(frappe.db.sql_list("""select distinct parent
from `tabDelivery Note Item` where docstatus=1 and so_detail=%s""", d.so_detail))
if not delivery_note and d.update_stock:
delivery_note = d.parent
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.customer, d.customer_name,
d.customer_group, d.debit_to, d.mode_of_payment, d.territory, d.project, d.company, d.sales_order,
@ -84,7 +86,7 @@ def get_items(filters):
si_item.item_code, si_item.item_name, si_item.item_group, si_item.sales_order,
si_item.delivery_note, si_item.income_account, si_item.cost_center, si_item.qty,
si_item.base_net_rate, si_item.base_net_amount, si.customer_name,
si.customer_group, si_item.so_detail, si.mode_of_payment
si.customer_group, si_item.so_detail, si.update_stock, si.mode_of_payment
from `tabSales Invoice` si, `tabSales Invoice Item` si_item
where si.name = si_item.parent and si.docstatus = 1 %s
order by si.posting_date desc, si_item.item_code desc""" % conditions, filters, as_dict=1)

View File

@ -7,12 +7,12 @@
"doctype": "Report",
"idx": 1,
"is_standard": "Yes",
"modified": "2016-05-17 08:26:50.810208",
"modified": "2016-08-18 14:29:50.680329",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Ordered Items To Be Billed",
"owner": "Administrator",
"query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`status` as \"Status\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project` as \"Project\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.base_amount as \"Amount:Currency:110\",\n (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1)) as \"Billed Amount:Currency:110\",\n (`tabSales Order Item`.base_amount - (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1))) as \"Pending Amount:Currency:120\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\",\n `tabSales Order`.`company` as \"Company:Link/Company:\"\nfrom\n `tabSales Order`, `tabSales Order Item`\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status != \"Closed\"\n and `tabSales Order Item`.amount > 0\n and `tabSales Order Item`.billed_amt < `tabSales Order Item`.amount\norder by `tabSales Order`.transaction_date asc",
"query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`customer_name` as \"Customer Name:150\",\n`tabSales Order`.`status` as \"Status\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project` as \"Project\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.base_amount as \"Amount:Currency:110\",\n (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1)) as \"Billed Amount:Currency:110\",\n (`tabSales Order Item`.base_amount - (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1))) as \"Pending Amount:Currency:120\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\",\n `tabSales Order`.`company` as \"Company:Link/Company:\"\nfrom\n `tabSales Order`, `tabSales Order Item`\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status != \"Closed\"\n and `tabSales Order Item`.amount > 0\n and `tabSales Order Item`.billed_amt < `tabSales Order Item`.amount\norder by `tabSales Order`.transaction_date asc",
"ref_doctype": "Sales Invoice",
"report_name": "Ordered Items To Be Billed",
"report_type": "Query Report"

View File

@ -7,12 +7,12 @@
"doctype": "Report",
"idx": 1,
"is_standard": "Yes",
"modified": "2016-05-17 08:28:26.093139",
"modified": "2016-08-18 15:46:45.789536",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Order Items To Be Billed",
"owner": "Administrator",
"query": "select \n `tabPurchase Order`.`name` as \"Purchase Order:Link/Purchase Order:120\",\n `tabPurchase Order`.`transaction_date` as \"Date:Date:100\",\n\t`tabPurchase Order`.`supplier` as \"Supplier:Link/Supplier:120\",\n\t`tabPurchase Order Item`.`project` as \"Project\",\n\t`tabPurchase Order Item`.item_code as \"Item Code:Link/Item:120\",\n\t`tabPurchase Order Item`.base_amount as \"Amount:Currency:100\",\n\t(`tabPurchase Order Item`.billed_amt * ifnull(`tabPurchase Order`.conversion_rate, 1)) as \"Billed Amount:Currency:100\", \n\t(`tabPurchase Order Item`.base_amount - (`tabPurchase Order Item`.billed_amt * ifnull(`tabPurchase Order`.conversion_rate, 1))) as \"Amount to Bill:Currency:100\",\n\t`tabPurchase Order Item`.item_name as \"Item Name::150\",\n\t`tabPurchase Order Item`.description as \"Description::200\",\n\t`tabPurchase Order`.company as \"Company:Link/Company:\"\nfrom\n\t`tabPurchase Order`, `tabPurchase Order Item`\nwhere\n\t`tabPurchase Order Item`.`parent` = `tabPurchase Order`.`name`\n\tand `tabPurchase Order`.docstatus = 1\n\tand `tabPurchase Order`.status != \"Closed\"\n and `tabPurchase Order Item`.amount > 0\n\tand (`tabPurchase Order Item`.billed_amt * ifnull(`tabPurchase Order`.conversion_rate, 1)) < `tabPurchase Order Item`.base_amount\norder by `tabPurchase Order`.transaction_date asc",
"query": "select \n `tabPurchase Order`.`name` as \"Purchase Order:Link/Purchase Order:120\",\n `tabPurchase Order`.`transaction_date` as \"Date:Date:100\",\n\t`tabPurchase Order`.`supplier` as \"Supplier:Link/Supplier:120\",\n\t`tabPurchase Order`.`supplier_name` as \"Supplier Name::150\",\n\t`tabPurchase Order Item`.`project` as \"Project\",\n\t`tabPurchase Order Item`.item_code as \"Item Code:Link/Item:120\",\n\t`tabPurchase Order Item`.base_amount as \"Amount:Currency:100\",\n\t(`tabPurchase Order Item`.billed_amt * ifnull(`tabPurchase Order`.conversion_rate, 1)) as \"Billed Amount:Currency:100\", \n\t(`tabPurchase Order Item`.base_amount - (`tabPurchase Order Item`.billed_amt * ifnull(`tabPurchase Order`.conversion_rate, 1))) as \"Amount to Bill:Currency:100\",\n\t`tabPurchase Order Item`.item_name as \"Item Name::150\",\n\t`tabPurchase Order Item`.description as \"Description::200\",\n\t`tabPurchase Order`.company as \"Company:Link/Company:\"\nfrom\n\t`tabPurchase Order`, `tabPurchase Order Item`\nwhere\n\t`tabPurchase Order Item`.`parent` = `tabPurchase Order`.`name`\n\tand `tabPurchase Order`.docstatus = 1\n\tand `tabPurchase Order`.status != \"Closed\"\n and `tabPurchase Order Item`.amount > 0\n\tand (`tabPurchase Order Item`.billed_amt * ifnull(`tabPurchase Order`.conversion_rate, 1)) < `tabPurchase Order Item`.base_amount\norder by `tabPurchase Order`.transaction_date asc",
"ref_doctype": "Purchase Invoice",
"report_name": "Purchase Order Items To Be Billed",
"report_type": "Query Report"

View File

@ -7,12 +7,12 @@
"doctype": "Report",
"idx": 1,
"is_standard": "Yes",
"modified": "2016-05-17 08:38:49.654749",
"modified": "2016-08-18 14:32:20.965816",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Received Items To Be Billed",
"owner": "Administrator",
"query": "select\n `tabPurchase Receipt`.`name` as \"Purchase Receipt:Link/Purchase Receipt:120\",\n `tabPurchase Receipt`.`supplier` as \"Supplier:Link/Supplier:120\",\n\t`tabPurchase Receipt`.`posting_date` as \"Date:Date\",\n\t`tabPurchase Receipt Item`.`project` as \"Project\",\n\t`tabPurchase Receipt Item`.`item_code` as \"Item:Link/Item:120\",\n\t(`tabPurchase Receipt Item`.`base_amount` - `tabPurchase Receipt Item`.`billed_amt`*ifnull(`tabPurchase Receipt`.conversion_rate, 1)) as \"Pending Amount:Currency:110\",\n\t`tabPurchase Receipt Item`.`item_name` as \"Item Name::150\",\n\t`tabPurchase Receipt Item`.`description` as \"Description::200\",\n\t`tabPurchase Receipt`.`company` as \"Company:Link/Company:\"\nfrom `tabPurchase Receipt`, `tabPurchase Receipt Item`\nwhere\n `tabPurchase Receipt`.name = `tabPurchase Receipt Item`.parent \n and `tabPurchase Receipt`.docstatus = 1 \n and `tabPurchase Receipt`.status != \"Closed\" \n and `tabPurchase Receipt Item`.amount > 0\n and `tabPurchase Receipt Item`.billed_amt < `tabPurchase Receipt Item`.amount\norder by `tabPurchase Receipt`.`name` desc",
"query": "select\n `tabPurchase Receipt`.`name` as \"Purchase Receipt:Link/Purchase Receipt:120\",\n `tabPurchase Receipt`.`supplier` as \"Supplier:Link/Supplier:120\",\n\t`tabPurchase Receipt`.`supplier_name` as \"Supplier Name::150\",\n\t`tabPurchase Receipt`.`posting_date` as \"Date:Date\",\n\t`tabPurchase Receipt Item`.`project` as \"Project\",\n\t`tabPurchase Receipt Item`.`item_code` as \"Item:Link/Item:120\",\n\t(`tabPurchase Receipt Item`.`base_amount` - `tabPurchase Receipt Item`.`billed_amt`*ifnull(`tabPurchase Receipt`.conversion_rate, 1)) as \"Pending Amount:Currency:110\",\n\t`tabPurchase Receipt Item`.`item_name` as \"Item Name::150\",\n\t`tabPurchase Receipt Item`.`description` as \"Description::200\",\n\t`tabPurchase Receipt`.`company` as \"Company:Link/Company:\"\nfrom `tabPurchase Receipt`, `tabPurchase Receipt Item`\nwhere\n `tabPurchase Receipt`.name = `tabPurchase Receipt Item`.parent \n and `tabPurchase Receipt`.docstatus = 1 \n and `tabPurchase Receipt`.status != \"Closed\" \n and `tabPurchase Receipt Item`.amount > 0\n and `tabPurchase Receipt Item`.billed_amt < `tabPurchase Receipt Item`.amount\norder by `tabPurchase Receipt`.`name` desc",
"ref_doctype": "Purchase Invoice",
"report_name": "Received Items To Be Billed",
"report_type": "Query Report"

View File

@ -570,3 +570,58 @@ def get_children():
each["balance_in_account_currency"] = flt(get_balance_on(each.get("value")))
return acc
def create_payment_gateway_and_account(gateway):
create_payment_gateway(gateway)
create_payment_gateway_account(gateway)
def create_payment_gateway(gateway):
# NOTE: we don't translate Payment Gateway name because it is an internal doctype
if not frappe.db.exists("Payment Gateway", gateway):
payment_gateway = frappe.get_doc({
"doctype": "Payment Gateway",
"gateway": gateway
})
payment_gateway.insert(ignore_permissions=True)
def create_payment_gateway_account(gateway):
from erpnext.setup.setup_wizard.setup_wizard import create_bank_account
company = frappe.db.get_value("Global Defaults", None, "default_company")
if not company:
return
# NOTE: we translate Payment Gateway account name because that is going to be used by the end user
bank_account = frappe.db.get_value("Account", {"account_name": _(gateway), "company": company},
["name", 'account_currency'], as_dict=1)
if not bank_account:
# check for untranslated one
bank_account = frappe.db.get_value("Account", {"account_name": gateway, "company": company},
["name", 'account_currency'], as_dict=1)
if not bank_account:
# try creating one
bank_account = create_bank_account({"company_name": company, "bank_account": _(gateway)})
if not bank_account:
frappe.msgprint(_("Payment Gateway Account not created, please create one manually."))
return
# if payment gateway account exists, return
if frappe.db.exists("Payment Gateway Account",
{"payment_gateway": gateway, "currency": bank_account.account_currency}):
return
try:
frappe.get_doc({
"doctype": "Payment Gateway Account",
"is_default": 1,
"payment_gateway": gateway,
"payment_account": bank_account.name,
"currency": bank_account.account_currency
}).insert(ignore_permissions=True)
except frappe.DuplicateEntryError:
# already exists, due to a reinstall?
pass

View File

@ -138,20 +138,15 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
},
qty: function(doc, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
if ((doc.doctype == "Purchase Receipt") || (doc.doctype == "Purchase Invoice" && doc.update_stock)) {
var item = frappe.get_doc(cdt, cdn);
frappe.model.round_floats_in(item, ["qty", "received_qty"]);
if(!(item.received_qty || item.rejected_qty) && item.qty) {
item.received_qty = item.qty;
}
if(item.qty > item.received_qty) {
msgprint(__("Error: {0} > {1}", [__(frappe.meta.get_label(item.doctype, "qty", item.name)),
__(frappe.meta.get_label(item.doctype, "received_qty", item.name))]))
item.qty = item.rejected_qty = 0.0;
} else {
item.rejected_qty = flt(item.received_qty - item.qty, precision("rejected_qty", item));
}
frappe.model.round_floats_in(item, ["qty", "received_qty"]);
item.rejected_qty = flt(item.received_qty - item.qty, precision("rejected_qty", item));
}
this._super(doc, cdt, cdn);
@ -160,26 +155,18 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
},
received_qty: function(doc, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
frappe.model.round_floats_in(item, ["qty", "received_qty"]);
item.qty = (item.qty < item.received_qty) ? item.qty : item.received_qty;
this.qty(doc, cdt, cdn);
this.calculate_accepted_qty(doc, cdt, cdn)
},
rejected_qty: function(doc, cdt, cdn) {
this.calculate_accepted_qty(doc, cdt, cdn)
},
calculate_accepted_qty: function(doc, cdt, cdn){
var item = frappe.get_doc(cdt, cdn);
frappe.model.round_floats_in(item, ["received_qty", "rejected_qty"]);
if(item.rejected_qty > item.received_qty) {
msgprint(__("Error: {0} > {1}", [__(frappe.meta.get_label(item.doctype, "rejected_qty", item.name)),
__(frappe.meta.get_label(item.doctype, "received_qty", item.name))]));
item.qty = item.rejected_qty = 0.0;
} else {
item.qty = flt(item.received_qty - item.rejected_qty, precision("qty", item));
}
item.qty = flt(item.received_qty - item.rejected_qty, precision("qty", item));
this.qty(doc, cdt, cdn);
},

View File

@ -41,10 +41,6 @@ erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.ext
// for backward compatibility: combine new and previous states
$.extend(cur_frm.cscript, new erpnext.buying.SupplierQuotationController({frm: cur_frm}));
cur_frm.cscript.uom = function(doc, cdt, cdn) {
// no need to trigger updation of stock uom, as this field doesn't exist in supplier quotation
}
cur_frm.fields_dict['items'].grid.get_field('project').get_query =
function(doc, cdt, cdn) {
return{

View File

@ -15,6 +15,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "supplier_section",
"fieldtype": "Section Break",
"hidden": 0,
@ -40,6 +41,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "{supplier_name}",
"fieldname": "title",
"fieldtype": "Data",
@ -66,6 +68,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@ -93,6 +96,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "supplier",
"fieldtype": "Link",
@ -121,6 +125,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"fieldname": "supplier_name",
"fieldtype": "Data",
"hidden": 0,
@ -145,6 +150,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@ -171,6 +177,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Today",
"fieldname": "transaction_date",
"fieldtype": "Date",
@ -198,6 +205,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 1,
@ -225,6 +233,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "company",
"fieldtype": "Link",
@ -253,6 +262,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "address_section",
"fieldtype": "Section Break",
"hidden": 0,
@ -278,6 +288,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "supplier_address",
"fieldtype": "Link",
"hidden": 0,
@ -303,6 +314,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "contact_person",
"fieldtype": "Link",
"hidden": 0,
@ -328,6 +340,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "address_display",
"fieldtype": "Small Text",
"hidden": 0,
@ -352,6 +365,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "contact_display",
"fieldtype": "Small Text",
"hidden": 0,
@ -376,6 +390,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "contact_mobile",
"fieldtype": "Small Text",
"hidden": 0,
@ -400,6 +415,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "contact_email",
"fieldtype": "Data",
"hidden": 0,
@ -425,6 +441,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "currency_and_price_list",
"fieldtype": "Section Break",
"hidden": 0,
@ -450,6 +467,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
@ -477,6 +495,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "conversion_rate",
"fieldtype": "Float",
@ -505,6 +524,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cb_price_list",
"fieldtype": "Column Break",
"hidden": 0,
@ -530,6 +550,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "buying_price_list",
"fieldtype": "Link",
"hidden": 0,
@ -555,6 +576,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "buying_price_list",
"fieldname": "price_list_currency",
"fieldtype": "Link",
@ -581,6 +603,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "buying_price_list",
"fieldname": "plc_conversion_rate",
"fieldtype": "Float",
@ -607,6 +630,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"hidden": 0,
@ -631,6 +655,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "items_section",
"fieldtype": "Section Break",
"hidden": 0,
@ -657,6 +682,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@ -684,6 +710,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_22",
"fieldtype": "Section Break",
"hidden": 0,
@ -707,6 +734,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "base_total",
"fieldtype": "Currency",
"hidden": 0,
@ -733,6 +761,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "base_net_total",
"fieldtype": "Currency",
"hidden": 0,
@ -760,6 +789,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_24",
"fieldtype": "Column Break",
"hidden": 0,
@ -783,6 +813,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total",
"fieldtype": "Currency",
"hidden": 0,
@ -809,6 +840,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "net_total",
"fieldtype": "Currency",
"hidden": 0,
@ -836,6 +868,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "taxes_section",
"fieldtype": "Section Break",
"hidden": 0,
@ -862,6 +895,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "taxes_and_charges",
"fieldtype": "Link",
@ -890,6 +924,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "taxes",
"fieldtype": "Table",
"hidden": 0,
@ -917,6 +952,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "HTML",
"hidden": 0,
@ -942,6 +978,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "totals",
"fieldtype": "Section Break",
"hidden": 0,
@ -968,6 +1005,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "base_taxes_and_charges_added",
"fieldtype": "Currency",
"hidden": 0,
@ -995,6 +1033,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "base_taxes_and_charges_deducted",
"fieldtype": "Currency",
"hidden": 0,
@ -1022,6 +1061,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "base_total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@ -1049,6 +1089,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_37",
"fieldtype": "Column Break",
"hidden": 0,
@ -1073,6 +1114,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "taxes_and_charges_added",
"fieldtype": "Currency",
"hidden": 0,
@ -1100,6 +1142,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "taxes_and_charges_deducted",
"fieldtype": "Currency",
"hidden": 0,
@ -1127,6 +1170,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@ -1154,6 +1198,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "discount_amount",
"columns": 0,
"fieldname": "section_break_41",
"fieldtype": "Section Break",
"hidden": 0,
@ -1179,6 +1224,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Grand Total",
"fieldname": "apply_discount_on",
"fieldtype": "Select",
@ -1206,6 +1252,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@ -1232,6 +1279,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_43",
"fieldtype": "Column Break",
"hidden": 0,
@ -1256,6 +1304,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "additional_discount_percentage",
"fieldtype": "Float",
"hidden": 0,
@ -1281,6 +1330,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@ -1307,6 +1357,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_46",
"fieldtype": "Section Break",
"hidden": 0,
@ -1331,6 +1382,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "base_grand_total",
"fieldtype": "Currency",
"hidden": 0,
@ -1358,6 +1410,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "base_in_words",
"fieldtype": "Data",
@ -1385,6 +1438,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "base_rounded_total",
"fieldtype": "Currency",
"hidden": 0,
@ -1412,6 +1466,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break4",
"fieldtype": "Column Break",
"hidden": 0,
@ -1436,6 +1491,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "grand_total",
"fieldtype": "Currency",
"hidden": 0,
@ -1463,6 +1519,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "in_words",
"fieldtype": "Data",
"hidden": 0,
@ -1490,6 +1547,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "terms",
"columns": 0,
"fieldname": "terms_section_break",
"fieldtype": "Section Break",
"hidden": 0,
@ -1516,6 +1574,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "tc_name",
"fieldtype": "Link",
"hidden": 0,
@ -1543,6 +1602,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "terms",
"fieldtype": "Text Editor",
"hidden": 0,
@ -1569,6 +1629,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "printing_settings",
"fieldtype": "Section Break",
"hidden": 0,
@ -1594,6 +1655,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "select_print_heading",
"fieldtype": "Link",
"hidden": 0,
@ -1621,6 +1683,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
@ -1648,6 +1711,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "language",
"fieldtype": "Data",
"hidden": 0,
@ -1673,6 +1737,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@ -1699,6 +1764,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@ -1726,6 +1792,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_57",
"fieldtype": "Column Break",
"hidden": 0,
@ -1749,6 +1816,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "No",
"fieldname": "is_subcontracted",
"fieldtype": "Select",
@ -1770,6 +1838,59 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "reference",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Reference",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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": "opportunity",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Opportunity",
"length": 0,
"no_copy": 1,
"options": "Opportunity",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"hide_heading": 0,
@ -1784,7 +1905,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2016-07-08 06:48:04.162164",
"modified": "2016-09-14 05:48:17.443848",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation",

View File

@ -3,6 +3,7 @@
from __future__ import unicode_literals
import frappe
from frappe.utils import flt
from frappe.model.mapper import get_mapped_doc
from erpnext.controllers.buying_controller import BuyingController
@ -62,7 +63,7 @@ def make_purchase_order(source_name, target_doc=None):
target.run_method("calculate_taxes_and_totals")
def update_item(obj, target, source_parent):
target.conversion_factor = 1
target.stock_qty = flt(obj.qty) * flt(obj.conversion_factor)
doclist = get_mapped_doc("Supplier Quotation", source_name, {
"Supplier Quotation": {
@ -76,8 +77,6 @@ def make_purchase_order(source_name, target_doc=None):
"field_map": [
["name", "supplier_quotation_item"],
["parent", "supplier_quotation"],
["uom", "stock_uom"],
["uom", "uom"],
["material_request", "material_request"],
["material_request_item", "material_request_item"]
],

View File

@ -303,6 +303,33 @@
"unique": 0,
"width": "60px"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "stock_uom",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Stock UOM",
"length": 0,
"no_copy": 0,
"options": "UOM",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -409,6 +436,32 @@
"unique": 0,
"width": "100px"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "conversion_factor",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "UOM Conversion Factor",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -1106,6 +1159,57 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_44",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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": "stock_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Qty as per Stock UOM",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
@ -1144,7 +1248,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-08-26 04:51:44.857545",
"modified": "2016-09-06 02:40:11.022104",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation Item",

View File

@ -4,12 +4,43 @@
frappe.query_reports["Quoted Item Comparison"] = {
"filters": [
{
"fieldname":"supplier_quotation",
"label": __("Supplier Quotation"),
"fieldtype": "Link",
"options": "Supplier Quotation",
"default": "",
"get_query": function() {
return {
filters: {"docstatus": ["<",2]}
}
}
},{
"fieldname":"item",
"label": __("Item"),
"fieldtype": "Link",
"options": "Item",
"default": ""
"default": "",
"reqd": 1,
"get_query": function() {
var quote = frappe.query_report_filters_by_name.supplier_quotation.get_value();
if (quote != "")
{
return {
query: "erpnext.buying.doctype.quality_inspection.quality_inspection.item_query",
filters: {
"from": "Supplier Quotation Item",
"parent": quote
}
}
}
else{
return{
filters: {"disabled":0}
}
}
}
}
],
onload: function(report) {

View File

@ -60,7 +60,7 @@ def get_data():
"link": "List/Lead"
},
{
"module_name": "Profit and Loss Statment",
"module_name": "Profit and Loss Statement",
"_doctype": "Account",
"color": "#3498db",
"icon": "octicon octicon-repo",

View File

@ -37,6 +37,10 @@ def get_data():
"type": "doctype",
"name": "Student Applicant"
},
{
"type": "doctype",
"name": "Student Admission"
},
{
"type": "doctype",
"name": "Program Enrollment"
@ -122,11 +126,15 @@ def get_data():
},
{
"type": "doctype",
"name": "Grading Structure"
"name": "Program"
},
{
"type": "doctype",
"name": "Program"
"name": "Student Category"
},
{
"type": "doctype",
"name": "Grading Structure"
},
{
"type": "doctype",

View File

@ -662,7 +662,7 @@ def get_advance_journal_entries(party_type, party, party_account, amount_field,
.format(order_doctype, order_condition))
reference_condition = " and (" + " or ".join(conditions) + ")" if conditions else ""
journal_entries = frappe.db.sql("""
select
"Journal Entry" as reference_type, t1.name as reference_name,
@ -674,8 +674,7 @@ def get_advance_journal_entries(party_type, party, party_account, amount_field,
t1.name = t2.parent and t2.account = %s
and t2.party_type = %s and t2.party = %s
and t2.is_advance = 'Yes' and t1.docstatus = 1
and {1} > 0
and (ifnull(t2.reference_name, '')='' {2})
and {1} > 0 {2}
order by t1.posting_date""".format(amount_field, dr_or_cr, reference_condition),
[party_account, party_type, party] + order_list, as_dict=1)

View File

@ -37,7 +37,7 @@ class BuyingController(StockController):
self.validate_purchase_receipt_if_update_stock()
if self.doctype=="Purchase Receipt" or (self.doctype=="Purchase Invoice" and self.update_stock):
self.validate_purchase_return()
# self.validate_purchase_return()
self.validate_rejected_warehouse()
self.validate_accepted_rejected_qty()
@ -346,7 +346,7 @@ class BuyingController(StockController):
})
sl_entries.append(sle)
if flt(d.rejected_qty) > 0:
if flt(d.rejected_qty) != 0:
sl_entries.append(self.get_sl_entries(d, {
"warehouse": d.rejected_warehouse,
"actual_qty": flt(d.rejected_qty) * flt(d.conversion_factor),

View File

@ -17,7 +17,8 @@ def get_filters_cond(doctype, filters, conditions):
if isinstance(f[1], basestring) and f[1][0] == '!':
flt.append([doctype, f[0], '!=', f[1][1:]])
else:
flt.append([doctype, f[0], '=', f[1]])
value = frappe.db.escape(f[1]) if isinstance(f[1], basestring) else f[1]
flt.append([doctype, f[0], '=', value])
query = DatabaseQuery(doctype)
query.filters = flt

View File

@ -53,13 +53,15 @@ def validate_returned_items(doc):
valid_items = frappe._dict()
select_fields = "item_code, qty" if doc.doctype=="Purchase Invoice" \
else "item_code, qty, serial_no, batch_no"
select_fields = "item_code, qty, parenttype" if doc.doctype=="Purchase Invoice" \
else "item_code, qty, serial_no, batch_no, parenttype"
if doc.doctype in ['Purchase Invoice', 'Purchase Receipt']:
select_fields += ",rejected_qty, received_qty"
for d in frappe.db.sql("""select {0} from `tab{1} Item` where parent = %s"""
.format(select_fields, doc.doctype), doc.return_against, as_dict=1):
valid_items = get_ref_item_dict(valid_items, d)
if doc.doctype in ("Delivery Note", "Sales Invoice"):
for d in frappe.db.sql("""select item_code, qty, serial_no, batch_no from `tabPacked Item`
@ -73,21 +75,15 @@ def validate_returned_items(doc):
items_returned = False
for d in doc.get("items"):
if flt(d.qty) < 0:
if flt(d.qty) < 0 or d.get('received_qty') < 0:
if d.item_code not in valid_items:
frappe.throw(_("Row # {0}: Returned Item {1} does not exists in {2} {3}")
.format(d.idx, d.item_code, doc.doctype, doc.return_against))
else:
ref = valid_items.get(d.item_code, frappe._dict())
already_returned_qty = flt(already_returned_items.get(d.item_code))
max_return_qty = flt(ref.qty) - already_returned_qty
validate_quantity(doc, d, ref, valid_items, already_returned_items)
if already_returned_qty >= ref.qty:
frappe.throw(_("Item {0} has already been returned").format(d.item_code), StockOverReturnError)
elif abs(d.qty) > max_return_qty:
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
.format(d.idx, ref.qty, d.item_code), StockOverReturnError)
elif ref.batch_no and d.batch_no not in ref.batch_no:
if ref.batch_no and d.batch_no not in ref.batch_no:
frappe.throw(_("Row # {0}: Batch No must be same as {1} {2}")
.format(d.idx, doc.doctype, doc.return_against))
elif ref.serial_no:
@ -107,18 +103,45 @@ def validate_returned_items(doc):
if not items_returned:
frappe.throw(_("Atleast one item should be entered with negative quantity in return document"))
def validate_quantity(doc, args, ref, valid_items, already_returned_items):
fields = ['qty']
if doc.doctype in ['Purchase Invoice', 'Purchase Receipt']:
fields.extend(['received_qty', 'rejected_qty'])
already_returned_data = already_returned_items.get(args.item_code) or {}
for column in fields:
return_qty = flt(already_returned_data.get(column, 0)) if len(already_returned_data) > 0 else 0
referenced_qty = ref.get(column)
max_return_qty = flt(referenced_qty) - return_qty
label = column.replace('_', ' ').title()
if flt(args.get(column)) > 0:
frappe.throw(_("{0} must be negative in return document").format(label))
elif return_qty >= referenced_qty and flt(args.get(column)) != 0:
frappe.throw(_("Item {0} has already been returned").format(args.item_code), StockOverReturnError)
elif abs(args.get(column)) > max_return_qty:
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
.format(args.idx, referenced_qty, args.item_code), StockOverReturnError)
def get_ref_item_dict(valid_items, ref_item_row):
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
valid_items.setdefault(ref_item_row.item_code, frappe._dict({
"qty": 0,
"rejected_qty": 0,
"received_qty": 0,
"serial_no": [],
"batch_no": []
}))
item_dict = valid_items[ref_item_row.item_code]
item_dict["qty"] += ref_item_row.qty
if ref_item_row.parenttype in ['Purchase Invoice', 'Purchase Receipt']:
item_dict["received_qty"] += ref_item_row.received_qty
item_dict["rejected_qty"] += ref_item_row.rejected_qty
if ref_item_row.get("serial_no"):
item_dict["serial_no"] += get_serial_nos(ref_item_row.serial_no)
@ -128,16 +151,30 @@ def get_ref_item_dict(valid_items, ref_item_row):
return valid_items
def get_already_returned_items(doc):
return frappe._dict(frappe.db.sql("""
select
child.item_code, sum(abs(child.qty)) as qty
column = 'child.item_code, sum(abs(child.qty)) as qty'
if doc.doctype in ['Purchase Invoice', 'Purchase Receipt']:
column += ', sum(abs(child.rejected_qty)) as rejected_qty, sum(abs(child.received_qty)) as received_qty'
data = frappe.db.sql("""
select {0}
from
`tab{0} Item` child, `tab{1}` par
`tab{1} Item` child, `tab{2}` par
where
child.parent = par.name and par.docstatus = 1
and par.is_return = 1 and par.return_against = %s and child.qty < 0
and par.is_return = 1 and par.return_against = %s
group by item_code
""".format(doc.doctype, doc.doctype), doc.return_against))
""".format(column, doc.doctype, doc.doctype), doc.return_against, as_dict=1)
items = {}
for d in data:
items.setdefault(d.item_code, frappe._dict({
"qty": d.get("qty"),
"received_qty": d.get("received_qty"),
"rejected_qty": d.get("rejected_qty")
}))
return items
def make_return_doc(doctype, source_name, target_doc=None):
from frappe.model.mapper import get_mapped_doc
@ -166,12 +203,18 @@ def make_return_doc(doctype, source_name, target_doc=None):
def update_item(source_doc, target_doc, source_parent):
target_doc.qty = -1* source_doc.qty
if doctype == "Purchase Receipt":
target_doc.received_qty = -1* source_doc.qty
target_doc.received_qty = -1* source_doc.received_qty
target_doc.rejected_qty = -1* source_doc.rejected_qty
target_doc.qty = -1* source_doc.qty
target_doc.purchase_order = source_doc.purchase_order
target_doc.rejected_warehouse = source_doc.rejected_warehouse
elif doctype == "Purchase Invoice":
target_doc.received_qty = -1* source_doc.qty
target_doc.received_qty = -1* source_doc.received_qty
target_doc.rejected_qty = -1* source_doc.rejected_qty
target_doc.qty = -1* source_doc.qty
target_doc.purchase_order = source_doc.purchase_order
target_doc.purchase_receipt = source_doc.purchase_receipt
target_doc.rejected_warehouse = source_doc.rejected_warehouse
target_doc.po_detail = source_doc.po_detail
target_doc.pr_detail = source_doc.pr_detail
elif doctype == "Delivery Note":

View File

@ -245,8 +245,8 @@ class StatusUpdater(Document):
frappe.db.sql("""update `tab%(target_parent_dt)s`
set %(target_parent_field)s = round(
ifnull((select
ifnull(sum(if(%(target_ref_field)s > %(target_field)s, %(target_field)s, %(target_ref_field)s)), 0)
/ sum(%(target_ref_field)s) * 100
ifnull(sum(if(%(target_ref_field)s > %(target_field)s, abs(%(target_field)s), abs(%(target_ref_field)s))), 0)
/ sum(abs(%(target_ref_field)s)) * 100
from `tab%(target_dt)s` where parent="%(name)s"), 0), 2)
%(update_modified)s
where name='%(name)s'""" % args)

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,6 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import cstr, validate_email_add, cint, comma_and, has_gravatar
from frappe import session
from frappe.model.mapper import get_mapped_doc
from erpnext.controllers.selling_controller import SellingController
@ -34,9 +33,6 @@ class Lead(SellingController):
self.set_status()
self.check_email_id_is_unique()
if self.source == 'Campaign' and not self.campaign_name and session['user'] != 'Guest':
frappe.throw(_("Campaign Name is required"))
if self.email_id:
if not self.flags.ignore_email_validation:
validate_email_add(self.email_id, True)

View File

@ -8,16 +8,47 @@ frappe.ui.form.on("Opportunity", {
customer: function(frm) {
erpnext.utils.get_party_details(frm);
},
customer_address: function(frm, cdt, cdn){
customer_address: function(frm, cdt, cdn) {
erpnext.utils.get_address_display(frm, 'customer_address', 'address_display', false);
},
contact_person: erpnext.utils.get_contact_details,
enquiry_from: function(frm) {
frm.toggle_reqd("lead", frm.doc.enquiry_from==="Lead");
frm.toggle_reqd("customer", frm.doc.enquiry_from==="Customer");
},
refresh: function(frm) {
var doc = frm.doc;
frm.events.enquiry_from(frm);
if(doc.status!=="Lost") {
if(doc.with_items){
frm.add_custom_button(__('Supplier Quotation'),
function() {
frm.trigger("make_supplier_quotation")
}, __("Make"));
frm.add_custom_button(__('Quotation'),
cur_frm.cscript.create_quotation, __("Make"));
frm.page.set_inner_btn_group_as_primary(__("Make"));
}
if(doc.status!=="Quotation") {
frm.add_custom_button(__('Lost'),
cur_frm.cscript['Declare Opportunity Lost']);
}
}
},
make_supplier_quotation: function(frm) {
frappe.model.open_mapped_doc({
method: "erpnext.crm.doctype.opportunity.opportunity.make_supplier_quotation",
frm: cur_frm
})
}
})
@ -91,17 +122,6 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) {
});
}
}
if(doc.status!=="Lost") {
if(doc.status!=="Quotation") {
cur_frm.add_custom_button(__('Lost'),
cur_frm.cscript['Declare Opportunity Lost']);
}
cur_frm.add_custom_button(__('Quotation'),
cur_frm.cscript.create_quotation);
}
}
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {

View File

@ -16,6 +16,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "from_section",
"fieldtype": "Section Break",
"hidden": 0,
@ -41,6 +42,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@ -68,6 +70,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "enquiry_from",
"fieldtype": "Select",
"hidden": 0,
@ -95,6 +98,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.enquiry_from===\"Customer\"",
"fieldname": "customer",
"fieldtype": "Link",
@ -123,6 +127,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.enquiry_from===\"Lead\"",
"fieldname": "lead",
"fieldtype": "Link",
@ -151,6 +156,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "customer_name",
"fieldtype": "Data",
@ -176,6 +182,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@ -201,6 +208,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "title",
"fieldtype": "Data",
"hidden": 1,
@ -226,6 +234,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Sales",
"fieldname": "enquiry_type",
"fieldtype": "Select",
@ -254,6 +263,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Open",
"fieldname": "status",
"fieldtype": "Select",
@ -282,6 +292,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.status===\"Lost\"",
"fieldname": "order_lost_reason",
"fieldtype": "Small Text",
@ -307,6 +318,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"fieldname": "mins_to_first_response",
"fieldtype": "Float",
"hidden": 0,
@ -332,6 +344,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "with_items",
"fieldtype": "Check",
"hidden": 0,
@ -357,6 +370,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "with_items",
"fieldname": "items_section",
"fieldtype": "Section Break",
@ -384,6 +398,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "items",
"fieldtype": "Table",
@ -413,6 +428,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "next_contact_by",
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
"fieldname": "contact_info",
"fieldtype": "Section Break",
@ -439,6 +455,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.customer || doc.lead",
"fieldname": "customer_address",
"fieldtype": "Link",
@ -465,6 +482,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "address_display",
"fieldtype": "Small Text",
"hidden": 1,
@ -491,6 +509,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
"description": "",
"fieldname": "territory",
@ -518,6 +537,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
"description": "",
"fieldname": "customer_group",
@ -547,6 +567,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break3",
"fieldtype": "Column Break",
"hidden": 0,
@ -570,6 +591,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
"fieldname": "contact_person",
"fieldtype": "Link",
@ -596,6 +618,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
"fieldname": "contact_display",
"fieldtype": "Small Text",
@ -621,6 +644,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
"fieldname": "contact_email",
"fieldtype": "Data",
@ -646,6 +670,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
"fieldname": "contact_mobile",
"fieldtype": "Small Text",
@ -672,6 +697,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "",
"columns": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@ -698,8 +724,9 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "source",
"fieldtype": "Select",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -710,7 +737,7 @@
"no_copy": 0,
"oldfieldname": "source",
"oldfieldtype": "Select",
"options": "\nExisting Customer\nReference\nAdvertisement\nCold Calling\nExhibition\nSupplier Reference\nMass Mailing\nCustomer's Vendor\nCampaign\nWalk In",
"options": "Lead Source",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@ -725,6 +752,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Enter name of campaign if source of enquiry is campaign",
"fieldname": "campaign",
"fieldtype": "Link",
@ -753,6 +781,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@ -778,6 +807,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@ -805,6 +835,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Today",
"fieldname": "transaction_date",
"fieldtype": "Date",
@ -834,6 +865,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "contact_by",
"columns": 0,
"fieldname": "next_contact",
"fieldtype": "Section Break",
"hidden": 0,
@ -859,6 +891,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Your sales person who will contact the customer in future",
"fieldname": "contact_by",
"fieldtype": "Link",
@ -888,6 +921,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Your sales person will get a reminder on this date to contact the customer",
"fieldname": "contact_date",
"fieldtype": "Datetime",
@ -915,6 +949,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
@ -940,6 +975,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "to_discuss",
"fieldtype": "Small Text",
"hidden": 0,
@ -966,6 +1002,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@ -1002,7 +1039,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-07-28 15:58:06.614493",
"modified": "2016-09-16 01:52:06.229882",
"modified_by": "Administrator",
"module": "CRM",
"name": "Opportunity",

View File

@ -231,6 +231,25 @@ def make_quotation(source_name, target_doc=None):
return doclist
@frappe.whitelist()
def make_supplier_quotation(source_name, target_doc=None):
doclist = get_mapped_doc("Opportunity", source_name, {
"Opportunity": {
"doctype": "Supplier Quotation",
"field_map": {
"name": "opportunity"
}
},
"Opportunity Item": {
"doctype": "Supplier Quotation Item",
"field_map": {
"uom": "stock_uom"
}
}
}, target_doc)
return doclist
@frappe.whitelist()
def set_multiple_status(names, status):
names = json.loads(names)

View File

@ -22,7 +22,7 @@ def make_timesheet_for_projects(current_date ):
ts = make_timesheet(employee, simulate = True, billable = 1,
activity_type=get_random("Activity Type"), project=data.project, task =data.name)
if flt(ts.total_billing_amount) > 0.0:
if flt(ts.total_billable_amount) > 0.0:
make_sales_invoice_for_timesheet(ts.name)
frappe.db.commit()

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

View File

@ -14,3 +14,4 @@ search-record-by-specific-field
set-language
set-precision
user-restriction
maximum-numbers-of-fields-in-a-form

View File

@ -0,0 +1,22 @@
Sometimes while creating custom fields, you might experienced an error message like below:
> Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
### What it actually means?
In simple terms, it means that you have reached the limit of maximum numbers of fields for the specific form/doctype. So, what is the limit of maximum numbers of fields?
In MySQL, there is a hard limit of 4096 columns per table, but the effective maximum may be less for a given table. The exact limit depends on several interacting factors.
Every table (regardless of storage engine) has a maximum row size of 65,535 bytes. Storage engines may place additional constraints on this limit, reducing the effective maximum row size.
The maximum row size constrains the number (and possibly size) of columns because the total length of all columns cannot exceed this size (65,535 bytes). For example, `utf8mb3` characters require up to 3 bytes per character, so for a `VARCHAR(140)` column, the server must allocate `140 × 3 = 420` bytes per value. Consequently, a table cannot contain more than `65,535 / 420 = 156` such columns.
In Frappe frapework, `VARCHAR(140)` type columns are created based on "Data", "Link", "Select", "Dynamic Link", "Password" and "Read Only" fieldtypes. Hence, you can create approximately 156 such columns in the system.
### Solutions:
To add more fields in the system, you can do some changes.
1. Convert some of the fields to "Text", "Small Text", "Text Editor" or "Code" type field. In MySQL, BLOB and TEXT columns count from one to four plus eight bytes each toward the row-size limit because their contents are stored separately from the rest of the row. So, converting to those fieldtypes will free up some spaces and will allow to add some more fields.
2. Set smaller value in the "Length" property while creating fields, default value is 140. System sets length of `VARCHAR` based on this property and allocates size for that columns. Hence, smaller Length leads to add more fields.

View File

@ -8,6 +8,9 @@ Timesheets can be tracked against Project and Tasks so that you can get reports
To bill Customer based on Timesheet, check "Is Billable" in the Timesheet created against Project and Task. To learn more about billing Customer from Timesheet, click [here]({{docs_base_url}}/user/manual/en/projects/timesheet/sales-invoice-from-timesheet.html).
User can also make invoice against timesheet by selecting the project on the invoice. System will fetch the records from the timesheet based on selected project, for mode detail check below video
<iframe width="560" height="315" src="https://www.youtube.com/embed/hVAjtOFFhDI" frameborder="0" allowfullscreen></iframe>
####Project Costing
When creating Timesheet, Employee will have to select an Activity Type. For each Activity Type, you can create an Activity Cost master. In the Activity Cost, Billing Rate and Costing rate is defined for each Employee.

View File

@ -0,0 +1,37 @@
# Email Reports at Regular Intervals
You can setup **Auto Email Report** to send reports at regular intervals. These must be saved reports of any type (Report Builder, Script or Query Report).
You can find Auto Email Report at
> Setup > Email > Auto Email Report
Or just type "Auto Email Report" on the Search bar.
### Example
#### Step 1
Select the Report, the user for which you want to create this report (permissions will apply for this user), the email ids where you want this report emailed and the frequency of the report.
<img class="screenshot" alt="Make Auto Email Report" src="{{docs_base_url}}/assets/img/setup/email/auto-email-1.png">
#### Step 2
If your report has filters, you will see a table with the filters
Step 1. Select the Report, the user for which you want to create this report. Permissions will apply for this user
<img class="screenshot" alt="With Filters" src="{{docs_base_url}}/assets/img/setup/email/auto-email-2.png">
Click on the table to edit the table
<img class="screenshot" alt="Edit Filters" src="{{docs_base_url}}/assets/img/setup/email/auto-email-3.png">
#### Test
You can also test the report by clicking on "Download" or "Send Now"
Here is an example of the email you will receive for a report
<img class="screenshot" alt="Report by Email" src="{{docs_base_url}}/assets/img/setup/email/auto-email-4.png">

View File

@ -1,5 +1,5 @@
email-account
email-alerts
email-digest
sending-email
setting-up-email
email-reports
sending-email

View File

@ -1,4 +1,4 @@
An Item is your companys' product or a service. The term Item is applicable to your core products as well as your raw materials. It can be a product or service that you buy/sell from your customers/ suppliers. ERPNext allows you to manage all sorts of items like raw-materials, sub-assemblies, finished goods, item variants and service items.
An Item is your companys' product or a service. The term Item is applicable to things (products or services) you sell as well as raw materials or components of products yet to be produced (before they can be sold to customers). An Item can be a phyical product or a service that you buy/sell from your customers/suppliers. ERPNext allows you to manage all sorts of items like raw-materials, sub-assemblies, finished goods, item variants and service items.
ERPNext is optimized for itemized management of your sales and purchase. If you are in services, you can create an Item for each services that your offer. Completing the Item Master is very essential for successful implementation of ERPNext.

View File

@ -1,10 +1,10 @@
A Item Variant is a different version of a Item, such as differing sizes or differing colours.
Without Item variants, you would have to treat the small, medium and large versions of a t-shirt as three separate Items;
Item variants let you treat the small, medium and large versions of a t-shirt as variations of the same Item.
A Item Variant is a version of a Item, such as differing sizes or differing colours (like a _blue_ t-shirt in size _small_ rather then just a t-shirt).
Without Item variants, you would have to treat the _small, medium_ and _large_ versions of a t-shirt as three separate Items;
Item variants let you treat the _small, medium_ and _large_ versions of a t-shirt as variations of the one Item 't-shirt'.
To use Item Variants in ERPNext, create an Item and check 'Has Variants'
To use Item Variants in ERPNext, create an Item and check 'Has Variants'.
* The Item shall then be referred as a 'Template'
* The Item shall then be referred to as a so called 'Template'. Such a Template is not identical to a regular 'Item' any longer. For example it (the Template) can not be used directly in any Transactions (Sales Order, Delivery Note, Purchase Invoice) itself. Only the Variants of an Item (_blue_ t-shirt in size _small)_ can be practically used in such. Therefore it would be ideal to decide whether an item 'Has Variants' or not directly when creating it.
<img class="screenshot" alt="Has Variants" src="{{docs_base_url}}/assets/img/stock/item-has-variants.png">

View File

@ -45,7 +45,7 @@ calendars = ["Task", "Production Order", "Leave Application", "Sales Order", "Ho
fixtures = ["Web Form"]
website_generators = ["Item Group", "Item", "Sales Partner", "Job Opening"]
website_generators = ["Item Group", "Item", "Sales Partner", "Job Opening", "Student Admission"]
website_context = {
"favicon": "/assets/erpnext/images/favicon.png",
@ -89,6 +89,7 @@ website_route_rules = [
}
},
{"from_route": "/jobs", "to_route": "Job Opening"},
{"from_route": "/admissions", "to_route": "Student Admission"},
]
portal_menu_items = [

View File

@ -2,17 +2,20 @@
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "APRSL.#####",
"autoname": "naming_series:",
"beta": 0,
"creation": "2013-01-10 16:34:12",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "employee_details",
"fieldtype": "Section Break",
"hidden": 0,
@ -38,6 +41,34 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Series",
"length": 0,
"no_copy": 1,
"options": "APRSL",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 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": "",
"fieldname": "kra_template",
"fieldtype": "Link",
@ -66,6 +97,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "kra_template",
"description": "",
"fieldname": "employee",
@ -95,6 +127,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "kra_template",
"fieldname": "employee_name",
"fieldtype": "Data",
@ -122,6 +155,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "kra_template",
"fieldname": "column_break0",
"fieldtype": "Column Break",
@ -148,6 +182,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Draft",
"depends_on": "kra_template",
"fieldname": "status",
@ -177,6 +212,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "kra_template",
"fieldname": "start_date",
"fieldtype": "Date",
@ -204,6 +240,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "kra_template",
"fieldname": "end_date",
"fieldtype": "Date",
@ -231,6 +268,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "kra_template",
"fieldname": "section_break0",
"fieldtype": "Section Break",
@ -258,6 +296,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "goals",
"fieldtype": "Table",
"hidden": 0,
@ -285,6 +324,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "calculate_total_score",
"fieldtype": "Button",
"hidden": 0,
@ -311,6 +351,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_score",
"fieldtype": "Float",
"hidden": 0,
@ -337,6 +378,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "kra_template",
"fieldname": "section_break1",
"fieldtype": "Section Break",
@ -361,6 +403,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Any other remarks, noteworthy effort that should go in the records.",
"fieldname": "remarks",
"fieldtype": "Text",
@ -386,6 +429,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "kra_template",
"fieldname": "other_details",
"fieldtype": "Section Break",
@ -411,6 +455,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@ -438,6 +483,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_17",
"fieldtype": "Column Break",
"hidden": 0,
@ -462,6 +508,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 1,
@ -491,13 +538,14 @@
"hide_toolbar": 0,
"icon": "icon-thumbs-up",
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-04-13 01:49:09.748819",
"modified": "2016-09-02 03:07:02.731236",
"modified_by": "Administrator",
"module": "HR",
"name": "Appraisal",
@ -564,6 +612,7 @@
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "status, employee, employee_name",

View File

@ -219,7 +219,11 @@ def get_employees_who_are_born_today():
and status = 'Active'""", {"date": today()}, as_dict=True)
def get_holiday_list_for_employee(employee, raise_exception=True):
holiday_list, company = frappe.db.get_value("Employee", employee, ["holiday_list", "company"])
if employee:
holiday_list, company = frappe.db.get_value("Employee", employee, ["holiday_list", "company"])
else:
holiday_list=''
company=frappe.db.get_value("Global Defaults", None, "default_company")
if not holiday_list:
holiday_list = frappe.db.get_value("Company", company, "default_holiday_list")

View File

@ -7,8 +7,6 @@ from __future__ import unicode_literals
import frappe
from frappe.website.website_generator import WebsiteGenerator
from frappe.utils import quoted
from frappe.utils.user import get_fullname_and_avatar
from frappe import _
class JobOpening(WebsiteGenerator):
@ -18,9 +16,6 @@ class JobOpening(WebsiteGenerator):
page_title_field = "job_title",
)
def make_route(self):
return 'jobs/' + self.scrub(self.job_title)
def get_context(self, context):
context.parents = [{'name': 'jobs', 'title': _('All Jobs') }]

View File

@ -2,21 +2,25 @@
"allow_copy": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "LAL/.#####",
"autoname": "naming_series:",
"beta": 0,
"creation": "2013-02-20 19:10:38",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
@ -36,10 +40,39 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Series",
"length": 0,
"no_copy": 1,
"options": "LAL/",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 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": "employee",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 1,
"label": "Employee",
@ -62,10 +95,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "employee_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 1,
"label": "Employee Name",
@ -85,10 +120,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
@ -108,10 +145,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Description",
@ -134,10 +173,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
@ -157,10 +198,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "leave_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 1,
"label": "Leave Type",
@ -183,10 +226,12 @@
"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_list_view": 0,
"label": "From Date",
@ -207,10 +252,12 @@
"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_list_view": 0,
"label": "To Date",
@ -231,10 +278,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_10",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
@ -254,10 +303,12 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "new_leaves_allocated",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "New Leaves Allocated",
@ -277,11 +328,13 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "carry_forward",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Add unused leaves from previous allocations",
@ -301,11 +354,13 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "carry_forward",
"fieldname": "carry_forwarded_leaves",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Unused leaves",
@ -325,10 +380,12 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_leaves_allocated",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Total Leaves Allocated",
@ -348,10 +405,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Amended From",
@ -375,13 +434,14 @@
"hide_toolbar": 0,
"icon": "icon-ok",
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-02-03 01:16:35.435720",
"modified": "2016-09-01 15:09:42.311292",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Allocation",
@ -428,10 +488,12 @@
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "employee,employee_name,leave_type,total_leaves_allocated",
"sort_field": "modified",
"sort_order": "DESC",
"timeline_field": "employee"
"timeline_field": "employee",
"track_seen": 0
}

View File

@ -3,22 +3,53 @@
"allow_import": 0,
"allow_rename": 0,
"autoname": "LAP/.#####",
"beta": 0,
"creation": "2013-02-20 11:18:11",
"custom": 0,
"description": "Apply / Approve Leaves",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Document",
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Series",
"length": 0,
"no_copy": 1,
"options": "LAP/",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 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,
"default": "Open",
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Status",
@ -39,10 +70,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_12",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
@ -62,10 +95,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "leave_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
"label": "Leave Type",
@ -86,10 +121,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "leave_balance",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Leave Balance Before Application",
@ -109,10 +146,12 @@
"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_list_view": 0,
"length": 0,
@ -132,10 +171,12 @@
"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_list_view": 1,
"label": "From Date",
@ -155,10 +196,12 @@
"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_list_view": 0,
"label": "To Date",
@ -178,10 +221,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "half_day",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Half Day",
@ -201,10 +246,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_leave_days",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Total Leave Days",
@ -224,10 +271,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
@ -248,10 +297,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Reason",
@ -271,10 +322,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_7",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
@ -294,10 +347,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "employee",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
"label": "Employee",
@ -318,10 +373,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "employee_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
"label": "Employee Name",
@ -341,10 +398,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_15",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
@ -364,11 +423,13 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "leave_approver",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Leave Approver",
@ -389,10 +450,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "leave_approver_name",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Leave Approver Name",
@ -413,10 +476,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sb10",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "",
@ -436,11 +501,13 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Today",
"fieldname": "posting_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Posting Date",
@ -460,11 +527,13 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "1",
"fieldname": "follow_via_email",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Follow via Email",
@ -484,10 +553,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_17",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
@ -506,10 +577,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Company",
@ -530,10 +603,12 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Letter Head",
@ -554,10 +629,12 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Amended From",
@ -579,13 +656,14 @@
"hide_toolbar": 0,
"icon": "icon-calendar",
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 3,
"modified": "2016-02-03 01:18:00.202671",
"modified": "2016-09-02 03:49:26.139593",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Application",
@ -735,11 +813,13 @@
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "employee,employee_name,leave_type,from_date,to_date,total_leave_days",
"sort_field": "modified",
"sort_order": "DESC",
"timeline_field": "employee",
"title_field": "employee_name"
"title_field": "employee_name",
"track_seen": 0
}

View File

@ -364,10 +364,11 @@ def get_events(start, end):
employee = frappe.db.get_value("Employee", {"user_id": frappe.session.user}, ["name", "company"],
as_dict=True)
if not employee:
return events
employee, company = employee.name, employee.company
if employee:
employee, company = employee.name, employee.company
else:
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")

View File

@ -8,14 +8,14 @@ frappe.query_reports["Employee Leave Balance"] = {
"label": __("From Date"),
"fieldtype": "Date",
"reqd": 1,
"default": frappe.datetime.year_start()
"default": frappe.defaults.get_default("year_start_date")
},
{
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"reqd": 1,
"default": frappe.datetime.year_end()
"default": frappe.defaults.get_default("year_end_date")
},
{
"fieldname":"company",
@ -26,4 +26,4 @@ frappe.query_reports["Employee Leave Balance"] = {
"default": frappe.defaults.get_user_default("Company")
}
]
}
}

View File

View File

@ -0,0 +1,3 @@
frappe.ready(function() {
// bind events here
})

View File

@ -0,0 +1,68 @@
{
"allow_comments": 1,
"allow_delete": 0,
"allow_edit": 1,
"allow_multiple": 1,
"creation": "2016-09-10 02:53:16.598314",
"doc_type": "Job Applicant",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"introduction_text": "",
"is_standard": 1,
"login_required": 0,
"modified": "2016-09-13 04:56:29.228762",
"modified_by": "Administrator",
"module": "HR",
"name": "job-application",
"owner": "Administrator",
"published": 1,
"route": "job_application",
"success_message": "Thank you for applying.",
"success_url": "/jobs",
"title": "Job Application",
"web_form_fields": [
{
"fieldname": "job_title",
"fieldtype": "Data",
"hidden": 0,
"label": "Job Opening",
"options": "",
"read_only": 1,
"reqd": 0
},
{
"fieldname": "applicant_name",
"fieldtype": "Data",
"hidden": 0,
"label": "Applicant Name",
"read_only": 0,
"reqd": 1
},
{
"fieldname": "email_id",
"fieldtype": "Data",
"hidden": 0,
"label": "Email Id",
"options": "Email",
"read_only": 0,
"reqd": 1
},
{
"fieldname": "cover_letter",
"fieldtype": "Text",
"hidden": 0,
"label": "Cover Letter",
"read_only": 0,
"reqd": 0
},
{
"fieldname": "resume_attachment",
"fieldtype": "Attach",
"hidden": 0,
"label": "Resume Attachment",
"read_only": 0,
"reqd": 0
}
]
}

View File

@ -0,0 +1,7 @@
from __future__ import unicode_literals
import frappe
def get_context(context):
# do your magic here
pass

View File

@ -2,18 +2,20 @@
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "MS.#####",
"autoname": "naming_series:",
"beta": 0,
"creation": "2013-01-10 16:34:30",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Document",
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "customer_details",
"fieldtype": "Section Break",
"hidden": 0,
@ -40,6 +42,34 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Series",
"length": 0,
"no_copy": 1,
"options": "MS",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 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": "customer",
"fieldtype": "Link",
"hidden": 0,
@ -67,6 +97,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@ -91,6 +122,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Draft",
"fieldname": "status",
"fieldtype": "Select",
@ -119,6 +151,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "transaction_date",
"fieldtype": "Date",
"hidden": 0,
@ -145,6 +178,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "items_section",
"fieldtype": "Section Break",
"hidden": 0,
@ -171,6 +205,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@ -198,6 +233,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "schedule",
"fieldtype": "Section Break",
"hidden": 0,
@ -224,6 +260,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "generate_schedule",
"fieldtype": "Button",
"hidden": 0,
@ -249,6 +286,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "schedules",
"fieldtype": "Table",
"hidden": 0,
@ -276,6 +314,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "contact_info",
"fieldtype": "Section Break",
"hidden": 0,
@ -300,6 +339,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
"fieldname": "customer_name",
"fieldtype": "Data",
@ -327,6 +367,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
"fieldname": "contact_person",
"fieldtype": "Link",
@ -353,6 +394,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
"fieldname": "contact_mobile",
"fieldtype": "Data",
@ -378,6 +420,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
"fieldname": "contact_email",
"fieldtype": "Data",
@ -403,6 +446,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "contact_display",
"fieldtype": "Small Text",
"hidden": 1,
@ -427,6 +471,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_17",
"fieldtype": "Column Break",
"hidden": 0,
@ -450,6 +495,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
"fieldname": "customer_address",
"fieldtype": "Link",
@ -476,6 +522,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "address_display",
"fieldtype": "Small Text",
"hidden": 1,
@ -500,6 +547,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
"description": "",
"fieldname": "territory",
@ -529,6 +577,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
"description": "",
"fieldname": "customer_group",
@ -556,6 +605,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@ -583,6 +633,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@ -616,7 +667,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-06-29 12:56:00.801674",
"modified": "2016-09-02 04:05:12.265769",
"modified_by": "Administrator",
"module": "Maintenance",
"name": "Maintenance Schedule",

View File

@ -58,7 +58,7 @@ class MaintenanceSchedule(TransactionBase):
if no_email_sp:
frappe.msgprint(
frappe._("Setting Events to {0}, since the Employee attached to the below Sales Persons does not have a User ID{1}").format(
self.owner, "<br>"+no_email_sp.join("<br>")
self.owner, "<br>" + "<br>".join(no_email_sp)
))
scheduled_date = frappe.db.sql("""select scheduled_date from
@ -187,14 +187,17 @@ class MaintenanceSchedule(TransactionBase):
if not sr_details:
frappe.throw(_("Serial No {0} not found").format(serial_no))
if sr_details.warranty_expiry_date and sr_details.warranty_expiry_date>=amc_start_date:
throw(_("Serial No {0} is under warranty upto {1}").format(serial_no, sr_details.warranty_expiry_date))
if sr_details.warranty_expiry_date \
and getdate(sr_details.warranty_expiry_date) >= getdate(amc_start_date):
throw(_("Serial No {0} is under warranty upto {1}")
.format(serial_no, sr_details.warranty_expiry_date))
if sr_details.amc_expiry_date and sr_details.amc_expiry_date >= amc_start_date:
throw(_("Serial No {0} is under maintenance contract upto {1}").format(serial_no, sr_details.amc_start_date))
if sr_details.amc_expiry_date and getdate(sr_details.amc_expiry_date) >= getdate(amc_start_date):
throw(_("Serial No {0} is under maintenance contract upto {1}")
.format(serial_no, sr_details.amc_start_date))
if not sr_details.warehouse and sr_details.delivery_date and \
sr_details.delivery_date >= amc_start_date:
getdate(sr_details.delivery_date) >= getdate(amc_start_date):
throw(_("Maintenance start date can not be before delivery date for Serial No {0}")
.format(serial_no))

View File

@ -2,17 +2,20 @@
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "MV.#####",
"autoname": "naming_series:",
"beta": 0,
"creation": "2013-01-10 16:34:31",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Document",
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "customer_details",
"fieldtype": "Section Break",
"hidden": 0,
@ -39,6 +42,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@ -63,6 +67,34 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Series",
"length": 0,
"no_copy": 1,
"options": "MV",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 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": "customer",
"fieldtype": "Link",
"hidden": 0,
@ -90,6 +122,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"fieldname": "customer_name",
"fieldtype": "Data",
"hidden": 1,
@ -114,6 +147,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "address_display",
"fieldtype": "Small Text",
"hidden": 1,
@ -138,6 +172,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "contact_display",
"fieldtype": "Small Text",
"hidden": 1,
@ -162,6 +197,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "contact_mobile",
"fieldtype": "Data",
"hidden": 1,
@ -186,6 +222,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "contact_email",
"fieldtype": "Data",
"hidden": 1,
@ -210,6 +247,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@ -235,6 +273,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Today",
"fieldname": "mntc_date",
"fieldtype": "Date",
@ -262,6 +301,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "mntc_time",
"fieldtype": "Time",
"hidden": 0,
@ -288,6 +328,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "maintenance_details",
"fieldtype": "Section Break",
"hidden": 0,
@ -314,6 +355,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "completion_status",
"fieldtype": "Select",
"hidden": 0,
@ -341,6 +383,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_14",
"fieldtype": "Column Break",
"hidden": 0,
@ -364,6 +407,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Unscheduled",
"fieldname": "maintenance_type",
"fieldtype": "Select",
@ -392,6 +436,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break0",
"fieldtype": "Section Break",
"hidden": 0,
@ -417,6 +462,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "purposes",
"fieldtype": "Table",
"hidden": 0,
@ -444,6 +490,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@ -470,6 +517,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "customer_feedback",
"fieldtype": "Small Text",
"hidden": 0,
@ -496,6 +544,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "col_break3",
"fieldtype": "Column Break",
"hidden": 0,
@ -519,6 +568,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Draft",
"fieldname": "status",
"fieldtype": "Data",
@ -547,6 +597,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@ -575,6 +626,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@ -602,6 +654,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
"fieldname": "contact_info_section",
"fieldtype": "Section Break",
@ -628,6 +681,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "customer_address",
"fieldtype": "Link",
"hidden": 0,
@ -653,6 +707,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "contact_person",
"fieldtype": "Link",
"hidden": 0,
@ -678,6 +733,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "col_break4",
"fieldtype": "Column Break",
"hidden": 0,
@ -701,6 +757,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "territory",
"fieldtype": "Link",
@ -727,6 +784,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "customer_group",
"fieldtype": "Link",
@ -761,7 +819,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-06-29 12:55:51.677519",
"modified": "2016-09-02 04:04:32.658556",
"modified_by": "Administrator",
"module": "Maintenance",
"name": "Maintenance Visit",

View File

@ -657,7 +657,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Item Desription",
"label": "Item Description",
"length": 0,
"no_copy": 0,
"permlevel": 0,

View File

@ -478,10 +478,12 @@ def make_stock_entry(production_order_id, purpose, qty=None):
if production_order.source_warehouse:
stock_entry.from_warehouse = production_order.source_warehouse
stock_entry.to_warehouse = production_order.wip_warehouse
stock_entry.project = production_order.project
else:
stock_entry.from_warehouse = production_order.wip_warehouse
stock_entry.to_warehouse = production_order.fg_warehouse
additional_costs = get_additional_costs(production_order, fg_qty=stock_entry.fg_completed_qty)
stock_entry.project = frappe.db.get_value("Stock Entry",{"production_order": production_order_id,"purpose": "Material Transfer for Manufacture"}, "project")
stock_entry.set("additional_costs", additional_costs)
stock_entry.get_items()

View File

@ -698,6 +698,32 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"description": "If checked, Will include non-stock items in the Material Requests.",
"fieldname": "create_material_requests_non_stock_request",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Include non-stock items",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -823,4 +849,4 @@
"read_only_onload": 0,
"sort_order": "ASC",
"track_seen": 0
}
}

View File

@ -249,6 +249,7 @@ class ProductionPlanningTool(Document):
"wip_warehouse" : "",
"fg_warehouse" : d.warehouse,
"status" : "Draft",
"project" : frappe.db.get_value("Sales Order", d.sales_order, "project")
}
""" Club similar BOM and item for processing in case of Sales Orders """
@ -306,7 +307,7 @@ class ProductionPlanningTool(Document):
self.get_raw_materials(bom_dict)
return self.get_csv()
def get_raw_materials(self, bom_dict):
def get_raw_materials(self, bom_dict,non_stock_item=0):
""" Get raw materials considering sub-assembly items
{
"item_code": [qty_required, description, stock_uom, min_order_qty]
@ -325,7 +326,7 @@ class ProductionPlanningTool(Document):
from `tabBOM Explosion Item` fb, `tabBOM` bom, `tabItem` item
where bom.name = fb.parent and item.name = fb.item_code
and (item.is_sub_contracted_item = 0 or ifnull(item.default_bom, "")="")
and item.is_stock_item = 1
""" + ("and item.is_stock_item = 1","")[non_stock_item] + """
and fb.docstatus<2 and bom.name=%(bom)s
group by fb.item_code, fb.stock_uom""", {"bom":bom}, as_dict=1):
bom_wise_item_details.setdefault(d.item_code, d)
@ -333,7 +334,7 @@ class ProductionPlanningTool(Document):
# Get all raw materials considering SA items as raw materials,
# so no childs of SA items
bom_wise_item_details = self.get_subitems(bom_wise_item_details, bom,1, \
self.use_multi_level_bom,self.only_raw_materials, self.include_subcontracted)
self.use_multi_level_bom,self.only_raw_materials, self.include_subcontracted,non_stock_item)
for item, item_details in bom_wise_item_details.items():
for so_qty in so_wise_qty:
@ -342,14 +343,14 @@ class ProductionPlanningTool(Document):
self.make_items_dict(item_list)
def get_subitems(self,bom_wise_item_details, bom, parent_qty, include_sublevel, only_raw, supply_subs):
def get_subitems(self,bom_wise_item_details, bom, parent_qty, include_sublevel, only_raw, supply_subs,non_stock_item=0):
for d in frappe.db.sql("""select bom_item.item_code, default_material_request_type,
ifnull(%(parent_qty)s * sum(bom_item.qty/ifnull(bom.quantity, 1)), 0) as qty,
item.is_sub_contracted_item as is_sub_contracted, item.default_bom as default_bom
from `tabBOM Item` bom_item, `tabBOM` bom, tabItem item
where bom.name = bom_item.parent and bom.name = %(bom)s and bom_item.docstatus < 2
and bom_item.item_code = item.name
and item.is_stock_item = 1
""" + ("and item.is_stock_item = 1","")[non_stock_item] + """
group by bom_item.item_code""", {"bom": bom, "parent_qty": parent_qty}, as_dict=1):
if (d.default_material_request_type == "Purchase" and not (d.is_sub_contracted \
and only_raw and include_sublevel)) or (d.default_material_request_type == \
@ -398,7 +399,7 @@ class ProductionPlanningTool(Document):
frappe.throw(_("Please enter Warehouse for which Material Request will be raised"))
bom_dict = self.get_so_wise_planned_qty()
self.get_raw_materials(bom_dict)
self.get_raw_materials(bom_dict,self.create_material_requests_non_stock_request)
if self.item_dict:
self.create_material_request()

View File

@ -295,7 +295,8 @@ erpnext.patches.v7_0.rename_prevdoc_fields
erpnext.patches.v7_0.rename_time_sheet_doctype
execute:frappe.delete_doc_if_exists("Report", "Customers Not Buying Since Long Time")
erpnext.patches.v7_0.make_is_group_fieldtype_as_check
execute:frappe.reload_doc('projects', 'doctype', 'timesheet', force=True) #2016-08-23
execute:frappe.reload_doc('projects', 'doctype', 'timesheet') #2016-09-12
erpnext.patches.v7_1.rename_field_timesheet
execute:frappe.delete_doc_if_exists("Report", "Employee Holiday Attendance")
execute:frappe.delete_doc_if_exists("DocType", "Payment Tool")
execute:frappe.delete_doc_if_exists("DocType", "Payment Tool Detail")
@ -322,3 +323,8 @@ erpnext.patches.v7_0.repost_gle_for_pos_sales_return
erpnext.patches.v7_0.update_missing_employee_in_timesheet
erpnext.patches.v7_0.update_status_for_timesheet
erpnext.patches.v7_0.set_party_name_in_payment_entry
erpnext.patches.v7_1.set_student_guardian
erpnext.patches.v7_0.update_conversion_factor_in_supplier_quotation_item
erpnext.patches.v7_1.move_sales_invoice_from_parent_to_child_timesheet
execute:frappe.db.sql("update `tabTimesheet` ts, `tabEmployee` emp set ts.employee_name = emp.employee_name where emp.name = ts.employee and ts.employee_name is null and ts.employee is not null")
erpnext.patches.v7_1.update_lead_source

View File

@ -4,8 +4,10 @@ from erpnext.manufacturing.doctype.production_order.production_order \
def execute():
frappe.reload_doc('projects', 'doctype', 'timesheet')
if not frappe.db.table_exists("Time Log"):
return
for data in frappe.get_all('Time Log', fields=["*"], filters = [["docstatus", "<", "2"]]):
for data in frappe.db.sql("select * from `tabTime Log` where docstatus < 2", as_dict=1):
if data.task:
company = frappe.db.get_value("Task", data.task, "company")
elif data.production_order:

View File

@ -4,17 +4,35 @@ import frappe
def execute():
frappe.reload_doc('accounts', 'doctype', 'sales_invoice_timesheet')
frappe.reload_doc('accounts', 'doctype', 'sales_invoice_payment')
for data in frappe.db.sql("""select name, mode_of_payment, cash_bank_account, paid_amount from
`tabSales Invoice` where is_pos = 1 and docstatus < 2 and cash_bank_account is not null""", as_dict=1):
frappe.reload_doc('accounts', 'doctype', 'mode_of_payment')
count = 0
for data in frappe.db.sql("""select name, mode_of_payment, cash_bank_account, paid_amount, company
from `tabSales Invoice` si
where si.is_pos = 1 and si.docstatus < 2
and si.cash_bank_account is not null and si.cash_bank_account != ''
and not exists(select name from `tabSales Invoice Payment` where parent=si.name)""", as_dict=1):
if not data.mode_of_payment and not frappe.db.exists("Mode of Payment", "Cash"):
mop = frappe.new_doc("Mode of Payment")
mop.mode_of_payment = "Cash"
mop.type = "Cash"
mop.save()
si_doc = frappe.get_doc('Sales Invoice', data.name)
si_doc.append('payments', {
row = si_doc.append('payments', {
'mode_of_payment': data.mode_of_payment or 'Cash',
'account': data.cash_bank_account,
'type': frappe.db.get_value('Mode of Payment', data.mode_of_payment, 'type') or 'Cash',
'amount': data.paid_amount
})
row.db_update()
si_doc.set_paid_amount()
si_doc.flags.ignore_validate_update_after_submit = True
si_doc.save()
si_doc.db_set("paid_amount", si_doc.paid_amount, update_modified = False)
si_doc.db_set("base_paid_amount", si_doc.base_paid_amount, update_modified = False)
count +=1
if count % 200 == 0:
frappe.db.commit()

View File

@ -3,12 +3,12 @@ import frappe
def execute():
frappe.reload_doc('accounts', 'doctype', 'sales_invoice')
frappe.reload_doc('accounts', 'doctype', 'sales_invoice_payment')
for time_sheet in frappe.db.sql(""" select sales_invoice, name, total_billing_amount from `tabTimesheet`
for time_sheet in frappe.db.sql(""" select sales_invoice, name, total_billable_amount from `tabTimesheet`
where sales_invoice is not null and docstatus < 2""", as_dict=True):
si_doc = frappe.get_doc('Sales Invoice', time_sheet.sales_invoice)
ts = si_doc.append('timesheets',{})
ts.time_sheet = time_sheet.name
ts.billing_amount = time_sheet.total_billing_amount
si_doc.update_time_sheet(time_sheet.sales_invoice)
si_doc.flags.ignore_validate_update_after_submit = True
si_doc.save()
ts.billing_amount = time_sheet.total_billable_amount
ts.db_update()
si_doc.calculate_billing_amount_from_timesheet()
si_doc.db_set("total_billing_amount", si_doc.total_billing_amount, update_modified = False)

View File

@ -1,9 +1,10 @@
import frappe
def execute():
for doctype in ['Time Log Batch', 'Time Log Batch Detail', 'Time Log']:
frappe.delete_doc('DocType', doctype)
if frappe.db.table_exists("Time Log"):
frappe.db.sql("""delete from `tabDocType`
where name in('Time Log Batch', 'Time Log Batch Detail', 'Time Log')""")
report = "Daily Time Log Summary"
if frappe.db.exists("Report", report):
frappe.delete_doc('Report', report)

View File

@ -9,7 +9,8 @@ def execute():
return
for expense_claim_type in frappe.get_all("Expense Claim Type", fields=["name", "default_account"]):
if expense_claim_type.default_account:
if expense_claim_type.default_account \
and frappe.db.exists("Account", expense_claim_type.default_account):
doc = frappe.get_doc("Expense Claim Type", expense_claim_type.name)
doc.append("accounts", {
"company": frappe.db.get_value("Account", expense_claim_type.default_account, "company"),

View File

@ -0,0 +1,19 @@
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc('buying', 'doctype', 'supplier_quotation_item')
frappe.db.sql("""update
`tabSupplier Quotation Item` as sqi_t,
(select sqi.item_code as item_code, sqi.uom as uom, ucd.conversion_factor as conversion_factor
from `tabSupplier Quotation Item` sqi left join `tabUOM Conversion Detail` ucd
on ucd.uom = sqi.uom and sqi.item_code = ucd.parent) as conversion_data,
`tabItem` as item
set
sqi_t.conversion_factor= ifnull(conversion_data.conversion_factor, 1),
sqi_t.stock_qty = (ifnull(conversion_data.conversion_factor, 1) * sqi_t.qty),
sqi_t.stock_uom = item.stock_uom
where
sqi_t.item_code = conversion_data.item_code and
sqi_t.uom = conversion_data.uom and sqi_t.item_code = item.name""")

View File

@ -0,0 +1,20 @@
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc('projects', 'doctype', 'timesheet_detail')
frappe.reload_doc('accounts', 'doctype', 'sales_invoice_timesheet')
frappe.db.sql(""" update
`tabTimesheet` as ts,
(select
sum(billing_amount) as billing_amount, sum(billing_hours) as billing_hours, time_sheet
from `tabSales Invoice Timesheet` where docstatus = 1 group by time_sheet
) as sit
set
ts.total_billed_amount = sit.billing_amount, ts.total_billed_hours = sit.billing_hours,
ts.per_billed = ((sit.billing_amount * 100)/ts.total_billable_amount)
where ts.name = sit.time_sheet and ts.docstatus = 1""")
frappe.db.sql(""" update `tabTimesheet Detail` tsd, `tabTimesheet` ts set tsd.sales_invoice = ts.sales_invoice
where tsd.parent = ts.name and ts.sales_invoice is not null""")

View File

@ -0,0 +1,11 @@
from __future__ import unicode_literals
import frappe
from frappe.model.utils.rename_field import rename_field
def execute():
doctype = 'Timesheet'
fields_dict = {'total_billing_amount': 'total_billable_amount', 'total_billing_hours': 'total_billable_hours'}
for old_fieldname, new_fieldname in fields_dict.items():
if old_fieldname in frappe.db.get_table_columns(doctype):
rename_field(doctype, old_fieldname, new_fieldname)

View File

@ -0,0 +1,16 @@
import frappe
def execute():
if frappe.db.exists("DocType", "Guardian"):
frappe.reload_doc("schools", "doctype", "student")
frappe.reload_doc("schools", "doctype", "student_guardian")
frappe.reload_doc("schools", "doctype", "student_sibling")
if "student" not in frappe.db.get_table_columns("Guardian"):
return
guardian = frappe.get_all("Guardian", fields=["name", "student"])
for d in guardian:
if d.student:
student = frappe.get_doc("Student", d.student)
if student:
student.append("guardians", {"guardian": d.name})
student.save()

View File

@ -0,0 +1,25 @@
import frappe
from frappe import _
def execute():
from erpnext.setup.setup_wizard.install_fixtures import default_lead_sources
frappe.reload_doc('selling', 'doctype', 'lead_source')
frappe.local.lang = frappe.db.get_default("lang") or 'en'
for s in default_lead_sources:
frappe.get_doc(dict(doctype='Lead Source', source_name=_(s))).insert()
# get lead sources in existing forms (customized)
# and create a document if not created
for d in ['Lead', 'Opportunity', 'Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice']:
sources = frappe.db.sql_list('select distinct source from `tab{0}`'.format(d))
for s in sources:
if s and s not in default_lead_sources:
frappe.get_doc(dict(doctype='Lead Source', source_name=s)).insert()
# remove customization for source
for p in frappe.get_all('Property Setter', {'doc_type':d, 'field_name':'source', 'property':'options'}):
frappe.delete_doc('Property Setter', p.name)

View File

@ -5,10 +5,10 @@ def execute():
frappe.reload_doc('projects', 'doctype', 'timesheet_detail')
frappe.reload_doc('accounts', 'doctype', 'sales_invoice_timesheet')
frappe.db.sql("""update tabTimesheet set total_billing_hours=total_hours
where total_billing_amount>0 and docstatus = 1""")
frappe.db.sql("""update tabTimesheet set total_billable_hours=total_hours
where total_billable_amount>0 and docstatus = 1""")
frappe.db.sql("""update `tabTimesheet Detail` set billing_hours=hours where docstatus < 2""")
frappe.db.sql(""" update `tabSales Invoice Timesheet` set billing_hours = (select total_billing_hours from `tabTimesheet`
frappe.db.sql(""" update `tabSales Invoice Timesheet` set billing_hours = (select total_billable_hours from `tabTimesheet`
where name = time_sheet) where time_sheet is not null""")

View File

@ -78,7 +78,7 @@ frappe.ui.form.on("Project", {
section.on('click', '.time-sheet-link', function() {
var activity_type = $(this).attr('data-activity_type');
frappe.set_route('List', 'Timesheet',
{'activity_type': activity_type, 'project': frm.doc.name});
{'activity_type': activity_type, 'project': frm.doc.name, 'status': ["!=", "Cancelled"]});
});
}
}

View File

@ -9,20 +9,22 @@ import datetime
from frappe.utils import now_datetime, nowdate
from erpnext.projects.doctype.timesheet.timesheet import OverlapError
from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_sales_invoice
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
class TestTimesheet(unittest.TestCase):
def test_timesheet_billing_amount(self):
salary_structure = make_salary_structure("_T-Employee-0001")
timesheet = make_timesheet("_T-Employee-0001", True)
timesheet = make_timesheet("_T-Employee-0001", simulate = True, billable=1)
self.assertEquals(timesheet.total_hours, 2)
self.assertEquals(timesheet.total_billing_hours, 2)
self.assertEquals(timesheet.total_billable_hours, 2)
self.assertEquals(timesheet.time_logs[0].billing_rate, 50)
self.assertEquals(timesheet.time_logs[0].billing_amount, 100)
self.assertEquals(timesheet.total_billable_amount, 100)
def test_salary_slip_from_timesheet(self):
salary_structure = make_salary_structure("_T-Employee-0001")
timesheet = make_timesheet("_T-Employee-0001", simulate = True)
timesheet = make_timesheet("_T-Employee-0001", simulate = True, billable=1)
salary_slip = make_salary_slip(timesheet.name)
salary_slip.submit()
@ -51,11 +53,20 @@ class TestTimesheet(unittest.TestCase):
item.rate = 100
sales_invoice.submit()
timesheet = frappe.get_doc('Timesheet', timesheet.name)
self.assertEquals(sales_invoice.total_billing_amount, 100)
self.assertEquals(timesheet.status, 'Billed')
def test_timesheet_billing_based_on_project(self):
timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=1, project = '_Test Project', company='_Test Company')
sales_invoice = create_sales_invoice(do_not_save=True)
sales_invoice.project = '_Test Project'
sales_invoice.submit()
ts = frappe.get_doc('Timesheet', timesheet.name)
self.assertEquals(ts.per_billed, 100)
self.assertEquals(ts.time_logs[0].sales_invoice, sales_invoice.name)
def make_salary_structure(employee):
name = frappe.db.get_value('Salary Structure Employee', {'employee': employee}, 'parent')
if name:
@ -93,7 +104,7 @@ def make_salary_structure(employee):
return salary_structure
def make_timesheet(employee, simulate=False, billable = 0, activity_type="_Test Activity Type", project=None, task=None):
def make_timesheet(employee, simulate=False, billable = 0, activity_type="_Test Activity Type", project=None, task=None, company=None):
update_activity_type(activity_type)
timesheet = frappe.new_doc("Timesheet")
timesheet.employee = employee
@ -105,6 +116,7 @@ def make_timesheet(employee, simulate=False, billable = 0, activity_type="_Test
timesheet_detail.to_time = timesheet_detail.from_time + datetime.timedelta(hours= timesheet_detail.hours)
timesheet_detail.project = project
timesheet_detail.task = task
timesheet_detail.company = company or '_Test Company'
for data in timesheet.get('time_logs'):
if simulate:

View File

@ -21,6 +21,14 @@ frappe.ui.form.on("Timesheet", {
}
}
}
frm.fields_dict['time_logs'].grid.get_field('project').get_query = function() {
return{
filters: {
'company': frm.doc.company
}
}
}
},
onload: function(frm){
@ -31,7 +39,7 @@ frappe.ui.form.on("Timesheet", {
refresh: function(frm) {
if(frm.doc.docstatus==1) {
if(!frm.doc.sales_invoice && frm.doc.total_billing_amount > 0){
if(frm.doc.per_billed < 100){
frm.add_custom_button(__("Make Sales Invoice"), function() { frm.trigger("make_invoice") },
"icon-file-alt");
}
@ -42,8 +50,9 @@ frappe.ui.form.on("Timesheet", {
}
}
if(frm.doc.sales_invoice) {
if(frm.doc.per_billed > 0) {
cur_frm.fields_dict["time_logs"].grid.toggle_enable("billing_hours", false);
cur_frm.fields_dict["time_logs"].grid.toggle_enable("billable", false);
}
},
@ -150,19 +159,22 @@ var calculate_time_and_amount = function(frm) {
var tl = frm.doc.time_logs || [];
total_working_hr = 0;
total_billing_hr = 0;
total_billing_amount = 0;
total_billable_amount = 0;
total_costing_amount = 0;
for(var i=0; i<tl.length; i++) {
if (tl[i].hours) {
total_working_hr += tl[i].hours;
total_billing_hr += tl[i].billing_hours;
total_billing_amount += tl[i].billing_amount;
total_billable_amount += tl[i].billing_amount;
total_costing_amount += tl[i].costing_amount;
if(tl[i].billable){
total_billing_hr += tl[i].billing_hours;
}
}
}
cur_frm.set_value("total_billing_hours", total_billing_hr);
cur_frm.set_value("total_billable_hours", total_billing_hr);
cur_frm.set_value("total_hours", total_working_hr);
cur_frm.set_value("total_billing_amount", total_billing_amount);
cur_frm.set_value("total_billable_amount", total_billable_amount);
cur_frm.set_value("total_costing_amount", total_costing_amount);
}

View File

@ -470,8 +470,8 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "working_hours",
"columns": 0,
"fieldname": "working_hours",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
@ -522,6 +522,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "billing_details",
"fieldtype": "Section Break",
"hidden": 0,
@ -544,24 +545,77 @@
"unique": 0
},
{
"allow_on_submit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"fieldname": "total_billing_hours",
"columns": 0,
"fieldname": "total_billable_hours",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Total Billing Hours",
"label": "Total Billable Hours",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_billed_hours",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Total Billed Hours",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_costing_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Total Costing Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -601,14 +655,14 @@
"default": "0",
"depends_on": "",
"description": "",
"fieldname": "total_billing_amount",
"fieldname": "total_billable_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Total Billing Amount",
"label": "Total Billable Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -623,23 +677,49 @@
"unique": 0
},
{
"allow_on_submit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_costing_amount",
"fieldname": "total_billed_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Total Costing Amount",
"label": "Total Billed Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "per_billed",
"fieldtype": "Percent",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "% Amount Billed",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
@ -737,7 +817,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-09-01 11:33:38.110421",
"modified": "2016-09-12 13:19:22.298036",
"modified_by": "Administrator",
"module": "Projects",
"name": "Timesheet",

View File

@ -8,6 +8,7 @@ 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.model.document import Document
from frappe.model.mapper import get_mapped_doc
@ -20,26 +21,41 @@ class OverProductionLoggedError(frappe.ValidationError): pass
class Timesheet(Document):
def validate(self):
self.set_employee_name()
self.set_status()
self.validate_dates()
self.validate_time_logs()
self.update_cost()
self.calculate_total_amounts()
self.calculate_percentage_billed()
def set_employee_name(self):
if self.employee and not self.employee_name:
self.employee_name = frappe.db.get_value('Employee', self.employee, 'employee_name')
def calculate_total_amounts(self):
self.total_hours = 0.0
self.total_billing_hours = 0.0
self.total_billing_amount = 0.0
self.total_billable_hours = 0.0
self.total_billed_hours = 0.0
self.total_billable_amount = 0.0
self.total_costing_amount = 0.0
self.total_billed_amount = 0.0
for d in self.get("time_logs"):
self.update_billing_hours(d)
self.total_hours += flt(d.hours)
self.total_billing_hours += flt(d.billing_hours)
if d.billable:
self.total_billing_amount += flt(d.billing_amount)
if d.billable:
self.total_billable_hours += flt(d.billing_hours)
self.total_billable_amount += flt(d.billing_amount)
self.total_costing_amount += flt(d.costing_amount)
self.total_billed_amount += flt(d.billing_amount) if d.sales_invoice else 0.0
self.total_billed_hours += flt(d.billing_hours) if d.sales_invoice else 0.0
def calculate_percentage_billed(self):
self.per_billed = 0
if self.total_billed_amount > 0 and self.total_billable_amount > 0:
self.per_billed = (self.total_billed_amount * 100) / self.total_billable_amount
def update_billing_hours(self, args):
if cint(args.billing_hours) == 0:
@ -52,7 +68,7 @@ class Timesheet(Document):
"2": "Cancelled"
}[str(self.docstatus or 0)]
if self.sales_invoice:
if self.per_billed == 100:
self.status = "Billed"
if self.salary_slip:
@ -236,31 +252,70 @@ class Timesheet(Document):
def update_cost(self):
for data in self.time_logs:
if data.activity_type and (not data.billing_amount or not data.costing_amount):
if data.activity_type and data.billable:
rate = get_activity_cost(self.employee, data.activity_type)
hours = data.billing_hours or 0
if rate:
data.billing_rate = flt(rate.get('billing_rate'))
data.costing_rate = flt(rate.get('costing_rate'))
data.billing_rate = flt(rate.get('billing_rate')) if flt(data.billing_rate) == 0 else data.billing_rate
data.costing_rate = flt(rate.get('costing_rate')) if flt(data.costing_rate) == 0 else data.costing_rate
data.billing_amount = data.billing_rate * hours
data.costing_amount = data.costing_rate * hours
@frappe.whitelist()
def get_projectwise_timesheet_data(project, parent=None):
cond = ''
if parent:
cond = "and parent = %(parent)s"
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)
@frappe.whitelist()
def get_timesheet(doctype, txt, searchfield, start, page_len, filters):
if not filters: filters = {}
condition = ""
if filters.get("project"):
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
and tsd.parent LIKE %(txt)s {condition}
order by tsd.parent limit %(start)s, %(page_len)s"""
.format(condition=condition), {
"txt": "%%%s%%" % frappe.db.escape(txt),
"start": start, "page_len": page_len, 'project': filters.get("project")
})
@frappe.whitelist()
def get_timesheet_data(name, project):
if project and project!='':
data = get_projectwise_timesheet_data(project, name)
else:
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 {
'billing_hours': data[0].billing_hours,
'billing_amount': data[0].billing_amt,
'timesheet_detail': data[0].name if project and project!= '' else None
}
@frappe.whitelist()
def make_sales_invoice(source_name, target=None):
target = frappe.new_doc("Sales Invoice")
timesheet = frappe.get_doc('Timesheet', source_name)
target.append("timesheets", get_mapped_doc("Timesheet", source_name, {
"Timesheet": {
"doctype": "Sales Invoice Timesheet",
"field_map": {
"total_billing_amount": "billing_amount",
"total_billing_hours": "billing_hours",
"name": "time_sheet"
},
}
}))
target.run_method("calculate_billing_amount_from_timesheet")
target.append('timesheets', {
'time_sheet': timesheet.name,
'billing_hours': flt(timesheet.total_billable_hours) - flt(timesheet.total_billed_hours),
'billing_amount': flt(timesheet.total_billable_amount) - flt(timesheet.total_billed_amount)
})
target.run_method("calculate_billing_amount_for_timesheet")
return target
@ -300,7 +355,7 @@ def get_activity_cost(employee=None, activity_type=None):
["costing_rate", "billing_rate"], as_dict=True)
return rate[0] if rate else {}
@frappe.whitelist()
def get_events(start, end, filters=None):
"""Returns events for Gantt / Calendar view rendering.
@ -311,10 +366,14 @@ def get_events(start, end, filters=None):
filters = json.loads(filters)
conditions = get_conditions(filters)
return frappe.db.sql("""select `tabTimesheet Detail`.name as name, `tabTimesheet Detail`.parent as parent,
from_time, hours, activity_type, project, to_time from `tabTimesheet Detail`,
`tabTimesheet` where `tabTimesheet Detail`.parent = `tabTimesheet`.name and `tabTimesheet`.docstatus < 2 and
(from_time between %(start)s and %(end)s) {conditions}""".format(conditions=conditions),
return frappe.db.sql("""select `tabTimesheet Detail`.name as name,
`tabTimesheet Detail`.docstatus as status, `tabTimesheet Detail`.parent as parent,
from_time, hours, activity_type, project, to_time
from `tabTimesheet Detail`, `tabTimesheet`
where `tabTimesheet Detail`.parent = `tabTimesheet`.name
and `tabTimesheet`.docstatus < 2
and (from_time between %(start)s and %(end)s) {conditions} {match_cond}
""".format(conditions=conditions, match_cond = get_match_cond('Timesheet')),
{
"start": start,
"end": end

View File

@ -8,6 +8,11 @@ frappe.views.calendar["Timesheet"] = {
"allDay": "allDay",
"child_name": "name"
},
style_map: {
"0": "info",
"1": "standard",
"2": "danger"
},
gantt: true,
filters: [
{

View File

@ -10,33 +10,6 @@
"document_type": "Document",
"editable_grid": 1,
"fields": [
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 1,
"depends_on": "",
"fieldname": "billable",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Bill",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -165,192 +138,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "billable",
"fieldname": "section_break_11",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"fieldname": "billing_hours",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Billing Hours",
"length": 0,
"no_copy": 0,
"permlevel": 1,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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,
"depends_on": "",
"fieldname": "billing_rate",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Billing Rate",
"length": 0,
"no_copy": 0,
"permlevel": 1,
"precision": "2",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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": "costing_rate",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Costing Rate",
"length": 0,
"no_copy": 0,
"permlevel": 1,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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_14",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"depends_on": "",
"description": "",
"fieldname": "billing_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Billing Amount",
"length": 0,
"no_copy": 0,
"permlevel": 1,
"precision": "2",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"description": "",
"fieldname": "costing_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Costing Amount",
"length": 0,
"no_copy": 0,
"permlevel": 1,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -403,55 +190,28 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 3,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Project",
"length": 0,
"no_copy": 0,
"options": "Project",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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,
"depends_on": "",
"fieldname": "task",
"depends_on": "eval:parent.production_order",
"fieldname": "workstation",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Task",
"label": "Workstation",
"length": 0,
"no_copy": 0,
"options": "Task",
"options": "Workstation",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -483,34 +243,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:parent.production_order",
"fieldname": "workstation",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Workstation",
"length": 0,
"no_copy": 0,
"options": "Workstation",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -565,6 +297,429 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "project_details",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 3,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Project",
"length": 0,
"no_copy": 0,
"options": "Project",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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_2",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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,
"depends_on": "",
"fieldname": "task",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Task",
"length": 0,
"no_copy": 0,
"options": "Task",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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_6",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 1,
"depends_on": "",
"fieldname": "billable",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Bill",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 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_8",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "billable",
"fieldname": "billing_hours",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Billing Hours",
"length": 0,
"no_copy": 0,
"permlevel": 1,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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,
"depends_on": "billable",
"fieldname": "section_break_11",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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,
"depends_on": "",
"fieldname": "billing_rate",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Billing Rate",
"length": 0,
"no_copy": 0,
"permlevel": 1,
"precision": "2",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"depends_on": "",
"description": "",
"fieldname": "billing_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Billing Amount",
"length": 0,
"no_copy": 0,
"permlevel": 1,
"precision": "2",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"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_14",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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": "costing_rate",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Costing Rate",
"length": 0,
"no_copy": 0,
"permlevel": 1,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"description": "",
"fieldname": "costing_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Costing Amount",
"length": 0,
"no_copy": 0,
"permlevel": 1,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"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": "reference",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Reference",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sales_invoice",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Sales Invoice",
"length": 0,
"no_copy": 1,
"options": "Sales Invoice",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"hide_heading": 0,
@ -577,7 +732,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-08-26 03:00:11.431794",
"modified": "2016-09-09 13:36:03.057513",
"modified_by": "Administrator",
"module": "Projects",
"name": "Timesheet Detail",

View File

@ -12,8 +12,9 @@ def execute(filters=None):
filters["from_time"] = "00:00:00"
filters["to_time"] = "24:00:00"
columns = [_("Timesheet") + ":Link/Timesheet:120", _("Employee") + "::150", _("From Datetime") + "::140",
_("To Datetime") + "::140", _("Hours") + "::70", _("Activity Type") + "::120", _("Task") + ":Link/Task:150",
columns = [_("Timesheet") + ":Link/Timesheet:120", _("Employee") + "::150", _("Employee Name") + "::150",
_("From Datetime") + "::140", _("To Datetime") + "::140", _("Hours") + "::70",
_("Activity Type") + "::120", _("Task") + ":Link/Task:150",
_("Project") + ":Link/Project:120", _("Status") + "::70"]
conditions = "ts.docstatus = 1"
@ -27,7 +28,8 @@ def execute(filters=None):
return columns, data
def get_data(conditions, filters):
time_sheet = frappe.db.sql(""" select ts.name, ts.employee, tsd.from_time, tsd.to_time, tsd.hours,
time_sheet = frappe.db.sql(""" select ts.name, ts.employee, ts.employee_name,
tsd.from_time, tsd.to_time, tsd.hours,
tsd.activity_type, tsd.task, tsd.project, ts.status from `tabTimesheet Detail` tsd,
`tabTimesheet` ts where ts.name = tsd.parent and %s order by ts.name"""%(conditions), filters, as_list=1)

View File

@ -45,11 +45,6 @@
.product-text {
padding: 15px 0px;
}
.product-label {
padding-bottom: 4px;
text-transform: uppercase;
font-size: 12px;
}
.product-search {
margin-bottom: 15px;
}

View File

@ -1,6 +1,7 @@
<div class="row list-row pos-invoice-list" invoice-name = "{{name}}">
<div class="col-xs-2">{%= sr %}</div>
<div class="col-xs-4">{%= customer %}</div>
<div class="col-xs-1">{%= sr %}</div>
<div class="col-xs-3">{%= customer %}</div>
<div class="col-xs-2 text-left"><span class="indicator {{data.indicator}}">{{ data.status }}</span></div>
<div class="col-xs-4 text-right">{%= grand_total %}</div>
<div class="col-xs-3 text-right">{%= paid_amount %}</div>
<div class="col-xs-3 text-right">{%= grand_total %}</div>
</div>

View File

@ -51,12 +51,6 @@
padding: 15px 0px;
}
.product-label {
padding-bottom: 4px;
text-transform: uppercase;
font-size: 12px;
}
.product-search {
margin-bottom: 15px;
}
@ -165,7 +159,7 @@
.cart-container {
margin: 50px 0px;
.checkout {
margin-bottom:15px;
}
@ -223,7 +217,7 @@
.cart-dropdown-container {
width: 400px;
padding: 15px;
.item-price {
display: block !important;
padding-bottom: 10px;
@ -232,12 +226,12 @@
.cart-item-header {
border-bottom: 1px solid #d1d8dd;
}
.cart-items-dropdown {
max-height: 350px;
overflow: auto;
overflow: auto;
}
.cart-items-dropdown .cart-dropdown {
display:block;
margin-top:15px;

View File

@ -103,13 +103,14 @@ def get_fee_components(fee_structure):
return fs
@frappe.whitelist()
def get_fee_schedule(program):
def get_fee_schedule(program, student_category=None):
"""Returns Fee Schedule.
:param program: Program.
:param student_category: Student Category
"""
fs = frappe.get_list("Program Fee", fields=["academic_term", "fee_structure", "due_date", "amount"] ,
filters={"parent": program}, order_by= "idx")
filters={"parent": program, "student_category": student_category }, order_by= "idx")
return fs
@frappe.whitelist()

View File

@ -15,6 +15,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "program",
"fieldtype": "Link",
"hidden": 0,
@ -43,6 +44,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@ -69,6 +71,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"hidden": 0,
@ -93,6 +96,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "academic_term",
"fieldtype": "Link",
"hidden": 0,
@ -122,6 +126,34 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "student_category",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Student Category",
"length": 0,
"no_copy": 0,
"options": "Student Category",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 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_4",
"fieldtype": "Section Break",
"hidden": 0,
@ -146,6 +178,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "components",
"fieldtype": "Table",
"hidden": 0,
@ -172,6 +205,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"hidden": 0,
@ -196,6 +230,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_amount",
"fieldtype": "Currency",
"hidden": 0,
@ -230,7 +265,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2016-07-25 08:44:07.886467",
"modified": "2016-09-05 06:54:22.360035",
"modified_by": "Administrator",
"module": "Schools",
"name": "Fee Structure",

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