Merge branch 'develop' into pi-expense-account
This commit is contained in:
commit
d43e6ced91
@ -27,6 +27,9 @@ class ExchangeRateRevaluation(Document):
|
|||||||
if not (self.company and self.posting_date):
|
if not (self.company and self.posting_date):
|
||||||
frappe.throw(_("Please select Company and Posting Date to getting entries"))
|
frappe.throw(_("Please select Company and Posting Date to getting entries"))
|
||||||
|
|
||||||
|
def on_cancel(self):
|
||||||
|
self.ignore_linked_doctypes = ('GL Entry')
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def check_journal_entry_condition(self):
|
def check_journal_entry_condition(self):
|
||||||
total_debit = frappe.db.get_value("Journal Entry Account", {
|
total_debit = frappe.db.get_value("Journal Entry Account", {
|
||||||
@ -99,10 +102,12 @@ class ExchangeRateRevaluation(Document):
|
|||||||
sum(debit) - sum(credit) as balance
|
sum(debit) - sum(credit) as balance
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where account in (%s)
|
where account in (%s)
|
||||||
group by account, party_type, party
|
and posting_date <= %s
|
||||||
|
and is_cancelled = 0
|
||||||
|
group by account, NULLIF(party_type,''), NULLIF(party,'')
|
||||||
having sum(debit) != sum(credit)
|
having sum(debit) != sum(credit)
|
||||||
order by account
|
order by account
|
||||||
""" % ', '.join(['%s']*len(accounts)), tuple(accounts), as_dict=1)
|
""" % (', '.join(['%s']*len(accounts)), '%s'), tuple(accounts + [self.posting_date]), as_dict=1)
|
||||||
|
|
||||||
return account_details
|
return account_details
|
||||||
|
|
||||||
@ -143,9 +148,9 @@ class ExchangeRateRevaluation(Document):
|
|||||||
"party_type": d.get("party_type"),
|
"party_type": d.get("party_type"),
|
||||||
"party": d.get("party"),
|
"party": d.get("party"),
|
||||||
"account_currency": d.get("account_currency"),
|
"account_currency": d.get("account_currency"),
|
||||||
"balance": d.get("balance_in_account_currency"),
|
"balance": flt(d.get("balance_in_account_currency"), d.precision("balance_in_account_currency")),
|
||||||
dr_or_cr: abs(d.get("balance_in_account_currency")),
|
dr_or_cr: flt(abs(d.get("balance_in_account_currency")), d.precision("balance_in_account_currency")),
|
||||||
"exchange_rate":d.get("new_exchange_rate"),
|
"exchange_rate": flt(d.get("new_exchange_rate"), d.precision("new_exchange_rate")),
|
||||||
"reference_type": "Exchange Rate Revaluation",
|
"reference_type": "Exchange Rate Revaluation",
|
||||||
"reference_name": self.name,
|
"reference_name": self.name,
|
||||||
})
|
})
|
||||||
@ -154,9 +159,9 @@ class ExchangeRateRevaluation(Document):
|
|||||||
"party_type": d.get("party_type"),
|
"party_type": d.get("party_type"),
|
||||||
"party": d.get("party"),
|
"party": d.get("party"),
|
||||||
"account_currency": d.get("account_currency"),
|
"account_currency": d.get("account_currency"),
|
||||||
"balance": d.get("balance_in_account_currency"),
|
"balance": flt(d.get("balance_in_account_currency"), d.precision("balance_in_account_currency")),
|
||||||
reverse_dr_or_cr: abs(d.get("balance_in_account_currency")),
|
reverse_dr_or_cr: flt(abs(d.get("balance_in_account_currency")), d.precision("balance_in_account_currency")),
|
||||||
"exchange_rate": d.get("current_exchange_rate"),
|
"exchange_rate": flt(d.get("current_exchange_rate"), d.precision("current_exchange_rate")),
|
||||||
"reference_type": "Exchange Rate Revaluation",
|
"reference_type": "Exchange Rate Revaluation",
|
||||||
"reference_name": self.name
|
"reference_name": self.name
|
||||||
})
|
})
|
||||||
@ -185,9 +190,9 @@ def get_account_details(account, company, posting_date, party_type=None, party=N
|
|||||||
|
|
||||||
account_details = {}
|
account_details = {}
|
||||||
company_currency = erpnext.get_company_currency(company)
|
company_currency = erpnext.get_company_currency(company)
|
||||||
balance = get_balance_on(account, party_type=party_type, party=party, in_account_currency=False)
|
balance = get_balance_on(account, date=posting_date, party_type=party_type, party=party, in_account_currency=False)
|
||||||
if balance:
|
if balance:
|
||||||
balance_in_account_currency = get_balance_on(account, party_type=party_type, party=party)
|
balance_in_account_currency = get_balance_on(account, date=posting_date, party_type=party_type, party=party)
|
||||||
current_exchange_rate = balance / balance_in_account_currency if balance_in_account_currency else 0
|
current_exchange_rate = balance / balance_in_account_currency if balance_in_account_currency else 0
|
||||||
new_exchange_rate = get_exchange_rate(account_currency, company_currency, posting_date)
|
new_exchange_rate = get_exchange_rate(account_currency, company_currency, posting_date)
|
||||||
new_balance_in_base_currency = balance_in_account_currency * new_exchange_rate
|
new_balance_in_base_currency = balance_in_account_currency * new_exchange_rate
|
||||||
|
@ -99,7 +99,6 @@ class ReceivablePayableReport(object):
|
|||||||
voucher_no = gle.voucher_no,
|
voucher_no = gle.voucher_no,
|
||||||
party = gle.party,
|
party = gle.party,
|
||||||
posting_date = gle.posting_date,
|
posting_date = gle.posting_date,
|
||||||
remarks = gle.remarks,
|
|
||||||
account_currency = gle.account_currency,
|
account_currency = gle.account_currency,
|
||||||
invoiced = 0.0,
|
invoiced = 0.0,
|
||||||
paid = 0.0,
|
paid = 0.0,
|
||||||
@ -579,7 +578,7 @@ class ReceivablePayableReport(object):
|
|||||||
self.gl_entries = frappe.db.sql("""
|
self.gl_entries = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
name, posting_date, account, party_type, party, voucher_type, voucher_no, cost_center,
|
name, posting_date, account, party_type, party, voucher_type, voucher_no, cost_center,
|
||||||
against_voucher_type, against_voucher, account_currency, remarks, {0}
|
against_voucher_type, against_voucher, account_currency, {0}
|
||||||
from
|
from
|
||||||
`tabGL Entry`
|
`tabGL Entry`
|
||||||
where
|
where
|
||||||
@ -792,8 +791,6 @@ class ReceivablePayableReport(object):
|
|||||||
self.add_column(label=_('Supplier Group'), fieldname='supplier_group', fieldtype='Link',
|
self.add_column(label=_('Supplier Group'), fieldname='supplier_group', fieldtype='Link',
|
||||||
options='Supplier Group')
|
options='Supplier Group')
|
||||||
|
|
||||||
self.add_column(label=_('Remarks'), fieldname='remarks', fieldtype='Text', width=200)
|
|
||||||
|
|
||||||
def add_column(self, label, fieldname=None, fieldtype='Currency', options=None, width=120):
|
def add_column(self, label, fieldname=None, fieldtype='Currency', options=None, width=120):
|
||||||
if not fieldname: fieldname = scrub(label)
|
if not fieldname: fieldname = scrub(label)
|
||||||
if fieldtype=='Currency': options='currency'
|
if fieldtype=='Currency': options='currency'
|
||||||
|
@ -1112,8 +1112,11 @@ class AccountsController(TransactionBase):
|
|||||||
for d in self.get("payment_schedule"):
|
for d in self.get("payment_schedule"):
|
||||||
if d.invoice_portion:
|
if d.invoice_portion:
|
||||||
d.payment_amount = flt(grand_total * flt(d.invoice_portion / 100), d.precision('payment_amount'))
|
d.payment_amount = flt(grand_total * flt(d.invoice_portion / 100), d.precision('payment_amount'))
|
||||||
d.base_payment_amount = flt(base_grand_total * flt(d.invoice_portion / 100), d.precision('payment_amount'))
|
d.base_payment_amount = flt(base_grand_total * flt(d.invoice_portion / 100), d.precision('base_payment_amount'))
|
||||||
d.outstanding = d.payment_amount
|
d.outstanding = d.payment_amount
|
||||||
|
elif not d.invoice_portion:
|
||||||
|
d.base_payment_amount = flt(base_grand_total * self.get("conversion_rate"), d.precision('base_payment_amount'))
|
||||||
|
|
||||||
|
|
||||||
def set_due_date(self):
|
def set_due_date(self):
|
||||||
due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date]
|
due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date]
|
||||||
|
@ -53,12 +53,17 @@ class StockController(AccountsController):
|
|||||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
if hasattr(d, 'serial_no') and hasattr(d, 'batch_no') and d.serial_no and d.batch_no:
|
if hasattr(d, 'serial_no') and hasattr(d, 'batch_no') and d.serial_no and d.batch_no:
|
||||||
serial_nos = get_serial_nos(d.serial_no)
|
serial_nos = frappe.get_all("Serial No",
|
||||||
for serial_no_data in frappe.get_all("Serial No",
|
fields=["batch_no", "name", "warehouse"],
|
||||||
filters={"name": ("in", serial_nos)}, fields=["batch_no", "name"]):
|
filters={
|
||||||
if serial_no_data.batch_no != d.batch_no:
|
"name": ("in", get_serial_nos(d.serial_no))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
for row in serial_nos:
|
||||||
|
if row.warehouse and row.batch_no != d.batch_no:
|
||||||
frappe.throw(_("Row #{0}: Serial No {1} does not belong to Batch {2}")
|
frappe.throw(_("Row #{0}: Serial No {1} does not belong to Batch {2}")
|
||||||
.format(d.idx, serial_no_data.name, d.batch_no))
|
.format(d.idx, row.name, d.batch_no))
|
||||||
|
|
||||||
if flt(d.qty) > 0.0 and d.get("batch_no") and self.get("posting_date") and self.docstatus < 2:
|
if flt(d.qty) > 0.0 and d.get("batch_no") and self.get("posting_date") and self.docstatus < 2:
|
||||||
expiry_date = frappe.get_cached_value("Batch", d.get("batch_no"), "expiry_date")
|
expiry_date = frappe.get_cached_value("Batch", d.get("batch_no"), "expiry_date")
|
||||||
|
0
erpnext/crm/doctype/campaign/__init__.py
Normal file
0
erpnext/crm/doctype/campaign/__init__.py
Normal file
17
erpnext/crm/doctype/campaign/campaign.js
Normal file
17
erpnext/crm/doctype/campaign/campaign.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Campaign', {
|
||||||
|
refresh: function(frm) {
|
||||||
|
erpnext.toggle_naming_series();
|
||||||
|
|
||||||
|
if (frm.doc.__islocal) {
|
||||||
|
frm.toggle_display("naming_series", frappe.boot.sysdefaults.campaign_naming_by=="Naming Series");
|
||||||
|
} else {
|
||||||
|
cur_frm.add_custom_button(__("View Leads"), function() {
|
||||||
|
frappe.route_options = {"source": "Campaign", "campaign_name": frm.doc.name};
|
||||||
|
frappe.set_route("List", "Lead");
|
||||||
|
}, "fa fa-list", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
@ -39,17 +40,9 @@
|
|||||||
"set_only_once": 1
|
"set_only_once": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "description",
|
"fieldname": "campaign_schedules_section",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Section Break",
|
||||||
"in_list_view": 1,
|
"label": "Campaign Schedules"
|
||||||
"label": "Description",
|
|
||||||
"oldfieldname": "description",
|
|
||||||
"oldfieldtype": "Text",
|
|
||||||
"width": "300px"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "description_section",
|
|
||||||
"fieldtype": "Section Break"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "campaign_schedules",
|
"fieldname": "campaign_schedules",
|
||||||
@ -58,16 +51,25 @@
|
|||||||
"options": "Campaign Email Schedule"
|
"options": "Campaign Email Schedule"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "campaign_schedules_section",
|
"fieldname": "description_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break"
|
||||||
"label": "Campaign Schedules"
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "description",
|
||||||
|
"fieldtype": "Text",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Description",
|
||||||
|
"oldfieldname": "description",
|
||||||
|
"oldfieldtype": "Text",
|
||||||
|
"width": "300px"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-bullhorn",
|
"icon": "fa fa-bullhorn",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"modified": "2019-07-22 12:03:39.832342",
|
"links": [],
|
||||||
|
"modified": "2021-06-30 18:05:06.412712",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "CRM",
|
||||||
"name": "Campaign",
|
"name": "Campaign",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
@ -1,9 +1,7 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# License: GNU General Public License v3. See license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.model.naming import set_name_by_naming_series
|
from frappe.model.naming import set_name_by_naming_series
|
||||||
|
|
8
erpnext/crm/doctype/campaign/test_campaign.py
Normal file
8
erpnext/crm/doctype/campaign/test_campaign.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestCampaign(unittest.TestCase):
|
||||||
|
pass
|
@ -192,11 +192,11 @@ class JobCard(Document):
|
|||||||
"completed_qty": args.get("completed_qty") or 0.0
|
"completed_qty": args.get("completed_qty") or 0.0
|
||||||
})
|
})
|
||||||
elif args.get("start_time"):
|
elif args.get("start_time"):
|
||||||
new_args = {
|
new_args = frappe._dict({
|
||||||
"from_time": get_datetime(args.get("start_time")),
|
"from_time": get_datetime(args.get("start_time")),
|
||||||
"operation": args.get("sub_operation"),
|
"operation": args.get("sub_operation"),
|
||||||
"completed_qty": 0.0
|
"completed_qty": 0.0
|
||||||
}
|
})
|
||||||
|
|
||||||
if employees:
|
if employees:
|
||||||
for name in employees:
|
for name in employees:
|
||||||
|
@ -10,6 +10,7 @@ def execute():
|
|||||||
if not frappe.db.has_column('Work Order', 'has_batch_no'):
|
if not frappe.db.has_column('Work Order', 'has_batch_no'):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
frappe.reload_doc('manufacturing', 'doctype', 'manufacturing_settings')
|
||||||
if cint(frappe.db.get_single_value('Manufacturing Settings', 'make_serial_no_batch_from_work_order')):
|
if cint(frappe.db.get_single_value('Manufacturing Settings', 'make_serial_no_batch_from_work_order')):
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -107,4 +108,4 @@ def repost_future_sle_and_gle(doc):
|
|||||||
"company": doc.company
|
"company": doc.company
|
||||||
})
|
})
|
||||||
|
|
||||||
create_repost_item_valuation_entry(args)
|
create_repost_item_valuation_entry(args)
|
||||||
|
@ -37,7 +37,7 @@ def execute():
|
|||||||
|
|
||||||
if frappe.db.exists('DocType', 'Opportunity'):
|
if frappe.db.exists('DocType', 'Opportunity'):
|
||||||
opportunities = frappe.db.get_all('Opportunity', fields=['name', 'mins_to_first_response'], order_by='creation desc')
|
opportunities = frappe.db.get_all('Opportunity', fields=['name', 'mins_to_first_response'], order_by='creation desc')
|
||||||
frappe.reload_doc('crm', 'doctype', 'opportunity')
|
frappe.reload_doctype('Opportunity', force=True)
|
||||||
rename_field('Opportunity', 'mins_to_first_response', 'first_response_time')
|
rename_field('Opportunity', 'mins_to_first_response', 'first_response_time')
|
||||||
|
|
||||||
# change fieldtype to duration
|
# change fieldtype to duration
|
||||||
|
@ -4,11 +4,18 @@
|
|||||||
frappe.ui.form.on('Salary Component', {
|
frappe.ui.form.on('Salary Component', {
|
||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
frm.set_query("account", "accounts", function(doc, cdt, cdn) {
|
frm.set_query("account", "accounts", function(doc, cdt, cdn) {
|
||||||
var d = locals[cdt][cdn];
|
let d = frappe.get_doc(cdt, cdn);
|
||||||
|
|
||||||
|
let root_type = "Liability";
|
||||||
|
if (frm.doc.type == "Deduction") {
|
||||||
|
root_type = "Expense";
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"company": d.company
|
"company": d.company,
|
||||||
|
"root_type": root_type
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
frappe.ui.form.on('E Invoice Settings', {
|
frappe.ui.form.on('E Invoice Settings', {
|
||||||
refresh(frm) {
|
refresh(frm) {
|
||||||
const docs_link = 'https://docs.erpnext.com/docs/user/manual/en/regional/india/setup-e-invoicing';
|
const docs_link = 'https://docs.erpnext.com/docs/v13/user/manual/en/regional/india/setup-e-invoicing';
|
||||||
frm.dashboard.set_headline(
|
frm.dashboard.set_headline(
|
||||||
__("Read {0} for more information on E Invoicing features.", [`<a href='${docs_link}'>documentation</a>`])
|
__("Read {0} for more information on E Invoicing features.", [`<a href='${docs_link}'>documentation</a>`])
|
||||||
);
|
);
|
||||||
|
@ -1 +0,0 @@
|
|||||||
Sales campaign / promotion, like special discount, exhibition, newsletter etc.
|
|
@ -1 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
@ -1,15 +0,0 @@
|
|||||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
// License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
frappe.ui.form.on("Campaign", "refresh", function(frm) {
|
|
||||||
erpnext.toggle_naming_series();
|
|
||||||
if(frm.doc.__islocal) {
|
|
||||||
frm.toggle_display("naming_series", frappe.boot.sysdefaults.campaign_naming_by=="Naming Series");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
cur_frm.add_custom_button(__("View Leads"), function() {
|
|
||||||
frappe.route_options = {"source": "Campaign","campaign_name": frm.doc.name}
|
|
||||||
frappe.set_route("List", "Lead");
|
|
||||||
}, "fa fa-list", true);
|
|
||||||
}
|
|
||||||
})
|
|
@ -1,17 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
from frappe import _
|
|
||||||
|
|
||||||
def get_data():
|
|
||||||
return {
|
|
||||||
'fieldname': 'campaign_name',
|
|
||||||
'transactions': [
|
|
||||||
{
|
|
||||||
'label': _('Email Campaigns'),
|
|
||||||
'items': ['Email Campaign']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'label': _('Social Media Campaigns'),
|
|
||||||
'items': ['Social Media Post']
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
|
|
||||||
import frappe
|
|
||||||
test_records = frappe.get_test_records('Campaign')
|
|
@ -1,10 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"campaign_name": "_Test Campaign",
|
|
||||||
"doctype": "Campaign"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"campaign_name": "_Test Campaign 1",
|
|
||||||
"doctype": "Campaign"
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,3 +1,4 @@
|
|||||||
.funnel-wrapper {
|
.funnel-wrapper {
|
||||||
margin: 15px;
|
margin: 15px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user