def test_subscription_remains_active_during_invoice_period(self): subscription = frappe.new_doc('Subscription') subscription.customer = '_Test Customer' subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) subscription.save() subscription.process() # no changes expected self.assertEqual(subscription.status, 'Active') self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) self.assertEqual(len(subscription.invoices), 0) subscription.process() # no changes expected still self.assertEqual(subscription.status, 'Active') self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) self.assertEqual(len(subscription.invoices), 0) subscription.process() # no changes expected yet still self.assertEqual(subscription.status, 'Active') self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) self.assertEqual(len(subscription.invoices), 0) subscription.delete()
def set_current_invoice_end(self): """ This sets the date of the end of the current billing period. If the subscription is in trial period, it will be set as the end of the trial period. If is not in a trial period, it will be `x` days from the beginning of the current billing period where `x` is the billing interval from the `Subscription Plan` in the `Subscription`. """ if self.is_trialling() and getdate( self.current_invoice_start) < getdate(self.trial_period_end): self.current_invoice_end = self.trial_period_end else: billing_cycle_info = self.get_billing_cycle_data() if billing_cycle_info: if self.is_new_subscription() and getdate( self.start_date) < getdate(self.current_invoice_start): self.current_invoice_end = add_to_date( self.start_date, **billing_cycle_info) # For cases where trial period is for an entire billing interval if getdate(self.current_invoice_end) < getdate( self.current_invoice_start): self.current_invoice_end = add_to_date( self.current_invoice_start, **billing_cycle_info) else: self.current_invoice_end = add_to_date( self.current_invoice_start, **billing_cycle_info) else: self.current_invoice_end = get_last_day( self.current_invoice_start) if self.follow_calendar_months: billing_info = self.get_billing_cycle_and_interval() billing_interval_count = billing_info[0][ 'billing_interval_count'] calendar_months = get_calendar_months(billing_interval_count) calendar_month = 0 current_invoice_end_month = getdate( self.current_invoice_end).month current_invoice_end_year = getdate( self.current_invoice_end).year for month in calendar_months: if month <= current_invoice_end_month: calendar_month = month if cint(calendar_month - billing_interval_count) <= 0 and \ getdate(self.current_invoice_start).month != 1: calendar_month = 12 current_invoice_end_year -= 1 self.current_invoice_end = get_last_day(cstr(current_invoice_end_year) + '-' \ + cstr(calendar_month) + '-01') if self.end_date and getdate(self.current_invoice_end) > getdate( self.end_date): self.current_invoice_end = self.end_date
def test_subscription_remains_active_during_invoice_period(self): subscription = frappe.new_doc("Subscription") subscription.party_type = "Customer" subscription.party = "_Test Customer" subscription.append("plans", {"plan": "_Test Plan Name", "qty": 1}) subscription.save() subscription.process() # no changes expected self.assertEqual(subscription.status, "Active") self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) self.assertEqual(len(subscription.invoices), 0) subscription.process() # no changes expected still self.assertEqual(subscription.status, "Active") self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) self.assertEqual(len(subscription.invoices), 0) subscription.process() # no changes expected yet still self.assertEqual(subscription.status, "Active") self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) self.assertEqual(len(subscription.invoices), 0) subscription.delete()
def test_subscription_remains_active_during_invoice_period(self): subscription = frappe.new_doc('Subscription') subscription.subscriber = '_Test Customer' subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) subscription.save() subscription.process() # no changes expected self.assertEqual(subscription.status, 'Active') self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) self.assertEqual(len(subscription.invoices), 0) subscription.process() # no changes expected still self.assertEqual(subscription.status, 'Active') self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) self.assertEqual(len(subscription.invoices), 0) subscription.process() # no changes expected yet still self.assertEqual(subscription.status, 'Active') self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) self.assertEqual(len(subscription.invoices), 0) subscription.delete()
def test_empty_month_in_between(self): today = getdate() movement = [ (100, add_to_date(today, months=0).replace(day=15)), (-50, add_to_date(today, months=1).replace(day=15)), # Skip a month (20, add_to_date(today, months=3).replace(day=15)), ] self.assert_single_item_report(movement, [100, 50, 50, 70])
def get_table_data(inpStartDate, house, from_price, to_price, from_size, to_size): calStartDate = getdate(inpStartDate) calcEndDate = add_to_date(calStartDate, days=60, as_string=True) #div style master_data = { 'headers': createHeaders(calStartDate, add_to_date(calStartDate, months=1)), 'rows': get_rows_for_div(calStartDate, house, from_price, to_price, from_size, to_size) } return master_data
def test_multi_month_missings(self): today = getdate() movement = [ (100, add_to_date(today, months=0).replace(day=15)), (-50, add_to_date(today, months=1).replace(day=15)), # Skip a month (20, add_to_date(today, months=3).replace(day=15)), # Skip another month (-10, add_to_date(today, months=5).replace(day=15)), ] self.assert_single_item_report(movement, [100, 50, 50, 70, 70, 60])
def _get_next_date(date, frequency): next_date = date if frequency == 'Monthly': next_date = add_to_date(next_date, months=1) elif frequency == 'Quarterly': next_date = add_to_date(next_date, months=4) elif frequency == 'Half-yearly': next_date = add_to_date(next_date, months=6) elif frequency == 'Yearly': next_date = add_to_date(next_date, years=1) return next_date
def _get_next_date(date, frequency): next_date = date if frequency == 'Daily': next_date = add_to_date(next_date, days=1) elif frequency == 'Weekly': next_date = add_to_date(next_date, days=7) elif frequency == 'Monthly': next_date = add_to_date(next_date, months=1) elif frequency == 'Yearly': next_date = add_to_date(next_date, years=1) return next_date
def test_basic_report_functionality(self): """Stock analytics report generates balance "as of" periods based on user defined ranges. Check that this behaviour is correct.""" # create stock movement in 3 months at 15th of month today = getdate() movement = [ (10, add_to_date(today, months=0).replace(day=15)), (-5, add_to_date(today, months=1).replace(day=15)), (10, add_to_date(today, months=2).replace(day=15)), ] self.assert_single_item_report(movement, [10, 5, 15])
def get_cleaning_table_data(inpStartDate, house, from_price, to_price, from_size, to_size): calStartDate = getdate(inpStartDate) calcEndDate = add_to_date(calStartDate, days=60, as_string=True) #div style raw_datas = get_cleaning_rows_for_div(calStartDate, house, from_price, to_price, from_size, to_size) master_data = { 'headers': createHeaders(calStartDate, add_to_date(calStartDate, months=1)), 'rows': raw_datas['rows'], 'default_cleanings': raw_datas['default_cleanings'] } return master_data
def test_site_expiry(self): user = frappe.get_doc('User', '*****@*****.**') user.enabled = 1 user.new_password = '******' user.save() update_limits({ 'expiry': add_to_date(today(), days=-1), 'support_email': '*****@*****.**' }) frappe.local.conf = _dict(frappe.get_site_config()) frappe.db.commit() res = requests.post(get_url(), params={ 'cmd': 'login', 'usr': '******', 'pwd': 'Eastern_43A1W', 'device': 'desktop' }) # While site is expired status code returned is 417 Failed Expectation self.assertEqual(res.status_code, 417) clear_limit("expiry") frappe.local.conf = _dict(frappe.get_site_config())
def get_current_documents(self, doctype): events = frappe.get_all("Subscription Event", filters={ "subscription": self.name, "document_type": doctype, "period_start": self.current_invoice_start, "period_end": self.current_invoice_end, "event_type": f"{doctype.capitalize()} created" }, fields=["document_name"]) if events: return [x.document_name for x in events] else: period_documents = [] transaction_date = "posting_date" if doctype == "Sales Invoice" else "transaction_date" billing_cycle_info = self.get_billing_cycle_data() documents = frappe.get_all(doctype, filters={"subscription": self.name}, \ fields=[transaction_date, "name", "docstatus"]) for document in documents: if billing_cycle_info: calculated_end = add_to_date( document.get(transaction_date), **billing_cycle_info) else: calculated_end = get_last_day( document.get(transaction_date)) if calculated_end >= getdate(self.current_invoice_end): period_documents.append(document) return period_documents
def test_corrective_costing(self): job_card = frappe.get_last_doc("Job Card", {"work_order": self.work_order.name}) job_card.append( "time_logs", { "from_time": now(), "to_time": add_to_date(now(), hours=1), "completed_qty": 2 }, ) job_card.submit() self.work_order.reload() original_cost = self.work_order.total_operating_cost # Create a corrective operation against it corrective_action = frappe.get_doc( doctype="Operation", is_corrective_operation=1, name=frappe.generate_hash()).insert() corrective_job_card = make_corrective_job_card( job_card.name, operation=corrective_action.name, for_operation=job_card.operation) corrective_job_card.hour_rate = 100 corrective_job_card.insert() corrective_job_card.append( "time_logs", { "from_time": add_to_date(now(), hours=2), "to_time": add_to_date(now(), hours=2, minutes=30), "completed_qty": 2, }, ) corrective_job_card.submit() self.work_order.reload() cost_after_correction = self.work_order.total_operating_cost self.assertGreater(cost_after_correction, original_cost) corrective_job_card.cancel() self.work_order.reload() cost_after_cancel = self.work_order.total_operating_cost self.assertEqual(cost_after_cancel, original_cost)
def validate_end_date(self): billing_cycle_info = self.get_billing_cycle_data() end_date = add_to_date(self.start_date, **billing_cycle_info) if self.end_date and getdate(self.end_date) <= getdate(end_date): frappe.throw( _("Subscription End Date must be after {0} as per the subscription plan" ).format(end_date))
def subscription_headline(name): subscription = frappe.get_doc('Subscription', name) billing_cycle_info = subscription.get_billing_cycle_data() if not subscription.has_invoice_for_period(): if subscription.generate_invoice_at_period_start: if subscription.is_trial(): next_invoice_date = add_days(subscription.trial_period_end, 1) else: next_invoice_date = subscription.current_invoice_start else: if subscription.is_trial(): if billing_cycle_info: next_invoice_date = add_to_date(add_days(subscription.trial_period_end, 1), \ **billing_cycle_info) else: next_invoice_date = get_last_day( add_days(subscription.trial_period_end, 1)) else: next_invoice_date = add_days(subscription.current_invoice_end, 1) else: if subscription.generate_invoice_at_period_start: next_invoice_date = add_days(subscription.current_invoice_end, 1) else: if billing_cycle_info: next_invoice_date = add_to_date(add_days(subscription.current_invoice_end, 1), \ **billing_cycle_info) else: next_invoice_date = get_last_day( add_days(subscription.current_invoice_end, 1)) if subscription.cancellation_date and getdate( subscription.cancellation_date) > getdate(nowdate()): return _("This subscription will be cancelled on {0}").format( global_date_format(subscription.cancellation_date)) elif subscription.cancellation_date and subscription.cancellation_date <= getdate( nowdate()): return _("This subscription has been cancelled on {0}").format( global_date_format(subscription.cancellation_date)) return _("The next invoice will be generated on {0}").format( global_date_format(next_invoice_date))
def destroy_scheduled_plants(): """Destroy expired Plants""" date = add_to_date(now(), days=-3) for name in frappe.get_list("Plant", [["disabled", "=", 0], ["destroy_scheduled", "=", 1], ["remove_time", "<", date]]): plant = frappe.get_doc("Plant", name) plant.disabled = 1 plant.remove_time = now() plant.flags.ignore_validate_update_after_submit = True plant.save()
def set_current_invoice_end(self): if self.trial_period_start and getdate( self.trial_period_end) > getdate(self.current_invoice_start): self.current_invoice_end = self.trial_period_end else: billing_cycle_info = self.get_billing_cycle_data() if billing_cycle_info: self.current_invoice_end = add_to_date( self.current_invoice_start, **billing_cycle_info) else: self.current_invoice_end = get_last_day( self.current_invoice_start)
def test_site_expiry(self): update_limits({'expiry': add_to_date(today(), days=-1)}) frappe.local.conf = _dict(frappe.get_site_config()) frappe.db.commit() res = requests.post(get_url(), params={'cmd': 'login', 'usr': '******', 'pwd': 'testpassword', 'device': 'desktop'}) # While site is expired status code returned is 417 Failed Expectation self.assertEqual(res.status_code, 417) clear_limit("expiry") frappe.local.conf = _dict(frappe.get_site_config())
def test_create_subscription_without_trial_with_correct_period(self): subscription = frappe.new_doc('Subscription') subscription.customer = '_Test Customer' subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) subscription.save() self.assertEqual(subscription.trial_period_start, None) self.assertEqual(subscription.trial_period_end, None) self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) # No invoice is created self.assertEqual(len(subscription.invoices), 0) self.assertEqual(subscription.status, 'Active') subscription.delete()
def test_site_expiry(self): update_limits({"expiry": add_to_date(today(), days=-1)}) frappe.local.conf = _dict(frappe.get_site_config()) frappe.db.commit() res = requests.post( get_url(), params={"cmd": "login", "usr": "******", "pwd": "testpassword", "device": "desktop"} ) # While site is expired status code returned is 417 Failed Expectation self.assertEqual(res.status_code, 417) clear_limit("expiry") frappe.local.conf = _dict(frappe.get_site_config())
def test_create_subscription_without_trial_with_correct_period(self): subscription = frappe.new_doc('Subscription') subscription.customer = '_Test Customer' subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) subscription.save() self.assertEqual(subscription.trial_period_start, None) self.assertEqual(subscription.trial_period_end, None) self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) # No invoice is created self.assertEqual(len(subscription.invoices), 0) self.assertEqual(subscription.status, 'Active') subscription.delete()
def test_rename_doc(self): from random import choice, sample available_documents = [] doctype = "ToDo" # data generation: 4 todo documents for num in range(1, 5): doc = frappe.get_doc({ "doctype": doctype, "date": add_to_date(now(), days=num), "description": "this is todo #{}".format(num) }).insert() available_documents.append(doc.name) # test 1: document renaming old_name = choice(available_documents) new_name = old_name + '.new' self.assertEqual( new_name, frappe.rename_doc(doctype, old_name, new_name, force=True)) available_documents.remove(old_name) available_documents.append(new_name) # test 2: merge documents first_todo, second_todo = sample(available_documents, 2) second_todo_doc = frappe.get_doc(doctype, second_todo) second_todo_doc.priority = "High" second_todo_doc.save() merged_todo = frappe.rename_doc(doctype, first_todo, second_todo, merge=True, force=True) merged_todo_doc = frappe.get_doc(doctype, merged_todo) available_documents.remove(first_todo) with self.assertRaises(frappe.DoesNotExistError): frappe.get_doc(doctype, first_todo) self.assertEqual(merged_todo_doc.priority, second_todo_doc.priority) for docname in available_documents: frappe.delete_doc(doctype, docname)
def test_create_subscription_without_trial_with_correct_period(self): subscription = frappe.new_doc("Subscription") subscription.party_type = "Customer" subscription.party = "_Test Customer" subscription.append("plans", {"plan": "_Test Plan Name", "qty": 1}) subscription.save() self.assertEqual(subscription.trial_period_start, None) self.assertEqual(subscription.trial_period_end, None) self.assertEqual(subscription.current_invoice_start, nowdate()) self.assertEqual(subscription.current_invoice_end, add_to_date(nowdate(), months=1, days=-1)) # No invoice is created self.assertEqual(len(subscription.invoices), 0) self.assertEqual(subscription.status, "Active") subscription.delete()
def test_invoice_is_generated_at_end_of_billing_period(self): start_date = add_to_date(nowdate(), months=-1) subscription = frappe.new_doc('Subscription') subscription.customer = '_Test Customer' subscription.start = start_date subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) subscription.insert() self.assertEqual(subscription.status, 'Active') self.assertEqual(subscription.current_invoice_start, start_date) self.assertEqual(subscription.current_invoice_end, add_days(nowdate(), -1)) subscription.process() self.assertEqual(len(subscription.invoices), 1) self.assertEqual(subscription.status, 'Past Due Date') subscription.delete()
def fetch_auth_token(self): headers = { 'gspappid': frappe.conf.einvoice_client_id, 'gspappsecret': frappe.conf.einvoice_client_secret } res = {} try: res = self.make_request('post', self.authenticate_url, headers) self.e_invoice_settings.auth_token = "{} {}".format(res.get('token_type'), res.get('access_token')) self.e_invoice_settings.token_expiry = add_to_date(None, seconds=res.get('expires_in')) self.e_invoice_settings.save(ignore_permissions=True) self.e_invoice_settings.reload() except Exception: self.log_error(res) self.raise_error(True)
def test_create_subscription_with_trial_with_correct_period(self): subscription = frappe.new_doc('Subscription') subscription.party_type = 'Customer' subscription.party = '_Test Customer' subscription.trial_period_start = nowdate() subscription.trial_period_end = add_months(nowdate(), 1) subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) subscription.save() self.assertEqual(subscription.trial_period_start, nowdate()) self.assertEqual(subscription.trial_period_end, add_months(nowdate(), 1)) self.assertEqual(add_days(subscription.trial_period_end, 1), get_date_str(subscription.current_invoice_start)) self.assertEqual(add_to_date(subscription.current_invoice_start, months=1, days=-1), get_date_str(subscription.current_invoice_end)) self.assertEqual(subscription.invoices, []) self.assertEqual(subscription.status, 'Trialling') subscription.delete()
def test_site_expiry(self): user = frappe.get_doc('User', '*****@*****.**') user.enabled = 1 user.new_password = '******' user.save() update_limits({'expiry': add_to_date(today(), days=-1), 'support_email': '*****@*****.**'}) frappe.local.conf = _dict(frappe.get_site_config()) frappe.db.commit() res = requests.post(get_url(), params={'cmd': 'login', 'usr': '******', 'pwd': 'Eastern_43A1W', 'device': 'desktop'}) # While site is expired status code returned is 417 Failed Expectation self.assertEqual(res.status_code, 417) clear_limit("expiry") frappe.local.conf = _dict(frappe.get_site_config())
def set_current_invoice_end(self): """ This sets the date of the end of the current billing period. If the subscription is in trial period, it will be set as the end of the trial period. If is not in a trial period, it will be `x` days from the beginning of the current billing period where `x` is the billing interval from the `Subscription Plan` in the `Subscription`. """ if self.is_trialling(): self.current_invoice_end = self.trial_period_end else: billing_cycle_info = self.get_billing_cycle_data() if billing_cycle_info: self.current_invoice_end = add_to_date(self.current_invoice_start, **billing_cycle_info) else: self.current_invoice_end = get_last_day(self.current_invoice_start)
def set_current_invoice_end(self): """ This sets the date of the end of the current billing period. If the subscription is in trial period, it will be set as the end of the trial period. If is not in a trial period, it will be `x` days from the beginning of the current billing period where `x` is the billing interval from the `Subscription Plan` in the `Subscription`. """ if self.is_trialling(): self.current_invoice_end = self.trial_period_end else: billing_cycle_info = self.get_billing_cycle_data() if billing_cycle_info: self.current_invoice_end = add_to_date(self.current_invoice_start, **billing_cycle_info) else: self.current_invoice_end = get_last_day(self.current_invoice_start)
def test_create_subscription_with_trial_with_correct_period(self): subscription = frappe.new_doc("Subscription") subscription.party_type = "Customer" subscription.party = "_Test Customer" subscription.trial_period_start = nowdate() subscription.trial_period_end = add_months(nowdate(), 1) subscription.append("plans", {"plan": "_Test Plan Name", "qty": 1}) subscription.save() self.assertEqual(subscription.trial_period_start, nowdate()) self.assertEqual(subscription.trial_period_end, add_months(nowdate(), 1)) self.assertEqual( add_days(subscription.trial_period_end, 1), get_date_str(subscription.current_invoice_start) ) self.assertEqual( add_to_date(subscription.current_invoice_start, months=1, days=-1), get_date_str(subscription.current_invoice_end), ) self.assertEqual(subscription.invoices, []) self.assertEqual(subscription.status, "Trialling") subscription.delete()
def update_timesheet(ts, time, doctype, reference, user, bemerkung, date=None): #********************************************************** #overwrite the time_log overlap validation of timesheet overwrite_ts_validation() #********************************************************** # check if first timesheet entry of reference existing_ts = frappe.db.sql( """SELECT `name` FROM `tabTimesheet` WHERE `docstatus` != 2 AND `name` IN ( SELECT `parent` FROM `tabTimesheet Detail` WHERE `spo_referenz` = '{reference}')""" .format(reference=reference), as_dict=True) if not len(existing_ts) > 0: default_time = get_default_time(doctype) if time < default_time: time = default_time ts = frappe.get_doc("Timesheet", ts) type = 'Mandatsarbeit' if doctype == 'Anfrage': type = 'Beratung' if not date: start = nowdate() + " 00:00:00" else: start = date + " 00:00:00" row = {} row["activity_type"] = type row["hours"] = time row["from_time"] = get_datetime(get_datetime_str(start)) row["to_time"] = add_to_date(get_datetime(get_datetime_str(start)), hours=time) row["spo_dokument"] = doctype row["spo_referenz"] = reference row['spo_remark'] = bemerkung ts.append('time_logs', row) ts.save(ignore_permissions=True)
def get_cleaning_rows_for_div(calStartDate, house, from_price, to_price, from_size, to_size): rows = [] default_cleanings = {} from_price = int(from_price) to_price = int(to_price) from_size = from_size to_size = to_size if house != 'All': house_filter = " AND `name` = '{house}'".format(house=house) else: house_filter = '' #houses = alle haeuser houses = frappe.db.sql("""SELECT `name` FROM `tabHouse` WHERE `disabled` = 0{house_filter} ORDER BY `name` ASC""".format(house_filter=house_filter), as_list=True) for _house in houses: house = _house[0] row_string = '<div class="planner-zeile">' # hinzufuegen zeile: haus apartment_qty = int(frappe.db.sql("""SELECT COUNT(`name`) FROM `tabAppartment` WHERE `house` = '{0}' AND `disabled` = 0 AND `price_per_month` >= {1} AND `price_per_month` <= {2} AND `apartment_size` >= '{3}' AND `apartment_size` <= '{4}' ORDER BY `name` ASC""".format(house, from_price, to_price, from_size, to_size), as_list=True)[0][0]) row_string += '<div class="house a{0}"><span>{1}</span></div>'.format(apartment_qty, house) #hinzufuegen appartments inkl. infos apartments = frappe.db.sql("""SELECT `name`, `apartment_size`, `position`, `price_per_month`, `service_price_per_month`, `price_per_day`, `service_price_per_day`, `remarks`, `cleaning_day`, `special_apartment`, `special_color` FROM `tabAppartment` WHERE `house` = '{0}' AND `disabled` = 0 AND `price_per_month` >= {1} AND `price_per_month` <= {2} AND `apartment_size` >= '{3}' AND `apartment_size` <= '{4}' ORDER BY `name` ASC""".format(house, from_price, to_price, from_size, to_size), as_list=True) apartment_int = 1 for _apartment in apartments: booking_time_ref = [] er_ref = [] apartment = _apartment[0] apartment_size = _apartment[1] position = _apartment[2] price_per_month = int(_apartment[3]) service_price_per_month = int(_apartment[4]) price_per_day = _apartment[5] service_price_per_day = _apartment[6] remarks = _apartment[7] cleaning_day = _apartment[8] special_apartment = _apartment[9] special_color = _apartment[10] if str(special_apartment) == '1': apartment_color_style = ' style="background-color: {special_color} !important;"'.format(special_color=str(special_color)) else: apartment_color_style = '' # sum_per_month = float(price_per_month) + float(service_price_per_month) # sum_per_day = float(price_per_day) + float(service_price_per_day) row_string += '<div class="apartment pos-{0}"{3} onclick="open_apartment({2})"><span>{1}</span></div>'.format(apartment_int, apartment, "'" + apartment + "'", apartment_color_style) row_string += '<div class="room pos-{0}"><span>{1}</span></div>'.format(apartment_int, apartment_size) row_string += '<div class="position pos-{0}"><span>{1}</span></div>'.format(apartment_int, position) row_string += '<div class="pricePM pos-{0}"><span>{1}</span></div>'.format(apartment_int, price_per_month) row_string += '<div class="pricePD pos-{0}"><span>{1}</span></div>'.format(apartment_int, service_price_per_month) #row_string += '<div class="newBookingPlaceHolder a1 s1 d61 z0 pos-{0}" onclick="new_cleaning_booking({1})"></div>'.format(apartment_int, "'" + apartment + "'") for_loop_count = 1 while for_loop_count < 62: row_string += '<div class="newBookingPlaceHolder a1 s{2} d1 pos-{0}" style="z-index: 1;" onclick="new_cleaning_booking({1}, {2})"></div>'.format(apartment_int, "'" + apartment + "'", for_loop_count) for_loop_count += 1 #hinzufuegen buchungen pro appartment bookings = frappe.db.sql("""SELECT `name`, `start_date`, `end_date`, `booking_status`, `is_checked`, `customer` FROM `tabBooking` WHERE `appartment` = '{0}' AND `end_date` >= '{1}' AND `start_date` <= '{2}' AND (`booking_status` = 'End-Cleaning' OR `booking_status` = 'Sub-Cleaning' OR `booking_status` = 'Service-Cleaning' OR `booking_status` = 'Booked' OR `booking_status` = 'Control-Cleaning')""".format(apartment, calStartDate, add_days(calStartDate, 61)), as_list=True) for _booking in bookings: z_index = 3 booking = _booking[0] start = _booking[1] end = _booking[2] bookingType = _booking[3] is_checked = _booking[4] datediff = date_diff(start, calStartDate) on_click_detail = ' onclick="show_cleaning_booking({0})"'.format("'" + booking + "'") cursor_style = '' if datediff <= 0: s_start = 1 dauer = date_diff(end, calStartDate) + 1 else: s_start = datediff + 1 dauer = date_diff(end, start) + 1 if bookingType == 'End-Cleaning': bookingType = "End-R" er_ref.append(s_start) #check if checked if is_checked == 1: color = 'b-green' elif is_checked == 0: color = 'b-red' else: color = 'b-orange' elif bookingType == 'Sub-Cleaning': bookingType = "Sub-R" color = 'b-red' elif bookingType == 'Service-Cleaning': bookingType = "Service" color = 'b-darkgrey' elif bookingType == 'Control-Cleaning': bookingType = "Control" color = 'b-darkgrey' elif bookingType == 'Booked': color = 'b-lightblue' z_index = 0 booking_time_ref.append([s_start, (s_start + dauer - 1),_booking[5]]) on_click_detail = '' cursor_style = ' cursor: default !important;' else: color = 'b-darkgrey' if dauer > 61: dauer = 61 if s_start > 61: s_start = 99 row_string += '<div class="clean-buchung pos-{0} s{1} d{2} z{4} {3}" style="height: 36px !important; margin-top: 0px !important;{8}"{7}>{6}</div>'.format(apartment_int, s_start, dauer, color, z_index, "'" + booking + "'", _(bookingType), on_click_detail, cursor_style) all_days = createCleaningHeaders(calStartDate, add_to_date(calStartDate, months=1)) s_start = 1 for days in all_days["headers"]: if days["weekday"] == cleaning_day: for bookong_ref in booking_time_ref: if s_start >= bookong_ref[0] and s_start <= bookong_ref[1]: row_string += '<div class="clean-buchung pos-{0} s{1} d{2} {3}" style="z-index: 2;" onclick="new_cleaning_booking({5})">Default</div>'.format(apartment_int, s_start, 1, 'b-darkgrey', 0, "'" + apartment + "', '" + str(s_start) + "'") if s_start not in er_ref: if str(s_start) in default_cleanings: default_cleanings[str(s_start)].append([apartment, bookong_ref[2]]) else: default_cleanings[str(s_start)] = [] default_cleanings[str(s_start)].append([apartment, bookong_ref[2]]) s_start += 1 apartment_int += 1 row_string += '</div>' rows.append(row_string) return {'rows': rows, 'default_cleanings': default_cleanings}
def create_ts_entry(user, doctype, record, datum, time, bemerkung='', nicht_verrechnen=0): #********************************************************** #overwrite the time_log overlap validation of timesheet overwrite_ts_validation() #********************************************************** time = float(time) datum = getdate(datum) latest_date = getdate(add_days(nowdate(), -7)) if datum < latest_date: frappe.throw( "Die Erfassung der standardzeit in Ihrem Timesheet konnte nicht erfasst werden, da das Datum weiter zurück als 7 Tage liegt." ) user = frappe.db.sql( """SELECT `name` FROM `tabEmployee` WHERE `user_id` = '{user}'""". format(user=user), as_list=True) if not user: frappe.throw("Es wurde kein Mitarbeiterstamm gefunden!") else: user = user[0][0] #time = get_default_time(doctype) ts = frappe.db.sql( """SELECT `name` FROM `tabTimesheet` WHERE `docstatus` = 1 AND `employee` = '{user}' AND `start_date` = '{nowdate}'""" .format(user=user, nowdate=datum.strftime("%Y-%m-%d")), as_dict=True) if len(ts) > 0: frappe.throw("Das Timesheet vom {datum} ist bereits verbucht.".format( datum=datum)) else: ts = frappe.db.sql( """SELECT `name` FROM `tabTimesheet` WHERE `docstatus` = 0 AND `employee` = '{user}' AND `start_date` = '{nowdate}'""" .format(user=user, nowdate=datum.strftime("%Y-%m-%d")), as_dict=True) if len(ts) > 0: ts = frappe.get_doc("Timesheet", ts[0].name) type = 'Mandatsarbeit' if doctype == 'Anfrage': type = 'Beratung' start = datum.strftime("%Y-%m-%d") + " 00:00:00" row = {} row["activity_type"] = type row["hours"] = time row["from_time"] = get_datetime(get_datetime_str(start)) row["to_time"] = add_to_date(get_datetime(get_datetime_str(start)), hours=time) row["spo_dokument"] = doctype row["spo_referenz"] = record row['spo_remark'] = bemerkung row['nicht_verrechnen'] = nicht_verrechnen ts.append('time_logs', row) ts.save(ignore_permissions=True) else: start = datum.strftime("%Y-%m-%d") + " 00:00:00" type = 'Mandatsarbeit' if doctype == 'Anfrage': type = 'Beratung' ts = frappe.get_doc({ "doctype": "Timesheet", "employee": user, "time_logs": [{ "activity_type": type, "hours": time, "spo_dokument": doctype, "spo_referenz": record, "from_time": get_datetime(get_datetime_str(start)), "spo_remark": bemerkung, "nicht_verrechnen": nicht_verrechnen }] }) ts.insert(ignore_permissions=True) frappe.db.commit()
def create_qr_code(doc, method=None): region = get_region(doc.company) if region not in ["Saudi Arabia"]: return # if QR Code field not present, create it. Invoices without QR are invalid as per law. if not hasattr(doc, "ksa_einv_qr"): create_custom_fields({ doc.doctype: [ dict( fieldname="ksa_einv_qr", label="KSA E-Invoicing QR", fieldtype="Attach Image", read_only=1, no_copy=1, hidden=1, ) ] }) # Don't create QR Code if it already exists qr_code = doc.get("ksa_einv_qr") if qr_code and frappe.db.exists({"doctype": "File", "file_url": qr_code}): return meta = frappe.get_meta(doc.doctype) if "ksa_einv_qr" in [d.fieldname for d in meta.get_image_fields()]: """TLV conversion for 1. Seller's Name 2. VAT Number 3. Time Stamp 4. Invoice Amount 5. VAT Amount """ tlv_array = [] # Sellers Name seller_name = frappe.db.get_value("Company", doc.company, "company_name_in_arabic") if not seller_name: frappe.throw( _("Arabic name missing for {} in the company document").format( doc.company)) tag = bytes([1]).hex() length = bytes([len(seller_name.encode("utf-8"))]).hex() value = seller_name.encode("utf-8").hex() tlv_array.append("".join([tag, length, value])) # VAT Number tax_id = frappe.db.get_value("Company", doc.company, "tax_id") if not tax_id: frappe.throw( _("Tax ID missing for {} in the company document").format( doc.company)) tag = bytes([2]).hex() length = bytes([len(tax_id)]).hex() value = tax_id.encode("utf-8").hex() tlv_array.append("".join([tag, length, value])) # Time Stamp posting_date = getdate(doc.posting_date) time = get_time(doc.posting_time) seconds = time.hour * 60 * 60 + time.minute * 60 + time.second time_stamp = add_to_date(posting_date, seconds=seconds) time_stamp = time_stamp.strftime("%Y-%m-%dT%H:%M:%SZ") tag = bytes([3]).hex() length = bytes([len(time_stamp)]).hex() value = time_stamp.encode("utf-8").hex() tlv_array.append("".join([tag, length, value])) # Invoice Amount invoice_amount = str(doc.grand_total) tag = bytes([4]).hex() length = bytes([len(invoice_amount)]).hex() value = invoice_amount.encode("utf-8").hex() tlv_array.append("".join([tag, length, value])) # VAT Amount vat_amount = str(get_vat_amount(doc)) tag = bytes([5]).hex() length = bytes([len(vat_amount)]).hex() value = vat_amount.encode("utf-8").hex() tlv_array.append("".join([tag, length, value])) # Joining bytes into one tlv_buff = "".join(tlv_array) # base64 conversion for QR Code base64_string = b64encode(bytes.fromhex(tlv_buff)).decode() qr_image = io.BytesIO() url = qr_create(base64_string, error="L") url.png(qr_image, scale=2, quiet_zone=1) name = frappe.generate_hash(doc.name, 5) # making file filename = f"QRCode-{name}.png".replace(os.path.sep, "__") _file = frappe.get_doc({ "doctype": "File", "file_name": filename, "is_private": 0, "content": qr_image.getvalue(), "attached_to_doctype": doc.get("doctype"), "attached_to_name": doc.get("name"), "attached_to_field": "ksa_einv_qr", }) _file.save() # assigning to document doc.db_set("ksa_einv_qr", _file.file_url) doc.notify_update()
def test_update_schedule_date(self): doc = make_course_schedule_test_record(schedule_date=add_to_date(today(), days=1)) doc.schedule_date = add_to_date(doc.schedule_date, days=1) doc.save()