Merge branch 'master' into develop
This commit is contained in:
commit
5fa2adcca9
@ -4,7 +4,7 @@ import inspect
|
||||
import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
|
||||
__version__ = '9.1.5'
|
||||
__version__ = '9.1.6'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
@ -486,17 +486,21 @@ def submit_invoice(si_doc, name, doc, name_list):
|
||||
if frappe.message_log: frappe.message_log.pop()
|
||||
frappe.db.rollback()
|
||||
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
|
||||
|
||||
def save_invoice(e, si_doc, name, name_list):
|
||||
def save_invoice(doc, name, name_list):
|
||||
try:
|
||||
if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}):
|
||||
si_doc.docstatus = 0
|
||||
si_doc.flags.ignore_mandatory = True
|
||||
si_doc.due_date = si_doc.posting_date
|
||||
si_doc.insert()
|
||||
si = frappe.new_doc('Sales Invoice')
|
||||
si.update(doc)
|
||||
si.set_posting_time = 1
|
||||
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)
|
||||
except Exception:
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
|
@ -3,8 +3,8 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest, copy
|
||||
from frappe.utils import nowdate, add_days, flt
|
||||
import unittest, copy, time
|
||||
from frappe.utils import nowdate, add_days, flt, cint
|
||||
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.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)
|
||||
|
||||
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):
|
||||
# check stock ledger entries
|
||||
sle = frappe.db.sql("""select * from `tabStock Ledger Entry`
|
||||
|
@ -107,6 +107,8 @@ class GrossProfitGenerator(object):
|
||||
|
||||
def process(self):
|
||||
self.grouped = {}
|
||||
self.grouped_data = []
|
||||
|
||||
for row in self.si_list:
|
||||
if self.skip_row(row, self.product_bundles):
|
||||
continue
|
||||
@ -150,7 +152,6 @@ class GrossProfitGenerator(object):
|
||||
|
||||
def get_average_rate_based_on_group_by(self):
|
||||
# sum buying / selling totals for group
|
||||
self.grouped_data = []
|
||||
for key in self.grouped.keys():
|
||||
if self.filters.get("group_by") != "Invoice":
|
||||
for i, row in enumerate(self.grouped[key]):
|
||||
|
@ -816,7 +816,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-21 14:06:46.309322",
|
||||
"modified": "2017-10-17 17:27:06.281494",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Request for Quotation",
|
||||
@ -903,26 +903,6 @@
|
||||
"submit": 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,
|
||||
"apply_user_permissions": 0,
|
||||
|
@ -205,9 +205,10 @@ def copy_attributes_to_variant(item, variant):
|
||||
|
||||
if item.variant_based_on=='Item Attribute':
|
||||
if variant.attributes:
|
||||
variant.description += "\n"
|
||||
for d in variant.attributes:
|
||||
variant.description += "<div>" + d.attribute + ": " + cstr(d.attribute_value) + "</div>"
|
||||
if not variant.description:
|
||||
variant.description += "\n"
|
||||
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):
|
||||
"""Uses template's item code and abbreviations to make variant's item code"""
|
||||
|
@ -78,7 +78,7 @@ def create_invoice(company, patient, physician, consultation_id):
|
||||
create_invoice_items(physician, sales_invoice, company)
|
||||
|
||||
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")
|
||||
if appointment:
|
||||
frappe.db.set_value("Patient Appointment", appointment, "sales_invoice", sales_invoice.name)
|
||||
|
@ -291,5 +291,5 @@ def create_invoice(company, patient, lab_tests, prescriptions):
|
||||
|
||||
@frappe.whitelist()
|
||||
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,
|
||||
`tabLab Prescription` cp where ct.patient='{0}' and cp.parent=ct.name and cp.test_created=0""").format(patient))
|
||||
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=%s and cp.parent=ct.name and cp.test_created=0""", (patient))
|
||||
|
@ -111,10 +111,10 @@ def make_invoice(patient, company):
|
||||
|
||||
@frappe.whitelist()
|
||||
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:
|
||||
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]
|
||||
if vital_sign:
|
||||
|
@ -125,7 +125,7 @@ def create_invoice(company, physician, patient, appointment_id, appointment_date
|
||||
create_invoice_items(appointment_id, physician, company, sales_invoice)
|
||||
|
||||
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)
|
||||
consultation = frappe.db.exists({
|
||||
"doctype": "Consultation",
|
||||
|
@ -147,22 +147,28 @@ class BOM(WebsiteGenerator):
|
||||
if arg.get('scrap_items'):
|
||||
rate = self.get_valuation_rate(arg)
|
||||
elif arg:
|
||||
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['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):
|
||||
if arg.get('bom_no') and self.set_rate_of_sub_assembly_item_based_on_bom:
|
||||
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)
|
||||
|
||||
|
@ -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.student_admission_childtable_migrate
|
||||
erpnext.patches.v9_0.add_healthcare_domain
|
||||
erpnext.patches.v9_0.set_variant_item_description
|
||||
|
45
erpnext/patches/v9_0/set_variant_item_description.py
Normal file
45
erpnext/patches/v9_0/set_variant_item_description.py
Normal 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)
|
@ -159,9 +159,14 @@ frappe.ui.form.on("Timesheet Detail", {
|
||||
});
|
||||
|
||||
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) {
|
||||
d.add(child.hours, "hours");
|
||||
frm._setting_hours = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user