def postproc(source, target): interest_income_account, interest_receivable_account, loan_account = frappe.get_value( 'Loan Settings', None, [ 'interest_income_account', 'interest_receivable_account', 'loan_account' ]) target.update({ 'loan_no': loan_no, 'posting_date': today(), 'loan_principal': source.amount, 'loan_account': loan_account, 'interest_income_account': interest_income_account, 'interest_receivable_account': interest_receivable_account, }) recovery_frequency, day, billing_day = frappe.get_value( 'Loan Plan', loan_application.loan_plan, ['recovery_frequency', 'day', 'billing_day']) billing_date = getdate( target.posting_date).replace(day=billing_day) if date_diff(billing_date, target.posting_date) < 0: if recovery_frequency == 'Weekly': add_days(billing_date, 7) elif recovery_frequency == 'Monthly': add_months(billing_date, 1) target.update({'billing_date': billing_date})
def get_quarter_start_end(fiscal_year, quarter): from frappe.utils.data import add_months, get_last_day fiscal_start_date = frappe.db.get_value('Fiscal Year', fiscal_year, 'year_start_date') if quarter == 'I': offset = 0 elif quarter == 'II': offset = 1 elif quarter == 'III': offset = 2 elif quarter == 'IV': offset = 3 start_d = add_months(fiscal_start_date, offset * 3) end_d = get_last_day(add_months(fiscal_start_date, (offset * 3) + 2)) return start_d, end_d.strftime('%Y-%m-%d')
def test_status_goes_back_to_active_after_invoice_is_paid(self): subscription = frappe.new_doc("Subscription") subscription.party_type = "Customer" subscription.party = "_Test Customer" subscription.append("plans", {"plan": "_Test Plan Name", "qty": 1}) subscription.start_date = "2018-01-01" subscription.insert() subscription.process() # generate first invoice self.assertEqual(len(subscription.invoices), 1) # Status is unpaid as Days until Due is zero and grace period is Zero self.assertEqual(subscription.status, "Unpaid") subscription.get_current_invoice() current_invoice = subscription.get_current_invoice() self.assertIsNotNone(current_invoice) current_invoice.db_set("outstanding_amount", 0) current_invoice.db_set("status", "Paid") subscription.process() self.assertEqual(subscription.status, "Active") self.assertEqual(subscription.current_invoice_start, add_months(subscription.start_date, 1)) self.assertEqual(len(subscription.invoices), 1) subscription.delete()
def test_status_goes_back_to_active_after_invoice_is_paid(self): subscription = frappe.new_doc('Subscription') subscription.party_type = 'Customer' subscription.party = '_Test Customer' subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) subscription.start_date = '2018-01-01' subscription.insert() subscription.process() # generate first invoice self.assertEqual(len(subscription.invoices), 1) # Status is unpaid as Days until Due is zero and grace period is Zero self.assertEqual(subscription.status, 'Unpaid') subscription.get_current_invoice() current_invoice = subscription.get_current_invoice() self.assertIsNotNone(current_invoice) current_invoice.db_set('outstanding_amount', 0) current_invoice.db_set('status', 'Paid') subscription.process() self.assertEqual(subscription.status, 'Active') self.assertEqual(subscription.current_invoice_start, add_months(subscription.start_date, 1)) self.assertEqual(len(subscription.invoices), 1) subscription.delete()
def test_status_goes_back_to_active_after_invoice_is_paid(self): subscription = frappe.new_doc('Subscription') subscription.subscriber = '_Test Customer' subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) subscription.start = '2018-01-01' subscription.insert() subscription.process() # generate first invoice self.assertEqual(len(subscription.invoices), 1) self.assertEqual(subscription.status, 'Past Due Date') subscription.get_current_invoice() current_invoice = subscription.get_current_invoice() self.assertIsNotNone(current_invoice) current_invoice.db_set('outstanding_amount', 0) current_invoice.db_set('status', 'Paid') subscription.process() self.assertEqual(subscription.status, 'Active') self.assertEqual(subscription.current_invoice_start, add_months(subscription.start, 1)) self.assertEqual(len(subscription.invoices), 1) subscription.delete()
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 get_interval(day_of_month, date_obj): '''Returns start and end date of the interval''' if not isinstance(date_obj, date): date_obj = getdate(date_obj) try: start_date = date_obj.replace(day=day_of_month) except ValueError: start_date = add_months(date_obj, -1).replace(day=day_of_month) if date_diff(date_obj, start_date) < 0: start_date = add_months(start_date, -1) try: end_date = date_obj.replace(day=day_of_month) except ValueError: end_date = get_last_day(date_obj) if date_diff(end_date, date_obj) <= 0: end_date = add_months(end_date, 1) end_date = add_days(end_date, -1) as_text = '{} - {}'.format(start_date, end_date) return start_date, end_date, as_text
def test_subscription_invoice_days_until_due(self): subscription = frappe.new_doc('Subscription') subscription.subscriber = '_Test Customer' subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) subscription.days_until_due = 10 subscription.start = add_months(nowdate(), -1) subscription.insert() subscription.process() # generate first invoice self.assertEqual(len(subscription.invoices), 1) self.assertEqual(subscription.status, 'Active') subscription.delete()
def test_subscription_invoice_days_until_due(self): subscription = frappe.new_doc('Subscription') subscription.customer = '_Test Customer' subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) subscription.days_until_due = 10 subscription.start = add_months(nowdate(), -1) subscription.insert() subscription.process() # generate first invoice self.assertEqual(len(subscription.invoices), 1) self.assertEqual(subscription.status, 'Active') subscription.delete()
def get_periods(day_of_month, date_obj, no_of_periods=5): intervals = [] limit_start = -((cint(no_of_periods) + 1) / 2) limit_end = cint(no_of_periods) / 2 for x in range(limit_start, limit_end): start_date, end_date, as_text = get_interval(day_of_month, add_months(date_obj, x)) intervals.append({ 'start_date': start_date, 'end_date': end_date, 'as_text': as_text, }) return intervals
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_subscription_invoice_days_until_due(self): subscription = frappe.new_doc("Subscription") subscription.party_type = "Customer" subscription.party = "_Test Customer" subscription.append("plans", {"plan": "_Test Plan Name", "qty": 1}) subscription.days_until_due = 10 subscription.start_date = add_months(nowdate(), -1) subscription.insert() subscription.process() # generate first invoice self.assertEqual(len(subscription.invoices), 1) self.assertEqual(subscription.status, "Active") subscription.delete()
def validate(self): if not self.last_calibration: self.last_calibration = nowdate() self.next_calibration = add_months(getdate(self.last_calibration), self.calibration_interval) if self.status == 'Calibrated': if getdate(self.next_calibration) < getdate(nowdate()): self.status = 'To Calibrate' if self.status == 'To Calibrate': if getdate(self.next_calibration) >= getdate(nowdate()): self.status = 'Calibrated'
def get_periods(period_date, no_of_periods=3): if not isinstance(period_date, date): period_date = getdate(period_date) periods = [] for x in range(-no_of_periods + 1, 1): pd = add_months(period_date, x) periods.append( frappe._dict({ 'start_date': get_first_day(pd), 'end_date': get_last_day(pd), 'label': pd.strftime("%b %Y"), 'key': pd.strftime("%b_%Y").lower(), })) return periods
def _get_datasets(filters): def make_month_si(data): posting_date = data.pop('posting_date') data['month'] = posting_date.strftime('%b') data['paid_amount'] = data['grand_total'] - data['outstanding_amount'] return data sales_invoices = frappe.db.sql( """ SELECT grand_total, outstanding_amount, posting_date FROM `tabSales Invoice` WHERE docstatus = 1 AND posting_date BETWEEN %(from_date)s AND %(to_date)s {clauses} """.format(clauses=_get_clauses(filters) or ''), { **filters, 'from_date': add_months(nowdate(), -_month_range), 'to_date': nowdate() }, as_dict=1) data = list(map(make_month_si, sales_invoices)) grand_total = _get_total_by_month('grand_total', data) paid_total = _get_total_by_month('paid_amount', data) unpaid_total = _get_total_by_month('outstanding_amount', data) return [{ 'name': 'Total Billed Rent', 'values': _get_values(grand_total) }, { 'name': 'Total Paid', 'values': _get_values(paid_total) }, { 'name': 'Total Unpaid', 'values': _get_values(unpaid_total) }]
def test_status_goes_back_to_active_after_invoice_is_paid(self): subscription = frappe.new_doc('Subscription') subscription.customer = '_Test Customer' subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) subscription.start = '2018-01-01' subscription.insert() subscription.process() # generate first invoice self.assertEqual(len(subscription.invoices), 1) self.assertEqual(subscription.status, 'Past Due Date') subscription.get_current_invoice() current_invoice = subscription.get_current_invoice() self.assertIsNotNone(current_invoice) current_invoice.db_set('outstanding_amount', 0) current_invoice.db_set('status', 'Paid') subscription.process() self.assertEqual(subscription.status, 'Active') self.assertEqual(subscription.current_invoice_start, add_months(subscription.start, 1)) self.assertEqual(len(subscription.invoices), 1) subscription.delete()
def make_data(x): current_date = add_months(today, -x) return current_date.strftime('%b')
def create_sales_order(apartment, customer, booking, start_date, end_date, guest='', invoice_partner=''): order = frappe.new_doc("Sales Order") delivery_date = start_date if guest == 'none' or guest == '': guest = 'Please add Guest' if invoice_partner == 'none' or invoice_partner == '': order.update({ "apartment": apartment.name, "customer": customer, "booking": booking.name, "guest": guest }) else: vertrags_adresse = frappe.db.sql("""SELECT `name` FROM `tabAddress` WHERE `is_shipping_address` = 1 AND `name` IN (SELECT `parent` FROM `tabDynamic Link` WHERE `parenttype` = 'Address' AND `link_name` = '{link_name}') LIMIT 1""".format(link_name=customer), as_list=True) if vertrags_adresse: vertrags_adresse = vertrags_adresse[0][0] else: vertrags_adresse = '' order.update({ "apartment": apartment.name, "customer": invoice_partner, "contractual_partner": customer, "contractual_partner_address": vertrags_adresse, "booking": booking.name, "guest": guest }) mietdauer = date_diff(end_date, start_date) + 1 #throw(str(apartment.name)) #_apartment = frappe.get_doc("Apartment", apartment.name) # Miete von Parkplatz --> if apartment.parking == 1: anz_monate = 1 items = [] items.append( { "item_code": "Miete mt 7.7%", "qty": "1", "rate": apartment.price_per_month, "delivery_date": delivery_date } ) while add_months(end_date, 0) > add_months(start_date, anz_monate): anz_monate += 1 items.append( { "item_code": "Miete mt 7.7%", "qty": "1", "rate": apartment.price_per_month, "delivery_date": add_months(delivery_date, (anz_monate - 1)) } ) #throw(str(anz_monate)) if anz_monate < 4: taxes = 'Kleiner Gleich 3 Monate - AAS' else: taxes = 'Grösser 3 Monate - AAS' order.update({ "items": items, "taxes_and_charges": taxes, "change_depot": 1, "remove_depot": 1, "change_service": 1, "remove_service": 1, "change_end_cleaning": 1, "remove_end_cleaning": 1 }) else: # Miete von Appartments --> # reine tagesmiete if mietdauer <= 19: taxes = 'Kleiner Gleich 3 Monate - AAS' miet_qty = mietdauer mietpreis = apartment.price_per_day mietservice = apartment.service_price_per_day order.update({ "items": [ { "item_code": "Depot", "qty": "1", "rate": apartment.price_per_month + apartment.service_price_per_month, "delivery_date": delivery_date }, { "item_code": "Miete 3.7 Tag", "qty": miet_qty, "rate": mietpreis, "delivery_date": delivery_date }, { "item_code": "Service 3.7 Tag", "qty": miet_qty, "rate": mietservice, "delivery_date": delivery_date }, { "item_code": "Endreinigung", "qty": "1", "rate": apartment.price_end_cleaning, "delivery_date": delivery_date } ], "taxes_and_charges": taxes }) else: items = [] items.append( { "item_code": "Depot", "qty": "1", "rate": apartment.price_per_month + apartment.service_price_per_month, "delivery_date": delivery_date } ) items.append( { "item_code": "Endreinigung", "qty": "1", "rate": apartment.price_end_cleaning, "delivery_date": delivery_date } ) #definition ob dauer >= 3Monate oder < 3Monate if end_date <= add_months(start_date, 3): monats_miete = 'Miete 3.7 Mt' monats_service = 'Service 3.7 Mt' tages_miete = 'Miete 3.7 Tag' tages_service = 'Service 3.7 Tag' taxes = 'Kleiner Gleich 3 Monate - AAS' else: monats_miete = 'Miete mt' monats_service = 'Service 7.7 Mt' tages_miete = 'Miete Tag' tages_service = 'Service 7.7 Tag' taxes = 'Grösser 3 Monate - AAS' start_monat = start_date folgemonat = add_months(start_date, 1) while getdate(str(end_date)) >= getdate(str(folgemonat)): items.append( { "item_code": monats_miete, "qty": "1", "rate": apartment.price_per_month, "delivery_date": str(start_monat) } ) items.append( { "item_code": monats_service, "qty": "1", "rate": apartment.service_price_per_month, "delivery_date": str(start_monat) } ) start_monat = folgemonat folgemonat = add_months(start_monat, 1) rest_tage = date_diff(end_date, start_monat) if rest_tage > 0 and rest_tage < 20: items.append( { "item_code": tages_miete, "qty": rest_tage, "rate": apartment.price_per_day, "delivery_date": str(start_monat) } ) items.append( { "item_code": tages_service, "qty": rest_tage, "rate": apartment.service_price_per_day, "delivery_date": str(start_monat) } ) else: if rest_tage > 0: items.append( { "item_code": monats_miete, "qty": "1", "rate": apartment.price_per_month, "delivery_date": str(start_monat) } ) items.append( { "item_code": monats_service, "qty": "1", "rate": apartment.service_price_per_month, "delivery_date": str(start_monat) } ) order.update({ "items": items, "taxes_and_charges": taxes }) order.insert(ignore_permissions=True) order.run_method("calculate_taxes_and_totals") order.save() frappe.db.commit() return order
def createHeaders(firstDate, secondDate): headers = [] total_qty = 0 #first month # prepare time filter year = firstDate.year month = firstDate.month month_string = firstDate.strftime("%B")[0:3] # prepare month columns days_per_month = calendar.monthrange(year,month)[1] # find first weekday (0: Monday, ... 6: Sunday) first_weekday = calendar.monthrange(year,month)[0] # collect headers #weekday = first_weekday weekday = firstDate.weekday() for i in range(firstDate.day - 1, days_per_month): if weekday == 0: wd = "Mo" elif weekday == 1: wd = "Di" elif weekday == 2: wd = "Mi" elif weekday == 3: wd = "Do" elif weekday == 4: wd = "Fr" elif weekday == 5: wd = "Sa" else: wd = "So" headers.append({ 'day': i + 1, 'weekday': month_string + '<br>' + wd}) weekday += 1 total_qty += 1 if weekday > 6: weekday = 0 #second month # prepare time filter year = secondDate.year month = secondDate.month month_string = secondDate.strftime("%B")[0:3] # prepare month columns days_per_month = calendar.monthrange(year,month)[1] # find first weekday (0: Monday, ... 6: Sunday) first_weekday = calendar.monthrange(year,month)[0] # collect headers weekday = first_weekday #weekday = 0 for i in range(0, days_per_month): if weekday == 0: wd = "Mo" elif weekday == 1: wd = "Di" elif weekday == 2: wd = "Mi" elif weekday == 3: wd = "Do" elif weekday == 4: wd = "Fr" elif weekday == 5: wd = "Sa" else: wd = "So" headers.append({ 'day': i + 1, 'weekday': month_string + '<br>' + wd}) weekday += 1 total_qty += 1 if weekday > 6: weekday = 0 #optionaly third month if total_qty < 60: thirdDate = add_months(secondDate, 1) total_diff = 60 - total_qty + 1 # prepare time filter year = thirdDate.year month = thirdDate.month month_string = thirdDate.strftime("%B")[0:3] # prepare month columns days_per_month = calendar.monthrange(year,month)[1] # find first weekday (0: Monday, ... 6: Sunday) first_weekday = calendar.monthrange(year,month)[0] # collect headers weekday = first_weekday #weekday = 0 for i in range(0, total_diff): if weekday == 0: wd = "Mo" elif weekday == 1: wd = "Di" elif weekday == 2: wd = "Mi" elif weekday == 3: wd = "Do" elif weekday == 4: wd = "Fr" elif weekday == 5: wd = "Sa" else: wd = "So" headers.append({ 'day': i + 1, 'weekday': month_string + '<br>' + wd}) weekday += 1 if weekday > 6: weekday = 0 return ( {'headers': headers} )