Merge branch 'develop' into fix-payment-entry-wrong-bank-account-fetch-develop

This commit is contained in:
Marica 2020-07-28 12:29:47 +05:30 committed by GitHub
commit c1e46d8131
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 189 additions and 98 deletions

View File

@ -26,22 +26,22 @@ def test_create_test_data():
"item_group": "_Test Item Group",
"item_name": "_Test Tesla Car",
"apply_warehouse_wise_reorder_level": 0,
"warehouse":"_Test Warehouse - _TC",
"warehouse":"Stores - TCP1",
"gst_hsn_code": "999800",
"valuation_rate": 5000,
"standard_rate":5000,
"item_defaults": [{
"company": "_Test Company",
"default_warehouse": "_Test Warehouse - _TC",
"company": "_Test Company with perpetual inventory",
"default_warehouse": "Stores - TCP1",
"default_price_list":"_Test Price List",
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"buying_cost_center": "_Test Cost Center - _TC",
"selling_cost_center": "_Test Cost Center - _TC",
"income_account": "Sales - _TC"
"expense_account": "Cost of Goods Sold - TCP1",
"buying_cost_center": "Main - TCP1",
"selling_cost_center": "Main - TCP1",
"income_account": "Sales - TCP1"
}],
"show_in_website": 1,
"route":"-test-tesla-car",
"website_warehouse": "_Test Warehouse - _TC"
"website_warehouse": "Stores - TCP1"
})
item.insert()
# create test item price
@ -63,12 +63,12 @@ def test_create_test_data():
"items": [{
"item_code": "_Test Tesla Car"
}],
"warehouse":"_Test Warehouse - _TC",
"warehouse":"Stores - TCP1",
"coupon_code_based":1,
"selling": 1,
"rate_or_discount": "Discount Percentage",
"discount_percentage": 30,
"company": "_Test Company",
"company": "_Test Company with perpetual inventory",
"currency":"INR",
"for_price_list":"_Test Price List"
})
@ -112,7 +112,10 @@ class TestCouponCode(unittest.TestCase):
self.assertEqual(coupon_code.get("used"),0)
def test_2_sales_order_with_coupon_code(self):
so = make_sales_order(customer="_Test Customer",selling_price_list="_Test Price List",item_code="_Test Tesla Car", rate=5000,qty=1, do_not_submit=True)
so = make_sales_order(company='_Test Company with perpetual inventory', warehouse='Stores - TCP1',
customer="_Test Customer", selling_price_list="_Test Price List", item_code="_Test Tesla Car", rate=5000,qty=1,
do_not_submit=True)
so = frappe.get_doc('Sales Order', so.name)
# check item price before coupon code is applied
self.assertEqual(so.items[0].rate, 5000)

View File

@ -6,6 +6,7 @@ import unittest, frappe
from frappe.utils import flt, nowdate
from erpnext.accounts.doctype.account.test_account import get_inventory_account
from erpnext.exceptions import InvalidAccountCurrency
from erpnext.accounts.general_ledger import StockAccountInvalidTransaction
class TestJournalEntry(unittest.TestCase):
def test_journal_entry_with_against_jv(self):
@ -81,19 +82,46 @@ class TestJournalEntry(unittest.TestCase):
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
set_perpetual_inventory()
jv = frappe.copy_doc(test_records[0])
jv = frappe.copy_doc({
"cheque_date": nowdate(),
"cheque_no": "33",
"company": "_Test Company with perpetual inventory",
"doctype": "Journal Entry",
"accounts": [
{
"account": "Debtors - TCP1",
"party_type": "Customer",
"party": "_Test Customer",
"credit_in_account_currency": 400.0,
"debit_in_account_currency": 0.0,
"doctype": "Journal Entry Account",
"parentfield": "accounts",
"cost_center": "Main - TCP1"
},
{
"account": "_Test Bank - TCP1",
"credit_in_account_currency": 0.0,
"debit_in_account_currency": 400.0,
"doctype": "Journal Entry Account",
"parentfield": "accounts",
"cost_center": "Main - TCP1"
}
],
"naming_series": "_T-Journal Entry-",
"posting_date": nowdate(),
"user_remark": "test",
"voucher_type": "Bank Entry"
})
jv.get("accounts")[0].update({
"account": get_inventory_account('_Test Company'),
"company": "_Test Company",
"account": get_inventory_account('_Test Company with perpetual inventory'),
"company": "_Test Company with perpetual inventory",
"party_type": None,
"party": None
})
jv.insert()
from erpnext.accounts.general_ledger import StockAccountInvalidTransaction
self.assertRaises(StockAccountInvalidTransaction, jv.submit)
jv.cancel()
set_perpetual_inventory(0)
def test_multi_currency(self):

View File

@ -219,19 +219,29 @@ class TestPOSInvoice(unittest.TestCase):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
se = make_serialized_item(target_warehouse="_Test Warehouse - _TC")
se = make_serialized_item(company='_Test Company with perpetual inventory',
target_warehouse="Stores - TCP1", cost_center='Main - TCP1', expense_account='Cost of Goods Sold - TCP1')
serial_nos = get_serial_nos(se.get("items")[0].serial_no)
pos = create_pos_invoice(item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
pos = create_pos_invoice(company='_Test Company with perpetual inventory', debit_to='Debtors - TCP1',
account_for_change_amount='Cash - TCP1', warehouse='Stores - TCP1', income_account='Sales - TCP1',
expense_account='Cost of Goods Sold - TCP1', cost_center='Main - TCP1',
item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
pos.get("items")[0].serial_no = serial_nos[0]
pos.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - _TC', 'amount': 1000})
pos.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - TCP1', 'amount': 1000})
pos.insert()
pos.submit()
pos2 = create_pos_invoice(item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
pos2 = create_pos_invoice(company='_Test Company with perpetual inventory', debit_to='Debtors - TCP1',
account_for_change_amount='Cash - TCP1', warehouse='Stores - TCP1', income_account='Sales - TCP1',
expense_account='Cost of Goods Sold - TCP1', cost_center='Main - TCP1',
item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
pos2.get("items")[0].serial_no = serial_nos[0]
pos2.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - _TC', 'amount': 1000})
pos2.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - TCP1', 'amount': 1000})
self.assertRaises(frappe.ValidationError, pos2.insert)
@ -299,7 +309,7 @@ def create_pos_invoice(**args):
pos_inv.return_against = args.return_against
pos_inv.currency=args.currency or "INR"
pos_inv.conversion_rate = args.conversion_rate or 1
pos_inv.account_for_change_amount = "Cash - _TC"
pos_inv.account_for_change_amount = args.account_for_change_amount or "Cash - _TC"
pos_inv.append("items", {
"item_code": args.item or args.item_code or "_Test Item",

View File

@ -158,8 +158,10 @@ def validate_account_for_perpetual_inventory(gl_map):
if account not in aii_accounts:
continue
# Always use current date to get stock and account balance as there can future entries for
# other items
account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(account,
gl_map[0].posting_date, gl_map[0].company)
getdate(), gl_map[0].company)
if gl_map[0].voucher_type=="Journal Entry":
# In case of Journal Entry, there are no corresponding SL entries,
@ -169,7 +171,6 @@ def validate_account_for_perpetual_inventory(gl_map):
frappe.throw(_("Account: {0} can only be updated via Stock Transactions")
.format(account), StockAccountInvalidTransaction)
# This has been comment for a temporary, will add this code again on release of immutable ledger
elif account_bal != stock_bal:
precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"),
currency=frappe.get_cached_value('Company', gl_map[0].company, "default_currency"))

View File

@ -140,7 +140,7 @@ education.StudentsEditor = Class.extend({
frappe.call({
method: "erpnext.education.api.mark_attendance",
freeze: true,
freeze_message: "Marking attendance",
freeze_message: __("Marking attendance"),
args: {
"students_present": students_present,
"students_absent": students_absent,

View File

@ -101,7 +101,7 @@ def get_formatted_result(args, get_assessment_criteria=False, get_course=False,
# create the nested dictionary structure as given below:
# <variable_name>.<student_name>.<course>.<assessment_group>.<assessment_criteria>.<grade/score/max_score>
# "Total Score" -> assessment criteria used for totaling and args.assessment_group -> for totaling all the assesments
# "Final Grade" -> assessment criteria used for totaling and args.assessment_group -> for totaling all the assesments
student_details = {}
formatted_assessment_result = defaultdict(dict)
@ -123,13 +123,13 @@ def get_formatted_result(args, get_assessment_criteria=False, get_course=False,
formatted_assessment_result[result.student][result.course][assessment_group]\
[assessment_criteria]["grade"] = tmp_grade
# create the assessment criteria "Total Score" with the sum of all the scores of the assessment criteria in a given assessment group
# create the assessment criteria "Final Grade" with the sum of all the scores of the assessment criteria in a given assessment group
def add_total_score(result, assessment_group):
if "Total Score" not in formatted_assessment_result[result.student][result.course][assessment_group]:
formatted_assessment_result[result.student][result.course][assessment_group]["Total Score"] = frappe._dict({
"assessment_criteria": "Total Score", "maximum_score": result.maximum_score, "score": result.score, "grade": result.grade})
if "Final Grade" not in formatted_assessment_result[result.student][result.course][assessment_group]:
formatted_assessment_result[result.student][result.course][assessment_group]["Final Grade"] = frappe._dict({
"assessment_criteria": "Final Grade", "maximum_score": result.maximum_score, "score": result.score, "grade": result.grade})
else:
add_score_and_recalculate_grade(result, assessment_group, "Total Score")
add_score_and_recalculate_grade(result, assessment_group, "Final Grade")
for result in assessment_result:
if result.student not in student_details:
@ -166,7 +166,7 @@ def get_formatted_result(args, get_assessment_criteria=False, get_course=False,
add_total_score(result, args.assessment_group)
total_maximum_score = formatted_assessment_result[result.student][result.course][args.assessment_group]\
["Total Score"]["maximum_score"]
["Final Grade"]["maximum_score"]
if get_assessment_criteria:
assessment_criteria_dict[result.assessment_criteria] = formatted_assessment_result[result.student][result.course]\
[args.assessment_group][result.assessment_criteria]["maximum_score"]
@ -174,7 +174,7 @@ def get_formatted_result(args, get_assessment_criteria=False, get_course=False,
course_dict[result.course] = total_maximum_score
if get_assessment_criteria and total_maximum_score:
assessment_criteria_dict["Total Score"] = total_maximum_score
assessment_criteria_dict["Final Grade"] = total_maximum_score
return {
"student_details": student_details,
@ -220,7 +220,7 @@ def get_chart_data(grades, criteria_list, kounter):
datasets = []
for grade in grades:
tmp = frappe._dict({"values":[], "title": grade})
tmp = frappe._dict({"name": grade, "values":[]})
for criteria in criteria_list:
if grade in kounter[criteria]:
tmp["values"].append(kounter[criteria][grade])

View File

@ -58,7 +58,7 @@ var create_multiple_dialog = function (listview) {
}
},
freeze: true,
freeze_message: 'Creating Lab Tests...'
freeze_message: __('Creating Lab Tests...')
});
dialog.hide();
}

View File

@ -220,7 +220,7 @@ var schedule_inpatient = function(frm) {
}
},
freeze: true,
freeze_message: 'Scheduling Patient Admission'
freeze_message: __('Scheduling Patient Admission')
});
frm.refresh_fields();
dialog.hide();

View File

@ -9,6 +9,7 @@ frappe.views.calendar["Holiday List"] = {
"title": "description",
"allDay": "allDay"
},
order_by: `from_date`,
get_events_method: "erpnext.hr.doctype.holiday_list.holiday_list.get_events",
filters: [
{

View File

@ -29,6 +29,14 @@ frappe.ui.form.on('Member', {
frappe.set_route('query-report', 'Accounts Receivable', {member:frm.doc.name});
});
if (!frm.doc.customer) {
frm.add_custom_button(__('Create Customer'), () => {
frm.call('make_customer_and_link').then(() => {
frm.reload_doc();
});
});
}
// indicator
erpnext.utils.set_party_dashboard_indicators(frm);

View File

@ -53,6 +53,19 @@ class Member(Document):
return subscription
def make_customer_and_link(self):
if self.customer:
frappe.msgprint(_("A customer is already linked to this Member"))
cust = create_customer(frappe._dict({
'fullname': self.member_name,
'email': self.email_id or self.user,
'phone': None
}))
self.customer = cust
self.save()
def get_or_create_member(user_details):
member_list = frappe.get_all("Member", filters={'email': user_details.email, 'membership_type': user_details.plan_id})
if member_list and member_list[0]:
@ -83,7 +96,9 @@ def create_customer(user_details):
try:
contact = frappe.new_doc("Contact")
contact.first_name = user_details.fullname
if user_details.mobile:
contact.add_phone(user_details.mobile, is_primary_phone=1, is_primary_mobile_no=1)
if user_details.email:
contact.add_email(user_details.email, is_primary=1)
contact.insert(ignore_permissions=True)
@ -121,7 +136,7 @@ def create_member_subscription_order(user_details):
'subscription_id': 'sub_EZycCvXFvqnC6p'
}
"""
# {"plan_id":"IFF Starter","fullname":"Shivam Mishra","mobile":"7506056962","email":"shivam@shivam.dev","pan":"Testing123"}
user_details = frappe._dict(user_details)
member = get_or_create_member(user_details)
if not member:

View File

@ -120,13 +120,15 @@
{
"fieldname": "webhook_payload",
"fieldtype": "Code",
"hidden": 1,
"label": "Webhook Payload",
"options": "JSON",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2020-04-06 14:29:33.856060",
"modified": "2020-07-27 14:28:11.532696",
"modified_by": "Administrator",
"module": "Non Profit",
"name": "Membership",

View File

@ -81,7 +81,12 @@ def verify_signature(data):
@frappe.whitelist(allow_guest=True)
def trigger_razorpay_subscription(*args, **kwargs):
data = frappe.request.get_data(as_text=True)
try:
verify_signature(data)
except Exception as e:
signature = frappe.request.headers.get('X-Razorpay-Signature')
log = "{0} \n\n {1} \n\n {2} \n\n {3}".format(e, frappe.get_traceback(), signature, data)
frappe.log_error(e, "Webhook Verification Error")
if isinstance(data, six.string_types):
data = json.loads(data)
@ -99,11 +104,11 @@ def trigger_razorpay_subscription(*args, **kwargs):
except Exception as e:
error_log = frappe.log_error(frappe.get_traceback() + '\n' + data_json , _("Membership Webhook Failed"))
notify_failure(error_log)
return False
return { status: 'Failed' }
if not member:
return False
return { status: 'Failed' }
try:
if data.event == "subscription.activated":
member.customer_id = payment.customer_id
elif data.event == "subscription.charged":
@ -127,8 +132,12 @@ def trigger_razorpay_subscription(*args, **kwargs):
member.subscription_end = datetime.fromtimestamp(subscription.end_at)
member.subscription_activated = 1
member.save(ignore_permissions=True)
except Exception as e:
log = frappe.log_error(e, "Error creating membership entry")
notify_failure(log)
return { status: 'Failed' }
return True
return { status: 'Success' }
def notify_failure(log):

View File

@ -15,7 +15,7 @@ erpnext.patches.v4_0.move_warehouse_user_to_restrictions
erpnext.patches.v4_0.global_defaults_to_system_settings
erpnext.patches.v4_0.update_incharge_name_to_sales_person_in_maintenance_schedule
execute:frappe.reload_doc("accounts", "doctype", "POS Payment Method") #2020-05-28
execute:frappe.reload_doc("HR", "doctype", "HR Settings") #2020-01-16
execute:frappe.reload_doc("HR", "doctype", "HR Settings") #2020-01-16 #2020-07-24
execute:frappe.reload_doc('stock', 'doctype', 'warehouse') # 2017-04-24
execute:frappe.reload_doc('accounts', 'doctype', 'sales_invoice') # 2016-08-31
execute:frappe.reload_doc('selling', 'doctype', 'sales_order') # 2014-01-29

View File

@ -12,11 +12,11 @@ def execute():
frappe.rename_doc('DocType', 'POS Closing Voucher Taxes', 'POS Closing Entry Taxes', force=True)
if not frappe.db.exists('DocType', 'POS Closing Voucher Details'):
frappe.rename_doc('DocType', 'POS Closing Voucher Details', 'POS Closing Entry Details', force=True)
frappe.rename_doc('DocType', 'POS Closing Voucher Details', 'POS Closing Entry Detail', force=True)
frappe.reload_doc('Accounts', 'doctype', 'POS Closing Entry')
frappe.reload_doc('Accounts', 'doctype', 'POS Closing Entry Taxes')
frappe.reload_doc('Accounts', 'doctype', 'POS Closing Entry Details')
frappe.reload_doc('Accounts', 'doctype', 'POS Closing Entry Detail')
if frappe.db.exists("DocType", "POS Closing Voucher"):
frappe.delete_doc("DocType", "POS Closing Voucher")

View File

@ -6,7 +6,7 @@ from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc("Selling", "doctype", "POS Payment Method")
frappe.reload_doc("accounts", "doctype", "POS Payment Method")
pos_profiles = frappe.get_all("POS Profile")
for pos_profile in pos_profiles:

View File

@ -213,7 +213,7 @@ frappe.ui.form.on('Payroll Entry', {
},
doc: frm.doc,
freeze: true,
freeze_message: 'Validating Employee Attendance...'
freeze_message: __('Validating Employee Attendance...')
});
}else{
frm.fields_dict.attendance_detail_html.html("");
@ -237,7 +237,7 @@ const submit_salary_slip = function (frm) {
callback: function() {frm.events.refresh(frm);},
doc: frm.doc,
freeze: true,
freeze_message: 'Submitting Salary Slips and creating Journal Entry...'
freeze_message: __('Submitting Salary Slips and creating Journal Entry...')
});
},
function() {

View File

@ -13,7 +13,7 @@ from erpnext.controllers.item_variant import (ItemVariantExistsError,
from erpnext.setup.doctype.item_group.item_group import (get_parent_item_groups, invalidate_cache_for)
from frappe import _, msgprint
from frappe.utils import (cint, cstr, flt, formatdate, get_timestamp, getdate,
now_datetime, random_string, strip, get_link_to_form)
now_datetime, random_string, strip, get_link_to_form, nowtime)
from frappe.utils.html_utils import clean_html
from frappe.website.doctype.website_slideshow.website_slideshow import \
get_slideshow
@ -194,7 +194,7 @@ class Item(WebsiteGenerator):
if default_warehouse:
stock_entry = make_stock_entry(item_code=self.name, target=default_warehouse, qty=self.opening_stock,
rate=self.valuation_rate, company=default.company)
rate=self.valuation_rate, company=default.company, posting_date=getdate(), posting_time=nowtime())
stock_entry.add_comment("Comment", _("Opening Stock"))

View File

@ -413,7 +413,7 @@ class TestStockEntry(unittest.TestCase):
def test_serial_item_error(self):
se, serial_nos = self.test_serial_by_series()
if not frappe.db.exists('Serial No', 'ABCD'):
make_serialized_item("_Test Serialized Item", "ABCD\nEFGH")
make_serialized_item(item_code="_Test Serialized Item", serial_no="ABCD\nEFGH")
se = frappe.copy_doc(test_records[0])
se.purpose = "Material Transfer"
@ -823,15 +823,29 @@ class TestStockEntry(unittest.TestCase):
])
)
def make_serialized_item(item_code=None, serial_no=None, target_warehouse=None):
def make_serialized_item(**args):
args = frappe._dict(args)
se = frappe.copy_doc(test_records[0])
se.get("items")[0].item_code = item_code or "_Test Serialized Item With Series"
se.get("items")[0].serial_no = serial_no
if args.company:
se.company = args.company
se.get("items")[0].item_code = args.item_code or "_Test Serialized Item With Series"
if args.serial_no:
se.get("items")[0].serial_no = args.serial_no
if args.cost_center:
se.get("items")[0].cost_center = args.cost_center
if args.expense_account:
se.get("items")[0].expense_account = args.expense_account
se.get("items")[0].qty = 2
se.get("items")[0].transfer_qty = 2
if target_warehouse:
se.get("items")[0].t_warehouse = target_warehouse
if args.target_warehouse:
se.get("items")[0].t_warehouse = args.target_warehouse
se.set_stock_entry_type()
se.insert()