mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-22 22:49:19 +00:00
Merge pull request #31932 from frappe/version-14-hotfix
chore: weekly version 14 release
This commit is contained in:
@@ -366,7 +366,7 @@ def update_outstanding_amt(
|
|||||||
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
|
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
|
||||||
ref_doc = frappe.get_doc(against_voucher_type, against_voucher)
|
ref_doc = frappe.get_doc(against_voucher_type, against_voucher)
|
||||||
|
|
||||||
# Didn't use db_set for optimisation purpose
|
# Didn't use db_set for optimization purpose
|
||||||
ref_doc.outstanding_amount = bal
|
ref_doc.outstanding_amount = bal
|
||||||
frappe.db.set_value(against_voucher_type, against_voucher, "outstanding_amount", bal)
|
frappe.db.set_value(against_voucher_type, against_voucher, "outstanding_amount", bal)
|
||||||
|
|
||||||
|
|||||||
@@ -181,7 +181,11 @@ class PaymentEntry(AccountsController):
|
|||||||
frappe.throw(_("Party is mandatory"))
|
frappe.throw(_("Party is mandatory"))
|
||||||
|
|
||||||
_party_name = "title" if self.party_type == "Shareholder" else self.party_type.lower() + "_name"
|
_party_name = "title" if self.party_type == "Shareholder" else self.party_type.lower() + "_name"
|
||||||
self.party_name = frappe.db.get_value(self.party_type, self.party, _party_name)
|
|
||||||
|
if frappe.db.has_column(self.party_type, _party_name):
|
||||||
|
self.party_name = frappe.db.get_value(self.party_type, self.party, _party_name)
|
||||||
|
else:
|
||||||
|
self.party_name = frappe.db.get_value(self.party_type, self.party, "name")
|
||||||
|
|
||||||
if self.party:
|
if self.party:
|
||||||
if not self.party_balance:
|
if not self.party_balance:
|
||||||
@@ -295,6 +299,9 @@ class PaymentEntry(AccountsController):
|
|||||||
def validate_reference_documents(self):
|
def validate_reference_documents(self):
|
||||||
valid_reference_doctypes = self.get_valid_reference_doctypes()
|
valid_reference_doctypes = self.get_valid_reference_doctypes()
|
||||||
|
|
||||||
|
if not valid_reference_doctypes:
|
||||||
|
return
|
||||||
|
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
if not d.allocated_amount:
|
if not d.allocated_amount:
|
||||||
continue
|
continue
|
||||||
@@ -362,7 +369,7 @@ class PaymentEntry(AccountsController):
|
|||||||
if not d.allocated_amount:
|
if not d.allocated_amount:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Fees"):
|
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||||
outstanding_amount, is_return = frappe.get_cached_value(
|
outstanding_amount, is_return = frappe.get_cached_value(
|
||||||
d.reference_doctype, d.reference_name, ["outstanding_amount", "is_return"]
|
d.reference_doctype, d.reference_name, ["outstanding_amount", "is_return"]
|
||||||
)
|
)
|
||||||
@@ -1201,7 +1208,7 @@ def get_outstanding_reference_documents(args):
|
|||||||
party_account_currency = get_account_currency(args.get("party_account"))
|
party_account_currency = get_account_currency(args.get("party_account"))
|
||||||
company_currency = frappe.get_cached_value("Company", args.get("company"), "default_currency")
|
company_currency = frappe.get_cached_value("Company", args.get("company"), "default_currency")
|
||||||
|
|
||||||
# Get positive outstanding sales /purchase invoices/ Fees
|
# Get positive outstanding sales /purchase invoices
|
||||||
condition = ""
|
condition = ""
|
||||||
if args.get("voucher_type") and args.get("voucher_no"):
|
if args.get("voucher_type") and args.get("voucher_no"):
|
||||||
condition = " and voucher_type={0} and voucher_no={1}".format(
|
condition = " and voucher_type={0} and voucher_no={1}".format(
|
||||||
@@ -1597,10 +1604,11 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
|||||||
elif reference_doctype != "Journal Entry":
|
elif reference_doctype != "Journal Entry":
|
||||||
if not total_amount:
|
if not total_amount:
|
||||||
if party_account_currency == company_currency:
|
if party_account_currency == company_currency:
|
||||||
total_amount = ref_doc.base_grand_total
|
# for handling cases that don't have multi-currency (base field)
|
||||||
|
total_amount = ref_doc.get("grand_total") or ref_doc.get("base_grand_total")
|
||||||
exchange_rate = 1
|
exchange_rate = 1
|
||||||
else:
|
else:
|
||||||
total_amount = ref_doc.grand_total
|
total_amount = ref_doc.get("grand_total")
|
||||||
if not exchange_rate:
|
if not exchange_rate:
|
||||||
# Get the exchange rate from the original ref doc
|
# Get the exchange rate from the original ref doc
|
||||||
# or get it based on the posting date of the ref doc.
|
# or get it based on the posting date of the ref doc.
|
||||||
@@ -1611,7 +1619,7 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
|||||||
if reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
if reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||||
outstanding_amount = ref_doc.get("outstanding_amount")
|
outstanding_amount = ref_doc.get("outstanding_amount")
|
||||||
else:
|
else:
|
||||||
outstanding_amount = flt(total_amount) - flt(ref_doc.advance_paid)
|
outstanding_amount = flt(total_amount) - flt(ref_doc.get("advance_paid"))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Get the exchange rate based on the posting date of the ref doc.
|
# Get the exchange rate based on the posting date of the ref doc.
|
||||||
@@ -1629,16 +1637,23 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None):
|
def get_payment_entry(
|
||||||
|
dt, dn, party_amount=None, bank_account=None, bank_amount=None, party_type=None, payment_type=None
|
||||||
|
):
|
||||||
reference_doc = None
|
reference_doc = None
|
||||||
doc = frappe.get_doc(dt, dn)
|
doc = frappe.get_doc(dt, dn)
|
||||||
if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
|
if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
|
||||||
frappe.throw(_("Can only make payment against unbilled {0}").format(dt))
|
frappe.throw(_("Can only make payment against unbilled {0}").format(dt))
|
||||||
|
|
||||||
party_type = set_party_type(dt)
|
if not party_type:
|
||||||
|
party_type = set_party_type(dt)
|
||||||
|
|
||||||
party_account = set_party_account(dt, dn, doc, party_type)
|
party_account = set_party_account(dt, dn, doc, party_type)
|
||||||
party_account_currency = set_party_account_currency(dt, party_account, doc)
|
party_account_currency = set_party_account_currency(dt, party_account, doc)
|
||||||
payment_type = set_payment_type(dt, doc)
|
|
||||||
|
if not payment_type:
|
||||||
|
payment_type = set_payment_type(dt, doc)
|
||||||
|
|
||||||
grand_total, outstanding_amount = set_grand_total_and_outstanding_amount(
|
grand_total, outstanding_amount = set_grand_total_and_outstanding_amount(
|
||||||
party_amount, dt, party_account_currency, doc
|
party_amount, dt, party_account_currency, doc
|
||||||
)
|
)
|
||||||
@@ -1788,8 +1803,6 @@ def set_party_account(dt, dn, doc, party_type):
|
|||||||
party_account = get_party_account_based_on_invoice_discounting(dn) or doc.debit_to
|
party_account = get_party_account_based_on_invoice_discounting(dn) or doc.debit_to
|
||||||
elif dt == "Purchase Invoice":
|
elif dt == "Purchase Invoice":
|
||||||
party_account = doc.credit_to
|
party_account = doc.credit_to
|
||||||
elif dt == "Fees":
|
|
||||||
party_account = doc.receivable_account
|
|
||||||
else:
|
else:
|
||||||
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
||||||
return party_account
|
return party_account
|
||||||
@@ -1805,8 +1818,7 @@ def set_party_account_currency(dt, party_account, doc):
|
|||||||
|
|
||||||
def set_payment_type(dt, doc):
|
def set_payment_type(dt, doc):
|
||||||
if (
|
if (
|
||||||
dt == "Sales Order"
|
dt == "Sales Order" or (dt in ("Sales Invoice", "Dunning") and doc.outstanding_amount > 0)
|
||||||
or (dt in ("Sales Invoice", "Fees", "Dunning") and doc.outstanding_amount > 0)
|
|
||||||
) or (dt == "Purchase Invoice" and doc.outstanding_amount < 0):
|
) or (dt == "Purchase Invoice" and doc.outstanding_amount < 0):
|
||||||
payment_type = "Receive"
|
payment_type = "Receive"
|
||||||
else:
|
else:
|
||||||
@@ -1824,18 +1836,15 @@ def set_grand_total_and_outstanding_amount(party_amount, dt, party_account_curre
|
|||||||
else:
|
else:
|
||||||
grand_total = doc.rounded_total or doc.grand_total
|
grand_total = doc.rounded_total or doc.grand_total
|
||||||
outstanding_amount = doc.outstanding_amount
|
outstanding_amount = doc.outstanding_amount
|
||||||
elif dt == "Fees":
|
|
||||||
grand_total = doc.grand_total
|
|
||||||
outstanding_amount = doc.outstanding_amount
|
|
||||||
elif dt == "Dunning":
|
elif dt == "Dunning":
|
||||||
grand_total = doc.grand_total
|
grand_total = doc.grand_total
|
||||||
outstanding_amount = doc.grand_total
|
outstanding_amount = doc.grand_total
|
||||||
else:
|
else:
|
||||||
if party_account_currency == doc.company_currency:
|
if party_account_currency == doc.company_currency:
|
||||||
grand_total = flt(doc.get("base_rounded_total") or doc.base_grand_total)
|
grand_total = flt(doc.get("base_rounded_total") or doc.get("base_grand_total"))
|
||||||
else:
|
else:
|
||||||
grand_total = flt(doc.get("rounded_total") or doc.grand_total)
|
grand_total = flt(doc.get("rounded_total") or doc.get("grand_total"))
|
||||||
outstanding_amount = grand_total - flt(doc.advance_paid)
|
outstanding_amount = doc.get("outstanding_amount") or (grand_total - flt(doc.advance_paid))
|
||||||
return grand_total, outstanding_amount
|
return grand_total, outstanding_amount
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,15 @@ frappe.ui.form.on('POS Closing Entry', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
set_html_data(frm);
|
set_html_data(frm);
|
||||||
|
|
||||||
|
if (frm.doc.docstatus == 1) {
|
||||||
|
if (!frm.doc.posting_date) {
|
||||||
|
frm.set_value("posting_date", frappe.datetime.nowdate());
|
||||||
|
}
|
||||||
|
if (!frm.doc.posting_time) {
|
||||||
|
frm.set_value("posting_time", frappe.datetime.now_time());
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"period_end_date",
|
"period_end_date",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"posting_date",
|
"posting_date",
|
||||||
|
"posting_time",
|
||||||
"pos_opening_entry",
|
"pos_opening_entry",
|
||||||
"status",
|
"status",
|
||||||
"section_break_5",
|
"section_break_5",
|
||||||
@@ -51,7 +52,6 @@
|
|||||||
"fieldtype": "Datetime",
|
"fieldtype": "Datetime",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Period End Date",
|
"label": "Period End Date",
|
||||||
"read_only": 1,
|
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -219,6 +219,13 @@
|
|||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Error",
|
"label": "Error",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "posting_time",
|
||||||
|
"fieldtype": "Time",
|
||||||
|
"label": "Posting Time",
|
||||||
|
"no_copy": 1,
|
||||||
|
"reqd": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
@@ -228,10 +235,11 @@
|
|||||||
"link_fieldname": "pos_closing_entry"
|
"link_fieldname": "pos_closing_entry"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2021-10-20 16:19:25.340565",
|
"modified": "2022-08-01 11:37:14.991228",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "POS Closing Entry",
|
"name": "POS Closing Entry",
|
||||||
|
"naming_rule": "Expression (old style)",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
@@ -278,5 +286,6 @@
|
|||||||
],
|
],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,9 @@ from erpnext.controllers.status_updater import StatusUpdater
|
|||||||
|
|
||||||
class POSClosingEntry(StatusUpdater):
|
class POSClosingEntry(StatusUpdater):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
|
self.posting_date = self.posting_date or frappe.utils.nowdate()
|
||||||
|
self.posting_time = self.posting_time or frappe.utils.nowtime()
|
||||||
|
|
||||||
if frappe.db.get_value("POS Opening Entry", self.pos_opening_entry, "status") != "Open":
|
if frappe.db.get_value("POS Opening Entry", self.pos_opening_entry, "status") != "Open":
|
||||||
frappe.throw(_("Selected POS Opening Entry should be open."), title=_("Invalid Opening Entry"))
|
frappe.throw(_("Selected POS Opening Entry should be open."), title=_("Invalid Opening Entry"))
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"posting_date",
|
"posting_date",
|
||||||
|
"posting_time",
|
||||||
"merge_invoices_based_on",
|
"merge_invoices_based_on",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"pos_closing_entry",
|
"pos_closing_entry",
|
||||||
@@ -105,12 +106,19 @@
|
|||||||
"label": "Customer Group",
|
"label": "Customer Group",
|
||||||
"mandatory_depends_on": "eval:doc.merge_invoices_based_on == 'Customer Group'",
|
"mandatory_depends_on": "eval:doc.merge_invoices_based_on == 'Customer Group'",
|
||||||
"options": "Customer Group"
|
"options": "Customer Group"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "posting_time",
|
||||||
|
"fieldtype": "Time",
|
||||||
|
"label": "Posting Time",
|
||||||
|
"no_copy": 1,
|
||||||
|
"reqd": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-09-14 11:17:19.001142",
|
"modified": "2022-08-01 11:36:42.456429",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "POS Invoice Merge Log",
|
"name": "POS Invoice Merge Log",
|
||||||
@@ -173,5 +181,6 @@
|
|||||||
],
|
],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@ from frappe import _
|
|||||||
from frappe.core.page.background_jobs.background_jobs import get_info
|
from frappe.core.page.background_jobs.background_jobs import get_info
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.model.mapper import map_child_doc, map_doc
|
from frappe.model.mapper import map_child_doc, map_doc
|
||||||
from frappe.utils import cint, flt, getdate, nowdate
|
from frappe.utils import cint, flt, get_time, getdate, nowdate, nowtime
|
||||||
from frappe.utils.background_jobs import enqueue
|
from frappe.utils.background_jobs import enqueue
|
||||||
from frappe.utils.scheduler import is_scheduler_inactive
|
from frappe.utils.scheduler import is_scheduler_inactive
|
||||||
|
|
||||||
@@ -99,6 +99,7 @@ class POSInvoiceMergeLog(Document):
|
|||||||
sales_invoice.is_consolidated = 1
|
sales_invoice.is_consolidated = 1
|
||||||
sales_invoice.set_posting_time = 1
|
sales_invoice.set_posting_time = 1
|
||||||
sales_invoice.posting_date = getdate(self.posting_date)
|
sales_invoice.posting_date = getdate(self.posting_date)
|
||||||
|
sales_invoice.posting_time = get_time(self.posting_time)
|
||||||
sales_invoice.save()
|
sales_invoice.save()
|
||||||
sales_invoice.submit()
|
sales_invoice.submit()
|
||||||
|
|
||||||
@@ -115,6 +116,7 @@ class POSInvoiceMergeLog(Document):
|
|||||||
credit_note.is_consolidated = 1
|
credit_note.is_consolidated = 1
|
||||||
credit_note.set_posting_time = 1
|
credit_note.set_posting_time = 1
|
||||||
credit_note.posting_date = getdate(self.posting_date)
|
credit_note.posting_date = getdate(self.posting_date)
|
||||||
|
credit_note.posting_time = get_time(self.posting_time)
|
||||||
# TODO: return could be against multiple sales invoice which could also have been consolidated?
|
# TODO: return could be against multiple sales invoice which could also have been consolidated?
|
||||||
# credit_note.return_against = self.consolidated_invoice
|
# credit_note.return_against = self.consolidated_invoice
|
||||||
credit_note.save()
|
credit_note.save()
|
||||||
@@ -402,6 +404,9 @@ def create_merge_logs(invoice_by_customer, closing_entry=None):
|
|||||||
merge_log.posting_date = (
|
merge_log.posting_date = (
|
||||||
getdate(closing_entry.get("posting_date")) if closing_entry else nowdate()
|
getdate(closing_entry.get("posting_date")) if closing_entry else nowdate()
|
||||||
)
|
)
|
||||||
|
merge_log.posting_time = (
|
||||||
|
get_time(closing_entry.get("posting_time")) if closing_entry else nowtime()
|
||||||
|
)
|
||||||
merge_log.customer = customer
|
merge_log.customer = customer
|
||||||
merge_log.pos_closing_entry = closing_entry.get("name") if closing_entry else None
|
merge_log.pos_closing_entry = closing_entry.get("name") if closing_entry else None
|
||||||
|
|
||||||
|
|||||||
@@ -1791,4 +1791,6 @@ def make_purchase_receipt(source_name, target_doc=None):
|
|||||||
target_doc,
|
target_doc,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
doc.set_onload("ignore_price_list", True)
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
|
|||||||
@@ -479,9 +479,13 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
|
|||||||
|
|
||||||
is_cash_or_non_trade_discount() {
|
is_cash_or_non_trade_discount() {
|
||||||
this.frm.set_df_property("additional_discount_account", "hidden", 1 - this.frm.doc.is_cash_or_non_trade_discount);
|
this.frm.set_df_property("additional_discount_account", "hidden", 1 - this.frm.doc.is_cash_or_non_trade_discount);
|
||||||
|
this.frm.set_df_property("additional_discount_account", "reqd", this.frm.doc.is_cash_or_non_trade_discount);
|
||||||
|
|
||||||
if (!this.frm.doc.is_cash_or_non_trade_discount) {
|
if (!this.frm.doc.is_cash_or_non_trade_discount) {
|
||||||
this.frm.set_value("additional_discount_account", "");
|
this.frm.set_value("additional_discount_account", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.calculate_taxes_and_totals();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1033,22 +1033,6 @@ class SalesInvoice(SellingController):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.apply_discount_on == "Grand Total" and self.get("is_cash_or_discount_account"):
|
|
||||||
gl_entries.append(
|
|
||||||
self.get_gl_dict(
|
|
||||||
{
|
|
||||||
"account": self.additional_discount_account,
|
|
||||||
"against": self.debit_to,
|
|
||||||
"debit": self.base_discount_amount,
|
|
||||||
"debit_in_account_currency": self.discount_amount,
|
|
||||||
"cost_center": self.cost_center,
|
|
||||||
"project": self.project,
|
|
||||||
},
|
|
||||||
self.currency,
|
|
||||||
item=self,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def make_tax_gl_entries(self, gl_entries):
|
def make_tax_gl_entries(self, gl_entries):
|
||||||
enable_discount_accounting = cint(
|
enable_discount_accounting = cint(
|
||||||
frappe.db.get_single_value("Selling Settings", "enable_discount_accounting")
|
frappe.db.get_single_value("Selling Settings", "enable_discount_accounting")
|
||||||
|
|||||||
@@ -318,7 +318,6 @@ def get_advance_vouchers(
|
|||||||
"is_cancelled": 0,
|
"is_cancelled": 0,
|
||||||
"party_type": party_type,
|
"party_type": party_type,
|
||||||
"party": ["in", parties],
|
"party": ["in", parties],
|
||||||
"against_voucher": ["is", "not set"],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if company:
|
if company:
|
||||||
|
|||||||
@@ -616,7 +616,7 @@ class GrossProfitGenerator(object):
|
|||||||
previous_stock_value = len(my_sle) > i + 1 and flt(my_sle[i + 1].stock_value) or 0.0
|
previous_stock_value = len(my_sle) > i + 1 and flt(my_sle[i + 1].stock_value) or 0.0
|
||||||
|
|
||||||
if previous_stock_value:
|
if previous_stock_value:
|
||||||
return (previous_stock_value - flt(sle.stock_value)) * flt(row.qty) / abs(flt(sle.qty))
|
return abs(previous_stock_value - flt(sle.stock_value)) * flt(row.qty) / abs(flt(sle.qty))
|
||||||
else:
|
else:
|
||||||
return flt(row.qty) * self.get_average_buying_rate(row, item_code)
|
return flt(row.qty) * self.get_average_buying_rate(row, item_code)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ def execute(filters=None):
|
|||||||
filters.naming_series = frappe.db.get_single_value("Buying Settings", "supp_master_name")
|
filters.naming_series = frappe.db.get_single_value("Buying Settings", "supp_master_name")
|
||||||
|
|
||||||
columns = get_columns(filters)
|
columns = get_columns(filters)
|
||||||
tds_docs, tds_accounts, tax_category_map = get_tds_docs(filters)
|
tds_docs, tds_accounts, tax_category_map, journal_entry_party_map = get_tds_docs(filters)
|
||||||
|
|
||||||
res = get_result(filters, tds_docs, tds_accounts, tax_category_map)
|
res = get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map)
|
||||||
final_result = group_by_supplier_and_category(res)
|
final_result = group_by_supplier_and_category(res)
|
||||||
|
|
||||||
return columns, final_result
|
return columns, final_result
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_
|
|||||||
supplier_map = get_supplier_pan_map()
|
supplier_map = get_supplier_pan_map()
|
||||||
tax_rate_map = get_tax_rate_map(filters)
|
tax_rate_map = get_tax_rate_map(filters)
|
||||||
gle_map = get_gle_map(tds_docs)
|
gle_map = get_gle_map(tds_docs)
|
||||||
print(journal_entry_party_map)
|
|
||||||
|
|
||||||
out = []
|
out = []
|
||||||
for name, details in gle_map.items():
|
for name, details in gle_map.items():
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
# Decompiled by https://python-decompiler.com
|
# Decompiled by https://python-decompiler.com
|
||||||
|
|
||||||
|
|
||||||
|
import copy
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests.utils import FrappeTestCase
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
@@ -11,10 +13,12 @@ from erpnext.buying.report.subcontracted_item_to_be_received.subcontracted_item_
|
|||||||
execute,
|
execute,
|
||||||
)
|
)
|
||||||
from erpnext.controllers.tests.test_subcontracting_controller import (
|
from erpnext.controllers.tests.test_subcontracting_controller import (
|
||||||
|
get_rm_items,
|
||||||
get_subcontracting_order,
|
get_subcontracting_order,
|
||||||
make_service_item,
|
make_service_item,
|
||||||
|
make_stock_in_entry,
|
||||||
|
make_stock_transfer_entry,
|
||||||
)
|
)
|
||||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
|
||||||
from erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order import (
|
from erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order import (
|
||||||
make_subcontracting_receipt,
|
make_subcontracting_receipt,
|
||||||
)
|
)
|
||||||
@@ -36,15 +40,18 @@ class TestSubcontractedItemToBeReceived(FrappeTestCase):
|
|||||||
sco = get_subcontracting_order(
|
sco = get_subcontracting_order(
|
||||||
service_items=service_items, supplier_warehouse="_Test Warehouse 1 - _TC"
|
service_items=service_items, supplier_warehouse="_Test Warehouse 1 - _TC"
|
||||||
)
|
)
|
||||||
make_stock_entry(
|
rm_items = get_rm_items(sco.supplied_items)
|
||||||
item_code="_Test Item", target="_Test Warehouse 1 - _TC", qty=100, basic_rate=100
|
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||||
)
|
|
||||||
make_stock_entry(
|
for item in rm_items:
|
||||||
item_code="_Test Item Home Desktop 100",
|
item["sco_rm_detail"] = sco.items[0].name
|
||||||
target="_Test Warehouse 1 - _TC",
|
|
||||||
qty=100,
|
make_stock_transfer_entry(
|
||||||
basic_rate=100,
|
sco_no=sco.name,
|
||||||
|
rm_items=rm_items,
|
||||||
|
itemwise_details=copy.deepcopy(itemwise_details),
|
||||||
)
|
)
|
||||||
|
|
||||||
make_subcontracting_receipt_against_sco(sco.name)
|
make_subcontracting_receipt_against_sco(sco.name)
|
||||||
sco.reload()
|
sco.reload()
|
||||||
col, data = execute(
|
col, data = execute(
|
||||||
|
|||||||
@@ -1109,17 +1109,17 @@ class AccountsController(TransactionBase):
|
|||||||
frappe.db.get_single_value("Selling Settings", "enable_discount_accounting")
|
frappe.db.get_single_value("Selling Settings", "enable_discount_accounting")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self.doctype == "Purchase Invoice":
|
||||||
|
dr_or_cr = "credit"
|
||||||
|
rev_dr_cr = "debit"
|
||||||
|
supplier_or_customer = self.supplier
|
||||||
|
|
||||||
|
else:
|
||||||
|
dr_or_cr = "debit"
|
||||||
|
rev_dr_cr = "credit"
|
||||||
|
supplier_or_customer = self.customer
|
||||||
|
|
||||||
if enable_discount_accounting:
|
if enable_discount_accounting:
|
||||||
if self.doctype == "Purchase Invoice":
|
|
||||||
dr_or_cr = "credit"
|
|
||||||
rev_dr_cr = "debit"
|
|
||||||
supplier_or_customer = self.supplier
|
|
||||||
|
|
||||||
else:
|
|
||||||
dr_or_cr = "debit"
|
|
||||||
rev_dr_cr = "credit"
|
|
||||||
supplier_or_customer = self.customer
|
|
||||||
|
|
||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
if item.get("discount_amount") and item.get("discount_account"):
|
if item.get("discount_amount") and item.get("discount_account"):
|
||||||
discount_amount = item.discount_amount * item.qty
|
discount_amount = item.discount_amount * item.qty
|
||||||
@@ -1173,18 +1173,22 @@ class AccountsController(TransactionBase):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.get("discount_amount") and self.get("additional_discount_account"):
|
if (
|
||||||
gl_entries.append(
|
(enable_discount_accounting or self.get("is_cash_or_non_trade_discount"))
|
||||||
self.get_gl_dict(
|
and self.get("additional_discount_account")
|
||||||
{
|
and self.get("discount_amount")
|
||||||
"account": self.additional_discount_account,
|
):
|
||||||
"against": supplier_or_customer,
|
gl_entries.append(
|
||||||
dr_or_cr: self.discount_amount,
|
self.get_gl_dict(
|
||||||
"cost_center": self.cost_center,
|
{
|
||||||
},
|
"account": self.additional_discount_account,
|
||||||
item=self,
|
"against": supplier_or_customer,
|
||||||
)
|
dr_or_cr: self.discount_amount,
|
||||||
|
"cost_center": self.cost_center,
|
||||||
|
},
|
||||||
|
item=self,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
|
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
|
||||||
from erpnext.controllers.status_updater import get_allowance_for
|
from erpnext.controllers.status_updater import get_allowance_for
|
||||||
|
|||||||
@@ -490,7 +490,7 @@ class SubcontractingController(StockController):
|
|||||||
row.item_code,
|
row.item_code,
|
||||||
row.get(self.subcontract_data.order_field),
|
row.get(self.subcontract_data.order_field),
|
||||||
) and transfer_item.qty > 0:
|
) and transfer_item.qty > 0:
|
||||||
qty = self.__get_qty_based_on_material_transfer(row, transfer_item) or 0
|
qty = flt(self.__get_qty_based_on_material_transfer(row, transfer_item))
|
||||||
transfer_item.qty -= qty
|
transfer_item.qty -= qty
|
||||||
self.__add_supplied_item(row, transfer_item.get("item_details"), qty)
|
self.__add_supplied_item(row, transfer_item.get("item_details"), qty)
|
||||||
|
|
||||||
@@ -720,6 +720,25 @@ class SubcontractingController(StockController):
|
|||||||
sco_doc = frappe.get_doc("Subcontracting Order", sco)
|
sco_doc = frappe.get_doc("Subcontracting Order", sco)
|
||||||
sco_doc.update_status()
|
sco_doc.update_status()
|
||||||
|
|
||||||
|
def set_missing_values_in_additional_costs(self):
|
||||||
|
self.total_additional_costs = sum(flt(item.amount) for item in self.get("additional_costs"))
|
||||||
|
|
||||||
|
if self.total_additional_costs:
|
||||||
|
if self.distribute_additional_costs_based_on == "Amount":
|
||||||
|
total_amt = sum(flt(item.amount) for item in self.get("items"))
|
||||||
|
for item in self.items:
|
||||||
|
item.additional_cost_per_qty = (
|
||||||
|
(item.amount * self.total_additional_costs) / total_amt
|
||||||
|
) / item.qty
|
||||||
|
else:
|
||||||
|
total_qty = sum(flt(item.qty) for item in self.get("items"))
|
||||||
|
additional_cost_per_qty = self.total_additional_costs / total_qty
|
||||||
|
for item in self.items:
|
||||||
|
item.additional_cost_per_qty = additional_cost_per_qty
|
||||||
|
else:
|
||||||
|
for item in self.items:
|
||||||
|
item.additional_cost_per_qty = 0
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_current_stock(self):
|
def get_current_stock(self):
|
||||||
if self.doctype in ["Purchase Receipt", "Subcontracting Receipt"]:
|
if self.doctype in ["Purchase Receipt", "Subcontracting Receipt"]:
|
||||||
@@ -730,7 +749,7 @@ class SubcontractingController(StockController):
|
|||||||
{"item_code": item.rm_item_code, "warehouse": self.supplier_warehouse},
|
{"item_code": item.rm_item_code, "warehouse": self.supplier_warehouse},
|
||||||
"actual_qty",
|
"actual_qty",
|
||||||
)
|
)
|
||||||
item.current_stock = flt(actual_qty) or 0
|
item.current_stock = flt(actual_qty)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sub_contracted_items(self):
|
def sub_contracted_items(self):
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ class calculate_taxes_and_totals(object):
|
|||||||
self.set_discount_amount()
|
self.set_discount_amount()
|
||||||
self.apply_discount_amount()
|
self.apply_discount_amount()
|
||||||
|
|
||||||
|
# Update grand total as per cash and non trade discount
|
||||||
|
if self.doc.apply_discount_on == "Grand Total" and self.doc.get("is_cash_or_non_trade_discount"):
|
||||||
|
self.doc.grand_total -= self.doc.discount_amount
|
||||||
|
self.doc.base_grand_total -= self.doc.base_discount_amount
|
||||||
|
|
||||||
self.calculate_shipping_charges()
|
self.calculate_shipping_charges()
|
||||||
|
|
||||||
if self.doc.doctype in ["Sales Invoice", "Purchase Invoice"]:
|
if self.doc.doctype in ["Sales Invoice", "Purchase Invoice"]:
|
||||||
@@ -500,9 +505,6 @@ class calculate_taxes_and_totals(object):
|
|||||||
else:
|
else:
|
||||||
self.doc.grand_total = flt(self.doc.net_total)
|
self.doc.grand_total = flt(self.doc.net_total)
|
||||||
|
|
||||||
if self.doc.apply_discount_on == "Grand Total" and self.doc.get("is_cash_or_non_trade_discount"):
|
|
||||||
self.doc.grand_total -= self.doc.discount_amount
|
|
||||||
|
|
||||||
if self.doc.get("taxes"):
|
if self.doc.get("taxes"):
|
||||||
self.doc.total_taxes_and_charges = flt(
|
self.doc.total_taxes_and_charges = flt(
|
||||||
self.doc.grand_total - self.doc.net_total - flt(self.doc.rounding_adjustment),
|
self.doc.grand_total - self.doc.net_total - flt(self.doc.rounding_adjustment),
|
||||||
@@ -597,16 +599,16 @@ class calculate_taxes_and_totals(object):
|
|||||||
if not self.doc.apply_discount_on:
|
if not self.doc.apply_discount_on:
|
||||||
frappe.throw(_("Please select Apply Discount On"))
|
frappe.throw(_("Please select Apply Discount On"))
|
||||||
|
|
||||||
|
self.doc.base_discount_amount = flt(
|
||||||
|
self.doc.discount_amount * self.doc.conversion_rate, self.doc.precision("base_discount_amount")
|
||||||
|
)
|
||||||
|
|
||||||
if self.doc.apply_discount_on == "Grand Total" and self.doc.get(
|
if self.doc.apply_discount_on == "Grand Total" and self.doc.get(
|
||||||
"is_cash_or_non_trade_discount"
|
"is_cash_or_non_trade_discount"
|
||||||
):
|
):
|
||||||
self.discount_amount_applied = True
|
self.discount_amount_applied = True
|
||||||
return
|
return
|
||||||
|
|
||||||
self.doc.base_discount_amount = flt(
|
|
||||||
self.doc.discount_amount * self.doc.conversion_rate, self.doc.precision("base_discount_amount")
|
|
||||||
)
|
|
||||||
|
|
||||||
total_for_discount_amount = self.get_total_for_discount_amount()
|
total_for_discount_amount = self.get_total_for_discount_amount()
|
||||||
taxes = self.doc.get("taxes")
|
taxes = self.doc.get("taxes")
|
||||||
net_total = 0
|
net_total = 0
|
||||||
|
|||||||
@@ -36,6 +36,36 @@ class TestSubcontractingController(FrappeTestCase):
|
|||||||
sco.remove_empty_rows()
|
sco.remove_empty_rows()
|
||||||
self.assertEqual((len_before - 1), len(sco.service_items))
|
self.assertEqual((len_before - 1), len(sco.service_items))
|
||||||
|
|
||||||
|
def test_set_missing_values_in_additional_costs(self):
|
||||||
|
sco = get_subcontracting_order(do_not_submit=1)
|
||||||
|
|
||||||
|
rate_without_additional_cost = sco.items[0].rate
|
||||||
|
amount_without_additional_cost = sco.items[0].amount
|
||||||
|
|
||||||
|
additional_amount = 120
|
||||||
|
sco.append(
|
||||||
|
"additional_costs",
|
||||||
|
{
|
||||||
|
"expense_account": "Cost of Goods Sold - _TC",
|
||||||
|
"description": "Test",
|
||||||
|
"amount": additional_amount,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
sco.save()
|
||||||
|
|
||||||
|
additional_cost_per_qty = additional_amount / sco.items[0].qty
|
||||||
|
|
||||||
|
self.assertEqual(sco.items[0].additional_cost_per_qty, additional_cost_per_qty)
|
||||||
|
self.assertEqual(rate_without_additional_cost + additional_cost_per_qty, sco.items[0].rate)
|
||||||
|
self.assertEqual(amount_without_additional_cost + additional_amount, sco.items[0].amount)
|
||||||
|
|
||||||
|
sco.additional_costs = []
|
||||||
|
sco.save()
|
||||||
|
|
||||||
|
self.assertEqual(sco.items[0].additional_cost_per_qty, 0)
|
||||||
|
self.assertEqual(rate_without_additional_cost, sco.items[0].rate)
|
||||||
|
self.assertEqual(amount_without_additional_cost, sco.items[0].amount)
|
||||||
|
|
||||||
def test_create_raw_materials_supplied(self):
|
def test_create_raw_materials_supplied(self):
|
||||||
sco = get_subcontracting_order()
|
sco = get_subcontracting_order()
|
||||||
sco.supplied_items = None
|
sco.supplied_items = None
|
||||||
|
|||||||
@@ -340,8 +340,8 @@
|
|||||||
"fieldname": "no_of_employees",
|
"fieldname": "no_of_employees",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "No of Employees",
|
"label": "No of Employees",
|
||||||
"options": "1-10\n11-20\n21-30\n31-100\n11-50\n51-200\n201-500\n101-500\n500-1000\n501-1000\n>1000\n1000+"
|
"options": "1-10\n11-50\n51-200\n201-500\n501-1000\n1000+"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_22",
|
"fieldname": "column_break_22",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
@@ -514,7 +514,7 @@
|
|||||||
"idx": 5,
|
"idx": 5,
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-07-22 15:55:03.176094",
|
"modified": "2022-08-09 18:26:17.101521",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Lead",
|
"name": "Lead",
|
||||||
|
|||||||
@@ -463,7 +463,7 @@
|
|||||||
"fieldname": "no_of_employees",
|
"fieldname": "no_of_employees",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "No of Employees",
|
"label": "No of Employees",
|
||||||
"options": "1-10\n11-20\n21-30\n31-100\n11-50\n51-200\n201-500\n101-500\n500-1000\n501-1000\n>1000\n1000+"
|
"options": "1-10\n11-50\n51-200\n201-500\n501-1000\n1000+"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "annual_revenue",
|
"fieldname": "annual_revenue",
|
||||||
@@ -622,7 +622,7 @@
|
|||||||
"icon": "fa fa-info-sign",
|
"icon": "fa fa-info-sign",
|
||||||
"idx": 195,
|
"idx": 195,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-07-22 18:46:32.858696",
|
"modified": "2022-08-09 18:26:37.235964",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Opportunity",
|
"name": "Opportunity",
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
"fieldname": "no_of_employees",
|
"fieldname": "no_of_employees",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "No. of Employees",
|
"label": "No. of Employees",
|
||||||
"options": "1-10\n11-20\n21-30\n31-100\n11-50\n51-200\n201-500\n101-500\n500-1000\n501-1000\n>1000\n1000+"
|
"options": "1-10\n11-50\n51-200\n201-500\n501-1000\n1000+"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "annual_revenue",
|
"fieldname": "annual_revenue",
|
||||||
@@ -218,7 +218,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-06-22 15:10:26.887502",
|
"modified": "2022-08-09 18:26:56.950185",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Prospect",
|
"name": "Prospect",
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from decimal import Decimal
|
|||||||
import frappe
|
import frappe
|
||||||
from bs4 import BeautifulSoup as bs
|
from bs4 import BeautifulSoup as bs
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
from frappe.custom.doctype.custom_field.custom_field import (
|
||||||
|
create_custom_fields as _create_custom_fields,
|
||||||
|
)
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils.data import format_datetime
|
from frappe.utils.data import format_datetime
|
||||||
|
|
||||||
@@ -577,22 +579,25 @@ class TallyMigration(Document):
|
|||||||
new_year.save()
|
new_year.save()
|
||||||
oldest_year = new_year
|
oldest_year = new_year
|
||||||
|
|
||||||
def create_custom_fields(doctypes):
|
def create_custom_fields():
|
||||||
tally_guid_df = {
|
_create_custom_fields(
|
||||||
"fieldtype": "Data",
|
{
|
||||||
"fieldname": "tally_guid",
|
("Journal Entry", "Purchase Invoice", "Sales Invoice"): [
|
||||||
"read_only": 1,
|
{
|
||||||
"label": "Tally GUID",
|
"fieldtype": "Data",
|
||||||
}
|
"fieldname": "tally_guid",
|
||||||
tally_voucher_no_df = {
|
"read_only": 1,
|
||||||
"fieldtype": "Data",
|
"label": "Tally GUID",
|
||||||
"fieldname": "tally_voucher_no",
|
},
|
||||||
"read_only": 1,
|
{
|
||||||
"label": "Tally Voucher Number",
|
"fieldtype": "Data",
|
||||||
}
|
"fieldname": "tally_voucher_no",
|
||||||
for df in [tally_guid_df, tally_voucher_no_df]:
|
"read_only": 1,
|
||||||
for doctype in doctypes:
|
"label": "Tally Voucher Number",
|
||||||
create_custom_field(doctype, df)
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def create_price_list():
|
def create_price_list():
|
||||||
frappe.get_doc(
|
frappe.get_doc(
|
||||||
@@ -628,7 +633,7 @@ class TallyMigration(Document):
|
|||||||
|
|
||||||
create_fiscal_years(vouchers)
|
create_fiscal_years(vouchers)
|
||||||
create_price_list()
|
create_price_list()
|
||||||
create_custom_fields(["Journal Entry", "Purchase Invoice", "Sales Invoice"])
|
create_custom_fields()
|
||||||
|
|
||||||
total = len(vouchers)
|
total = len(vouchers)
|
||||||
is_last = False
|
is_last = False
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from urllib.parse import urlparse
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils.nestedset import get_root_of
|
from frappe.utils.nestedset import get_root_of
|
||||||
|
|
||||||
@@ -19,27 +19,24 @@ 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_custom_fields(
|
||||||
# create
|
{
|
||||||
for doctype in ["Customer", "Sales Order", "Item", "Address"]:
|
("Customer", "Sales Order", "Item", "Address"): dict(
|
||||||
df = dict(
|
fieldname="woocommerce_id",
|
||||||
fieldname="woocommerce_id",
|
label="Woocommerce ID",
|
||||||
label="Woocommerce ID",
|
fieldtype="Data",
|
||||||
fieldtype="Data",
|
read_only=1,
|
||||||
read_only=1,
|
print_hide=1,
|
||||||
print_hide=1,
|
),
|
||||||
)
|
("Customer", "Address"): dict(
|
||||||
create_custom_field(doctype, df)
|
fieldname="woocommerce_email",
|
||||||
|
label="Woocommerce Email",
|
||||||
for doctype in ["Customer", "Address"]:
|
fieldtype="Data",
|
||||||
df = dict(
|
read_only=1,
|
||||||
fieldname="woocommerce_email",
|
print_hide=1,
|
||||||
label="Woocommerce Email",
|
),
|
||||||
fieldtype="Data",
|
}
|
||||||
read_only=1,
|
)
|
||||||
print_hide=1,
|
|
||||||
)
|
|
||||||
create_custom_field(doctype, df)
|
|
||||||
|
|
||||||
if not frappe.get_value("Item Group", {"name": _("WooCommerce Products")}):
|
if not frappe.get_value("Item Group", {"name": _("WooCommerce Products")}):
|
||||||
item_group = frappe.new_doc("Item Group")
|
item_group = frappe.new_doc("Item Group")
|
||||||
|
|||||||
@@ -135,7 +135,11 @@ def calculate_accrual_amount_for_demand_loans(
|
|||||||
def make_accrual_interest_entry_for_demand_loans(
|
def make_accrual_interest_entry_for_demand_loans(
|
||||||
posting_date, process_loan_interest, open_loans=None, loan_type=None, accrual_type="Regular"
|
posting_date, process_loan_interest, open_loans=None, loan_type=None, accrual_type="Regular"
|
||||||
):
|
):
|
||||||
query_filters = {"status": ("in", ["Disbursed", "Partially Disbursed"]), "docstatus": 1}
|
query_filters = {
|
||||||
|
"status": ("in", ["Disbursed", "Partially Disbursed"]),
|
||||||
|
"docstatus": 1,
|
||||||
|
"is_term_loan": 0,
|
||||||
|
}
|
||||||
|
|
||||||
if loan_type:
|
if loan_type:
|
||||||
query_filters.update({"loan_type": loan_type})
|
query_filters.update({"loan_type": loan_type})
|
||||||
@@ -229,6 +233,7 @@ def get_term_loans(date, term_loan=None, loan_type=None):
|
|||||||
AND l.is_term_loan =1
|
AND l.is_term_loan =1
|
||||||
AND rs.payment_date <= %s
|
AND rs.payment_date <= %s
|
||||||
AND rs.is_accrued=0 {0}
|
AND rs.is_accrued=0 {0}
|
||||||
|
AND rs.interest_amount > 0
|
||||||
AND l.status = 'Disbursed'
|
AND l.status = 'Disbursed'
|
||||||
ORDER BY rs.payment_date""".format(
|
ORDER BY rs.payment_date""".format(
|
||||||
condition
|
condition
|
||||||
|
|||||||
@@ -310,4 +310,5 @@ erpnext.patches.v14_0.crm_ux_cleanup
|
|||||||
erpnext.patches.v14_0.remove_india_localisation # 14-07-2022
|
erpnext.patches.v14_0.remove_india_localisation # 14-07-2022
|
||||||
erpnext.patches.v13_0.fix_number_and_frequency_for_monthly_depreciation
|
erpnext.patches.v13_0.fix_number_and_frequency_for_monthly_depreciation
|
||||||
erpnext.patches.v14_0.remove_hr_and_payroll_modules # 20-07-2022
|
erpnext.patches.v14_0.remove_hr_and_payroll_modules # 20-07-2022
|
||||||
erpnext.patches.v14_0.create_accounting_dimensions_in_subcontracting_doctypes
|
erpnext.patches.v14_0.fix_crm_no_of_employees
|
||||||
|
erpnext.patches.v14_0.create_accounting_dimensions_in_subcontracting_doctypes
|
||||||
|
|||||||
26
erpnext/patches/v14_0/fix_crm_no_of_employees.py
Normal file
26
erpnext/patches/v14_0/fix_crm_no_of_employees.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
options = {
|
||||||
|
"11-20": "11-50",
|
||||||
|
"21-30": "11-50",
|
||||||
|
"31-100": "51-200",
|
||||||
|
"101-500": "201-500",
|
||||||
|
"500-1000": "501-1000",
|
||||||
|
">1000": "1000+",
|
||||||
|
}
|
||||||
|
|
||||||
|
for doctype in ("Lead", "Opportunity", "Prospect"):
|
||||||
|
frappe.reload_doctype(doctype)
|
||||||
|
for key, value in options.items():
|
||||||
|
frappe.db.sql(
|
||||||
|
"""
|
||||||
|
update `tab{doctype}`
|
||||||
|
set no_of_employees = %s
|
||||||
|
where no_of_employees = %s
|
||||||
|
""".format(
|
||||||
|
doctype=doctype
|
||||||
|
),
|
||||||
|
(value, key),
|
||||||
|
)
|
||||||
@@ -39,6 +39,12 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
this._calculate_taxes_and_totals();
|
this._calculate_taxes_and_totals();
|
||||||
this.calculate_discount_amount();
|
this.calculate_discount_amount();
|
||||||
|
|
||||||
|
// # Update grand total as per cash and non trade discount
|
||||||
|
if (this.frm.doc.apply_discount_on == "Grand Total" && this.frm.doc.is_cash_or_non_trade_discount) {
|
||||||
|
this.frm.doc.grand_total -= this.frm.doc.discount_amount;
|
||||||
|
this.frm.doc.base_grand_total -= this.frm.doc.base_discount_amount;
|
||||||
|
}
|
||||||
|
|
||||||
await this.calculate_shipping_charges();
|
await this.calculate_shipping_charges();
|
||||||
|
|
||||||
// Advance calculation applicable to Sales /Purchase Invoice
|
// Advance calculation applicable to Sales /Purchase Invoice
|
||||||
@@ -633,6 +639,10 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
this.frm.doc.base_discount_amount = flt(this.frm.doc.discount_amount * this.frm.doc.conversion_rate,
|
this.frm.doc.base_discount_amount = flt(this.frm.doc.discount_amount * this.frm.doc.conversion_rate,
|
||||||
precision("base_discount_amount"));
|
precision("base_discount_amount"));
|
||||||
|
|
||||||
|
if (this.frm.doc.apply_discount_on == "Grand Total" && this.frm.doc.is_cash_or_non_trade_discount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var total_for_discount_amount = this.get_total_for_discount_amount();
|
var total_for_discount_amount = this.get_total_for_discount_amount();
|
||||||
var net_total = 0;
|
var net_total = 0;
|
||||||
// calculate item amount after Discount Amount
|
// calculate item amount after Discount Amount
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||||
from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to
|
from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to
|
||||||
from frappe.utils import cint
|
from frappe.utils import cint
|
||||||
|
|
||||||
@@ -83,35 +83,32 @@ def setup_currency_exchange():
|
|||||||
|
|
||||||
|
|
||||||
def create_print_setting_custom_fields():
|
def create_print_setting_custom_fields():
|
||||||
create_custom_field(
|
create_custom_fields(
|
||||||
"Print Settings",
|
|
||||||
{
|
{
|
||||||
"label": _("Compact Item Print"),
|
"Print Settings": [
|
||||||
"fieldname": "compact_item_print",
|
{
|
||||||
"fieldtype": "Check",
|
"label": _("Compact Item Print"),
|
||||||
"default": 1,
|
"fieldname": "compact_item_print",
|
||||||
"insert_after": "with_letterhead",
|
"fieldtype": "Check",
|
||||||
},
|
"default": "1",
|
||||||
)
|
"insert_after": "with_letterhead",
|
||||||
create_custom_field(
|
},
|
||||||
"Print Settings",
|
{
|
||||||
{
|
"label": _("Print UOM after Quantity"),
|
||||||
"label": _("Print UOM after Quantity"),
|
"fieldname": "print_uom_after_quantity",
|
||||||
"fieldname": "print_uom_after_quantity",
|
"fieldtype": "Check",
|
||||||
"fieldtype": "Check",
|
"default": "0",
|
||||||
"default": 0,
|
"insert_after": "compact_item_print",
|
||||||
"insert_after": "compact_item_print",
|
},
|
||||||
},
|
{
|
||||||
)
|
"label": _("Print taxes with zero amount"),
|
||||||
create_custom_field(
|
"fieldname": "print_taxes_with_zero_amount",
|
||||||
"Print Settings",
|
"fieldtype": "Check",
|
||||||
{
|
"default": "0",
|
||||||
"label": _("Print taxes with zero amount"),
|
"insert_after": "allow_print_for_cancelled",
|
||||||
"fieldname": "print_taxes_with_zero_amount",
|
},
|
||||||
"fieldtype": "Check",
|
]
|
||||||
"default": 0,
|
}
|
||||||
"insert_after": "allow_print_for_cancelled",
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ frappe.ui.form.on('Repost Item Valuation', {
|
|||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
name: ['in', ['Purchase Receipt', 'Purchase Invoice', 'Delivery Note',
|
name: ['in', ['Purchase Receipt', 'Purchase Invoice', 'Delivery Note',
|
||||||
'Sales Invoice', 'Stock Entry', 'Stock Reconciliation']]
|
'Sales Invoice', 'Stock Entry', 'Stock Reconciliation', 'Subcontracting Receipt']]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
let document_list = ['Landed Cost Voucher', 'Stock Entry'];
|
let document_list = ['Landed Cost Voucher', 'Stock Entry', 'Subcontracting Order', 'Subcontracting Receipt'];
|
||||||
|
|
||||||
document_list.forEach((doctype) => {
|
document_list.forEach((doctype) => {
|
||||||
frappe.ui.form.on(doctype, {
|
frappe.ui.form.on(doctype, {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
frappe.provide('erpnext.buying');
|
frappe.provide('erpnext.buying');
|
||||||
|
|
||||||
|
{% include 'erpnext/stock/landed_taxes_and_charges_common.js' %};
|
||||||
|
|
||||||
frappe.ui.form.on('Subcontracting Order', {
|
frappe.ui.form.on('Subcontracting Order', {
|
||||||
setup: (frm) => {
|
setup: (frm) => {
|
||||||
frm.get_field("items").grid.cannot_add_rows = true;
|
frm.get_field("items").grid.cannot_add_rows = true;
|
||||||
@@ -136,6 +138,16 @@ frappe.ui.form.on('Subcontracting Order', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on('Landed Cost Taxes and Charges', {
|
||||||
|
amount: function (frm, cdt, cdn) {
|
||||||
|
frm.events.set_base_amount(frm, cdt, cdn);
|
||||||
|
},
|
||||||
|
|
||||||
|
expense_account: function (frm, cdt, cdn) {
|
||||||
|
frm.events.set_account_currency(frm, cdt, cdn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
erpnext.buying.SubcontractingOrderController = class SubcontractingOrderController {
|
erpnext.buying.SubcontractingOrderController = class SubcontractingOrderController {
|
||||||
setup() {
|
setup() {
|
||||||
this.frm.custom_make_buttons = {
|
this.frm.custom_make_buttons = {
|
||||||
|
|||||||
@@ -82,25 +82,6 @@ class SubcontractingOrder(SubcontractingController):
|
|||||||
self.set_missing_values_in_supplied_items()
|
self.set_missing_values_in_supplied_items()
|
||||||
self.set_missing_values_in_items()
|
self.set_missing_values_in_items()
|
||||||
|
|
||||||
def set_missing_values_in_additional_costs(self):
|
|
||||||
if self.get("additional_costs"):
|
|
||||||
self.total_additional_costs = sum(flt(item.amount) for item in self.get("additional_costs"))
|
|
||||||
|
|
||||||
if self.total_additional_costs:
|
|
||||||
if self.distribute_additional_costs_based_on == "Amount":
|
|
||||||
total_amt = sum(flt(item.amount) for item in self.get("items"))
|
|
||||||
for item in self.items:
|
|
||||||
item.additional_cost_per_qty = (
|
|
||||||
(item.amount * self.total_additional_costs) / total_amt
|
|
||||||
) / item.qty
|
|
||||||
else:
|
|
||||||
total_qty = sum(flt(item.qty) for item in self.get("items"))
|
|
||||||
additional_cost_per_qty = self.total_additional_costs / total_qty
|
|
||||||
for item in self.items:
|
|
||||||
item.additional_cost_per_qty = additional_cost_per_qty
|
|
||||||
else:
|
|
||||||
self.total_additional_costs = 0
|
|
||||||
|
|
||||||
def set_missing_values_in_service_items(self):
|
def set_missing_values_in_service_items(self):
|
||||||
for idx, item in enumerate(self.get("service_items")):
|
for idx, item in enumerate(self.get("service_items")):
|
||||||
self.items[idx].service_cost_per_qty = item.amount / self.items[idx].qty
|
self.items[idx].service_cost_per_qty = item.amount / self.items[idx].qty
|
||||||
@@ -114,9 +95,7 @@ class SubcontractingOrder(SubcontractingController):
|
|||||||
def set_missing_values_in_items(self):
|
def set_missing_values_in_items(self):
|
||||||
total_qty = total = 0
|
total_qty = total = 0
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
item.rate = (
|
item.rate = item.rm_cost_per_qty + item.service_cost_per_qty + flt(item.additional_cost_per_qty)
|
||||||
item.rm_cost_per_qty + item.service_cost_per_qty + (item.additional_cost_per_qty or 0)
|
|
||||||
)
|
|
||||||
item.amount = item.qty * item.rate
|
item.amount = item.qty * item.rate
|
||||||
total_qty += flt(item.qty)
|
total_qty += flt(item.qty)
|
||||||
total += flt(item.amount)
|
total += flt(item.amount)
|
||||||
@@ -187,7 +166,7 @@ class SubcontractingOrder(SubcontractingController):
|
|||||||
total_required_qty = total_supplied_qty = 0
|
total_required_qty = total_supplied_qty = 0
|
||||||
for item in self.supplied_items:
|
for item in self.supplied_items:
|
||||||
total_required_qty += item.required_qty
|
total_required_qty += item.required_qty
|
||||||
total_supplied_qty += item.supplied_qty or 0
|
total_supplied_qty += flt(item.supplied_qty)
|
||||||
if total_supplied_qty:
|
if total_supplied_qty:
|
||||||
status = "Partial Material Transferred"
|
status = "Partial Material Transferred"
|
||||||
if total_supplied_qty >= total_required_qty:
|
if total_supplied_qty >= total_required_qty:
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
frappe.provide('erpnext.buying');
|
frappe.provide('erpnext.buying');
|
||||||
|
|
||||||
|
{% include 'erpnext/stock/landed_taxes_and_charges_common.js' %};
|
||||||
|
|
||||||
frappe.ui.form.on('Subcontracting Receipt', {
|
frappe.ui.form.on('Subcontracting Receipt', {
|
||||||
setup: (frm) => {
|
setup: (frm) => {
|
||||||
frm.get_field('supplied_items').grid.cannot_add_rows = true;
|
frm.get_field('supplied_items').grid.cannot_add_rows = true;
|
||||||
@@ -128,6 +130,16 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on('Landed Cost Taxes and Charges', {
|
||||||
|
amount: function (frm, cdt, cdn) {
|
||||||
|
frm.events.set_base_amount(frm, cdt, cdn);
|
||||||
|
},
|
||||||
|
|
||||||
|
expense_account: function (frm, cdt, cdn) {
|
||||||
|
frm.events.set_account_currency(frm, cdt, cdn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
frappe.ui.form.on('Subcontracting Receipt Item', {
|
frappe.ui.form.on('Subcontracting Receipt Item', {
|
||||||
item_code(frm) {
|
item_code(frm) {
|
||||||
set_missing_values(frm);
|
set_missing_values(frm);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"company",
|
"company",
|
||||||
"posting_date",
|
"posting_date",
|
||||||
"posting_time",
|
"posting_time",
|
||||||
|
"set_posting_time",
|
||||||
"is_return",
|
"is_return",
|
||||||
"return_against",
|
"return_against",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
@@ -47,12 +48,14 @@
|
|||||||
"raw_material_details",
|
"raw_material_details",
|
||||||
"get_current_stock",
|
"get_current_stock",
|
||||||
"supplied_items",
|
"supplied_items",
|
||||||
|
"additional_costs_section",
|
||||||
|
"distribute_additional_costs_based_on",
|
||||||
|
"additional_costs",
|
||||||
|
"total_additional_costs",
|
||||||
"section_break_46",
|
"section_break_46",
|
||||||
"in_words",
|
"in_words",
|
||||||
"bill_no",
|
"bill_no",
|
||||||
"bill_date",
|
"bill_date",
|
||||||
"accounting_details_section",
|
|
||||||
"provisional_expense_account",
|
|
||||||
"more_info",
|
"more_info",
|
||||||
"status",
|
"status",
|
||||||
"column_break_39",
|
"column_break_39",
|
||||||
@@ -136,6 +139,7 @@
|
|||||||
"label": "Date",
|
"label": "Date",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
|
"read_only_depends_on": "eval: !doc.set_posting_time",
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
@@ -148,6 +152,7 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
|
"read_only_depends_on": "eval: !doc.set_posting_time",
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
@@ -524,19 +529,6 @@
|
|||||||
"options": "Company",
|
"options": "Company",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"collapsible": 1,
|
|
||||||
"fieldname": "accounting_details_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Accounting Details"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "provisional_expense_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 1,
|
|
||||||
"label": "Provisional Expense Account",
|
|
||||||
"options": "Account"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "is_return",
|
"fieldname": "is_return",
|
||||||
@@ -595,11 +587,48 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Project",
|
"label": "Project",
|
||||||
"options": "Project"
|
"options": "Project"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"collapsible_depends_on": "total_additional_costs",
|
||||||
|
"depends_on": "eval:(doc.docstatus == 0 || doc.total_additional_costs)",
|
||||||
|
"fieldname": "additional_costs_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Additional Costs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "Qty",
|
||||||
|
"fieldname": "distribute_additional_costs_based_on",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Distribute Additional Costs Based On ",
|
||||||
|
"options": "Qty\nAmount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "additional_costs",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"label": "Additional Costs",
|
||||||
|
"options": "Landed Cost Taxes and Charges"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "total_additional_costs",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Total Additional Costs",
|
||||||
|
"print_hide_if_no_value": 1,
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"depends_on": "eval:doc.docstatus==0",
|
||||||
|
"fieldname": "set_posting_time",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Edit Posting Date and Time",
|
||||||
|
"print_hide": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"in_create": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-08-15 14:30:29.447307",
|
"modified": "2022-08-22 17:30:40.827517",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Subcontracting",
|
"module": "Subcontracting",
|
||||||
"name": "Subcontracting Receipt",
|
"name": "Subcontracting Receipt",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import cint, getdate, nowdate
|
from frappe.utils import cint, flt, getdate, nowdate
|
||||||
|
|
||||||
from erpnext.controllers.subcontracting_controller import SubcontractingController
|
from erpnext.controllers.subcontracting_controller import SubcontractingController
|
||||||
|
|
||||||
@@ -103,6 +103,7 @@ class SubcontractingReceipt(SubcontractingController):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def set_missing_values(self):
|
def set_missing_values(self):
|
||||||
|
self.set_missing_values_in_additional_costs()
|
||||||
self.set_missing_values_in_supplied_items()
|
self.set_missing_values_in_supplied_items()
|
||||||
self.set_missing_values_in_items()
|
self.set_missing_values_in_items()
|
||||||
|
|
||||||
@@ -125,12 +126,12 @@ class SubcontractingReceipt(SubcontractingController):
|
|||||||
item.rm_cost_per_qty = item.rm_supp_cost / item.qty
|
item.rm_cost_per_qty = item.rm_supp_cost / item.qty
|
||||||
rm_supp_cost.pop(item.name)
|
rm_supp_cost.pop(item.name)
|
||||||
|
|
||||||
if self.is_new() and item.rm_supp_cost > 0:
|
if item.recalculate_rate:
|
||||||
item.rate = (
|
item.rate = (
|
||||||
item.rm_cost_per_qty + (item.service_cost_per_qty or 0) + item.additional_cost_per_qty
|
flt(item.rm_cost_per_qty) + flt(item.service_cost_per_qty) + flt(item.additional_cost_per_qty)
|
||||||
)
|
)
|
||||||
|
|
||||||
item.received_qty = item.qty + (item.rejected_qty or 0)
|
item.received_qty = item.qty + flt(item.rejected_qty)
|
||||||
item.amount = item.qty * item.rate
|
item.amount = item.qty * item.rate
|
||||||
total_qty += item.qty
|
total_qty += item.qty
|
||||||
total_amount += item.amount
|
total_amount += item.amount
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
"rate_and_amount",
|
"rate_and_amount",
|
||||||
"rate",
|
"rate",
|
||||||
"amount",
|
"amount",
|
||||||
|
"recalculate_rate",
|
||||||
"column_break_19",
|
"column_break_19",
|
||||||
"rm_cost_per_qty",
|
"rm_cost_per_qty",
|
||||||
"service_cost_per_qty",
|
"service_cost_per_qty",
|
||||||
@@ -193,6 +194,8 @@
|
|||||||
"label": "Rate",
|
"label": "Rate",
|
||||||
"options": "currency",
|
"options": "currency",
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
|
"read_only": 1,
|
||||||
|
"read_only_depends_on": "eval: doc.recalculate_rate",
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -460,12 +463,18 @@
|
|||||||
"fieldname": "accounting_details_section",
|
"fieldname": "accounting_details_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Accounting Details"
|
"label": "Accounting Details"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "1",
|
||||||
|
"fieldname": "recalculate_rate",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Recalculate Rate"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-08-15 14:51:10.613347",
|
"modified": "2022-08-20 17:16:48.269164",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Subcontracting",
|
"module": "Subcontracting",
|
||||||
"name": "Subcontracting Receipt Item",
|
"name": "Subcontracting Receipt Item",
|
||||||
|
|||||||
Reference in New Issue
Block a user