def monthly_auto_repeat(self, doctype, docname, start_date, end_date): def get_months(start, end): diff = (12 * end.year + end.month) - (12 * start.year + start.month) return diff + 1 doc = make_auto_repeat( reference_doctype=doctype, frequency='Monthly', reference_document=docname, start_date=start_date, end_date=end_date) disable_auto_repeat(doc) for data in get_auto_repeat_entries(today()): create_repeated_entries(data) docnames = frappe.get_all(doc.reference_doctype, {'auto_repeat': doc.name}) self.assertEqual(len(docnames), 1) doc = frappe.get_doc('Auto Repeat', doc.name) doc.db_set('disabled', 0) months = get_months(getdate(start_date), getdate(today())) for data in get_auto_repeat_entries(today()): create_repeated_entries(data) docnames = frappe.get_all(doc.reference_doctype, {'auto_repeat': doc.name}) self.assertEqual(len(docnames), months)
def scrap_asset(asset_name): asset = frappe.get_doc("Asset", asset_name) if asset.docstatus != 1: frappe.throw(_("Asset {0} must be submitted").format(asset.name)) elif asset.status in ("Cancelled", "Sold", "Scrapped"): frappe.throw(_("Asset {0} cannot be scrapped, as it is already {1}").format(asset.name, asset.status)) depreciation_series = frappe.db.get_value("Company", asset.company, "series_for_depreciation_entry") je = frappe.new_doc("Journal Entry") je.voucher_type = "Journal Entry" je.naming_series = depreciation_series je.posting_date = today() je.company = asset.company je.remark = "Scrap Entry for asset {0}".format(asset_name) for entry in get_gl_entries_on_asset_disposal(asset): entry.update({ "reference_type": "Asset", "reference_name": asset_name }) je.append("accounts", entry) je.flags.ignore_permissions = True je.submit() frappe.db.set_value("Asset", asset_name, "disposal_date", today()) frappe.db.set_value("Asset", asset_name, "journal_entry_for_scrap", je.name) asset.set_status("Scrapped") frappe.msgprint(_("Asset scrapped via Journal Entry {0}").format(je.name))
def update_status(self): status = frappe.db.get_value("Task", self.name, "status") if self.status=="Working" and status !="Working" and not self.act_start_date: self.act_start_date = today() if self.status=="Closed" and status != "Closed" and not self.act_end_date: self.act_end_date = today()
def validateDates(self): years = int((getdate(today()) - getdate(self.dob)).days / 365.25) if(years < 18): frappe.throw(_("Date of Birth is invalid..Tenant age must be over 18 years")) if getdate(self.dob) >= getdate(today()): frappe.throw(_("Date of Birth cannot be greater than or equal to Today")) if self.status =="Terminated": if not self.wet: frappe.throw(_("Date of Termination is Mandatory when the tenant is terminated"))
def validate(self): # Maintain Status-wise dates for report purpose if self.status == "Recommended" and not self.recommend_date : self.recommend_date = today() if self.status == "Rejected" and not self.rejected_date : self.rejected_date = today() if self.status == "Alloted" and not self.alotted_date : self.alotted_date = today() if self.status == "Discharged" and not self.discharge_date : self.discharge_date = today()
def test_closing_entry(self): year_start_date = get_fiscal_year(today())[1] make_journal_entry("_Test Bank - _TC", "Sales - _TC", 400, "_Test Cost Center - _TC", posting_date=now(), submit=True) make_journal_entry("_Test Account Cost for Goods Sold - _TC", "_Test Bank - _TC", 600, "_Test Cost Center - _TC", posting_date=now(), submit=True) random_expense_account = frappe.db.sql(""" select t1.account, sum(t1.debit) - sum(t1.credit) as balance, sum(t1.debit_in_account_currency) - sum(t1.credit_in_account_currency) \ as balance_in_account_currency from `tabGL Entry` t1, `tabAccount` t2 where t1.account = t2.name and t2.root_type = 'Expense' and t2.docstatus < 2 and t2.company = '_Test Company' and t1.posting_date between %s and %s group by t1.account having sum(t1.debit) > sum(t1.credit) limit 1""", (year_start_date, today()), as_dict=True) profit_or_loss = frappe.db.sql("""select sum(t1.debit) - sum(t1.credit) as balance from `tabGL Entry` t1, `tabAccount` t2 where t1.account = t2.name and t2.report_type = 'Profit and Loss' and t2.docstatus < 2 and t2.company = '_Test Company' and t1.posting_date between %s and %s""", (year_start_date, today())) profit_or_loss = flt(profit_or_loss[0][0]) if profit_or_loss else 0 pcv = self.make_period_closing_voucher() # Check value for closing account gle_amount_for_closing_account = frappe.db.sql("""select debit - credit from `tabGL Entry` where voucher_type='Period Closing Voucher' and voucher_no=%s and account = '_Test Account Reserves and Surplus - _TC'""", pcv.name) gle_amount_for_closing_account = flt(gle_amount_for_closing_account[0][0]) \ if gle_amount_for_closing_account else 0 self.assertEqual(gle_amount_for_closing_account, profit_or_loss) if random_expense_account: # Check posted value for teh above random_expense_account gle_for_random_expense_account = frappe.db.sql(""" select debit - credit as amount, debit_in_account_currency - credit_in_account_currency as amount_in_account_currency from `tabGL Entry` where voucher_type='Period Closing Voucher' and voucher_no=%s and account =%s""", (pcv.name, random_expense_account[0].account), as_dict=True) self.assertEqual(gle_for_random_expense_account[0].amount, -1*random_expense_account[0].balance) self.assertEqual(gle_for_random_expense_account[0].amount_in_account_currency, -1*random_expense_account[0].balance_in_account_currency)
def make_subscription_entry(date=None): date = date or today() for data in get_subscription_entries(date): schedule_date = getdate(data.next_schedule_date) while schedule_date <= getdate(today()): create_documents(data, schedule_date) schedule_date = get_next_schedule_date(schedule_date, data.frequency, data.repeat_on_day) if schedule_date and not frappe.db.get_value('Subscription', data.name, 'disabled'): frappe.db.set_value('Subscription', data.name, 'next_schedule_date', schedule_date)
def test_create_training_event(self): if not frappe.db.get_value("Training Event", "Basic Training Event"): frappe.get_doc({ "doctype": "Training Event", "event_name": "Basic Training Event", "training_program": "Basic Training", "location": "Union Square", "start_time": add_days(today(), 5), "end_time": add_days(today(), 6), "introduction": "Welcome to the Basic Training Event", "employees": get_attendees(self.employee, self.employee2) }).insert()
def make_period_closing_voucher(self): pcv = frappe.get_doc({ "doctype": "Period Closing Voucher", "closing_account_head": "_Test Account Reserves and Surplus - _TC", "company": "_Test Company", "fiscal_year": get_fiscal_year(today())[0], "posting_date": today(), "remarks": "test" }) pcv.insert() pcv.submit() return pcv
def update_status(self): status = frappe.db.get_value("Task", self.name, "status") if self.status=="Working" and status !="Working" and not self.act_start_date: self.act_start_date = today() if self.status=="Closed" and status != "Closed" and not self.act_end_date: self.act_end_date = today() if self.status=="Closed" and status != "Closed" : #receiver_list=frappe.db.sql("") from erpnext.setup.doctype.sms_settings.sms_settings import send_sms receiver_list=[] receiver_list.append("9960066444") send_sms(receiver_list, "Hi the task is closed")
def create_delivery_note(**args): dn = frappe.new_doc("Delivery Note") args = frappe._dict(args) dn.posting_date = args.posting_date or today() if args.posting_time: dn.posting_time = args.posting_time dn.company = args.company or "_Test Company" dn.customer = args.customer or "_Test Customer" dn.currency = args.currency or "INR" dn.is_return = args.is_return dn.return_against = args.return_against dn.append("items", { "item_code": args.item or args.item_code or "_Test Item", "warehouse": args.warehouse or "_Test Warehouse - _TC", "qty": args.qty or 1, "rate": args.rate or 100, "conversion_factor": 1.0, "expense_account": "Cost of Goods Sold - _TC", "cost_center": "_Test Cost Center - _TC", "serial_no": args.serial_no, "target_warehouse": args.target_warehouse }) if not args.do_not_save: dn.insert() if not args.do_not_submit: dn.submit() return dn
def make_course_schedule_test_record(**args): args = frappe._dict(args) course_schedule = frappe.new_doc("Course Schedule") course_schedule.student_group = args.student_group or "Course-TC101-2014-2015 (_Test Academic Term)" course_schedule.course = args.course or "TC101" course_schedule.instructor = args.instructor or "_Test Instructor" course_schedule.room = args.room or frappe.get_all("Room")[0].name course_schedule.schedule_date = args.schedule_date or today() course_schedule.from_time = args.from_time or to_timedelta("01:00:00") course_schedule.to_time = args.to_time or course_schedule.from_time + datetime.timedelta(hours= 1) if not args.do_not_save: if args.simulate: while True: try: course_schedule.save() break except OverlapError: course_schedule.from_time = course_schedule.from_time + datetime.timedelta(minutes=10) course_schedule.to_time = course_schedule.from_time + datetime.timedelta(hours= 1) else: course_schedule.save() return course_schedule
def collect_project_status(): for data in frappe.get_all("Project Update", {'date': today(), 'sent': 0}): replies = frappe.get_all('Communication', fields=['content', 'text_content', 'sender'], filters=dict(reference_doctype="Project Update", reference_name=data.name, communication_type='Communication', sent_or_received='Received'), order_by='creation asc') for d in replies: doc = frappe.get_doc("Project Update", data.name) user_data = frappe.db.get_values("User", {"email": d.sender}, ["full_name", "user_image", "name"], as_dict=True)[0] doc.append("users", { 'user': user_data.name, 'full_name': user_data.full_name, 'image': user_data.user_image, 'project_status': frappe.utils.md_to_html( EmailReplyParser.parse_reply(d.text_content) or d.content ) }) doc.save(ignore_permissions=True)
def make_sharing_request(event_data, data, files_list=None, event_dict=None, sub_event_count=None): req = frappe.new_doc('Shared Requests') d = event_data.get('sharelist')[0] frappe.errprint([d, type(d), data]) req.event_id = d.get("event_tag_id") req.provider_id = d.get("to_profile_id") req.date = today() req.patient = d.get("from_profile_id") req.patient_name = frappe.db.get_value("User", {"profile_id":d.get("from_profile_id")}, 'concat(first_name, " ", last_name)') or data.get('lphr_name') req.reason = data.get('reason') req.valid_upto = data.get('sharing_duration') if d.get("visit_tag_id"): req.event_title = get_event_info(d.get("event_tag_id")) req.visit_id = d.get("visit_tag_id") else: req.event_title = data.get("event_title") req.doc_name = 'Event' if files_list: req.files_list = json.dumps(files_list) req.event_dict = json.dumps(event_dict) req.sub_event_count = json.dumps(sub_event_count) req.save(ignore_permissions=True)
def make_purchase_receipt(**args): pr = frappe.new_doc("Purchase Receipt") args = frappe._dict(args) pr.posting_date = args.posting_date or today() if args.posting_time: pr.posting_time = args.posting_time pr.company = args.company or "_Test Company" pr.supplier = args.supplier or "_Test Supplier" pr.is_subcontracted = args.is_subcontracted or "No" pr.supplier_warehouse = "_Test Warehouse 1 - _TC" pr.currency = args.currency or "INR" pr.is_return = args.is_return pr.return_against = args.return_against qty = args.qty or 5 received_qty = args.received_qty or qty rejected_qty = args.rejected_qty or flt(received_qty) - flt(qty) pr.append("items", { "item_code": args.item or args.item_code or "_Test Item", "warehouse": args.warehouse or "_Test Warehouse - _TC", "qty": qty, "received_qty": received_qty, "rejected_qty": rejected_qty, "rejected_warehouse": args.rejected_warehouse or "_Test Rejected Warehouse - _TC" if rejected_qty != 0 else "", "rate": args.rate or 50, "conversion_factor": 1.0, "serial_no": args.serial_no, "stock_uom": "_Test UOM" }) if not args.do_not_save: pr.insert() if not args.do_not_submit: pr.submit() return pr
def create_purchase_invoice(**args): # return sales invoice doc object item = frappe.get_doc('Item', {'item_name': 'TDS Item'}) args = frappe._dict(args) pi = frappe.get_doc({ "doctype": "Purchase Invoice", "posting_date": today(), "apply_tds": 1, "supplier": args.supplier, "company": '_Test Company', "taxes_and_charges": "", "currency": "INR", "credit_to": "Creditors - _TC", "taxes": [], "items": [{ 'doctype': 'Purchase Invoice Item', 'item_code': item.name, 'qty': args.qty or 1, 'rate': args.rate or 10000, 'cost_center': 'Main - _TC', 'expense_account': 'Stock Received But Not Billed - _TC' }] }) pi.save() return pi
def validate_date(self): if self.date_of_birth and getdate(self.date_of_birth) > getdate(today()): throw(_("Date of Birth cannot be greater than today.")) if self.date_of_birth and self.date_of_joining and getdate(self.date_of_birth) >= getdate(self.date_of_joining): throw(_("Date of Joining must be greater than Date of Birth")) elif ( self.date_of_retirement and self.date_of_joining and (getdate(self.date_of_retirement) <= getdate(self.date_of_joining)) ): throw(_("Date Of Retirement must be greater than Date of Joining")) elif ( self.relieving_date and self.date_of_joining and (getdate(self.relieving_date) <= getdate(self.date_of_joining)) ): throw(_("Relieving Date must be greater than Date of Joining")) elif ( self.contract_end_date and self.date_of_joining and (getdate(self.contract_end_date) <= getdate(self.date_of_joining)) ): throw(_("Contract End Date must be greater than Date of Joining"))
def make_course_schedule_test_record(**args): args = frappe._dict(args) course_schedule = frappe.new_doc("Course Schedule") course_schedule.student_group = args.student_group or "_Test Student Group" course_schedule.course = args.course or "_Test Course" course_schedule.instructor = args.instructor or "_T-Instructor-00001" course_schedule.room = args.room or "RM0001" course_schedule.schedule_date = args.schedule_date or today() course_schedule.from_time = args.from_time or to_timedelta("01:00:00") course_schedule.to_time = args.to_time or course_schedule.from_time + datetime.timedelta(hours= 1) if not args.do_not_save: if args.simulate: while True: try: course_schedule.save() break except OverlapError: course_schedule.from_time = course_schedule.from_time + datetime.timedelta(minutes=10) course_schedule.to_time = course_schedule.from_time + datetime.timedelta(hours= 1) else: course_schedule.save() return course_schedule
def get_booking_dates(doc, item, posting_date=None): if not posting_date: posting_date = add_days(today(), -1) last_gl_entry = False deferred_account = "deferred_revenue_account" if doc.doctype=="Sales Invoice" else "deferred_expense_account" prev_gl_entry = frappe.db.sql(''' select name, posting_date from `tabGL Entry` where company=%s and account=%s and voucher_type=%s and voucher_no=%s and voucher_detail_no=%s order by posting_date desc limit 1 ''', (doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True) if prev_gl_entry: start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1)) else: start_date = item.service_start_date end_date = get_last_day(start_date) if end_date >= item.service_end_date: end_date = item.service_end_date last_gl_entry = True elif item.service_stop_date and end_date >= item.service_stop_date: end_date = item.service_stop_date last_gl_entry = True if end_date > getdate(posting_date): end_date = posting_date if getdate(start_date) <= getdate(end_date): return start_date, end_date, last_gl_entry else: return None, None, None
def send_project_update_email_to_users(project): doc = frappe.get_doc('Project', project) if is_holiday_today(doc.holiday_list) or not doc.users: return project_update = frappe.get_doc({ "doctype" : "Project Update", "project" : project, "sent": 0, "date": today(), "time": nowtime(), "naming_series": "UPDATE-.project.-.YY.MM.DD.-", }).insert() subject = "For project %s, update your status" % (project) incoming_email_account = frappe.db.get_value('Email Account', dict(enable_incoming=1, default_incoming=1), 'email_id') frappe.sendmail(recipients=get_users_email(doc), message=doc.message, subject=_(subject), reference_doctype=project_update.doctype, reference_name=project_update.name, reply_to=incoming_email_account )
def set_tax_withholding_category(company): accounts = [] abbr = frappe.get_value("Company", company, "abbr") tds_account = frappe.get_value("Account", 'TDS Payable - {0}'.format(abbr), 'name') if company and tds_account: accounts = [dict(company=company, account=tds_account)] fiscal_year = get_fiscal_year(today(), company=company)[0] docs = get_tds_details(accounts, fiscal_year) for d in docs: try: doc = frappe.get_doc(d) doc.flags.ignore_permissions = True doc.flags.ignore_mandatory = True doc.insert() except frappe.DuplicateEntryError: doc = frappe.get_doc("Tax Withholding Category", d.get("name")) doc.append("accounts", accounts[0]) # if fiscal year don't match with any of the already entered data, append rate row fy_exist = [k for k in doc.get('rates') if k.get('fiscal_year')==fiscal_year] if not fy_exist: doc.append("rates", d.get('rates')[0]) doc.save()
def test_get_mode_of_payments(self): filters = get_filters() for dummy in range(2): si = create_sales_invoice_record() si.insert() si.submit() if int(si.name[-3:])%2 == 0: bank_account = "_Test Cash - _TC" mode_of_payment = "Cash" else: bank_account = "_Test Bank - _TC" mode_of_payment = "Credit Card" pe = get_payment_entry("Sales Invoice", si.name, bank_account=bank_account) pe.reference_no = "_Test" pe.reference_date = today() pe.mode_of_payment = mode_of_payment pe.insert() pe.submit() mop = get_mode_of_payments(filters) self.assertTrue('Credit Card' in mop.values()[0]) self.assertTrue('Cash' in mop.values()[0]) # Cancel all Cash payment entry and check if this mode of payment is still fetched. payment_entries = frappe.get_all("Payment Entry", filters={"mode_of_payment": "Cash", "docstatus": 1}, fields=["name", "docstatus"]) for payment_entry in payment_entries: pe = frappe.get_doc("Payment Entry", payment_entry.name) pe.cancel() mop = get_mode_of_payments(filters) self.assertTrue('Credit Card' in mop.values()[0]) self.assertTrue('Cash' not in mop.values()[0])
def make_opportunity(**args): args = frappe._dict(args) opp_doc = frappe.get_doc({ "doctype": "Opportunity", "enquiry_from": args.enquiry_from or "Customer", "enquiry_type": "Sales", "with_items": args.with_items or 0, "transaction_date": today() }) if opp_doc.enquiry_from == 'Customer': opp_doc.customer = args.customer or "_Test Customer" if opp_doc.enquiry_from == 'Lead': opp_doc.customer = args.lead or "_T-Lead-00001" if args.with_items: opp_doc.append('items', { "item_code": args.item_code or "_Test Item", "qty": args.qty or 1 }) opp_doc.insert() return opp_doc
def get_item_map(item_code): """Optimization: get only the item doc and re_order_levels table""" condition = "" if item_code: condition = 'and item_code = "{0}"'.format(frappe.db.escape(item_code, percent=False)) items = frappe.db.sql("""select * from `tabItem` item where is_stock_item = 1 and disabled=0 {condition} and (end_of_life > %(today)s or end_of_life is null or end_of_life='0000-00-00') and exists (select name from `tabBin` bin where bin.item_code=item.name)"""\ .format(condition=condition), {"today": today()}, as_dict=True) condition = "" if item_code: condition = 'where parent="{0}"'.format(frappe.db.escape(item_code, percent=False)) reorder_levels = frappe._dict() for ir in frappe.db.sql("""select * from `tabItem Reorder` {condition}""".format(condition=condition), as_dict=1): if ir.parent not in reorder_levels: reorder_levels[ir.parent] = [] reorder_levels[ir.parent].append(ir) item_map = frappe._dict() for item in items: item["reorder_levels"] = reorder_levels.get(item.name) or [] item_map[item.name] = item return item_map
def set_missing_values(self, for_validate=False): for fieldname in ["posting_date", "transaction_date"]: if not self.get(fieldname) and self.meta.get_field(fieldname): self.set(fieldname, today()) if not self.fiscal_year: self.fiscal_year = get_fiscal_year(self.get(fieldname))[0] break
def add_support_communication(subject, content, sender, docname=None, mail=None): if docname: ticket = frappe.get_doc("Support Ticket", docname) ticket.status = 'Open' ticket.ignore_permissions = True ticket.save() else: ticket = frappe.get_doc(decode_dict({ "doctype":"Support Ticket", "description": content, "subject": subject, "raised_by": sender, "content_type": mail.content_type if mail else None, "status": "Open", })) ticket.ignore_permissions = True ticket.ignore_mandatory = True ticket.insert() _make(content=content, sender=sender, subject = subject, doctype="Support Ticket", name=ticket.name, date=mail.date if mail else today(), sent_or_received="Received") if mail: mail.save_attachments_in_doc(ticket) return ticket
def test_make_new_lead_if_required(self): args = { "doctype": "Opportunity", "contact_email":"*****@*****.**", "enquiry_type": "Sales", "with_items": 0, "transaction_date": today() } # new lead should be created against the [email protected] opp_doc = frappe.get_doc(args).insert(ignore_permissions=True) self.assertTrue(opp_doc.lead) self.assertEquals(opp_doc.enquiry_from, "Lead") self.assertEquals(frappe.db.get_value("Lead", opp_doc.lead, "email_id"), '*****@*****.**') # create new customer and create new contact against '*****@*****.**' customer = make_customer(opp_doc.lead).insert(ignore_permissions=True) frappe.get_doc({ "doctype": "Contact", "email_id": "*****@*****.**", "first_name": "_Test Opportunity Customer", "links": [{ "link_doctype": "Customer", "link_name": customer.name }] }).insert(ignore_permissions=True) opp_doc = frappe.get_doc(args).insert(ignore_permissions=True) self.assertTrue(opp_doc.customer) self.assertEquals(opp_doc.enquiry_from, "Customer") self.assertEquals(opp_doc.customer, customer.name)
def validate(self): if session['user'] != 'Guest' and not self.customer: frappe.throw(_("Customer is required")) if self.status=="Closed" and \ frappe.db.get_value("Warranty Claim", self.name, "status")!="Closed": self.resolution_date = today()
def make_auto_repeat_entry(date=None): enqueued_method = 'frappe.desk.doctype.auto_repeat.auto_repeat.create_repeated_entries' jobs = get_jobs() if not jobs or enqueued_method not in jobs[frappe.local.site]: date = date or today() for data in get_auto_repeat_entries(date): frappe.enqueue(enqueued_method, data=data)
def convert_deferred_revenue_to_income(start_date=None, end_date=None): # book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM if not start_date: start_date = add_months(today(), -1) if not end_date: end_date = add_days(today(), -1) # check for the sales invoice for which GL entries has to be done invoices = frappe.db.sql_list(''' select distinct parent from `tabSales Invoice Item` where service_start_date<=%s and service_end_date>=%s and enable_deferred_revenue = 1 and docstatus = 1 and ifnull(amount, 0) > 0 ''', (end_date, start_date)) for invoice in invoices: doc = frappe.get_doc("Sales Invoice", invoice) book_deferred_income_or_expense(doc, end_date)
def make_patient_activity(patient, activity_items, sales_person=None): activity_items = json.loads(activity_items) patient_activity = frappe.get_doc({ 'doctype': 'Patient Activity', 'patient': patient, 'sales_person': sales_person, 'posting_date': today() }) for activity_item in activity_items: patient_activity.append( 'items', { 'activity_type': activity_item.get('activity_type'), 'description': activity_item.get('description'), 'attach': activity_item.get('attach') }) patient_activity.save() return patient_activity
def send_birthday_wish(): birthdays = frappe.db.sql( """select name,date_of_birth,company_email, employee_name from tabEmployee where day(date_of_birth) = day(%(date)s) and month(date_of_birth) = month(%(date)s) and status = 'Active'""", {"date": today()}, as_dict=True) for r in birthdays: print(r) wish = frappe.get_doc("Birthday Wishes") result = [] for w in wish.wishes: res = w.wishes result.append(res) s = random.sample(result, 1) print(s) if birthdays: frappe.sendmail(recipients=['r.company_email'], subject="Birthday Wishes for {0}"), message = """<p> Dear {1} <br> {2} ,</p>""".format( r.employee_name, r.employee_name, s)
def update_maintenance_status(): assets = frappe.get_all("Asset", filters={ "docstatus": 1, "maintenance_required": 1 }) for asset in assets: asset = frappe.get_doc("Asset", asset.name) if frappe.db.exists("Asset Repair", { "asset_name": asset.name, "repair_status": "Pending" }): asset.set_status("Out of Order") elif frappe.db.exists("Asset Maintenance Task", { "parent": asset.name, "next_due_date": today() }): asset.set_status("In Maintenance") else: asset.set_status()
def update_company_current_month_sales(company): current_month_year = formatdate(today(), "MM-yyyy") results = frappe.db.sql(''' select sum(base_grand_total) as total, date_format(posting_date, '%m-%Y') as month_year from `tabSales Invoice` where date_format(posting_date, '%m-%Y')="{0}" and docstatus = 1 and company = "{1}" group by month_year '''.format(current_month_year, frappe.db.escape(company)), as_dict=True) monthly_total = results[0]['total'] if len(results) > 0 else 0 frappe.db.set_value("Company", company, "total_monthly_sales", monthly_total)
def test_disable_scheduler_on_expiry(self): update_limits({'expiry': add_to_date(today(), days=-1)}) frappe.local.conf = _dict(frappe.get_site_config()) if not frappe.db.exists('User', '*****@*****.**'): user = frappe.new_doc('User') user.email = '*****@*****.**' user.first_name = 'Test_scheduler' user.save() user.add_roles('System Manager') frappe.db.commit() frappe.set_user("*****@*****.**") disable_scheduler_on_expiry() ss = frappe.get_doc("System Settings") self.assertFalse(ss.enable_scheduler) clear_limit("expiry") frappe.local.conf = _dict(frappe.get_site_config())
def allocate_review_points(): settings = frappe.get_single('Energy Point Settings') if not can_allocate_today(settings.last_point_allocation_date, settings.point_allocation_periodicity): return user_point_map = {} for level in settings.review_levels: users = get_users_with_role(level.role) for user in users: user_point_map.setdefault(user, 0) # to avoid duplicate point allocation user_point_map[user] = max([user_point_map[user], level.review_points]) for user, points in user_point_map.items(): create_review_points_log(user, points) settings.last_point_allocation_date = today() settings.save(ignore_permissions=True)
def execute(): if frappe.db.exists('DocType', 'Email Campaign'): email_campaign = frappe.get_all('Email Campaign') for campaign in email_campaign: doc = frappe.get_doc("Email Campaign", campaign["name"]) send_after_days = [] camp = frappe.get_doc("Campaign", doc.campaign_name) for entry in camp.get("campaign_schedules"): send_after_days.append(entry.send_after_days) if send_after_days: end_date = add_days(getdate(doc.start_date), max(send_after_days)) doc.db_set("end_date", end_date) today_date = getdate(today()) if doc.start_date > today_date: doc.db_set("status", "Scheduled") elif end_date >= today_date: doc.db_set("status", "In Progress") elif end_date < today_date: doc.db_set("status", "Completed")
def validate_dates(self): for sibling in self.siblings: if sibling.date_of_birth and getdate( sibling.date_of_birth) > getdate(): frappe.throw( _("Row {0}:Sibling Date of Birth cannot be greater than today." ).format(sibling.idx)) if self.date_of_birth and getdate(self.date_of_birth) >= getdate( today()): frappe.throw(_("Date of Birth cannot be greater than today.")) if self.date_of_birth and getdate(self.date_of_birth) >= getdate( self.joining_date): frappe.throw( _("Date of Birth cannot be greater than Joining Date.")) if (self.joining_date and self.date_of_leaving and getdate(self.joining_date) > getdate(self.date_of_leaving)): frappe.throw( _("Joining Date can not be greater than Leaving Date"))
def get_loyalty_details(customer, loyalty_program, expiry_date=None, company=None, include_expired_entry=False): if not expiry_date: expiry_date = today() condition = '' if company: condition = " and company='%s' " % frappe.db.escape(company) if not include_expired_entry: condition += " and expiry_date>='%s' " % expiry_date loyalty_point_details = frappe.db.sql('''select sum(loyalty_points) as loyalty_points, sum(purchase_amount) as total_spent from `tabLoyalty Point Entry` where customer=%s and loyalty_program=%s and posting_date <= %s {condition} group by customer'''.format(condition=condition), (customer, loyalty_program, expiry_date), as_dict=1) if loyalty_point_details: return loyalty_point_details[0] else: return {"loyalty_points": 0, "total_spent": 0}
def save_payment_allocation(data): if data: data = json.loads(data) pa = frappe.new_doc("Payment Allocation") pa.customer = data.get("customer") pa.posting_date = today() for k, v in data.get("items", {}).items(): pa.append( "payment_allocation_items", { "item_code": k, "qty": v[0], "rate": v[1], "amount": int(v[0]) * flt(v[1]), "against_sales_order": v[2], "remarks": v[4] }) pa.flags.ignore_permissions = True pa.save() frappe.db.commit() return "Success"
def get_payment_terms_from_file(file_content): terms = [] #Get mode of payment dict from setup mop_options = frappe.get_meta('Mode of Payment').fields[4].options mop_str = re.sub('\n', ',', mop_options) mop_dict = dict(item.split("-") for item in mop_str.split(",")) #read file for payment information for line in file_content.find_all("DettaglioPagamento"): mop_code = line.ModalitaPagamento.text + '-' + mop_dict.get(line.ModalitaPagamento.text) if line.find("DataScadenzaPagamento"): due_date = dateutil.parser.parse(line.DataScadenzaPagamento.text).strftime("%Y-%m-%d") else: due_date = today() terms.append({ "mode_of_payment_code": mop_code, "bank_account_iban": line.IBAN.text if line.find("IBAN") else "", "due_date": due_date, "payment_amount": line.ImportoPagamento.text }) return terms
def save_sales_order_item_for_sd(sid, item_id, item_qty, rate): #rate=frappe.db.get("Item",{"name":item_id}).standard_rate item_doc = frappe.get_doc({ "docstatus": 0, "doctype": "Sales Order Item", "name": "New Sales Order Item 1", "__islocal": 1, "__unsaved": 1, "owner": str(frappe.session.user), "parent": str(sid), "parentfield": "items", "parenttype": "Sales Order", "idx": 1, "qty": str(item_qty), "rate": rate, "item_code": str(item_id), "update_stock": 0, "delivery_date": str(today()) }) item_save = item_doc.insert()
def test_leave_balance_value_and_amount(self): frappe.db.sql('''delete from `tabLeave Encashment`''') leave_encashment = frappe.get_doc( dict(doctype='Leave Encashment', employee=self.employee, leave_type="_Test Leave Type Encashment", leave_period=self.leave_period.name, payroll_date=today(), currency="INR")).insert() self.assertEqual(leave_encashment.leave_balance, 10) self.assertEqual(leave_encashment.encashable_days, 5) self.assertEqual(leave_encashment.encashment_amount, 250) leave_encashment.submit() # assert links add_sal = frappe.get_all( "Additional Salary", filters={"ref_docname": leave_encashment.name})[0] self.assertTrue(add_sal)
def update_company_current_month_sales(company): current_month_year = formatdate(today(), "MM-yyyy") results = frappe.db.sql(''' SELECT SUM(base_grand_total) AS total, DATE_FORMAT(`posting_date`, '%m-%Y') AS month_year FROM `tabSales Invoice` WHERE DATE_FORMAT(`posting_date`, '%m-%Y') = '{current_month_year}' AND docstatus = 1 AND company = {company} GROUP BY month_year '''.format(current_month_year=current_month_year, company=frappe.db.escape(company)), as_dict = True) monthly_total = results[0]['total'] if len(results) > 0 else 0 frappe.db.set_value("Company", company, "total_monthly_sales", monthly_total)
def makeReceivingSheet(master_sales_order): to_date=today() master_so=frappe.get_doc("Master Sales Order",str(master_sales_order)) if not frappe.db.exists("Master Sales Receiving Mode",str(master_sales_order)): data2=frappe.get_doc({ "docstatus": 0, "doctype": "Master Sales Receiving Mode", "name": "New Master Sales Receiving Mode 1", "master_sales_order": master_sales_order, "shipping_date": master_so.shipping_date, "delivery_date": master_so.delivery_date, "order_type": master_so.order_type, "receiving_date": to_date }) d=data2.insert(ignore_permissions=True) if d: return d.name else: check_sheet=frappe.get_doc("Receiving Sheet",str(master_sales_order)) return check_sheet.name
def reconcile_dr_cr_note(dr_cr_notes, company): for d in dr_cr_notes: voucher_type = ('Credit Note' if d.voucher_type == 'Sales Invoice' else 'Debit Note') reconcile_dr_or_cr = ('debit_in_account_currency' if d.dr_or_cr == 'credit_in_account_currency' else 'credit_in_account_currency') company_currency = erpnext.get_company_currency(company) jv = frappe.get_doc({ "doctype": "Journal Entry", "voucher_type": voucher_type, "posting_date": today(), "company": company, "multi_currency": 1 if d.currency != company_currency else 0, "accounts": [ { 'account': d.account, 'party': d.party, 'party_type': d.party_type, d.dr_or_cr: abs(d.allocated_amount), 'reference_type': d.against_voucher_type, 'reference_name': d.against_voucher, 'cost_center': erpnext.get_default_cost_center(company) }, { 'account': d.account, 'party': d.party, 'party_type': d.party_type, reconcile_dr_or_cr: (abs(d.allocated_amount) if abs(d.unadjusted_amount) > abs(d.allocated_amount) else abs(d.unadjusted_amount)), 'reference_type': d.voucher_type, 'reference_name': d.voucher_no, 'cost_center': erpnext.get_default_cost_center(company) } ] }) jv.submit()
def update_password(new_password, logout_all_sessions=0, key=None, old_password=None): # validate key to avoid key input like ['like', '%'], '', ['in', ['']] if key and not isinstance(key, str): frappe.throw(_("Invalid key type")) result = test_password_strength(new_password, key, old_password) feedback = result.get("feedback", None) if feedback and not feedback.get("password_policy_validation_passed", False): handle_password_test_fail(result) res = _get_user_for_update_password(key, old_password) if res.get("message"): frappe.local.response.http_status_code = 410 return res["message"] else: user = res["user"] logout_all_sessions = cint(logout_all_sessions) or frappe.db.get_single_value( "System Settings", "logout_on_password_reset" ) _update_password(user, new_password, logout_all_sessions=cint(logout_all_sessions)) user_doc, redirect_url = reset_user_data(user) # get redirect url from cache redirect_to = frappe.cache().hget("redirect_after_login", user) if redirect_to: redirect_url = redirect_to frappe.cache().hdel("redirect_after_login", user) frappe.local.login_manager.login_as(user) frappe.db.set_value("User", user, "last_password_reset_date", today()) frappe.db.set_value("User", user, "reset_password_key", "") if user_doc.user_type == "System User": return "/app" else: return redirect_url if redirect_url else "/"
def process_expired_allocation(): ''' Check if a carry forwarded allocation has expired and create a expiry ledger entry ''' # fetch leave type records that has carry forwarded leaves expiry leave_type_records = frappe.db.get_values( "Leave Type", filters={'expire_carry_forwarded_leaves_after_days': (">", 0)}, fieldname=['name']) if leave_type_records: leave_type = [record[0] for record in leave_type_records] expired_allocation = frappe.db.sql_list("""SELECT name FROM `tabLeave Ledger Entry` WHERE `transaction_type`='Leave Allocation' AND `is_expired`=1""") expire_allocation = frappe.get_all("Leave Ledger Entry", fields=[ 'leaves', 'to_date', 'employee', 'leave_type', 'is_carry_forward', 'transaction_name as name', 'transaction_type' ], filters={ 'to_date': ("<", today()), 'transaction_type': 'Leave Allocation', 'transaction_name': ('not in', expired_allocation) }, or_filters={ 'is_carry_forward': 0, 'leave_type': ('in', leave_type) }) if expire_allocation: create_expiry_ledger_entry(expire_allocation)
def create_invoice(customer, billing, shipping, pflanzenfreund_abo, abo): sales_invoice = frappe.new_doc("Sales Invoice") sales_invoice.update({ "customer": customer, "customer_address": billing, "shipping_address_name": shipping, "delivery_date": utils.today(), "pflanzenfreund_abo": pflanzenfreund_abo.name, "taxes_and_charges": "Schweiz normal (302) - GCM", "items": [{ "item_code": abo, "qty": "1" }], "taxes": [{ "charge_type": "On Net Total", "account_head": "2200 - Umsatzsteuer - GCM", "cost_center": "Haupt - GCM", "rate": "7.7", "description": "Inkl. 7.7% MwSt" }] }) sales_invoice.flags.ignore_mandatory = True sales_invoice.save(ignore_permissions=True) referencenumber = sales_invoice.name.split("-")[1] sales_invoice.update({ "esr_reference": esr.get_reference_number(referencenumber), "esr_code": esr.generateCodeline(sales_invoice.grand_total, referencenumber, "013100113") }) sales_invoice.save(ignore_permissions=True) sales_invoice.submit() frappe.db.commit()
def process_expired_allocation(): ''' Check if a carry forwarded allocation has expired and create a expiry ledger entry Case 1: carry forwarded expiry period is set for the leave type, create a separate leave expiry entry against each entry of carry forwarded and non carry forwarded leaves Case 2: leave type has no specific expiry period for carry forwarded leaves and there is no carry forwarded leave allocation, create a single expiry against the remaining leaves. ''' # fetch leave type records that has carry forwarded leaves expiry leave_type_records = frappe.db.get_values( "Leave Type", filters={'expire_carry_forwarded_leaves_after_days': (">", 0)}, fieldname=['name']) leave_type = [record[0] for record in leave_type_records] or [''] # fetch non expired leave ledger entry of transaction_type allocation expire_allocation = frappe.db.sql(""" SELECT leaves, to_date, employee, leave_type, is_carry_forward, transaction_name as name, transaction_type FROM `tabLeave Ledger Entry` l WHERE (NOT EXISTS (SELECT name FROM `tabLeave Ledger Entry` WHERE transaction_name = l.transaction_name AND transaction_type = 'Leave Allocation' AND name<>l.name AND docstatus = 1 AND ( is_carry_forward=l.is_carry_forward OR (is_carry_forward = 0 AND leave_type not in %s) ))) AND transaction_type = 'Leave Allocation' AND to_date < %s""", (leave_type, today()), as_dict=1) if expire_allocation: create_expiry_ledger_entry(expire_allocation)
def get_data(report_filters): data = [] checkmark = [] if (report_filters.date): filters = { "status": report_filters.status, "date": ['is', report_filters.date], } else: filters = { "status": report_filters.status, } names_of_todo_docs = frappe.get_all("ToDo", filters=filters, fields = ["name","description", "status", "priority", "reference_type", "reference_name","date"], order_by = "") # print(names_of_todo_docs) for entry in names_of_todo_docs: # print(entry) #### calculate remaining time today = utils.today(); if entry.date: datediff = utils.date_diff(entry.date, today) entry['days_to_due_date'] = datediff if entry.reference_type: entry.reference = """<a href="#Form/%s/%s">%s: %s</a>""" % (entry.reference_type, entry.reference_name, entry.reference_type, entry.reference_name) else: entry.reference = None data.append(entry) return data
def test_multi_uom_for_purchase(self): mr = frappe.copy_doc(test_records[0]) mr.material_request_type = 'Purchase' item = mr.items[0] mr.schedule_date = today() if not frappe.db.get_value('UOM Conversion Detail', {'parent': item.item_code, 'uom': 'Kg'}): item_doc = frappe.get_doc('Item', item.item_code) item_doc.append('uoms', { 'uom': 'Kg', 'conversion_factor': 5 }) item_doc.save(ignore_permissions=True) item.uom = 'Kg' for item in mr.items: item.schedule_date = mr.schedule_date mr.insert() self.assertRaises(frappe.ValidationError, make_purchase_order, mr.name) mr = frappe.get_doc("Material Request", mr.name) mr.submit() item = mr.items[0] self.assertEqual(item.uom, "Kg") self.assertEqual(item.conversion_factor, 5.0) self.assertEqual(item.stock_qty, flt(item.qty * 5)) po = make_purchase_order(mr.name) self.assertEqual(po.doctype, "Purchase Order") self.assertEqual(len(po.get("items")), len(mr.get("items"))) po.supplier = '_Test Supplier' po.insert() po.submit() mr = frappe.get_doc("Material Request", mr.name) self.assertEqual(mr.per_ordered, 100)
def get_sal_structure(employee): cond = """and sa.employee=%(employee)s and sa.from_date <= %(date)s""" st_name = frappe.db.sql( """ select sa.salary_structure from `tabSalary Structure Assignment` sa join `tabSalary Structure` ss where sa.salary_structure=ss.name and sa.docstatus = 1 and ss.docstatus = 1 and ss.is_active ='Yes' %s order by sa.from_date desc limit 1 """ % cond, { 'employee': employee, 'date': today() }) if st_name: return st_name[0][0] else: frappe.msgprint(_( "No active or default Salary Structure found for employee {0} for the given dates" ).format(employee), title=_('Salary Structure Missing'))
def get_next_schedule_date(self, schedule_date, for_full_schedule=False): """ Returns the next schedule date for auto repeat after a recurring document has been created. Adds required offset to the schedule_date param and returns the next schedule date. :param schedule_date: The date when the last recurring document was created. :param for_full_schedule: If True, returns the immediate next schedule date, else the full schedule. """ if month_map.get(self.frequency): month_count = month_map.get(self.frequency) + month_diff( schedule_date, self.start_date) - 1 else: month_count = 0 day_count = 0 if month_count and self.repeat_on_last_day: day_count = 31 next_date = get_next_date(self.start_date, month_count, day_count) elif month_count and self.repeat_on_day: day_count = self.repeat_on_day next_date = get_next_date(self.start_date, month_count, day_count) elif month_count: next_date = get_next_date(self.start_date, month_count) else: days = self.get_days(schedule_date) next_date = add_days(schedule_date, days) # next schedule date should be after or on current date if not for_full_schedule: while getdate(next_date) < getdate(today()): if month_count: month_count += month_map.get(self.frequency, 0) next_date = get_next_date(self.start_date, month_count, day_count) else: days = self.get_days(next_date) next_date = add_days(next_date, days) return next_date
def validate_date(self): if self.date_of_birth and getdate(self.date_of_birth) > getdate( today()): throw(_("Date of Birth cannot be greater than today.")) if self.date_of_birth and self.date_of_joining and getdate( self.date_of_birth) >= getdate(self.date_of_joining): throw(_("Date of Joining must be greater than Date of Birth")) elif self.date_of_retirement and self.date_of_joining and (getdate( self.date_of_retirement) <= getdate(self.date_of_joining)): throw(_("Date Of Retirement must be greater than Date of Joining")) elif self.relieving_date and self.date_of_joining and (getdate( self.relieving_date) < getdate(self.date_of_joining)): throw( _("Relieving Date must be greater than or equal to Date of Joining" )) elif self.contract_end_date and self.date_of_joining and (getdate( self.contract_end_date) <= getdate(self.date_of_joining)): throw(_("Contract End Date must be greater than Date of Joining"))
def make_journal_voucher(self): doc = frappe.get_doc({ "doctype": "Journal Entry", "voucher_type": "Journal Entry", "posting_date": today(), "realestate_payment_entry": self.name }) if self.payment_type == "Pay": #from doc.append( "accounts", { "account": self.account_paid_from, "credit_in_account_currency": self.paid_amount }) #to doc.append( "accounts", { "account": self.account_paid_to, "party_type": "Shareholder", "party": self.shareholder, "debit_in_account_currency": self.paid_amount }) else: #to doc.append( "accounts", { "account": self.account_paid_to, "debit_in_account_currency": self.paid_amount }) #from doc.append( "accounts", { "account": self.account_paid_from, "party_type": "Shareholder", "party": self.shareholder, "credit_in_account_currency": self.paid_amount }) doc.insert() doc.submit()
def send_project_status_email_to_users(): yesterday = add_days(today(), -1) for d in frappe.get_all("Project Update", {'date': yesterday, 'sent': 0}): doc = frappe.get_doc("Project Update", d.name) project_doc = frappe.get_doc('Project', doc.project) args = { "users": doc.users, "title": _("Project Summary for {0}").format(yesterday) } frappe.sendmail(recipients=get_users_email(project_doc), template='daily_project_summary', args=args, subject=_("Daily Project Summary for {0}").format( d.name), reference_doctype="Project Update", reference_name=d.name) doc.db_set('sent', 1)
def save_purchase_order_item(sid, item_id, item_qty): #rate=frappe.db.get("Item",{"name":item_id}).standard_rate item_doc = frappe.get_doc({ "docstatus": 0, "doctype": "Purchase Order Item", "name": "New Purchase Order Item 1", "__islocal": 1, "__unsaved": 1, "owner": str(frappe.session.user), "parent": str(sid), "parentfield": "items", "parenttype": "Sales Order", "idx": 1, "qty": str(item_qty), "item_code": str(item_id), "rate": getItemRate(item_id), "update_stock": 0, "warehouse": "Sundine Kestrel- . - .", "delivery_date": str(today()) }) item_save = item_doc.insert()
def saveLandingCostPO(po): data = json.loads(po) count = 0 i = 0 for row1 in data["landing_cost_suppliers"]: data3 = frappe.get_doc({ "docstatus": 1, "status": "Draft", "doctype": "Purchase Invoice", "naming_series": "PINV-", "name": "New Purchase Invoice 1", "supplier": row1["supplier"], "posting_date": today(), "due_date": data["arrival_date"], "master_po_id": data["master_purchase_order"], "idx": 0, "items": row1["items"], "credit_to": "2100 - CAD Accounts Payable - ." }) d = data3.insert(ignore_permissions=True) count = count + 1
def update_password(new_password, logout_all_sessions=0, key=None, old_password=None): result = test_password_strength(new_password, key, old_password) feedback = result.get("feedback", None) if feedback and not feedback.get('password_policy_validation_passed', False): handle_password_test_fail(result) res = _get_user_for_update_password(key, old_password) if res.get('message'): frappe.local.response.http_status_code = 410 return res['message'] else: user = res['user'] _update_password(user, new_password, logout_all_sessions=int(logout_all_sessions)) user_doc, redirect_url = reset_user_data(user) # get redirect url from cache redirect_to = frappe.cache().hget('redirect_after_login', user) if redirect_to: redirect_url = redirect_to frappe.cache().hdel('redirect_after_login', user) frappe.local.login_manager.login_as(user) frappe.db.set_value("User", user, "last_password_reset_date", today()) frappe.db.set_value("User", user, "reset_password_key", "") if user_doc.user_type == "System User": return "/desk" else: return redirect_url if redirect_url else "/"