Exemple #1
0
def write_docfile(data):
	import os
	for indx, file_path in enumerate(data.get('files')):
		base_dir_path = os.path.join(os.getcwd(), get_site_path().replace('.',"").replace('/', ""), 'public', 'files')
		folder_lst = file_path.split('/')
		file_path =  '/'.join(folder_lst[:-1]) 
		doc_name = folder_lst[-1:][0]
		doc_base_path = os.path.join(base_dir_path, file_path)

		if '-watermark' not in doc_name:
			dname = doc_name.split('.')
			doc_name = dname[0]+'-watermark.'+dname[1]

		data.get('files')[indx] = "{doc_base_path}/{doc_name}".format(doc_base_path=doc_base_path, doc_name=doc_name)

		if not os.path.exists(doc_base_path + '/' +doc_name):
			frappe.create_folder(doc_base_path)
			data = {
				"entityid": folder_lst[4],
				"profile_id": folder_lst[0],
				"event_id": folder_lst[1],
				"tag_id": folder_lst[4] + '-' + cstr(folder_lst[2].split('-')[1]) + cstr(folder_lst[3].split('_')[1]),
				"file_id": [
					doc_name.replace('-watermark','')
				],
				"file_location": [
					doc_base_path + '/' + doc_name
				]
			}

			from templates.pages.event import write_file
			res = write_file(data)
Exemple #2
0
def get_data(filters):
	conditions, filters = get_conditions(filters)

        data = frappe.db.sql("""
                select t1.employee, t3.employee_name, t1.designation, t3.passport_number,
                        sum(case when t2.salary_component = 'Basic Pay' then ifnull(t2.amount,0) else 0 end) as basicpay,
                        t3.nppf_number,
                        sum(case when t2.salary_component = 'PF' then ifnull(t2.amount,0) else 0 end) as employeepf,
                        sum(case when t2.salary_component = 'PF' then ifnull(t2.amount,0) else 0 end) as employerpf,
                        sum(case when t2.salary_component = 'PF' then ifnull(t2.amount,0)*2 else 0 end) as total,
                        t1.company, t1.branch, t1.department, t1.division, t1.section,
                        t1.fiscal_year, t1.month
                from `tabSalary Slip` t1, `tabSalary Detail` t2, `tabEmployee` t3
                where t1.docstatus = 1 %s
                and t3.employee = t1.employee
                and t2.parent = t1.name
                and t2.salary_component in ('Basic Pay','PF')
                group by t1.employee, t3.employee_name, t1.designation, t3.passport_number,
                        t3.nppf_number, t1.company, t1.branch, t1.department, t1.division, t1.section,
                        t1.fiscal_year, t1.month
                """ % conditions, filters)
		
	if not data:
		msgprint(_("No Data Found for month: ") + cstr(filters.get("month")) + 
			_(" and year: ") + cstr(filters.get("fiscal_year")), raise_exception=1)
	
	return data
Exemple #3
0
	def get_outstanding_invoices(self):
		self.set('accounts', [])
		total = 0
		for d in self.get_values():
			total += flt(d.outstanding_amount, self.precision("credit", "accounts"))
			jd1 = self.append('accounts', {})
			jd1.account = d.account
			jd1.party = d.party

			if self.write_off_based_on == 'Accounts Receivable':
				jd1.party_type = "Customer"
				jd1.credit = flt(d.outstanding_amount, self.precision("credit", "accounts"))
				jd1.reference_type = "Sales Invoice"
				jd1.reference_name = cstr(d.name)
			elif self.write_off_based_on == 'Accounts Payable':
				jd1.party_type = "Supplier"
				jd1.debit = flt(d.outstanding_amount, self.precision("debit", "accounts"))
				jd1.reference_type = "Purchase Invoice"
				jd1.reference_name = cstr(d.name)

		jd2 = self.append('accounts', {})
		if self.write_off_based_on == 'Accounts Receivable':
			jd2.debit = total
		elif self.write_off_based_on == 'Accounts Payable':
			jd2.credit = total

		self.validate_total_debit_and_credit()
def merge_merchandise_items(doc):
	amount = 0.0
	for d in doc.get('merchandise_item'):
		e = doc.append('entries', {})
		e.barcode=d.merchandise_barcode
		e.item_code=d.merchandise_item_code
		e.item_name=d.merchandise_item_name
		e.item_group = frappe.db.get_value('Item', d.merchandise_item_code, 'item_group')
		e.work_order=d.merchandise_work_order
		e.description=d.merchandise_description
		e.sales_invoice_branch = d.merchandise_branch
		e.warehouse = frappe.db.get_value('Branch', d.merchandise_branch, 'warehouse')
		e.income_account=d.merchandise_income_account
		e.cost_center=d.merchandise_cost_center
		e.batch_no=d.merchandise_batch_no
		e.item_tax_rate=d.merchandise_item_tax_rate
		e.stock_uom=d.merchandise_stock_uom 
		e.price_list_rate=d.merchandise_price_list_rate
		e.discount_percentage=d.merchandise_discount_percentage
		e.amount= d.merchandise_amount
		e.base_amount=cstr(flt(d.merchandise_amount)*flt(doc.conversion_rate))
		e.base_rate=cstr(flt(d.merchandise_rate)*flt(doc.conversion_rate))
		e.rate=d.merchandise_rate
		e.base_price_list_rate=d.merchandise_base_price_list_rate
		e.qty=d.merchandise_qty
		e.base_price_list_rate=d.merchandise_base_price_list_rate
		e.delivery_date  =  d.merchandise_delivery_date
		amount += flt(e.amount) 
	return amount
Exemple #5
0
def find_variant(template, args, variant_item_code=None):
	conditions = ["""(iv_attribute.attribute="{0}" and iv_attribute.attribute_value="{1}")"""\
		.format(frappe.db.escape(key), frappe.db.escape(cstr(value))) for key, value in args.items()]

	conditions = " or ".join(conditions)

	# use approximate match and shortlist possible variant matches
	# it is approximate because we are matching using OR condition
	# and it need not be exact match at this stage
	# this uses a simpler query instead of using multiple exists conditions
	possible_variants = frappe.db.sql_list("""select name from `tabItem` item
		where variant_of=%s and exists (
			select name from `tabItem Variant Attribute` iv_attribute
				where iv_attribute.parent=item.name
				and ({conditions}) and parent != %s
		)""".format(conditions=conditions), (template, cstr(variant_item_code)))

	for variant in possible_variants:
		variant = frappe.get_doc("Item", variant)

		if len(args.keys()) == len(variant.get("attributes")):
			# has the same number of attributes and values
			# assuming no duplication as per the validation in Item
			match_count = 0

			for attribute, value in args.items():
				for row in variant.attributes:
					if row.attribute==attribute and row.attribute_value== cstr(value):
						# this row matches
						match_count += 1
						break

			if match_count == len(args.keys()):
				return variant.name
Exemple #6
0
	def get_item_list(self):
		il = []
		for d in self.get("items"):
			if d.qty is None:
				frappe.throw(_("Row {0}: Qty is mandatory").format(d.idx))

			if self.has_product_bundle(d.item_code):
				for p in self.get("packed_items"):
					if p.parent_detail_docname == d.name and p.parent_item == d.item_code:
						# the packing details table's qty is already multiplied with parent's qty
						il.append(frappe._dict({
							'warehouse': p.warehouse or d.warehouse,
							'item_code': p.item_code,
							'qty': flt(p.qty),
							'uom': p.uom,
							'batch_no': cstr(p.batch_no).strip(),
							'serial_no': cstr(p.serial_no).strip(),
							'name': d.name,
							'target_warehouse': p.target_warehouse
						}))
			else:
				il.append(frappe._dict({
					'warehouse': d.warehouse,
					'item_code': d.item_code,
					'qty': d.stock_qty,
					'uom': d.uom,
					'stock_uom': d.stock_uom,
					'conversion_factor': d.conversion_factor,
					'batch_no': cstr(d.get("batch_no")).strip(),
					'serial_no': cstr(d.get("serial_no")).strip(),
					'name': d.name,
					'target_warehouse': d.target_warehouse
				}))
		return il
def get_fy_details(fy_start_date, fy_end_date):
	start_year = getdate(fy_start_date).year
	if start_year == getdate(fy_end_date).year:
		fy = cstr(start_year)
	else:
		fy = cstr(start_year) + '-' + cstr(start_year + 1)
	return fy
Exemple #8
0
def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
	"""returns last purchase details in stock uom"""
	# get last purchase order item details
	last_purchase_order = frappe.db.sql("""\
		select po.name, po.transaction_date, po.conversion_rate,
			po_item.conversion_factor, po_item.base_price_list_rate,
			po_item.discount_percentage, po_item.base_rate
		from `tabPurchase Order` po, `tabPurchase Order Item` po_item
		where po.docstatus = 1 and po_item.item_code = %s and po.name != %s and
			po.name = po_item.parent
		order by po.transaction_date desc, po.name desc
		limit 1""", (item_code, cstr(doc_name)), as_dict=1)

	# get last purchase receipt item details
	last_purchase_receipt = frappe.db.sql("""\
		select pr.name, pr.posting_date, pr.posting_time, pr.conversion_rate,
			pr_item.conversion_factor, pr_item.base_price_list_rate, pr_item.discount_percentage,
			pr_item.base_rate
		from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pr_item
		where pr.docstatus = 1 and pr_item.item_code = %s and pr.name != %s and
			pr.name = pr_item.parent
		order by pr.posting_date desc, pr.posting_time desc, pr.name desc
		limit 1""", (item_code, cstr(doc_name)), as_dict=1)

	purchase_order_date = getdate(last_purchase_order and last_purchase_order[0].transaction_date \
		or "1900-01-01")
	purchase_receipt_date = getdate(last_purchase_receipt and \
		last_purchase_receipt[0].posting_date or "1900-01-01")

	if (purchase_order_date > purchase_receipt_date) or \
			(last_purchase_order and not last_purchase_receipt):
		# use purchase order
		last_purchase = last_purchase_order[0]
		purchase_date = purchase_order_date

	elif (purchase_receipt_date > purchase_order_date) or \
			(last_purchase_receipt and not last_purchase_order):
		# use purchase receipt
		last_purchase = last_purchase_receipt[0]
		purchase_date = purchase_receipt_date

	else:
		return frappe._dict()

	conversion_factor = flt(last_purchase.conversion_factor)
	out = frappe._dict({
		"base_price_list_rate": flt(last_purchase.base_price_list_rate) / conversion_factor,
		"base_rate": flt(last_purchase.base_rate) / conversion_factor,
		"discount_percentage": flt(last_purchase.discount_percentage),
		"purchase_date": purchase_date
	})

	conversion_rate = flt(conversion_rate) or 1.0
	out.update({
		"price_list_rate": out.base_price_list_rate / conversion_rate,
		"rate": out.base_rate / conversion_rate,
		"base_rate": out.base_rate
	})

	return out
	def update_stock_ledger(self):
		sl_entries = []
		stock_items = self.get_stock_items()

		for d in self.get('purchase_receipt_details'):
			if d.item_code in stock_items and d.warehouse:
				pr_qty = flt(d.qty) * flt(d.conversion_factor)

				if pr_qty:
					sl_entries.append(self.get_sl_entries(d, {
						"actual_qty": flt(pr_qty),
						"serial_no": cstr(d.serial_no).strip(),
						"incoming_rate": d.valuation_rate
					}))

				if flt(d.rejected_qty) > 0:
					sl_entries.append(self.get_sl_entries(d, {
						"warehouse": d.rejected_warehouse,
						"actual_qty": flt(d.rejected_qty) * flt(d.conversion_factor),
						"serial_no": cstr(d.rejected_serial_no).strip(),
						"incoming_rate": 0.0
					}))

		self.bk_flush_supp_wh(sl_entries)
		self.make_sl_entries(sl_entries)
def update_details(prop_list=None,followup_type=None,followup_date=None):
	properties = json.loads(prop_list)
	for i in properties:
		lead_property = frappe.get_doc("Lead Property Details", i.get('name'))
		if followup_type=='Follow-Up For Share':
			lead_property.share_followup_status = i.get('status')
			lead_property.share_followup_date = datetime.datetime.strptime(cstr(followup_date),'%d-%m-%Y')
			if i.get("status") in ["Intrested"]:
				lead_property.schedule_se = 1
		elif followup_type=='Follow-Up For SE':
			lead_property.se_follow_up_status = i.get('status')
			lead_property.se_followup_date = datetime.datetime.strptime(cstr(followup_date),'%d-%m-%Y')
			if i.get("status") in ["Reschedule"]:
				lead_property.schedule_se = 1
			if i.get("status") in ["Intrested"]:
				lead_property.schedule_acm = 1
		else:
			lead_property.acm_followup_status = i.get('status')
			lead_property.acm_followup_date = datetime.datetime.strptime(cstr(followup_date),'%d-%m-%Y')
			if i.get("status") in ["Reschedule"]:
				lead_property.schedule_acm = 1
		lead_property.save(ignore_permissions=True)


	return True
Exemple #11
0
	def update_stock_ledger(self):
		sl_entries = []

		# make sl entries for source warehouse first, then do for target warehouse
		for d in self.get('items'):
			if cstr(d.s_warehouse):
				sl_entries.append(self.get_sl_entries(d, {
					"warehouse": cstr(d.s_warehouse),
					"actual_qty": -flt(d.transfer_qty),
					"incoming_rate": 0
				}))

		for d in self.get('items'):
			if cstr(d.t_warehouse):
				sl_entries.append(self.get_sl_entries(d, {
					"warehouse": cstr(d.t_warehouse),
					"actual_qty": flt(d.transfer_qty),
					"incoming_rate": flt(d.valuation_rate)
				}))

		# On cancellation, make stock ledger entry for
		# target warehouse first, to update serial no values properly

			# if cstr(d.s_warehouse) and self.docstatus == 2:
			# 	sl_entries.append(self.get_sl_entries(d, {
			# 		"warehouse": cstr(d.s_warehouse),
			# 		"actual_qty": -flt(d.transfer_qty),
			# 		"incoming_rate": 0
			# 	}))

		if self.docstatus == 2:
			sl_entries.reverse()

		self.make_sl_entries(sl_entries, self.amended_from and 'Yes' or 'No')
Exemple #12
0
	def validate_bom(self):
		if cstr(self.current_bom) == cstr(self.new_bom):
			frappe.throw(_("Current BOM and New BOM can not be same"))
			
		if frappe.db.get_value("BOM", self.current_bom, "item") \
			!= frappe.db.get_value("BOM", self.new_bom, "item"):
				frappe.throw(_("The selected BOMs are not for the same item"))
	def db_insert(self):
		"""INSERT the document (with valid columns) in the database."""
		if not self.name:
			# name will be set by document class in most cases
			set_new_name(self)
		d = self.get_valid_dict()
		columns = d.keys()
		try:
			frappe.db.sql("""insert into `tab{doctype}`
				({columns}) values ({values})""".format(
					doctype = self.doctype,
					columns = ", ".join(["`"+c+"`" for c in columns]),
					values = ", ".join(["%s"] * len(columns))
				), d.values())
		except Exception, e:
			if e.args[0]==1062:
				if "PRIMARY" in cstr(e.args[1]):
					if self.meta.autoname=="hash":
						# hash collision? try again
						self.name = None
						self.db_insert()
						return

					type, value, traceback = sys.exc_info()
					frappe.msgprint(_("Duplicate name {0} {1}").format(self.doctype, self.name))
					raise frappe.DuplicateEntryError, (self.doctype, self.name, e), traceback

				elif "Duplicate" in cstr(e.args[1]):
					# unique constraint
					self.show_unique_validation_message(e)
				else:
					raise
			else:
				raise
Exemple #14
0
def get_disease_fields(name,profile_id=None):
	if name:
		dm = frappe.get_doc("Disease Monitoring",
			frappe.db.get_value("Disease Monitoring",{"disease_name":name},"name"))
		if dm:
			fields, rows, dm_cols, field_mapper = [], [], [{"title":"", "width":"10px !important;"}], ["sr"]
			row_count = 0
			sec_label=name+' Readings'
			fields.append({"fieldname":"","fieldtype":"section_break","label":sec_label,"options":"<i class='fa fa-pencil-square-o'></i>"})
			for d in dm.get('parameters'):
				row_count += 1
				f_dic = {"fieldname":d.fieldname,"fieldtype":d.fieldtype,"label":d.label,"placeholder":"", "required": d.required or 0,}
				fields.append(f_dic)
				dm_cols.append({"title":d.label,"width":cstr(d.width) and cstr(d.width) + 'px !important;' or "10px;"})
				field_mapper.append(d.fieldname)

				if row_count==4:
					row_count=0
					fields.append({"fieldname":"","fieldtype":"column_break","label":""})
			#s_break = {"fieldname":"","fieldtype":"section_break","label":""}	
			#fields.append(s_break)
			rows.append(dm_cols)
			sec_label=name+' Monitoring Logs'		
			fields.append({"fieldname":"","fieldtype":"section_break","label":sec_label,"options":"<i class='fa fa-list-alt'></i>"})
			#raw_fields.append(s_break)
			row_dic={"fieldname":"tab","fieldtype": "table","label": "Disease Monitoring","rows":rows}
			fields.append(row_dic)
			values=get_values(profile_id, fields, dm.event_master_id, field_mapper)

			return {
				"fields":fields, 
				"event_master_id":dm.event_master_id,
				"values":values,
				"field_mapper":field_mapper
			}
Exemple #15
0
def check_stock_uom_with_bin(item, stock_uom):
	if stock_uom == frappe.db.get_value("Item", item, "stock_uom"):
		return

	matched=True
	ref_uom = frappe.db.get_value("Stock Ledger Entry",
		{"item_code": item}, "stock_uom")

	if ref_uom:
		if cstr(ref_uom) != cstr(stock_uom):
			matched = False
	else:
		bin_list = frappe.db.sql("select * from tabBin where item_code=%s", item, as_dict=1)
		for bin in bin_list:
			if (bin.reserved_qty > 0 or bin.ordered_qty > 0 or bin.indented_qty > 0 \
				or bin.planned_qty > 0) and cstr(bin.stock_uom) != cstr(stock_uom):
					matched = False
					break

		if matched and bin_list:
			frappe.db.sql("""update tabBin set stock_uom=%s where item_code=%s""", (stock_uom, item))

	if not matched:
		frappe.throw(_("Default Unit of Measure for Item {0} cannot be changed directly because \
			you have already made some transaction(s) with another UOM. To change default UOM, \
			use 'UOM Replace Utility' tool under Stock module.").format(item))
def store_request_in_elastic_search(property_data, search_query, request_type, adv_search_query=None):
	request_id =  "REQ-"  + cstr(int(time.time())) + '-' +  cstr(random.randint(100000,999999))
	request_dict = {
		"user_id":property_data.get("user_id"),
		"request_id":request_id, 
		"operation":property_data.get("operation"), 
		"property_type":property_data.get("property_type"), 
		"property_subtype":property_data.get("property_subtype"),
		"project_type":property_data.get("project_type"), 
		"project_subtype":property_data.get("project_subtype"),  
		"location":property_data.get("location"), 
		"property_subtype_option":property_data.get("property_subtype_option"), 
		"min_area":property_data.get("min_area"),
		"max_area":property_data.get("max_area"), 
		"min_budget":property_data.get("min_budget"), 
		"max_budget":property_data.get("max_budget"),
		"city":property_data.get("city"),
		"unit_of_area":property_data.get("unit_of_area"),
		"search_query":cstr(search_query),
		"adv_search_query":cstr(adv_search_query),
		"request_type":request_type

	}
	meta_dict = add_meta_fields_before_posting(property_data)
	request_dict.update(meta_dict)
	es = ElasticSearchController()
	es_result = es.index_document("request",request_dict, request_id)
	return request_id
def process_property_data_before_posting(property_data, request_data, email):
	
	"""
		Add necessary fields to property dictionary
		before indexing property data, 
		store image in full size & thumbnails format. 

	"""

	custom_id = "PROP-"  + cstr(int(time.time())) + '-' +  cstr(random.randint(10000,99999))
	property_data["property_id"] = custom_id
	meta_dict = add_meta_fields_before_posting(request_data)
	property_data.update(meta_dict)
	property_photo_url_dict = store_property_photos_in_propshikari(request_data.get("property_photos"),custom_id)
	property_data["full_size_images"] = property_photo_url_dict.get("full_size",[])
	property_data["thumbnails"] = property_photo_url_dict.get("thumbnails",[])
	property_data["property_photo"] = property_photo_url_dict.get("thumbnails")[0] if len(property_photo_url_dict.get("thumbnails")) else ""
	property_data["posted_by"] = request_data.get("user_id")
	property_data["user_email"] = email
	property_data["posting_date"] = property_data.get("posting_date") if property_data.get("posting_date") else property_data.get("creation_date")
	property_data["amenities"] = putil.prepare_amenities_data(property_data.get("amenities",""), property_data.get("property_type"))
	property_data["flat_facilities"] = putil.prepare_flat_facilities_data(property_data.get("flat_facilities",""), property_data.get("property_type"))
	property_data["possession_status"] = "Immediate" if property_data.get("possession") else property_data.get("possession_date")
	property_data["discounted_price"] = putil.get_discounted_price(property_data) if property_data.get("discount_percentage") else 0.0
	mandatory_list = property_mandatory_fields.get(property_data.get("property_type"))
	property_data["percent_completion"] = putil.calculate_percent_completion(property_data, mandatory_list)
	if not property_data.get("possession_date"):
		property_data.pop("possession_date", None)
	return custom_id	
def make_new_document(ref_wrapper, date_field, posting_date):
	from erpnext.accounts.utils import get_fiscal_year
	new_document = frappe.copy_doc(ref_wrapper)
	mcount = month_map[ref_wrapper.recurring_type]

	from_date = get_next_date(ref_wrapper.from_date, mcount)

	# get last day of the month to maintain period if the from date is first day of its own month
	# and to date is the last day of its own month
	if (cstr(get_first_day(ref_wrapper.from_date)) == cstr(ref_wrapper.from_date)) and \
		(cstr(get_last_day(ref_wrapper.to_date)) == cstr(ref_wrapper.to_date)):
			to_date = get_last_day(get_next_date(ref_wrapper.to_date, mcount))
	else:
		to_date = get_next_date(ref_wrapper.to_date, mcount)

	new_document.update({
		date_field: posting_date,
		"from_date": from_date,
		"to_date": to_date,
		"fiscal_year": get_fiscal_year(posting_date)[0],
		"owner": ref_wrapper.owner,
	})

	if ref_wrapper.doctype == "Sales Order":
		new_document.update({
			"delivery_date": get_next_date(ref_wrapper.delivery_date, mcount,
				cint(ref_wrapper.repeat_on_day_of_month))
	})

	new_document.submit()

	return new_document
Exemple #19
0
	def update_stock_ledger(self, allow_negative_stock=False, via_landed_cost_voucher=False):
		sl_entries = []
		stock_items = self.get_stock_items()

		for d in self.get('items'):
			if d.item_code in stock_items and d.warehouse:
				pr_qty = flt(d.qty) * flt(d.conversion_factor)

				if pr_qty:
					val_rate_db_precision = 6 if cint(self.precision("valuation_rate", d)) <= 6 else 9
					sl_entries.append(self.get_sl_entries(d, {
						"actual_qty": flt(pr_qty),
						"serial_no": cstr(d.serial_no).strip(),
						"incoming_rate": flt(d.valuation_rate, val_rate_db_precision)
					}))

				if flt(d.rejected_qty) > 0:
					sl_entries.append(self.get_sl_entries(d, {
						"warehouse": d.rejected_warehouse,
						"actual_qty": flt(d.rejected_qty) * flt(d.conversion_factor),
						"serial_no": cstr(d.rejected_serial_no).strip(),
						"incoming_rate": 0.0
					}))

		self.bk_flush_supp_wh(sl_entries)
		self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock,
			via_landed_cost_voucher=via_landed_cost_voucher)
def create_item(item, warehouse, has_variant=0, attributes=None,variant_of=None):
	item_dict = {
		"doctype": "Item",
		"shopify_id": item.get("id"),
		"shopify_variant_id": item.get("variant_id"),
		"variant_of": variant_of,
		"sync_with_shopify": 1,
		"item_code": cstr(item.get("item_code")) or cstr(item.get("id")),
		"item_name": item.get("title"),
		"description": item.get("body_html") or item.get("title"),
		"item_group": get_item_group(item.get("product_type")),
		"has_variants": has_variant,
		"attributes":attributes or [],
		"stock_uom": item.get("uom") or _("Nos"),
		"stock_keeping_unit": item.get("sku") or get_sku(item),
		"default_warehouse": warehouse,
		"image": get_item_image(item)
	}

	name, item_details = get_item_details(item)

	if not name:
		new_item = frappe.get_doc(item_dict)
		new_item.insert()
		name = new_item.name

	else:
		update_item(item_details, item_dict)

	if not has_variant:
		add_to_price_list(item, name)
	def allocate_leave(self):
		self.validate_values()
		leave_allocated_for = []
		employees = self.get_employees()
		if not employees:
			frappe.throw(_("No employee found"))

		for d in self.get_employees():
			try:
				la = frappe.new_doc('Leave Allocation')
				la.set("__islocal", 1)
				la.employee = cstr(d[0])
				la.employee_name = frappe.db.get_value('Employee',cstr(d[0]),'employee_name')
				la.leave_type = self.leave_type
				la.from_date = self.from_date
				la.to_date = self.to_date
				la.carry_forward = cint(self.carry_forward)
				la.new_leaves_allocated = flt(self.no_of_days)
				la.docstatus = 1
				la.save()
				leave_allocated_for.append(d[0])
			except:
				pass
		if leave_allocated_for:
			msgprint(_("Leaves Allocated Successfully for {0}").format(comma_and(leave_allocated_for)))
def message_braudcast_send(data):
    """
    this will return recipents details
    """
    dts=json.loads(data)
    from frappe.model.db_query import DatabaseQuery
    qry="select user from __Auth where user='******'username'])+"' and password=password('"+cstr(dts['userpass'])+"') "
    valid=frappe.db.sql(qry)
    msg=''
    if not valid:
        return {
                "status":"401",
                "message":"User name or Password is incorrect"
        }   
    if dts['sms']:
    	from erpnext.setup.doctype.sms_settings.sms_settings import send_sms
    	rc_list=frappe.db.sql("select phone_1 from tabMember where phone_1 is not null and email_id in ('%s') limit 3" %(dts['recipents'].replace(",","','")),as_list=1)      
    	if rc_list:
    		send_sms([ x[0] for x in rc_list ], cstr(dts['message']))
    		msg+= "SMS "
    rc_list=dts['recipents'].split(',')
    if dts['push']:
        data={}
        data['Message']=dts['message']
        gcm = GCM('AIzaSyBIc4LYCnUU9wFV_pBoFHHzLoGm_xHl-5k')
        res=frappe.db.sql("select device_id from tabUser where name in ('%s')" % "','".join(map(str,rc_list)),as_list=1)
        if res:
                res = gcm.json_request(registration_ids=res, data=data,collapse_key='uptoyou', delay_while_idle=True, time_to_live=3600)
                msg+= "Push notification"
    if dts['email']:
        frappe.sendmail(recipients=dts['recipents'], sender='*****@*****.**', content=dts['message'], subject='Broadcast Message')
        msg+=" Email"
    return msg +" sent Successfully"
	def test_make_vehicle_log(self):
		license_plate=random_string(10).upper()
		employee_id=frappe.db.sql("""select name from `tabEmployee` order by modified desc limit 1""")[0][0]
		vehicle = frappe.get_doc({
			"doctype": "Vehicle",
			"license_plate": cstr(license_plate),
			"make": "Maruti",
			"model": "PCM",
			"last_odometer":5000,
			"acquisition_date":frappe.utils.nowdate(),
			"location": "Mumbai",
			"chassis_no": "1234ABCD",
			"vehicle_value":frappe.utils.flt(500000)
		})
		try:
			vehicle.insert()
		except frappe.DuplicateEntryError:
			pass
		vehicle_log = frappe.get_doc({
			"doctype": "Vehicle Log",
			"license_plate": cstr(license_plate),
			"employee":employee_id,
			"date":frappe.utils.nowdate(),
			"odometer":5010,
			"fuel_qty":frappe.utils.flt(50),
			"price": frappe.utils.flt(500)
		})
		vehicle_log.insert()
		vehicle_log.submit()
Exemple #24
0
	def check_if_latest(self):
		conflict = False
		self._action = "save"
		if not self.get('__islocal'):
			if self.meta.issingle:
				modified = frappe.db.get_value(self.doctype, self.name, "modified")
				if cstr(modified) and cstr(modified) != cstr(self._original_modified):
					conflict = True
			else:
				tmp = frappe.db.get_value(self.doctype, self.name,
					["modified", "docstatus"], as_dict=True)

				if not tmp:
					frappe.throw(_("Record does not exist"))

				modified = cstr(tmp.modified)

				if modified and modified != cstr(self._original_modified):
					conflict = True

				self.check_docstatus_transition(tmp.docstatus)

			if conflict:
				frappe.msgprint(_("Error: Document has been modified after you have opened it") \
				+ (" (%s, %s). " % (modified, self.modified)) \
				+ _("Please refresh to get the latest document."),
					raise_exception=frappe.TimestampMismatchError)
		else:
			self.check_docstatus_transition(0)
Exemple #25
0
def update_outstanding_amt(account, party_type, party, against_voucher_type, against_voucher, on_cancel=False):
	# get final outstanding amt
	bal = flt(frappe.db.sql("""select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
		from `tabGL Entry`
		where against_voucher_type=%s and against_voucher=%s
		and account = %s and ifnull(party_type, '')=%s and ifnull(party, '')=%s""",
		(against_voucher_type, against_voucher, account, party_type, party))[0][0] or 0.0)

	if against_voucher_type == 'Purchase Invoice':
		bal = -bal
	elif against_voucher_type == "Journal Entry":
		against_voucher_amount = flt(frappe.db.sql("""
			select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
			from `tabGL Entry` where voucher_type = 'Journal Entry' and voucher_no = %s
			and account = %s and ifnull(party_type, '')=%s and ifnull(party, '')=%s
			and ifnull(against_voucher, '') = ''""",
			(against_voucher, account, cstr(party_type), cstr(party)))[0][0])

		if not against_voucher_amount:
			frappe.throw(_("Against Journal Entry {0} is already adjusted against some other voucher")
				.format(against_voucher))

		bal = against_voucher_amount + bal
		if against_voucher_amount < 0:
			bal = -bal

	# Validation : Outstanding can not be negative
	if bal < 0 and not on_cancel:
		frappe.throw(_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal)))

	# Update outstanding amt on against voucher
	if against_voucher_type in ["Sales Invoice", "Purchase Invoice"]:
		frappe.db.sql("update `tab%s` set outstanding_amount=%s where name=%s" %
			(against_voucher_type, '%s', '%s'),	(bal, against_voucher))
Exemple #26
0
	def validate_for_items(self):
		chk_dupl_itm = []
		for d in self.get('quotation_details'):
			if [cstr(d.item_code),cstr(d.description)] in chk_dupl_itm:
				frappe.throw(_("Item {0} with same description entered twice").format(d.item_code))
			else:
				chk_dupl_itm.append([cstr(d.item_code),cstr(d.description)])
Exemple #27
0
def update_against_doc(d, jv_obj):
    """
		Updates against document, if partial amount splits into rows
	"""
    jv_detail = jv_obj.get("entries", {"name": d["voucher_detail_no"]})[0]
    jv_detail.set(d["dr_or_cr"], d["allocated_amt"])
    jv_detail.set(d["against_fld"], d["against_voucher"])

    if d["allocated_amt"] < d["unadjusted_amt"]:
        jvd = frappe.db.sql(
            """select cost_center, balance, against_account, is_advance
			from `tabJournal Voucher Detail` where name = %s""",
            d["voucher_detail_no"],
        )
        # new entry with balance amount
        ch = jv_obj.append("entries")
        ch.account = d["account"]
        ch.cost_center = cstr(jvd[0][0])
        ch.balance = cstr(jvd[0][1])
        ch.set(d["dr_or_cr"], flt(d["unadjusted_amt"]) - flt(d["allocated_amt"]))
        ch.set(d["dr_or_cr"] == "debit" and "credit" or "debit", 0)
        ch.against_account = cstr(jvd[0][2])
        ch.is_advance = cstr(jvd[0][3])
        ch.docstatus = 1

        # will work as update after submit
    jv_obj.ignore_validate_update_after_submit = True
    jv_obj.save()
Exemple #28
0
def update_against_doc(d, jv_obj):
	"""
		Updates against document, if partial amount splits into rows
	"""
	jv_detail = jv_obj.get("accounts", {"name": d["voucher_detail_no"]})[0]
	jv_detail.set(d["dr_or_cr"], d["allocated_amt"])
	jv_detail.set(d["against_fld"], d["against_voucher"])

	if d['allocated_amt'] < d['unadjusted_amt']:
		jvd = frappe.db.sql("""select cost_center, balance, against_account, is_advance
			from `tabJournal Entry Account` where name = %s""", d['voucher_detail_no'])
		# new entry with balance amount
		ch = jv_obj.append("accounts")
		ch.account = d['account']
		ch.party_type = d["party_type"]
		ch.party = d["party"]
		ch.cost_center = cstr(jvd[0][0])
		ch.balance = flt(jvd[0][1])
		ch.set(d['dr_or_cr'], flt(d['unadjusted_amt']) - flt(d['allocated_amt']))
		ch.set(d['dr_or_cr']== 'debit' and 'credit' or 'debit', 0)
		ch.against_account = cstr(jvd[0][2])
		ch.is_advance = cstr(jvd[0][3])
		ch.docstatus = 1

	# will work as update after submit
	jv_obj.flags.ignore_validate_update_after_submit = True
	jv_obj.save()
Exemple #29
0
    def get_outstanding_invoices(self):
        self.set("accounts", [])
        total = 0
        for d in self.get_values():
            total += flt(d.outstanding_amount, self.precision("credit", "accounts"))
            jd1 = self.append("accounts", {})
            jd1.account = d.account
            jd1.party = d.party

            if self.write_off_based_on == "Accounts Receivable":
                jd1.party_type = "Customer"
                jd1.credit = flt(d.outstanding_amount, self.precision("credit", "accounts"))
                jd1.against_invoice = cstr(d.name)
            elif self.write_off_based_on == "Accounts Payable":
                jd1.party_type = "Supplier"
                jd1.debit = flt(d.outstanding_amount, self.precision("debit", "accounts"))
                jd1.against_voucher = cstr(d.name)

        jd2 = self.append("accounts", {})
        if self.write_off_based_on == "Accounts Receivable":
            jd2.debit = total
        elif self.write_off_based_on == "Accounts Payable":
            jd2.credit = total

        self.validate_debit_and_credit()
Exemple #30
0
def get_data(filters):
	conditions, filters = get_conditions(filters)

        data = frappe.db.sql("""
                select t1.employee, t3.employee_name, t1.designation, t3.passport_number,
                        t3.date_of_birth, t1.employee_subgroup, t3.gis_number, t2.amount,
                        t1.company, t1.branch, t1.department, t1.division, t1.section,
                        t1.fiscal_year, t1.month
                from `tabSalary Slip` t1, `tabSalary Detail` t2, `tabEmployee` t3
                where t1.docstatus = 1 %s
                and t3.employee = t1.employee
                and t2.parent = t1.name
                and t2.parentfield = 'deductions'
                and exists(select 1
                                from `tabSalary Component` sc
                                where sc.name = t2.salary_component
                                and sc.gl_head = 'Group Insurance Scheme - SMCL')
                order by t1.employee
                """ % conditions, filters)
		
	if not data:
		msgprint(_("No Data Found for month: ") + cstr(filters.get("month")) + 
			_(" and year: ") + cstr(filters.get("fiscal_year")), raise_exception=1)
	
	return data
Exemple #31
0
def get_invoice_summary(items, taxes):
    summary_data = frappe._dict()
    for tax in taxes:
        #Include only VAT charges.
        if tax.charge_type == "Actual":
            continue

        #Charges to appear as items in the e-invoice.
        if tax.charge_type in [
                "On Previous Row Total", "On Previous Row Amount"
        ]:
            reference_row = next(
                (row for row in taxes if row.idx == int(tax.row_id or 0)),
                None)
            if reference_row:
                items.append(
                    frappe._dict(
                        idx=len(items) + 1,
                        item_code=reference_row.description,
                        item_name=reference_row.description,
                        description=reference_row.description,
                        rate=reference_row.tax_amount,
                        qty=1.0,
                        amount=reference_row.tax_amount,
                        stock_uom=frappe.db.get_single_value(
                            "Stock Settings", "stock_uom") or _("Nos"),
                        tax_rate=tax.rate,
                        tax_amount=(reference_row.tax_amount * tax.rate) / 100,
                        net_amount=reference_row.tax_amount,
                        taxable_amount=reference_row.tax_amount,
                        item_tax_rate={tax.account_head: tax.rate},
                        charges=True))

        #Check item tax rates if tax rate is zero.
        if tax.rate == 0:
            for item in items:
                item_tax_rate = item.item_tax_rate
                if isinstance(item.item_tax_rate, string_types):
                    item_tax_rate = json.loads(item.item_tax_rate)

                if item_tax_rate and tax.account_head in item_tax_rate:
                    key = cstr(item_tax_rate[tax.account_head])
                    if key not in summary_data:
                        summary_data.setdefault(
                            key, {
                                "tax_amount": 0.0,
                                "taxable_amount": 0.0,
                                "tax_exemption_reason": "",
                                "tax_exemption_law": ""
                            })

                    summary_data[key]["tax_amount"] += item.tax_amount
                    summary_data[key]["taxable_amount"] += item.net_amount
                    if key == "0.0":
                        summary_data[key][
                            "tax_exemption_reason"] = tax.tax_exemption_reason
                        summary_data[key][
                            "tax_exemption_law"] = tax.tax_exemption_law

            if summary_data == {}:  #Implies that Zero VAT has not been set on any item.
                summary_data.setdefault(
                    "0.0", {
                        "tax_amount": 0.0,
                        "taxable_amount": tax.total,
                        "tax_exemption_reason": tax.tax_exemption_reason,
                        "tax_exemption_law": tax.tax_exemption_law
                    })

        else:
            item_wise_tax_detail = json.loads(tax.item_wise_tax_detail)
            for rate_item in [
                    tax_item for tax_item in item_wise_tax_detail.items()
                    if tax_item[1][0] == tax.rate
            ]:
                key = cstr(tax.rate)
                if not summary_data.get(key):
                    summary_data.setdefault(key, {
                        "tax_amount": 0.0,
                        "taxable_amount": 0.0
                    })
                summary_data[key]["tax_amount"] += rate_item[1][1]
                summary_data[key]["taxable_amount"] += sum([
                    item.net_amount for item in items
                    if item.item_code == rate_item[0]
                ])

            for item in items:
                key = cstr(tax.rate)
                if item.get("charges"):
                    if not summary_data.get(key):
                        summary_data.setdefault(key, {"taxable_amount": 0.0})
                    summary_data[key]["taxable_amount"] += item.taxable_amount

    return summary_data
Exemple #32
0
    def validate_warehouse(self):
        """perform various (sometimes conditional) validations on warehouse"""

        source_mandatory = [
            "Material Issue", "Material Transfer", "Subcontract",
            "Material Transfer for Manufacture"
        ]
        target_mandatory = [
            "Material Receipt", "Material Transfer", "Subcontract",
            "Material Transfer for Manufacture"
        ]

        validate_for_manufacture_repack = any(
            [d.bom_no for d in self.get("items")])

        if self.purpose in source_mandatory and self.purpose not in target_mandatory:
            self.to_warehouse = None
            for d in self.get('items'):
                d.t_warehouse = None
        elif self.purpose in target_mandatory and self.purpose not in source_mandatory:
            self.from_warehouse = None
            for d in self.get('items'):
                d.s_warehouse = None

        for d in self.get('items'):
            if not d.s_warehouse and not d.t_warehouse:
                d.s_warehouse = self.from_warehouse
                d.t_warehouse = self.to_warehouse

            if not (d.s_warehouse or d.t_warehouse):
                frappe.throw(_("Atleast one warehouse is mandatory"))

            if self.purpose in source_mandatory and not d.s_warehouse:
                if self.from_warehouse:
                    d.s_warehouse = self.from_warehouse
                else:
                    frappe.throw(
                        _("Source warehouse is mandatory for row {0}").format(
                            d.idx))

            if self.purpose in target_mandatory and not d.t_warehouse:
                if self.to_warehouse:
                    d.t_warehouse = self.to_warehouse
                else:
                    frappe.throw(
                        _("Target warehouse is mandatory for row {0}").format(
                            d.idx))

            if self.purpose in ["Manufacture", "Repack"]:
                if validate_for_manufacture_repack:
                    if d.bom_no:
                        d.s_warehouse = None

                        if not d.t_warehouse:
                            frappe.throw(
                                _("Target warehouse is mandatory for row {0}").
                                format(d.idx))

                        elif self.pro_doc and cstr(
                                d.t_warehouse) != self.pro_doc.fg_warehouse:
                            frappe.throw(
                                _("Target warehouse in row {0} must be same as Production Order"
                                  ).format(d.idx))

                    else:
                        d.t_warehouse = None
                        if not d.s_warehouse:
                            frappe.throw(
                                _("Source warehouse is mandatory for row {0}").
                                format(d.idx))

            if cstr(d.s_warehouse) == cstr(d.t_warehouse):
                frappe.throw(
                    _("Source and target warehouse cannot be same for row {0}"
                      ).format(d.idx))
Exemple #33
0
    def get_item_list(self):
        il = []
        for d in self.get("items"):
            if d.qty is None:
                frappe.throw(_("Row {0}: Qty is mandatory").format(d.idx))

            if self.has_product_bundle(d.item_code):
                for p in self.get("packed_items"):
                    if p.parent_detail_docname == d.name and p.parent_item == d.item_code:
                        # the packing details table's qty is already multiplied with parent's qty
                        il.append(
                            frappe._dict({
                                'warehouse':
                                p.warehouse or d.warehouse,
                                'item_code':
                                p.item_code,
                                'qty':
                                flt(p.qty),
                                'uom':
                                p.uom,
                                'batch_no':
                                cstr(p.batch_no).strip(),
                                'serial_no':
                                cstr(p.serial_no).strip(),
                                'name':
                                d.name,
                                'target_warehouse':
                                p.target_warehouse,
                                'company':
                                self.company,
                                'voucher_type':
                                self.doctype,
                                'allow_zero_valuation':
                                d.allow_zero_valuation_rate
                            }))
            else:
                il.append(
                    frappe._dict({
                        'warehouse':
                        d.warehouse,
                        'item_code':
                        d.item_code,
                        'qty':
                        d.stock_qty,
                        'uom':
                        d.uom,
                        'stock_uom':
                        d.stock_uom,
                        'conversion_factor':
                        d.conversion_factor,
                        'batch_no':
                        cstr(d.get("batch_no")).strip(),
                        'serial_no':
                        cstr(d.get("serial_no")).strip(),
                        'name':
                        d.name,
                        'target_warehouse':
                        d.target_warehouse,
                        'company':
                        self.company,
                        'voucher_type':
                        self.doctype,
                        'allow_zero_valuation':
                        d.allow_zero_valuation_rate
                    }))
        return il
 def validate_bom(self):
     if cstr(self.current_bom) == cstr(self.new_bom):
         frappe.throw(_("Current BOM and New BOM can not be same"))
Exemple #35
0
def execute_job(site,
                method,
                event,
                job_name,
                kwargs,
                user=None,
                is_async=True,
                retry=0):
    """Executes job in a worker, performs commit/rollback and logs if there is any error"""
    if is_async:
        frappe.connect(site)
        if os.environ.get("CI"):
            frappe.flags.in_test = True

        if user:
            frappe.set_user(user)

    if isinstance(method, string_types):
        method_name = method
        method = frappe.get_attr(method)
    else:
        method_name = cstr(method.__name__)

    frappe.monitor.start("job", method_name, kwargs)
    try:
        method(**kwargs)

    except (frappe.db.InternalError, frappe.RetryBackgroundJobError) as e:
        frappe.db.rollback()

        if retry < 5 and (isinstance(e, frappe.RetryBackgroundJobError) or
                          (frappe.db.is_deadlocked(e)
                           or frappe.db.is_timedout(e))):
            # retry the job if
            # 1213 = deadlock
            # 1205 = lock wait timeout
            # or RetryBackgroundJobError is explicitly raised
            frappe.destroy()
            time.sleep(retry + 1)

            return execute_job(site,
                               method,
                               event,
                               job_name,
                               kwargs,
                               is_async=is_async,
                               retry=retry + 1)

        else:
            frappe.log_error(title=method_name)
            raise

    except:
        frappe.db.rollback()
        frappe.log_error(title=method_name)
        frappe.db.commit()
        print(frappe.get_traceback())
        raise

    else:
        frappe.db.commit()

    finally:
        frappe.monitor.stop()
        if is_async:
            frappe.destroy()
Exemple #36
0
def create_pos_profile(doc):
    item_groups = []
    for service_type in doc.services_type:
        if service_type.is_provided == 'Yes':
            item_groups.append({
                "doctype": "POS Item Group",
                "item_group": cstr(service_type.services)
            })

    pos_profile = frappe.get_doc({
        "doctype":
        "POS Profile",
        "pos_profile_name":
        str(doc.employee_name) + " - " + str(doc.name),
        "naming_series":
        "SINV-",
        "update_stock":
        1,
        "ignore_pricing_rule":
        1,
        "allow_delete":
        1,
        "allow_user_to_edit_rate":
        1,
        "allow_user_to_edit_discount":
        1,
        "allow_print_before_pay":
        1,
        "warehouse":
        frappe.db.get_value("Branch", doc.branch, "warehouse"),
        "select_print_heading":
        str(doc.branch),
        "selling_price_list":
        str(doc.employee_price_list),
        "write_off_account":
        "Write Off - " +
        str(frappe.db.get_value("Company", doc.company, "abbr")),
        "write_off_cost_center":
        str(doc.branch) + " - " +
        str(frappe.db.get_value("Company", doc.company, "abbr")),
        "income_account":
        str(doc.branch) + " - " +
        str(frappe.db.get_value("Company", doc.company, "abbr")),
        "cost_center":
        str(doc.branch) + " - " +
        str(frappe.db.get_value("Company", doc.company, "abbr")),
        "employee":
        str(doc.name),
        "item_groups":
        item_groups,
        "letter_head":
        frappe.db.get_value("Company", doc.company, "default_letter_head"),
        "tc_name":
        frappe.db.get_value("Company", doc.company, "default_terms"),
        "taxes_and_charges":
        frappe.db.get_value("Sales Taxes and Charges Template",
                            {"is_default": 1}, "name"),
        "territory":
        frappe.db.get_value("Branch", doc.branch, "territory")
    })

    pos_profile.flags.ignore_permissions = True
    pos_profile.insert()
Exemple #37
0
def on_update(doc, method):
    # ---------------------------------------------------------------------------
    # update pos profile
    # --------------------------------------------------------------------------- */
    if frappe.db.get_value("POS Profile", {"employee": cstr(doc.employee)},
                           "name"):
        # ---------------------------------------------------------------------------
        # update pos profile warehouse
        # --------------------------------------------------------------------------- */
        pos_profile_warehouse = frappe.db.get_value(
            "POS Profile", {"employee": cstr(doc.name)}, "warehouse")
        branch_warehouse = frappe.db.get_value("Branch", doc.branch,
                                               "warehouse")
        if branch_warehouse != pos_profile_warehouse:
            frappe.db.set_value("POS Profile", {"employee": cstr(doc.name)},
                                "warehouse", cstr(branch_warehouse))
            frappe.db.commit()

        # ---------------------------------------------------------------------------
        # update pos profile item groups
        # --------------------------------------------------------------------------- */
        for service_type in doc.services_type:
            pos_profile = frappe.get_doc(
                "POS Profile",
                cstr(doc.employee_name) + " - " + cstr(doc.name))
            if service_type.is_provided == "Yes":
                if len(pos_profile.item_groups) > 0:
                    pos_lambda = lambda i: "Yes" if cstr(
                        pos_profile.item_groups[i].item_group).strip() == cstr(
                            service_type.services).strip() else "No"
                    is_exist = "No"
                    for j in range(len(pos_profile.item_groups)):
                        is_exist = pos_lambda(j)

                        if is_exist == "Yes":
                            break

                    if is_exist == "No":
                        # Add service in pos profile
                        pos_profile.append(
                            "item_groups", {
                                "item_group": cstr(service_type.services),
                                "doctype": "POS Item Group"
                            })
                        pos_profile.flags.ignore_permissions = True
                        pos_profile.save()

                if len(pos_profile.item_groups) == 0:
                    # Add service in pos profile
                    pos_profile.append(
                        "item_groups", {
                            "item_group": cstr(service_type.services),
                            "doctype": "POS Item Group"
                        })
                    pos_profile.flags.ignore_permissions = True
                    pos_profile.save()
            elif service_type.is_provided == "No":
                # Delete service in pos pos profile
                service_name = frappe.db.get_value(
                    "POS Item Group", {
                        "parent": cstr(pos_profile.name),
                        "item_group": cstr(service_type.services)
                    }, "name")
                delete = frappe.delete_doc("POS Item Group",
                                           cstr(service_name))
                frappe.db.commit()

        # ---------------------------------------------------------------------------
        # update pos profile price list
        # --------------------------------------------------------------------------- */
        pos_profile_price_list = frappe.db.get_value(
            "POS Profile", {"employee": cstr(doc.name)}, "selling_price_list")
        if cstr(pos_profile_price_list) != cstr(doc.employee_price_list):
            frappe.db.set_value("POS Profile", {"employee": cstr(doc.name)},
                                "selling_price_list",
                                cstr(doc.employee_price_list))
            frappe.db.commit()

        # ---------------------------------------------------------------------------
        # update pos print heading
        # --------------------------------------------------------------------------- */
        pos_profile_print_heading = frappe.db.get_value(
            "POS Profile", {"employee": cstr(doc.name)},
            "select_print_heading")
        print_heading = frappe.db.get_value("Print Heading", cstr(doc.branch),
                                            "name")
        if cstr(pos_profile_print_heading) != cstr(print_heading):
            frappe.db.set_value("POS Profile", {"employee": cstr(doc.name)},
                                "select_print_heading", cstr(print_heading))
            frappe.db.commit()

        # ---------------------------------------------------------------------------
        # update pos write off cost center
        # --------------------------------------------------------------------------- */
        pos_profile_write_off_cost_center = frappe.db.get_value(
            "POS Profile", {"employee": cstr(doc.name)},
            "write_off_cost_center")
        branch_cost_center = frappe.db.get_value("Branch", cstr(doc.branch),
                                                 "cost_center")
        if cstr(pos_profile_write_off_cost_center) != cstr(branch_cost_center):
            frappe.db.set_value("POS Profile", {"employee": cstr(doc.name)},
                                "write_off_cost_center",
                                cstr(branch_cost_center))
            frappe.db.commit()

        # ---------------------------------------------------------------------------
        # update pos cost center
        # --------------------------------------------------------------------------- */
        pos_profile_cost_center = frappe.db.get_value(
            "POS Profile", {"employee": cstr(doc.name)}, "cost_center")
        branch_cost_center = frappe.db.get_value("Branch", cstr(doc.branch),
                                                 "cost_center")
        if cstr(pos_profile_cost_center) != cstr(branch_cost_center):
            frappe.db.set_value("POS Profile", {"employee": cstr(doc.name)},
                                "cost_center", cstr(branch_cost_center))
            frappe.db.commit()

        # ---------------------------------------------------------------------------
        # update income account
        # --------------------------------------------------------------------------- */
        pos_profile_income_account = frappe.db.get_value(
            "POS Profile", {"employee": cstr(doc.name)}, "income_account")
        income_account = cstr(doc.branch) + " - " + frappe.db.get_value(
            "Company", doc.company, "abbr")
        if cstr(pos_profile_income_account) != cstr(income_account):
            frappe.db.set_value("POS Profile", {"employee": cstr(doc.name)},
                                "income_account", cstr(income_account))
            frappe.db.commit()

        # ---------------------------------------------------------------------------
        # update pos territory
        # --------------------------------------------------------------------------- */
        pos_profile_territory = frappe.db.get_value(
            "POS Profile", {"employee": cstr(doc.name)}, "territory")
        territory = frappe.db.get_value("Branch", cstr(doc.branch),
                                        "territory")
        if cstr(pos_profile_territory) != cstr(print_heading):
            frappe.db.set_value("POS Profile", {"employee": cstr(doc.name)},
                                "territory", cstr(territory))
            frappe.db.commit()
Exemple #38
0
	def link_exists(self, value, df):
		key = df.options + "::" + cstr(value)
		if Row.link_values_exist_map.get(key) is None:
			Row.link_values_exist_map[key] = frappe.db.exists(df.options, value)
		return Row.link_values_exist_map.get(key)
Exemple #39
0
 def update_status(self, status):
     self.check_modified_date()
     frappe.db.set(self, 'status', cstr(status))
     self.update_requested_qty()
     frappe.msgprint(_("Status updated to {0}").format(_(status)))
Exemple #40
0
	def block_invoice(self, hold_comment=None):
		self.db_set('on_hold', 1)
		self.db_set('hold_comment', cstr(hold_comment))
Exemple #41
0
def get_balance_on(account=None,
                   date=None,
                   party_type=None,
                   party=None,
                   in_account_currency=True):
    if not account and frappe.form_dict.get("account"):
        account = frappe.form_dict.get("account")
    if not date and frappe.form_dict.get("date"):
        date = frappe.form_dict.get("date")
    if not party_type and frappe.form_dict.get("party_type"):
        party_type = frappe.form_dict.get("party_type")
    if not party and frappe.form_dict.get("party"):
        party = frappe.form_dict.get("party")

    cond = []
    if date:
        cond.append("posting_date <= '%s'" % frappe.db.escape(cstr(date)))
    else:
        # get balance of all entries that exist
        date = nowdate()

    try:
        year_start_date = get_fiscal_year(date, verbose=0)[1]
    except FiscalYearError:
        if getdate(date) > getdate(nowdate()):
            # if fiscal year not found and the date is greater than today
            # get fiscal year for today's date and its corresponding year start date
            year_start_date = get_fiscal_year(nowdate(), verbose=1)[1]
        else:
            # this indicates that it is a date older than any existing fiscal year.
            # hence, assuming balance as 0.0
            return 0.0

    if account:
        acc = frappe.get_doc("Account", account)

        if not frappe.flags.ignore_account_permission:
            acc.check_permission("read")

        # for pl accounts, get balance within a fiscal year
        if acc.report_type == 'Profit and Loss':
            cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
             % year_start_date)

        # different filter for group and ledger - improved performance
        if acc.is_group:
            cond.append("""exists (
				select name from `tabAccount` ac where ac.name = gle.account
				and ac.lft >= %s and ac.rgt <= %s
			)""" % (acc.lft, acc.rgt))

            # If group and currency same as company,
            # always return balance based on debit and credit in company currency
            if acc.account_currency == frappe.db.get_value(
                    "Company", acc.company, "default_currency"):
                in_account_currency = False
        else:
            cond.append("""gle.account = "%s" """ %
                        (frappe.db.escape(account, percent=False), ))

    if party_type and party:
        cond.append("""gle.party_type = "%s" and gle.party = "%s" """ %
                    (frappe.db.escape(party_type),
                     frappe.db.escape(party, percent=False)))

    if account or (party_type and party):
        if in_account_currency:
            select_field = "sum(debit_in_account_currency) - sum(credit_in_account_currency)"
        else:
            select_field = "sum(debit) - sum(credit)"
        bal = frappe.db.sql("""
			SELECT {0}
			FROM `tabGL Entry` gle
			WHERE {1}""".format(select_field, " and ".join(cond)))[0][0]

        # if bal is None, return 0
        return flt(bal)
Exemple #42
0
def get_basic_details(args, item, overwrite_warehouse=True):
    """
	:param args: {
			"item_code": "",
			"warehouse": None,
			"customer": "",
			"conversion_rate": 1.0,
			"selling_price_list": None,
			"price_list_currency": None,
			"price_list_uom_dependant": None,
			"plc_conversion_rate": 1.0,
			"doctype": "",
			"name": "",
			"supplier": None,
			"transaction_date": None,
			"conversion_rate": 1.0,
			"buying_price_list": None,
			"is_subcontracted": "Yes" / "No",
			"ignore_pricing_rule": 0/1
			"project": "",
			barcode: "",
			serial_no: "",
			currency: "",
			update_stock: "",
			price_list: "",
			company: "",
			order_type: "",
			is_pos: "",
			project: "",
			qty: "",
			stock_qty: "",
			conversion_factor: ""
		}
	:param item: `item_code` of Item object
	:return: frappe._dict
	"""

    if not item:
        item = frappe.get_doc("Item", args.get("item_code"))

    if item.variant_of:
        item.update_template_tables()

    item_defaults = get_item_defaults(item.name, args.company)
    item_group_defaults = get_item_group_defaults(item.name, args.company)
    brand_defaults = get_brand_defaults(item.name, args.company)

    if overwrite_warehouse or not args.warehouse:
        warehouse = (args.get("set_warehouse")
                     or item_defaults.get("default_warehouse")
                     or item_group_defaults.get("default_warehouse")
                     or brand_defaults.get("default_warehouse")
                     or args.warehouse)

        if not warehouse:
            defaults = frappe.defaults.get_defaults() or {}
            warehouse_exists = frappe.db.exists("Warehouse", {
                'name': defaults.default_warehouse,
                'company': args.company
            })
            if defaults.get("default_warehouse") and warehouse_exists:
                warehouse = defaults.default_warehouse

    else:
        warehouse = args.warehouse

    if args.get('doctype') == "Material Request" and not args.get(
            'material_request_type'):
        args['material_request_type'] = frappe.db.get_value(
            'Material Request',
            args.get('name'),
            'material_request_type',
            cache=True)

    expense_account = None

    if args.get('doctype') == 'Purchase Invoice' and item.is_fixed_asset:
        from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
        expense_account = get_asset_category_account(
            fieldname="fixed_asset_account",
            item=args.item_code,
            company=args.company)

    #Set the UOM to the Default Sales UOM or Default Purchase UOM if configured in the Item Master
    if not args.uom:
        if args.get('doctype') in sales_doctypes:
            args.uom = item.sales_uom if item.sales_uom else item.stock_uom
        elif (args.get('doctype') in ['Purchase Order', 'Purchase Receipt', 'Purchase Invoice']) or \
         (args.get('doctype') == 'Material Request' and args.get('material_request_type') == 'Purchase'):
            args.uom = item.purchase_uom if item.purchase_uom else item.stock_uom
        else:
            args.uom = item.stock_uom

    out = frappe._dict({
        "item_code":
        item.name,
        "item_name":
        item.item_name,
        "description":
        cstr(item.description).strip(),
        "image":
        cstr(item.image).strip(),
        "warehouse":
        warehouse,
        "income_account":
        get_default_income_account(args, item_defaults, item_group_defaults,
                                   brand_defaults),
        "expense_account":
        expense_account or get_default_expense_account(
            args, item_defaults, item_group_defaults, brand_defaults),
        "cost_center":
        get_default_cost_center(args, item_defaults, item_group_defaults,
                                brand_defaults),
        'has_serial_no':
        item.has_serial_no,
        'has_batch_no':
        item.has_batch_no,
        "batch_no":
        None,
        "uom":
        args.uom,
        "min_order_qty":
        flt(item.min_order_qty) if args.doctype == "Material Request" else "",
        "qty":
        flt(args.qty) or 1.0,
        "stock_qty":
        flt(args.qty) or 1.0,
        "price_list_rate":
        0.0,
        "base_price_list_rate":
        0.0,
        "rate":
        0.0,
        "base_rate":
        0.0,
        "amount":
        0.0,
        "base_amount":
        0.0,
        "net_rate":
        0.0,
        "net_amount":
        0.0,
        "discount_percentage":
        0.0,
        "supplier":
        get_default_supplier(args, item_defaults, item_group_defaults,
                             brand_defaults),
        "update_stock":
        args.get("update_stock")
        if args.get('doctype') in ['Sales Invoice', 'Purchase Invoice'] else 0,
        "delivered_by_supplier":
        item.delivered_by_supplier
        if args.get("doctype") in ["Sales Order", "Sales Invoice"] else 0,
        "is_fixed_asset":
        item.is_fixed_asset,
        "weight_per_unit":
        item.weight_per_unit,
        "weight_uom":
        item.weight_uom,
        "last_purchase_rate":
        item.last_purchase_rate
        if args.get("doctype") in ["Purchase Order"] else 0,
        "transaction_date":
        args.get("transaction_date")
    })

    if item.get("enable_deferred_revenue") or item.get(
            "enable_deferred_expense"):
        out.update(calculate_service_end_date(args, item))

    # calculate conversion factor
    if item.stock_uom == args.uom:
        out.conversion_factor = 1.0
    else:
        out.conversion_factor = args.conversion_factor or \
         get_conversion_factor(item.name, args.uom).get("conversion_factor")

    args.conversion_factor = out.conversion_factor
    out.stock_qty = out.qty * out.conversion_factor

    # calculate last purchase rate
    if args.get('doctype') in purchase_doctypes:
        from erpnext.buying.doctype.purchase_order.purchase_order import item_last_purchase_rate
        out.last_purchase_rate = item_last_purchase_rate(
            args.name, args.conversion_rate, item.name, out.conversion_factor)

    # if default specified in item is for another company, fetch from company
    for d in [["Account", "income_account", "default_income_account"],
              ["Account", "expense_account", "default_expense_account"],
              ["Cost Center", "cost_center", "cost_center"],
              ["Warehouse", "warehouse", ""]]:
        if not out[d[1]]:
            out[d[1]] = frappe.get_cached_value('Company', args.company,
                                                d[2]) if d[2] else None

    for fieldname in ("item_name", "item_group", "barcodes", "brand",
                      "stock_uom"):
        out[fieldname] = item.get(fieldname)

    if args.get("manufacturer"):
        part_no = get_item_manufacturer_part_no(args.get("item_code"),
                                                args.get("manufacturer"))
        if part_no:
            out["manufacturer_part_no"] = part_no
        else:
            out["manufacturer_part_no"] = None
            out["manufacturer"] = None

    child_doctype = args.doctype + ' Item'
    meta = frappe.get_meta(child_doctype)
    if meta.get_field("barcode"):
        update_barcode_value(out)

    return out
Exemple #43
0
	def has_login_limit_exceeded(self, e):
		return "-ERR Exceeded the login limit" in strip(cstr(e.message))
	def autoname(self):
		self.name = " ".join(filter(None,
			[cstr(self.get(f)).strip() for f in ["number", "period"]]))
Exemple #45
0
def encrypt(pwd):
	cipher_suite = Fernet(encode(get_encryption_key()))
	cipher_text = cstr(cipher_suite.encrypt(encode(pwd)))
	return cipher_text
Exemple #46
0
def update_reference_in_journal_entry(d, jv_obj):
    """
		Updates against document, if partial amount splits into rows
	"""
    jv_detail = jv_obj.get("accounts", {"name": d["voucher_detail_no"]})[0]
    jv_detail.set(d["dr_or_cr"], d["allocated_amount"])
    jv_detail.set(
        'debit' if d['dr_or_cr'] == 'debit_in_account_currency' else 'credit',
        d["allocated_amount"] * flt(jv_detail.exchange_rate))

    original_reference_type = jv_detail.reference_type
    original_reference_name = jv_detail.reference_name

    jv_detail.set("reference_type", d["against_voucher_type"])
    jv_detail.set("reference_name", d["against_voucher"])

    if d['allocated_amount'] < d['unadjusted_amount']:
        jvd = frappe.db.sql("""
			select cost_center, balance, against_account, is_advance,
				account_type, exchange_rate, account_currency
			from `tabJournal Entry Account` where name = %s
		""",
                            d['voucher_detail_no'],
                            as_dict=True)

        amount_in_account_currency = flt(d['unadjusted_amount']) - flt(
            d['allocated_amount'])
        amount_in_company_currency = amount_in_account_currency * flt(
            jvd[0]['exchange_rate'])

        # new entry with balance amount
        ch = jv_obj.append("accounts")
        ch.account = d['account']
        ch.account_type = jvd[0]['account_type']
        ch.account_currency = jvd[0]['account_currency']
        ch.exchange_rate = jvd[0]['exchange_rate']
        ch.party_type = d["party_type"]
        ch.party = d["party"]
        ch.cost_center = cstr(jvd[0]["cost_center"])
        ch.balance = flt(jvd[0]["balance"])

        ch.set(d['dr_or_cr'], amount_in_account_currency)
        ch.set(
            'debit' if d['dr_or_cr'] == 'debit_in_account_currency' else
            'credit', amount_in_company_currency)

        ch.set(
            'credit_in_account_currency' if d['dr_or_cr']
            == 'debit_in_account_currency' else 'debit_in_account_currency', 0)
        ch.set(
            'credit'
            if d['dr_or_cr'] == 'debit_in_account_currency' else 'debit', 0)

        ch.against_account = cstr(jvd[0]["against_account"])
        ch.reference_type = original_reference_type
        ch.reference_name = original_reference_name
        ch.is_advance = cstr(jvd[0]["is_advance"])
        ch.docstatus = 1

    # will work as update after submit
    jv_obj.flags.ignore_validate_update_after_submit = True
    jv_obj.save(ignore_permissions=True)
Exemple #47
0
def set_stock_balance_as_per_serial_no(item_code=None,
                                       posting_date=None,
                                       posting_time=None,
                                       fiscal_year=None):
    if not posting_date: posting_date = nowdate()
    if not posting_time: posting_time = nowtime()

    condition = " and item.name='%s'" % item_code.replace(
        "'", "\'") if item_code else ""

    bin = frappe.db.sql(
        """select bin.item_code, bin.warehouse, bin.actual_qty, item.stock_uom
		from `tabBin` bin, tabItem item
		where bin.item_code = item.name and item.has_serial_no = 1 %s""" % condition)

    for d in bin:
        serial_nos = frappe.db.sql(
            """select count(name) from `tabSerial No`
			where item_code=%s and warehouse=%s and docstatus < 2""", (d[0], d[1]))

        if serial_nos and flt(serial_nos[0][0]) != flt(d[2]):
            print(d[0], d[1], d[2], serial_nos[0][0])

        sle = frappe.db.sql(
            """select valuation_rate, company from `tabStock Ledger Entry`
			where item_code = %s and warehouse = %s and is_cancelled = 0
			order by posting_date desc limit 1""", (d[0], d[1]))

        sle_dict = {
            'doctype':
            'Stock Ledger Entry',
            'item_code':
            d[0],
            'warehouse':
            d[1],
            'transaction_date':
            nowdate(),
            'posting_date':
            posting_date,
            'posting_time':
            posting_time,
            'voucher_type':
            'Stock Reconciliation (Manual)',
            'voucher_no':
            '',
            'voucher_detail_no':
            '',
            'actual_qty':
            flt(serial_nos[0][0]) - flt(d[2]),
            'stock_uom':
            d[3],
            'incoming_rate':
            sle and flt(serial_nos[0][0]) > flt(d[2]) and flt(sle[0][0]) or 0,
            'company':
            sle and cstr(sle[0][1]) or 0,
            'batch_no':
            '',
            'serial_no':
            ''
        }

        sle_doc = frappe.get_doc(sle_dict)
        sle_doc.flags.ignore_validate = True
        sle_doc.flags.ignore_links = True
        sle_doc.insert()

        args = sle_dict.copy()
        args.update({"sle_id": sle_doc.name})

        update_bin(args)

        create_repost_item_valuation_entry({
            "item_code": d[0],
            "warehouse": d[1],
            "posting_date": posting_date,
            "posting_time": posting_time
        })
Exemple #48
0
	def make_route(self):
		if not self.route:
			return cstr(frappe.db.get_value('Item Group', self.item_group,
				'route')) + '/' + self.scrub(self.item_name + '-' + random_string(5))
Exemple #49
0
 def send_form_sms(self, arg):
     "called from client side"
     args = json.loads(arg)
     self.send_sms([cstr(args['number'])], cstr(args['message']))
Exemple #50
0
def get_serial_nos(serial_no):
	return [s.strip() for s in cstr(serial_no).strip().upper().replace(',', '\n').split('\n')
		if s.strip()]
Exemple #51
0
def generate_report_result(report, filters=None, user=None):
    status = None
    if not user:
        user = frappe.session.user
    if not filters:
        filters = []

    if filters and isinstance(filters, string_types):
        filters = json.loads(filters)
    columns, result, message, chart, data_to_be_printed = [], [], None, None, None
    if report.report_type == "Query Report":
        if not report.query:
            status = "error"
            frappe.msgprint(_("Must specify a Query to run"),
                            raise_exception=True)

        if not report.query.lower().startswith("select"):
            status = "error"
            frappe.msgprint(_("Query must be a SELECT"), raise_exception=True)

        result = [list(t) for t in frappe.db.sql(report.query, filters)]
        columns = [cstr(c[0]) for c in frappe.db.get_description()]
    else:
        module = report.module or frappe.db.get_value(
            "DocType", report.ref_doctype, "module")
        if report.is_standard == "Yes":
            method_name = get_report_module_dotted_path(
                module, report.name) + ".execute"
            threshold = 30
            res = []

            start_time = datetime.datetime.now()
            # The JOB
            res = frappe.get_attr(method_name)(frappe._dict(filters))

            end_time = datetime.datetime.now()

            execution_time = (end_time - start_time).seconds

            if execution_time > threshold and not report.prepared_report:
                report.db_set('prepared_report', 1)

            frappe.cache().hset('report_execution_time', report.name,
                                execution_time)

            columns, result = res[0], res[1]
            if len(res) > 2:
                message = res[2]
            if len(res) > 3:
                chart = res[3]
            if len(res) > 4:
                data_to_be_printed = res[4]

            if report.custom_columns:
                columns = json.loads(report.custom_columns)
                result = add_data_to_custom_columns(columns, result)

    if result:
        result = get_filtered_data(report.ref_doctype, columns, result, user)

    if cint(report.add_total_row) and result:
        result = add_total_row(result, columns)

    return {
        "result":
        result,
        "columns":
        columns,
        "message":
        message,
        "chart":
        chart,
        "data_to_be_printed":
        data_to_be_printed,
        "status":
        status,
        "execution_time":
        frappe.cache().hget('report_execution_time', report.name) or 0
    }
Exemple #52
0
        def _get_children(bom_no):
            return [
                cstr(d[0]) for d in frappe.db.sql(
                    """select bom_no from `tabBOM Item`
				where parent = %s and ifnull(bom_no, '') != ''""", bom_no)
            ]
Exemple #53
0
def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
    """returns last purchase details in stock uom"""
    # get last purchase order item details
    last_purchase_order = frappe.db.sql("""\
		select po.name, po.transaction_date, po.conversion_rate,
			po_item.conversion_factor, po_item.base_price_list_rate,
			po_item.discount_percentage, po_item.base_rate
		from `tabPurchase Order` po, `tabPurchase Order Item` po_item
		where po.docstatus = 1 and po_item.item_code = %s and po.name != %s and
			po.name = po_item.parent
		order by po.transaction_date desc, po.name desc
		limit 1""", (item_code, cstr(doc_name)),
                                        as_dict=1)

    # get last purchase receipt item details
    last_purchase_receipt = frappe.db.sql("""\
		select pr.name, pr.posting_date, pr.posting_time, pr.conversion_rate,
			pr_item.conversion_factor, pr_item.base_price_list_rate, pr_item.discount_percentage,
			pr_item.base_rate
		from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pr_item
		where pr.docstatus = 1 and pr_item.item_code = %s and pr.name != %s and
			pr.name = pr_item.parent
		order by pr.posting_date desc, pr.posting_time desc, pr.name desc
		limit 1""", (item_code, cstr(doc_name)),
                                          as_dict=1)

    purchase_order_date = getdate(last_purchase_order and last_purchase_order[0].transaction_date \
     or "1900-01-01")
    purchase_receipt_date = getdate(last_purchase_receipt and \
     last_purchase_receipt[0].posting_date or "1900-01-01")

    if (purchase_order_date > purchase_receipt_date) or \
      (last_purchase_order and not last_purchase_receipt):
        # use purchase order
        last_purchase = last_purchase_order[0]
        purchase_date = purchase_order_date

    elif (purchase_receipt_date > purchase_order_date) or \
      (last_purchase_receipt and not last_purchase_order):
        # use purchase receipt
        last_purchase = last_purchase_receipt[0]
        purchase_date = purchase_receipt_date

    else:
        return frappe._dict()

    conversion_factor = flt(last_purchase.conversion_factor)
    out = frappe._dict({
        "base_price_list_rate":
        flt(last_purchase.base_price_list_rate) / conversion_factor,
        "base_rate":
        flt(last_purchase.base_rate) / conversion_factor,
        "discount_percentage":
        flt(last_purchase.discount_percentage),
        "purchase_date":
        purchase_date
    })

    conversion_rate = flt(conversion_rate) or 1.0
    out.update({
        "price_list_rate": out.base_price_list_rate / conversion_rate,
        "rate": out.base_rate / conversion_rate,
        "base_rate": out.base_rate
    })

    return out
	def get_items(self):
		self.set('mtn_details', [])
		self.validate_production_order()

		pro_obj = None
		if self.production_order:
			# common validations
			pro_obj = frappe.get_doc('Production Order', self.production_order)
			if pro_obj:
				self.bom_no = pro_obj.bom_no
			else:
				# invalid production order
				self.production_order = None

		if self.bom_no:
			if self.purpose in ["Material Issue", "Material Transfer", "Manufacture", "Repack",
					"Subcontract"]:
				if self.production_order and self.purpose == "Material Transfer":
					item_dict = self.get_pending_raw_materials(pro_obj)
					if self.to_warehouse and pro_obj:
						for item in item_dict.values():
							item["to_warehouse"] = pro_obj.wip_warehouse
				else:
					if not self.fg_completed_qty:
						frappe.throw(_("Manufacturing Quantity is mandatory"))
					item_dict = self.get_bom_raw_materials(self.fg_completed_qty)
					for item in item_dict.values():
						if pro_obj:
							item["from_warehouse"] = pro_obj.wip_warehouse

						item["to_warehouse"] = self.to_warehouse if self.purpose=="Subcontract" else ""

				# add raw materials to Stock Entry Detail table
				self.add_to_stock_entry_detail(item_dict)

			# add finished good item to Stock Entry Detail table -- along with bom_no
			if self.production_order and self.purpose == "Manufacture":
				item = frappe.db.get_value("Item", pro_obj.production_item, ["item_name",
					"description", "stock_uom", "expense_account", "buying_cost_center"], as_dict=1)
				self.add_to_stock_entry_detail({
					cstr(pro_obj.production_item): {
						"to_warehouse": pro_obj.fg_warehouse,
						"from_warehouse": "",
						"qty": self.fg_completed_qty,
						"item_name": item.item_name,
						"description": item.description,
						"stock_uom": item.stock_uom,
						"expense_account": item.expense_account,
						"cost_center": item.buying_cost_center,
					}
				}, bom_no=pro_obj.bom_no)

			elif self.purpose in ["Material Receipt", "Repack"]:
				if self.purpose=="Material Receipt":
					self.from_warehouse = ""

				item = frappe.db.sql("""select name, item_name, description,
					stock_uom, expense_account, buying_cost_center from `tabItem`
					where name=(select item from tabBOM where name=%s)""",
					self.bom_no, as_dict=1)
				self.add_to_stock_entry_detail({
					item[0]["name"] : {
						"qty": self.fg_completed_qty,
						"item_name": item[0].item_name,
						"description": item[0]["description"],
						"stock_uom": item[0]["stock_uom"],
						"from_warehouse": "",
						"expense_account": item[0].expense_account,
						"cost_center": item[0].buying_cost_center,
					}
				}, bom_no=self.bom_no)

		self.get_stock_and_rate()
Exemple #55
0
def make_boilerplate(dest, app_name):
	if not os.path.exists(dest):
		print("Destination directory does not exist")
		return

	# app_name should be in snake_case
	app_name = frappe.scrub(app_name)

	hooks = frappe._dict()
	hooks.app_name = app_name
	app_title = hooks.app_name.replace("_", " ").title()
	for key in ("App Title (default: {0})".format(app_title),
		"App Description", "App Publisher", "App Email",
		"App Icon (default 'octicon octicon-file-directory')",
		"App Color (default 'grey')",
		"App License (default 'MIT')"):
		hook_key = key.split(" (")[0].lower().replace(" ", "_")
		hook_val = None
		while not hook_val:
			hook_val = cstr(input(key + ": "))

			if not hook_val:
				defaults = {
					"app_title": app_title,
					"app_icon": "octicon octicon-file-directory",
					"app_color": "grey",
					"app_license": "MIT"
				}
				if hook_key in defaults:
					hook_val = defaults[hook_key]

			if hook_key=="app_name" and hook_val.lower().replace(" ", "_") != hook_val:
				print("App Name must be all lowercase and without spaces")
				hook_val = ""
			elif hook_key=="app_title" and not re.match("^(?![\W])[^\d_\s][\w -]+$", hook_val, re.UNICODE):
				print("App Title should start with a letter and it can only consist of letters, numbers, spaces and underscores")
				hook_val = ""

		hooks[hook_key] = hook_val

	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, frappe.scrub(hooks.app_title)),
		with_init=True)
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates"), with_init=True)
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "www"))
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates",
		"pages"), with_init=True)
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates",
		"includes"))
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "config"), with_init=True)
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "public",
		"css"))
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "public",
		"js"))

	with open(os.path.join(dest, hooks.app_name, hooks.app_name, "__init__.py"), "w") as f:
		f.write(encode(init_template))

	with open(os.path.join(dest, hooks.app_name, "MANIFEST.in"), "w") as f:
		f.write(encode(manifest_template.format(**hooks)))

	with open(os.path.join(dest, hooks.app_name, ".gitignore"), "w") as f:
		f.write(encode(gitignore_template.format(app_name = hooks.app_name)))

	with open(os.path.join(dest, hooks.app_name, "setup.py"), "w") as f:
		f.write(encode(setup_template.format(**hooks)))

	with open(os.path.join(dest, hooks.app_name, "requirements.txt"), "w") as f:
		f.write("frappe")

	with open(os.path.join(dest, hooks.app_name, "README.md"), "w") as f:
		f.write(encode("## {0}\n\n{1}\n\n#### License\n\n{2}".format(hooks.app_title,
			hooks.app_description, hooks.app_license)))

	with open(os.path.join(dest, hooks.app_name, "license.txt"), "w") as f:
		f.write(encode("License: " + hooks.app_license))

	with open(os.path.join(dest, hooks.app_name, hooks.app_name, "modules.txt"), "w") as f:
		f.write(encode(hooks.app_title))

	with open(os.path.join(dest, hooks.app_name, hooks.app_name, "hooks.py"), "w") as f:
		f.write(encode(hooks_template.format(**hooks)))

	touch_file(os.path.join(dest, hooks.app_name, hooks.app_name, "patches.txt"))

	with open(os.path.join(dest, hooks.app_name, hooks.app_name, "config", "desktop.py"), "w") as f:
		f.write(encode(desktop_template.format(**hooks)))

	with open(os.path.join(dest, hooks.app_name, hooks.app_name, "config", "docs.py"), "w") as f:
		f.write(encode(docs_template.format(**hooks)))

	print("'{app}' created at {path}".format(app=app_name, path=os.path.join(dest, app_name)))
Exemple #56
0
def get_email_queue(recipients, sender, subject, **kwargs):
    '''Make Email Queue object'''
    e = frappe.new_doc('Email Queue')
    e.priority = kwargs.get('send_priority')
    attachments = kwargs.get('attachments')
    if attachments:
        # store attachments with fid or print format details, to be attached on-demand later
        _attachments = []
        for att in attachments:
            if att.get('fid'):
                _attachments.append(att)
            elif att.get("print_format_attachment") == 1:
                if not att.get('lang', None):
                    att['lang'] = frappe.local.lang
                att['print_letterhead'] = kwargs.get('print_letterhead')
                _attachments.append(att)
        e.attachments = json.dumps(_attachments)

    try:
        mail = get_email(recipients,
                         sender=sender,
                         subject=subject,
                         formatted=kwargs.get('formatted'),
                         text_content=kwargs.get('text_content'),
                         attachments=kwargs.get('attachments'),
                         reply_to=kwargs.get('reply_to'),
                         cc=kwargs.get('cc'),
                         bcc=kwargs.get('bcc'),
                         email_account=kwargs.get('email_account'),
                         expose_recipients=kwargs.get('expose_recipients'),
                         inline_images=kwargs.get('inline_images'),
                         header=kwargs.get('header'))

        mail.set_message_id(kwargs.get('message_id'),
                            kwargs.get('is_notification'))
        if kwargs.get('read_receipt'):
            mail.msg_root["Disposition-Notification-To"] = sender
        if kwargs.get('in_reply_to'):
            mail.set_in_reply_to(kwargs.get('in_reply_to'))

        e.message_id = mail.msg_root["Message-Id"].strip(" <>")
        e.message = cstr(mail.as_string())
        e.sender = mail.sender

    except frappe.InvalidEmailAddressError:
        # bad Email Address - don't add to queue
        import traceback
        frappe.log_error(
            'Invalid Email ID Sender: {0}, Recipients: {1}, \nTraceback: {2} '.
            format(mail.sender, ', '.join(mail.recipients),
                   traceback.format_exc()), 'Email Not Sent')

    recipients = list(
        set(recipients + kwargs.get('cc', []) + kwargs.get('bcc', [])))
    e.set_recipients(recipients)
    e.reference_doctype = kwargs.get('reference_doctype')
    e.reference_name = kwargs.get('reference_name')
    e.add_unsubscribe_link = kwargs.get("add_unsubscribe_link")
    e.unsubscribe_method = kwargs.get('unsubscribe_method')
    e.unsubscribe_params = kwargs.get('unsubscribe_params')
    e.expose_recipients = kwargs.get('expose_recipients')
    e.communication = kwargs.get('communication')
    e.send_after = kwargs.get('send_after')
    e.show_as_cc = ",".join(kwargs.get('cc', []))
    e.show_as_bcc = ",".join(kwargs.get('bcc', []))
    e.insert(ignore_permissions=True)

    return e
    def set_fieldname_and_label(self):
        if not self.label:
            self.label = cstr(self.document_type)

        if not self.fieldname:
            self.fieldname = scrub(self.label)
 def _check_serial_no_values(serial_no, field_values):
     serial_no = frappe.get_doc("Serial No", serial_no)
     for field, value in iteritems(field_values):
         self.assertEqual(cstr(serial_no.get(field)), value)
Exemple #59
0
def get_count_on(account, fieldname, date):
    cond = []
    if date:
        cond.append("posting_date <= '%s'" % frappe.db.escape(cstr(date)))
    else:
        # get balance of all entries that exist
        date = nowdate()

    try:
        year_start_date = get_fiscal_year(date, verbose=0)[1]
    except FiscalYearError:
        if getdate(date) > getdate(nowdate()):
            # if fiscal year not found and the date is greater than today
            # get fiscal year for today's date and its corresponding year start date
            year_start_date = get_fiscal_year(nowdate(), verbose=1)[1]
        else:
            # this indicates that it is a date older than any existing fiscal year.
            # hence, assuming balance as 0.0
            return 0.0

    if account:
        acc = frappe.get_doc("Account", account)

        if not frappe.flags.ignore_account_permission:
            acc.check_permission("read")

        # for pl accounts, get balance within a fiscal year
        if acc.report_type == 'Profit and Loss':
            cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
             % year_start_date)

        # different filter for group and ledger - improved performance
        if acc.is_group:
            cond.append("""exists (
				select name from `tabAccount` ac where ac.name = gle.account
				and ac.lft >= %s and ac.rgt <= %s
			)""" % (acc.lft, acc.rgt))
        else:
            cond.append("""gle.account = "%s" """ %
                        (frappe.db.escape(account, percent=False), ))

        entries = frappe.db.sql("""
			SELECT name, posting_date, account, party_type, party,debit,credit,
				voucher_type, voucher_no, against_voucher_type, against_voucher
			FROM `tabGL Entry` gle
			WHERE {0}""".format(" and ".join(cond)),
                                as_dict=True)

        count = 0
        for gle in entries:
            if fieldname not in ('invoiced_amount', 'payables'):
                count += 1
            else:
                dr_or_cr = "debit" if fieldname == "invoiced_amount" else "credit"
                cr_or_dr = "credit" if fieldname == "invoiced_amount" else "debit"
                select_fields = "ifnull(sum(credit-debit),0)" \
                 if fieldname == "invoiced_amount" else "ifnull(sum(debit-credit),0)"

                if ((not gle.against_voucher)
                        or (gle.against_voucher_type
                            in ["Sales Order", "Purchase Order"])
                        or (gle.against_voucher == gle.voucher_no
                            and gle.get(dr_or_cr) > 0)):
                    payment_amount = frappe.db.sql(
                        """
						SELECT {0}
						FROM `tabGL Entry` gle
						WHERE docstatus < 2 and posting_date <= %(date)s and against_voucher = %(voucher_no)s
						and party = %(party)s and name != %(name)s""".format(select_fields), {
                            "date": date,
                            "voucher_no": gle.voucher_no,
                            "party": gle.party,
                            "name": gle.name
                        })[0][0]

                    outstanding_amount = flt(gle.get(dr_or_cr)) - flt(
                        gle.get(cr_or_dr)) - payment_amount
                    currency_precision = get_currency_precision() or 2
                    if abs(flt(outstanding_amount)
                           ) > 0.1 / 10**currency_precision:
                        count += 1

        return count
Exemple #60
0
	def check_modified_date(self):
		mod_db = frappe.db.get_value("Sales Order", self.name, "modified")
		date_diff = frappe.db.sql("select TIMEDIFF('%s', '%s')" %
			( mod_db, cstr(self.modified)))
		if date_diff and date_diff[0][0]:
			frappe.throw(_("{0} {1} has been modified. Please refresh.").format(self.doctype, self.name))