예제 #1
0
	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()
예제 #2
0
    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
예제 #3
0
	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()
예제 #4
0
    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()
예제 #5
0
 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])
예제 #6
0
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
예제 #7
0
 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
예제 #9
0
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
예제 #10
0
    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])
예제 #11
0
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
예제 #12
0
파일: test_user.py 프로젝트: yered1/frappe
    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())
예제 #13
0
    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
예제 #14
0
    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)
예제 #15
0
    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))
예제 #16
0
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))
예제 #17
0
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()
예제 #18
0
 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)
예제 #19
0
	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())
예제 #20
0
	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()
예제 #21
0
    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())
예제 #22
0
	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()
예제 #23
0
    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)
예제 #24
0
	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()
예제 #25
0
	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()
예제 #26
0
	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)
예제 #27
0
	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()
예제 #28
0
	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())
예제 #29
0
	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)
예제 #30
0
	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)
예제 #31
0
	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()
예제 #32
0
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)
예제 #33
0
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}
예제 #34
0
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()
예제 #35
0
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()
예제 #36
0
	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()