mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 00:14:50 +00:00
@@ -5,12 +5,11 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import msgprint, _
|
from frappe import msgprint, _
|
||||||
from frappe.utils import getdate, add_days, add_years, cstr
|
from frappe.utils import getdate, add_days, add_years, cstr
|
||||||
from datetime import timedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class FiscalYear(Document):
|
class FiscalYear(Document):
|
||||||
|
|
||||||
def set_as_default(self):
|
def set_as_default(self):
|
||||||
frappe.db.set_value("Global Defaults", None, "current_fiscal_year", self.name)
|
frappe.db.set_value("Global Defaults", None, "current_fiscal_year", self.name)
|
||||||
frappe.get_doc("Global Defaults").on_update()
|
frappe.get_doc("Global Defaults").on_update()
|
||||||
@@ -24,18 +23,21 @@ class FiscalYear(Document):
|
|||||||
year_start_end_dates = frappe.db.sql("""select year_start_date, year_end_date
|
year_start_end_dates = frappe.db.sql("""select year_start_date, year_end_date
|
||||||
from `tabFiscal Year` where name=%s""", (self.name))
|
from `tabFiscal Year` where name=%s""", (self.name))
|
||||||
|
|
||||||
|
self.validate_dates()
|
||||||
|
|
||||||
if year_start_end_dates:
|
if year_start_end_dates:
|
||||||
if getdate(self.year_start_date) != year_start_end_dates[0][0] or getdate(self.year_end_date) != year_start_end_dates[0][1]:
|
if getdate(self.year_start_date) != year_start_end_dates[0][0] or getdate(self.year_end_date) != year_start_end_dates[0][1]:
|
||||||
frappe.throw(_("Cannot change Fiscal Year Start Date and Fiscal Year End Date once the Fiscal Year is saved."))
|
frappe.throw(_("Cannot change Fiscal Year Start Date and Fiscal Year End Date once the Fiscal Year is saved."))
|
||||||
|
|
||||||
def on_update(self):
|
def validate_dates(self):
|
||||||
# validate year start date and year end date
|
|
||||||
if getdate(self.year_start_date) > getdate(self.year_end_date):
|
if getdate(self.year_start_date) > getdate(self.year_end_date):
|
||||||
frappe.throw(_("Fiscal Year Start Date should not be greater than Fiscal Year End Date"))
|
frappe.throw(_("Fiscal Year Start Date should not be greater than Fiscal Year End Date"))
|
||||||
|
|
||||||
if (getdate(self.year_end_date) - getdate(self.year_start_date)).days > 366:
|
if (getdate(self.year_end_date) - getdate(self.year_start_date)).days > 366:
|
||||||
frappe.throw(_("Fiscal Year Start Date and Fiscal Year End Date cannot be more than a year apart."))
|
date = getdate(self.year_start_date) + relativedelta(years=1) - relativedelta(days=1)
|
||||||
|
self.year_end_date = date.strftime("%Y-%m-%d")
|
||||||
|
|
||||||
|
def on_update(self):
|
||||||
check_duplicate_fiscal_year(self)
|
check_duplicate_fiscal_year(self)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
@@ -3,6 +3,20 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import frappe
|
import frappe, unittest
|
||||||
|
|
||||||
|
test_records = frappe.get_test_records('Fiscal Year')
|
||||||
|
|
||||||
|
class TestFiscalYear(unittest.TestCase):
|
||||||
|
def test_extra_year(self):
|
||||||
|
if frappe.db.exists("Fiscal Year", "_Test Fiscal Year 2000"):
|
||||||
|
frappe.delete_doc("Fiscal Year", "_Test Fiscal Year 2000")
|
||||||
|
fy = frappe.get_doc({
|
||||||
|
"doctype": "Fiscal Year",
|
||||||
|
"year": "_Test Fiscal Year 2000",
|
||||||
|
"year_end_date": "2002-12-31",
|
||||||
|
"year_start_date": "2000-04-01"
|
||||||
|
})
|
||||||
|
fy.insert()
|
||||||
|
self.assertEquals(fy.year_end_date, '2001-03-31')
|
||||||
|
|
||||||
test_records = frappe.get_test_records('Fiscal Year')
|
|
||||||
@@ -33,6 +33,7 @@ class Lead(SellingController):
|
|||||||
})
|
})
|
||||||
|
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
self.check_email_id_is_unique()
|
||||||
|
|
||||||
if self.source == 'Campaign' and not self.campaign_name and session['user'] != 'Guest':
|
if self.source == 'Campaign' and not self.campaign_name and session['user'] != 'Guest':
|
||||||
frappe.throw(_("Campaign Name is required"))
|
frappe.throw(_("Campaign Name is required"))
|
||||||
@@ -45,7 +46,6 @@ class Lead(SellingController):
|
|||||||
self.lead_owner = None
|
self.lead_owner = None
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
self.check_email_id_is_unique()
|
|
||||||
self.add_calendar_event()
|
self.add_calendar_event()
|
||||||
|
|
||||||
def add_calendar_event(self, opts=None, force=False):
|
def add_calendar_event(self, opts=None, force=False):
|
||||||
@@ -62,9 +62,10 @@ class Lead(SellingController):
|
|||||||
# validate email is unique
|
# validate email is unique
|
||||||
email_list = frappe.db.sql("""select name from tabLead where email_id=%s""",
|
email_list = frappe.db.sql("""select name from tabLead where email_id=%s""",
|
||||||
self.email_id)
|
self.email_id)
|
||||||
|
email_list = [e[0] for e in email_list if e[0]!=self.name]
|
||||||
if len(email_list) > 1:
|
if len(email_list) > 1:
|
||||||
items = [e[0] for e in email_list if e[0]!=self.name]
|
frappe.throw(_("Email id must be unique, already exists for {0}").format(comma_and(email_list)),
|
||||||
frappe.throw(_("Email id must be unique, already exists for {0}").format(comma_and(items)), frappe.DuplicateEntryError)
|
frappe.DuplicateEntryError)
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
frappe.db.sql("""update `tabIssue` set lead='' where lead=%s""",
|
frappe.db.sql("""update `tabIssue` set lead='' where lead=%s""",
|
||||||
|
|||||||
@@ -92,12 +92,20 @@
|
|||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"fieldname": "title",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Title",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "Sales",
|
||||||
"fieldname": "enquiry_type",
|
"fieldname": "enquiry_type",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Opportunity Type",
|
"label": "Opportunity Type",
|
||||||
"oldfieldname": "enquiry_type",
|
"oldfieldname": "enquiry_type",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "\nSales\nMaintenance",
|
"options": "Sales\nMaintenance",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
@@ -118,6 +126,14 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"fieldname": "with_items",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "With Items",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "with_items",
|
||||||
"fieldname": "items_section",
|
"fieldname": "items_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "",
|
"label": "",
|
||||||
@@ -127,7 +143,7 @@
|
|||||||
"read_only": 0
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Items which do not exist in Item master can also be entered on customer's request",
|
"description": "",
|
||||||
"fieldname": "items",
|
"fieldname": "items",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Items",
|
"label": "Items",
|
||||||
@@ -391,7 +407,7 @@
|
|||||||
"icon": "icon-info-sign",
|
"icon": "icon-info-sign",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2015-02-23 02:19:39.853388",
|
"modified": "2015-04-02 22:03:52.841173",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Opportunity",
|
"name": "Opportunity",
|
||||||
@@ -432,5 +448,5 @@
|
|||||||
"search_fields": "status,transaction_date,customer,lead,enquiry_type,territory,company",
|
"search_fields": "status,transaction_date,customer,lead,enquiry_type,territory,company",
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "customer_name"
|
"title_field": "title"
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,23 @@ from frappe.model.mapper import get_mapped_doc
|
|||||||
from erpnext.utilities.transaction_base import TransactionBase
|
from erpnext.utilities.transaction_base import TransactionBase
|
||||||
|
|
||||||
class Opportunity(TransactionBase):
|
class Opportunity(TransactionBase):
|
||||||
|
def set_sender(self, email_id):
|
||||||
|
"""Set lead against new opportunity"""
|
||||||
|
lead_name = frappe.get_value("Lead", {"email_id": email_id})
|
||||||
|
if not lead_name:
|
||||||
|
lead = frappe.get_doc({
|
||||||
|
"doctype": "Lead",
|
||||||
|
"email_id": email_id,
|
||||||
|
"lead_name": email_id
|
||||||
|
})
|
||||||
|
lead.insert(ignore_permissions=True)
|
||||||
|
lead_name = lead.name
|
||||||
|
|
||||||
|
self.enquiry_from = "Lead"
|
||||||
|
self.lead = lead_name
|
||||||
|
|
||||||
|
def set_subject(self, subject):
|
||||||
|
self.title = subject
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self._prev = frappe._dict({
|
self._prev = frappe._dict({
|
||||||
@@ -28,6 +45,9 @@ class Opportunity(TransactionBase):
|
|||||||
self.validate_lead_cust()
|
self.validate_lead_cust()
|
||||||
self.validate_cust_name()
|
self.validate_cust_name()
|
||||||
|
|
||||||
|
if not self.title:
|
||||||
|
self.title = self.customer_name
|
||||||
|
|
||||||
from erpnext.accounts.utils import validate_fiscal_year
|
from erpnext.accounts.utils import validate_fiscal_year
|
||||||
validate_fiscal_year(self.transaction_date, self.fiscal_year, _("Opportunity Date"), self)
|
validate_fiscal_year(self.transaction_date, self.fiscal_year, _("Opportunity Date"), self)
|
||||||
|
|
||||||
@@ -118,7 +138,7 @@ class Opportunity(TransactionBase):
|
|||||||
|
|
||||||
def validate_item_details(self):
|
def validate_item_details(self):
|
||||||
if not self.get('items'):
|
if not self.get('items'):
|
||||||
frappe.throw(_("Items required"))
|
return
|
||||||
|
|
||||||
# set missing values
|
# set missing values
|
||||||
item_fields = ("item_name", "description", "item_group", "brand")
|
item_fields = ("item_name", "description", "item_group", "brand")
|
||||||
|
|||||||
0
erpnext/crm/doctype/opportunity_item/__init__.py
Normal file
0
erpnext/crm/doctype/opportunity_item/__init__.py
Normal file
@@ -133,9 +133,9 @@
|
|||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2015-02-23 02:09:55.105233",
|
"modified": "2015-04-02 22:04:26.867653",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "CRM",
|
||||||
"name": "Opportunity Item",
|
"name": "Opportunity Item",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": []
|
"permissions": []
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
# -*- coding: utf-8 -*-
|
||||||
# License: GNU General Public License v3. See license.txt
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class OpportunityItem(Document):
|
class OpportunityItem(Document):
|
||||||
pass
|
pass
|
||||||
@@ -25,7 +25,7 @@ on_logout = "erpnext.shopping_cart.utils.clear_cart_count"
|
|||||||
# website
|
# website
|
||||||
update_website_context = "erpnext.shopping_cart.utils.update_website_context"
|
update_website_context = "erpnext.shopping_cart.utils.update_website_context"
|
||||||
my_account_context = "erpnext.shopping_cart.utils.update_my_account_context"
|
my_account_context = "erpnext.shopping_cart.utils.update_my_account_context"
|
||||||
email_append_to = ["Lead", "Job Applicant", "Opportunity", "Issue", "Warranty Claim"]
|
email_append_to = ["Job Applicant", "Opportunity", "Issue"]
|
||||||
|
|
||||||
website_route_rules = [
|
website_route_rules = [
|
||||||
{"from_route": "/orders", "to_route": "Sales Order"},
|
{"from_route": "/orders", "to_route": "Sales Order"},
|
||||||
|
|||||||
@@ -135,4 +135,5 @@ erpnext.patches.v4_2.repost_sle_for_si_with_no_warehouse
|
|||||||
erpnext.patches.v5_0.newsletter
|
erpnext.patches.v5_0.newsletter
|
||||||
execute:frappe.delete_doc("DocType", "Chart of Accounts")
|
execute:frappe.delete_doc("DocType", "Chart of Accounts")
|
||||||
execute:frappe.delete_doc("DocType", "Style Settings")
|
execute:frappe.delete_doc("DocType", "Style Settings")
|
||||||
|
erpnext.patches.v5_0.update_opportunity
|
||||||
|
|
||||||
|
|||||||
14
erpnext/patches/v5_0/update_opportunity.py
Normal file
14
erpnext/patches/v5_0/update_opportunity.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doc('crm', 'doctype', 'opportunity')
|
||||||
|
frappe.reload_doc('crm', 'doctype', 'opportunity_item')
|
||||||
|
|
||||||
|
# all existing opportunities were with items
|
||||||
|
frappe.db.sql("update `tabDocType` set module = 'CRM' where name='Opportunity Item'")
|
||||||
|
frappe.db.sql("update tabOpportunity set with_items=1, title=customer_name")
|
||||||
|
frappe.db.sql("update `tabEmail Account` set append_to='Opportunity' where append_to='Lead'")
|
||||||
@@ -1 +0,0 @@
|
|||||||
Items considered in the parent Opportunity.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
@@ -151,7 +151,7 @@ def install(country=None):
|
|||||||
{"attribute_value": _("White"), "abbr": "WHI"}
|
{"attribute_value": _("White"), "abbr": "WHI"}
|
||||||
]},
|
]},
|
||||||
|
|
||||||
{'doctype': "Email Account", "email_id": "sales@example.com", "append_to": "Lead"},
|
{'doctype': "Email Account", "email_id": "sales@example.com", "append_to": "Opportunity"},
|
||||||
{'doctype': "Email Account", "email_id": "support@example.com", "append_to": "Issue"},
|
{'doctype': "Email Account", "email_id": "support@example.com", "append_to": "Issue"},
|
||||||
{'doctype': "Email Account", "email_id": "jobs@example.com", "append_to": "Job Applicant"}
|
{'doctype': "Email Account", "email_id": "jobs@example.com", "append_to": "Job Applicant"}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"label": "Raised By (Email)",
|
"label": "Raised By (Email)",
|
||||||
"oldfieldname": "raised_by",
|
"oldfieldname": "raised_by",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
|
"options": "Email",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
@@ -217,7 +218,7 @@
|
|||||||
],
|
],
|
||||||
"icon": "icon-ticket",
|
"icon": "icon-ticket",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"modified": "2015-02-05 05:11:39.362659",
|
"modified": "2015-04-02 22:06:02.684820",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Support",
|
"module": "Support",
|
||||||
"name": "Issue",
|
"name": "Issue",
|
||||||
|
|||||||
Reference in New Issue
Block a user