Merge branch 'master' into develop

This commit is contained in:
Saurabh 2017-10-18 16:23:44 +05:30
commit 5fa2adcca9
14 changed files with 141 additions and 57 deletions

View File

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

View File

@ -486,17 +486,21 @@ def submit_invoice(si_doc, name, doc, name_list):
if frappe.message_log: frappe.message_log.pop() if frappe.message_log: frappe.message_log.pop()
frappe.db.rollback() frappe.db.rollback()
frappe.log_error(frappe.get_traceback()) frappe.log_error(frappe.get_traceback())
name_list = save_invoice(e, si_doc, name, name_list) name_list = save_invoice(doc, name, name_list)
return name_list return name_list
def save_invoice(e, si_doc, name, name_list): def save_invoice(doc, name, name_list):
try: try:
if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}): if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}):
si_doc.docstatus = 0 si = frappe.new_doc('Sales Invoice')
si_doc.flags.ignore_mandatory = True si.update(doc)
si_doc.due_date = si_doc.posting_date si.set_posting_time = 1
si_doc.insert() si.customer = get_customer_id(doc)
si.due_date = doc.get('posting_date')
si.flags.ignore_mandatory = True
si.insert(ignore_permissions=True)
frappe.db.commit()
name_list.append(name) name_list.append(name)
except Exception: except Exception:
frappe.log_error(frappe.get_traceback()) frappe.log_error(frappe.get_traceback())

View File

@ -3,8 +3,8 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
import unittest, copy import unittest, copy, time
from frappe.utils import nowdate, add_days, flt from frappe.utils import nowdate, add_days, flt, cint
from frappe.model.dynamic_links import get_dynamic_link_map from frappe.model.dynamic_links import get_dynamic_link_map
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice
@ -665,6 +665,47 @@ class TestSalesInvoice(unittest.TestCase):
self.pos_gl_entry(si, pos, 330) self.pos_gl_entry(si, pos, 330)
def test_make_pos_invoice_in_draft(self):
from erpnext.accounts.doctype.sales_invoice.pos import make_invoice
from erpnext.stock.doctype.item.test_item import make_item
set_perpetual_inventory()
allow_negative_stock = frappe.db.get_single_value('Stock Settings', 'allow_negative_stock')
if allow_negative_stock:
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 0)
make_pos_profile()
timestamp = cint(time.time())
item = make_item("_Test POS Item")
pos = copy.deepcopy(test_records[1])
pos['items'][0]['item_code'] = item.name
pos["is_pos"] = 1
pos["offline_pos_name"] = timestamp
pos["update_stock"] = 1
pos["payments"] = [{'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - _TC', 'amount': 300},
{'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 330}]
invoice_data = [{timestamp: pos}]
si = make_invoice(invoice_data).get('invoice')
self.assertEquals(si[0], timestamp)
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
self.assertEquals(sales_invoice[0].docstatus, 0)
timestamp = cint(time.time())
pos["offline_pos_name"] = timestamp
invoice_data = [{timestamp: pos}]
si1 = make_invoice(invoice_data).get('invoice')
self.assertEquals(si1[0], timestamp)
sales_invoice1 = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
self.assertEquals(sales_invoice1[0].docstatus, 0)
if allow_negative_stock:
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 1)
def pos_gl_entry(self, si, pos, cash_amount): def pos_gl_entry(self, si, pos, cash_amount):
# check stock ledger entries # check stock ledger entries
sle = frappe.db.sql("""select * from `tabStock Ledger Entry` sle = frappe.db.sql("""select * from `tabStock Ledger Entry`

View File

@ -107,6 +107,8 @@ class GrossProfitGenerator(object):
def process(self): def process(self):
self.grouped = {} self.grouped = {}
self.grouped_data = []
for row in self.si_list: for row in self.si_list:
if self.skip_row(row, self.product_bundles): if self.skip_row(row, self.product_bundles):
continue continue
@ -150,7 +152,6 @@ class GrossProfitGenerator(object):
def get_average_rate_based_on_group_by(self): def get_average_rate_based_on_group_by(self):
# sum buying / selling totals for group # sum buying / selling totals for group
self.grouped_data = []
for key in self.grouped.keys(): for key in self.grouped.keys():
if self.filters.get("group_by") != "Invoice": if self.filters.get("group_by") != "Invoice":
for i, row in enumerate(self.grouped[key]): for i, row in enumerate(self.grouped[key]):

View File

@ -816,7 +816,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2017-07-21 14:06:46.309322", "modified": "2017-10-17 17:27:06.281494",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Buying", "module": "Buying",
"name": "Request for Quotation", "name": "Request for Quotation",
@ -903,26 +903,6 @@
"submit": 0, "submit": 0,
"write": 0 "write": 0
}, },
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Supplier",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
{ {
"amend": 0, "amend": 0,
"apply_user_permissions": 0, "apply_user_permissions": 0,

View File

@ -205,9 +205,10 @@ def copy_attributes_to_variant(item, variant):
if item.variant_based_on=='Item Attribute': if item.variant_based_on=='Item Attribute':
if variant.attributes: if variant.attributes:
variant.description += "\n" if not variant.description:
for d in variant.attributes: variant.description += "\n"
variant.description += "<div>" + d.attribute + ": " + cstr(d.attribute_value) + "</div>" for d in variant.attributes:
variant.description += "<div>" + d.attribute + ": " + cstr(d.attribute_value) + "</div>"
def make_variant_item_code(template_item_code, template_item_name, variant): def make_variant_item_code(template_item_code, template_item_name, variant):
"""Uses template's item code and abbreviations to make variant's item code""" """Uses template's item code and abbreviations to make variant's item code"""

View File

@ -78,7 +78,7 @@ def create_invoice(company, patient, physician, consultation_id):
create_invoice_items(physician, sales_invoice, company) create_invoice_items(physician, sales_invoice, company)
sales_invoice.save(ignore_permissions=True) sales_invoice.save(ignore_permissions=True)
frappe.db.sql(_("""update tabConsultation set invoice='{0}' where name='{1}'""").format(sales_invoice.name, consultation_id)) frappe.db.sql("""update tabConsultation set invoice=%s where name=%s""", (sales_invoice.name, consultation_id))
appointment = frappe.db.get_value("Consultation", consultation_id, "appointment") appointment = frappe.db.get_value("Consultation", consultation_id, "appointment")
if appointment: if appointment:
frappe.db.set_value("Patient Appointment", appointment, "sales_invoice", sales_invoice.name) frappe.db.set_value("Patient Appointment", appointment, "sales_invoice", sales_invoice.name)

View File

@ -291,5 +291,5 @@ def create_invoice(company, patient, lab_tests, prescriptions):
@frappe.whitelist() @frappe.whitelist()
def get_lab_test_prescribed(patient): def get_lab_test_prescribed(patient):
return frappe.db.sql(_("""select cp.name, cp.test_code, cp.parent, cp.invoice, ct.physician, ct.consultation_date from tabConsultation ct, return frappe.db.sql("""select cp.name, cp.test_code, cp.parent, cp.invoice, ct.physician, ct.consultation_date from tabConsultation ct,
`tabLab Prescription` cp where ct.patient='{0}' and cp.parent=ct.name and cp.test_created=0""").format(patient)) `tabLab Prescription` cp where ct.patient=%s and cp.parent=ct.name and cp.test_created=0""", (patient))

View File

@ -111,10 +111,10 @@ def make_invoice(patient, company):
@frappe.whitelist() @frappe.whitelist()
def get_patient_detail(patient, company=None): def get_patient_detail(patient, company=None):
patient_dict = frappe.db.sql(_("""select * from tabPatient where name='{0}'""").format(patient), as_dict=1) patient_dict = frappe.db.sql("""select * from tabPatient where name=%s""", (patient), as_dict=1)
if not patient_dict: if not patient_dict:
frappe.throw("Patient not found") frappe.throw("Patient not found")
vital_sign = frappe.db.sql(_("""select * from `tabVital Signs` where patient='{0}' order by signs_date desc limit 1""").format(patient), as_dict=1) vital_sign = frappe.db.sql("""select * from `tabVital Signs` where patient=%s order by signs_date desc limit 1""", (patient), as_dict=1)
details = patient_dict[0] details = patient_dict[0]
if vital_sign: if vital_sign:

View File

@ -125,7 +125,7 @@ def create_invoice(company, physician, patient, appointment_id, appointment_date
create_invoice_items(appointment_id, physician, company, sales_invoice) create_invoice_items(appointment_id, physician, company, sales_invoice)
sales_invoice.save(ignore_permissions=True) sales_invoice.save(ignore_permissions=True)
frappe.db.sql(_("""update `tabPatient Appointment` set sales_invoice='{0}' where name='{1}'""").format(sales_invoice.name, appointment_id)) frappe.db.sql("""update `tabPatient Appointment` set sales_invoice=%s where name=%s""", (sales_invoice.name, appointment_id))
frappe.db.set_value("Fee Validity", fee_validity.name, "ref_invoice", sales_invoice.name) frappe.db.set_value("Fee Validity", fee_validity.name, "ref_invoice", sales_invoice.name)
consultation = frappe.db.exists({ consultation = frappe.db.exists({
"doctype": "Consultation", "doctype": "Consultation",

View File

@ -147,22 +147,28 @@ class BOM(WebsiteGenerator):
if arg.get('scrap_items'): if arg.get('scrap_items'):
rate = self.get_valuation_rate(arg) rate = self.get_valuation_rate(arg)
elif arg: elif arg:
if self.rm_cost_as_per == 'Valuation Rate': if arg.get('bom_no') and self.set_rate_of_sub_assembly_item_based_on_bom:
rate = self.get_valuation_rate(arg)
elif self.rm_cost_as_per == 'Last Purchase Rate':
rate = arg['last_purchase_rate'] \
or frappe.db.get_value("Item", arg['item_code'], "last_purchase_rate")
elif self.rm_cost_as_per == "Price List":
if not self.buying_price_list:
frappe.throw(_("Please select Price List"))
rate = frappe.db.get_value("Item Price",
{"price_list": self.buying_price_list, "item_code": arg["item_code"]}, "price_list_rate")
price_list_currency = frappe.db.get_value("Price List", self.buying_price_list, "currency")
if price_list_currency != self.company_currency():
rate = flt(rate * self.conversion_rate)
if arg['bom_no'] and (not rate or self.set_rate_of_sub_assembly_item_based_on_bom):
rate = self.get_bom_unitcost(arg['bom_no']) rate = self.get_bom_unitcost(arg['bom_no'])
else:
if self.rm_cost_as_per == 'Valuation Rate':
rate = self.get_valuation_rate(arg)
elif self.rm_cost_as_per == 'Last Purchase Rate':
rate = arg.get('last_purchase_rate') \
or frappe.db.get_value("Item", arg['item_code'], "last_purchase_rate")
elif self.rm_cost_as_per == "Price List":
if not self.buying_price_list:
frappe.throw(_("Please select Price List"))
rate = frappe.db.get_value("Item Price", {"price_list": self.buying_price_list,
"item_code": arg["item_code"]}, "price_list_rate")
price_list_currency = frappe.db.get_value("Price List",
self.buying_price_list, "currency")
if price_list_currency != self.company_currency():
rate = flt(rate * self.conversion_rate)
if not rate:
frappe.msgprint(_("{0} not found for Item {1}")
.format(self.rm_cost_as_per, arg["item_code"]))
return flt(rate) return flt(rate)

View File

@ -452,3 +452,4 @@ erpnext.patches.v9_0.fix_subscription_next_date
erpnext.patches.v9_0.set_schedule_date_for_material_request_and_purchase_order erpnext.patches.v9_0.set_schedule_date_for_material_request_and_purchase_order
erpnext.patches.v9_0.student_admission_childtable_migrate erpnext.patches.v9_0.student_admission_childtable_migrate
erpnext.patches.v9_0.add_healthcare_domain erpnext.patches.v9_0.add_healthcare_domain
erpnext.patches.v9_0.set_variant_item_description

View File

@ -0,0 +1,45 @@
import frappe
from frappe.utils import cstr
def execute():
'''
Issue:
While copying data from template item to variant item,
the system appending description multiple times to the respective variant.
Purpose:
Check variant description,
if variant have user defined description remove all system appended descriptions
else replace multiple system generated descriptions with single description
Steps:
1. Get all variant items
2. Create system generated variant description
3. If variant have user defined description, remove all system generated descriptions
4. If variant description only contains system generated description,
replace multiple descriptions by new description.
'''
for item in frappe.db.sql(""" select name from tabItem
where ifnull(variant_of, '') != '' """,as_dict=1):
variant = frappe.get_doc("Item", item.name)
temp_variant_description = '\n'
if variant.attributes:
for d in variant.attributes:
temp_variant_description += "<div>" + d.attribute + ": " + cstr(d.attribute_value) + "</div>"
variant_description = variant.description.replace(temp_variant_description, '').rstrip()
if variant_description:
splitted_desc = variant.description.strip().split(temp_variant_description)
if len(splitted_desc) > 2:
if splitted_desc[0] == '':
variant_description = temp_variant_description + variant_description
elif splitted_desc[1] == '' or splitted_desc[1] == '\n':
variant_description += temp_variant_description
variant.db_set('description', variant_description, update_modified=False)
else:
variant.db_set('description', variant_description, update_modified=False)
else:
variant.db_set('description', temp_variant_description, update_modified=False)

View File

@ -159,9 +159,14 @@ frappe.ui.form.on("Timesheet Detail", {
}); });
var calculate_end_time = function(frm, cdt, cdn) { var calculate_end_time = function(frm, cdt, cdn) {
var child = locals[cdt][cdn]; let child = locals[cdt][cdn];
var d = moment(child.from_time); if(!child.from_time) {
// if from_time value is not available then set the current datetime
frappe.model.set_value(cdt, cdn, "from_time", frappe.datetime.get_datetime_as_string());
}
let d = moment(child.from_time);
if(child.hours) { if(child.hours) {
d.add(child.hours, "hours"); d.add(child.hours, "hours");
frm._setting_hours = true; frm._setting_hours = true;