mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 16:34:46 +00:00
Merge branch 'develop' into fix_create_item_tax_with_salespurchasetax
This commit is contained in:
@@ -61,8 +61,10 @@ class AccountingDimension(Document):
|
|||||||
def on_update(self):
|
def on_update(self):
|
||||||
frappe.flags.accounting_dimensions = None
|
frappe.flags.accounting_dimensions = None
|
||||||
|
|
||||||
def make_dimension_in_accounting_doctypes(doc):
|
def make_dimension_in_accounting_doctypes(doc, doclist=None):
|
||||||
doclist = get_doctypes_with_dimensions()
|
if not doclist:
|
||||||
|
doclist = get_doctypes_with_dimensions()
|
||||||
|
|
||||||
doc_count = len(get_accounting_dimensions())
|
doc_count = len(get_accounting_dimensions())
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
@@ -82,13 +84,13 @@ def make_dimension_in_accounting_doctypes(doc):
|
|||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
}
|
}
|
||||||
|
|
||||||
if doctype == "Budget":
|
meta = frappe.get_meta(doctype, cached=False)
|
||||||
add_dimension_to_budget_doctype(df, doc)
|
fieldnames = [d.fieldname for d in meta.get("fields")]
|
||||||
else:
|
|
||||||
meta = frappe.get_meta(doctype, cached=False)
|
|
||||||
fieldnames = [d.fieldname for d in meta.get("fields")]
|
|
||||||
|
|
||||||
if df['fieldname'] not in fieldnames:
|
if df['fieldname'] not in fieldnames:
|
||||||
|
if doctype == "Budget":
|
||||||
|
add_dimension_to_budget_doctype(df.copy(), doc)
|
||||||
|
else:
|
||||||
create_custom_field(doctype, df)
|
create_custom_field(doctype, df)
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
@@ -178,15 +180,7 @@ def toggle_disabling(doc):
|
|||||||
frappe.clear_cache(doctype=doctype)
|
frappe.clear_cache(doctype=doctype)
|
||||||
|
|
||||||
def get_doctypes_with_dimensions():
|
def get_doctypes_with_dimensions():
|
||||||
doclist = ["GL Entry", "Sales Invoice", "POS Invoice", "Purchase Invoice", "Payment Entry", "Asset",
|
return frappe.get_hooks("accounting_dimension_doctypes")
|
||||||
"Expense Claim", "Expense Claim Detail", "Expense Taxes and Charges", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note",
|
|
||||||
"Sales Invoice Item", "POS Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item",
|
|
||||||
"Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule",
|
|
||||||
"Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation",
|
|
||||||
"Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item", "Subscription",
|
|
||||||
"Subscription Plan"]
|
|
||||||
|
|
||||||
return doclist
|
|
||||||
|
|
||||||
def get_accounting_dimensions(as_list=True):
|
def get_accounting_dimensions(as_list=True):
|
||||||
if frappe.flags.accounting_dimensions is None:
|
if frappe.flags.accounting_dimensions is None:
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ class PricingRule(Document):
|
|||||||
for d in self.items:
|
for d in self.items:
|
||||||
max_discount = frappe.get_cached_value("Item", d.item_code, "max_discount")
|
max_discount = frappe.get_cached_value("Item", d.item_code, "max_discount")
|
||||||
if max_discount and flt(self.discount_percentage) > flt(max_discount):
|
if max_discount and flt(self.discount_percentage) > flt(max_discount):
|
||||||
throw(_("Max discount allowed for item: {0} is {1}%").format(self.item_code, max_discount))
|
throw(_("Max discount allowed for item: {0} is {1}%").format(d.item_code, max_discount))
|
||||||
|
|
||||||
def validate_price_list_with_currency(self):
|
def validate_price_list_with_currency(self):
|
||||||
if self.currency and self.for_price_list:
|
if self.currency and self.for_price_list:
|
||||||
|
|||||||
@@ -10,6 +10,14 @@ frappe.ui.form.on('Subscription', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frm.set_query('cost_center', function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
company: frm.doc.company
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
|
|||||||
@@ -7,9 +7,10 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"party_type",
|
"party_type",
|
||||||
"status",
|
|
||||||
"cb_1",
|
|
||||||
"party",
|
"party",
|
||||||
|
"cb_1",
|
||||||
|
"company",
|
||||||
|
"status",
|
||||||
"subscription_period",
|
"subscription_period",
|
||||||
"start_date",
|
"start_date",
|
||||||
"end_date",
|
"end_date",
|
||||||
@@ -44,80 +45,107 @@
|
|||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"fieldname": "cb_1",
|
"fieldname": "cb_1",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "status",
|
"fieldname": "status",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Status",
|
"label": "Status",
|
||||||
|
"no_copy": 1,
|
||||||
"options": "\nTrialling\nActive\nPast Due Date\nCancelled\nUnpaid\nCompleted",
|
"options": "\nTrialling\nActive\nPast Due Date\nCancelled\nUnpaid\nCompleted",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "subscription_period",
|
"fieldname": "subscription_period",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Subscription Period"
|
"label": "Subscription Period",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "cancelation_date",
|
"fieldname": "cancelation_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Cancelation Date",
|
"label": "Cancelation Date",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"fieldname": "trial_period_start",
|
"fieldname": "trial_period_start",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Trial Period Start Date",
|
"label": "Trial Period Start Date",
|
||||||
"set_only_once": 1
|
"set_only_once": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.trial_period_start",
|
"depends_on": "eval:doc.trial_period_start",
|
||||||
"fieldname": "trial_period_end",
|
"fieldname": "trial_period_end",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Trial Period End Date",
|
"label": "Trial Period End Date",
|
||||||
"set_only_once": 1
|
"set_only_once": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_11",
|
"fieldname": "column_break_11",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "current_invoice_start",
|
"fieldname": "current_invoice_start",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Current Invoice Start Date",
|
"label": "Current Invoice Start Date",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "current_invoice_end",
|
"fieldname": "current_invoice_end",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Current Invoice End Date",
|
"label": "Current Invoice End Date",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"description": "Number of days that the subscriber has to pay invoices generated by this subscription",
|
"description": "Number of days that the subscriber has to pay invoices generated by this subscription",
|
||||||
"fieldname": "days_until_due",
|
"fieldname": "days_until_due",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "Days Until Due"
|
"label": "Days Until Due",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "cancel_at_period_end",
|
"fieldname": "cancel_at_period_end",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Cancel At End Of Period"
|
"label": "Cancel At End Of Period",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "generate_invoice_at_period_start",
|
"fieldname": "generate_invoice_at_period_start",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Generate Invoice At Beginning Of Period"
|
"label": "Generate Invoice At Beginning Of Period",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"fieldname": "sb_4",
|
"fieldname": "sb_4",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Plans"
|
"label": "Plans",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
@@ -125,62 +153,84 @@
|
|||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Plans",
|
"label": "Plans",
|
||||||
"options": "Subscription Plan Detail",
|
"options": "Subscription Plan Detail",
|
||||||
"reqd": 1
|
"reqd": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:['Customer', 'Supplier'].includes(doc.party_type)",
|
"depends_on": "eval:['Customer', 'Supplier'].includes(doc.party_type)",
|
||||||
"fieldname": "sb_1",
|
"fieldname": "sb_1",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Taxes"
|
"label": "Taxes",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "sb_2",
|
"fieldname": "sb_2",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Discounts"
|
"label": "Discounts",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "apply_additional_discount",
|
"fieldname": "apply_additional_discount",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Apply Additional Discount On",
|
"label": "Apply Additional Discount On",
|
||||||
"options": "\nGrand Total\nNet Total"
|
"options": "\nGrand Total\nNet Total",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "cb_2",
|
"fieldname": "cb_2",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "additional_discount_percentage",
|
"fieldname": "additional_discount_percentage",
|
||||||
"fieldtype": "Percent",
|
"fieldtype": "Percent",
|
||||||
"label": "Additional DIscount Percentage"
|
"label": "Additional DIscount Percentage",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "additional_discount_amount",
|
"fieldname": "additional_discount_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Additional DIscount Amount"
|
"label": "Additional DIscount Amount",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.invoices",
|
"depends_on": "eval:doc.invoices",
|
||||||
"fieldname": "sb_3",
|
"fieldname": "sb_3",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Invoices"
|
"label": "Invoices",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "invoices",
|
"fieldname": "invoices",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Invoices",
|
"label": "Invoices",
|
||||||
"options": "Subscription Invoice"
|
"options": "Subscription Invoice",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "accounting_dimensions_section",
|
"fieldname": "accounting_dimensions_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Accounting Dimensions"
|
"label": "Accounting Dimensions",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "dimension_col_break",
|
"fieldname": "dimension_col_break",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "party_type",
|
"fieldname": "party_type",
|
||||||
@@ -188,7 +238,9 @@
|
|||||||
"label": "Party Type",
|
"label": "Party Type",
|
||||||
"options": "DocType",
|
"options": "DocType",
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"set_only_once": 1
|
"set_only_once": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "party",
|
"fieldname": "party",
|
||||||
@@ -197,21 +249,27 @@
|
|||||||
"label": "Party",
|
"label": "Party",
|
||||||
"options": "party_type",
|
"options": "party_type",
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"set_only_once": 1
|
"set_only_once": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.party_type === 'Customer'",
|
"depends_on": "eval:doc.party_type === 'Customer'",
|
||||||
"fieldname": "sales_tax_template",
|
"fieldname": "sales_tax_template",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Sales Taxes and Charges Template",
|
"label": "Sales Taxes and Charges Template",
|
||||||
"options": "Sales Taxes and Charges Template"
|
"options": "Sales Taxes and Charges Template",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.party_type === 'Supplier'",
|
"depends_on": "eval:doc.party_type === 'Supplier'",
|
||||||
"fieldname": "purchase_tax_template",
|
"fieldname": "purchase_tax_template",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Purchase Taxes and Charges Template",
|
"label": "Purchase Taxes and Charges Template",
|
||||||
"options": "Purchase Taxes and Charges Template"
|
"options": "Purchase Taxes and Charges Template",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
@@ -219,36 +277,55 @@
|
|||||||
"fieldname": "follow_calendar_months",
|
"fieldname": "follow_calendar_months",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Follow Calendar Months",
|
"label": "Follow Calendar Months",
|
||||||
"set_only_once": 1
|
"set_only_once": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"description": "New invoices will be generated as per schedule even if current invoices are unpaid or past due date",
|
"description": "New invoices will be generated as per schedule even if current invoices are unpaid or past due date",
|
||||||
"fieldname": "generate_new_invoices_past_due_date",
|
"fieldname": "generate_new_invoices_past_due_date",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Generate New Invoices Past Due Date"
|
"label": "Generate New Invoices Past Due Date",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "end_date",
|
"fieldname": "end_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Subscription End Date",
|
"label": "Subscription End Date",
|
||||||
"set_only_once": 1
|
"set_only_once": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "start_date",
|
"fieldname": "start_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Subscription Start Date",
|
"label": "Subscription Start Date",
|
||||||
"set_only_once": 1
|
"set_only_once": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "cost_center",
|
"fieldname": "cost_center",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Cost Center",
|
"label": "Cost Center",
|
||||||
"options": "Cost Center"
|
"options": "Cost Center",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Company",
|
||||||
|
"options": "Company",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-06-25 10:52:52.265105",
|
"modified": "2021-02-09 15:44:20.024789",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Subscription",
|
"name": "Subscription",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
@@ -5,12 +6,13 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
import erpnext
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils.data import nowdate, getdate, cstr, cint, add_days, date_diff, get_last_day, add_to_date, flt
|
from frappe.utils.data import nowdate, getdate, cstr, cint, add_days, date_diff, get_last_day, add_to_date, flt
|
||||||
from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_plan_rate
|
from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_plan_rate
|
||||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||||
|
from erpnext import get_default_company
|
||||||
|
|
||||||
class Subscription(Document):
|
class Subscription(Document):
|
||||||
def before_insert(self):
|
def before_insert(self):
|
||||||
@@ -243,6 +245,7 @@ class Subscription(Document):
|
|||||||
self.validate_plans_billing_cycle(self.get_billing_cycle_and_interval())
|
self.validate_plans_billing_cycle(self.get_billing_cycle_and_interval())
|
||||||
self.validate_end_date()
|
self.validate_end_date()
|
||||||
self.validate_to_follow_calendar_months()
|
self.validate_to_follow_calendar_months()
|
||||||
|
self.cost_center = erpnext.get_default_cost_center(self.get('company'))
|
||||||
|
|
||||||
def validate_trial_period(self):
|
def validate_trial_period(self):
|
||||||
"""
|
"""
|
||||||
@@ -304,6 +307,14 @@ class Subscription(Document):
|
|||||||
doctype = 'Sales Invoice' if self.party_type == 'Customer' else 'Purchase Invoice'
|
doctype = 'Sales Invoice' if self.party_type == 'Customer' else 'Purchase Invoice'
|
||||||
|
|
||||||
invoice = frappe.new_doc(doctype)
|
invoice = frappe.new_doc(doctype)
|
||||||
|
|
||||||
|
# For backward compatibility
|
||||||
|
# Earlier subscription didn't had any company field
|
||||||
|
company = self.get('company') or get_default_company()
|
||||||
|
if not company:
|
||||||
|
frappe.throw(_("Company is mandatory was generating invoice. Please set default company in Global Defaults"))
|
||||||
|
|
||||||
|
invoice.company = company
|
||||||
invoice.set_posting_time = 1
|
invoice.set_posting_time = 1
|
||||||
invoice.posting_date = self.current_invoice_start if self.generate_invoice_at_period_start \
|
invoice.posting_date = self.current_invoice_start if self.generate_invoice_at_period_start \
|
||||||
else self.current_invoice_end
|
else self.current_invoice_end
|
||||||
@@ -330,6 +341,7 @@ class Subscription(Document):
|
|||||||
# for that reason
|
# for that reason
|
||||||
items_list = self.get_items_from_plans(self.plans, prorate)
|
items_list = self.get_items_from_plans(self.plans, prorate)
|
||||||
for item in items_list:
|
for item in items_list:
|
||||||
|
item['cost_center'] = self.cost_center
|
||||||
invoice.append('items', item)
|
invoice.append('items', item)
|
||||||
|
|
||||||
# Taxes
|
# Taxes
|
||||||
@@ -380,7 +392,8 @@ class Subscription(Document):
|
|||||||
Returns the `Item`s linked to `Subscription Plan`
|
Returns the `Item`s linked to `Subscription Plan`
|
||||||
"""
|
"""
|
||||||
if prorate:
|
if prorate:
|
||||||
prorate_factor = get_prorata_factor(self.current_invoice_end, self.current_invoice_start)
|
prorate_factor = get_prorata_factor(self.current_invoice_end, self.current_invoice_start,
|
||||||
|
self.generate_invoice_at_period_start)
|
||||||
|
|
||||||
items = []
|
items = []
|
||||||
party = self.party
|
party = self.party
|
||||||
@@ -583,10 +596,13 @@ def get_calendar_months(billing_interval):
|
|||||||
|
|
||||||
return calendar_months
|
return calendar_months
|
||||||
|
|
||||||
def get_prorata_factor(period_end, period_start):
|
def get_prorata_factor(period_end, period_start, is_prepaid):
|
||||||
diff = flt(date_diff(nowdate(), period_start) + 1)
|
if is_prepaid:
|
||||||
plan_days = flt(date_diff(period_end, period_start) + 1)
|
prorate_factor = 1
|
||||||
prorate_factor = diff / plan_days
|
else:
|
||||||
|
diff = flt(date_diff(nowdate(), period_start) + 1)
|
||||||
|
plan_days = flt(date_diff(period_end, period_start) + 1)
|
||||||
|
prorate_factor = diff / plan_days
|
||||||
|
|
||||||
return prorate_factor
|
return prorate_factor
|
||||||
|
|
||||||
|
|||||||
@@ -321,7 +321,8 @@ class TestSubscription(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
flt(
|
flt(
|
||||||
get_prorata_factor(subscription.current_invoice_end, subscription.current_invoice_start),
|
get_prorata_factor(subscription.current_invoice_end, subscription.current_invoice_start,
|
||||||
|
subscription.generate_invoice_at_period_start),
|
||||||
2),
|
2),
|
||||||
flt(prorate_factor, 2)
|
flt(prorate_factor, 2)
|
||||||
)
|
)
|
||||||
@@ -561,9 +562,7 @@ class TestSubscription(unittest.TestCase):
|
|||||||
current_inv = subscription.get_current_invoice()
|
current_inv = subscription.get_current_invoice()
|
||||||
self.assertEqual(current_inv.status, "Unpaid")
|
self.assertEqual(current_inv.status, "Unpaid")
|
||||||
|
|
||||||
diff = flt(date_diff(nowdate(), subscription.current_invoice_start) + 1)
|
prorate_factor = 1
|
||||||
plan_days = flt(date_diff(subscription.current_invoice_end, subscription.current_invoice_start) + 1)
|
|
||||||
prorate_factor = flt(diff / plan_days)
|
|
||||||
|
|
||||||
self.assertEqual(flt(current_inv.grand_total, 2), flt(prorate_factor * 900, 2))
|
self.assertEqual(flt(current_inv.grand_total, 2), flt(prorate_factor * 900, 2))
|
||||||
|
|
||||||
|
|||||||
@@ -13,21 +13,28 @@
|
|||||||
"fieldname": "document_type",
|
"fieldname": "document_type",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Document Type ",
|
"label": "Document Type ",
|
||||||
|
"no_copy": 1,
|
||||||
"options": "DocType",
|
"options": "DocType",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "invoice",
|
"fieldname": "invoice",
|
||||||
"fieldtype": "Dynamic Link",
|
"fieldtype": "Dynamic Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Invoice",
|
"label": "Invoice",
|
||||||
|
"no_copy": 1,
|
||||||
"options": "document_type",
|
"options": "document_type",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-06-01 22:23:54.462718",
|
"modified": "2021-02-09 15:43:32.026233",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Subscription Invoice",
|
"name": "Subscription Invoice",
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ def make_round_off_gle(gl_map, debit_credit_diff, precision):
|
|||||||
|
|
||||||
if not round_off_gle:
|
if not round_off_gle:
|
||||||
for k in ["voucher_type", "voucher_no", "company",
|
for k in ["voucher_type", "voucher_no", "company",
|
||||||
"posting_date", "remarks", "is_opening"]:
|
"posting_date", "remarks"]:
|
||||||
round_off_gle[k] = gl_map[0][k]
|
round_off_gle[k] = gl_map[0][k]
|
||||||
|
|
||||||
round_off_gle.update({
|
round_off_gle.update({
|
||||||
@@ -208,6 +208,7 @@ def make_round_off_gle(gl_map, debit_credit_diff, precision):
|
|||||||
"cost_center": round_off_cost_center,
|
"cost_center": round_off_cost_center,
|
||||||
"party_type": None,
|
"party_type": None,
|
||||||
"party": None,
|
"party": None,
|
||||||
|
"is_opening": "No",
|
||||||
"against_voucher_type": None,
|
"against_voucher_type": None,
|
||||||
"against_voucher": None
|
"against_voucher": None
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ def call_mws_method(mws_method, *args, **kwargs):
|
|||||||
return response
|
return response
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
delay = math.pow(4, x) * 125
|
delay = math.pow(4, x) * 125
|
||||||
frappe.log_error(message=e, title=str(mws_method))
|
frappe.log_error(message=e, title=f'Method "{mws_method.__name__}" failed')
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
@@ -393,6 +393,15 @@ payment_gateway_enabled = "erpnext.accounts.utils.create_payment_gateway_account
|
|||||||
|
|
||||||
communication_doctypes = ["Customer", "Supplier"]
|
communication_doctypes = ["Customer", "Supplier"]
|
||||||
|
|
||||||
|
accounting_dimension_doctypes = ["GL Entry", "Sales Invoice", "Purchase Invoice", "Payment Entry", "Asset",
|
||||||
|
"Expense Claim", "Expense Claim Detail", "Expense Taxes and Charges", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note",
|
||||||
|
"Sales Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item",
|
||||||
|
"Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule",
|
||||||
|
"Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation",
|
||||||
|
"Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item", "Subscription",
|
||||||
|
"Subscription Plan"
|
||||||
|
]
|
||||||
|
|
||||||
regional_overrides = {
|
regional_overrides = {
|
||||||
'France': {
|
'France': {
|
||||||
'erpnext.tests.test_regional.test_method': 'erpnext.regional.france.utils.test_method'
|
'erpnext.tests.test_regional.test_method': 'erpnext.regional.france.utils.test_method'
|
||||||
|
|||||||
@@ -138,7 +138,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-08-27 14:30:28.995324",
|
"modified": "2021-02-25 12:31:14.947865",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "HR Settings",
|
"name": "HR Settings",
|
||||||
@@ -155,5 +155,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC"
|
"sort_order": "ASC",
|
||||||
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"allow_events_in_timeline": 0,
|
"allow_events_in_timeline": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 1,
|
||||||
"autoname": "field:skill_name",
|
"autoname": "field:skill_name",
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
"creation": "2019-04-16 09:54:39.486915",
|
"creation": "2019-04-16 09:54:39.486915",
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2019-04-16 09:55:00.536328",
|
"modified": "2021-02-24 09:55:00.536328",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Skill",
|
"name": "Skill",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 6,
|
"columns": 6,
|
||||||
|
"fetch_from": "task.subject",
|
||||||
"fieldname": "subject",
|
"fieldname": "subject",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -28,7 +29,7 @@
|
|||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-01-07 15:13:40.995071",
|
"modified": "2021-02-24 15:18:49.095071",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Project Template Task",
|
"name": "Project Template Task",
|
||||||
|
|||||||
@@ -212,8 +212,7 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"ignore_user_permissions": 1,
|
"ignore_user_permissions": 1,
|
||||||
"label": "Represents Company",
|
"label": "Represents Company",
|
||||||
"options": "Company",
|
"options": "Company"
|
||||||
"unique": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "represents_company",
|
"depends_on": "represents_company",
|
||||||
@@ -500,7 +499,7 @@
|
|||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-01-27 12:54:57.258959",
|
"modified": "2021-01-28 12:54:57.258959",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Customer",
|
"name": "Customer",
|
||||||
|
|||||||
@@ -521,8 +521,7 @@
|
|||||||
"fieldname": "has_variants",
|
"fieldname": "has_variants",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Has Variants",
|
"label": "Has Variants"
|
||||||
"no_copy": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "Item Attribute",
|
"default": "Item Attribute",
|
||||||
@@ -538,7 +537,6 @@
|
|||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Attributes",
|
"label": "Attributes",
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Item Variant Attribute"
|
"options": "Item Variant Attribute"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1068,7 +1066,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"max_attachments": 1,
|
"max_attachments": 1,
|
||||||
"modified": "2021-01-25 20:49:50.222976",
|
"modified": "2021-02-18 14:00:19.668049",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item",
|
"name": "Item",
|
||||||
|
|||||||
@@ -276,9 +276,10 @@ class StockEntry(StockController):
|
|||||||
item_wise_qty.setdefault(d.item_code, []).append(d.qty)
|
item_wise_qty.setdefault(d.item_code, []).append(d.qty)
|
||||||
|
|
||||||
for item_code, qty_list in iteritems(item_wise_qty):
|
for item_code, qty_list in iteritems(item_wise_qty):
|
||||||
if self.fg_completed_qty != sum(qty_list):
|
total = flt(sum(qty_list), frappe.get_precision("Stock Entry Detail", "qty"))
|
||||||
|
if self.fg_completed_qty != total:
|
||||||
frappe.throw(_("The finished product {0} quantity {1} and For Quantity {2} cannot be different")
|
frappe.throw(_("The finished product {0} quantity {1} and For Quantity {2} cannot be different")
|
||||||
.format(frappe.bold(item_code), frappe.bold(sum(qty_list)), frappe.bold(self.fg_completed_qty)))
|
.format(frappe.bold(item_code), frappe.bold(total), frappe.bold(self.fg_completed_qty)))
|
||||||
|
|
||||||
def validate_difference_account(self):
|
def validate_difference_account(self):
|
||||||
if not cint(erpnext.is_perpetual_inventory_enabled(self.company)):
|
if not cint(erpnext.is_perpetual_inventory_enabled(self.company)):
|
||||||
|
|||||||
Reference in New Issue
Block a user