Compare commits

..

45 Commits

Author SHA1 Message Date
Saurabh
6ad1082433 Merge branch 'hotfix' 2017-11-08 12:12:37 +05:30
Saurabh
db781e607a bumped to version 9.2.5 2017-11-08 12:42:37 +06:00
rohitwaghchaure
521606e433 Merge pull request #11398 from rohitwaghchaure/item_variants_donot_copy_option
[enhance] In item variants settings added provision, do not update the variants of variants from the template but will copy the value while making new variant aginst the template
2017-11-08 11:49:24 +05:30
Rohit Waghchaure
acc8995c48 [enhance] In item variants settings added provision, do not update the fields of variants from the template but will copy the value while making new variant aginst the template 2017-11-08 11:39:08 +05:30
rohitwaghchaure
f688af3809 [fix] Offline pos name is not defined issue in the POS (#11469) 2017-11-08 11:33:39 +05:30
rohitwaghchaure
9f2a27c99c Merge pull request #11477 from rohitwaghchaure/pos_profile_test_cases
[fix] POS Profile test cases
2017-11-07 16:35:52 +05:30
rohitwaghchaure
6058dcc2ce Merge pull request #11470 from rohitwaghchaure/pos_online_invalid_grand_total_issue
[Fix] Fast clicking on an item, showing invalid grand total and quantity in the POS cart
2017-11-07 16:19:51 +05:30
Rohit Waghchaure
35fc45eff9 [fix] POS Profile test cases 2017-11-07 10:43:16 +05:30
Rohit Waghchaure
57cc924d29 [Fix] Fast clicking on an item, showing invalid grand total and quantity in the POS cart 2017-11-06 18:42:37 +05:30
rohitwaghchaure
adbbb0b0f3 Merge pull request #11364 from manassolanki/set-pos-profile
set the pos profile in the sales invoice
2017-11-06 14:08:59 +05:30
Manas Solanki
40ef7e7039 patch for renaming the pos profile and setting the pos profile name 2017-11-06 13:53:52 +05:30
Manas Solanki
b1616a0cb3 changes in thepos profile 2017-11-06 13:53:52 +05:30
Manas Solanki
3f0dfd720f set the pos profile in the sales invoice 2017-11-06 13:53:52 +05:30
Saurabh
5647bf081a Merge branch 'hotfix' 2017-11-03 16:56:23 +05:30
Saurabh
56cb0aa9c1 bumped to version 9.2.4 2017-11-03 17:26:23 +06:00
rohitwaghchaure
7677ff00a2 [hotfix] User not able to edit exchange rate even if Allow Stale Exchange Rates is disabled in the accounts settings (#11409) 2017-11-02 18:12:14 +05:30
Saurabh
75f3f81a9b Merge branch 'hotfix' 2017-11-02 12:14:41 +05:30
Saurabh
870ce3cfea bumped to version 9.2.3 2017-11-02 12:44:40 +06:00
Saurabh
0ad2cc3def Merge pull request #11403 from tundebabzy/issue-11402
Error In Employee Loan Form (#11402)
2017-11-02 12:09:54 +05:30
Saurabh
00f6c2d61d Merge pull request #11417 from rohitwaghchaure/issue_not_save_v9
[Fix] Customer is manadatory even if customer has selected in the Issue
2017-11-02 12:07:32 +05:30
Saurabh
38008f8daa Merge pull request #11406 from rohitwaghchaure/payment_entry_differnece_amount_issue
[Fix] Wrong difference amount in the payment entry for the internal transfer type
2017-11-02 12:07:14 +05:30
Saurabh
afb63af3b6 Merge pull request #11397 from rohitwaghchaure/delivery_note_issue_from_so
[Fix] Getting an error while making delivery note from sales order and sales order has no item code
2017-11-02 12:06:08 +05:30
Rohit Waghchaure
816ce33daf [Fix] Customer is manadatory even if customer has selected in the Issue 2017-11-01 19:02:09 +05:30
Rohit Waghchaure
99748dbacf [Fix] Wrong difference amount in the payment entry for the internal transfer type 2017-11-01 11:45:02 +05:30
tunde
31287b00a6 call get_employee_loan_application only when appropriate 2017-10-31 18:10:17 +01:00
Rohit Waghchaure
5ec9f6930b [Fix] Getting an error while making delivery note from sales order and sales order has no item code 2017-10-31 15:26:56 +05:30
Faris Ansari
40611e4f69 [fix] hub get_item_details (#11383) 2017-10-31 13:00:09 +05:30
Saurabh
dd0bdc7fa6 Merge pull request #11356 from tundebabzy/issue-11355
fix object has not attribute 'is_item_from_hub'
2017-10-31 12:23:09 +05:30
tunde
bbce7b7e5d get attribute with get method 2017-10-26 14:31:13 +01:00
Nabin Hait
92e09c0b7b Merge branch 'hotfix' 2017-10-26 14:35:33 +05:30
Nabin Hait
819c50c042 bumped to version 9.2.2 2017-10-26 15:05:33 +06:00
Faris Ansari
6887cedaea [fix] item qty trigger (#11349) 2017-10-26 14:34:15 +05:30
Nabin Hait
aa7896f1e1 [test] Fixed physician test cases (#11347) 2017-10-26 14:33:28 +05:30
Nabin Hait
52909b73bb [test] Fixed advance jv cancellation (#11333) 2017-10-26 11:06:07 +05:30
Saurabh
5235aa833c Merge branch 'hotfix' 2017-10-26 09:59:22 +05:30
Saurabh
d0131762cc bumped to version 9.2.1 2017-10-26 10:29:22 +06:00
Saurabh
97b98b6c01 Merge pull request #11345 from saurabh6790/setup_wiz_fixes
[HOTFIX] translate domain
2017-10-26 09:52:45 +05:30
Saurabh
92a6155bb0 [fix] translate domain 2017-10-26 09:44:51 +05:30
Saurabh
d6e67ce123 [fix] check for null date fields (#11334) 2017-10-25 17:44:22 +05:30
Nabin Hait
6a4e230cde [fix] Status of Item (#11326) 2017-10-25 17:06:30 +05:30
rohitwaghchaure
c65f1d7745 Search item using name instead of item code (#11327) 2017-10-25 17:04:56 +05:30
rohitwaghchaure
e02ee898e9 [Fix] Production order not displaying in the calendar view, if po has no operations (#11328) 2017-10-25 17:04:31 +05:30
rohitwaghchaure
2e6f6d6749 [minor] cleanup code (#11331) 2017-10-25 17:03:49 +05:30
Nabin Hait
014b138074 Merge branch 'tundebabzy-issue-11080' into hotfix 2017-10-25 15:53:53 +05:30
Nabin Hait
fb734976eb Removed appintment field from Invoice, it should be a custom field and will be added from domain settings 2017-10-25 15:53:07 +05:30
37 changed files with 569 additions and 303 deletions

View File

@@ -4,7 +4,7 @@ import inspect
import frappe
from erpnext.hooks import regional_overrides
__version__ = '9.2.0'
__version__ = '9.2.5'
def get_default_company(user=None):
'''Get default company for user'''

View File

@@ -648,13 +648,13 @@ frappe.ui.form.on('Payment Entry', {
set_difference_amount: function(frm) {
var unallocated_amount = 0;
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
function(d) { return flt(d.amount) }));
if(frm.doc.party) {
var party_amount = frm.doc.payment_type=="Receive" ?
frm.doc.paid_amount : frm.doc.received_amount;
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
function(d) { return flt(d.amount) }));
if(frm.doc.total_allocated_amount < party_amount) {
if(frm.doc.payment_type == "Receive") {
unallocated_amount = party_amount - (frm.doc.total_allocated_amount - total_deductions);

View File

@@ -3,7 +3,7 @@
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "hash",
"autoname": "field:pos_profile_name",
"beta": 0,
"creation": "2013-05-24 12:15:51",
"custom": 0,
@@ -11,6 +11,96 @@
"doctype": "DocType",
"editable_grid": 0,
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "disabled",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Disabled",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_2",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "pos_profile_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "POS Profile Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -112,9 +202,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "update_stock",
"fieldname": "warehouse",
"fieldtype": "Link",
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -122,13 +211,11 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Warehouse",
"label": "Ignore Pricing Rule",
"length": 0,
"no_copy": 0,
"oldfieldname": "warehouse",
"oldfieldtype": "Link",
"options": "Warehouse",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -145,8 +232,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "campaign",
"fieldtype": "Link",
"fieldname": "allow_delete",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -154,10 +241,39 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Campaign",
"label": "Allow Delete",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "allow_user_to_edit_rate",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow user to edit Rate",
"length": 0,
"no_copy": 0,
"options": "Campaign",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -300,7 +416,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "currency",
"depends_on": "update_stock",
"fieldname": "warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -309,19 +426,19 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Currency",
"label": "Warehouse",
"length": 0,
"no_copy": 0,
"oldfieldname": "currency",
"oldfieldtype": "Select",
"options": "Currency",
"oldfieldname": "warehouse",
"oldfieldtype": "Link",
"options": "Warehouse",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -332,8 +449,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"fieldname": "campaign",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -341,69 +458,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Ignore Pricing Rule",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "allow_delete",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow Delete",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "allow_user_to_edit_rate",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow user to edit Rate",
"label": "Campaign",
"length": 0,
"no_copy": 0,
"options": "Campaign",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -422,6 +480,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_11",
"fieldtype": "Section Break",
"hidden": 0,
@@ -482,6 +541,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_14",
"fieldtype": "Section Break",
"hidden": 0,
@@ -602,6 +662,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_16",
"fieldtype": "Section Break",
"hidden": 0,
@@ -882,6 +943,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "offline_pos_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1037,6 +1099,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_19",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1046,6 +1109,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Accounting",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -1060,6 +1124,38 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Currency",
"length": 0,
"no_copy": 0,
"oldfieldname": "currency",
"oldfieldtype": "Select",
"options": "Currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -1154,38 +1250,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "taxes_and_charges",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Taxes and Charges",
"length": 0,
"no_copy": 0,
"oldfieldname": "charge",
"oldfieldtype": "Link",
"options": "Sales Taxes and Charges Template",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -1309,6 +1373,38 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "taxes_and_charges",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Taxes and Charges",
"length": 0,
"no_copy": 0,
"oldfieldname": "charge",
"oldfieldtype": "Link",
"options": "Sales Taxes and Charges Template",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
@@ -1322,7 +1418,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-09-01 15:55:14.890452",
"modified": "2017-10-27 06:45:32.957674",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",

View File

@@ -41,6 +41,7 @@ def make_pos_profile():
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"income_account": "Sales - _TC",
"name": "_Test POS Profile",
"pos_profile_name": "_Test POS Profile",
"naming_series": "_T-POS Profile-",
"selling_price_list": "_Test Price List",
"territory": "_Test Territory",

View File

@@ -473,6 +473,7 @@ class TestPurchaseInvoice(unittest.TestCase):
import test_records as jv_test_records
jv = frappe.copy_doc(jv_test_records[1])
jv.accounts[0].is_advance = 'Yes'
jv.insert()
jv.submit()

View File

@@ -92,6 +92,7 @@ def update_pos_profile_data(doc, pos_profile, company_data):
doc.customer_group = pos_profile.get('customer_group') or get_root('Customer Group')
doc.territory = pos_profile.get('territory') or get_root('Territory')
doc.terms = frappe.db.get_value('Terms and Conditions', pos_profile.get('tc_name'), 'terms') or doc.terms or ''
doc.offline_pos_name = ''
def get_root(table):
root = frappe.db.sql(""" select name from `tab%(table)s` having

View File

@@ -70,7 +70,6 @@ class SalesInvoice(SellingController):
self.clear_unallocated_advances("Sales Invoice Advance", "advances")
self.add_remarks()
self.validate_write_off_account()
self.validate_duplicate_offline_pos_entry()
self.validate_account_for_change_amount()
self.validate_fixed_asset()
self.set_income_account_for_fixed_assets()
@@ -305,6 +304,7 @@ class SalesInvoice(SellingController):
self.account_for_change_amount = frappe.db.get_value('Company', self.company, 'default_cash_account')
if pos:
self.pos_profile = pos.name
if not for_validate and not self.customer:
self.customer = pos.customer
self.mode_of_payment = pos.mode_of_payment
@@ -463,12 +463,6 @@ class SalesInvoice(SellingController):
if flt(self.write_off_amount) and not self.write_off_account:
msgprint(_("Please enter Write Off Account"), raise_exception=1)
def validate_duplicate_offline_pos_entry(self):
if self.is_pos and self.offline_pos_name \
and frappe.db.get_value('Sales Invoice',
{'offline_pos_name': self.offline_pos_name, 'docstatus': 1}):
frappe.throw(_("Duplicate offline pos sales invoice {0}").format(self.offline_pos_name))
def validate_account_for_change_amount(self):
if flt(self.change_amount) and not self.account_for_change_amount:
msgprint(_("Please enter Account for Change Amount"), raise_exception=1)

View File

@@ -1133,6 +1133,7 @@ class TestSalesInvoice(unittest.TestCase):
import test_records as jv_test_records
jv = frappe.copy_doc(jv_test_records[0])
jv.accounts[0].is_advance = 'Yes'
jv.insert()
jv.submit()

View File

@@ -200,7 +200,7 @@ def update_doc(new_document, reference_doc, args, schedule_date):
new_document.run_method("on_recurring", reference_doc=reference_doc, subscription_doc=args)
def set_subscription_period(args, mcount, new_document):
if new_document.meta.get_field('from_date') and new_document.meta.get_field('to_date'):
if mcount and new_document.meta.get_field('from_date') and new_document.meta.get_field('to_date'):
last_ref_doc = frappe.db.sql("""
select name, from_date, to_date
from `tab{0}`

View File

@@ -179,41 +179,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}
},
dialog_actions: function () {
var me = this;
$(this.list_body).find('.list-select-all').click(function () {
me.removed_items = [];
$(me.list_body).find('.list-delete').prop("checked", $(this).is(":checked"))
if ($(this).is(":checked")) {
$.each(me.si_docs, function (index, data) {
for (key in data) {
me.removed_items.push(key)
}
})
}
me.toggle_delete_button();
})
$(this.list_body).find('.list-delete').click(function () {
me.name = $(this).parent().parent().attr('invoice-name');
if ($(this).is(":checked")) {
me.removed_items.push(me.name);
} else {
me.removed_items.pop(me.name)
}
me.toggle_delete_button();
})
},
edit_record: function () {
var me = this;
doc_data = this.get_invoice_doc(this.si_docs);
if (doc_data) {
this.frm.doc = doc_data[0][this.name];
this.frm.doc = doc_data[0][this.frm.doc.offline_pos_name];
this.set_missing_values();
this.refresh(false);
this.toggle_input_field();
@@ -226,16 +197,15 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.validate_list()
this.remove_doc_from_localstorage()
this.update_localstorage();
// this.dialog_actions();
this.toggle_delete_button();
},
validate_list: function() {
var me = this;
this.si_docs = this.get_submitted_invoice()
$.each(this.removed_items, function(index, name){
$.each(this.removed_items, function(index, pos_name){
$.each(me.si_docs, function(key, data){
if(me.si_docs[key][name] && me.si_docs[key][name].offline_pos_name == name ){
if(me.si_docs[key][pos_name] && me.si_docs[key][pos_name].offline_pos_name == pos_name ){
frappe.throw(__("Submitted orders can not be deleted"))
}
})
@@ -294,7 +264,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
return $.grep(this.si_docs, function (data) {
for (key in data) {
return key == me.name
return key == me.frm.doc.offline_pos_name;
}
})
},
@@ -348,7 +318,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
create_new: function () {
var me = this;
this.frm = {}
this.name = null;
this.load_data(true);
this.setup();
this.set_default_customer()
@@ -362,6 +331,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
if (load_doc) {
this.frm.doc = JSON.parse(localStorage.getItem('doc'));
this.frm.doc.offline_pos_name = null;
}
$.each(this.meta, function (i, data) {
@@ -629,6 +599,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
// this.list_customers.empty();
this.si_docs = this.get_doc_from_localstorage();
if (!this.si_docs.length) {
this.list_customers.find('.list-customers-table').html("");
return;
}
@@ -655,7 +626,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
me.list_customers_btn.toggleClass("view_customer");
me.pos_bill.show();
me.list_customers_btn.show();
me.name = $(this).parents().attr('invoice-name')
me.frm.doc.offline_pos_name = $(this).parents().attr('invoice-name')
me.edit_record();
})
@@ -675,11 +646,11 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
});
$(this.wrapper).find('.list-delete').click(function () {
me.name = $(this).parent().parent().attr('invoice-name');
me.frm.doc.offline_pos_name = $(this).parent().parent().attr('invoice-name');
if ($(this).is(":checked")) {
me.removed_items.push(me.name);
me.removed_items.push(me.frm.doc.offline_pos_name);
} else {
me.removed_items.pop(me.name)
me.removed_items.pop(me.frm.doc.offline_pos_name)
}
me.toggle_delete_button();
@@ -1435,7 +1406,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
},
update_paid_amount_status: function (update_paid_amount) {
if (this.name) {
if (this.frm.doc.offline_pos_name) {
update_paid_amount = update_paid_amount ? false : true;
}
@@ -1643,18 +1614,17 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
create_invoice: function () {
var me = this;
var invoice_data = {}
var invoice_data = {};
this.si_docs = this.get_doc_from_localstorage();
if (this.name) {
this.update_invoice()
if (this.frm.doc.offline_pos_name) {
this.update_invoice();
} else {
this.name = $.now();
this.frm.doc.offline_pos_name = this.name;
this.frm.doc.offline_pos_name = $.now();
this.frm.doc.posting_date = frappe.datetime.get_today();
this.frm.doc.posting_time = frappe.datetime.now_time();
this.frm.doc.pos_profile = this.pos_profile_data['name'];
invoice_data[this.name] = this.frm.doc
this.si_docs.push(invoice_data)
invoice_data[this.frm.doc.offline_pos_name] = this.frm.doc;
this.si_docs.push(invoice_data);
this.update_localstorage();
this.set_primary_action();
}
@@ -1666,12 +1636,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.si_docs = this.get_doc_from_localstorage();
$.each(this.si_docs, function (index, data) {
for (var key in data) {
if (key == me.name) {
if (key == me.frm.doc.offline_pos_name) {
me.si_docs[index][key] = me.frm.doc;
me.update_localstorage();
}
}
})
});
},
update_localstorage: function () {
@@ -1710,6 +1680,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
freeze_screen = this.freeze_screen || false;
if ((this.si_docs.length || this.email_queue_list || this.customers_list) && !this.freeze) {
this.freeze = true;
frappe.call({
method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
freeze: freeze_screen,
@@ -1720,17 +1692,19 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
},
callback: function (r) {
if (r.message) {
me.freeze = false;
me.customers = r.message.synced_customers_list;
me.address = r.message.synced_address;
me.contacts = r.message.synced_contacts;
me.removed_items = r.message.invoice;
me.removed_email = r.message.email_queue
me.removed_customers = r.message.customers
me.removed_email = r.message.email_queue;
me.removed_customers = r.message.customers;
me.remove_doc_from_localstorage();
me.remove_email_queue_from_localstorage();
me.remove_customer_from_localstorage();
me.prepare_customer_mapper()
me.autocomplete_customers()
me.prepare_customer_mapper();
me.autocomplete_customers();
me.render_list_customers();
}
}
})

View File

@@ -6,6 +6,7 @@ QUnit.test("test:Sales Invoice", function(assert) {
() => {
return frappe.tests.make("POS Profile", [
{naming_series: "SINV"},
{pos_profile_name: "_Test POS Profile"},
{country: "India"},
{currency: "INR"},
{write_off_account: "Write Off - FT"},

View File

@@ -19,13 +19,13 @@ class TestFeeValidity(unittest.TestCase):
patient = frappe.new_doc("Patient")
patient.patient_name = "Test Patient"
patient.sex = "Male"
patient.save(ignore_permissions = True)
patient.save(ignore_permissions=True)
patient = patient.name
if not physician:
physician = frappe.new_doc("Physician")
physician.first_name= "Amit Jain"
physician.save(ignore_permissions = True)
physician.first_name = "Amit Jain"
physician.save(ignore_permissions=True)
physician = physician.name
frappe.db.set_value("Healthcare Settings", None, "max_visit", 2)
@@ -50,5 +50,5 @@ def create_appointment(patient, physician, appointment_date):
appointment.patient = patient
appointment.physician = physician
appointment.appointment_date = appointment_date
appointment.save(ignore_permissions = True)
appointment.save(ignore_permissions=True)
return appointment

View File

@@ -30,6 +30,14 @@ frappe.ui.form.on('Patient Appointment', {
frm.add_custom_button(__('Cancel'), function() {
btn_update_status(frm, "Cancelled");
});
frm.add_custom_button(__("Consultation"),function(){
btn_create_consultation(frm);
},"Create");
frm.add_custom_button(__('Vital Signs'), function() {
btn_create_vital_signs(frm);
},"Create");
}
if(frm.doc.status == "Pending"){
frm.add_custom_button(__('Set Open'), function() {
@@ -40,14 +48,6 @@ frappe.ui.form.on('Patient Appointment', {
});
}
frm.add_custom_button(__("Consultation"),function(){
btn_create_consultation(frm);
},"Create");
frm.add_custom_button(__('Vital Signs'), function() {
btn_create_vital_signs(frm);
},"Create");
if(!frm.doc.__islocal){
if(frm.doc.sales_invoice && frappe.user.has_role("Accounts User")){
frm.add_custom_button(__('Invoice'), function() {
@@ -188,7 +188,7 @@ var btn_update_status = function(frm, status){
frappe.call({
method:
"erpnext.healthcare.doctype.patient_appointment.patient_appointment.update_status",
args: {appointmentId: doc.name, status:status},
args: {appointment_id: doc.name, status:status},
callback: function(data){
if(!data.exc){
frm.reload_doc();

View File

@@ -234,6 +234,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"fieldname": "section_break_1",
"fieldtype": "Section Break",
"hidden": 0,
@@ -755,7 +756,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-10-05 12:13:03.204936",
"modified": "2017-10-25 23:33:36.060803",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient Appointment",

View File

@@ -6,66 +6,100 @@ from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
import json
from frappe.utils import getdate
from frappe.utils import getdate, cint
from frappe import _
import datetime
from frappe.core.doctype.sms_settings.sms_settings import send_sms
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account
class PatientAppointment(Document):
def on_update(self):
today = datetime.date.today()
appointment_date = getdate(self.appointment_date)
#If appointment created for today set as open
if(today == appointment_date):
frappe.db.set_value("Patient Appointment",self.name,"status","Open")
# If appointment created for today set as open
if today == appointment_date:
frappe.db.set_value("Patient Appointment", self.name, "status", "Open")
self.reload()
def after_insert(self):
#Check fee validity exists
# Check fee validity exists
appointment = self
validity_exist = validity_exists(appointment.physician, appointment.patient)
if validity_exist :
fee_validity = frappe.get_doc("Fee Validity",validity_exist[0][0])
#Check if the validity is valid
if validity_exist:
fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
# Check if the validity is valid
appointment_date = getdate(appointment.appointment_date)
if((fee_validity.valid_till >= appointment_date) and (fee_validity.visited < fee_validity.max_visit)):
if (fee_validity.valid_till >= appointment_date) and (fee_validity.visited < fee_validity.max_visit):
visited = fee_validity.visited + 1
frappe.db.set_value("Fee Validity",fee_validity.name,"visited",visited)
if(fee_validity.ref_invoice):
frappe.db.set_value("Patient Appointment",appointment.name,"sales_invoice",fee_validity.ref_invoice)
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
if fee_validity.ref_invoice:
frappe.db.set_value("Patient Appointment", appointment.name, "sales_invoice", fee_validity.ref_invoice)
frappe.msgprint(_("{0} has fee validity till {1}").format(appointment.patient, fee_validity.valid_till))
confirm_sms(self)
def appointment_cancel(appointmentId):
appointment = frappe.get_doc("Patient Appointment",appointmentId)
#If invoice --> fee_validity update with -1 visit
if (appointment.sales_invoice):
validity = frappe.db.exists({"doctype": "Fee Validity","ref_invoice": appointment.sales_invoice})
if(validity):
fee_validity = frappe.get_doc("Fee Validity",validity[0][0])
visited = fee_validity.visited - 1
frappe.db.set_value("Fee Validity",fee_validity.name,"visited",visited)
if visited <= 0:
frappe.msgprint(_("Appointment cancelled, Please review and cancel the invoice {0}".format(appointment.sales_invoice)))
else:
frappe.msgprint(_("Appointment cancelled"))
def save(self, *args, **kwargs):
# duration is the only changeable field in the document
if not self.is_new():
self.db_set('duration', cint(self.duration))
else:
super(PatientAppointment, self).save(*args, **kwargs)
def appointment_cancel(appointment_id):
appointment = frappe.get_doc("Patient Appointment", appointment_id)
# If invoice --> fee_validity update with -1 visit
if appointment.sales_invoice:
validity = frappe.db.exists({"doctype": "Fee Validity", "ref_invoice": appointment.sales_invoice})
if validity:
fee_validity = frappe.get_doc("Fee Validity", validity[0][0])
visited = fee_validity.visited - 1
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
if visited <= 0:
frappe.msgprint(
_("Appointment cancelled, Please review and cancel the invoice {0}".format(appointment.sales_invoice))
)
else:
frappe.msgprint(_("Appointment cancelled"))
@frappe.whitelist()
def get_availability_data(date, physician):
# get availability data of 'physician' on 'date'
"""
Get availability data of 'physician' on 'date'
:param date: Date to check in schedule
:param physician: Name of the physician
:return: dict containing a list of available slots, list of appointments and time of appointments
"""
date = getdate(date)
weekday = date.strftime("%A")
available_slots = []
physician_schedule_name = None
physician_schedule = None
time_per_appointment = None
# get physicians schedule
physician_schedule_name = frappe.db.get_value("Physician", physician, "physician_schedule")
physician_schedule = frappe.get_doc("Physician Schedule", physician_schedule_name)
time_per_appointment = frappe.db.get_value("Physician", physician, "time_per_appointment")
if physician_schedule_name:
physician_schedule = frappe.get_doc("Physician Schedule", physician_schedule_name)
time_per_appointment = frappe.db.get_value("Physician", physician, "time_per_appointment")
else:
frappe.throw(_("Dr {0} does not have a Physician Schedule. Add it in Physician master".format(physician)))
for t in physician_schedule.time_slots:
if weekday == t.day:
available_slots.append(t)
if physician_schedule:
for t in physician_schedule.time_slots:
if weekday == t.day:
available_slots.append(t)
# `time_per_appointment` should never be None since validation in `Patient` is supposed to prevent
# that. However, it isn't impossible so we'll prepare for that.
if not time_per_appointment:
frappe.throw(_('"Time Per Appointment" hasn"t been set for Dr {0}. Add it in Physician master.').format(physician))
# if physician not available return
if not available_slots:
@@ -89,27 +123,36 @@ def get_availability_data(date, physician):
"time_per_appointment": time_per_appointment
}
@frappe.whitelist()
def update_status(appointmentId, status):
frappe.db.set_value("Patient Appointment",appointmentId,"status",status)
if(status=="Cancelled"):
appointment_cancel(appointmentId)
def update_status(appointment_id, status):
frappe.db.set_value("Patient Appointment", appointment_id, "status", status)
if status == "Cancelled":
appointment_cancel(appointment_id)
@frappe.whitelist()
def set_open_appointments():
today = getdate()
frappe.db.sql("""update `tabPatient Appointment` set status='Open' where status = 'Scheduled' and appointment_date = %s""",(today))
frappe.db.sql(
"update `tabPatient Appointment` set status='Open' where status = 'Scheduled'"
" and appointment_date = %s", today)
@frappe.whitelist()
def set_pending_appointments():
today = getdate()
frappe.db.sql("""update `tabPatient Appointment` set status='Pending' where status in ('Scheduled','Open') and appointment_date < %s""",(today))
frappe.db.sql(
"update `tabPatient Appointment` set status='Pending' where status in "
"('Scheduled','Open') and appointment_date < %s", today)
def confirm_sms(doc):
if (frappe.db.get_value("Healthcare Settings", None, "app_con")=='1'):
if frappe.db.get_value("Healthcare Settings", None, "app_con") == '1':
message = frappe.db.get_value("Healthcare Settings", None, "app_con_msg")
send_message(doc, message)
@frappe.whitelist()
def create_invoice(company, physician, patient, appointment_id, appointment_date):
if not appointment_id:
@@ -134,21 +177,24 @@ def create_invoice(company, physician, patient, appointment_id, appointment_date
frappe.db.set_value("Consultation", consultation[0][0], "invoice", sales_invoice.name)
return sales_invoice.name
def get_fee_validity(physician, patient, date):
validity_exist = validity_exists(physician, patient)
if validity_exist :
fee_validity = frappe.get_doc("Fee Validity",validity_exist[0][0])
if validity_exist:
fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
fee_validity = update_fee_validity(fee_validity, date)
else:
fee_validity = create_fee_validity(physician, patient, date)
return fee_validity
def validity_exists(physician, patient):
return frappe.db.exists({
"doctype": "Fee Validity",
"physician": physician,
"patient": patient})
def update_fee_validity(fee_validity, date):
max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
@@ -164,6 +210,7 @@ def update_fee_validity(fee_validity, date):
fee_validity.save(ignore_permissions=True)
return fee_validity
def create_fee_validity(physician, patient, date):
fee_validity = frappe.new_doc("Fee Validity")
fee_validity.physician = physician
@@ -171,6 +218,7 @@ def create_fee_validity(physician, patient, date):
fee_validity = update_fee_validity(fee_validity, date)
return fee_validity
def create_invoice_items(appointment_id, physician, company, invoice):
item_line = invoice.append("items")
item_line.item_name = "Consulting Charges"
@@ -178,16 +226,17 @@ def create_invoice_items(appointment_id, physician, company, invoice):
item_line.qty = 1
item_line.uom = "Nos"
item_line.conversion_factor = 1
item_line.income_account = get_income_account(physician,company)
item_line.income_account = get_income_account(physician, company)
op_consulting_charge = frappe.db.get_value("Physician", physician, "op_consulting_charge")
if op_consulting_charge:
item_line.rate = op_consulting_charge
item_line.amount = op_consulting_charge
return invoice
@frappe.whitelist()
def create_consultation(appointment):
appointment = frappe.get_doc("Patient Appointment",appointment)
appointment = frappe.get_doc("Patient Appointment", appointment)
consultation = frappe.new_doc("Consultation")
consultation.appointment = appointment.name
consultation.patient = appointment.patient
@@ -199,29 +248,37 @@ def create_consultation(appointment):
consultation.invoice = appointment.sales_invoice
return consultation.as_dict()
def remind_appointment():
if (frappe.db.get_value("Healthcare Settings", None, "app_rem")=='1'):
if frappe.db.get_value("Healthcare Settings", None, "app_rem") == '1':
rem_before = datetime.datetime.strptime(frappe.get_value("Healthcare Settings", None, "rem_before"), "%H:%M:%S")
rem_dt = datetime.datetime.now() + datetime.timedelta(hours = rem_before.hour, minutes=rem_before.minute, seconds= rem_before.second)
rem_dt = datetime.datetime.now() + datetime.timedelta(
hours=rem_before.hour, minutes=rem_before.minute, seconds=rem_before.second)
appointment_list = frappe.db.sql("select name from `tabPatient Appointment` where start_dt between %s and %s and reminded = 0 ", (datetime.datetime.now(), rem_dt))
appointment_list = frappe.db.sql(
"select name from `tabPatient Appointment` where start_dt between %s and %s and reminded = 0 ",
(datetime.datetime.now(), rem_dt)
)
for i in range (0,len(appointment_list)):
for i in range(0, len(appointment_list)):
doc = frappe.get_doc("Patient Appointment", appointment_list[i][0])
message = frappe.db.get_value("Healthcare Settings", None, "app_rem_msg")
send_message(doc, message)
frappe.db.set_value("Patient Appointment",doc.name,"reminded",1)
frappe.db.set_value("Patient Appointment", doc.name, "reminded",1)
def send_message(doc, message):
patient = frappe.get_doc("Patient",doc.patient)
if(patient.mobile):
patient = frappe.get_doc("Patient", doc.patient)
if patient.mobile:
context = {"doc": doc, "alert": doc, "comments": None}
if doc.get("_comments"):
context["comments"] = json.loads(doc.get("_comments"))
#jinja to string convertion happens here
# jinja to string convertion happens here
message = frappe.render_template(message, context)
number = [patient.mobile]
send_sms(number,message)
send_sms(number, message)
@frappe.whitelist()
def get_events(start, end, filters=None):

View File

@@ -501,6 +501,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "In minutes",
"fieldname": "time_per_appointment",
"fieldtype": "Data",
"hidden": 0,
@@ -809,7 +810,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-10-04 17:35:44.363742",
"modified": "2017-10-05 16:08:24.624644",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Physician",

View File

@@ -20,22 +20,32 @@ class Physician(Document):
[cstr(self.get(f)).strip() for f in ["first_name","middle_name","last_name"]]))
def validate(self):
self.validate_schedule_and_time()
validate_party_accounts(self)
if self.user_id:
self.validate_for_enabled_user_id()
self.validate_duplicate_user_id()
existing_user_id = frappe.db.get_value("Physician", self.name, "user_id")
if(self.user_id != existing_user_id):
if self.user_id != existing_user_id:
frappe.permissions.remove_user_permission(
"Physician", self.name, existing_user_id)
else:
existing_user_id = frappe.db.get_value("Physician", self.name, "user_id")
if existing_user_id:
frappe.permissions.remove_user_permission(
"Physician", self.name, existing_user_id)
def validate_schedule_and_time(self):
if (self.physician_schedule or self.time_per_appointment) and \
not (self.physician_schedule and self.time_per_appointment):
frappe.msgprint(
_('Both "Physician Schedule" and Time Per Appointment" must be set for Dr {0}').format(
self.first_name),
title='Error', raise_exception=1, indicator='red'
)
def on_update(self):
if self.user_id:
frappe.permissions.add_user_permission("Physician", self.name, self.user_id)

View File

@@ -3,8 +3,35 @@
# See license.txt
from __future__ import unicode_literals
import unittest
import frappe
test_dependencies = ['Physician Schedule']
# test_records = frappe.get_test_records('Physician')
class TestPhysician(unittest.TestCase):
pass
def tearDown(self):
frappe.delete_doc_if_exists('Physician', '_Testdoctor2', force=1)
def test_schedule_and_time(self):
physician = frappe.new_doc('Physician')
physician.first_name = '_Testdoctor2'
physician.physician_schedule = '_Testdoctor2 Schedule'
self.assertRaises(frappe.ValidationError, physician.insert)
physician.physician_schedule = ''
physician.time_per_appointment = 15
self.assertRaises(frappe.ValidationError, physician.insert)
physician.physician_schedule = '_Testdoctor2 Schedule'
physician.time_per_appointment = 15
physician.insert()
def test_new_physician_without_schedule(self):
physician = frappe.new_doc('Physician')
physician.first_name = '_Testdoctor2'
physician.insert()
self.assertEqual(frappe.get_value('Physician', '_Testdoctor2', 'first_name'), '_Testdoctor2')

View File

@@ -5,5 +5,7 @@
from __future__ import unicode_literals
from frappe.model.document import Document
class PhysicianSchedule(Document):
pass
def autoname(self):
self.name = self.schedule_name

View File

@@ -0,0 +1,8 @@
[
{
"schedule_name": "_Testdoctor1 Schedule"
},
{
"schedule_name": "_Testdoctor2 Schedule"
}
]

View File

@@ -87,22 +87,24 @@ frappe.ui.form.on('Employee Loan', {
},
employee_loan_application: function (frm) {
return frappe.call({
method: "erpnext.hr.doctype.employee_loan.employee_loan.get_employee_loan_application",
args: {
"employee_loan_application": frm.doc.employee_loan_application
},
callback: function (r) {
if (!r.exc && r.message) {
frm.set_value("loan_type", r.message.loan_type);
frm.set_value("loan_amount", r.message.loan_amount);
frm.set_value("repayment_method", r.message.repayment_method);
frm.set_value("monthly_repayment_amount", r.message.repayment_amount);
frm.set_value("repayment_periods", r.message.repayment_periods);
frm.set_value("rate_of_interest", r.message.rate_of_interest);
}
}
})
if(frm.doc.employee_loan_application){
return frappe.call({
method: "erpnext.hr.doctype.employee_loan.employee_loan.get_employee_loan_application",
args: {
"employee_loan_application": frm.doc.employee_loan_application
},
callback: function (r) {
if (!r.exc && r.message) {
frm.set_value("loan_type", r.message.loan_type);
frm.set_value("loan_amount", r.message.loan_amount);
frm.set_value("repayment_method", r.message.repayment_method);
frm.set_value("monthly_repayment_amount", r.message.repayment_amount);
frm.set_value("repayment_periods", r.message.repayment_periods);
frm.set_value("rate_of_interest", r.message.rate_of_interest);
}
}
});
}
},
repayment_method: function (frm) {

View File

@@ -34,7 +34,9 @@ def get_categories():
return response
@frappe.whitelist()
def get_item_details(hub_sync_id):
def get_item_details(hub_sync_id=None):
if not hub_sync_id:
return
connection = get_connection()
return connection.get_doc('Hub Item', hub_sync_id)

View File

@@ -382,6 +382,7 @@ erpnext.hub.Hub = class Hub {
},
method: "erpnext.hub_node.get_item_details",
callback: (r) => {
if (!r || !r.message) return;
let item = r.message;
this.item_cache[item_code] = item;
this.render_item_page(item);

View File

@@ -569,7 +569,7 @@ def get_events(start, end, filters=None):
where ((ifnull(planned_start_date, '0000-00-00')!= '0000-00-00') \
and (planned_start_date <= %(end)s) \
and ((ifnull(planned_start_date, '0000-00-00')!= '0000-00-00') \
and planned_end_date >= %(start)s)) {conditions}
and ifnull(planned_end_date, '2199-12-31 00:00:00') >= %(start)s)) {conditions}
""".format(conditions=conditions), {
"start": start,
"end": end

View File

@@ -455,3 +455,4 @@ erpnext.patches.v9_0.add_healthcare_domain
erpnext.patches.v9_0.set_variant_item_description
erpnext.patches.v9_0.set_uoms_in_variant_field
erpnext.patches.v9_0.copy_old_fees_field_data
erpnext.patches.v9_0.set_pos_profile_name

View File

@@ -0,0 +1,19 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
doctype = 'POS Profile'
frappe.reload_doctype(doctype)
for pos in frappe.get_all(doctype):
doc = frappe.get_doc(doctype, pos.name)
if not doc.user: continue
doc.pos_profile_name = doc.user + ' - ' + doc.company
doc.save()
frappe.rename_doc(doctype, doc.name, doc.pos_profile_name, force=True)

View File

@@ -17,6 +17,8 @@ def execute():
doc = frappe.get_doc(doctype, record)
if doc.items:
if not doc.schedule_date:
min_schedule_date = min([d.schedule_date for d in doc.items])
frappe.db.set_value(doctype, record,
"schedule_date", min_schedule_date, update_modified=False)
schedule_dates = [d.schedule_date for d in doc.items if d.schedule_date]
if len(schedule_dates) > 0:
min_schedule_date = min(schedule_dates)
frappe.db.set_value(doctype, record,
"schedule_date", min_schedule_date, update_modified=False)

View File

@@ -38,7 +38,7 @@ $.extend(erpnext, {
},
stale_rate_allowed: () => {
return cint(frappe.boot.sysdefaults.allow_stale) || 1;
return cint(frappe.boot.sysdefaults.allow_stale);
},
setup_serial_no: function() {

View File

@@ -477,9 +477,11 @@ def make_delivery_note(source_name, target_doc=None):
target.qty = flt(source.qty) - flt(source.delivered_qty)
item = frappe.db.get_value("Item", target.item_code, ["item_group", "selling_cost_center"], as_dict=1)
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \
or item.selling_cost_center \
or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
if item:
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \
or item.selling_cost_center \
or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
target_doc = get_mapped_doc("Sales Order", source_name, {
"Sales Order": {

View File

@@ -43,6 +43,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
make() {
return frappe.run_serially([
() => frappe.dom.freeze(),
() => {
this.prepare_dom();
this.prepare_menu();
@@ -55,6 +56,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
frappe.timeout(1);
this.make_items();
this.bind_events();
frappe.dom.unfreeze();
},
() => this.page.set_title(__('Point of Sale'))
]);
@@ -156,6 +158,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
}
update_item_in_cart(item_code, field='qty', value=1) {
frappe.dom.freeze();
if(this.cart.exists(item_code)) {
const item = this.frm.doc.items.find(i => i.item_code === item_code);
frappe.flags.hide_serial_batch_dialog = false;
@@ -208,7 +211,9 @@ erpnext.pos.PointOfSale = class PointOfSale {
this.update_item_in_frm(item)
.then(() => {
// update cart
this.remove_item_from_cart(item);
if (item.qty === 0) {
frappe.model.clear_doc(item.doctype, item.name);
}
this.update_cart_data(item);
});
}, true);
@@ -218,6 +223,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
this.cart.add_item(item);
this.cart.update_taxes_and_totals();
this.cart.update_grand_total();
frappe.dom.unfreeze();
}
update_item_in_frm(item, field, value) {
@@ -227,22 +233,16 @@ erpnext.pos.PointOfSale = class PointOfSale {
}
if (field) {
frappe.model.set_value(item.doctype, item.name, field, value);
return frappe.model.set_value(item.doctype, item.name, field, value)
.then(() => this.frm.script_manager.trigger('qty', item.doctype, item.name))
.then(() => {
if (field === 'qty' && item.qty === 0) {
frappe.model.clear_doc(item.doctype, item.name);
}
})
}
return this.frm.script_manager
.trigger('qty', item.doctype, item.name)
.then(() => {
if (field === 'qty') {
this.remove_item_from_cart(item);
}
});
}
remove_item_from_cart(item) {
if (item.qty === 0) {
frappe.model.clear_doc(item.doctype, item.name);
}
return Promise.resolve();
}
make_payment_modal() {

View File

@@ -71,9 +71,9 @@ def get_items(start, page_length, price_list, item_group, search_value=""):
def get_conditions(item_code, serial_no, batch_no, barcode):
if serial_no or batch_no or barcode:
return frappe.db.escape(item_code), "i.item_code = %(item_code)s"
return frappe.db.escape(item_code), "i.name = %(item_code)s"
condition = """(i.item_code like %(item_code)s
condition = """(i.name like %(item_code)s
or i.item_name like %(item_code)s)"""
return '%%%s%%'%(frappe.db.escape(item_code)), condition

View File

@@ -40,7 +40,7 @@ def setup_complete(args=None):
frappe.local.message_log = []
domain_settings = frappe.get_single('Domain Settings')
domain_settings.set_active_domains([args.get('domain')])
domain_settings.set_active_domains([_(args.get('domain'))])
frappe.db.commit()
login_as_first_user(args)

View File

@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe.utils import cint
def boot_session(bootinfo):
"""boot session - send website info if guest"""
@@ -19,8 +20,8 @@ def boot_session(bootinfo):
'territory')
bootinfo.sysdefaults.customer_group = frappe.db.get_single_value('Selling Settings',
'customer_group')
bootinfo.sysdefaults.allow_stale = frappe.db.get_single_value('Accounts Settings',
'allow_stale') or 1
bootinfo.sysdefaults.allow_stale = cint(frappe.db.get_single_value('Accounts Settings',
'allow_stale'))
bootinfo.notification_settings = frappe.get_doc("Notification Control",
"Notification Control")

View File

@@ -57,7 +57,7 @@ class Item(WebsiteGenerator):
if not self.description:
self.description = self.item_name
if self.is_sales_item and not self.is_item_from_hub:
if self.is_sales_item and not self.get('is_item_from_hub'):
self.publish_in_hub = 1
def after_insert(self):
@@ -624,7 +624,8 @@ class Item(WebsiteGenerator):
template_item.save()
def update_variants(self):
if self.flags.dont_update_variants:
if self.flags.dont_update_variants or \
frappe.db.get_single_value('Item Variant Settings', 'do_not_update_variants'):
return
if self.has_variants:
updated = []

View File

@@ -4,12 +4,12 @@ frappe.listview_settings['Item'] = {
filters: [["disabled", "=", "0"]],
get_indicator: function(doc) {
if(doc.total_projected_qty < 0) {
return [__("Shortage"), "red", "total_projected_qty,<,0"];
} else if (doc.disabled) {
if (doc.disabled) {
return [__("Disabled"), "grey", "disabled,=,Yes"];
} else if (doc.end_of_life && doc.end_of_life < frappe.datetime.get_today()) {
return [__("Expired"), "grey", "end_of_life,<,Today"];
} else if(doc.total_projected_qty < 0) {
return [__("Shortage"), "red", "total_projected_qty,<,0"];
} else if (doc.has_variants) {
return [__("Template"), "orange", "has_variants,=,Yes"];
} else if (doc.variant_of) {

View File

@@ -12,6 +12,66 @@
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_3",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "If enabled then system will not update the fields of variants from the template but will copy the data of below mentioned fields while making new variant",
"fieldname": "do_not_update_variants",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Do not Update Variants",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -84,8 +144,8 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2017-09-11 12:05:16.288601",
"modified_by": "rohit@erpnext.com",
"modified": "2017-11-08 11:38:12.821404",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item Variant Settings",
"name_case": "",

View File

@@ -32,7 +32,7 @@ class Issue(Document):
if email_id:
if not self.lead:
self.lead = frappe.db.get_value("Lead", {"email_id": email_id})
if not self.contact:
if not self.contact and not self.customer:
self.contact = frappe.db.get_value("Contact", {"email_id": email_id})
if self.contact: