Merge branch 'develop' of https://github.com/frappe/erpnext into develop
This commit is contained in:
commit
420359284f
@ -19,6 +19,11 @@ def get(chart_name = None, chart = None, no_cache = None, from_date = None, to_d
|
|||||||
else:
|
else:
|
||||||
chart = frappe._dict(frappe.parse_json(chart))
|
chart = frappe._dict(frappe.parse_json(chart))
|
||||||
timespan = chart.timespan
|
timespan = chart.timespan
|
||||||
|
|
||||||
|
if chart.timespan == 'Select Date Range':
|
||||||
|
from_date = chart.from_date
|
||||||
|
to_date = chart.to_date
|
||||||
|
|
||||||
timegrain = chart.time_interval
|
timegrain = chart.time_interval
|
||||||
filters = frappe.parse_json(chart.filters_json)
|
filters = frappe.parse_json(chart.filters_json)
|
||||||
|
|
||||||
@ -88,7 +93,8 @@ def get_gl_entries(account, to_date):
|
|||||||
fields = ['posting_date', 'debit', 'credit'],
|
fields = ['posting_date', 'debit', 'credit'],
|
||||||
filters = [
|
filters = [
|
||||||
dict(posting_date = ('<', to_date)),
|
dict(posting_date = ('<', to_date)),
|
||||||
dict(account = ('in', child_accounts))
|
dict(account = ('in', child_accounts)),
|
||||||
|
dict(voucher_type = ('!=', 'Period Closing Voucher'))
|
||||||
],
|
],
|
||||||
order_by = 'posting_date asc')
|
order_by = 'posting_date asc')
|
||||||
|
|
||||||
|
@ -174,6 +174,8 @@ def make_gl_entries(doc, credit_account, debit_account, against,
|
|||||||
# GL Entry for crediting the amount in the deferred expense
|
# GL Entry for crediting the amount in the deferred expense
|
||||||
from erpnext.accounts.general_ledger import make_gl_entries
|
from erpnext.accounts.general_ledger import make_gl_entries
|
||||||
|
|
||||||
|
if amount == 0: return
|
||||||
|
|
||||||
gl_entries = []
|
gl_entries = []
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
doc.get_gl_dict({
|
doc.get_gl_dict({
|
||||||
|
@ -24,6 +24,11 @@ class AccountingDimension(Document):
|
|||||||
msg = _("Not allowed to create accounting dimension for {0}").format(self.document_type)
|
msg = _("Not allowed to create accounting dimension for {0}").format(self.document_type)
|
||||||
frappe.throw(msg)
|
frappe.throw(msg)
|
||||||
|
|
||||||
|
exists = frappe.db.get_value("Accounting Dimension", {'document_type': self.document_type}, ['name'])
|
||||||
|
|
||||||
|
if exists and self.is_new():
|
||||||
|
frappe.throw("Document Type already used as a dimension")
|
||||||
|
|
||||||
def after_insert(self):
|
def after_insert(self):
|
||||||
if frappe.flags.in_test:
|
if frappe.flags.in_test:
|
||||||
make_dimension_in_accounting_doctypes(doc=self)
|
make_dimension_in_accounting_doctypes(doc=self)
|
||||||
@ -60,7 +65,8 @@ def make_dimension_in_accounting_doctypes(doc):
|
|||||||
"label": doc.label,
|
"label": doc.label,
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": doc.document_type,
|
"options": doc.document_type,
|
||||||
"insert_after": insert_after_field
|
"insert_after": insert_after_field,
|
||||||
|
"owner": "Administrator"
|
||||||
}
|
}
|
||||||
|
|
||||||
if doctype == "Budget":
|
if doctype == "Budget":
|
||||||
|
@ -15,8 +15,8 @@ class AccountsSettings(Document):
|
|||||||
frappe.clear_cache()
|
frappe.clear_cache()
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
for f in ["add_taxes_from_item_tax_template"]:
|
frappe.db.set_default("add_taxes_from_item_tax_template",
|
||||||
frappe.db.set_default(f, self.get(f, ""))
|
self.get("add_taxes_from_item_tax_template", 0))
|
||||||
|
|
||||||
self.validate_stale_days()
|
self.validate_stale_days()
|
||||||
self.enable_payment_schedule_in_print()
|
self.enable_payment_schedule_in_print()
|
||||||
|
@ -570,7 +570,7 @@ $.extend(erpnext.journal_entry, {
|
|||||||
},
|
},
|
||||||
{fieldtype: "Date", fieldname: "posting_date", label: __("Date"), reqd: 1,
|
{fieldtype: "Date", fieldname: "posting_date", label: __("Date"), reqd: 1,
|
||||||
default: frm.doc.posting_date},
|
default: frm.doc.posting_date},
|
||||||
{fieldtype: "Small Text", fieldname: "user_remark", label: __("User Remark"), reqd: 1},
|
{fieldtype: "Small Text", fieldname: "user_remark", label: __("User Remark")},
|
||||||
{fieldtype: "Select", fieldname: "naming_series", label: __("Series"), reqd: 1,
|
{fieldtype: "Select", fieldname: "naming_series", label: __("Series"), reqd: 1,
|
||||||
options: naming_series_options, default: naming_series_default},
|
options: naming_series_options, default: naming_series_default},
|
||||||
]
|
]
|
||||||
|
@ -32,8 +32,10 @@ class OpeningInvoiceCreationTool(Document):
|
|||||||
})
|
})
|
||||||
invoices_summary.update({company: _summary})
|
invoices_summary.update({company: _summary})
|
||||||
|
|
||||||
paid_amount.append(invoice.paid_amount)
|
if invoice.paid_amount:
|
||||||
outstanding_amount.append(invoice.outstanding_amount)
|
paid_amount.append(invoice.paid_amount)
|
||||||
|
if invoice.outstanding_amount:
|
||||||
|
outstanding_amount.append(invoice.outstanding_amount)
|
||||||
|
|
||||||
if paid_amount or outstanding_amount:
|
if paid_amount or outstanding_amount:
|
||||||
max_count.update({
|
max_count.update({
|
||||||
|
@ -554,7 +554,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
frappe.flags.allocate_payment_amount = true;
|
frappe.flags.allocate_payment_amount = true;
|
||||||
frm.events.validate_filters_data(frm, filters);
|
frm.events.validate_filters_data(frm, filters);
|
||||||
frm.events.get_outstanding_documents(frm, filters);
|
frm.events.get_outstanding_documents(frm, filters);
|
||||||
}, __("Filters"), __("Get Outstanding Invoices"));
|
}, __("Filters"), __("Get Outstanding Documents"));
|
||||||
},
|
},
|
||||||
|
|
||||||
validate_filters_data: function(frm, filters) {
|
validate_filters_data: function(frm, filters) {
|
||||||
|
@ -62,6 +62,7 @@
|
|||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"section_break_12",
|
"section_break_12",
|
||||||
|
"status",
|
||||||
"remarks",
|
"remarks",
|
||||||
"column_break_16",
|
"column_break_16",
|
||||||
"letter_head",
|
"letter_head",
|
||||||
@ -563,10 +564,18 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "dimension_col_break",
|
"fieldname": "dimension_col_break",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "Draft",
|
||||||
|
"fieldname": "status",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Status",
|
||||||
|
"options": "\nDraft\nSubmitted\nCancelled",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-05-27 15:53:21.108857",
|
"modified": "2019-11-06 12:59:43.151721",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
@ -61,6 +61,7 @@ class PaymentEntry(AccountsController):
|
|||||||
self.validate_duplicate_entry()
|
self.validate_duplicate_entry()
|
||||||
self.validate_allocated_amount()
|
self.validate_allocated_amount()
|
||||||
self.ensure_supplier_is_not_blocked()
|
self.ensure_supplier_is_not_blocked()
|
||||||
|
self.set_status()
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.setup_party_account_field()
|
self.setup_party_account_field()
|
||||||
@ -70,6 +71,7 @@ class PaymentEntry(AccountsController):
|
|||||||
self.update_outstanding_amounts()
|
self.update_outstanding_amounts()
|
||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
self.update_expense_claim()
|
self.update_expense_claim()
|
||||||
|
self.set_status()
|
||||||
|
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
@ -79,6 +81,7 @@ class PaymentEntry(AccountsController):
|
|||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
self.update_expense_claim()
|
self.update_expense_claim()
|
||||||
self.delink_advance_entry_references()
|
self.delink_advance_entry_references()
|
||||||
|
self.set_status()
|
||||||
|
|
||||||
def update_outstanding_amounts(self):
|
def update_outstanding_amounts(self):
|
||||||
self.set_missing_ref_details(force=True)
|
self.set_missing_ref_details(force=True)
|
||||||
@ -275,6 +278,14 @@ class PaymentEntry(AccountsController):
|
|||||||
frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry")
|
frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry")
|
||||||
.format(d.reference_name, dr_or_cr))
|
.format(d.reference_name, dr_or_cr))
|
||||||
|
|
||||||
|
def set_status(self):
|
||||||
|
if self.docstatus == 2:
|
||||||
|
self.status = 'Cancelled'
|
||||||
|
elif self.docstatus == 1:
|
||||||
|
self.status = 'Submitted'
|
||||||
|
else:
|
||||||
|
self.status = 'Draft'
|
||||||
|
|
||||||
def set_amounts(self):
|
def set_amounts(self):
|
||||||
self.set_amounts_in_company_currency()
|
self.set_amounts_in_company_currency()
|
||||||
self.set_total_allocated_amount()
|
self.set_total_allocated_amount()
|
||||||
|
@ -90,7 +90,8 @@ class PaymentReconciliation(Document):
|
|||||||
FROM `tab{doc}`, `tabGL Entry`
|
FROM `tab{doc}`, `tabGL Entry`
|
||||||
WHERE
|
WHERE
|
||||||
(`tab{doc}`.name = `tabGL Entry`.against_voucher or `tab{doc}`.name = `tabGL Entry`.voucher_no)
|
(`tab{doc}`.name = `tabGL Entry`.against_voucher or `tab{doc}`.name = `tabGL Entry`.voucher_no)
|
||||||
and `tab{doc}`.is_return = 1 and `tabGL Entry`.against_voucher_type = %(voucher_type)s
|
and `tab{doc}`.is_return = 1 and `tab{doc}`.return_against IS NULL
|
||||||
|
and `tabGL Entry`.against_voucher_type = %(voucher_type)s
|
||||||
and `tab{doc}`.docstatus = 1 and `tabGL Entry`.party = %(party)s
|
and `tab{doc}`.docstatus = 1 and `tabGL Entry`.party = %(party)s
|
||||||
and `tabGL Entry`.party_type = %(party_type)s and `tabGL Entry`.account = %(account)s
|
and `tabGL Entry`.party_type = %(party_type)s and `tabGL Entry`.account = %(account)s
|
||||||
GROUP BY `tab{doc}`.name
|
GROUP BY `tab{doc}`.name
|
||||||
|
@ -18,13 +18,14 @@ from erpnext.accounts.general_ledger import make_gl_entries, merge_similar_entri
|
|||||||
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
|
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
|
||||||
from erpnext.buying.utils import check_on_hold_or_closed_status
|
from erpnext.buying.utils import check_on_hold_or_closed_status
|
||||||
from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center
|
from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center
|
||||||
from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_disabled
|
from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled
|
||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\
|
from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\
|
||||||
unlink_inter_company_doc
|
unlink_inter_company_doc
|
||||||
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
|
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
|
||||||
from erpnext.accounts.deferred_revenue import validate_service_stop_date
|
from erpnext.accounts.deferred_revenue import validate_service_stop_date
|
||||||
|
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import get_item_account_wise_additional_cost
|
||||||
|
|
||||||
form_grid_templates = {
|
form_grid_templates = {
|
||||||
"items": "templates/form_grid/item_grid.html"
|
"items": "templates/form_grid/item_grid.html"
|
||||||
@ -225,6 +226,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
# in case of auto inventory accounting,
|
# in case of auto inventory accounting,
|
||||||
# expense account is always "Stock Received But Not Billed" for a stock item
|
# expense account is always "Stock Received But Not Billed" for a stock item
|
||||||
# except epening entry, drop-ship entry and fixed asset items
|
# except epening entry, drop-ship entry and fixed asset items
|
||||||
|
if item.item_code:
|
||||||
|
asset_category = frappe.get_cached_value("Item", item.item_code, "asset_category")
|
||||||
|
|
||||||
if auto_accounting_for_stock and item.item_code in stock_items \
|
if auto_accounting_for_stock and item.item_code in stock_items \
|
||||||
and self.is_opening == 'No' and not item.is_fixed_asset \
|
and self.is_opening == 'No' and not item.is_fixed_asset \
|
||||||
@ -235,7 +238,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
item.expense_account = warehouse_account[item.warehouse]["account"]
|
item.expense_account = warehouse_account[item.warehouse]["account"]
|
||||||
else:
|
else:
|
||||||
item.expense_account = stock_not_billed_account
|
item.expense_account = stock_not_billed_account
|
||||||
elif item.is_fixed_asset and is_cwip_accounting_disabled():
|
|
||||||
|
elif item.is_fixed_asset and not is_cwip_accounting_enabled(self.company, asset_category):
|
||||||
if not item.asset:
|
if not item.asset:
|
||||||
frappe.throw(_("Row {0}: asset is required for item {1}")
|
frappe.throw(_("Row {0}: asset is required for item {1}")
|
||||||
.format(item.idx, item.item_code))
|
.format(item.idx, item.item_code))
|
||||||
@ -391,7 +395,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
self.make_supplier_gl_entry(gl_entries)
|
self.make_supplier_gl_entry(gl_entries)
|
||||||
self.make_item_gl_entries(gl_entries)
|
self.make_item_gl_entries(gl_entries)
|
||||||
if not is_cwip_accounting_disabled():
|
|
||||||
|
if self.check_asset_cwip_enabled():
|
||||||
self.get_asset_gl_entry(gl_entries)
|
self.get_asset_gl_entry(gl_entries)
|
||||||
|
|
||||||
self.make_tax_gl_entries(gl_entries)
|
self.make_tax_gl_entries(gl_entries)
|
||||||
@ -404,6 +409,15 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
return gl_entries
|
return gl_entries
|
||||||
|
|
||||||
|
def check_asset_cwip_enabled(self):
|
||||||
|
# Check if there exists any item with cwip accounting enabled in it's asset category
|
||||||
|
for item in self.get("items"):
|
||||||
|
if item.item_code and item.is_fixed_asset:
|
||||||
|
asset_category = frappe.get_cached_value("Item", item.item_code, "asset_category")
|
||||||
|
if is_cwip_accounting_enabled(self.company, asset_category):
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
def make_supplier_gl_entry(self, gl_entries):
|
def make_supplier_gl_entry(self, gl_entries):
|
||||||
# Checked both rounding_adjustment and rounded_total
|
# Checked both rounding_adjustment and rounded_total
|
||||||
# because rounded_total had value even before introcution of posting GLE based on rounded total
|
# because rounded_total had value even before introcution of posting GLE based on rounded total
|
||||||
@ -436,6 +450,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
if self.update_stock and self.auto_accounting_for_stock:
|
if self.update_stock and self.auto_accounting_for_stock:
|
||||||
warehouse_account = get_warehouse_account_map(self.company)
|
warehouse_account = get_warehouse_account_map(self.company)
|
||||||
|
|
||||||
|
landed_cost_entries = get_item_account_wise_additional_cost(self.name)
|
||||||
|
|
||||||
voucher_wise_stock_value = {}
|
voucher_wise_stock_value = {}
|
||||||
if self.update_stock:
|
if self.update_stock:
|
||||||
for d in frappe.get_all('Stock Ledger Entry',
|
for d in frappe.get_all('Stock Ledger Entry',
|
||||||
@ -445,6 +461,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
if flt(item.base_net_amount):
|
if flt(item.base_net_amount):
|
||||||
account_currency = get_account_currency(item.expense_account)
|
account_currency = get_account_currency(item.expense_account)
|
||||||
|
if item.item_code:
|
||||||
|
asset_category = frappe.get_cached_value("Item", item.item_code, "asset_category")
|
||||||
|
|
||||||
if self.update_stock and self.auto_accounting_for_stock and item.item_code in stock_items:
|
if self.update_stock and self.auto_accounting_for_stock and item.item_code in stock_items:
|
||||||
# warehouse account
|
# warehouse account
|
||||||
@ -463,15 +481,16 @@ class PurchaseInvoice(BuyingController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Amount added through landed-cost-voucher
|
# Amount added through landed-cost-voucher
|
||||||
if flt(item.landed_cost_voucher_amount):
|
if landed_cost_entries:
|
||||||
gl_entries.append(self.get_gl_dict({
|
for account, amount in iteritems(landed_cost_entries[(item.item_code, item.name)]):
|
||||||
"account": expenses_included_in_valuation,
|
gl_entries.append(self.get_gl_dict({
|
||||||
"against": item.expense_account,
|
"account": account,
|
||||||
"cost_center": item.cost_center,
|
"against": item.expense_account,
|
||||||
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
|
"cost_center": item.cost_center,
|
||||||
"credit": flt(item.landed_cost_voucher_amount),
|
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
|
||||||
"project": item.project
|
"credit": flt(amount),
|
||||||
}, item=item))
|
"project": item.project
|
||||||
|
}, item=item))
|
||||||
|
|
||||||
# sub-contracting warehouse
|
# sub-contracting warehouse
|
||||||
if flt(item.rm_supp_cost):
|
if flt(item.rm_supp_cost):
|
||||||
@ -486,8 +505,9 @@ class PurchaseInvoice(BuyingController):
|
|||||||
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
|
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
|
||||||
"credit": flt(item.rm_supp_cost)
|
"credit": flt(item.rm_supp_cost)
|
||||||
}, warehouse_account[self.supplier_warehouse]["account_currency"], item=item))
|
}, warehouse_account[self.supplier_warehouse]["account_currency"], item=item))
|
||||||
elif not item.is_fixed_asset or (item.is_fixed_asset and is_cwip_accounting_disabled()):
|
|
||||||
|
|
||||||
|
elif not item.is_fixed_asset or (item.is_fixed_asset and not is_cwip_accounting_enabled(self.company,
|
||||||
|
asset_category)):
|
||||||
expense_account = (item.expense_account
|
expense_account = (item.expense_account
|
||||||
if (not item.enable_deferred_expense or self.is_return) else item.deferred_expense_account)
|
if (not item.enable_deferred_expense or self.is_return) else item.deferred_expense_account)
|
||||||
|
|
||||||
@ -528,7 +548,10 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
def get_asset_gl_entry(self, gl_entries):
|
def get_asset_gl_entry(self, gl_entries):
|
||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
if item.is_fixed_asset:
|
if item.item_code and item.is_fixed_asset :
|
||||||
|
asset_category = frappe.get_cached_value("Item", item.item_code, "asset_category")
|
||||||
|
|
||||||
|
if item.is_fixed_asset and is_cwip_accounting_enabled(self.company, asset_category) :
|
||||||
eiiav_account = self.get_company_default("expenses_included_in_asset_valuation")
|
eiiav_account = self.get_company_default("expenses_included_in_asset_valuation")
|
||||||
|
|
||||||
asset_amount = flt(item.net_amount) + flt(item.item_tax_amount/self.conversion_rate)
|
asset_amount = flt(item.net_amount) + flt(item.item_tax_amount/self.conversion_rate)
|
||||||
|
@ -6,8 +6,8 @@ frappe.listview_settings['Purchase Invoice'] = {
|
|||||||
add_fields: ["supplier", "supplier_name", "base_grand_total", "outstanding_amount", "due_date", "company",
|
add_fields: ["supplier", "supplier_name", "base_grand_total", "outstanding_amount", "due_date", "company",
|
||||||
"currency", "is_return", "release_date", "on_hold"],
|
"currency", "is_return", "release_date", "on_hold"],
|
||||||
get_indicator: function(doc) {
|
get_indicator: function(doc) {
|
||||||
if(flt(doc.outstanding_amount) < 0 && doc.docstatus == 1) {
|
if( (flt(doc.outstanding_amount) <= 0) && doc.docstatus == 1 && doc.status == 'Debit Note Issued') {
|
||||||
return [__("Debit Note Issued"), "darkgrey", "outstanding_amount,<,0"]
|
return [__("Debit Note Issued"), "darkgrey", "outstanding_amount,<=,0"];
|
||||||
} else if(flt(doc.outstanding_amount) > 0 && doc.docstatus==1) {
|
} else if(flt(doc.outstanding_amount) > 0 && doc.docstatus==1) {
|
||||||
if(cint(doc.on_hold) && !doc.release_date) {
|
if(cint(doc.on_hold) && !doc.release_date) {
|
||||||
return [__("On Hold"), "darkgrey"];
|
return [__("On Hold"), "darkgrey"];
|
||||||
|
@ -991,10 +991,8 @@ class SalesInvoice(SellingController):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
for serial_no in item.serial_no.split("\n"):
|
for serial_no in item.serial_no.split("\n"):
|
||||||
if serial_no and frappe.db.exists('Serial No', serial_no):
|
if serial_no and frappe.db.get_value('Serial No', serial_no, 'item_code') == item.item_code:
|
||||||
sno = frappe.get_doc('Serial No', serial_no)
|
frappe.db.set_value('Serial No', serial_no, 'sales_invoice', invoice)
|
||||||
sno.sales_invoice = invoice
|
|
||||||
sno.db_update()
|
|
||||||
|
|
||||||
def validate_serial_numbers(self):
|
def validate_serial_numbers(self):
|
||||||
"""
|
"""
|
||||||
@ -1040,8 +1038,9 @@ class SalesInvoice(SellingController):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
for serial_no in item.serial_no.split("\n"):
|
for serial_no in item.serial_no.split("\n"):
|
||||||
sales_invoice = frappe.db.get_value("Serial No", serial_no, "sales_invoice")
|
sales_invoice, item_code = frappe.db.get_value("Serial No", serial_no,
|
||||||
if sales_invoice and self.name != sales_invoice:
|
["sales_invoice", "item_code"])
|
||||||
|
if sales_invoice and item_code == item.item_code and self.name != sales_invoice:
|
||||||
sales_invoice_company = frappe.db.get_value("Sales Invoice", sales_invoice, "company")
|
sales_invoice_company = frappe.db.get_value("Sales Invoice", sales_invoice, "company")
|
||||||
if sales_invoice_company == self.company:
|
if sales_invoice_company == self.company:
|
||||||
frappe.throw(_("Serial Number: {0} is already referenced in Sales Invoice: {1}"
|
frappe.throw(_("Serial Number: {0} is already referenced in Sales Invoice: {1}"
|
||||||
@ -1230,7 +1229,8 @@ class SalesInvoice(SellingController):
|
|||||||
self.status = "Unpaid and Discounted"
|
self.status = "Unpaid and Discounted"
|
||||||
elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) >= getdate(nowdate()):
|
elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) >= getdate(nowdate()):
|
||||||
self.status = "Unpaid"
|
self.status = "Unpaid"
|
||||||
elif flt(self.outstanding_amount) < 0 and self.is_return==0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
|
#Check if outstanding amount is 0 due to credit note issued against invoice
|
||||||
|
elif flt(self.outstanding_amount) <= 0 and self.is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
|
||||||
self.status = "Credit Note Issued"
|
self.status = "Credit Note Issued"
|
||||||
elif self.is_return == 1:
|
elif self.is_return == 1:
|
||||||
self.status = "Return"
|
self.status = "Return"
|
||||||
|
@ -21,6 +21,8 @@ frappe.ui.form.on('Share Transfer', {
|
|||||||
erpnext.share_transfer.make_jv(frm);
|
erpnext.share_transfer.make_jv(frm);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frm.toggle_reqd("asset_account", frm.doc.transfer_type != "Transfer");
|
||||||
},
|
},
|
||||||
no_of_shares: (frm) => {
|
no_of_shares: (frm) => {
|
||||||
if (frm.doc.rate != undefined || frm.doc.rate != null){
|
if (frm.doc.rate != undefined || frm.doc.rate != null){
|
||||||
@ -56,6 +58,10 @@ frappe.ui.form.on('Share Transfer', {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
transfer_type: function(frm) {
|
||||||
|
frm.toggle_reqd("asset_account", frm.doc.transfer_type != "Transfer");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,881 +1,239 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"autoname": "ACC-SHT-.YYYY.-.#####",
|
"autoname": "ACC-SHT-.YYYY.-.#####",
|
||||||
"beta": 0,
|
|
||||||
"creation": "2017-12-25 17:18:03.143726",
|
"creation": "2017-12-25 17:18:03.143726",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"transfer_type",
|
||||||
|
"column_break_1",
|
||||||
|
"date",
|
||||||
|
"section_break_1",
|
||||||
|
"from_shareholder",
|
||||||
|
"from_folio_no",
|
||||||
|
"column_break_3",
|
||||||
|
"to_shareholder",
|
||||||
|
"to_folio_no",
|
||||||
|
"section_break_10",
|
||||||
|
"equity_or_liability_account",
|
||||||
|
"column_break_12",
|
||||||
|
"asset_account",
|
||||||
|
"section_break_4",
|
||||||
|
"share_type",
|
||||||
|
"from_no",
|
||||||
|
"rate",
|
||||||
|
"column_break_8",
|
||||||
|
"no_of_shares",
|
||||||
|
"to_no",
|
||||||
|
"amount",
|
||||||
|
"section_break_11",
|
||||||
|
"company",
|
||||||
|
"section_break_6",
|
||||||
|
"remarks",
|
||||||
|
"amended_from"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "transfer_type",
|
"fieldname": "transfer_type",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Transfer Type",
|
"label": "Transfer Type",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "\nIssue\nPurchase\nTransfer",
|
"options": "\nIssue\nPurchase\nTransfer",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_1",
|
"fieldname": "column_break_1",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "date",
|
"fieldname": "date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Date",
|
"label": "Date",
|
||||||
"length": 0,
|
"reqd": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_1",
|
"fieldname": "section_break_1",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:doc.transfer_type != 'Issue'",
|
"depends_on": "eval:doc.transfer_type != 'Issue'",
|
||||||
"fieldname": "from_shareholder",
|
"fieldname": "from_shareholder",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "From Shareholder",
|
"label": "From Shareholder",
|
||||||
"length": 0,
|
"options": "Shareholder"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Shareholder",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:doc.transfer_type != 'Issue'",
|
"depends_on": "eval:doc.transfer_type != 'Issue'",
|
||||||
"fetch_from": "from_shareholder.folio_no",
|
"fetch_from": "from_shareholder.folio_no",
|
||||||
"fieldname": "from_folio_no",
|
"fieldname": "from_folio_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"label": "From Folio No"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "From Folio No",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:doc.company",
|
"depends_on": "eval:doc.company",
|
||||||
"fieldname": "equity_or_liability_account",
|
"fieldname": "equity_or_liability_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Equity/Liability Account",
|
"label": "Equity/Liability Account",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Account",
|
"options": "Account",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:(doc.transfer_type != 'Transfer') && (doc.company)",
|
"depends_on": "eval:(doc.transfer_type != 'Transfer') && (doc.company)",
|
||||||
"fieldname": "asset_account",
|
"fieldname": "asset_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Asset Account",
|
"label": "Asset Account",
|
||||||
"length": 0,
|
"options": "Account"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Account",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_3",
|
"fieldname": "column_break_3",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:doc.transfer_type != 'Purchase'",
|
"depends_on": "eval:doc.transfer_type != 'Purchase'",
|
||||||
"fieldname": "to_shareholder",
|
"fieldname": "to_shareholder",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "To Shareholder",
|
"label": "To Shareholder",
|
||||||
"length": 0,
|
"options": "Shareholder"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Shareholder",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:doc.transfer_type != 'Purchase'",
|
"depends_on": "eval:doc.transfer_type != 'Purchase'",
|
||||||
"fetch_from": "to_shareholder.folio_no",
|
"fetch_from": "to_shareholder.folio_no",
|
||||||
"fieldname": "to_folio_no",
|
"fieldname": "to_folio_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"label": "To Folio No"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "To Folio No",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_4",
|
"fieldname": "section_break_4",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "share_type",
|
"fieldname": "share_type",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Share Type",
|
"label": "Share Type",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Share Type",
|
"options": "Share Type",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"description": "(including)",
|
"description": "(including)",
|
||||||
"fieldname": "from_no",
|
"fieldname": "from_no",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "From No",
|
"label": "From No",
|
||||||
"length": 0,
|
"reqd": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "rate",
|
"fieldname": "rate",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Rate",
|
"label": "Rate",
|
||||||
"length": 0,
|
"reqd": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_8",
|
"fieldname": "column_break_8",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "no_of_shares",
|
"fieldname": "no_of_shares",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "No of Shares",
|
"label": "No of Shares",
|
||||||
"length": 0,
|
"reqd": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"description": "(including)",
|
"description": "(including)",
|
||||||
"fieldname": "to_no",
|
"fieldname": "to_no",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "To No",
|
"label": "To No",
|
||||||
"length": 0,
|
"reqd": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "amount",
|
"fieldname": "amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Amount",
|
"label": "Amount",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_11",
|
"fieldname": "section_break_11",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Company",
|
"label": "Company",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_6",
|
"fieldname": "section_break_6",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "remarks",
|
"fieldname": "remarks",
|
||||||
"fieldtype": "Long Text",
|
"fieldtype": "Long Text",
|
||||||
"hidden": 0,
|
"label": "Remarks"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Remarks",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Amended From",
|
"label": "Amended From",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Share Transfer",
|
"options": "Share Transfer",
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"print_hide_if_no_value": 0,
|
"read_only": 1
|
||||||
"read_only": 1,
|
},
|
||||||
"remember_last_selected_value": 0,
|
{
|
||||||
"report_hide": 0,
|
"fieldname": "section_break_10",
|
||||||
"reqd": 0,
|
"fieldtype": "Section Break"
|
||||||
"search_index": 0,
|
},
|
||||||
"set_only_once": 0,
|
{
|
||||||
"translatable": 0,
|
"fieldname": "column_break_12",
|
||||||
"unique": 0
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"issingle": 0,
|
"modified": "2019-11-07 13:31:17.999744",
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-09-18 14:14:46.233568",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Share Transfer",
|
"name": "Share Transfer",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "System Manager",
|
"role": "System Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Accounts User",
|
"role": "Accounts User",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Accounts Manager",
|
"role": "Accounts Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1,
|
"track_changes": 1
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
@ -163,19 +163,32 @@ def validate_account_for_perpetual_inventory(gl_map):
|
|||||||
.format(account), StockAccountInvalidTransaction)
|
.format(account), StockAccountInvalidTransaction)
|
||||||
|
|
||||||
elif account_bal != stock_bal:
|
elif account_bal != stock_bal:
|
||||||
frappe.throw(_("Account Balance ({0}) and Stock Value ({1}) is out of sync for account {2} and linked warehouse ({3}). Please create adjustment Journal Entry for amount {4}.")
|
error_reason = _("Account Balance ({0}) and Stock Value ({1}) is out of sync for account {2} and it's linked warehouses.").format(
|
||||||
.format(account_bal, stock_bal, account, comma_and(warehouse_list), stock_bal - account_bal),
|
account_bal, stock_bal, frappe.bold(account))
|
||||||
StockValueAndAccountBalanceOutOfSync)
|
error_resolution = _("Please create adjustment Journal Entry for amount {0} ").format(frappe.bold(stock_bal - account_bal))
|
||||||
|
button_text = _("Make Adjustment Entry")
|
||||||
|
|
||||||
|
frappe.throw("""{0}<br></br>{1}<br></br>
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<button class="btn btn-primary" onclick="frappe.new_doc('Journal Entry')">{2}</button>
|
||||||
|
</div>""".format(error_reason, error_resolution, button_text),
|
||||||
|
StockValueAndAccountBalanceOutOfSync, title=_('Account Balance Out Of Sync'))
|
||||||
|
|
||||||
def validate_cwip_accounts(gl_map):
|
def validate_cwip_accounts(gl_map):
|
||||||
if not cint(frappe.db.get_value("Asset Settings", None, "disable_cwip_accounting")) \
|
cwip_enabled = cint(frappe.get_cached_value("Company",
|
||||||
and gl_map[0].voucher_type == "Journal Entry":
|
gl_map[0].company, "enable_cwip_accounting"))
|
||||||
|
|
||||||
|
if not cwip_enabled:
|
||||||
|
cwip_enabled = any([cint(ac.enable_cwip_accounting) for ac in frappe.db.get_all("Asset Category","enable_cwip_accounting")])
|
||||||
|
|
||||||
|
if cwip_enabled and gl_map[0].voucher_type == "Journal Entry":
|
||||||
cwip_accounts = [d[0] for d in frappe.db.sql("""select name from tabAccount
|
cwip_accounts = [d[0] for d in frappe.db.sql("""select name from tabAccount
|
||||||
where account_type = 'Capital Work in Progress' and is_group=0""")]
|
where account_type = 'Capital Work in Progress' and is_group=0""")]
|
||||||
|
|
||||||
for entry in gl_map:
|
for entry in gl_map:
|
||||||
if entry.account in cwip_accounts:
|
if entry.account in cwip_accounts:
|
||||||
frappe.throw(_("Account: <b>{0}</b> is capital Work in progress and can not be updated by Journal Entry").format(entry.account))
|
frappe.throw(
|
||||||
|
_("Account: <b>{0}</b> is capital Work in progress and can not be updated by Journal Entry").format(entry.account))
|
||||||
|
|
||||||
def round_off_debit_credit(gl_map):
|
def round_off_debit_credit(gl_map):
|
||||||
precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"),
|
precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"),
|
||||||
|
@ -140,14 +140,10 @@ erpnext.accounts.bankTransactionUpload = class bankTransactionUpload {
|
|||||||
|
|
||||||
make() {
|
make() {
|
||||||
const me = this;
|
const me = this;
|
||||||
frappe.upload.make({
|
new frappe.ui.FileUploader({
|
||||||
args: {
|
method: 'erpnext.accounts.doctype.bank_transaction.bank_transaction_upload.upload_bank_statement',
|
||||||
method: 'erpnext.accounts.doctype.bank_transaction.bank_transaction_upload.upload_bank_statement',
|
allow_multiple: 0,
|
||||||
allow_multiple: 0
|
on_success: function(attachment, r) {
|
||||||
},
|
|
||||||
no_socketio: true,
|
|
||||||
sample_url: "e.g. http://example.com/somefile.csv",
|
|
||||||
callback: function(attachment, r) {
|
|
||||||
if (!r.exc && r.message) {
|
if (!r.exc && r.message) {
|
||||||
me.data = r.message;
|
me.data = r.message;
|
||||||
me.setup_transactions_dom();
|
me.setup_transactions_dom();
|
||||||
@ -533,9 +529,16 @@ erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
|||||||
frappe.db.get_doc(dt, event.value)
|
frappe.db.get_doc(dt, event.value)
|
||||||
.then(doc => {
|
.then(doc => {
|
||||||
let displayed_docs = []
|
let displayed_docs = []
|
||||||
|
let payment = []
|
||||||
if (dt === "Payment Entry") {
|
if (dt === "Payment Entry") {
|
||||||
payment.currency = doc.payment_type == "Receive" ? doc.paid_to_account_currency : doc.paid_from_account_currency;
|
payment.currency = doc.payment_type == "Receive" ? doc.paid_to_account_currency : doc.paid_from_account_currency;
|
||||||
payment.doctype = dt
|
payment.doctype = dt
|
||||||
|
payment.posting_date = doc.posting_date;
|
||||||
|
payment.party = doc.party;
|
||||||
|
payment.reference_no = doc.reference_no;
|
||||||
|
payment.reference_date = doc.reference_date;
|
||||||
|
payment.paid_amount = doc.paid_amount;
|
||||||
|
payment.name = doc.name;
|
||||||
displayed_docs.push(payment);
|
displayed_docs.push(payment);
|
||||||
} else if (dt === "Journal Entry") {
|
} else if (dt === "Journal Entry") {
|
||||||
doc.accounts.forEach(payment => {
|
doc.accounts.forEach(payment => {
|
||||||
@ -568,8 +571,8 @@ erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
|||||||
|
|
||||||
const details_wrapper = me.dialog.fields_dict.payment_details.$wrapper;
|
const details_wrapper = me.dialog.fields_dict.payment_details.$wrapper;
|
||||||
details_wrapper.append(frappe.render_template("linked_payment_header"));
|
details_wrapper.append(frappe.render_template("linked_payment_header"));
|
||||||
displayed_docs.forEach(values => {
|
displayed_docs.forEach(payment => {
|
||||||
details_wrapper.append(frappe.render_template("linked_payment_row", values));
|
details_wrapper.append(frappe.render_template("linked_payment_row", payment));
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -79,13 +79,20 @@ frappe.query_reports["Accounts Receivable"] = {
|
|||||||
"options": "Customer",
|
"options": "Customer",
|
||||||
on_change: () => {
|
on_change: () => {
|
||||||
var customer = frappe.query_report.get_filter_value('customer');
|
var customer = frappe.query_report.get_filter_value('customer');
|
||||||
|
var company = frappe.query_report.get_filter_value('company');
|
||||||
if (customer) {
|
if (customer) {
|
||||||
frappe.db.get_value('Customer', customer, ["tax_id", "customer_name", "credit_limit", "payment_terms"], function(value) {
|
frappe.db.get_value('Customer', customer, ["tax_id", "customer_name", "payment_terms"], function(value) {
|
||||||
frappe.query_report.set_filter_value('tax_id', value["tax_id"]);
|
frappe.query_report.set_filter_value('tax_id', value["tax_id"]);
|
||||||
frappe.query_report.set_filter_value('customer_name', value["customer_name"]);
|
frappe.query_report.set_filter_value('customer_name', value["customer_name"]);
|
||||||
frappe.query_report.set_filter_value('credit_limit', value["credit_limit"]);
|
|
||||||
frappe.query_report.set_filter_value('payment_terms', value["payment_terms"]);
|
frappe.query_report.set_filter_value('payment_terms', value["payment_terms"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.db.get_value('Customer Credit Limit', {'parent': customer, 'company': company},
|
||||||
|
["credit_limit"], function(value) {
|
||||||
|
if (value) {
|
||||||
|
frappe.query_report.set_filter_value('credit_limit', value["credit_limit"]);
|
||||||
|
}
|
||||||
|
}, "Customer");
|
||||||
} else {
|
} else {
|
||||||
frappe.query_report.set_filter_value('tax_id', "");
|
frappe.query_report.set_filter_value('tax_id', "");
|
||||||
frappe.query_report.set_filter_value('customer_name', "");
|
frappe.query_report.set_filter_value('customer_name', "");
|
||||||
|
@ -188,7 +188,11 @@ class ReceivablePayableReport(object):
|
|||||||
self.data.append(row)
|
self.data.append(row)
|
||||||
|
|
||||||
def set_invoice_details(self, row):
|
def set_invoice_details(self, row):
|
||||||
row.update(self.invoice_details.get(row.voucher_no, {}))
|
invoice_details = self.invoice_details.get(row.voucher_no, {})
|
||||||
|
if row.due_date:
|
||||||
|
invoice_details.pop("due_date", None)
|
||||||
|
row.update(invoice_details)
|
||||||
|
|
||||||
if row.voucher_type == 'Sales Invoice':
|
if row.voucher_type == 'Sales Invoice':
|
||||||
if self.filters.show_delivery_notes:
|
if self.filters.show_delivery_notes:
|
||||||
self.set_delivery_notes(row)
|
self.set_delivery_notes(row)
|
||||||
|
@ -36,6 +36,9 @@ class AccountsReceivableSummary(ReceivablePayableReport):
|
|||||||
self.filters.report_date) or {}
|
self.filters.report_date) or {}
|
||||||
|
|
||||||
for party, party_dict in iteritems(self.party_total):
|
for party, party_dict in iteritems(self.party_total):
|
||||||
|
if party_dict.outstanding <= 0:
|
||||||
|
continue
|
||||||
|
|
||||||
row = frappe._dict()
|
row = frappe._dict()
|
||||||
|
|
||||||
row.party = party
|
row.party = party
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
||||||
frappe.query_reports["Balance Sheet"] = erpnext.financial_statements;
|
frappe.query_reports["Balance Sheet"] = $.extend({}, erpnext.financial_statements);
|
||||||
|
|
||||||
frappe.query_reports["Balance Sheet"]["filters"].push({
|
frappe.query_reports["Balance Sheet"]["filters"].push({
|
||||||
"fieldname": "accumulated_values",
|
"fieldname": "accumulated_values",
|
||||||
|
@ -76,8 +76,7 @@ def get_data(filters):
|
|||||||
accumulate_values_into_parents(accounts, accounts_by_name)
|
accumulate_values_into_parents(accounts, accounts_by_name)
|
||||||
|
|
||||||
data = prepare_data(accounts, filters, total_row, parent_children_map, company_currency)
|
data = prepare_data(accounts, filters, total_row, parent_children_map, company_currency)
|
||||||
data = filter_out_zero_value_rows(data, parent_children_map,
|
data = filter_out_zero_value_rows(data, parent_children_map, show_zero_values=filters.get("show_zero_values"))
|
||||||
show_zero_values=filters.get("show_zero_values"))
|
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@ -187,33 +186,11 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
|
|||||||
|
|
||||||
d["closing_debit"] = d["opening_debit"] + d["debit"]
|
d["closing_debit"] = d["opening_debit"] + d["debit"]
|
||||||
d["closing_credit"] = d["opening_credit"] + d["credit"]
|
d["closing_credit"] = d["opening_credit"] + d["credit"]
|
||||||
total_row["debit"] += d["debit"]
|
|
||||||
total_row["credit"] += d["credit"]
|
|
||||||
|
|
||||||
if d["root_type"] == "Asset" or d["root_type"] == "Equity" or d["root_type"] == "Expense":
|
prepare_opening_closing(d)
|
||||||
d["opening_debit"] -= d["opening_credit"]
|
|
||||||
d["closing_debit"] -= d["closing_credit"]
|
|
||||||
|
|
||||||
# For opening
|
for field in value_fields:
|
||||||
check_opening_closing_has_negative_value(d, "opening_debit", "opening_credit")
|
total_row[field] += d[field]
|
||||||
|
|
||||||
# For closing
|
|
||||||
check_opening_closing_has_negative_value(d, "closing_debit", "closing_credit")
|
|
||||||
|
|
||||||
if d["root_type"] == "Liability" or d["root_type"] == "Income":
|
|
||||||
d["opening_credit"] -= d["opening_debit"]
|
|
||||||
d["closing_credit"] -= d["closing_debit"]
|
|
||||||
|
|
||||||
# For opening
|
|
||||||
check_opening_closing_has_negative_value(d, "opening_credit", "opening_debit")
|
|
||||||
|
|
||||||
# For closing
|
|
||||||
check_opening_closing_has_negative_value(d, "closing_credit", "closing_debit")
|
|
||||||
|
|
||||||
total_row["opening_debit"] += d["opening_debit"]
|
|
||||||
total_row["closing_debit"] += d["closing_debit"]
|
|
||||||
total_row["opening_credit"] += d["opening_credit"]
|
|
||||||
total_row["closing_credit"] += d["closing_credit"]
|
|
||||||
|
|
||||||
return total_row
|
return total_row
|
||||||
|
|
||||||
@ -227,6 +204,10 @@ def prepare_data(accounts, filters, total_row, parent_children_map, company_curr
|
|||||||
data = []
|
data = []
|
||||||
|
|
||||||
for d in accounts:
|
for d in accounts:
|
||||||
|
# Prepare opening closing for group account
|
||||||
|
if parent_children_map.get(d.account):
|
||||||
|
prepare_opening_closing(d)
|
||||||
|
|
||||||
has_value = False
|
has_value = False
|
||||||
row = {
|
row = {
|
||||||
"account": d.name,
|
"account": d.name,
|
||||||
@ -313,11 +294,16 @@ def get_columns():
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
def check_opening_closing_has_negative_value(d, dr_or_cr, switch_to_column):
|
def prepare_opening_closing(row):
|
||||||
# If opening debit has negetive value then move it to opening credit and vice versa.
|
dr_or_cr = "debit" if row["root_type"] in ["Asset", "Equity", "Expense"] else "credit"
|
||||||
|
reverse_dr_or_cr = "credit" if dr_or_cr == "debit" else "debit"
|
||||||
|
|
||||||
if d[dr_or_cr] < 0:
|
for col_type in ["opening", "closing"]:
|
||||||
d[switch_to_column] = abs(d[dr_or_cr])
|
valid_col = col_type + "_" + dr_or_cr
|
||||||
d[dr_or_cr] = 0.0
|
reverse_col = col_type + "_" + reverse_dr_or_cr
|
||||||
else:
|
row[valid_col] -= row[reverse_col]
|
||||||
d[switch_to_column] = 0.0
|
if row[valid_col] < 0:
|
||||||
|
row[reverse_col] = abs(row[valid_col])
|
||||||
|
row[valid_col] = 0.0
|
||||||
|
else:
|
||||||
|
row[reverse_col] = 0.0
|
@ -51,27 +51,25 @@ class CropCycle(Document):
|
|||||||
self.create_task(disease_doc.treatment_task, self.name, start_date)
|
self.create_task(disease_doc.treatment_task, self.name, start_date)
|
||||||
|
|
||||||
def create_project(self, period, crop_tasks):
|
def create_project(self, period, crop_tasks):
|
||||||
project = frappe.new_doc("Project")
|
project = frappe.get_doc({
|
||||||
project.update({
|
"doctype": "Project",
|
||||||
"project_name": self.title,
|
"project_name": self.title,
|
||||||
"expected_start_date": self.start_date,
|
"expected_start_date": self.start_date,
|
||||||
"expected_end_date": add_days(self.start_date, period - 1)
|
"expected_end_date": add_days(self.start_date, period - 1)
|
||||||
})
|
}).insert()
|
||||||
project.insert()
|
|
||||||
|
|
||||||
return project.name
|
return project.name
|
||||||
|
|
||||||
def create_task(self, crop_tasks, project_name, start_date):
|
def create_task(self, crop_tasks, project_name, start_date):
|
||||||
for crop_task in crop_tasks:
|
for crop_task in crop_tasks:
|
||||||
task = frappe.new_doc("Task")
|
frappe.get_doc({
|
||||||
task.update({
|
"doctype": "Task",
|
||||||
"subject": crop_task.get("task_name"),
|
"subject": crop_task.get("task_name"),
|
||||||
"priority": crop_task.get("priority"),
|
"priority": crop_task.get("priority"),
|
||||||
"project": project_name,
|
"project": project_name,
|
||||||
"exp_start_date": add_days(start_date, crop_task.get("start_day") - 1),
|
"exp_start_date": add_days(start_date, crop_task.get("start_day") - 1),
|
||||||
"exp_end_date": add_days(start_date, crop_task.get("end_day") - 1)
|
"exp_end_date": add_days(start_date, crop_task.get("end_day") - 1)
|
||||||
})
|
}).insert()
|
||||||
task.insert()
|
|
||||||
|
|
||||||
def reload_linked_analysis(self):
|
def reload_linked_analysis(self):
|
||||||
linked_doctypes = ['Soil Texture', 'Soil Analysis', 'Plant Analysis']
|
linked_doctypes = ['Soil Texture', 'Soil Analysis', 'Plant Analysis']
|
||||||
|
@ -203,7 +203,7 @@ frappe.ui.form.on('Asset', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
opening_accumulated_depreciation: function(frm) {
|
opening_accumulated_depreciation: function(frm) {
|
||||||
erpnext.asset.set_accululated_depreciation(frm);
|
erpnext.asset.set_accumulated_depreciation(frm);
|
||||||
},
|
},
|
||||||
|
|
||||||
make_schedules_editable: function(frm) {
|
make_schedules_editable: function(frm) {
|
||||||
@ -282,17 +282,6 @@ frappe.ui.form.on('Asset', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
calculate_depreciation: function(frm) {
|
calculate_depreciation: function(frm) {
|
||||||
frappe.db.get_value("Asset Settings", {'name':"Asset Settings"}, 'schedule_based_on_fiscal_year', (data) => {
|
|
||||||
if (data.schedule_based_on_fiscal_year == 1) {
|
|
||||||
frm.set_df_property("depreciation_method", "options", "\nStraight Line\nManual");
|
|
||||||
frm.toggle_reqd("available_for_use_date", true);
|
|
||||||
frm.toggle_display("frequency_of_depreciation", false);
|
|
||||||
frappe.db.get_value("Fiscal Year", {'name': frappe.sys_defaults.fiscal_year}, "year_end_date", (data) => {
|
|
||||||
frm.set_value("next_depreciation_date", data.year_end_date);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation);
|
frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -371,12 +360,12 @@ frappe.ui.form.on('Depreciation Schedule', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
depreciation_amount: function(frm, cdt, cdn) {
|
depreciation_amount: function(frm, cdt, cdn) {
|
||||||
erpnext.asset.set_accululated_depreciation(frm);
|
erpnext.asset.set_accumulated_depreciation(frm);
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
erpnext.asset.set_accululated_depreciation = function(frm) {
|
erpnext.asset.set_accumulated_depreciation = function(frm) {
|
||||||
if(frm.doc.depreciation_method != "Manual") return;
|
if(frm.doc.depreciation_method != "Manual") return;
|
||||||
|
|
||||||
var accumulated_depreciation = flt(frm.doc.opening_accumulated_depreciation);
|
var accumulated_depreciation = flt(frm.doc.opening_accumulated_depreciation);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe, erpnext, math, json
|
import frappe, erpnext, math, json
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from six import string_types
|
from six import string_types
|
||||||
from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff, add_days
|
from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff, month_diff, add_days
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
|
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
|
||||||
from erpnext.assets.doctype.asset.depreciation \
|
from erpnext.assets.doctype.asset.depreciation \
|
||||||
@ -30,7 +30,8 @@ class Asset(AccountsController):
|
|||||||
self.validate_in_use_date()
|
self.validate_in_use_date()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
self.update_stock_movement()
|
self.update_stock_movement()
|
||||||
if not self.booked_fixed_asset and not is_cwip_accounting_disabled():
|
if not self.booked_fixed_asset and is_cwip_accounting_enabled(self.company,
|
||||||
|
self.asset_category):
|
||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
@ -76,10 +77,13 @@ class Asset(AccountsController):
|
|||||||
self.set('finance_books', finance_books)
|
self.set('finance_books', finance_books)
|
||||||
|
|
||||||
def validate_asset_values(self):
|
def validate_asset_values(self):
|
||||||
|
if not self.asset_category:
|
||||||
|
self.asset_category = frappe.get_cached_value("Item", self.item_code, "asset_category")
|
||||||
|
|
||||||
if not flt(self.gross_purchase_amount):
|
if not flt(self.gross_purchase_amount):
|
||||||
frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
|
frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
|
||||||
|
|
||||||
if not is_cwip_accounting_disabled():
|
if is_cwip_accounting_enabled(self.company, self.asset_category):
|
||||||
if not self.is_existing_asset and not (self.purchase_receipt or self.purchase_invoice):
|
if not self.is_existing_asset and not (self.purchase_receipt or self.purchase_invoice):
|
||||||
frappe.throw(_("Please create purchase receipt or purchase invoice for the item {0}").
|
frappe.throw(_("Please create purchase receipt or purchase invoice for the item {0}").
|
||||||
format(self.item_code))
|
format(self.item_code))
|
||||||
@ -145,19 +149,31 @@ class Asset(AccountsController):
|
|||||||
schedule_date = add_months(d.depreciation_start_date,
|
schedule_date = add_months(d.depreciation_start_date,
|
||||||
n * cint(d.frequency_of_depreciation))
|
n * cint(d.frequency_of_depreciation))
|
||||||
|
|
||||||
|
# schedule date will be a year later from start date
|
||||||
|
# so monthly schedule date is calculated by removing 11 months from it
|
||||||
|
monthly_schedule_date = add_months(schedule_date, - d.frequency_of_depreciation + 1)
|
||||||
|
|
||||||
# For first row
|
# For first row
|
||||||
if has_pro_rata and n==0:
|
if has_pro_rata and n==0:
|
||||||
depreciation_amount, days = get_pro_rata_amt(d, depreciation_amount,
|
depreciation_amount, days, months = get_pro_rata_amt(d, depreciation_amount,
|
||||||
self.available_for_use_date, d.depreciation_start_date)
|
self.available_for_use_date, d.depreciation_start_date)
|
||||||
|
|
||||||
|
# For first depr schedule date will be the start date
|
||||||
|
# so monthly schedule date is calculated by removing month difference between use date and start date
|
||||||
|
monthly_schedule_date = add_months(d.depreciation_start_date, - months + 1)
|
||||||
|
|
||||||
# For last row
|
# For last row
|
||||||
elif has_pro_rata and n == cint(number_of_pending_depreciations) - 1:
|
elif has_pro_rata and n == cint(number_of_pending_depreciations) - 1:
|
||||||
to_date = add_months(self.available_for_use_date,
|
to_date = add_months(self.available_for_use_date,
|
||||||
n * cint(d.frequency_of_depreciation))
|
n * cint(d.frequency_of_depreciation))
|
||||||
|
|
||||||
depreciation_amount, days = get_pro_rata_amt(d,
|
depreciation_amount, days, months = get_pro_rata_amt(d,
|
||||||
depreciation_amount, schedule_date, to_date)
|
depreciation_amount, schedule_date, to_date)
|
||||||
|
|
||||||
|
monthly_schedule_date = add_months(schedule_date, 1)
|
||||||
|
|
||||||
schedule_date = add_days(schedule_date, days)
|
schedule_date = add_days(schedule_date, days)
|
||||||
|
last_schedule_date = schedule_date
|
||||||
|
|
||||||
if not depreciation_amount: continue
|
if not depreciation_amount: continue
|
||||||
value_after_depreciation -= flt(depreciation_amount,
|
value_after_depreciation -= flt(depreciation_amount,
|
||||||
@ -171,13 +187,50 @@ class Asset(AccountsController):
|
|||||||
skip_row = True
|
skip_row = True
|
||||||
|
|
||||||
if depreciation_amount > 0:
|
if depreciation_amount > 0:
|
||||||
self.append("schedules", {
|
# With monthly depreciation, each depreciation is divided by months remaining until next date
|
||||||
"schedule_date": schedule_date,
|
if self.allow_monthly_depreciation:
|
||||||
"depreciation_amount": depreciation_amount,
|
# month range is 1 to 12
|
||||||
"depreciation_method": d.depreciation_method,
|
# In pro rata case, for first and last depreciation, month range would be different
|
||||||
"finance_book": d.finance_book,
|
month_range = months \
|
||||||
"finance_book_id": d.idx
|
if (has_pro_rata and n==0) or (has_pro_rata and n == cint(number_of_pending_depreciations) - 1) \
|
||||||
})
|
else d.frequency_of_depreciation
|
||||||
|
|
||||||
|
for r in range(month_range):
|
||||||
|
if (has_pro_rata and n == 0):
|
||||||
|
# For first entry of monthly depr
|
||||||
|
if r == 0:
|
||||||
|
days_until_first_depr = date_diff(monthly_schedule_date, self.available_for_use_date)
|
||||||
|
per_day_amt = depreciation_amount / days
|
||||||
|
depreciation_amount_for_current_month = per_day_amt * days_until_first_depr
|
||||||
|
depreciation_amount -= depreciation_amount_for_current_month
|
||||||
|
date = monthly_schedule_date
|
||||||
|
amount = depreciation_amount_for_current_month
|
||||||
|
else:
|
||||||
|
date = add_months(monthly_schedule_date, r)
|
||||||
|
amount = depreciation_amount / (month_range - 1)
|
||||||
|
elif (has_pro_rata and n == cint(number_of_pending_depreciations) - 1) and r == cint(month_range) - 1:
|
||||||
|
# For last entry of monthly depr
|
||||||
|
date = last_schedule_date
|
||||||
|
amount = depreciation_amount / month_range
|
||||||
|
else:
|
||||||
|
date = add_months(monthly_schedule_date, r)
|
||||||
|
amount = depreciation_amount / month_range
|
||||||
|
|
||||||
|
self.append("schedules", {
|
||||||
|
"schedule_date": date,
|
||||||
|
"depreciation_amount": amount,
|
||||||
|
"depreciation_method": d.depreciation_method,
|
||||||
|
"finance_book": d.finance_book,
|
||||||
|
"finance_book_id": d.idx
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
self.append("schedules", {
|
||||||
|
"schedule_date": schedule_date,
|
||||||
|
"depreciation_amount": depreciation_amount,
|
||||||
|
"depreciation_method": d.depreciation_method,
|
||||||
|
"finance_book": d.finance_book,
|
||||||
|
"finance_book_id": d.idx
|
||||||
|
})
|
||||||
|
|
||||||
def check_is_pro_rata(self, row):
|
def check_is_pro_rata(self, row):
|
||||||
has_pro_rata = False
|
has_pro_rata = False
|
||||||
@ -424,7 +477,7 @@ def update_maintenance_status():
|
|||||||
asset.set_status('Out of Order')
|
asset.set_status('Out of Order')
|
||||||
|
|
||||||
def make_post_gl_entry():
|
def make_post_gl_entry():
|
||||||
if is_cwip_accounting_disabled():
|
if not is_cwip_accounting_enabled(self.company, self.asset_category):
|
||||||
return
|
return
|
||||||
|
|
||||||
assets = frappe.db.sql_list(""" select name from `tabAsset`
|
assets = frappe.db.sql_list(""" select name from `tabAsset`
|
||||||
@ -574,14 +627,20 @@ def make_journal_entry(asset_name):
|
|||||||
|
|
||||||
return je
|
return je
|
||||||
|
|
||||||
def is_cwip_accounting_disabled():
|
def is_cwip_accounting_enabled(company, asset_category=None):
|
||||||
return cint(frappe.db.get_single_value("Asset Settings", "disable_cwip_accounting"))
|
enable_cwip_in_company = cint(frappe.db.get_value("Company", company, "enable_cwip_accounting"))
|
||||||
|
|
||||||
|
if enable_cwip_in_company or not asset_category:
|
||||||
|
return enable_cwip_in_company
|
||||||
|
|
||||||
|
return cint(frappe.db.get_value("Asset Category", asset_category, "enable_cwip_accounting"))
|
||||||
|
|
||||||
def get_pro_rata_amt(row, depreciation_amount, from_date, to_date):
|
def get_pro_rata_amt(row, depreciation_amount, from_date, to_date):
|
||||||
days = date_diff(to_date, from_date)
|
days = date_diff(to_date, from_date)
|
||||||
|
months = month_diff(to_date, from_date)
|
||||||
total_days = get_total_days(to_date, row.frequency_of_depreciation)
|
total_days = get_total_days(to_date, row.frequency_of_depreciation)
|
||||||
|
|
||||||
return (depreciation_amount * flt(days)) / flt(total_days), days
|
return (depreciation_amount * flt(days)) / flt(total_days), days, months
|
||||||
|
|
||||||
def get_total_days(date, frequency):
|
def get_total_days(date, frequency):
|
||||||
period_start_date = add_months(date,
|
period_start_date = add_months(date,
|
||||||
|
@ -14,7 +14,6 @@ from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchas
|
|||||||
class TestAsset(unittest.TestCase):
|
class TestAsset(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
set_depreciation_settings_in_company()
|
set_depreciation_settings_in_company()
|
||||||
remove_prorated_depreciation_schedule()
|
|
||||||
create_asset_data()
|
create_asset_data()
|
||||||
frappe.db.sql("delete from `tabTax Rule`")
|
frappe.db.sql("delete from `tabTax Rule`")
|
||||||
|
|
||||||
@ -70,11 +69,13 @@ class TestAsset(unittest.TestCase):
|
|||||||
{"voucher_type": "Purchase Invoice", "voucher_no": pi.name}))
|
{"voucher_type": "Purchase Invoice", "voucher_no": pi.name}))
|
||||||
|
|
||||||
def test_is_fixed_asset_set(self):
|
def test_is_fixed_asset_set(self):
|
||||||
|
asset = create_asset(is_existing_asset = 1)
|
||||||
doc = frappe.new_doc('Purchase Invoice')
|
doc = frappe.new_doc('Purchase Invoice')
|
||||||
doc.supplier = '_Test Supplier'
|
doc.supplier = '_Test Supplier'
|
||||||
doc.append('items', {
|
doc.append('items', {
|
||||||
'item_code': 'Macbook Pro',
|
'item_code': 'Macbook Pro',
|
||||||
'qty': 1
|
'qty': 1,
|
||||||
|
'asset': asset.name
|
||||||
})
|
})
|
||||||
|
|
||||||
doc.set_missing_values()
|
doc.set_missing_values()
|
||||||
@ -200,7 +201,6 @@ class TestAsset(unittest.TestCase):
|
|||||||
self.assertEqual(schedules, expected_schedules)
|
self.assertEqual(schedules, expected_schedules)
|
||||||
|
|
||||||
def test_schedule_for_prorated_straight_line_method(self):
|
def test_schedule_for_prorated_straight_line_method(self):
|
||||||
set_prorated_depreciation_schedule()
|
|
||||||
pr = make_purchase_receipt(item_code="Macbook Pro",
|
pr = make_purchase_receipt(item_code="Macbook Pro",
|
||||||
qty=1, rate=100000.0, location="Test Location")
|
qty=1, rate=100000.0, location="Test Location")
|
||||||
|
|
||||||
@ -233,8 +233,6 @@ class TestAsset(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(schedules, expected_schedules)
|
self.assertEqual(schedules, expected_schedules)
|
||||||
|
|
||||||
remove_prorated_depreciation_schedule()
|
|
||||||
|
|
||||||
def test_depreciation(self):
|
def test_depreciation(self):
|
||||||
pr = make_purchase_receipt(item_code="Macbook Pro",
|
pr = make_purchase_receipt(item_code="Macbook Pro",
|
||||||
qty=1, rate=100000.0, location="Test Location")
|
qty=1, rate=100000.0, location="Test Location")
|
||||||
@ -487,6 +485,8 @@ class TestAsset(unittest.TestCase):
|
|||||||
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
|
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
|
||||||
make_purchase_invoice as make_purchase_invoice_from_pr)
|
make_purchase_invoice as make_purchase_invoice_from_pr)
|
||||||
|
|
||||||
|
#frappe.db.set_value("Asset Category","Computers","enable_cwip_accounting", 1)
|
||||||
|
|
||||||
pr = make_purchase_receipt(item_code="Macbook Pro",
|
pr = make_purchase_receipt(item_code="Macbook Pro",
|
||||||
qty=1, rate=5000, do_not_submit=True, location="Test Location")
|
qty=1, rate=5000, do_not_submit=True, location="Test Location")
|
||||||
|
|
||||||
@ -565,6 +565,7 @@ class TestAsset(unittest.TestCase):
|
|||||||
where voucher_type='Asset' and voucher_no = %s
|
where voucher_type='Asset' and voucher_no = %s
|
||||||
order by account""", asset_doc.name)
|
order by account""", asset_doc.name)
|
||||||
|
|
||||||
|
|
||||||
self.assertEqual(gle, expected_gle)
|
self.assertEqual(gle, expected_gle)
|
||||||
|
|
||||||
def test_expense_head(self):
|
def test_expense_head(self):
|
||||||
@ -575,7 +576,6 @@ class TestAsset(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEquals('Asset Received But Not Billed - _TC', doc.items[0].expense_account)
|
self.assertEquals('Asset Received But Not Billed - _TC', doc.items[0].expense_account)
|
||||||
|
|
||||||
|
|
||||||
def create_asset_data():
|
def create_asset_data():
|
||||||
if not frappe.db.exists("Asset Category", "Computers"):
|
if not frappe.db.exists("Asset Category", "Computers"):
|
||||||
create_asset_category()
|
create_asset_category()
|
||||||
@ -596,15 +596,15 @@ def create_asset(**args):
|
|||||||
|
|
||||||
asset = frappe.get_doc({
|
asset = frappe.get_doc({
|
||||||
"doctype": "Asset",
|
"doctype": "Asset",
|
||||||
"asset_name": "Macbook Pro 1",
|
"asset_name": args.asset_name or "Macbook Pro 1",
|
||||||
"asset_category": "Computers",
|
"asset_category": "Computers",
|
||||||
"item_code": "Macbook Pro",
|
"item_code": args.item_code or "Macbook Pro",
|
||||||
"company": "_Test Company",
|
"company": args.company or"_Test Company",
|
||||||
"purchase_date": "2015-01-01",
|
"purchase_date": "2015-01-01",
|
||||||
"calculate_depreciation": 0,
|
"calculate_depreciation": 0,
|
||||||
"gross_purchase_amount": 100000,
|
"gross_purchase_amount": 100000,
|
||||||
"expected_value_after_useful_life": 10000,
|
"expected_value_after_useful_life": 10000,
|
||||||
"warehouse": "_Test Warehouse - _TC",
|
"warehouse": args.warehouse or "_Test Warehouse - _TC",
|
||||||
"available_for_use_date": "2020-06-06",
|
"available_for_use_date": "2020-06-06",
|
||||||
"location": "Test Location",
|
"location": "Test Location",
|
||||||
"asset_owner": "Company",
|
"asset_owner": "Company",
|
||||||
@ -616,6 +616,9 @@ def create_asset(**args):
|
|||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if args.submit:
|
||||||
|
asset.submit()
|
||||||
|
|
||||||
return asset
|
return asset
|
||||||
|
|
||||||
def create_asset_category():
|
def create_asset_category():
|
||||||
@ -623,6 +626,7 @@ def create_asset_category():
|
|||||||
asset_category.asset_category_name = "Computers"
|
asset_category.asset_category_name = "Computers"
|
||||||
asset_category.total_number_of_depreciations = 3
|
asset_category.total_number_of_depreciations = 3
|
||||||
asset_category.frequency_of_depreciation = 3
|
asset_category.frequency_of_depreciation = 3
|
||||||
|
asset_category.enable_cwip_accounting = 1
|
||||||
asset_category.append("accounts", {
|
asset_category.append("accounts", {
|
||||||
"company_name": "_Test Company",
|
"company_name": "_Test Company",
|
||||||
"fixed_asset_account": "_Test Fixed Asset - _TC",
|
"fixed_asset_account": "_Test Fixed Asset - _TC",
|
||||||
@ -657,18 +661,3 @@ def set_depreciation_settings_in_company():
|
|||||||
|
|
||||||
# Enable booking asset depreciation entry automatically
|
# Enable booking asset depreciation entry automatically
|
||||||
frappe.db.set_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically", 1)
|
frappe.db.set_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically", 1)
|
||||||
|
|
||||||
def remove_prorated_depreciation_schedule():
|
|
||||||
asset_settings = frappe.get_doc("Asset Settings", "Asset Settings")
|
|
||||||
asset_settings.schedule_based_on_fiscal_year = 0
|
|
||||||
asset_settings.save()
|
|
||||||
|
|
||||||
frappe.db.commit()
|
|
||||||
|
|
||||||
def set_prorated_depreciation_schedule():
|
|
||||||
asset_settings = frappe.get_doc("Asset Settings", "Asset Settings")
|
|
||||||
asset_settings.schedule_based_on_fiscal_year = 1
|
|
||||||
asset_settings.number_of_days_in_fiscal_year = 360
|
|
||||||
asset_settings.save()
|
|
||||||
|
|
||||||
frappe.db.commit()
|
|
||||||
|
@ -1,284 +1,115 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "field:asset_category_name",
|
"autoname": "field:asset_category_name",
|
||||||
"beta": 0,
|
|
||||||
"creation": "2016-03-01 17:41:39.778765",
|
"creation": "2016-03-01 17:41:39.778765",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "Document",
|
||||||
"editable_grid": 0,
|
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"asset_category_name",
|
||||||
|
"column_break_3",
|
||||||
|
"depreciation_options",
|
||||||
|
"enable_cwip_accounting",
|
||||||
|
"finance_book_detail",
|
||||||
|
"finance_books",
|
||||||
|
"section_break_2",
|
||||||
|
"accounts"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "asset_category_name",
|
"fieldname": "asset_category_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Asset Category Name",
|
"label": "Asset Category Name",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"unique": 1
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_3",
|
"fieldname": "column_break_3",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "finance_book_detail",
|
"fieldname": "finance_book_detail",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Finance Book Detail"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Finance Book Detail",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "finance_books",
|
"fieldname": "finance_books",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Finance Books",
|
"label": "Finance Books",
|
||||||
"length": 0,
|
"options": "Asset Finance Book"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset Finance Book",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_2",
|
"fieldname": "section_break_2",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Accounts"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Accounts",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "accounts",
|
"fieldname": "accounts",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Accounts",
|
"label": "Accounts",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset Category Account",
|
"options": "Asset Category Account",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"precision": "",
|
},
|
||||||
"print_hide": 0,
|
{
|
||||||
"print_hide_if_no_value": 0,
|
"fieldname": "depreciation_options",
|
||||||
"read_only": 0,
|
"fieldtype": "Section Break",
|
||||||
"remember_last_selected_value": 0,
|
"label": "Depreciation Options"
|
||||||
"report_hide": 0,
|
},
|
||||||
"reqd": 1,
|
{
|
||||||
"search_index": 0,
|
"default": "0",
|
||||||
"set_only_once": 0,
|
"fieldname": "enable_cwip_accounting",
|
||||||
"unique": 0
|
"fieldtype": "Check",
|
||||||
|
"label": "Enable Capital Work in Progress Accounting"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"modified": "2019-10-11 12:19:59.759136",
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-05-12 14:56:04.116425",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset Category",
|
"name": "Asset Category",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 1,
|
"import": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Accounts User",
|
"role": "Accounts User",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 1,
|
"import": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Accounts Manager",
|
"role": "Accounts Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Quality Manager",
|
"role": "Quality Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC"
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
@ -10,11 +10,24 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
class AssetCategory(Document):
|
class AssetCategory(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
|
self.validate_finance_books()
|
||||||
|
self.validate_enable_cwip_accounting()
|
||||||
|
|
||||||
|
def validate_finance_books(self):
|
||||||
for d in self.finance_books:
|
for d in self.finance_books:
|
||||||
for field in ("Total Number of Depreciations", "Frequency of Depreciation"):
|
for field in ("Total Number of Depreciations", "Frequency of Depreciation"):
|
||||||
if cint(d.get(frappe.scrub(field)))<1:
|
if cint(d.get(frappe.scrub(field)))<1:
|
||||||
frappe.throw(_("Row {0}: {1} must be greater than 0").format(d.idx, field), frappe.MandatoryError)
|
frappe.throw(_("Row {0}: {1} must be greater than 0").format(d.idx, field), frappe.MandatoryError)
|
||||||
|
|
||||||
|
def validate_enable_cwip_accounting(self):
|
||||||
|
if self.enable_cwip_accounting :
|
||||||
|
for d in self.accounts:
|
||||||
|
cwip = frappe.db.get_value("Company",d.company_name,"enable_cwip_accounting")
|
||||||
|
if cwip:
|
||||||
|
frappe.throw(_
|
||||||
|
("CWIP is enabled globally in Company {1}. To enable it in Asset Category, first disable it in {1} ").format(
|
||||||
|
frappe.bold(d.idx), frappe.bold(d.company_name)))
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_asset_category_account(asset, fieldname, account=None, asset_category = None, company = None):
|
def get_asset_category_account(asset, fieldname, account=None, asset_category = None, company = None):
|
||||||
if not asset_category and company:
|
if not asset_category and company:
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
frappe.ui.form.on('Asset Settings', {
|
|
||||||
});
|
|
@ -1,148 +0,0 @@
|
|||||||
{
|
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2018-01-03 10:30:32.983381",
|
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
|
||||||
"engine": "InnoDB",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "depreciation_options",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Depreciation Options",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "disable_cwip_accounting",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Disable CWIP Accounting",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 1,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2019-05-26 18:31:19.930563",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Assets",
|
|
||||||
"name": "Asset Settings",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
|
||||||
{
|
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 0,
|
|
||||||
"role": "System Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 0,
|
|
||||||
"role": "Accounts Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
from frappe.model.document import Document
|
|
||||||
|
|
||||||
class AssetSettings(Document):
|
|
||||||
pass
|
|
@ -1,23 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
// rename this file from _test_[name] to test_[name] to activate
|
|
||||||
// and remove above this line
|
|
||||||
|
|
||||||
QUnit.test("test: Asset Settings", function (assert) {
|
|
||||||
let done = assert.async();
|
|
||||||
|
|
||||||
// number of asserts
|
|
||||||
assert.expect(1);
|
|
||||||
|
|
||||||
frappe.run_serially([
|
|
||||||
// insert a new Asset Settings
|
|
||||||
() => frappe.tests.make('Asset Settings', [
|
|
||||||
// values to be set
|
|
||||||
{key: 'value'}
|
|
||||||
]),
|
|
||||||
() => {
|
|
||||||
assert.equal(cur_frm.doc.key, 'value');
|
|
||||||
},
|
|
||||||
() => done()
|
|
||||||
]);
|
|
||||||
|
|
||||||
});
|
|
@ -1,9 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# See license.txt
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
class TestAssetSettings(unittest.TestCase):
|
|
||||||
pass
|
|
@ -134,7 +134,7 @@ frappe.ui.form.on("Request for Quotation",{
|
|||||||
if (args.search_type === "Tag" && args.tag) {
|
if (args.search_type === "Tag" && args.tag) {
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
method: "frappe.desk.tags.get_tagged_docs",
|
method: "frappe.desk.doctype.tag.tag.get_tagged_docs",
|
||||||
args: {
|
args: {
|
||||||
"doctype": "Supplier",
|
"doctype": "Supplier",
|
||||||
"tag": args.tag
|
"tag": args.tag
|
||||||
|
@ -344,13 +344,9 @@ def get_item_from_material_requests_based_on_supplier(source_name, target_doc =
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_supplier_tag():
|
def get_supplier_tag():
|
||||||
data = frappe.db.sql("select _user_tags from `tabSupplier`")
|
if not frappe.cache().hget("Supplier", "Tags"):
|
||||||
|
filters = {"document_type": "Supplier"}
|
||||||
tags = []
|
tags = list(set([tag.tag for tag in frappe.get_all("Tag Link", filters=filters, fields=["tag"]) if tag]))
|
||||||
for tag in data:
|
frappe.cache().hset("Supplier", "Tags", tags)
|
||||||
tags += filter(bool, tag[0].split(","))
|
|
||||||
|
|
||||||
tags = list(set(tags))
|
|
||||||
|
|
||||||
return tags
|
|
||||||
|
|
||||||
|
return frappe.cache().hget("Supplier", "Tags")
|
||||||
|
@ -21,10 +21,6 @@ def get_data():
|
|||||||
"name": "Asset Category",
|
"name": "Asset Category",
|
||||||
"onboard": 1,
|
"onboard": 1,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Asset Settings",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Asset Movement",
|
"name": "Asset Movement",
|
||||||
|
@ -1193,8 +1193,9 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
frappe.throw(_("Cannot set quantity less than received quantity"))
|
frappe.throw(_("Cannot set quantity less than received quantity"))
|
||||||
|
|
||||||
child_item.qty = flt(d.get("qty"))
|
child_item.qty = flt(d.get("qty"))
|
||||||
|
precision = child_item.precision("rate") or 2
|
||||||
|
|
||||||
if flt(child_item.billed_amt) > (flt(d.get("rate")) * flt(d.get("qty"))):
|
if flt(child_item.billed_amt, precision) > flt(flt(d.get("rate")) * flt(d.get("qty")), precision):
|
||||||
frappe.throw(_("Row #{0}: Cannot set Rate if amount is greater than billed amount for Item {1}.")
|
frappe.throw(_("Row #{0}: Cannot set Rate if amount is greater than billed amount for Item {1}.")
|
||||||
.format(child_item.idx, child_item.item_code))
|
.format(child_item.idx, child_item.item_code))
|
||||||
else:
|
else:
|
||||||
|
@ -49,7 +49,8 @@ status_map = {
|
|||||||
["Submitted", "eval:self.docstatus==1"],
|
["Submitted", "eval:self.docstatus==1"],
|
||||||
["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
|
["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
|
||||||
["Return", "eval:self.is_return==1 and self.docstatus==1"],
|
["Return", "eval:self.is_return==1 and self.docstatus==1"],
|
||||||
["Debit Note Issued", "eval:self.outstanding_amount < 0 and self.docstatus==1"],
|
["Debit Note Issued",
|
||||||
|
"eval:self.outstanding_amount <= 0 and self.docstatus==1 and self.is_return==0 and get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1})"],
|
||||||
["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
|
["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
|
||||||
["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
|
["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
|
||||||
["Cancelled", "eval:self.docstatus==2"],
|
["Cancelled", "eval:self.docstatus==2"],
|
||||||
@ -118,7 +119,6 @@ class StatusUpdater(Document):
|
|||||||
|
|
||||||
if self.doctype in status_map:
|
if self.doctype in status_map:
|
||||||
_status = self.status
|
_status = self.status
|
||||||
|
|
||||||
if status and update:
|
if status and update:
|
||||||
self.db_set("status", status)
|
self.db_set("status", status)
|
||||||
|
|
||||||
|
@ -52,7 +52,8 @@
|
|||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Email Campaign For ",
|
"label": "Email Campaign For ",
|
||||||
"options": "\nLead\nContact"
|
"options": "\nLead\nContact",
|
||||||
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "recipient",
|
"fieldname": "recipient",
|
||||||
@ -69,7 +70,7 @@
|
|||||||
"options": "User"
|
"options": "User"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2019-07-12 13:47:37.261213",
|
"modified": "2019-11-11 17:18:47.342839",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Email Campaign",
|
"name": "Email Campaign",
|
||||||
|
@ -73,13 +73,13 @@ def send_mail(entry, email_campaign):
|
|||||||
|
|
||||||
email_template = frappe.get_doc("Email Template", entry.get("email_template"))
|
email_template = frappe.get_doc("Email Template", entry.get("email_template"))
|
||||||
sender = frappe.db.get_value("User", email_campaign.get("sender"), 'email')
|
sender = frappe.db.get_value("User", email_campaign.get("sender"), 'email')
|
||||||
|
context = {"doc": frappe.get_doc(email_campaign.email_campaign_for, email_campaign.recipient)}
|
||||||
# send mail and link communication to document
|
# send mail and link communication to document
|
||||||
comm = make(
|
comm = make(
|
||||||
doctype = "Email Campaign",
|
doctype = "Email Campaign",
|
||||||
name = email_campaign.name,
|
name = email_campaign.name,
|
||||||
subject = email_template.get("subject"),
|
subject = email_template.get("subject"),
|
||||||
content = email_template.get("response"),
|
content = frappe.render_template(email_template.get("response"), context),
|
||||||
sender = sender,
|
sender = sender,
|
||||||
recipients = recipient,
|
recipients = recipient,
|
||||||
communication_medium = "Email",
|
communication_medium = "Email",
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"validate_batch",
|
"validate_batch",
|
||||||
"validate_course",
|
"validate_course",
|
||||||
"academic_term_reqd",
|
"academic_term_reqd",
|
||||||
|
"user_creation_skip",
|
||||||
"section_break_7",
|
"section_break_7",
|
||||||
"instructor_created_by",
|
"instructor_created_by",
|
||||||
"web_academy_settings_section",
|
"web_academy_settings_section",
|
||||||
@ -91,6 +92,13 @@
|
|||||||
"fieldname": "enable_lms",
|
"fieldname": "enable_lms",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Enable LMS"
|
"label": "Enable LMS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"description": "By default, a new User is created for every new Student. If enabled, no new User will be created when a new Student is created.",
|
||||||
|
"fieldname": "user_creation_skip",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Skip User creation for new Student"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
|
@ -40,7 +40,8 @@ class Student(Document):
|
|||||||
frappe.throw(_("Student {0} exist against student applicant {1}").format(student[0][0], self.student_applicant))
|
frappe.throw(_("Student {0} exist against student applicant {1}").format(student[0][0], self.student_applicant))
|
||||||
|
|
||||||
def after_insert(self):
|
def after_insert(self):
|
||||||
self.create_student_user()
|
if not frappe.get_single('Education Settings').user_creation_skip:
|
||||||
|
self.create_student_user()
|
||||||
|
|
||||||
def create_student_user(self):
|
def create_student_user(self):
|
||||||
"""Create a website user for student creation if not already exists"""
|
"""Create a website user for student creation if not already exists"""
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, base64, hashlib, hmac, json
|
import frappe, base64, hashlib, hmac, json
|
||||||
import datetime
|
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
|
||||||
|
|
||||||
def verify_request():
|
def verify_request():
|
||||||
woocommerce_settings = frappe.get_doc("Woocommerce Settings")
|
woocommerce_settings = frappe.get_doc("Woocommerce Settings")
|
||||||
sig = base64.b64encode(
|
sig = base64.b64encode(
|
||||||
@ -30,191 +28,149 @@ def order(*args, **kwargs):
|
|||||||
frappe.log_error(error_message, "WooCommerce Error")
|
frappe.log_error(error_message, "WooCommerce Error")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def _order(*args, **kwargs):
|
def _order(*args, **kwargs):
|
||||||
woocommerce_settings = frappe.get_doc("Woocommerce Settings")
|
woocommerce_settings = frappe.get_doc("Woocommerce Settings")
|
||||||
if frappe.flags.woocomm_test_order_data:
|
if frappe.flags.woocomm_test_order_data:
|
||||||
fd = frappe.flags.woocomm_test_order_data
|
order = frappe.flags.woocomm_test_order_data
|
||||||
event = "created"
|
event = "created"
|
||||||
|
|
||||||
elif frappe.request and frappe.request.data:
|
elif frappe.request and frappe.request.data:
|
||||||
verify_request()
|
verify_request()
|
||||||
fd = json.loads(frappe.request.data)
|
try:
|
||||||
|
order = json.loads(frappe.request.data)
|
||||||
|
except ValueError:
|
||||||
|
#woocommerce returns 'webhook_id=value' for the first request which is not JSON
|
||||||
|
order = frappe.request.data
|
||||||
event = frappe.get_request_header("X-Wc-Webhook-Event")
|
event = frappe.get_request_header("X-Wc-Webhook-Event")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return "success"
|
return "success"
|
||||||
|
|
||||||
if event == "created":
|
if event == "created":
|
||||||
raw_billing_data = fd.get("billing")
|
raw_billing_data = order.get("billing")
|
||||||
customer_woo_com_email = raw_billing_data.get("email")
|
|
||||||
|
|
||||||
if frappe.get_value("Customer",{"woocommerce_email": customer_woo_com_email}):
|
|
||||||
# Edit
|
|
||||||
link_customer_and_address(raw_billing_data,1)
|
|
||||||
else:
|
|
||||||
# Create
|
|
||||||
link_customer_and_address(raw_billing_data,0)
|
|
||||||
|
|
||||||
|
|
||||||
items_list = fd.get("line_items")
|
|
||||||
for item in items_list:
|
|
||||||
|
|
||||||
item_woo_com_id = item.get("product_id")
|
|
||||||
|
|
||||||
if frappe.get_value("Item",{"woocommerce_id": item_woo_com_id}):
|
|
||||||
#Edit
|
|
||||||
link_item(item,1)
|
|
||||||
else:
|
|
||||||
link_item(item,0)
|
|
||||||
|
|
||||||
|
|
||||||
customer_name = raw_billing_data.get("first_name") + " " + raw_billing_data.get("last_name")
|
customer_name = raw_billing_data.get("first_name") + " " + raw_billing_data.get("last_name")
|
||||||
|
link_customer_and_address(raw_billing_data, customer_name)
|
||||||
|
link_items(order.get("line_items"), woocommerce_settings)
|
||||||
|
create_sales_order(order, woocommerce_settings, customer_name)
|
||||||
|
|
||||||
new_sales_order = frappe.new_doc("Sales Order")
|
def link_customer_and_address(raw_billing_data, customer_name):
|
||||||
new_sales_order.customer = customer_name
|
customer_woo_com_email = raw_billing_data.get("email")
|
||||||
|
customer_exists = frappe.get_value("Customer", {"woocommerce_email": customer_woo_com_email})
|
||||||
created_date = fd.get("date_created").split("T")
|
if not customer_exists:
|
||||||
new_sales_order.transaction_date = created_date[0]
|
# Create Customer
|
||||||
|
|
||||||
new_sales_order.po_no = fd.get("id")
|
|
||||||
new_sales_order.woocommerce_id = fd.get("id")
|
|
||||||
new_sales_order.naming_series = woocommerce_settings.sales_order_series or "SO-WOO-"
|
|
||||||
|
|
||||||
placed_order_date = created_date[0]
|
|
||||||
raw_date = datetime.datetime.strptime(placed_order_date, "%Y-%m-%d")
|
|
||||||
raw_delivery_date = frappe.utils.add_to_date(raw_date,days = 7)
|
|
||||||
order_delivery_date_str = raw_delivery_date.strftime('%Y-%m-%d')
|
|
||||||
order_delivery_date = str(order_delivery_date_str)
|
|
||||||
|
|
||||||
new_sales_order.delivery_date = order_delivery_date
|
|
||||||
default_set_company = frappe.get_doc("Global Defaults")
|
|
||||||
company = raw_billing_data.get("company") or default_set_company.default_company
|
|
||||||
found_company = frappe.get_doc("Company",{"name":company})
|
|
||||||
company_abbr = found_company.abbr
|
|
||||||
|
|
||||||
new_sales_order.company = company
|
|
||||||
|
|
||||||
for item in items_list:
|
|
||||||
woocomm_item_id = item.get("product_id")
|
|
||||||
found_item = frappe.get_doc("Item",{"woocommerce_id": woocomm_item_id})
|
|
||||||
|
|
||||||
ordered_items_tax = item.get("total_tax")
|
|
||||||
|
|
||||||
new_sales_order.append("items",{
|
|
||||||
"item_code": found_item.item_code,
|
|
||||||
"item_name": found_item.item_name,
|
|
||||||
"description": found_item.item_name,
|
|
||||||
"delivery_date":order_delivery_date,
|
|
||||||
"uom": woocommerce_settings.uom or _("Nos"),
|
|
||||||
"qty": item.get("quantity"),
|
|
||||||
"rate": item.get("price"),
|
|
||||||
"warehouse": woocommerce_settings.warehouse or "Stores" + " - " + company_abbr
|
|
||||||
})
|
|
||||||
|
|
||||||
add_tax_details(new_sales_order,ordered_items_tax,"Ordered Item tax",0)
|
|
||||||
|
|
||||||
# shipping_details = fd.get("shipping_lines") # used for detailed order
|
|
||||||
shipping_total = fd.get("shipping_total")
|
|
||||||
shipping_tax = fd.get("shipping_tax")
|
|
||||||
|
|
||||||
add_tax_details(new_sales_order,shipping_tax,"Shipping Tax",1)
|
|
||||||
add_tax_details(new_sales_order,shipping_total,"Shipping Total",1)
|
|
||||||
|
|
||||||
new_sales_order.submit()
|
|
||||||
|
|
||||||
frappe.db.commit()
|
|
||||||
|
|
||||||
def link_customer_and_address(raw_billing_data,customer_status):
|
|
||||||
|
|
||||||
if customer_status == 0:
|
|
||||||
# create
|
|
||||||
customer = frappe.new_doc("Customer")
|
customer = frappe.new_doc("Customer")
|
||||||
address = frappe.new_doc("Address")
|
else:
|
||||||
|
# Edit Customer
|
||||||
if customer_status == 1:
|
customer = frappe.get_doc("Customer", {"woocommerce_email": customer_woo_com_email})
|
||||||
# Edit
|
|
||||||
customer_woo_com_email = raw_billing_data.get("email")
|
|
||||||
customer = frappe.get_doc("Customer",{"woocommerce_email": customer_woo_com_email})
|
|
||||||
old_name = customer.customer_name
|
old_name = customer.customer_name
|
||||||
|
|
||||||
full_name = str(raw_billing_data.get("first_name"))+ " "+str(raw_billing_data.get("last_name"))
|
customer.customer_name = customer_name
|
||||||
customer.customer_name = full_name
|
customer.woocommerce_email = customer_woo_com_email
|
||||||
customer.woocommerce_email = str(raw_billing_data.get("email"))
|
customer.flags.ignore_mandatory = True
|
||||||
customer.save()
|
customer.save()
|
||||||
frappe.db.commit()
|
|
||||||
|
|
||||||
if customer_status == 1:
|
if customer_exists:
|
||||||
frappe.rename_doc("Customer", old_name, full_name)
|
frappe.rename_doc("Customer", old_name, customer_name)
|
||||||
address = frappe.get_doc("Address",{"woocommerce_email":customer_woo_com_email})
|
address = frappe.get_doc("Address", {"woocommerce_email": customer_woo_com_email})
|
||||||
customer = frappe.get_doc("Customer",{"woocommerce_email": customer_woo_com_email})
|
else:
|
||||||
|
address = frappe.new_doc("Address")
|
||||||
|
|
||||||
address.address_line1 = raw_billing_data.get("address_1", "Not Provided")
|
address.address_line1 = raw_billing_data.get("address_1", "Not Provided")
|
||||||
address.address_line2 = raw_billing_data.get("address_2", "Not Provided")
|
address.address_line2 = raw_billing_data.get("address_2", "Not Provided")
|
||||||
address.city = raw_billing_data.get("city", "Not Provided")
|
address.city = raw_billing_data.get("city", "Not Provided")
|
||||||
address.woocommerce_email = str(raw_billing_data.get("email"))
|
address.woocommerce_email = customer_woo_com_email
|
||||||
address.address_type = "Shipping"
|
address.address_type = "Billing"
|
||||||
address.country = frappe.get_value("Country", filters={"code":raw_billing_data.get("country", "IN").lower()})
|
address.country = frappe.get_value("Country", {"code": raw_billing_data.get("country", "IN").lower()})
|
||||||
address.state = raw_billing_data.get("state")
|
address.state = raw_billing_data.get("state")
|
||||||
address.pincode = str(raw_billing_data.get("postcode"))
|
address.pincode = raw_billing_data.get("postcode")
|
||||||
address.phone = str(raw_billing_data.get("phone"))
|
address.phone = raw_billing_data.get("phone")
|
||||||
address.email_id = str(raw_billing_data.get("email"))
|
address.email_id = customer_woo_com_email
|
||||||
|
|
||||||
address.append("links", {
|
address.append("links", {
|
||||||
"link_doctype": "Customer",
|
"link_doctype": "Customer",
|
||||||
"link_name": customer.customer_name
|
"link_name": customer.customer_name
|
||||||
})
|
})
|
||||||
|
address.flags.ignore_mandatory = True
|
||||||
|
address = address.save()
|
||||||
|
|
||||||
address.save()
|
if customer_exists:
|
||||||
frappe.db.commit()
|
|
||||||
|
|
||||||
if customer_status == 1:
|
|
||||||
|
|
||||||
address = frappe.get_doc("Address",{"woocommerce_email":customer_woo_com_email})
|
|
||||||
old_address_title = address.name
|
old_address_title = address.name
|
||||||
new_address_title = customer.customer_name+"-billing"
|
new_address_title = customer.customer_name + "-billing"
|
||||||
address.address_title = customer.customer_name
|
address.address_title = customer.customer_name
|
||||||
address.save()
|
address.save()
|
||||||
|
|
||||||
frappe.rename_doc("Address",old_address_title,new_address_title)
|
frappe.rename_doc("Address", old_address_title, new_address_title)
|
||||||
|
|
||||||
frappe.db.commit()
|
def link_items(items_list, woocommerce_settings):
|
||||||
|
for item_data in items_list:
|
||||||
def link_item(item_data,item_status):
|
|
||||||
woocommerce_settings = frappe.get_doc("Woocommerce Settings")
|
|
||||||
|
|
||||||
if item_status == 0:
|
|
||||||
#Create Item
|
|
||||||
item = frappe.new_doc("Item")
|
|
||||||
|
|
||||||
if item_status == 1:
|
|
||||||
#Edit Item
|
|
||||||
item_woo_com_id = item_data.get("product_id")
|
item_woo_com_id = item_data.get("product_id")
|
||||||
item = frappe.get_doc("Item",{"woocommerce_id": item_woo_com_id})
|
|
||||||
|
|
||||||
item.item_name = str(item_data.get("name"))
|
if frappe.get_value("Item", {"woocommerce_id": item_woo_com_id}):
|
||||||
item.item_code = "woocommerce - " + str(item_data.get("product_id"))
|
#Edit Item
|
||||||
item.woocommerce_id = str(item_data.get("product_id"))
|
item = frappe.get_doc("Item", {"woocommerce_id": item_woo_com_id})
|
||||||
item.item_group = _("WooCommerce Products")
|
else:
|
||||||
item.stock_uom = woocommerce_settings.uom or _("Nos")
|
#Create Item
|
||||||
item.save()
|
item = frappe.new_doc("Item")
|
||||||
|
|
||||||
|
item.item_name = item_data.get("name")
|
||||||
|
item.item_code = _("woocommerce - {0}").format(item_data.get("product_id"))
|
||||||
|
item.woocommerce_id = item_data.get("product_id")
|
||||||
|
item.item_group = _("WooCommerce Products")
|
||||||
|
item.stock_uom = woocommerce_settings.uom or _("Nos")
|
||||||
|
item.flags.ignore_mandatory = True
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
def create_sales_order(order, woocommerce_settings, customer_name):
|
||||||
|
new_sales_order = frappe.new_doc("Sales Order")
|
||||||
|
new_sales_order.customer = customer_name
|
||||||
|
|
||||||
|
new_sales_order.po_no = new_sales_order.woocommerce_id = order.get("id")
|
||||||
|
new_sales_order.naming_series = woocommerce_settings.sales_order_series or "SO-WOO-"
|
||||||
|
|
||||||
|
created_date = order.get("date_created").split("T")
|
||||||
|
new_sales_order.transaction_date = created_date[0]
|
||||||
|
delivery_after = woocommerce_settings.delivery_after_days or 7
|
||||||
|
new_sales_order.delivery_date = frappe.utils.add_days(created_date[0], delivery_after)
|
||||||
|
|
||||||
|
new_sales_order.company = woocommerce_settings.company
|
||||||
|
|
||||||
|
set_items_in_sales_order(new_sales_order, woocommerce_settings, order)
|
||||||
|
new_sales_order.flags.ignore_mandatory = True
|
||||||
|
new_sales_order.insert()
|
||||||
|
new_sales_order.submit()
|
||||||
|
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
def add_tax_details(sales_order,price,desc,status):
|
def set_items_in_sales_order(new_sales_order, woocommerce_settings, order):
|
||||||
|
company_abbr = frappe.db.get_value('Company', woocommerce_settings.company, 'abbr')
|
||||||
|
|
||||||
woocommerce_settings = frappe.get_doc("Woocommerce Settings")
|
for item in order.get("line_items"):
|
||||||
|
woocomm_item_id = item.get("product_id")
|
||||||
|
found_item = frappe.get_doc("Item", {"woocommerce_id": woocomm_item_id})
|
||||||
|
|
||||||
if status == 0:
|
ordered_items_tax = item.get("total_tax")
|
||||||
# Product taxes
|
|
||||||
account_head_type = woocommerce_settings.tax_account
|
|
||||||
|
|
||||||
if status == 1:
|
new_sales_order.append("items",{
|
||||||
# Shipping taxes
|
"item_code": found_item.item_code,
|
||||||
account_head_type = woocommerce_settings.f_n_f_account
|
"item_name": found_item.item_name,
|
||||||
|
"description": found_item.item_name,
|
||||||
|
"delivery_date": new_sales_order.delivery_date,
|
||||||
|
"uom": woocommerce_settings.uom or _("Nos"),
|
||||||
|
"qty": item.get("quantity"),
|
||||||
|
"rate": item.get("price"),
|
||||||
|
"warehouse": woocommerce_settings.warehouse or _("Stores - {0}").format(company_abbr)
|
||||||
|
})
|
||||||
|
|
||||||
sales_order.append("taxes",{
|
add_tax_details(new_sales_order, ordered_items_tax, "Ordered Item tax", woocommerce_settings.tax_account)
|
||||||
"charge_type":"Actual",
|
|
||||||
"account_head": account_head_type,
|
# shipping_details = order.get("shipping_lines") # used for detailed order
|
||||||
"tax_amount": price,
|
|
||||||
"description": desc
|
add_tax_details(new_sales_order, order.get("shipping_tax"), "Shipping Tax", woocommerce_settings.f_n_f_account)
|
||||||
})
|
add_tax_details(new_sales_order, order.get("shipping_total"), "Shipping Total", woocommerce_settings.f_n_f_account)
|
||||||
|
|
||||||
|
def add_tax_details(sales_order, price, desc, tax_account_head):
|
||||||
|
sales_order.append("taxes", {
|
||||||
|
"charge_type":"Actual",
|
||||||
|
"account_head": tax_account_head,
|
||||||
|
"tax_amount": price,
|
||||||
|
"description": desc
|
||||||
|
})
|
||||||
|
@ -50,7 +50,7 @@ class ShopifySettings(Document):
|
|||||||
deleted_webhooks = []
|
deleted_webhooks = []
|
||||||
|
|
||||||
for d in self.webhooks:
|
for d in self.webhooks:
|
||||||
url = get_shopify_url('admin/api/2019-04/webhooks.json'.format(d.webhook_id), self)
|
url = get_shopify_url('admin/api/2019-04/webhooks/{0}.json'.format(d.webhook_id), self)
|
||||||
try:
|
try:
|
||||||
res = session.delete(url, headers=get_header(self))
|
res = session.delete(url, headers=get_header(self))
|
||||||
res.raise_for_status()
|
res.raise_for_status()
|
||||||
|
@ -1,694 +1,175 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2018-02-12 15:10:05.495713",
|
"creation": "2018-02-12 15:10:05.495713",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"enable_sync",
|
||||||
|
"sb_00",
|
||||||
|
"woocommerce_server_url",
|
||||||
|
"secret",
|
||||||
|
"cb_00",
|
||||||
|
"api_consumer_key",
|
||||||
|
"api_consumer_secret",
|
||||||
|
"sb_accounting_details",
|
||||||
|
"tax_account",
|
||||||
|
"column_break_10",
|
||||||
|
"f_n_f_account",
|
||||||
|
"defaults_section",
|
||||||
|
"creation_user",
|
||||||
|
"warehouse",
|
||||||
|
"sales_order_series",
|
||||||
|
"column_break_14",
|
||||||
|
"company",
|
||||||
|
"delivery_after_days",
|
||||||
|
"uom",
|
||||||
|
"endpoints",
|
||||||
|
"endpoint"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "0",
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "enable_sync",
|
"fieldname": "enable_sync",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"label": "Enable Sync"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Enable Sync",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "sb_00",
|
"fieldname": "sb_00",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "woocommerce_server_url",
|
"fieldname": "woocommerce_server_url",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"label": "Woocommerce Server URL"
|
||||||
"label": "Woocommerce Server URL",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "secret",
|
"fieldname": "secret",
|
||||||
"fieldtype": "Code",
|
"fieldtype": "Code",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Secret",
|
"label": "Secret",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "cb_00",
|
"fieldname": "cb_00",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "api_consumer_key",
|
"fieldname": "api_consumer_key",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"label": "API consumer key"
|
||||||
"label": "API consumer key",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "api_consumer_secret",
|
"fieldname": "api_consumer_secret",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"label": "API consumer secret"
|
||||||
"label": "API consumer secret",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "sb_accounting_details",
|
"fieldname": "sb_accounting_details",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Accounting Details"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Accounting Details",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "tax_account",
|
"fieldname": "tax_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Tax Account",
|
"label": "Tax Account",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Account",
|
"options": "Account",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "column_break_10",
|
"fieldname": "column_break_10",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "f_n_f_account",
|
"fieldname": "f_n_f_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Freight and Forwarding Account",
|
"label": "Freight and Forwarding Account",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Account",
|
"options": "Account",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "defaults_section",
|
"fieldname": "defaults_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Defaults"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Defaults",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"description": "The user that will be used to create Customers, Items and Sales Orders. This user should have the relevant permissions.",
|
"description": "The user that will be used to create Customers, Items and Sales Orders. This user should have the relevant permissions.",
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "creation_user",
|
"fieldname": "creation_user",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Creation User",
|
"label": "Creation User",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "User",
|
"options": "User",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"description": "This warehouse will be used to create Sales Orders. The fallback warehouse is \"Stores\".",
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"description": "This warehouse will be used to create Sale Orders. The fallback warehouse is \"Stores\".",
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "warehouse",
|
"fieldname": "warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Warehouse",
|
"label": "Warehouse",
|
||||||
"length": 0,
|
"options": "Warehouse"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Warehouse",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "column_break_14",
|
"fieldname": "column_break_14",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"description": "The fallback series is \"SO-WOO-\".",
|
"description": "The fallback series is \"SO-WOO-\".",
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "sales_order_series",
|
"fieldname": "sales_order_series",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"label": "Sales Order Series"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Sales Order Series",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"description": "This is the default UOM used for items and Sales orders. The fallback UOM is \"Nos\".",
|
"description": "This is the default UOM used for items and Sales orders. The fallback UOM is \"Nos\".",
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "uom",
|
"fieldname": "uom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "UOM",
|
"label": "UOM",
|
||||||
"length": 0,
|
"options": "UOM"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "UOM",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "endpoints",
|
"fieldname": "endpoints",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Endpoints"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Endpoints",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "endpoint",
|
"fieldname": "endpoint",
|
||||||
"fieldtype": "Code",
|
"fieldtype": "Code",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Endpoint",
|
"label": "Endpoint",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
},
|
||||||
"permlevel": 0,
|
{
|
||||||
"precision": "",
|
"description": "This company will be used to create Sales Orders.",
|
||||||
"print_hide": 0,
|
"fieldname": "company",
|
||||||
"print_hide_if_no_value": 0,
|
"fieldtype": "Link",
|
||||||
"read_only": 1,
|
"label": "Company",
|
||||||
"remember_last_selected_value": 0,
|
"options": "Company",
|
||||||
"report_hide": 0,
|
"reqd": 1
|
||||||
"reqd": 0,
|
},
|
||||||
"search_index": 0,
|
{
|
||||||
"set_only_once": 0,
|
"description": "This is the default offset (days) for the Delivery Date in Sales Orders. The fallback offset is 7 days from the order placement date.",
|
||||||
"translatable": 0,
|
"fieldname": "delivery_after_days",
|
||||||
"unique": 0
|
"fieldtype": "Int",
|
||||||
|
"label": "Delivery After (Days)"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"modified": "2019-11-04 00:45:21.232096",
|
||||||
"max_attachments": 0,
|
|
||||||
"menu_index": 0,
|
|
||||||
"modified": "2019-04-08 17:04:16.720696",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "ERPNext Integrations",
|
"module": "ERPNext Integrations",
|
||||||
"name": "Woocommerce Settings",
|
"name": "Woocommerce Settings",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 0,
|
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 0,
|
|
||||||
"role": "System Manager",
|
"role": "System Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1,
|
"track_changes": 1
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
@ -8,6 +8,7 @@ from frappe import _
|
|||||||
from frappe.utils.nestedset import get_root_of
|
from frappe.utils.nestedset import get_root_of
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from six.moves.urllib.parse import urlparse
|
from six.moves.urllib.parse import urlparse
|
||||||
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
||||||
|
|
||||||
class WoocommerceSettings(Document):
|
class WoocommerceSettings(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
@ -17,75 +18,21 @@ class WoocommerceSettings(Document):
|
|||||||
|
|
||||||
def create_delete_custom_fields(self):
|
def create_delete_custom_fields(self):
|
||||||
if self.enable_sync:
|
if self.enable_sync:
|
||||||
|
custom_fields = {}
|
||||||
# create
|
# create
|
||||||
create_custom_field_id_and_check_status = False
|
for doctype in ["Customer", "Sales Order", "Item", "Address"]:
|
||||||
create_custom_field_email_check = False
|
df = dict(fieldname='woocommerce_id', label='Woocommerce ID', fieldtype='Data', read_only=1, print_hide=1)
|
||||||
names = ["Customer-woocommerce_id","Sales Order-woocommerce_id","Item-woocommerce_id","Address-woocommerce_id"]
|
create_custom_field(doctype, df)
|
||||||
names_check_box = ["Customer-woocommerce_check","Sales Order-woocommerce_check","Item-woocommerce_check","Address-woocommerce_check"]
|
|
||||||
email_names = ["Customer-woocommerce_email","Address-woocommerce_email"]
|
|
||||||
|
|
||||||
for i in zip(names,names_check_box):
|
for doctype in ["Customer", "Address"]:
|
||||||
|
df = dict(fieldname='woocommerce_email', label='Woocommerce Email', fieldtype='Data', read_only=1, print_hide=1)
|
||||||
|
create_custom_field(doctype, df)
|
||||||
|
|
||||||
if not frappe.get_value("Custom Field",{"name":i[0]}) or not frappe.get_value("Custom Field",{"name":i[1]}):
|
if not frappe.get_value("Item Group", {"name": _("WooCommerce Products")}):
|
||||||
create_custom_field_id_and_check_status = True
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
if create_custom_field_id_and_check_status:
|
|
||||||
names = ["Customer","Sales Order","Item","Address"]
|
|
||||||
for name in names:
|
|
||||||
custom = frappe.new_doc("Custom Field")
|
|
||||||
custom.dt = name
|
|
||||||
custom.label = "woocommerce_id"
|
|
||||||
custom.read_only = 1
|
|
||||||
custom.save()
|
|
||||||
|
|
||||||
custom = frappe.new_doc("Custom Field")
|
|
||||||
custom.dt = name
|
|
||||||
custom.label = "woocommerce_check"
|
|
||||||
custom.fieldtype = "Check"
|
|
||||||
custom.read_only = 1
|
|
||||||
custom.save()
|
|
||||||
|
|
||||||
for i in email_names:
|
|
||||||
|
|
||||||
if not frappe.get_value("Custom Field",{"name":i}):
|
|
||||||
create_custom_field_email_check = True
|
|
||||||
break;
|
|
||||||
|
|
||||||
if create_custom_field_email_check:
|
|
||||||
names = ["Customer","Address"]
|
|
||||||
for name in names:
|
|
||||||
custom = frappe.new_doc("Custom Field")
|
|
||||||
custom.dt = name
|
|
||||||
custom.label = "woocommerce_email"
|
|
||||||
custom.read_only = 1
|
|
||||||
custom.save()
|
|
||||||
|
|
||||||
if not frappe.get_value("Item Group",{"name": _("WooCommerce Products")}):
|
|
||||||
item_group = frappe.new_doc("Item Group")
|
item_group = frappe.new_doc("Item Group")
|
||||||
item_group.item_group_name = _("WooCommerce Products")
|
item_group.item_group_name = _("WooCommerce Products")
|
||||||
item_group.parent_item_group = get_root_of("Item Group")
|
item_group.parent_item_group = get_root_of("Item Group")
|
||||||
item_group.save()
|
item_group.insert()
|
||||||
|
|
||||||
|
|
||||||
elif not self.enable_sync:
|
|
||||||
# delete
|
|
||||||
names = ["Customer-woocommerce_id","Sales Order-woocommerce_id","Item-woocommerce_id","Address-woocommerce_id"]
|
|
||||||
names_check_box = ["Customer-woocommerce_check","Sales Order-woocommerce_check","Item-woocommerce_check","Address-woocommerce_check"]
|
|
||||||
email_names = ["Customer-woocommerce_email","Address-woocommerce_email"]
|
|
||||||
for name in names:
|
|
||||||
frappe.delete_doc("Custom Field",name)
|
|
||||||
|
|
||||||
for name in names_check_box:
|
|
||||||
frappe.delete_doc("Custom Field",name)
|
|
||||||
|
|
||||||
for name in email_names:
|
|
||||||
frappe.delete_doc("Custom Field",name)
|
|
||||||
|
|
||||||
frappe.delete_doc("Item Group", _("WooCommerce Products"))
|
|
||||||
|
|
||||||
frappe.db.commit()
|
|
||||||
|
|
||||||
def validate_settings(self):
|
def validate_settings(self):
|
||||||
if self.enable_sync:
|
if self.enable_sync:
|
||||||
|
@ -235,17 +235,16 @@ doc_events = {
|
|||||||
("Sales Taxes and Charges Template", 'Price List'): {
|
("Sales Taxes and Charges Template", 'Price List'): {
|
||||||
"on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings"
|
"on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings"
|
||||||
},
|
},
|
||||||
|
|
||||||
"Website Settings": {
|
"Website Settings": {
|
||||||
"validate": "erpnext.portal.doctype.products_settings.products_settings.home_page_is_products"
|
"validate": "erpnext.portal.doctype.products_settings.products_settings.home_page_is_products"
|
||||||
},
|
},
|
||||||
"Sales Invoice": {
|
"Sales Invoice": {
|
||||||
"on_submit": ["erpnext.regional.france.utils.create_transaction_log", "erpnext.regional.italy.utils.sales_invoice_on_submit"],
|
"on_submit": ["erpnext.regional.create_transaction_log", "erpnext.regional.italy.utils.sales_invoice_on_submit"],
|
||||||
"on_cancel": "erpnext.regional.italy.utils.sales_invoice_on_cancel",
|
"on_cancel": "erpnext.regional.italy.utils.sales_invoice_on_cancel",
|
||||||
"on_trash": "erpnext.regional.check_deletion_permission"
|
"on_trash": "erpnext.regional.check_deletion_permission"
|
||||||
},
|
},
|
||||||
"Payment Entry": {
|
"Payment Entry": {
|
||||||
"on_submit": ["erpnext.regional.france.utils.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.make_status_as_paid"],
|
"on_submit": ["erpnext.regional.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.make_status_as_paid"],
|
||||||
"on_trash": "erpnext.regional.check_deletion_permission"
|
"on_trash": "erpnext.regional.check_deletion_permission"
|
||||||
},
|
},
|
||||||
'Address': {
|
'Address': {
|
||||||
|
@ -19,14 +19,20 @@ def get_approvers(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
approvers = []
|
approvers = []
|
||||||
department_details = {}
|
department_details = {}
|
||||||
department_list = []
|
department_list = []
|
||||||
employee_department = filters.get("department") or frappe.get_value("Employee", filters.get("employee"), "department")
|
employee = frappe.get_value("Employee", filters.get("employee"), ["department", "leave_approver"], as_dict=True)
|
||||||
|
if employee.leave_approver:
|
||||||
|
approver = frappe.db.get_value("User", employee.leave_approver, ['name', 'first_name', 'last_name'])
|
||||||
|
approvers.append(approver)
|
||||||
|
return approvers
|
||||||
|
|
||||||
|
employee_department = filters.get("department") or employee.department
|
||||||
if employee_department:
|
if employee_department:
|
||||||
department_details = frappe.db.get_value("Department", {"name": employee_department}, ["lft", "rgt"], as_dict=True)
|
department_details = frappe.db.get_value("Department", {"name": employee_department}, ["lft", "rgt"], as_dict=True)
|
||||||
if department_details:
|
if department_details:
|
||||||
department_list = frappe.db.sql("""select name from `tabDepartment` where lft <= %s
|
department_list = frappe.db.sql("""select name from `tabDepartment` where lft <= %s
|
||||||
and rgt >= %s
|
and rgt >= %s
|
||||||
and disabled=0
|
and disabled=0
|
||||||
order by lft desc""", (department_details.lft, department_details.rgt), as_list = True)
|
order by lft desc""", (department_details.lft, department_details.rgt), as_list=True)
|
||||||
|
|
||||||
if filters.get("doctype") == "Leave Application":
|
if filters.get("doctype") == "Leave Application":
|
||||||
parentfield = "leave_approvers"
|
parentfield = "leave_approvers"
|
||||||
|
@ -167,10 +167,11 @@ class Employee(NestedSet):
|
|||||||
def validate_status(self):
|
def validate_status(self):
|
||||||
if self.status == 'Left':
|
if self.status == 'Left':
|
||||||
reports_to = frappe.db.get_all('Employee',
|
reports_to = frappe.db.get_all('Employee',
|
||||||
filters={'reports_to': self.name}
|
filters={'reports_to': self.name, 'status': "Active"},
|
||||||
|
fields=['name','employee_name']
|
||||||
)
|
)
|
||||||
if reports_to:
|
if reports_to:
|
||||||
link_to_employees = [frappe.utils.get_link_to_form('Employee', employee.name) for employee in reports_to]
|
link_to_employees = [frappe.utils.get_link_to_form('Employee', employee.name, label=employee.employee_name) for employee in reports_to]
|
||||||
throw(_("Employee status cannot be set to 'Left' as following employees are currently reporting to this employee: ")
|
throw(_("Employee status cannot be set to 'Left' as following employees are currently reporting to this employee: ")
|
||||||
+ ', '.join(link_to_employees), EmployeeLeftValidationError)
|
+ ', '.join(link_to_employees), EmployeeLeftValidationError)
|
||||||
if not self.relieving_date:
|
if not self.relieving_date:
|
||||||
|
@ -21,7 +21,7 @@ def get_data():
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
'label': _('Expense'),
|
'label': _('Expense'),
|
||||||
'items': ['Expense Claim', 'Travel Request']
|
'items': ['Expense Claim', 'Travel Request', 'Employee Advance']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'label': _('Benefit'),
|
'label': _('Benefit'),
|
||||||
|
@ -1,435 +1,436 @@
|
|||||||
{
|
{
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2013-01-10 16:34:14",
|
"creation": "2013-01-10 16:34:14",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Setup",
|
"document_type": "Setup",
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"naming_series",
|
"naming_series",
|
||||||
"employee",
|
"employee",
|
||||||
"employee_name",
|
"employee_name",
|
||||||
"department",
|
"department",
|
||||||
"column_break_5",
|
"column_break_5",
|
||||||
"expense_approver",
|
"expense_approver",
|
||||||
"approval_status",
|
"approval_status",
|
||||||
"is_paid",
|
"is_paid",
|
||||||
"expense_details",
|
"expense_details",
|
||||||
"expenses",
|
"expenses",
|
||||||
"sb1",
|
"sb1",
|
||||||
"taxes",
|
"taxes",
|
||||||
"transactions_section",
|
"transactions_section",
|
||||||
"total_sanctioned_amount",
|
"total_sanctioned_amount",
|
||||||
"total_taxes_and_charges",
|
"total_taxes_and_charges",
|
||||||
"total_advance_amount",
|
"total_advance_amount",
|
||||||
"column_break_17",
|
"column_break_17",
|
||||||
"grand_total",
|
"grand_total",
|
||||||
"total_claimed_amount",
|
"total_claimed_amount",
|
||||||
"total_amount_reimbursed",
|
"total_amount_reimbursed",
|
||||||
"section_break_16",
|
"section_break_16",
|
||||||
"posting_date",
|
"posting_date",
|
||||||
"vehicle_log",
|
"vehicle_log",
|
||||||
"task",
|
"task",
|
||||||
"cb1",
|
"cb1",
|
||||||
"remark",
|
"remark",
|
||||||
"title",
|
"title",
|
||||||
"email_id",
|
"email_id",
|
||||||
"accounting_details",
|
"accounting_details",
|
||||||
"company",
|
"company",
|
||||||
"mode_of_payment",
|
"mode_of_payment",
|
||||||
"clearance_date",
|
"clearance_date",
|
||||||
"column_break_24",
|
"column_break_24",
|
||||||
"payable_account",
|
"payable_account",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"project",
|
"project",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"more_details",
|
"more_details",
|
||||||
"status",
|
"status",
|
||||||
"amended_from",
|
"amended_from",
|
||||||
"advance_payments",
|
"advance_payments",
|
||||||
"advances"
|
"advances"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldname": "naming_series",
|
"fieldname": "naming_series",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Series",
|
"label": "Series",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "HR-EXP-.YYYY.-",
|
"options": "HR-EXP-.YYYY.-",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"set_only_once": 1
|
"set_only_once": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "employee",
|
"fieldname": "employee",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
"label": "From Employee",
|
"label": "From Employee",
|
||||||
"oldfieldname": "employee",
|
"oldfieldname": "employee",
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Employee",
|
"options": "Employee",
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "employee.employee_name",
|
"fetch_from": "employee.employee_name",
|
||||||
"fieldname": "employee_name",
|
"fieldname": "employee_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
"label": "Employee Name",
|
"label": "Employee Name",
|
||||||
"oldfieldname": "employee_name",
|
"oldfieldname": "employee_name",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "employee.department",
|
"fetch_from": "employee.department",
|
||||||
"fieldname": "department",
|
"fieldname": "department",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Department",
|
"label": "Department",
|
||||||
"options": "Department",
|
"options": "Department",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_5",
|
"fieldname": "column_break_5",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "expense_approver",
|
"fieldname": "expense_approver",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Expense Approver",
|
"label": "Expense Approver",
|
||||||
"options": "User"
|
"options": "User"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "Draft",
|
"default": "Draft",
|
||||||
"fieldname": "approval_status",
|
"fieldname": "approval_status",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Approval Status",
|
"label": "Approval Status",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Draft\nApproved\nRejected",
|
"options": "Draft\nApproved\nRejected",
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "total_claimed_amount",
|
"fieldname": "total_claimed_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Total Claimed Amount",
|
"label": "Total Claimed Amount",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "total_claimed_amount",
|
"oldfieldname": "total_claimed_amount",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"width": "160px"
|
"width": "160px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "total_sanctioned_amount",
|
"fieldname": "total_sanctioned_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Total Sanctioned Amount",
|
"label": "Total Sanctioned Amount",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "total_sanctioned_amount",
|
"oldfieldname": "total_sanctioned_amount",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"width": "160px"
|
"width": "160px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"depends_on": "eval:(doc.docstatus==0 || doc.is_paid)",
|
"depends_on": "eval:(doc.docstatus==0 || doc.is_paid)",
|
||||||
"fieldname": "is_paid",
|
"fieldname": "is_paid",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Paid"
|
"label": "Is Paid"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "expense_details",
|
"fieldname": "expense_details",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"oldfieldtype": "Section Break"
|
"oldfieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "expenses",
|
"fieldname": "expenses",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Expenses",
|
"label": "Expenses",
|
||||||
"oldfieldname": "expense_voucher_details",
|
"oldfieldname": "expense_voucher_details",
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"options": "Expense Claim Detail",
|
"options": "Expense Claim Detail",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "sb1",
|
"fieldname": "sb1",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"options": "Simple"
|
"options": "Simple"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "Today",
|
"default": "Today",
|
||||||
"fieldname": "posting_date",
|
"fieldname": "posting_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Posting Date",
|
"label": "Posting Date",
|
||||||
"oldfieldname": "posting_date",
|
"oldfieldname": "posting_date",
|
||||||
"oldfieldtype": "Date",
|
"oldfieldtype": "Date",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "vehicle_log",
|
"fieldname": "vehicle_log",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Vehicle Log",
|
"label": "Vehicle Log",
|
||||||
"options": "Vehicle Log",
|
"options": "Vehicle Log",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "project",
|
"fieldname": "project",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Project",
|
"label": "Project",
|
||||||
"options": "Project"
|
"options": "Project"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "task",
|
"fieldname": "task",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Task",
|
"label": "Task",
|
||||||
"options": "Task",
|
"options": "Task",
|
||||||
"remember_last_selected_value": 1
|
"remember_last_selected_value": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "cb1",
|
"fieldname": "cb1",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "total_amount_reimbursed",
|
"fieldname": "total_amount_reimbursed",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Total Amount Reimbursed",
|
"label": "Total Amount Reimbursed",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "remark",
|
"fieldname": "remark",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Remark",
|
"label": "Remark",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "remark",
|
"oldfieldname": "remark",
|
||||||
"oldfieldtype": "Small Text"
|
"oldfieldtype": "Small Text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"default": "{employee_name}",
|
"default": "{employee_name}",
|
||||||
"fieldname": "title",
|
"fieldname": "title",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Title",
|
"label": "Title",
|
||||||
"no_copy": 1
|
"no_copy": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "email_id",
|
"fieldname": "email_id",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Employees Email Id",
|
"label": "Employees Email Id",
|
||||||
"oldfieldname": "email_id",
|
"oldfieldname": "email_id",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "accounting_details",
|
"fieldname": "accounting_details",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Accounting Details"
|
"label": "Accounting Details"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Company",
|
"label": "Company",
|
||||||
"oldfieldname": "company",
|
"oldfieldname": "company",
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
"remember_last_selected_value": 1,
|
"remember_last_selected_value": 1,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "is_paid",
|
"depends_on": "is_paid",
|
||||||
"fieldname": "mode_of_payment",
|
"fieldname": "mode_of_payment",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Mode of Payment",
|
"label": "Mode of Payment",
|
||||||
"options": "Mode of Payment"
|
"options": "Mode of Payment"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "clearance_date",
|
"fieldname": "clearance_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Clearance Date"
|
"label": "Clearance Date"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_24",
|
"fieldname": "column_break_24",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "payable_account",
|
"fieldname": "payable_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Payable Account",
|
"label": "Payable Account",
|
||||||
"options": "Account"
|
"options": "Account",
|
||||||
},
|
"reqd": 1
|
||||||
{
|
},
|
||||||
"fieldname": "cost_center",
|
{
|
||||||
"fieldtype": "Link",
|
"fieldname": "cost_center",
|
||||||
"label": "Cost Center",
|
"fieldtype": "Link",
|
||||||
"options": "Cost Center"
|
"label": "Cost Center",
|
||||||
},
|
"options": "Cost Center"
|
||||||
{
|
},
|
||||||
"collapsible": 1,
|
{
|
||||||
"fieldname": "more_details",
|
"collapsible": 1,
|
||||||
"fieldtype": "Section Break",
|
"fieldname": "more_details",
|
||||||
"label": "More Details"
|
"fieldtype": "Section Break",
|
||||||
},
|
"label": "More Details"
|
||||||
{
|
},
|
||||||
"default": "Draft",
|
{
|
||||||
"fieldname": "status",
|
"default": "Draft",
|
||||||
"fieldtype": "Select",
|
"fieldname": "status",
|
||||||
"in_list_view": 1,
|
"fieldtype": "Select",
|
||||||
"label": "Status",
|
"in_list_view": 1,
|
||||||
"no_copy": 1,
|
"label": "Status",
|
||||||
"options": "Draft\nPaid\nUnpaid\nRejected\nSubmitted\nCancelled",
|
"no_copy": 1,
|
||||||
"print_hide": 1,
|
"options": "Draft\nPaid\nUnpaid\nRejected\nSubmitted\nCancelled",
|
||||||
"read_only": 1
|
"print_hide": 1,
|
||||||
},
|
"read_only": 1
|
||||||
{
|
},
|
||||||
"fieldname": "amended_from",
|
{
|
||||||
"fieldtype": "Link",
|
"fieldname": "amended_from",
|
||||||
"ignore_user_permissions": 1,
|
"fieldtype": "Link",
|
||||||
"label": "Amended From",
|
"ignore_user_permissions": 1,
|
||||||
"no_copy": 1,
|
"label": "Amended From",
|
||||||
"oldfieldname": "amended_from",
|
"no_copy": 1,
|
||||||
"oldfieldtype": "Data",
|
"oldfieldname": "amended_from",
|
||||||
"options": "Expense Claim",
|
"oldfieldtype": "Data",
|
||||||
"print_hide": 1,
|
"options": "Expense Claim",
|
||||||
"read_only": 1,
|
"print_hide": 1,
|
||||||
"report_hide": 1,
|
"read_only": 1,
|
||||||
"width": "160px"
|
"report_hide": 1,
|
||||||
},
|
"width": "160px"
|
||||||
{
|
},
|
||||||
"fieldname": "advance_payments",
|
{
|
||||||
"fieldtype": "Section Break",
|
"fieldname": "advance_payments",
|
||||||
"label": "Advance Payments"
|
"fieldtype": "Section Break",
|
||||||
},
|
"label": "Advance Payments"
|
||||||
{
|
},
|
||||||
"fieldname": "advances",
|
{
|
||||||
"fieldtype": "Table",
|
"fieldname": "advances",
|
||||||
"label": "Advances",
|
"fieldtype": "Table",
|
||||||
"options": "Expense Claim Advance"
|
"label": "Advances",
|
||||||
},
|
"options": "Expense Claim Advance"
|
||||||
{
|
},
|
||||||
"fieldname": "total_advance_amount",
|
{
|
||||||
"fieldtype": "Currency",
|
"fieldname": "total_advance_amount",
|
||||||
"label": "Total Advance Amount",
|
"fieldtype": "Currency",
|
||||||
"options": "Company:company:default_currency",
|
"label": "Total Advance Amount",
|
||||||
"read_only": 1
|
"options": "Company:company:default_currency",
|
||||||
},
|
"read_only": 1
|
||||||
{
|
},
|
||||||
"fieldname": "accounting_dimensions_section",
|
{
|
||||||
"fieldtype": "Section Break",
|
"fieldname": "accounting_dimensions_section",
|
||||||
"label": "Accounting Dimensions"
|
"fieldtype": "Section Break",
|
||||||
},
|
"label": "Accounting Dimensions"
|
||||||
{
|
},
|
||||||
"fieldname": "dimension_col_break",
|
{
|
||||||
"fieldtype": "Column Break"
|
"fieldname": "dimension_col_break",
|
||||||
},
|
"fieldtype": "Column Break"
|
||||||
{
|
},
|
||||||
"fieldname": "taxes",
|
{
|
||||||
"fieldtype": "Table",
|
"fieldname": "taxes",
|
||||||
"label": "Expense Taxes and Charges",
|
"fieldtype": "Table",
|
||||||
"options": "Expense Taxes and Charges"
|
"label": "Expense Taxes and Charges",
|
||||||
},
|
"options": "Expense Taxes and Charges"
|
||||||
{
|
},
|
||||||
"fieldname": "section_break_16",
|
{
|
||||||
"fieldtype": "Section Break"
|
"fieldname": "section_break_16",
|
||||||
},
|
"fieldtype": "Section Break"
|
||||||
{
|
},
|
||||||
"fieldname": "transactions_section",
|
{
|
||||||
"fieldtype": "Section Break"
|
"fieldname": "transactions_section",
|
||||||
},
|
"fieldtype": "Section Break"
|
||||||
{
|
},
|
||||||
"fieldname": "grand_total",
|
{
|
||||||
"fieldtype": "Currency",
|
"fieldname": "grand_total",
|
||||||
"in_list_view": 1,
|
"fieldtype": "Currency",
|
||||||
"label": "Grand Total",
|
"in_list_view": 1,
|
||||||
"options": "Company:company:default_currency",
|
"label": "Grand Total",
|
||||||
"read_only": 1
|
"options": "Company:company:default_currency",
|
||||||
},
|
"read_only": 1
|
||||||
{
|
},
|
||||||
"fieldname": "column_break_17",
|
{
|
||||||
"fieldtype": "Column Break"
|
"fieldname": "column_break_17",
|
||||||
},
|
"fieldtype": "Column Break"
|
||||||
{
|
},
|
||||||
"fieldname": "total_taxes_and_charges",
|
{
|
||||||
"fieldtype": "Currency",
|
"fieldname": "total_taxes_and_charges",
|
||||||
"label": "Total Taxes and Charges",
|
"fieldtype": "Currency",
|
||||||
"options": "Company:company:default_currency",
|
"label": "Total Taxes and Charges",
|
||||||
"read_only": 1
|
"options": "Company:company:default_currency",
|
||||||
}
|
"read_only": 1
|
||||||
],
|
}
|
||||||
"icon": "fa fa-money",
|
],
|
||||||
"idx": 1,
|
"icon": "fa fa-money",
|
||||||
"is_submittable": 1,
|
"idx": 1,
|
||||||
"modified": "2019-06-26 18:05:52.530462",
|
"is_submittable": 1,
|
||||||
"modified_by": "Administrator",
|
"modified": "2019-11-08 14:13:08.964547",
|
||||||
"module": "HR",
|
"modified_by": "Administrator",
|
||||||
"name": "Expense Claim",
|
"module": "HR",
|
||||||
"name_case": "Title Case",
|
"name": "Expense Claim",
|
||||||
"owner": "harshada@webnotestech.com",
|
"name_case": "Title Case",
|
||||||
"permissions": [
|
"owner": "harshada@webnotestech.com",
|
||||||
{
|
"permissions": [
|
||||||
"amend": 1,
|
{
|
||||||
"cancel": 1,
|
"amend": 1,
|
||||||
"create": 1,
|
"cancel": 1,
|
||||||
"delete": 1,
|
"create": 1,
|
||||||
"email": 1,
|
"delete": 1,
|
||||||
"export": 1,
|
"email": 1,
|
||||||
"print": 1,
|
"export": 1,
|
||||||
"read": 1,
|
"print": 1,
|
||||||
"report": 1,
|
"read": 1,
|
||||||
"role": "HR Manager",
|
"report": 1,
|
||||||
"share": 1,
|
"role": "HR Manager",
|
||||||
"submit": 1,
|
"share": 1,
|
||||||
"write": 1
|
"submit": 1,
|
||||||
},
|
"write": 1
|
||||||
{
|
},
|
||||||
"create": 1,
|
{
|
||||||
"email": 1,
|
"create": 1,
|
||||||
"print": 1,
|
"email": 1,
|
||||||
"read": 1,
|
"print": 1,
|
||||||
"report": 1,
|
"read": 1,
|
||||||
"role": "Employee",
|
"report": 1,
|
||||||
"share": 1,
|
"role": "Employee",
|
||||||
"write": 1
|
"share": 1,
|
||||||
},
|
"write": 1
|
||||||
{
|
},
|
||||||
"amend": 1,
|
{
|
||||||
"cancel": 1,
|
"amend": 1,
|
||||||
"create": 1,
|
"cancel": 1,
|
||||||
"delete": 1,
|
"create": 1,
|
||||||
"email": 1,
|
"delete": 1,
|
||||||
"print": 1,
|
"email": 1,
|
||||||
"read": 1,
|
"print": 1,
|
||||||
"report": 1,
|
"read": 1,
|
||||||
"role": "Expense Approver",
|
"report": 1,
|
||||||
"share": 1,
|
"role": "Expense Approver",
|
||||||
"submit": 1,
|
"share": 1,
|
||||||
"write": 1
|
"submit": 1,
|
||||||
},
|
"write": 1
|
||||||
{
|
},
|
||||||
"amend": 1,
|
{
|
||||||
"cancel": 1,
|
"amend": 1,
|
||||||
"create": 1,
|
"cancel": 1,
|
||||||
"delete": 1,
|
"create": 1,
|
||||||
"email": 1,
|
"delete": 1,
|
||||||
"print": 1,
|
"email": 1,
|
||||||
"read": 1,
|
"print": 1,
|
||||||
"report": 1,
|
"read": 1,
|
||||||
"role": "HR User",
|
"report": 1,
|
||||||
"share": 1,
|
"role": "HR User",
|
||||||
"submit": 1,
|
"share": 1,
|
||||||
"write": 1
|
"submit": 1,
|
||||||
}
|
"write": 1
|
||||||
],
|
}
|
||||||
"search_fields": "employee,employee_name",
|
],
|
||||||
"show_name_in_global_search": 1,
|
"search_fields": "employee,employee_name",
|
||||||
"sort_field": "modified",
|
"show_name_in_global_search": 1,
|
||||||
"sort_order": "DESC",
|
"sort_field": "modified",
|
||||||
"timeline_field": "employee",
|
"sort_order": "DESC",
|
||||||
"title_field": "title"
|
"timeline_field": "employee",
|
||||||
}
|
"title_field": "title"
|
||||||
|
}
|
@ -144,6 +144,33 @@ class ExpenseClaim(AccountsController):
|
|||||||
"against_voucher": self.name
|
"against_voucher": self.name
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
gl_entry.append(
|
||||||
|
self.get_gl_dict({
|
||||||
|
"account": data.advance_account,
|
||||||
|
"debit": data.allocated_amount,
|
||||||
|
"debit_in_account_currency": data.allocated_amount,
|
||||||
|
"against": self.payable_account,
|
||||||
|
"party_type": "Employee",
|
||||||
|
"party": self.employee,
|
||||||
|
"against_voucher_type": self.doctype,
|
||||||
|
"against_voucher": self.name
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
gl_entry.append(
|
||||||
|
self.get_gl_dict({
|
||||||
|
"account": self.payable_account,
|
||||||
|
"credit": data.allocated_amount,
|
||||||
|
"credit_in_account_currency": data.allocated_amount,
|
||||||
|
"against": data.advance_account,
|
||||||
|
"party_type": "Employee",
|
||||||
|
"party": self.employee,
|
||||||
|
"against_voucher_type": "Employee Advance",
|
||||||
|
"against_voucher": data.employee_advance
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
self.add_tax_gl_entries(gl_entry)
|
self.add_tax_gl_entries(gl_entry)
|
||||||
|
|
||||||
if self.is_paid and self.grand_total:
|
if self.is_paid and self.grand_total:
|
||||||
@ -192,9 +219,6 @@ class ExpenseClaim(AccountsController):
|
|||||||
if not self.cost_center:
|
if not self.cost_center:
|
||||||
frappe.throw(_("Cost center is required to book an expense claim"))
|
frappe.throw(_("Cost center is required to book an expense claim"))
|
||||||
|
|
||||||
if not self.payable_account:
|
|
||||||
frappe.throw(_("Please set default payable account for the company {0}").format(getlink("Company",self.company)))
|
|
||||||
|
|
||||||
if self.is_paid:
|
if self.is_paid:
|
||||||
if not self.mode_of_payment:
|
if not self.mode_of_payment:
|
||||||
frappe.throw(_("Mode of payment is required to make a payment").format(self.employee))
|
frappe.throw(_("Mode of payment is required to make a payment").format(self.employee))
|
||||||
|
@ -55,11 +55,11 @@ class LeaveApplication(Document):
|
|||||||
self.reload()
|
self.reload()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
|
self.create_leave_ledger_entry(submit=False)
|
||||||
self.status = "Cancelled"
|
self.status = "Cancelled"
|
||||||
# notify leave applier about cancellation
|
# notify leave applier about cancellation
|
||||||
self.notify_employee()
|
self.notify_employee()
|
||||||
self.cancel_attendance()
|
self.cancel_attendance()
|
||||||
self.create_leave_ledger_entry(submit=False)
|
|
||||||
|
|
||||||
def validate_applicable_after(self):
|
def validate_applicable_after(self):
|
||||||
if self.leave_type:
|
if self.leave_type:
|
||||||
@ -351,6 +351,9 @@ class LeaveApplication(Document):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def create_leave_ledger_entry(self, submit=True):
|
def create_leave_ledger_entry(self, submit=True):
|
||||||
|
if self.status != 'Approved':
|
||||||
|
return
|
||||||
|
|
||||||
expiry_date = get_allocation_expiry(self.employee, self.leave_type,
|
expiry_date = get_allocation_expiry(self.employee, self.leave_type,
|
||||||
self.to_date, self.from_date)
|
self.to_date, self.from_date)
|
||||||
|
|
||||||
|
@ -47,9 +47,11 @@ frappe.ui.form.on('Salary Structure', {
|
|||||||
frm.fields_dict['earnings'].grid.set_column_disp("default_amount", false);
|
frm.fields_dict['earnings'].grid.set_column_disp("default_amount", false);
|
||||||
frm.fields_dict['deductions'].grid.set_column_disp("default_amount", false);
|
frm.fields_dict['deductions'].grid.set_column_disp("default_amount", false);
|
||||||
|
|
||||||
frm.add_custom_button(__("Preview Salary Slip"), function() {
|
if(frm.doc.docstatus === 1) {
|
||||||
frm.trigger('preview_salary_slip');
|
frm.add_custom_button(__("Preview Salary Slip"), function() {
|
||||||
});
|
frm.trigger('preview_salary_slip');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if(frm.doc.docstatus==1) {
|
if(frm.doc.docstatus==1) {
|
||||||
frm.add_custom_button(__("Assign Salary Structure"), function() {
|
frm.add_custom_button(__("Assign Salary Structure"), function() {
|
||||||
|
@ -169,5 +169,10 @@ def make_salary_slip(source_name, target_doc = None, employee = None, as_print =
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_employees(salary_structure):
|
def get_employees(salary_structure):
|
||||||
employees = frappe.get_list('Salary Structure Assignment',
|
employees = frappe.get_list('Salary Structure Assignment',
|
||||||
filters={'salary_structure': salary_structure}, fields=['employee'])
|
filters={'salary_structure': salary_structure, 'docstatus': 1}, fields=['employee'])
|
||||||
|
|
||||||
|
if not employees:
|
||||||
|
frappe.throw(_("There's no Employee with Salary Structure: {0}. \
|
||||||
|
Assign {1} to an Employee to preview Salary Slip").format(salary_structure, salary_structure))
|
||||||
|
|
||||||
return list(set([d.employee for d in employees]))
|
return list(set([d.employee for d in employees]))
|
||||||
|
@ -7,6 +7,7 @@ import frappe
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import getdate, nowdate, cint, flt
|
from frappe.utils import getdate, nowdate, cint, flt
|
||||||
|
from frappe.utils.nestedset import get_descendants_of
|
||||||
|
|
||||||
class SubsidiaryCompanyError(frappe.ValidationError): pass
|
class SubsidiaryCompanyError(frappe.ValidationError): pass
|
||||||
class ParentCompanyError(frappe.ValidationError): pass
|
class ParentCompanyError(frappe.ValidationError): pass
|
||||||
@ -131,7 +132,8 @@ def get_designation_counts(designation, company):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
employee_counts = {}
|
employee_counts = {}
|
||||||
company_set = get_company_set(company)
|
company_set = get_descendants_of('Company', company)
|
||||||
|
company_set.append(company)
|
||||||
|
|
||||||
employee_counts["employee_count"] = frappe.db.get_value("Employee",
|
employee_counts["employee_count"] = frappe.db.get_value("Employee",
|
||||||
filters={
|
filters={
|
||||||
@ -168,13 +170,3 @@ def get_active_staffing_plan_details(company, designation, from_date=getdate(now
|
|||||||
|
|
||||||
# Only a single staffing plan can be active for a designation on given date
|
# Only a single staffing plan can be active for a designation on given date
|
||||||
return staffing_plan if staffing_plan else None
|
return staffing_plan if staffing_plan else None
|
||||||
|
|
||||||
def get_company_set(company):
|
|
||||||
return frappe.db.sql_list("""
|
|
||||||
SELECT
|
|
||||||
name
|
|
||||||
FROM `tabCompany`
|
|
||||||
WHERE
|
|
||||||
parent_company=%(company)s
|
|
||||||
OR name=%(company)s
|
|
||||||
""", (dict(company=company)))
|
|
@ -2,4 +2,14 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.query_reports["Department Analytics"] = {
|
frappe.query_reports["Department Analytics"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"fieldname":"company",
|
||||||
|
"label": __("Company"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"default": frappe.defaults.get_user_default("Company"),
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
]
|
||||||
};
|
};
|
@ -7,6 +7,10 @@ from frappe import _
|
|||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
|
|
||||||
|
if not filters["company"]:
|
||||||
|
frappe.throw(_('{0} is mandatory').format(_('Company')))
|
||||||
|
|
||||||
columns = get_columns()
|
columns = get_columns()
|
||||||
employees = get_employees(filters)
|
employees = get_employees(filters)
|
||||||
departments_result = get_department(filters)
|
departments_result = get_department(filters)
|
||||||
@ -28,6 +32,9 @@ def get_conditions(filters):
|
|||||||
conditions = ""
|
conditions = ""
|
||||||
if filters.get("department"): conditions += " and department = '%s'" % \
|
if filters.get("department"): conditions += " and department = '%s'" % \
|
||||||
filters["department"].replace("'", "\\'")
|
filters["department"].replace("'", "\\'")
|
||||||
|
|
||||||
|
if filters.get("company"): conditions += " and company = '%s'" % \
|
||||||
|
filters["company"].replace("'", "\\'")
|
||||||
return conditions
|
return conditions
|
||||||
|
|
||||||
def get_employees(filters):
|
def get_employees(filters):
|
||||||
@ -37,7 +44,7 @@ def get_employees(filters):
|
|||||||
gender, company from `tabEmployee` where status = 'Active' %s""" % conditions, as_list=1)
|
gender, company from `tabEmployee` where status = 'Active' %s""" % conditions, as_list=1)
|
||||||
|
|
||||||
def get_department(filters):
|
def get_department(filters):
|
||||||
return frappe.db.sql("""select name from `tabDepartment`""" , as_list=1)
|
return frappe.db.sql("""select name from `tabDepartment` where company = %s""", (filters["company"]), as_list=1)
|
||||||
|
|
||||||
def get_chart_data(departments,employees):
|
def get_chart_data(departments,employees):
|
||||||
if not departments:
|
if not departments:
|
||||||
|
@ -420,8 +420,12 @@ class BOM(WebsiteGenerator):
|
|||||||
|
|
||||||
def traverse_tree(self, bom_list=None):
|
def traverse_tree(self, bom_list=None):
|
||||||
def _get_children(bom_no):
|
def _get_children(bom_no):
|
||||||
return frappe.db.sql_list("""select bom_no from `tabBOM Item`
|
children = frappe.cache().hget('bom_children', bom_no)
|
||||||
where parent = %s and ifnull(bom_no, '') != '' and parenttype='BOM'""", bom_no)
|
if children is None:
|
||||||
|
children = frappe.db.sql_list("""SELECT `bom_no` FROM `tabBOM Item`
|
||||||
|
WHERE `parent`=%s AND `bom_no`!='' AND `parenttype`='BOM'""", bom_no)
|
||||||
|
frappe.cache().hset('bom_children', bom_no, children)
|
||||||
|
return children
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
if not bom_list:
|
if not bom_list:
|
||||||
@ -534,12 +538,24 @@ class BOM(WebsiteGenerator):
|
|||||||
def get_child_exploded_items(self, bom_no, stock_qty):
|
def get_child_exploded_items(self, bom_no, stock_qty):
|
||||||
""" Add all items from Flat BOM of child BOM"""
|
""" Add all items from Flat BOM of child BOM"""
|
||||||
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
|
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
|
||||||
child_fb_items = frappe.db.sql("""select bom_item.item_code, bom_item.item_name,
|
child_fb_items = frappe.db.sql("""
|
||||||
bom_item.description, bom_item.source_warehouse, bom_item.operation,
|
SELECT
|
||||||
bom_item.stock_uom, bom_item.stock_qty, bom_item.rate, bom_item.include_item_in_manufacturing,
|
bom_item.item_code,
|
||||||
bom_item.stock_qty / ifnull(bom.quantity, 1) as qty_consumed_per_unit
|
bom_item.item_name,
|
||||||
from `tabBOM Explosion Item` bom_item, tabBOM bom
|
bom_item.description,
|
||||||
where bom_item.parent = bom.name and bom.name = %s and bom.docstatus = 1""", bom_no, as_dict = 1)
|
bom_item.source_warehouse,
|
||||||
|
bom_item.operation,
|
||||||
|
bom_item.stock_uom,
|
||||||
|
bom_item.stock_qty,
|
||||||
|
bom_item.rate,
|
||||||
|
bom_item.include_item_in_manufacturing,
|
||||||
|
bom_item.stock_qty / ifnull(bom.quantity, 1) AS qty_consumed_per_unit
|
||||||
|
FROM `tabBOM Explosion Item` bom_item, tabBOM bom
|
||||||
|
WHERE
|
||||||
|
bom_item.parent = bom.name
|
||||||
|
AND bom.name = %s
|
||||||
|
AND bom.docstatus = 1
|
||||||
|
""", bom_no, as_dict = 1)
|
||||||
|
|
||||||
for d in child_fb_items:
|
for d in child_fb_items:
|
||||||
self.add_to_cur_exploded_items(frappe._dict({
|
self.add_to_cur_exploded_items(frappe._dict({
|
||||||
@ -760,6 +776,8 @@ def add_additional_cost(stock_entry, work_order):
|
|||||||
# Add non stock items cost in the additional cost
|
# Add non stock items cost in the additional cost
|
||||||
bom = frappe.get_doc('BOM', work_order.bom_no)
|
bom = frappe.get_doc('BOM', work_order.bom_no)
|
||||||
table = 'exploded_items' if work_order.get('use_multi_level_bom') else 'items'
|
table = 'exploded_items' if work_order.get('use_multi_level_bom') else 'items'
|
||||||
|
expenses_included_in_valuation = frappe.get_cached_value("Company", work_order.company,
|
||||||
|
"expenses_included_in_valuation")
|
||||||
|
|
||||||
items = {}
|
items = {}
|
||||||
for d in bom.get(table):
|
for d in bom.get(table):
|
||||||
@ -770,6 +788,7 @@ def add_additional_cost(stock_entry, work_order):
|
|||||||
|
|
||||||
for name in non_stock_items:
|
for name in non_stock_items:
|
||||||
stock_entry.append('additional_costs', {
|
stock_entry.append('additional_costs', {
|
||||||
|
'expense_account': expenses_included_in_valuation,
|
||||||
'description': name[0],
|
'description': name[0],
|
||||||
'amount': items.get(name[0])
|
'amount': items.get(name[0])
|
||||||
})
|
})
|
||||||
|
@ -14,23 +14,23 @@ class BOMUpdateTool(Document):
|
|||||||
def replace_bom(self):
|
def replace_bom(self):
|
||||||
self.validate_bom()
|
self.validate_bom()
|
||||||
self.update_new_bom()
|
self.update_new_bom()
|
||||||
|
frappe.cache().delete_key('bom_children')
|
||||||
bom_list = self.get_parent_boms(self.new_bom)
|
bom_list = self.get_parent_boms(self.new_bom)
|
||||||
updated_bom = []
|
updated_bom = []
|
||||||
|
|
||||||
for bom in bom_list:
|
for bom in bom_list:
|
||||||
try:
|
try:
|
||||||
bom_obj = frappe.get_doc("BOM", bom)
|
bom_obj = frappe.get_cached_doc('BOM', bom)
|
||||||
bom_obj.load_doc_before_save()
|
# this is only used for versioning and we do not want
|
||||||
updated_bom = bom_obj.update_cost_and_exploded_items(updated_bom)
|
# to make separate db calls by using load_doc_before_save
|
||||||
|
# which proves to be expensive while doing bulk replace
|
||||||
|
bom_obj._doc_before_save = bom_obj.as_dict()
|
||||||
bom_obj.calculate_cost()
|
bom_obj.calculate_cost()
|
||||||
bom_obj.update_parent_cost()
|
bom_obj.update_parent_cost()
|
||||||
bom_obj.db_update()
|
bom_obj.db_update()
|
||||||
if (getattr(bom_obj.meta, 'track_changes', False) and not bom_obj.flags.ignore_version):
|
if bom_obj.meta.get('track_changes') and not bom_obj.flags.ignore_version:
|
||||||
bom_obj.save_version()
|
bom_obj.save_version()
|
||||||
|
|
||||||
frappe.db.commit()
|
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.db.rollback()
|
|
||||||
frappe.log_error(frappe.get_traceback())
|
frappe.log_error(frappe.get_traceback())
|
||||||
|
|
||||||
def validate_bom(self):
|
def validate_bom(self):
|
||||||
@ -42,22 +42,22 @@ class BOMUpdateTool(Document):
|
|||||||
frappe.throw(_("The selected BOMs are not for the same item"))
|
frappe.throw(_("The selected BOMs are not for the same item"))
|
||||||
|
|
||||||
def update_new_bom(self):
|
def update_new_bom(self):
|
||||||
new_bom_unitcost = frappe.db.sql("""select total_cost/quantity
|
new_bom_unitcost = frappe.db.sql("""SELECT `total_cost`/`quantity`
|
||||||
from `tabBOM` where name = %s""", self.new_bom)
|
FROM `tabBOM` WHERE name = %s""", self.new_bom)
|
||||||
new_bom_unitcost = flt(new_bom_unitcost[0][0]) if new_bom_unitcost else 0
|
new_bom_unitcost = flt(new_bom_unitcost[0][0]) if new_bom_unitcost else 0
|
||||||
|
|
||||||
frappe.db.sql("""update `tabBOM Item` set bom_no=%s,
|
frappe.db.sql("""update `tabBOM Item` set bom_no=%s,
|
||||||
rate=%s, amount=stock_qty*%s where bom_no = %s and docstatus < 2 and parenttype='BOM'""",
|
rate=%s, amount=stock_qty*%s where bom_no = %s and docstatus < 2 and parenttype='BOM'""",
|
||||||
(self.new_bom, new_bom_unitcost, new_bom_unitcost, self.current_bom))
|
(self.new_bom, new_bom_unitcost, new_bom_unitcost, self.current_bom))
|
||||||
|
|
||||||
def get_parent_boms(self, bom, bom_list=None):
|
def get_parent_boms(self, bom, bom_list=[]):
|
||||||
if not bom_list:
|
data = frappe.db.sql("""SELECT DISTINCT parent FROM `tabBOM Item`
|
||||||
bom_list = []
|
WHERE bom_no = %s AND docstatus < 2 AND parenttype='BOM'""", bom)
|
||||||
|
|
||||||
data = frappe.db.sql(""" select distinct parent from `tabBOM Item`
|
|
||||||
where bom_no = %s and docstatus < 2 and parenttype='BOM'""", bom)
|
|
||||||
|
|
||||||
for d in data:
|
for d in data:
|
||||||
|
if self.new_bom == d[0]:
|
||||||
|
frappe.throw(_("BOM recursion: {0} cannot be child of {1}").format(bom, self.new_bom))
|
||||||
|
|
||||||
bom_list.append(d[0])
|
bom_list.append(d[0])
|
||||||
self.get_parent_boms(d[0], bom_list)
|
self.get_parent_boms(d[0], bom_list)
|
||||||
|
|
||||||
|
@ -1,443 +1,135 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2017-12-01 12:12:55.048691",
|
"creation": "2017-12-01 12:12:55.048691",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"item_code",
|
||||||
|
"item_name",
|
||||||
|
"warehouse",
|
||||||
|
"material_request_type",
|
||||||
|
"column_break_4",
|
||||||
|
"quantity",
|
||||||
|
"uom",
|
||||||
|
"projected_qty",
|
||||||
|
"actual_qty",
|
||||||
|
"item_details",
|
||||||
|
"description",
|
||||||
|
"min_order_qty",
|
||||||
|
"section_break_8",
|
||||||
|
"sales_order",
|
||||||
|
"requested_qty"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item Code",
|
"label": "Item Code",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Item",
|
"options": "Item",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "item_name",
|
"fieldname": "item_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"label": "Item Name"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "warehouse",
|
"fieldname": "warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Warehouse",
|
"label": "Warehouse",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Warehouse",
|
"options": "Warehouse",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "material_request_type",
|
"fieldname": "material_request_type",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Material Request Type",
|
"label": "Material Request Type",
|
||||||
"length": 0,
|
"options": "\nPurchase\nMaterial Transfer\nMaterial Issue\nManufacture\nCustomer Provided"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "\nPurchase\nMaterial Transfer\nMaterial Issue\nManufacture\nCustomer Provided",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "column_break_4",
|
"fieldname": "column_break_4",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break"
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "quantity",
|
"fieldname": "quantity",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Required Quantity",
|
"label": "Required Quantity",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "projected_qty",
|
"fieldname": "projected_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Projected Qty",
|
"label": "Projected Qty",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"collapsible_depends_on": "",
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "",
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "actual_qty",
|
"fieldname": "actual_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Actual Qty",
|
"label": "Actual Qty",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"permlevel": 0,
|
"read_only": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "min_order_qty",
|
"fieldname": "min_order_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Minimum Order Quantity",
|
"label": "Minimum Order Quantity",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "section_break_8",
|
"fieldname": "section_break_8",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Reference"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Reference",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "sales_order",
|
"fieldname": "sales_order",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Sales Order",
|
"label": "Sales Order",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Sales Order",
|
"options": "Sales Order",
|
||||||
"permlevel": 0,
|
"read_only": 1
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "",
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "requested_qty",
|
"fieldname": "requested_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Requested Qty",
|
"label": "Requested Qty",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
},
|
||||||
"permlevel": 0,
|
{
|
||||||
"precision": "",
|
"collapsible": 1,
|
||||||
"print_hide": 0,
|
"fieldname": "item_details",
|
||||||
"print_hide_if_no_value": 0,
|
"fieldtype": "Section Break",
|
||||||
"read_only": 1,
|
"label": "Item Description"
|
||||||
"remember_last_selected_value": 0,
|
},
|
||||||
"report_hide": 0,
|
{
|
||||||
"reqd": 0,
|
"fieldname": "description",
|
||||||
"search_index": 0,
|
"fieldtype": "Text Editor",
|
||||||
"set_only_once": 0,
|
"label": "Description"
|
||||||
"translatable": 0,
|
},
|
||||||
"unique": 0
|
{
|
||||||
|
"fieldname": "uom",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "UOM",
|
||||||
|
"options": "UOM",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"modified": "2019-11-08 15:15:43.979360",
|
||||||
"modified": "2019-04-08 18:15:26.849602",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Material Request Plan Item",
|
"name": "Material Request Plan Item",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1,
|
"track_changes": 1
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
@ -3,6 +3,11 @@
|
|||||||
|
|
||||||
frappe.ui.form.on('Production Plan', {
|
frappe.ui.form.on('Production Plan', {
|
||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
|
frm.custom_make_buttons = {
|
||||||
|
'Work Order': 'Work Order',
|
||||||
|
'Material Request': 'Material Request',
|
||||||
|
};
|
||||||
|
|
||||||
frm.fields_dict['po_items'].grid.get_field('warehouse').get_query = function(doc) {
|
frm.fields_dict['po_items'].grid.get_field('warehouse').get_query = function(doc) {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
@ -182,8 +187,8 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
get_items_for_mr: function(frm) {
|
get_items_for_mr: function(frm) {
|
||||||
const set_fields = ['actual_qty', 'item_code',
|
const set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom',
|
||||||
'item_name', 'min_order_qty', 'quantity', 'sales_order', 'warehouse', 'projected_qty', 'material_request_type'];
|
'min_order_qty', 'quantity', 'sales_order', 'warehouse', 'projected_qty', 'material_request_type'];
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_items_for_material_requests",
|
method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_items_for_material_requests",
|
||||||
freeze: true,
|
freeze: true,
|
||||||
@ -233,7 +238,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
|
|
||||||
if (item_wise_qty) {
|
if (item_wise_qty) {
|
||||||
for (var key in item_wise_qty) {
|
for (var key in item_wise_qty) {
|
||||||
title += __('Item {0}: {1} qty produced, ', [key, item_wise_qty[key]]);
|
title += __('Item {0}: {1} qty produced. ', [key, item_wise_qty[key]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ class ProductionPlan(Document):
|
|||||||
self.get_mr_items()
|
self.get_mr_items()
|
||||||
|
|
||||||
def get_so_items(self):
|
def get_so_items(self):
|
||||||
so_list = [d.sales_order for d in self.get("sales_orders", []) if d.sales_order]
|
so_list = [d.sales_order for d in self.sales_orders if d.sales_order]
|
||||||
if not so_list:
|
if not so_list:
|
||||||
msgprint(_("Please enter Sales Orders in the above table"))
|
msgprint(_("Please enter Sales Orders in the above table"))
|
||||||
return []
|
return []
|
||||||
@ -109,7 +109,7 @@ class ProductionPlan(Document):
|
|||||||
item_condition = ' and so_item.item_code = {0}'.format(frappe.db.escape(self.item_code))
|
item_condition = ' and so_item.item_code = {0}'.format(frappe.db.escape(self.item_code))
|
||||||
|
|
||||||
items = frappe.db.sql("""select distinct parent, item_code, warehouse,
|
items = frappe.db.sql("""select distinct parent, item_code, warehouse,
|
||||||
(qty - work_order_qty) * conversion_factor as pending_qty, name
|
(qty - work_order_qty) * conversion_factor as pending_qty, description, name
|
||||||
from `tabSales Order Item` so_item
|
from `tabSales Order Item` so_item
|
||||||
where parent in (%s) and docstatus = 1 and qty > work_order_qty
|
where parent in (%s) and docstatus = 1 and qty > work_order_qty
|
||||||
and exists (select name from `tabBOM` bom where bom.item=so_item.item_code
|
and exists (select name from `tabBOM` bom where bom.item=so_item.item_code
|
||||||
@ -121,7 +121,7 @@ class ProductionPlan(Document):
|
|||||||
|
|
||||||
packed_items = frappe.db.sql("""select distinct pi.parent, pi.item_code, pi.warehouse as warehouse,
|
packed_items = frappe.db.sql("""select distinct pi.parent, pi.item_code, pi.warehouse as warehouse,
|
||||||
(((so_item.qty - so_item.work_order_qty) * pi.qty) / so_item.qty)
|
(((so_item.qty - so_item.work_order_qty) * pi.qty) / so_item.qty)
|
||||||
as pending_qty, pi.parent_item, so_item.name
|
as pending_qty, pi.parent_item, pi.description, so_item.name
|
||||||
from `tabSales Order Item` so_item, `tabPacked Item` pi
|
from `tabSales Order Item` so_item, `tabPacked Item` pi
|
||||||
where so_item.parent = pi.parent and so_item.docstatus = 1
|
where so_item.parent = pi.parent and so_item.docstatus = 1
|
||||||
and pi.parent_item = so_item.item_code
|
and pi.parent_item = so_item.item_code
|
||||||
@ -134,7 +134,7 @@ class ProductionPlan(Document):
|
|||||||
self.calculate_total_planned_qty()
|
self.calculate_total_planned_qty()
|
||||||
|
|
||||||
def get_mr_items(self):
|
def get_mr_items(self):
|
||||||
mr_list = [d.material_request for d in self.get("material_requests", []) if d.material_request]
|
mr_list = [d.material_request for d in self.material_requests if d.material_request]
|
||||||
if not mr_list:
|
if not mr_list:
|
||||||
msgprint(_("Please enter Material Requests in the above table"))
|
msgprint(_("Please enter Material Requests in the above table"))
|
||||||
return []
|
return []
|
||||||
@ -143,7 +143,7 @@ class ProductionPlan(Document):
|
|||||||
if self.item_code:
|
if self.item_code:
|
||||||
item_condition = " and mr_item.item_code ={0}".format(frappe.db.escape(self.item_code))
|
item_condition = " and mr_item.item_code ={0}".format(frappe.db.escape(self.item_code))
|
||||||
|
|
||||||
items = frappe.db.sql("""select distinct parent, name, item_code, warehouse,
|
items = frappe.db.sql("""select distinct parent, name, item_code, warehouse, description,
|
||||||
(qty - ordered_qty) as pending_qty
|
(qty - ordered_qty) as pending_qty
|
||||||
from `tabMaterial Request Item` mr_item
|
from `tabMaterial Request Item` mr_item
|
||||||
where parent in (%s) and docstatus = 1 and qty > ordered_qty
|
where parent in (%s) and docstatus = 1 and qty > ordered_qty
|
||||||
@ -162,7 +162,7 @@ class ProductionPlan(Document):
|
|||||||
'include_exploded_items': 1,
|
'include_exploded_items': 1,
|
||||||
'warehouse': data.warehouse,
|
'warehouse': data.warehouse,
|
||||||
'item_code': data.item_code,
|
'item_code': data.item_code,
|
||||||
'description': item_details and item_details.description or '',
|
'description': data.description or item_details.description,
|
||||||
'stock_uom': item_details and item_details.stock_uom or '',
|
'stock_uom': item_details and item_details.stock_uom or '',
|
||||||
'bom_no': item_details and item_details.bom_no or '',
|
'bom_no': item_details and item_details.bom_no or '',
|
||||||
'planned_qty': data.pending_qty,
|
'planned_qty': data.pending_qty,
|
||||||
@ -174,10 +174,12 @@ class ProductionPlan(Document):
|
|||||||
if self.get_items_from == "Sales Order":
|
if self.get_items_from == "Sales Order":
|
||||||
pi.sales_order = data.parent
|
pi.sales_order = data.parent
|
||||||
pi.sales_order_item = data.name
|
pi.sales_order_item = data.name
|
||||||
|
pi.description = data.description
|
||||||
|
|
||||||
elif self.get_items_from == "Material Request":
|
elif self.get_items_from == "Material Request":
|
||||||
pi.material_request = data.parent
|
pi.material_request = data.parent
|
||||||
pi.material_request_item = data.name
|
pi.material_request_item = data.name
|
||||||
|
pi.description = data.description
|
||||||
|
|
||||||
def calculate_total_planned_qty(self):
|
def calculate_total_planned_qty(self):
|
||||||
self.total_planned_qty = 0
|
self.total_planned_qty = 0
|
||||||
@ -195,7 +197,6 @@ class ProductionPlan(Document):
|
|||||||
for data in self.po_items:
|
for data in self.po_items:
|
||||||
if data.name == production_plan_item:
|
if data.name == production_plan_item:
|
||||||
data.produced_qty = produced_qty
|
data.produced_qty = produced_qty
|
||||||
data.pending_qty = data.planned_qty - data.produced_qty
|
|
||||||
data.db_update()
|
data.db_update()
|
||||||
|
|
||||||
self.calculate_total_produced_qty()
|
self.calculate_total_produced_qty()
|
||||||
@ -302,6 +303,7 @@ class ProductionPlan(Document):
|
|||||||
wo_list.extend(work_orders)
|
wo_list.extend(work_orders)
|
||||||
|
|
||||||
frappe.flags.mute_messages = False
|
frappe.flags.mute_messages = False
|
||||||
|
|
||||||
if wo_list:
|
if wo_list:
|
||||||
wo_list = ["""<a href="#Form/Work Order/%s" target="_blank">%s</a>""" % \
|
wo_list = ["""<a href="#Form/Work Order/%s" target="_blank">%s</a>""" % \
|
||||||
(p, p) for p in wo_list]
|
(p, p) for p in wo_list]
|
||||||
@ -309,16 +311,15 @@ class ProductionPlan(Document):
|
|||||||
else :
|
else :
|
||||||
msgprint(_("No Work Orders created"))
|
msgprint(_("No Work Orders created"))
|
||||||
|
|
||||||
|
|
||||||
def make_work_order_for_sub_assembly_items(self, item):
|
def make_work_order_for_sub_assembly_items(self, item):
|
||||||
work_orders = []
|
work_orders = []
|
||||||
bom_data = {}
|
bom_data = {}
|
||||||
|
|
||||||
get_sub_assembly_items(item.get("bom_no"), bom_data, item.get("qty"))
|
get_sub_assembly_items(item.get("bom_no"), bom_data)
|
||||||
|
|
||||||
for key, data in bom_data.items():
|
for key, data in bom_data.items():
|
||||||
data.update({
|
data.update({
|
||||||
'qty': data.get("stock_qty"),
|
'qty': data.get("stock_qty") * item.get("qty"),
|
||||||
'production_plan': self.name,
|
'production_plan': self.name,
|
||||||
'company': self.company,
|
'company': self.company,
|
||||||
'fg_warehouse': item.get("fg_warehouse"),
|
'fg_warehouse': item.get("fg_warehouse"),
|
||||||
@ -528,6 +529,7 @@ def get_material_request_items(row, sales_order,
|
|||||||
required_qty = ceil(required_qty)
|
required_qty = ceil(required_qty)
|
||||||
|
|
||||||
if required_qty > 0:
|
if required_qty > 0:
|
||||||
|
print(row)
|
||||||
return {
|
return {
|
||||||
'item_code': row.item_code,
|
'item_code': row.item_code,
|
||||||
'item_name': row.item_name,
|
'item_name': row.item_name,
|
||||||
@ -540,7 +542,9 @@ def get_material_request_items(row, sales_order,
|
|||||||
'projected_qty': bin_dict.get("projected_qty", 0),
|
'projected_qty': bin_dict.get("projected_qty", 0),
|
||||||
'min_order_qty': row['min_order_qty'],
|
'min_order_qty': row['min_order_qty'],
|
||||||
'material_request_type': row.get("default_material_request_type"),
|
'material_request_type': row.get("default_material_request_type"),
|
||||||
'sales_order': sales_order
|
'sales_order': sales_order,
|
||||||
|
'description': row.get("description"),
|
||||||
|
'uom': row.get("purchase_uom") or row.get("stock_uom")
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_sales_orders(self):
|
def get_sales_orders(self):
|
||||||
@ -558,7 +562,7 @@ def get_sales_orders(self):
|
|||||||
item_filter += " and so_item.item_code = %(item)s"
|
item_filter += " and so_item.item_code = %(item)s"
|
||||||
|
|
||||||
open_so = frappe.db.sql("""
|
open_so = frappe.db.sql("""
|
||||||
select distinct so.name, so.transaction_date, so.customer, so.base_grand_total as grand_total
|
select distinct so.name, so.transaction_date, so.customer, so.base_grand_total
|
||||||
from `tabSales Order` so, `tabSales Order Item` so_item
|
from `tabSales Order` so, `tabSales Order Item` so_item
|
||||||
where so_item.parent = so.name
|
where so_item.parent = so.name
|
||||||
and so.docstatus = 1 and so.status not in ("Stopped", "Closed")
|
and so.docstatus = 1 and so.status not in ("Stopped", "Closed")
|
||||||
@ -622,7 +626,7 @@ def get_items_for_material_requests(doc, ignore_existing_ordered_qty=None):
|
|||||||
for data in po_items:
|
for data in po_items:
|
||||||
planned_qty = data.get('required_qty') or data.get('planned_qty')
|
planned_qty = data.get('required_qty') or data.get('planned_qty')
|
||||||
ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or ignore_existing_ordered_qty
|
ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or ignore_existing_ordered_qty
|
||||||
warehouse = warehouse or data.get("warehouse")
|
warehouse = data.get("warehouse") or warehouse
|
||||||
|
|
||||||
item_details = {}
|
item_details = {}
|
||||||
if data.get("bom") or data.get("bom_no"):
|
if data.get("bom") or data.get("bom_no"):
|
||||||
@ -705,11 +709,11 @@ def get_item_data(item_code):
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
"bom_no": item_details.get("bom_no"),
|
"bom_no": item_details.get("bom_no"),
|
||||||
"stock_uom": item_details.get("stock_uom"),
|
"stock_uom": item_details.get("stock_uom")
|
||||||
"description": item_details.get("description")
|
# "description": item_details.get("description")
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_sub_assembly_items(bom_no, bom_data, qty):
|
def get_sub_assembly_items(bom_no, bom_data):
|
||||||
data = get_children('BOM', parent = bom_no)
|
data = get_children('BOM', parent = bom_no)
|
||||||
for d in data:
|
for d in data:
|
||||||
if d.expandable:
|
if d.expandable:
|
||||||
@ -726,6 +730,6 @@ def get_sub_assembly_items(bom_no, bom_data, qty):
|
|||||||
})
|
})
|
||||||
|
|
||||||
bom_item = bom_data.get(key)
|
bom_item = bom_data.get(key)
|
||||||
bom_item["stock_qty"] += ((d.stock_qty * qty) / d.parent_bom_qty)
|
bom_item["stock_qty"] += d.stock_qty
|
||||||
|
|
||||||
get_sub_assembly_items(bom_item.get("bom_no"), bom_data, bom_item["stock_qty"])
|
get_sub_assembly_items(bom_item.get("bom_no"), bom_data)
|
||||||
|
@ -11,11 +11,9 @@ from erpnext.manufacturing.doctype.production_plan.production_plan import get_sa
|
|||||||
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
|
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
|
||||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
from erpnext.manufacturing.doctype.production_plan.production_plan import get_items_for_material_requests
|
from erpnext.manufacturing.doctype.production_plan.production_plan import get_items_for_material_requests
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
|
||||||
|
|
||||||
class TestProductionPlan(unittest.TestCase):
|
class TestProductionPlan(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
set_perpetual_inventory(0)
|
|
||||||
for item in ['Test Production Item 1', 'Subassembly Item 1',
|
for item in ['Test Production Item 1', 'Subassembly Item 1',
|
||||||
'Raw Material Item 1', 'Raw Material Item 2']:
|
'Raw Material Item 1', 'Raw Material Item 2']:
|
||||||
create_item(item, valuation_rate=100)
|
create_item(item, valuation_rate=100)
|
||||||
|
@ -395,6 +395,11 @@ frappe.ui.form.on("Work Order", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
additional_operating_cost: function(frm) {
|
||||||
|
erpnext.work_order.calculate_cost(frm.doc);
|
||||||
|
erpnext.work_order.calculate_total_cost(frm);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -534,8 +539,7 @@ erpnext.work_order = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
calculate_total_cost: function(frm) {
|
calculate_total_cost: function(frm) {
|
||||||
var variable_cost = frm.doc.actual_operating_cost ?
|
let variable_cost = flt(frm.doc.actual_operating_cost) || flt(frm.doc.planned_operating_cost);
|
||||||
flt(frm.doc.actual_operating_cost) : flt(frm.doc.planned_operating_cost);
|
|
||||||
frm.set_value("total_operating_cost", (flt(frm.doc.additional_operating_cost) + variable_cost));
|
frm.set_value("total_operating_cost", (flt(frm.doc.additional_operating_cost) + variable_cost));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -223,7 +223,15 @@ class WorkOrder(Document):
|
|||||||
|
|
||||||
def update_production_plan_status(self):
|
def update_production_plan_status(self):
|
||||||
production_plan = frappe.get_doc('Production Plan', self.production_plan)
|
production_plan = frappe.get_doc('Production Plan', self.production_plan)
|
||||||
production_plan.run_method("update_produced_qty", self.produced_qty, self.production_plan_item)
|
produced_qty = 0
|
||||||
|
if self.production_plan_item:
|
||||||
|
total_qty = frappe.get_all("Work Order", fields = "sum(produced_qty) as produced_qty",
|
||||||
|
filters = {'docstatus': 1, 'production_plan': self.production_plan,
|
||||||
|
'production_plan_item': self.production_plan_item}, as_list=1)
|
||||||
|
|
||||||
|
produced_qty = total_qty[0][0] if total_qty else 0
|
||||||
|
|
||||||
|
production_plan.run_method("update_produced_qty", produced_qty, self.production_plan_item)
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
if not self.wip_warehouse:
|
if not self.wip_warehouse:
|
||||||
@ -645,7 +653,8 @@ def make_stock_entry(work_order_id, purpose, qty=None):
|
|||||||
stock_entry.to_warehouse = work_order.fg_warehouse
|
stock_entry.to_warehouse = work_order.fg_warehouse
|
||||||
stock_entry.project = work_order.project
|
stock_entry.project = work_order.project
|
||||||
if purpose=="Manufacture":
|
if purpose=="Manufacture":
|
||||||
additional_costs = get_additional_costs(work_order, fg_qty=stock_entry.fg_completed_qty)
|
additional_costs = get_additional_costs(work_order, fg_qty=stock_entry.fg_completed_qty,
|
||||||
|
company=work_order.company)
|
||||||
stock_entry.set("additional_costs", additional_costs)
|
stock_entry.set("additional_costs", additional_costs)
|
||||||
|
|
||||||
stock_entry.set_stock_entry_type()
|
stock_entry.set_stock_entry_type()
|
||||||
|
@ -638,6 +638,11 @@ erpnext.patches.v12_0.add_variant_of_in_item_attribute_table
|
|||||||
erpnext.patches.v12_0.rename_bank_account_field_in_journal_entry_account
|
erpnext.patches.v12_0.rename_bank_account_field_in_journal_entry_account
|
||||||
erpnext.patches.v12_0.create_default_energy_point_rules
|
erpnext.patches.v12_0.create_default_energy_point_rules
|
||||||
erpnext.patches.v12_0.set_produced_qty_field_in_sales_order_for_work_order
|
erpnext.patches.v12_0.set_produced_qty_field_in_sales_order_for_work_order
|
||||||
erpnext.patches.v12_0.generate_leave_ledger_entries
|
|
||||||
erpnext.patches.v12_0.set_default_shopify_app_type
|
erpnext.patches.v12_0.set_default_shopify_app_type
|
||||||
|
erpnext.patches.v12_0.set_cwip_and_delete_asset_settings
|
||||||
|
erpnext.patches.v12_0.set_expense_account_in_landed_cost_voucher_taxes
|
||||||
erpnext.patches.v12_0.replace_accounting_with_accounts_in_home_settings
|
erpnext.patches.v12_0.replace_accounting_with_accounts_in_home_settings
|
||||||
|
erpnext.patches.v12_0.set_payment_entry_status
|
||||||
|
erpnext.patches.v12_0.update_owner_fields_in_acc_dimension_custom_fields
|
||||||
|
erpnext.patches.v12_0.set_default_for_add_taxes_from_item_tax_template
|
||||||
|
erpnext.patches.v12_0.remove_denied_leaves_from_leave_ledger
|
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
|
frappe.reload_doc('setup', 'doctype', 'global_defaults', force=True)
|
||||||
frappe.reload_doc('stock', 'doctype', 'delivery_trip')
|
frappe.reload_doc('stock', 'doctype', 'delivery_trip')
|
||||||
frappe.reload_doc('stock', 'doctype', 'delivery_stop', force=True)
|
frappe.reload_doc('stock', 'doctype', 'delivery_stop', force=True)
|
||||||
|
|
||||||
|
@ -1,20 +1,30 @@
|
|||||||
import frappe
|
import frappe
|
||||||
import json
|
import json
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
|
from frappe.model.naming import make_autoname
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
if "tax_type" not in frappe.db.get_table_columns("Item Tax"):
|
if "tax_type" not in frappe.db.get_table_columns("Item Tax"):
|
||||||
return
|
return
|
||||||
old_item_taxes = {}
|
old_item_taxes = {}
|
||||||
item_tax_templates = {}
|
item_tax_templates = {}
|
||||||
rename_template_to_untitled = []
|
|
||||||
|
frappe.reload_doc("accounts", "doctype", "item_tax_template_detail", force=1)
|
||||||
|
frappe.reload_doc("accounts", "doctype", "item_tax_template", force=1)
|
||||||
|
existing_templates = frappe.db.sql("""select template.name, details.tax_type, details.tax_rate
|
||||||
|
from `tabItem Tax Template` template, `tabItem Tax Template Detail` details
|
||||||
|
where details.parent=template.name
|
||||||
|
""", as_dict=1)
|
||||||
|
|
||||||
|
if len(existing_templates):
|
||||||
|
for d in existing_templates:
|
||||||
|
item_tax_templates.setdefault(d.name, {})
|
||||||
|
item_tax_templates[d.name][d.tax_type] = d.tax_rate
|
||||||
|
|
||||||
for d in frappe.db.sql("""select parent as item_code, tax_type, tax_rate from `tabItem Tax`""", as_dict=1):
|
for d in frappe.db.sql("""select parent as item_code, tax_type, tax_rate from `tabItem Tax`""", as_dict=1):
|
||||||
old_item_taxes.setdefault(d.item_code, [])
|
old_item_taxes.setdefault(d.item_code, [])
|
||||||
old_item_taxes[d.item_code].append(d)
|
old_item_taxes[d.item_code].append(d)
|
||||||
|
|
||||||
frappe.reload_doc("accounts", "doctype", "item_tax_template_detail", force=1)
|
|
||||||
frappe.reload_doc("accounts", "doctype", "item_tax_template", force=1)
|
|
||||||
frappe.reload_doc("stock", "doctype", "item", force=1)
|
frappe.reload_doc("stock", "doctype", "item", force=1)
|
||||||
frappe.reload_doc("stock", "doctype", "item_tax", force=1)
|
frappe.reload_doc("stock", "doctype", "item_tax", force=1)
|
||||||
frappe.reload_doc("selling", "doctype", "quotation_item", force=1)
|
frappe.reload_doc("selling", "doctype", "quotation_item", force=1)
|
||||||
@ -27,6 +37,8 @@ def execute():
|
|||||||
frappe.reload_doc("accounts", "doctype", "purchase_invoice_item", force=1)
|
frappe.reload_doc("accounts", "doctype", "purchase_invoice_item", force=1)
|
||||||
frappe.reload_doc("accounts", "doctype", "accounts_settings", force=1)
|
frappe.reload_doc("accounts", "doctype", "accounts_settings", force=1)
|
||||||
|
|
||||||
|
frappe.db.auto_commit_on_many_writes = True
|
||||||
|
|
||||||
# for each item that have item tax rates
|
# for each item that have item tax rates
|
||||||
for item_code in old_item_taxes.keys():
|
for item_code in old_item_taxes.keys():
|
||||||
# make current item's tax map
|
# make current item's tax map
|
||||||
@ -34,8 +46,7 @@ def execute():
|
|||||||
for d in old_item_taxes[item_code]:
|
for d in old_item_taxes[item_code]:
|
||||||
item_tax_map[d.tax_type] = d.tax_rate
|
item_tax_map[d.tax_type] = d.tax_rate
|
||||||
|
|
||||||
item_tax_template_name = get_item_tax_template(item_tax_templates, rename_template_to_untitled,
|
item_tax_template_name = get_item_tax_template(item_tax_templates, item_tax_map, item_code)
|
||||||
item_tax_map, item_code)
|
|
||||||
|
|
||||||
# update the item tax table
|
# update the item tax table
|
||||||
item = frappe.get_doc("Item", item_code)
|
item = frappe.get_doc("Item", item_code)
|
||||||
@ -49,35 +60,33 @@ def execute():
|
|||||||
'Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice',
|
'Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice',
|
||||||
'Supplier Quotation', 'Purchase Order', 'Purchase Receipt', 'Purchase Invoice'
|
'Supplier Quotation', 'Purchase Order', 'Purchase Receipt', 'Purchase Invoice'
|
||||||
]
|
]
|
||||||
|
|
||||||
for dt in doctypes:
|
for dt in doctypes:
|
||||||
for d in frappe.db.sql("""select name, parent, item_code, item_tax_rate from `tab{0} Item`
|
for d in frappe.db.sql("""select name, parent, item_code, item_tax_rate from `tab{0} Item`
|
||||||
where ifnull(item_tax_rate, '') not in ('', '{{}}')""".format(dt), as_dict=1):
|
where ifnull(item_tax_rate, '') not in ('', '{{}}')
|
||||||
|
and item_tax_template is NULL""".format(dt), as_dict=1):
|
||||||
item_tax_map = json.loads(d.item_tax_rate)
|
item_tax_map = json.loads(d.item_tax_rate)
|
||||||
item_tax_template = get_item_tax_template(item_tax_templates, rename_template_to_untitled,
|
item_tax_template_name = get_item_tax_template(item_tax_templates,
|
||||||
item_tax_map, d.item_code, d.parent)
|
item_tax_map, d.item_code, d.parent)
|
||||||
frappe.db.set_value(dt + " Item", d.name, "item_tax_template", item_tax_template)
|
frappe.db.set_value(dt + " Item", d.name, "item_tax_template", item_tax_template_name)
|
||||||
|
|
||||||
idx = 1
|
frappe.db.auto_commit_on_many_writes = False
|
||||||
for oldname in rename_template_to_untitled:
|
|
||||||
frappe.rename_doc("Item Tax Template", oldname, "Untitled {}".format(idx))
|
|
||||||
idx += 1
|
|
||||||
|
|
||||||
settings = frappe.get_single("Accounts Settings")
|
settings = frappe.get_single("Accounts Settings")
|
||||||
settings.add_taxes_from_item_tax_template = 0
|
settings.add_taxes_from_item_tax_template = 0
|
||||||
settings.determine_address_tax_category_from = "Billing Address"
|
settings.determine_address_tax_category_from = "Billing Address"
|
||||||
settings.save()
|
settings.save()
|
||||||
|
|
||||||
def get_item_tax_template(item_tax_templates, rename_template_to_untitled, item_tax_map, item_code, parent=None):
|
def get_item_tax_template(item_tax_templates, item_tax_map, item_code, parent=None):
|
||||||
# search for previously created item tax template by comparing tax maps
|
# search for previously created item tax template by comparing tax maps
|
||||||
for template, item_tax_template_map in iteritems(item_tax_templates):
|
for template, item_tax_template_map in iteritems(item_tax_templates):
|
||||||
if item_tax_map == item_tax_template_map:
|
if item_tax_map == item_tax_template_map:
|
||||||
if not parent:
|
|
||||||
rename_template_to_untitled.append(template)
|
|
||||||
return template
|
return template
|
||||||
|
|
||||||
# if no item tax template found, create one
|
# if no item tax template found, create one
|
||||||
item_tax_template = frappe.new_doc("Item Tax Template")
|
item_tax_template = frappe.new_doc("Item Tax Template")
|
||||||
item_tax_template.title = "{}--{}".format(parent, item_code) if parent else "Item-{}".format(item_code)
|
item_tax_template.title = make_autoname("Item Tax Template-.####")
|
||||||
|
|
||||||
for tax_type, tax_rate in iteritems(item_tax_map):
|
for tax_type, tax_rate in iteritems(item_tax_map):
|
||||||
if not frappe.db.exists("Account", tax_type):
|
if not frappe.db.exists("Account", tax_type):
|
||||||
parts = tax_type.strip().split(" - ")
|
parts = tax_type.strip().split(" - ")
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
# Copyright (c) 2018, Frappe and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe.utils import getdate, today
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
''' Delete leave ledger entry created
|
||||||
|
via leave applications with status != Approved '''
|
||||||
|
if not frappe.db.a_row_exists("Leave Ledger Entry"):
|
||||||
|
return
|
||||||
|
|
||||||
|
leave_application_list = get_denied_leave_application_list()
|
||||||
|
if leave_application_list:
|
||||||
|
delete_denied_leaves_from_leave_ledger_entry(leave_application_list)
|
||||||
|
|
||||||
|
def get_denied_leave_application_list():
|
||||||
|
return frappe.db.sql_list(''' Select name from `tabLeave Application` where status <> 'Approved' ''')
|
||||||
|
|
||||||
|
def delete_denied_leaves_from_leave_ledger_entry(leave_application_list):
|
||||||
|
if leave_application_list:
|
||||||
|
frappe.db.sql(''' Delete
|
||||||
|
FROM `tabLeave Ledger Entry`
|
||||||
|
WHERE
|
||||||
|
transaction_type = 'Leave Application'
|
||||||
|
AND transaction_name in (%s) ''' % (', '.join(['%s'] * len(leave_application_list))), #nosec
|
||||||
|
tuple(leave_application_list))
|
21
erpnext/patches/v12_0/set_cwip_and_delete_asset_settings.py
Normal file
21
erpnext/patches/v12_0/set_cwip_and_delete_asset_settings.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe.utils import cint
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
'''Get 'Disable CWIP Accounting value' from Asset Settings, set it in 'Enable Capital Work in Progress Accounting' field
|
||||||
|
in Company, delete Asset Settings '''
|
||||||
|
|
||||||
|
if frappe.db.exists("DocType","Asset Settings"):
|
||||||
|
frappe.reload_doctype("Company")
|
||||||
|
cwip_value = frappe.db.get_single_value("Asset Settings","disable_cwip_accounting")
|
||||||
|
|
||||||
|
companies = [x['name'] for x in frappe.get_all("Company", "name")]
|
||||||
|
for company in companies:
|
||||||
|
enable_cwip_accounting = cint(not cint(cwip_value))
|
||||||
|
frappe.db.set_value("Company", company, "enable_cwip_accounting", enable_cwip_accounting)
|
||||||
|
|
||||||
|
frappe.db.sql(
|
||||||
|
""" DELETE FROM `tabSingles` where doctype = 'Asset Settings' """)
|
||||||
|
frappe.delete_doc_if_exists("DocType","Asset Settings")
|
@ -0,0 +1,5 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.db.set_value("Accounts Settings", None, "add_taxes_from_item_tax_template", 1)
|
||||||
|
frappe.db.set_default("add_taxes_from_item_tax_template", 1)
|
@ -0,0 +1,33 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from six import iteritems
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doctype('Landed Cost Taxes and Charges')
|
||||||
|
|
||||||
|
company_account_map = frappe._dict(frappe.db.sql("""
|
||||||
|
SELECT name, expenses_included_in_valuation from `tabCompany`
|
||||||
|
"""))
|
||||||
|
|
||||||
|
for company, account in iteritems(company_account_map):
|
||||||
|
frappe.db.sql("""
|
||||||
|
UPDATE
|
||||||
|
`tabLanded Cost Taxes and Charges` t, `tabLanded Cost Voucher` l
|
||||||
|
SET
|
||||||
|
t.expense_account = %s
|
||||||
|
WHERE
|
||||||
|
l.docstatus = 1
|
||||||
|
AND l.company = %s
|
||||||
|
AND t.parent = l.name
|
||||||
|
""", (account, company))
|
||||||
|
|
||||||
|
frappe.db.sql("""
|
||||||
|
UPDATE
|
||||||
|
`tabLanded Cost Taxes and Charges` t, `tabStock Entry` s
|
||||||
|
SET
|
||||||
|
t.expense_account = %s
|
||||||
|
WHERE
|
||||||
|
s.docstatus = 1
|
||||||
|
AND s.company = %s
|
||||||
|
AND t.parent = s.name
|
||||||
|
""", (account, company))
|
9
erpnext/patches/v12_0/set_payment_entry_status.py
Normal file
9
erpnext/patches/v12_0/set_payment_entry_status.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doctype("Payment Entry")
|
||||||
|
frappe.db.sql("""update `tabPayment Entry` set status = CASE
|
||||||
|
WHEN docstatus = 1 THEN 'Submitted'
|
||||||
|
WHEN docstatus = 2 THEN 'Cancelled'
|
||||||
|
ELSE 'Draft'
|
||||||
|
END;""")
|
@ -0,0 +1,17 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_doctypes_with_dimensions
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
accounting_dimensions = frappe.db.sql("""select fieldname from
|
||||||
|
`tabAccounting Dimension`""", as_dict=1)
|
||||||
|
|
||||||
|
doclist = get_doctypes_with_dimensions()
|
||||||
|
|
||||||
|
for dimension in accounting_dimensions:
|
||||||
|
frappe.db.sql("""
|
||||||
|
UPDATE `tabCustom Field`
|
||||||
|
SET owner = 'Administrator'
|
||||||
|
WHERE fieldname = %s
|
||||||
|
AND dt IN (%s)""" % #nosec
|
||||||
|
('%s', ', '.join(['%s']* len(doclist))), tuple([dimension.fieldname] + doclist))
|
@ -19,7 +19,7 @@ frappe.ui.form.on("Project", {
|
|||||||
frappe.ui.form.make_quick_entry(doctype, null, null, new_doc);
|
frappe.ui.form.make_quick_entry(doctype, null, null, new_doc);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
onload: function (frm) {
|
onload: function (frm) {
|
||||||
var so = frappe.meta.get_docfield("Project", "sales_order");
|
var so = frappe.meta.get_docfield("Project", "sales_order");
|
||||||
@ -28,15 +28,15 @@ frappe.ui.form.on("Project", {
|
|||||||
return {
|
return {
|
||||||
"customer": frm.doc.customer,
|
"customer": frm.doc.customer,
|
||||||
"project_name": frm.doc.name
|
"project_name": frm.doc.name
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
frm.set_query('customer', 'erpnext.controllers.queries.customer_query');
|
frm.set_query('customer', 'erpnext.controllers.queries.customer_query');
|
||||||
|
|
||||||
frm.set_query("user", "users", function () {
|
frm.set_query("user", "users", function () {
|
||||||
return {
|
return {
|
||||||
query: "erpnext.projects.doctype.project.project.get_users_for_project"
|
query: "erpnext.projects.doctype.project.project.get_users_for_project"
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// sales order
|
// sales order
|
||||||
@ -51,8 +51,35 @@ frappe.ui.form.on("Project", {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
filters: filters
|
filters: filters
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
refresh: function (frm) {
|
||||||
|
if (frm.doc.__islocal) {
|
||||||
|
frm.web_link && frm.web_link.remove();
|
||||||
|
} else {
|
||||||
|
frm.add_web_link("/projects?project=" + encodeURIComponent(frm.doc.name));
|
||||||
|
|
||||||
|
frm.trigger('show_dashboard');
|
||||||
|
}
|
||||||
|
frm.events.set_buttons(frm);
|
||||||
|
},
|
||||||
|
|
||||||
|
set_buttons: function(frm) {
|
||||||
|
if (!frm.is_new()) {
|
||||||
|
frm.add_custom_button(__('Duplicate Project with Tasks'), () => {
|
||||||
|
frm.events.create_duplicate(frm);
|
||||||
|
});
|
||||||
|
|
||||||
|
frm.add_custom_button(__('Completed'), () => {
|
||||||
|
frm.events.set_status(frm, 'Completed');
|
||||||
|
}, __('Set Status'));
|
||||||
|
|
||||||
|
frm.add_custom_button(__('Cancelled'), () => {
|
||||||
|
frm.events.set_status(frm, 'Cancelled');
|
||||||
|
}, __('Set Status'));
|
||||||
|
}
|
||||||
|
|
||||||
if (frappe.model.can_read("Task")) {
|
if (frappe.model.can_read("Task")) {
|
||||||
frm.add_custom_button(__("Gantt Chart"), function () {
|
frm.add_custom_button(__("Gantt Chart"), function () {
|
||||||
@ -72,27 +99,20 @@ frappe.ui.form.on("Project", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function (frm) {
|
create_duplicate: function(frm) {
|
||||||
if (frm.doc.__islocal) {
|
return new Promise(resolve => {
|
||||||
frm.web_link && frm.web_link.remove();
|
frappe.prompt('Project Name', (data) => {
|
||||||
} else {
|
frappe.xcall('erpnext.projects.doctype.project.project.create_duplicate_project',
|
||||||
frm.add_web_link("/projects?project=" + encodeURIComponent(frm.doc.name));
|
{
|
||||||
|
prev_doc: frm.doc,
|
||||||
frm.trigger('show_dashboard');
|
project_name: data.value
|
||||||
}
|
}).then(() => {
|
||||||
frm.events.set_buttons(frm);
|
frappe.set_route('Form', "Project", data.value);
|
||||||
},
|
frappe.show_alert(__("Duplicate project has been created"));
|
||||||
|
});
|
||||||
set_buttons: function(frm) {
|
resolve();
|
||||||
if (!frm.is_new()) {
|
});
|
||||||
frm.add_custom_button(__('Completed'), () => {
|
});
|
||||||
frm.events.set_status(frm, 'Completed');
|
|
||||||
}, __('Set Status'));
|
|
||||||
|
|
||||||
frm.add_custom_button(__('Cancelled'), () => {
|
|
||||||
frm.events.set_status(frm, 'Cancelled');
|
|
||||||
}, __('Set Status'));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
set_status: function(frm, status) {
|
set_status: function(frm, status) {
|
||||||
|
@ -323,6 +323,37 @@ def allow_to_make_project_update(project, time, frequency):
|
|||||||
if get_time(nowtime()) >= get_time(time):
|
if get_time(nowtime()) >= get_time(time):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def create_duplicate_project(prev_doc, project_name):
|
||||||
|
''' Create duplicate project based on the old project '''
|
||||||
|
import json
|
||||||
|
prev_doc = json.loads(prev_doc)
|
||||||
|
|
||||||
|
if project_name == prev_doc.get('name'):
|
||||||
|
frappe.throw(_("Use a name that is different from previous project name"))
|
||||||
|
|
||||||
|
# change the copied doc name to new project name
|
||||||
|
project = frappe.copy_doc(prev_doc)
|
||||||
|
project.name = project_name
|
||||||
|
project.project_template = ''
|
||||||
|
project.project_name = project_name
|
||||||
|
project.insert()
|
||||||
|
|
||||||
|
# fetch all the task linked with the old project
|
||||||
|
task_list = frappe.get_all("Task", filters={
|
||||||
|
'project': prev_doc.get('name')
|
||||||
|
}, fields=['name'])
|
||||||
|
|
||||||
|
# Create duplicate task for all the task
|
||||||
|
for task in task_list:
|
||||||
|
task = frappe.get_doc('Task', task)
|
||||||
|
new_task = frappe.copy_doc(task)
|
||||||
|
new_task.project = project.name
|
||||||
|
new_task.insert()
|
||||||
|
|
||||||
|
project.db_set('project_template', prev_doc.get('project_template'))
|
||||||
|
|
||||||
def get_projects_for_collect_progress(frequency, fields):
|
def get_projects_for_collect_progress(frequency, fields):
|
||||||
fields.extend(["name"])
|
fields.extend(["name"])
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ from frappe import _, throw
|
|||||||
from frappe.utils import add_days, cstr, date_diff, get_link_to_form, getdate
|
from frappe.utils import add_days, cstr, date_diff, get_link_to_form, getdate
|
||||||
from frappe.utils.nestedset import NestedSet
|
from frappe.utils.nestedset import NestedSet
|
||||||
from frappe.desk.form.assign_to import close_all_assignments, clear
|
from frappe.desk.form.assign_to import close_all_assignments, clear
|
||||||
|
from frappe.utils import date_diff
|
||||||
|
|
||||||
class CircularReferenceError(frappe.ValidationError): pass
|
class CircularReferenceError(frappe.ValidationError): pass
|
||||||
class EndDateCannotBeGreaterThanProjectEndDateError(frappe.ValidationError): pass
|
class EndDateCannotBeGreaterThanProjectEndDateError(frappe.ValidationError): pass
|
||||||
@ -28,16 +29,29 @@ class Task(NestedSet):
|
|||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_dates()
|
self.validate_dates()
|
||||||
|
self.validate_parent_project_dates()
|
||||||
self.validate_progress()
|
self.validate_progress()
|
||||||
self.validate_status()
|
self.validate_status()
|
||||||
self.update_depends_on()
|
self.update_depends_on()
|
||||||
|
|
||||||
def validate_dates(self):
|
def validate_dates(self):
|
||||||
if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date):
|
if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date):
|
||||||
frappe.throw(_("'Expected Start Date' can not be greater than 'Expected End Date'"))
|
frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Expected Start Date"), \
|
||||||
|
frappe.bold("Expected End Date")))
|
||||||
|
|
||||||
if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date):
|
if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date):
|
||||||
frappe.throw(_("'Actual Start Date' can not be greater than 'Actual End Date'"))
|
frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Actual Start Date"), \
|
||||||
|
frappe.bold("Actual End Date")))
|
||||||
|
|
||||||
|
def validate_parent_project_dates(self):
|
||||||
|
if not self.project or frappe.flags.in_test:
|
||||||
|
return
|
||||||
|
|
||||||
|
expected_end_date = getdate(frappe.db.get_value("Project", self.project, "expected_end_date"))
|
||||||
|
|
||||||
|
if expected_end_date:
|
||||||
|
validate_project_dates(expected_end_date, self, "exp_start_date", "exp_end_date", "Expected")
|
||||||
|
validate_project_dates(expected_end_date, self, "act_start_date", "act_end_date", "Actual")
|
||||||
|
|
||||||
def validate_status(self):
|
def validate_status(self):
|
||||||
if self.status!=self.get_db_value("status") and self.status == "Completed":
|
if self.status!=self.get_db_value("status") and self.status == "Completed":
|
||||||
@ -255,3 +269,10 @@ def add_multiple_tasks(data, parent):
|
|||||||
|
|
||||||
def on_doctype_update():
|
def on_doctype_update():
|
||||||
frappe.db.add_index("Task", ["lft", "rgt"])
|
frappe.db.add_index("Task", ["lft", "rgt"])
|
||||||
|
|
||||||
|
def validate_project_dates(project_end_date, task, task_start, task_end, actual_or_expected_date):
|
||||||
|
if task.get(task_start) and date_diff(project_end_date, getdate(task.get(task_start))) < 0:
|
||||||
|
frappe.throw(_("Task's {0} Start Date cannot be after Project's End Date.").format(actual_or_expected_date))
|
||||||
|
|
||||||
|
if task.get(task_end) and date_diff(project_end_date, getdate(task.get(task_end))) < 0:
|
||||||
|
frappe.throw(_("Task's {0} End Date cannot be after Project's End Date.").format(actual_or_expected_date))
|
@ -188,6 +188,8 @@ class Timesheet(Document):
|
|||||||
}, as_dict=True)
|
}, as_dict=True)
|
||||||
# check internal overlap
|
# check internal overlap
|
||||||
for time_log in self.time_logs:
|
for time_log in self.time_logs:
|
||||||
|
if not (time_log.from_time or time_log.to_time): continue
|
||||||
|
|
||||||
if (fieldname != 'workstation' or args.get(fieldname) == time_log.get(fieldname)) and \
|
if (fieldname != 'workstation' or args.get(fieldname) == time_log.get(fieldname)) and \
|
||||||
args.idx != time_log.idx and ((args.from_time > time_log.from_time and args.from_time < time_log.to_time) or
|
args.idx != time_log.idx and ((args.from_time > time_log.from_time and args.from_time < time_log.to_time) or
|
||||||
(args.to_time > time_log.from_time and args.to_time < time_log.to_time) or
|
(args.to_time > time_log.from_time and args.to_time < time_log.to_time) or
|
||||||
|
@ -63,12 +63,15 @@ $.extend(erpnext, {
|
|||||||
let callback = '';
|
let callback = '';
|
||||||
let on_close = '';
|
let on_close = '';
|
||||||
|
|
||||||
if (grid_row.doc.serial_no) {
|
frappe.model.get_value('Item', {'name':grid_row.doc.item_code}, 'has_serial_no',
|
||||||
grid_row.doc.has_serial_no = true;
|
(data) => {
|
||||||
}
|
if(data) {
|
||||||
|
grid_row.doc.has_serial_no = data.has_serial_no;
|
||||||
me.show_serial_batch_selector(grid_row.frm, grid_row.doc,
|
me.show_serial_batch_selector(grid_row.frm, grid_row.doc,
|
||||||
callback, on_close, true);
|
callback, on_close, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -10,3 +10,21 @@ def check_deletion_permission(doc, method):
|
|||||||
region = get_region(doc.company)
|
region = get_region(doc.company)
|
||||||
if region in ["Nepal", "France"] and doc.docstatus != 0:
|
if region in ["Nepal", "France"] and doc.docstatus != 0:
|
||||||
frappe.throw(_("Deletion is not permitted for country {0}".format(region)))
|
frappe.throw(_("Deletion is not permitted for country {0}".format(region)))
|
||||||
|
|
||||||
|
def create_transaction_log(doc, method):
|
||||||
|
"""
|
||||||
|
Appends the transaction to a chain of hashed logs for legal resons.
|
||||||
|
Called on submit of Sales Invoice and Payment Entry.
|
||||||
|
"""
|
||||||
|
region = get_region()
|
||||||
|
if region not in ["France", "Germany"]:
|
||||||
|
return
|
||||||
|
|
||||||
|
data = str(doc.as_dict())
|
||||||
|
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Transaction Log",
|
||||||
|
"reference_doctype": doc.doctype,
|
||||||
|
"document_name": doc.name,
|
||||||
|
"data": data
|
||||||
|
}).insert(ignore_permissions=True)
|
||||||
|
@ -3,22 +3,6 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
|
||||||
from erpnext import get_region
|
|
||||||
|
|
||||||
def create_transaction_log(doc, method):
|
|
||||||
region = get_region()
|
|
||||||
if region not in ["France"]:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
data = str(doc.as_dict())
|
|
||||||
|
|
||||||
frappe.get_doc({
|
|
||||||
"doctype": "Transaction Log",
|
|
||||||
"reference_doctype": doc.doctype,
|
|
||||||
"document_name": doc.name,
|
|
||||||
"data": data
|
|
||||||
}).insert(ignore_permissions=True)
|
|
||||||
|
|
||||||
# don't remove this function it is used in tests
|
# don't remove this function it is used in tests
|
||||||
def test_method():
|
def test_method():
|
||||||
|
@ -72,8 +72,8 @@ def validate_gstin_check_digit(gstin, label='GSTIN'):
|
|||||||
total += digit
|
total += digit
|
||||||
factor = 2 if factor == 1 else 1
|
factor = 2 if factor == 1 else 1
|
||||||
if gstin[-1] != code_point_chars[((mod - (total % mod)) % mod)]:
|
if gstin[-1] != code_point_chars[((mod - (total % mod)) % mod)]:
|
||||||
frappe.throw(_("Invalid {0}! The check digit validation has failed. " +
|
frappe.throw(_("""Invalid {0}! The check digit validation has failed.
|
||||||
"Please ensure you've typed the {0} correctly.".format(label)))
|
Please ensure you've typed the {0} correctly.""".format(label)))
|
||||||
|
|
||||||
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
|
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
|
||||||
if frappe.get_meta(item_doctype).has_field('gst_hsn_code'):
|
if frappe.get_meta(item_doctype).has_field('gst_hsn_code'):
|
||||||
|
@ -116,7 +116,7 @@ class Gstr1Report(object):
|
|||||||
taxable_value = 0
|
taxable_value = 0
|
||||||
for item_code, net_amount in self.invoice_items.get(invoice).items():
|
for item_code, net_amount in self.invoice_items.get(invoice).items():
|
||||||
if item_code in items:
|
if item_code in items:
|
||||||
if self.item_tax_rate.get(invoice) and tax_rate in self.item_tax_rate.get(invoice, {}).get(item_code):
|
if self.item_tax_rate.get(invoice) and tax_rate in self.item_tax_rate.get(invoice, {}).get(item_code, []):
|
||||||
taxable_value += abs(net_amount)
|
taxable_value += abs(net_amount)
|
||||||
elif not self.item_tax_rate.get(invoice):
|
elif not self.item_tax_rate.get(invoice):
|
||||||
taxable_value += abs(net_amount)
|
taxable_value += abs(net_amount)
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
frappe.query_reports["Item-wise Sales History"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
fieldname:"company",
|
||||||
|
label: __("Company"),
|
||||||
|
fieldtype: "Link",
|
||||||
|
options: "Company",
|
||||||
|
default: frappe.defaults.get_user_default("Company"),
|
||||||
|
reqd: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname:"item_group",
|
||||||
|
label: __("Item Group"),
|
||||||
|
fieldtype: "Link",
|
||||||
|
options: "Item Group"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname:"from_date",
|
||||||
|
label: __("From Date"),
|
||||||
|
fieldtype: "Date",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname:"to_date",
|
||||||
|
label: __("To Date"),
|
||||||
|
fieldtype: "Date",
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
};
|
@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"add_total_row": 1,
|
"add_total_row": 1,
|
||||||
"creation": "2013-05-23 17:42:24",
|
"creation": "2013-05-23 17:42:24",
|
||||||
|
"disable_prepared_report": 0,
|
||||||
"disabled": 0,
|
"disabled": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Report",
|
"doctype": "Report",
|
||||||
"idx": 3,
|
"idx": 3,
|
||||||
"is_standard": "Yes",
|
"is_standard": "Yes",
|
||||||
"modified": "2019-01-03 22:52:41.519890",
|
"modified": "2019-11-04 16:28:14.608904",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Item-wise Sales History",
|
"name": "Item-wise Sales History",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"prepared_report": 0,
|
"prepared_report": 0,
|
||||||
"query": "select\n so_item.item_code as \"Item Code:Link/Item:120\",\n\tso_item.item_name as \"Item Name::120\",\n so_item.item_group as \"Item Group:Link/Item Group:120\",\n\tso_item.description as \"Description::150\",\n\tso_item.qty as \"Qty:Data:100\",\n\tso_item.uom as \"UOM:Link/UOM:80\",\n\tso_item.base_rate as \"Rate:Currency:120\",\n\tso_item.base_amount as \"Amount:Currency:120\",\n\tso.name as \"Sales Order:Link/Sales Order:120\",\n\tso.transaction_date as \"Transaction Date:Date:140\",\n\tso.customer as \"Customer:Link/Customer:130\",\n cu.customer_name as \"Customer Name::150\",\n\tcu.customer_group as \"Customer Group:Link/Customer Group:130\",\n\tso.territory as \"Territory:Link/Territory:130\",\n \tso.project as \"Project:Link/Project:130\",\n\tifnull(so_item.delivered_qty, 0) as \"Delivered Qty:Float:120\",\n\tifnull(so_item.billed_amt, 0) as \"Billed Amount:Currency:120\",\n\tso.company as \"Company:Link/Company:\"\nfrom\n\t`tabSales Order` so, `tabSales Order Item` so_item, `tabCustomer` cu\nwhere\n\tso.name = so_item.parent and so.customer=cu.name\n\tand so.docstatus = 1\norder by so.name desc",
|
|
||||||
"ref_doctype": "Sales Order",
|
"ref_doctype": "Sales Order",
|
||||||
"report_name": "Item-wise Sales History",
|
"report_name": "Item-wise Sales History",
|
||||||
"report_type": "Query Report",
|
"report_type": "Script Report",
|
||||||
"roles": [
|
"roles": [
|
||||||
{
|
{
|
||||||
"role": "Sales User"
|
"role": "Sales User"
|
||||||
|
@ -0,0 +1,214 @@
|
|||||||
|
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import flt
|
||||||
|
from frappe.utils.nestedset import get_descendants_of
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
filters = frappe._dict(filters or {})
|
||||||
|
columns = get_columns(filters)
|
||||||
|
data = get_data(filters)
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
def get_columns(filters):
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"label": _("Item Code"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": "item_code",
|
||||||
|
"options": "Item",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Item Name"),
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"fieldname": "item_name",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Item Group"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": "item_group",
|
||||||
|
"options": "Item Group",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Description"),
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"fieldname": "description",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Quantity"),
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"fieldname": "quantity",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("UOM"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": "uom",
|
||||||
|
"options": "UOM",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Rate"),
|
||||||
|
"fieldname": "rate",
|
||||||
|
"options": "Currency",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Amount"),
|
||||||
|
"fieldname": "amount",
|
||||||
|
"options": "Currency",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Sales Order"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": "sales_order",
|
||||||
|
"options": "Sales Order",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Transaction Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"fieldname": "transaction_date",
|
||||||
|
"width": 90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Customer"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": "customer",
|
||||||
|
"options": "Customer",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Customer Name"),
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"fieldname": "customer_name",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Customer Group"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": "customer_group",
|
||||||
|
"options": "customer Group",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Territory"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": "territory",
|
||||||
|
"options": "Territory",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Project"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": "project",
|
||||||
|
"options": "Project",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Delivered Quantity"),
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"fieldname": "delivered_quantity",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Billed Amount"),
|
||||||
|
"fieldname": "rate",
|
||||||
|
"options": "billed_amount",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Company"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": "company",
|
||||||
|
"options": "Company",
|
||||||
|
"width": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_data(filters):
|
||||||
|
|
||||||
|
data = []
|
||||||
|
|
||||||
|
company_list = get_descendants_of("Company", filters.get("company"))
|
||||||
|
company_list.append(filters.get("company"))
|
||||||
|
|
||||||
|
customer_details = get_customer_details()
|
||||||
|
sales_order_records = get_sales_order_details(company_list, filters)
|
||||||
|
|
||||||
|
for record in sales_order_records:
|
||||||
|
customer_record = customer_details.get(record.customer)
|
||||||
|
row = {
|
||||||
|
"item_code": record.item_code,
|
||||||
|
"item_name": record.item_name,
|
||||||
|
"item_group": record.item_group,
|
||||||
|
"description": record.description,
|
||||||
|
"quantity": record.qty,
|
||||||
|
"uom": record.uom,
|
||||||
|
"rate": record.base_rate,
|
||||||
|
"amount": record.base_amount,
|
||||||
|
"sales_order": record.name,
|
||||||
|
"transaction_date": record.transaction_date,
|
||||||
|
"customer": record.customer,
|
||||||
|
"customer_name": customer_record.customer_name,
|
||||||
|
"customer_group": customer_record.customer_group,
|
||||||
|
"territory": record.territory,
|
||||||
|
"project": record.project,
|
||||||
|
"delivered_quantity": flt(record.delivered_qty),
|
||||||
|
"billed_amount": flt(record.billed_amt),
|
||||||
|
"company": record.company
|
||||||
|
}
|
||||||
|
data.append(row)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_conditions(filters):
|
||||||
|
conditions = ''
|
||||||
|
if filters.get('item_group'):
|
||||||
|
conditions += "AND so_item.item_group = %s" %frappe.db.escape(filters.item_group)
|
||||||
|
|
||||||
|
if filters.get('from_date'):
|
||||||
|
conditions += "AND so.transaction_date >= '%s'" %filters.from_date
|
||||||
|
|
||||||
|
if filters.get('to_date'):
|
||||||
|
conditions += "AND so.transaction_date <= '%s'" %filters.to_date
|
||||||
|
|
||||||
|
return conditions
|
||||||
|
|
||||||
|
def get_customer_details():
|
||||||
|
details = frappe.get_all('Customer',
|
||||||
|
fields=['name', 'customer_name', "customer_group"])
|
||||||
|
customer_details = {}
|
||||||
|
for d in details:
|
||||||
|
customer_details.setdefault(d.name, frappe._dict({
|
||||||
|
"customer_name": d.customer_name,
|
||||||
|
"customer_group": d.customer_group
|
||||||
|
}))
|
||||||
|
return customer_details
|
||||||
|
|
||||||
|
def get_sales_order_details(company_list, filters):
|
||||||
|
conditions = get_conditions(filters)
|
||||||
|
return frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
so_item.item_code, so_item.item_name, so_item.item_group,
|
||||||
|
so_item.description, so_item.qty, so_item.uom,
|
||||||
|
so_item.base_rate, so_item.base_amount, so.name,
|
||||||
|
so.transaction_date, so.customer, so.territory,
|
||||||
|
so.project, so_item.delivered_qty,
|
||||||
|
so_item.billed_amt, so.company
|
||||||
|
FROM
|
||||||
|
`tabSales Order` so, `tabSales Order Item` so_item
|
||||||
|
WHERE
|
||||||
|
so.name = so_item.parent
|
||||||
|
AND so.company in (%s)
|
||||||
|
AND so.docstatus = 1
|
||||||
|
{0}
|
||||||
|
""".format(conditions), company_list, as_dict=1) #nosec
|
@ -72,6 +72,7 @@
|
|||||||
"stock_received_but_not_billed",
|
"stock_received_but_not_billed",
|
||||||
"expenses_included_in_valuation",
|
"expenses_included_in_valuation",
|
||||||
"fixed_asset_depreciation_settings",
|
"fixed_asset_depreciation_settings",
|
||||||
|
"enable_cwip_accounting",
|
||||||
"accumulated_depreciation_account",
|
"accumulated_depreciation_account",
|
||||||
"depreciation_expense_account",
|
"depreciation_expense_account",
|
||||||
"series_for_depreciation_entry",
|
"series_for_depreciation_entry",
|
||||||
@ -720,12 +721,18 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Default Buying Terms",
|
"label": "Default Buying Terms",
|
||||||
"options": "Terms and Conditions"
|
"options": "Terms and Conditions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "enable_cwip_accounting",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Enable Capital Work in Progress Accounting"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-building",
|
"icon": "fa fa-building",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"image_field": "company_logo",
|
"image_field": "company_logo",
|
||||||
"modified": "2019-07-04 22:20:45.104307",
|
"modified": "2019-10-09 14:42:04.440974",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Setup",
|
"module": "Setup",
|
||||||
"name": "Company",
|
"name": "Company",
|
||||||
@ -767,6 +774,18 @@
|
|||||||
{
|
{
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"role": "Projects User"
|
"role": "Projects User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
|
@ -207,7 +207,7 @@ class Company(NestedSet):
|
|||||||
"default_expense_account": "Cost of Goods Sold"
|
"default_expense_account": "Cost of Goods Sold"
|
||||||
})
|
})
|
||||||
|
|
||||||
if self.update_default_account or frappe.flags.in_test:
|
if self.update_default_account:
|
||||||
for default_account in default_accounts:
|
for default_account in default_accounts:
|
||||||
self._set_default_account(default_account, default_accounts.get(default_account))
|
self._set_default_account(default_account, default_accounts.get(default_account))
|
||||||
|
|
||||||
|
@ -11,10 +11,19 @@ from frappe.utils import get_datetime_str, formatdate, nowdate, cint
|
|||||||
|
|
||||||
class CurrencyExchange(Document):
|
class CurrencyExchange(Document):
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
|
purpose = ""
|
||||||
if not self.date:
|
if not self.date:
|
||||||
self.date = nowdate()
|
self.date = nowdate()
|
||||||
self.name = '{0}-{1}-{2}'.format(formatdate(get_datetime_str(self.date), "yyyy-MM-dd"),
|
|
||||||
self.from_currency, self.to_currency)
|
# If both selling and buying enabled
|
||||||
|
purpose = "Selling-Buying"
|
||||||
|
if cint(self.for_buying)==0 and cint(self.for_selling)==1:
|
||||||
|
purpose = "Selling"
|
||||||
|
if cint(self.for_buying)==1 and cint(self.for_selling)==0:
|
||||||
|
purpose = "Buying"
|
||||||
|
|
||||||
|
self.name = '{0}-{1}-{2}{3}'.format(formatdate(get_datetime_str(self.date), "yyyy-MM-dd"),
|
||||||
|
self.from_currency, self.to_currency, ("-" + purpose) if purpose else "")
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_value("exchange_rate", ">", 0)
|
self.validate_value("exchange_rate", ">", 0)
|
||||||
|
@ -4,15 +4,23 @@ from __future__ import unicode_literals
|
|||||||
import frappe, unittest
|
import frappe, unittest
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from erpnext.setup.utils import get_exchange_rate
|
from erpnext.setup.utils import get_exchange_rate
|
||||||
|
from frappe.utils import cint
|
||||||
|
|
||||||
test_records = frappe.get_test_records('Currency Exchange')
|
test_records = frappe.get_test_records('Currency Exchange')
|
||||||
|
|
||||||
|
|
||||||
def save_new_records(test_records):
|
def save_new_records(test_records):
|
||||||
for record in test_records:
|
for record in test_records:
|
||||||
|
# If both selling and buying enabled
|
||||||
|
purpose = "Selling-Buying"
|
||||||
|
|
||||||
|
if cint(record.get("for_buying"))==0 and cint(record.get("for_selling"))==1:
|
||||||
|
purpose = "Selling"
|
||||||
|
if cint(record.get("for_buying"))==1 and cint(record.get("for_selling"))==0:
|
||||||
|
purpose = "Buying"
|
||||||
kwargs = dict(
|
kwargs = dict(
|
||||||
doctype=record.get("doctype"),
|
doctype=record.get("doctype"),
|
||||||
docname=record.get("date") + '-' + record.get("from_currency") + '-' + record.get("to_currency"),
|
docname=record.get("date") + '-' + record.get("from_currency") + '-' + record.get("to_currency") + '-' + purpose,
|
||||||
fieldname="exchange_rate",
|
fieldname="exchange_rate",
|
||||||
value=record.get("exchange_rate"),
|
value=record.get("exchange_rate"),
|
||||||
)
|
)
|
||||||
@ -25,6 +33,8 @@ def save_new_records(test_records):
|
|||||||
curr_exchange.from_currency = record["from_currency"]
|
curr_exchange.from_currency = record["from_currency"]
|
||||||
curr_exchange.to_currency = record["to_currency"]
|
curr_exchange.to_currency = record["to_currency"]
|
||||||
curr_exchange.exchange_rate = record["exchange_rate"]
|
curr_exchange.exchange_rate = record["exchange_rate"]
|
||||||
|
curr_exchange.for_buying = record["for_buying"]
|
||||||
|
curr_exchange.for_selling = record["for_selling"]
|
||||||
curr_exchange.insert()
|
curr_exchange.insert()
|
||||||
|
|
||||||
|
|
||||||
@ -44,18 +54,18 @@ class TestCurrencyExchange(unittest.TestCase):
|
|||||||
frappe.db.set_value("Accounts Settings", None, "allow_stale", 1)
|
frappe.db.set_value("Accounts Settings", None, "allow_stale", 1)
|
||||||
|
|
||||||
# Start with allow_stale is True
|
# Start with allow_stale is True
|
||||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-01")
|
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-01", "for_buying")
|
||||||
self.assertEqual(flt(exchange_rate, 3), 60.0)
|
self.assertEqual(flt(exchange_rate, 3), 60.0)
|
||||||
|
|
||||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15")
|
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15", "for_buying")
|
||||||
self.assertEqual(exchange_rate, 65.1)
|
self.assertEqual(exchange_rate, 65.1)
|
||||||
|
|
||||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-30")
|
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-30", "for_selling")
|
||||||
self.assertEqual(exchange_rate, 62.9)
|
self.assertEqual(exchange_rate, 62.9)
|
||||||
|
|
||||||
# Exchange rate as on 15th Dec, 2015, should be fetched from fixer.io
|
# Exchange rate as on 15th Dec, 2015, should be fetched from fixer.io
|
||||||
self.clear_cache()
|
self.clear_cache()
|
||||||
exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15")
|
exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15", "for_selling")
|
||||||
self.assertFalse(exchange_rate == 60)
|
self.assertFalse(exchange_rate == 60)
|
||||||
self.assertEqual(flt(exchange_rate, 3), 66.894)
|
self.assertEqual(flt(exchange_rate, 3), 66.894)
|
||||||
|
|
||||||
@ -64,35 +74,35 @@ class TestCurrencyExchange(unittest.TestCase):
|
|||||||
frappe.db.set_value("Accounts Settings", None, "allow_stale", 0)
|
frappe.db.set_value("Accounts Settings", None, "allow_stale", 0)
|
||||||
frappe.db.set_value("Accounts Settings", None, "stale_days", 1)
|
frappe.db.set_value("Accounts Settings", None, "stale_days", 1)
|
||||||
|
|
||||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-01")
|
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-01", "for_buying")
|
||||||
self.assertEqual(exchange_rate, 60.0)
|
self.assertEqual(exchange_rate, 60.0)
|
||||||
|
|
||||||
# Will fetch from fixer.io
|
# Will fetch from fixer.io
|
||||||
self.clear_cache()
|
self.clear_cache()
|
||||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15")
|
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15", "for_buying")
|
||||||
self.assertEqual(flt(exchange_rate, 3), 67.79)
|
self.assertEqual(flt(exchange_rate, 3), 67.79)
|
||||||
|
|
||||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-30")
|
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-30", "for_selling")
|
||||||
self.assertEqual(exchange_rate, 62.9)
|
self.assertEqual(exchange_rate, 62.9)
|
||||||
|
|
||||||
# Exchange rate as on 15th Dec, 2015, should be fetched from fixer.io
|
# Exchange rate as on 15th Dec, 2015, should be fetched from fixer.io
|
||||||
self.clear_cache()
|
self.clear_cache()
|
||||||
exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15")
|
exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15", "for_buying")
|
||||||
self.assertEqual(flt(exchange_rate, 3), 66.894)
|
self.assertEqual(flt(exchange_rate, 3), 66.894)
|
||||||
|
|
||||||
exchange_rate = get_exchange_rate("INR", "NGN", "2016-01-10")
|
exchange_rate = get_exchange_rate("INR", "NGN", "2016-01-10", "for_selling")
|
||||||
self.assertEqual(exchange_rate, 65.1)
|
self.assertEqual(exchange_rate, 65.1)
|
||||||
|
|
||||||
# NGN is not available on fixer.io so these should return 0
|
# NGN is not available on fixer.io so these should return 0
|
||||||
exchange_rate = get_exchange_rate("INR", "NGN", "2016-01-09")
|
exchange_rate = get_exchange_rate("INR", "NGN", "2016-01-09", "for_selling")
|
||||||
self.assertEqual(exchange_rate, 0)
|
self.assertEqual(exchange_rate, 0)
|
||||||
|
|
||||||
exchange_rate = get_exchange_rate("INR", "NGN", "2016-01-11")
|
exchange_rate = get_exchange_rate("INR", "NGN", "2016-01-11", "for_selling")
|
||||||
self.assertEqual(exchange_rate, 0)
|
self.assertEqual(exchange_rate, 0)
|
||||||
|
|
||||||
def test_exchange_rate_strict_switched(self):
|
def test_exchange_rate_strict_switched(self):
|
||||||
# Start with allow_stale is True
|
# Start with allow_stale is True
|
||||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15")
|
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15", "for_buying")
|
||||||
self.assertEqual(exchange_rate, 65.1)
|
self.assertEqual(exchange_rate, 65.1)
|
||||||
|
|
||||||
frappe.db.set_value("Accounts Settings", None, "allow_stale", 0)
|
frappe.db.set_value("Accounts Settings", None, "allow_stale", 0)
|
||||||
@ -100,5 +110,5 @@ class TestCurrencyExchange(unittest.TestCase):
|
|||||||
|
|
||||||
# Will fetch from fixer.io
|
# Will fetch from fixer.io
|
||||||
self.clear_cache()
|
self.clear_cache()
|
||||||
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15")
|
exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15", "for_buying")
|
||||||
self.assertEqual(flt(exchange_rate, 3), 67.79)
|
self.assertEqual(flt(exchange_rate, 3), 67.79)
|
@ -1,44 +1,56 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"doctype": "Currency Exchange",
|
"doctype": "Currency Exchange",
|
||||||
"date": "2016-01-01",
|
"date": "2016-01-01",
|
||||||
"exchange_rate": 60.0,
|
"exchange_rate": 60.0,
|
||||||
"from_currency": "USD",
|
"from_currency": "USD",
|
||||||
"to_currency": "INR"
|
"to_currency": "INR",
|
||||||
},
|
"for_buying": 1,
|
||||||
{
|
"for_selling": 0
|
||||||
"doctype": "Currency Exchange",
|
},
|
||||||
"date": "2016-01-01",
|
|
||||||
"exchange_rate": 0.773,
|
|
||||||
"from_currency": "USD",
|
|
||||||
"to_currency": "EUR"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Currency Exchange",
|
|
||||||
"date": "2016-01-01",
|
|
||||||
"exchange_rate": 0.0167,
|
|
||||||
"from_currency": "INR",
|
|
||||||
"to_currency": "USD"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Currency Exchange",
|
|
||||||
"date": "2016-01-10",
|
|
||||||
"exchange_rate": 65.1,
|
|
||||||
"from_currency": "USD",
|
|
||||||
"to_currency": "INR"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"doctype": "Currency Exchange",
|
"doctype": "Currency Exchange",
|
||||||
"date": "2016-01-30",
|
"date": "2016-01-01",
|
||||||
"exchange_rate": 62.9,
|
"exchange_rate": 0.773,
|
||||||
"from_currency": "USD",
|
"from_currency": "USD",
|
||||||
"to_currency": "INR"
|
"to_currency": "EUR",
|
||||||
},
|
"for_buying": 0,
|
||||||
{
|
"for_selling": 1
|
||||||
"doctype": "Currency Exchange",
|
},
|
||||||
"date": "2016-01-10",
|
{
|
||||||
"exchange_rate": 65.1,
|
"doctype": "Currency Exchange",
|
||||||
"from_currency": "INR",
|
"date": "2016-01-01",
|
||||||
"to_currency": "NGN"
|
"exchange_rate": 0.0167,
|
||||||
}
|
"from_currency": "INR",
|
||||||
|
"to_currency": "USD",
|
||||||
|
"for_buying": 1,
|
||||||
|
"for_selling": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Currency Exchange",
|
||||||
|
"date": "2016-01-10",
|
||||||
|
"exchange_rate": 65.1,
|
||||||
|
"from_currency": "USD",
|
||||||
|
"to_currency": "INR",
|
||||||
|
"for_buying": 1,
|
||||||
|
"for_selling": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Currency Exchange",
|
||||||
|
"date": "2016-01-30",
|
||||||
|
"exchange_rate": 62.9,
|
||||||
|
"from_currency": "USD",
|
||||||
|
"to_currency": "INR",
|
||||||
|
"for_buying": 1,
|
||||||
|
"for_selling": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Currency Exchange",
|
||||||
|
"date": "2016-01-10",
|
||||||
|
"exchange_rate": 65.1,
|
||||||
|
"from_currency": "INR",
|
||||||
|
"to_currency": "NGN",
|
||||||
|
"for_buying": 1,
|
||||||
|
"for_selling": 1
|
||||||
|
}
|
||||||
]
|
]
|
@ -4,8 +4,8 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import fmt_money, formatdate, format_time, now_datetime, \
|
from frappe.utils import (fmt_money, formatdate, format_time, now_datetime,
|
||||||
get_url_to_form, get_url_to_list, flt, get_link_to_report
|
get_url_to_form, get_url_to_list, flt, get_link_to_report, add_to_date, today)
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
from frappe.core.doctype.user.user import STANDARD_USERS
|
from frappe.core.doctype.user.user import STANDARD_USERS
|
||||||
@ -151,8 +151,9 @@ class EmailDigest(Document):
|
|||||||
def get_calendar_events(self):
|
def get_calendar_events(self):
|
||||||
"""Get calendar events for given user"""
|
"""Get calendar events for given user"""
|
||||||
from frappe.desk.doctype.event.event import get_events
|
from frappe.desk.doctype.event.event import get_events
|
||||||
events = get_events(self.future_from_date.strftime("%Y-%m-%d"),
|
from_date, to_date = get_future_date_for_calendaer_event(self.frequency)
|
||||||
self.future_to_date.strftime("%Y-%m-%d")) or []
|
|
||||||
|
events = get_events(from_date, to_date)
|
||||||
|
|
||||||
event_count = 0
|
event_count = 0
|
||||||
for i, e in enumerate(events):
|
for i, e in enumerate(events):
|
||||||
@ -826,3 +827,13 @@ def get_count_for_period(account, fieldname, from_date, to_date):
|
|||||||
count = count_on_to_date + (last_year_closing_count - count_before_from_date)
|
count = count_on_to_date + (last_year_closing_count - count_before_from_date)
|
||||||
|
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
def get_future_date_for_calendaer_event(frequency):
|
||||||
|
from_date = to_date = today()
|
||||||
|
|
||||||
|
if frequency == "Weekly":
|
||||||
|
to_date = add_to_date(from_date, weeks=1)
|
||||||
|
elif frequency == "Monthly":
|
||||||
|
to_date = add_to_date(from_date, months=1)
|
||||||
|
|
||||||
|
return from_date, to_date
|
@ -11,6 +11,7 @@ from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings
|
|||||||
from frappe.utils.nestedset import get_root_of
|
from frappe.utils.nestedset import get_root_of
|
||||||
from erpnext.accounts.utils import get_account_name
|
from erpnext.accounts.utils import get_account_name
|
||||||
from erpnext.utilities.product import get_qty_in_stock
|
from erpnext.utilities.product import get_qty_in_stock
|
||||||
|
from frappe.contacts.doctype.contact.contact import get_contact_name
|
||||||
|
|
||||||
|
|
||||||
class WebsitePriceListMissingError(frappe.ValidationError):
|
class WebsitePriceListMissingError(frappe.ValidationError):
|
||||||
@ -371,7 +372,7 @@ def get_party(user=None):
|
|||||||
if not user:
|
if not user:
|
||||||
user = frappe.session.user
|
user = frappe.session.user
|
||||||
|
|
||||||
contact_name = frappe.db.get_value("Contact", {"email_id": user})
|
contact_name = get_contact_name(user)
|
||||||
party = None
|
party = None
|
||||||
|
|
||||||
if contact_name:
|
if contact_name:
|
||||||
@ -417,7 +418,7 @@ def get_party(user=None):
|
|||||||
contact = frappe.new_doc("Contact")
|
contact = frappe.new_doc("Contact")
|
||||||
contact.update({
|
contact.update({
|
||||||
"first_name": fullname,
|
"first_name": fullname,
|
||||||
"email_id": user
|
"email_ids": [{"email_id": user, "is_primary": 1}]
|
||||||
})
|
})
|
||||||
contact.append('links', dict(link_doctype='Customer', link_name=customer.name))
|
contact.append('links', dict(link_doctype='Customer', link_name=customer.name))
|
||||||
contact.flags.ignore_mandatory = True
|
contact.flags.ignore_mandatory = True
|
||||||
@ -504,7 +505,7 @@ def get_applicable_shipping_rules(party=None, quotation=None):
|
|||||||
if shipping_rules:
|
if shipping_rules:
|
||||||
rule_label_map = frappe.db.get_values("Shipping Rule", shipping_rules, "label")
|
rule_label_map = frappe.db.get_values("Shipping Rule", shipping_rules, "label")
|
||||||
# we need this in sorted order as per the position of the rule in the settings page
|
# we need this in sorted order as per the position of the rule in the settings page
|
||||||
return [[rule, rule_label_map.get(rule)] for rule in shipping_rules]
|
return [[rule, rule] for rule in shipping_rules]
|
||||||
|
|
||||||
def get_shipping_rules(quotation=None, cart_settings=None):
|
def get_shipping_rules(quotation=None, cart_settings=None):
|
||||||
if not quotation:
|
if not quotation:
|
||||||
|
@ -185,9 +185,17 @@ def get_batches_by_oldest(item_code, warehouse):
|
|||||||
def split_batch(batch_no, item_code, warehouse, qty, new_batch_id=None):
|
def split_batch(batch_no, item_code, warehouse, qty, new_batch_id=None):
|
||||||
"""Split the batch into a new batch"""
|
"""Split the batch into a new batch"""
|
||||||
batch = frappe.get_doc(dict(doctype='Batch', item=item_code, batch_id=new_batch_id)).insert()
|
batch = frappe.get_doc(dict(doctype='Batch', item=item_code, batch_id=new_batch_id)).insert()
|
||||||
|
|
||||||
|
company = frappe.db.get_value('Stock Ledger Entry', dict(
|
||||||
|
item_code=item_code,
|
||||||
|
batch_no=batch_no,
|
||||||
|
warehouse=warehouse
|
||||||
|
), ['company'])
|
||||||
|
|
||||||
stock_entry = frappe.get_doc(dict(
|
stock_entry = frappe.get_doc(dict(
|
||||||
doctype='Stock Entry',
|
doctype='Stock Entry',
|
||||||
purpose='Repack',
|
purpose='Repack',
|
||||||
|
company=company,
|
||||||
items=[
|
items=[
|
||||||
dict(
|
dict(
|
||||||
item_code=item_code,
|
item_code=item_code,
|
||||||
|
@ -1,129 +1,51 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2014-07-11 11:51:00.453717",
|
"creation": "2014-07-11 11:51:00.453717",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"expense_account",
|
||||||
|
"description",
|
||||||
|
"col_break3",
|
||||||
|
"amount"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "description",
|
"fieldname": "description",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Description",
|
"label": "Description",
|
||||||
"length": 0,
|
"reqd": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "col_break3",
|
"fieldname": "col_break3",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0,
|
|
||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "amount",
|
"fieldname": "amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Amount",
|
"label": "Amount",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"print_hide": 0,
|
},
|
||||||
"print_hide_if_no_value": 0,
|
{
|
||||||
"read_only": 0,
|
"fieldname": "expense_account",
|
||||||
"remember_last_selected_value": 0,
|
"fieldtype": "Link",
|
||||||
"report_hide": 0,
|
"in_list_view": 1,
|
||||||
"reqd": 1,
|
"label": "Expense Account",
|
||||||
"search_index": 0,
|
"options": "Account",
|
||||||
"set_only_once": 0,
|
"reqd": 1
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"modified": "2019-09-30 18:28:32.070655",
|
||||||
"modified": "2017-11-15 19:27:59.542487",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Landed Cost Taxes and Charges",
|
"name": "Landed Cost Taxes and Charges",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC"
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
@ -30,6 +30,16 @@ erpnext.stock.LandedCostVoucher = erpnext.stock.StockController.extend({
|
|||||||
this.frm.add_fetch("receipt_document", "posting_date", "posting_date");
|
this.frm.add_fetch("receipt_document", "posting_date", "posting_date");
|
||||||
this.frm.add_fetch("receipt_document", "base_grand_total", "grand_total");
|
this.frm.add_fetch("receipt_document", "base_grand_total", "grand_total");
|
||||||
|
|
||||||
|
this.frm.set_query("expense_account", "taxes", function() {
|
||||||
|
return {
|
||||||
|
query: "erpnext.controllers.queries.tax_account_query",
|
||||||
|
filters: {
|
||||||
|
"account_type": ["Tax", "Chargeable", "Income Account", "Expenses Included In Valuation", "Expenses Included In Asset Valuation"],
|
||||||
|
"company": me.frm.doc.company
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
|
@ -179,7 +179,7 @@ def submit_landed_cost_voucher(receipt_document_type, receipt_document, charges=
|
|||||||
|
|
||||||
lcv.set("taxes", [{
|
lcv.set("taxes", [{
|
||||||
"description": "Insurance Charges",
|
"description": "Insurance Charges",
|
||||||
"account": "_Test Account Insurance Charges - _TC",
|
"expense_account": "Expenses Included In Valuation - TCP1",
|
||||||
"amount": charges
|
"amount": charges
|
||||||
}])
|
}])
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user