Merge pull request #5313 from shreyasp/support-week-hotfix

[Hotfixes] Payment tool and Leave Allocation Tool
This commit is contained in:
Nabin Hait 2016-05-05 16:44:40 +05:30
commit 09fec7a15e
6 changed files with 116 additions and 39 deletions

View File

@ -146,6 +146,10 @@ frappe.ui.form.on("Payment Tool", "get_outstanding_vouchers", function(frm) {
c.total_amount = d.invoice_amount; c.total_amount = d.invoice_amount;
c.outstanding_amount = d.outstanding_amount; c.outstanding_amount = d.outstanding_amount;
if (in_list(['Sales Invoice', 'Purchase Invoice'], d.voucher_type)){
c.due_date = d.due_date
}
if (frm.doc.set_payment_amount) { if (frm.doc.set_payment_amount) {
c.payment_amount = d.outstanding_amount; c.payment_amount = d.outstanding_amount;
} }
@ -202,7 +206,7 @@ frappe.ui.form.on("Payment Tool Detail", "against_voucher_no", function(frm, cdt
} }
frappe.call({ frappe.call({
method: 'erpnext.accounts.doctype.payment_tool.payment_tool.get_against_voucher_amount', method: 'erpnext.accounts.doctype.payment_tool.payment_tool.get_against_voucher_details',
args: { args: {
"against_voucher_type": row.against_voucher_type, "against_voucher_type": row.against_voucher_type,
"against_voucher_no": row.against_voucher_no, "against_voucher_no": row.against_voucher_no,

View File

@ -20,15 +20,15 @@ class PaymentTool(Document):
jv.company = self.company jv.company = self.company
jv.cheque_no = self.reference_no jv.cheque_no = self.reference_no
jv.cheque_date = self.reference_date jv.cheque_date = self.reference_date
party_account_currency, party_account_type = frappe.db.get_value("Account", self.party_account, party_account_currency, party_account_type = frappe.db.get_value("Account", self.party_account,
["account_currency", "account_type"]) ["account_currency", "account_type"])
bank_account_currency, bank_account_type = None, None bank_account_currency, bank_account_type = None, None
if self.payment_account: if self.payment_account:
bank_account_currency, bank_account_type = frappe.db.get_value("Account", self.payment_account, bank_account_currency, bank_account_type = frappe.db.get_value("Account", self.payment_account,
["account_currency", "account_type"]) ["account_currency", "account_type"])
if not self.total_payment_amount: if not self.total_payment_amount:
frappe.throw(_("Please enter Payment Amount in atleast one row")) frappe.throw(_("Please enter Payment Amount in atleast one row"))
@ -36,11 +36,11 @@ class PaymentTool(Document):
if not frappe.db.get_value(v.against_voucher_type, {"name": v.against_voucher_no}): if not frappe.db.get_value(v.against_voucher_type, {"name": v.against_voucher_no}):
frappe.throw(_("Row {0}: {1} is not a valid {2}").format(v.idx, v.against_voucher_no, frappe.throw(_("Row {0}: {1} is not a valid {2}").format(v.idx, v.against_voucher_no,
v.against_voucher_type)) v.against_voucher_type))
if v.payment_amount: if v.payment_amount:
exchange_rate = get_exchange_rate(self.party_account, party_account_currency, exchange_rate = get_exchange_rate(self.party_account, party_account_currency,
self.company, v.against_voucher_type, v.against_voucher_no) self.company, v.against_voucher_type, v.against_voucher_no)
d1 = jv.append("accounts") d1 = jv.append("accounts")
d1.account = self.party_account d1.account = self.party_account
d1.party_type = self.party_type d1.party_type = self.party_type
@ -56,7 +56,7 @@ class PaymentTool(Document):
d1.reference_name = v.against_voucher_no d1.reference_name = v.against_voucher_no
d1.is_advance = 'Yes' \ d1.is_advance = 'Yes' \
if v.against_voucher_type in ['Sales Order', 'Purchase Order'] else 'No' if v.against_voucher_type in ['Sales Order', 'Purchase Order'] else 'No'
amount = flt(d1.debit_in_account_currency) - flt(d1.credit_in_account_currency) amount = flt(d1.debit_in_account_currency) - flt(d1.credit_in_account_currency)
if bank_account_currency == party_account_currency: if bank_account_currency == party_account_currency:
total_payment_amount += amount total_payment_amount += amount
@ -65,27 +65,27 @@ class PaymentTool(Document):
d2 = jv.append("accounts") d2 = jv.append("accounts")
if self.payment_account: if self.payment_account:
bank_account_currency, bank_account_type = frappe.db.get_value("Account", self.payment_account, bank_account_currency, bank_account_type = frappe.db.get_value("Account", self.payment_account,
["account_currency", "account_type"]) ["account_currency", "account_type"])
d2.account = self.payment_account d2.account = self.payment_account
d2.account_currency = bank_account_currency d2.account_currency = bank_account_currency
d2.account_type = bank_account_type d2.account_type = bank_account_type
d2.exchange_rate = get_exchange_rate(self.payment_account, bank_account_currency, self.company, d2.exchange_rate = get_exchange_rate(self.payment_account, bank_account_currency, self.company,
debit=(abs(total_payment_amount) if total_payment_amount < 0 else 0), debit=(abs(total_payment_amount) if total_payment_amount < 0 else 0),
credit=(total_payment_amount if total_payment_amount > 0 else 0)) credit=(total_payment_amount if total_payment_amount > 0 else 0))
d2.account_balance = get_balance_on(self.payment_account) d2.account_balance = get_balance_on(self.payment_account)
amount_field_bank = 'debit_in_account_currency' if total_payment_amount < 0 \ amount_field_bank = 'debit_in_account_currency' if total_payment_amount < 0 \
else 'credit_in_account_currency' else 'credit_in_account_currency'
d2.set(amount_field_bank, abs(total_payment_amount)) d2.set(amount_field_bank, abs(total_payment_amount))
company_currency = frappe.db.get_value("Company", self.company, "default_currency") company_currency = frappe.db.get_value("Company", self.company, "default_currency")
if party_account_currency != company_currency or \ if party_account_currency != company_currency or \
(bank_account_currency and bank_account_currency != company_currency): (bank_account_currency and bank_account_currency != company_currency):
jv.multi_currency = 1 jv.multi_currency = 1
jv.set_amounts_in_company_currency() jv.set_amounts_in_company_currency()
jv.set_total_debit_credit() jv.set_total_debit_credit()
@ -150,7 +150,7 @@ def get_orders_to_be_billed(party_type, party, party_account_currency, company_c
return order_list return order_list
@frappe.whitelist() @frappe.whitelist()
def get_against_voucher_amount(against_voucher_type, against_voucher_no, party_account, company): def get_against_voucher_details(against_voucher_type, against_voucher_no, party_account, company):
party_account_currency = get_account_currency(party_account) party_account_currency = get_account_currency(party_account)
company_currency = frappe.db.get_value("Company", company, "default_currency") company_currency = frappe.db.get_value("Company", company, "default_currency")
ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total" ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"

View File

@ -16,14 +16,16 @@
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 1, "in_list_view": 0,
"label": "Against Voucher Type", "label": "Against Voucher Type",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "DocType", "options": "DocType",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "", "print_width": "",
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
@ -41,6 +43,7 @@
"fieldtype": "Dynamic Link", "fieldtype": "Dynamic Link",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"label": "Against Voucher No", "label": "Against Voucher No",
@ -49,6 +52,7 @@
"options": "against_voucher_type", "options": "against_voucher_type",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -56,6 +60,31 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "due_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Due Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -64,6 +93,7 @@
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"length": 0, "length": 0,
@ -71,6 +101,7 @@
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -86,6 +117,7 @@
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"label": "Total Amount", "label": "Total Amount",
@ -94,6 +126,7 @@
"options": "party_account_currency", "options": "party_account_currency",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1, "read_only": 1,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -109,6 +142,7 @@
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"label": "Outstanding Amount", "label": "Outstanding Amount",
@ -117,6 +151,7 @@
"options": "party_account_currency", "options": "party_account_currency",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1, "read_only": 1,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -132,6 +167,7 @@
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"label": "Payment Amount", "label": "Payment Amount",
@ -140,6 +176,7 @@
"options": "party_account_currency", "options": "party_account_currency",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 1, "reqd": 1,
@ -150,13 +187,14 @@
], ],
"hide_heading": 0, "hide_heading": 0,
"hide_toolbar": 0, "hide_toolbar": 0,
"idx": 0,
"in_create": 0, "in_create": 0,
"in_dialog": 0, "in_dialog": 0,
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2015-11-16 06:29:51.626386", "modified": "2016-05-05 06:22:24.736160",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Payment Tool Detail", "name": "Payment Tool Detail",

View File

@ -473,7 +473,8 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
'posting_date': d.posting_date, 'posting_date': d.posting_date,
'invoice_amount': flt(d.invoice_amount), 'invoice_amount': flt(d.invoice_amount),
'payment_amount': flt(d.payment_amount), 'payment_amount': flt(d.payment_amount),
'outstanding_amount': flt(d.invoice_amount - d.payment_amount, precision) 'outstanding_amount': flt(d.invoice_amount - d.payment_amount, precision),
'due_date': frappe.db.get_value(d.voucher_type, d.voucher_no, "due_date")
}) })
return outstanding_invoices return outstanding_invoices

View File

@ -15,11 +15,14 @@
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -33,17 +36,20 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"description": "Leave blank if considered for all employee types", "description": "Leave blank if considered for all employee types",
"fieldname": "employee_type", "fieldname": "employment_type",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"label": "Employee Type", "label": "Employment Type",
"length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Employment Type", "options": "Employment Type",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -60,13 +66,16 @@
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"label": "Branch", "label": "Branch",
"length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Branch", "options": "Branch",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -83,13 +92,16 @@
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"label": "Department", "label": "Department",
"length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Department", "options": "Department",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -106,13 +118,16 @@
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"label": "Designation", "label": "Designation",
"length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Designation", "options": "Designation",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -128,11 +143,14 @@
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -149,13 +167,16 @@
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"label": "From Date", "label": "From Date",
"length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 1, "reqd": 1,
@ -171,13 +192,16 @@
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"label": "To Date", "label": "To Date",
"length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 1, "reqd": 1,
@ -193,13 +217,16 @@
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"label": "Leave Type", "label": "Leave Type",
"length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Leave Type", "options": "Leave Type",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 1, "reqd": 1,
@ -216,12 +243,15 @@
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"label": "Carry Forward", "label": "Carry Forward",
"length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -237,12 +267,15 @@
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"label": "New Leaves Allocated (In Days)", "label": "New Leaves Allocated (In Days)",
"length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 1, "reqd": 1,
@ -258,13 +291,16 @@
"fieldtype": "Button", "fieldtype": "Button",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"label": "Allocate", "label": "Allocate",
"length": 0,
"no_copy": 0, "no_copy": 0,
"options": "allocate_leave", "options": "allocate_leave",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -282,7 +318,8 @@
"is_submittable": 0, "is_submittable": 0,
"issingle": 1, "issingle": 1,
"istable": 0, "istable": 0,
"modified": "2015-10-28 16:23:57.733900", "max_attachments": 0,
"modified": "2016-05-05 05:45:33.355366",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Leave Control Panel", "name": "Leave Control Panel",

View File

@ -10,27 +10,24 @@ from frappe.model.document import Document
class LeaveControlPanel(Document): class LeaveControlPanel(Document):
def get_employees(self): def get_employees(self):
lst1 = [[self.employee_type,"employment_type"],[self.branch,"branch"],[self.designation,"designation"],[self.department, "department"]] conditions, values = [], []
condition = "where " for field in ["employment_type", "branch", "designation", "department"]:
flag = 0 if self.get(field):
for l in lst1: conditions.append("{0}=%s".format(field))
if(l[0]): values.append(self.get(field))
if flag == 0:
condition += l[1] + "= '" + l[0] +"'" condition_str = " and " + " and ".join(conditions) if len(conditions) else ""
else:
condition += " and " + l[1]+ "= '" +l[0] +"'" e = frappe.db.sql("select name from tabEmployee where status='Active' {condition}"
flag = 1 .format(condition=condition_str), tuple(values))
emp_query = "select name from `tabEmployee` "
if flag == 1:
emp_query += condition
e = frappe.db.sql(emp_query)
return e return e
def validate_values(self): def validate_values(self):
for f in ["from_date", "to_date", "leave_type", "no_of_days"]: for f in ["from_date", "to_date", "leave_type", "no_of_days"]:
if not self.get(f): if not self.get(f):
frappe.throw(_("{0} is required").format(self.meta.get_label(f))) frappe.throw(_("{0} is required").format(self.meta.get_label(f)))
def to_date_validation(self): def to_date_validation(self):
if date_diff(self.to_date, self.from_date) <= 0: if date_diff(self.to_date, self.from_date) <= 0:
return "Invalid period" return "Invalid period"