Merge branch 'develop' into asset_last_day_test_bug
This commit is contained in:
commit
ba38001116
@ -91,7 +91,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"description": "Enabling ensure each Sales Invoice has a unique value in Supplier Invoice No. field",
|
"description": "Enabling ensure each Purchase Invoice has a unique value in Supplier Invoice No. field",
|
||||||
"fieldname": "check_supplier_invoice_uniqueness",
|
"fieldname": "check_supplier_invoice_uniqueness",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Check Supplier Invoice Number Uniqueness"
|
"label": "Check Supplier Invoice Number Uniqueness"
|
||||||
@ -354,7 +354,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-07-11 13:37:50.605141",
|
"modified": "2022-11-27 21:49:52.538655",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
|
@ -37,6 +37,14 @@ frappe.ui.form.on("Bank Clearance", {
|
|||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
frm.disable_save();
|
frm.disable_save();
|
||||||
|
|
||||||
|
if (frm.doc.account && frm.doc.from_date && frm.doc.to_date) {
|
||||||
|
frm.add_custom_button(__('Get Payment Entries'), () =>
|
||||||
|
frm.trigger("get_payment_entries")
|
||||||
|
);
|
||||||
|
|
||||||
|
frm.change_custom_button_type('Get Payment Entries', null, 'primary');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
update_clearance_date: function(frm) {
|
update_clearance_date: function(frm) {
|
||||||
@ -46,22 +54,30 @@ frappe.ui.form.on("Bank Clearance", {
|
|||||||
callback: function(r, rt) {
|
callback: function(r, rt) {
|
||||||
frm.refresh_field("payment_entries");
|
frm.refresh_field("payment_entries");
|
||||||
frm.refresh_fields();
|
frm.refresh_fields();
|
||||||
|
|
||||||
|
if (!frm.doc.payment_entries.length) {
|
||||||
|
frm.change_custom_button_type('Get Payment Entries', null, 'primary');
|
||||||
|
frm.change_custom_button_type('Update Clearance Date', null, 'default');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
get_payment_entries: function(frm) {
|
get_payment_entries: function(frm) {
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: "get_payment_entries",
|
method: "get_payment_entries",
|
||||||
doc: frm.doc,
|
doc: frm.doc,
|
||||||
callback: function(r, rt) {
|
callback: function(r, rt) {
|
||||||
frm.refresh_field("payment_entries");
|
frm.refresh_field("payment_entries");
|
||||||
frm.refresh_fields();
|
|
||||||
|
|
||||||
$(frm.fields_dict.payment_entries.wrapper).find("[data-fieldname=amount]").each(function(i,v){
|
if (frm.doc.payment_entries.length) {
|
||||||
if (i !=0){
|
frm.add_custom_button(__('Update Clearance Date'), () =>
|
||||||
$(v).addClass("text-right")
|
frm.trigger("update_clearance_date")
|
||||||
|
);
|
||||||
|
|
||||||
|
frm.change_custom_button_type('Get Payment Entries', null, 'default');
|
||||||
|
frm.change_custom_button_type('Update Clearance Date', null, 'primary');
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_copy": 1,
|
"allow_copy": 1,
|
||||||
"creation": "2013-01-10 16:34:05",
|
"creation": "2013-01-10 16:34:05",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -13,11 +14,8 @@
|
|||||||
"bank_account",
|
"bank_account",
|
||||||
"include_reconciled_entries",
|
"include_reconciled_entries",
|
||||||
"include_pos_transactions",
|
"include_pos_transactions",
|
||||||
"get_payment_entries",
|
|
||||||
"section_break_10",
|
"section_break_10",
|
||||||
"payment_entries",
|
"payment_entries"
|
||||||
"update_clearance_date",
|
|
||||||
"total_amount"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -76,11 +74,6 @@
|
|||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Include POS Transactions"
|
"label": "Include POS Transactions"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "get_payment_entries",
|
|
||||||
"fieldtype": "Button",
|
|
||||||
"label": "Get Payment Entries"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_10",
|
"fieldname": "section_break_10",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
@ -91,25 +84,14 @@
|
|||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Payment Entries",
|
"label": "Payment Entries",
|
||||||
"options": "Bank Clearance Detail"
|
"options": "Bank Clearance Detail"
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "update_clearance_date",
|
|
||||||
"fieldtype": "Button",
|
|
||||||
"label": "Update Clearance Date"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "total_amount",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"label": "Total Amount",
|
|
||||||
"options": "account_currency",
|
|
||||||
"read_only": 1
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hide_toolbar": 1,
|
"hide_toolbar": 1,
|
||||||
"icon": "fa fa-check",
|
"icon": "fa fa-check",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"modified": "2020-04-06 16:12:06.628008",
|
"links": [],
|
||||||
|
"modified": "2022-11-28 17:24:13.008692",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Clearance",
|
"name": "Bank Clearance",
|
||||||
@ -126,5 +108,6 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC"
|
"sort_order": "ASC",
|
||||||
|
"states": []
|
||||||
}
|
}
|
@ -179,7 +179,6 @@ class BankClearance(Document):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.set("payment_entries", [])
|
self.set("payment_entries", [])
|
||||||
self.total_amount = 0.0
|
|
||||||
default_currency = erpnext.get_default_currency()
|
default_currency = erpnext.get_default_currency()
|
||||||
|
|
||||||
for d in entries:
|
for d in entries:
|
||||||
@ -198,7 +197,6 @@ class BankClearance(Document):
|
|||||||
d.pop("debit")
|
d.pop("debit")
|
||||||
d.pop("account_currency")
|
d.pop("account_currency")
|
||||||
row.update(d)
|
row.update(d)
|
||||||
self.total_amount += flt(amount)
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def update_clearance_date(self):
|
def update_clearance_date(self):
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
frappe.provide("erpnext.accounts");
|
frappe.provide("erpnext.accounts");
|
||||||
|
|
||||||
erpnext.selling.POSInvoiceController = class POSInvoiceController extends erpnext.selling.SellingController {
|
erpnext.selling.POSInvoiceController = class POSInvoiceController extends erpnext.selling.SellingController {
|
||||||
|
settings = {};
|
||||||
|
|
||||||
setup(doc) {
|
setup(doc) {
|
||||||
this.setup_posting_date_time_check();
|
this.setup_posting_date_time_check();
|
||||||
super.setup(doc);
|
super.setup(doc);
|
||||||
@ -12,21 +14,37 @@ erpnext.selling.POSInvoiceController = class POSInvoiceController extends erpnex
|
|||||||
|
|
||||||
company() {
|
company() {
|
||||||
erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype);
|
erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype);
|
||||||
|
this.frm.set_value("set_warehouse", "");
|
||||||
|
this.frm.set_value("taxes_and_charges", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
onload(doc) {
|
onload(doc) {
|
||||||
super.onload();
|
super.onload();
|
||||||
this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice Merge Log', 'POS Closing Entry'];
|
this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice Merge Log', 'POS Closing Entry'];
|
||||||
|
|
||||||
if(doc.__islocal && doc.is_pos && frappe.get_route_str() !== 'point-of-sale') {
|
if(doc.__islocal && doc.is_pos && frappe.get_route_str() !== 'point-of-sale') {
|
||||||
this.frm.script_manager.trigger("is_pos");
|
this.frm.script_manager.trigger("is_pos");
|
||||||
this.frm.refresh_fields();
|
this.frm.refresh_fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.frm.set_query("set_warehouse", function(doc) {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
company: doc.company ? doc.company : '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype);
|
erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onload_post_render(frm) {
|
||||||
|
this.pos_profile(frm);
|
||||||
|
}
|
||||||
|
|
||||||
refresh(doc) {
|
refresh(doc) {
|
||||||
super.refresh();
|
super.refresh();
|
||||||
|
|
||||||
if (doc.docstatus == 1 && !doc.is_return) {
|
if (doc.docstatus == 1 && !doc.is_return) {
|
||||||
this.frm.add_custom_button(__('Return'), this.make_sales_return, __('Create'));
|
this.frm.add_custom_button(__('Return'), this.make_sales_return, __('Create'));
|
||||||
this.frm.page.set_inner_btn_group_as_primary(__('Create'));
|
this.frm.page.set_inner_btn_group_as_primary(__('Create'));
|
||||||
@ -36,6 +54,18 @@ erpnext.selling.POSInvoiceController = class POSInvoiceController extends erpnex
|
|||||||
this.frm.return_print_format = "Sales Invoice Return";
|
this.frm.return_print_format = "Sales Invoice Return";
|
||||||
this.frm.set_value('consolidated_invoice', '');
|
this.frm.set_value('consolidated_invoice', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.frm.set_query("customer", (function () {
|
||||||
|
const customer_groups = this.settings?.customer_groups;
|
||||||
|
|
||||||
|
if (!customer_groups?.length) return {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
customer_group: ["in", customer_groups],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
is_pos() {
|
is_pos() {
|
||||||
@ -88,6 +118,25 @@ erpnext.selling.POSInvoiceController = class POSInvoiceController extends erpnex
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pos_profile(frm) {
|
||||||
|
if (!frm.pos_profile || frm.pos_profile == '') {
|
||||||
|
this.update_customer_groups_settings([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.selling.page.point_of_sale.point_of_sale.get_pos_profile_data",
|
||||||
|
args: { "pos_profile": frm.pos_profile },
|
||||||
|
callback: ({ message: profile }) => {
|
||||||
|
this.update_customer_groups_settings(profile?.customer_groups);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
update_customer_groups_settings(customer_groups) {
|
||||||
|
this.settings.customer_groups = customer_groups?.map((group) => group.name)
|
||||||
|
}
|
||||||
|
|
||||||
amount(){
|
amount(){
|
||||||
this.write_off_outstanding_amount_automatically()
|
this.write_off_outstanding_amount_automatically()
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
"tax_category",
|
"tax_category",
|
||||||
"column_break_49",
|
"column_break_49",
|
||||||
"shipping_rule",
|
"shipping_rule",
|
||||||
|
"incoterm",
|
||||||
"section_break_51",
|
"section_break_51",
|
||||||
"taxes",
|
"taxes",
|
||||||
"totals",
|
"totals",
|
||||||
@ -1534,13 +1535,19 @@
|
|||||||
"oldfieldtype": "Section Break",
|
"oldfieldtype": "Section Break",
|
||||||
"options": "fa fa-file-text",
|
"options": "fa fa-file-text",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "incoterm",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Incoterm",
|
||||||
|
"options": "Incoterm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 204,
|
"idx": 204,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-11-22 12:44:29.935567",
|
"modified": "2022-11-25 12:44:29.935567",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Invoice",
|
"name": "Purchase Invoice",
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
"discount_amount",
|
"discount_amount",
|
||||||
"base_rate_with_margin",
|
"base_rate_with_margin",
|
||||||
"sec_break2",
|
"sec_break2",
|
||||||
"apply_tds",
|
|
||||||
"rate",
|
"rate",
|
||||||
"amount",
|
"amount",
|
||||||
"item_tax_template",
|
"item_tax_template",
|
||||||
@ -50,6 +49,7 @@
|
|||||||
"pricing_rules",
|
"pricing_rules",
|
||||||
"stock_uom_rate",
|
"stock_uom_rate",
|
||||||
"is_free_item",
|
"is_free_item",
|
||||||
|
"apply_tds",
|
||||||
"section_break_22",
|
"section_break_22",
|
||||||
"net_rate",
|
"net_rate",
|
||||||
"net_amount",
|
"net_amount",
|
||||||
@ -880,7 +880,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-10-26 16:05:37.304788",
|
"modified": "2022-11-29 13:01:20.438217",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Invoice Item",
|
"name": "Purchase Invoice Item",
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
"taxes_and_charges",
|
"taxes_and_charges",
|
||||||
"column_break_38",
|
"column_break_38",
|
||||||
"shipping_rule",
|
"shipping_rule",
|
||||||
|
"incoterm",
|
||||||
"column_break_55",
|
"column_break_55",
|
||||||
"tax_category",
|
"tax_category",
|
||||||
"section_break_40",
|
"section_break_40",
|
||||||
@ -2114,6 +2115,12 @@
|
|||||||
"label": "Repost Required",
|
"label": "Repost Required",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "incoterm",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Incoterm",
|
||||||
|
"options": "Incoterm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
@ -2126,7 +2133,7 @@
|
|||||||
"link_fieldname": "consolidated_invoice"
|
"link_fieldname": "consolidated_invoice"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2022-11-15 09:33:47.870616",
|
"modified": "2022-11-17 17:17:10.883487",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice",
|
"name": "Sales Invoice",
|
||||||
|
@ -14,9 +14,17 @@ 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, journal_entry_party_map = get_tds_docs(filters)
|
(
|
||||||
|
tds_docs,
|
||||||
|
tds_accounts,
|
||||||
|
tax_category_map,
|
||||||
|
journal_entry_party_map,
|
||||||
|
invoice_total_map,
|
||||||
|
) = get_tds_docs(filters)
|
||||||
|
|
||||||
res = get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map)
|
res = get_result(
|
||||||
|
filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map, invoice_total_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
|
||||||
|
@ -8,11 +8,19 @@ from frappe import _
|
|||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
validate_filters(filters)
|
validate_filters(filters)
|
||||||
tds_docs, tds_accounts, tax_category_map, journal_entry_party_map = get_tds_docs(filters)
|
(
|
||||||
|
tds_docs,
|
||||||
|
tds_accounts,
|
||||||
|
tax_category_map,
|
||||||
|
journal_entry_party_map,
|
||||||
|
invoice_net_total_map,
|
||||||
|
) = get_tds_docs(filters)
|
||||||
|
|
||||||
columns = get_columns(filters)
|
columns = get_columns(filters)
|
||||||
|
|
||||||
res = get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map)
|
res = get_result(
|
||||||
|
filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map, invoice_net_total_map
|
||||||
|
)
|
||||||
return columns, res
|
return columns, res
|
||||||
|
|
||||||
|
|
||||||
@ -22,7 +30,9 @@ def validate_filters(filters):
|
|||||||
frappe.throw(_("From Date must be before To Date"))
|
frappe.throw(_("From Date must be before To Date"))
|
||||||
|
|
||||||
|
|
||||||
def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map):
|
def get_result(
|
||||||
|
filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map, invoice_net_total_map
|
||||||
|
):
|
||||||
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)
|
||||||
@ -50,6 +60,9 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_
|
|||||||
if entry.account in tds_accounts:
|
if entry.account in tds_accounts:
|
||||||
tds_deducted += entry.credit - entry.debit
|
tds_deducted += entry.credit - entry.debit
|
||||||
|
|
||||||
|
if invoice_net_total_map.get(name):
|
||||||
|
total_amount_credited = invoice_net_total_map.get(name)
|
||||||
|
else:
|
||||||
total_amount_credited += entry.credit
|
total_amount_credited += entry.credit
|
||||||
|
|
||||||
if tds_deducted:
|
if tds_deducted:
|
||||||
@ -179,9 +192,10 @@ def get_tds_docs(filters):
|
|||||||
purchase_invoices = []
|
purchase_invoices = []
|
||||||
payment_entries = []
|
payment_entries = []
|
||||||
journal_entries = []
|
journal_entries = []
|
||||||
tax_category_map = {}
|
tax_category_map = frappe._dict()
|
||||||
or_filters = {}
|
invoice_net_total_map = frappe._dict()
|
||||||
journal_entry_party_map = {}
|
or_filters = frappe._dict()
|
||||||
|
journal_entry_party_map = frappe._dict()
|
||||||
bank_accounts = frappe.get_all("Account", {"is_group": 0, "account_type": "Bank"}, pluck="name")
|
bank_accounts = frappe.get_all("Account", {"is_group": 0, "account_type": "Bank"}, pluck="name")
|
||||||
|
|
||||||
tds_accounts = frappe.get_all(
|
tds_accounts = frappe.get_all(
|
||||||
@ -218,16 +232,22 @@ def get_tds_docs(filters):
|
|||||||
tds_documents.append(d.voucher_no)
|
tds_documents.append(d.voucher_no)
|
||||||
|
|
||||||
if purchase_invoices:
|
if purchase_invoices:
|
||||||
get_tax_category_map(purchase_invoices, "Purchase Invoice", tax_category_map)
|
get_doc_info(purchase_invoices, "Purchase Invoice", tax_category_map, invoice_net_total_map)
|
||||||
|
|
||||||
if payment_entries:
|
if payment_entries:
|
||||||
get_tax_category_map(payment_entries, "Payment Entry", tax_category_map)
|
get_doc_info(payment_entries, "Payment Entry", tax_category_map)
|
||||||
|
|
||||||
if journal_entries:
|
if journal_entries:
|
||||||
journal_entry_party_map = get_journal_entry_party_map(journal_entries)
|
journal_entry_party_map = get_journal_entry_party_map(journal_entries)
|
||||||
get_tax_category_map(journal_entries, "Journal Entry", tax_category_map)
|
get_doc_info(journal_entries, "Journal Entry", tax_category_map)
|
||||||
|
|
||||||
return tds_documents, tds_accounts, tax_category_map, journal_entry_party_map
|
return (
|
||||||
|
tds_documents,
|
||||||
|
tds_accounts,
|
||||||
|
tax_category_map,
|
||||||
|
journal_entry_party_map,
|
||||||
|
invoice_net_total_map,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_journal_entry_party_map(journal_entries):
|
def get_journal_entry_party_map(journal_entries):
|
||||||
@ -244,17 +264,18 @@ def get_journal_entry_party_map(journal_entries):
|
|||||||
return journal_entry_party_map
|
return journal_entry_party_map
|
||||||
|
|
||||||
|
|
||||||
def get_tax_category_map(vouchers, doctype, tax_category_map):
|
def get_doc_info(vouchers, doctype, tax_category_map, invoice_net_total_map=None):
|
||||||
tax_category_map.update(
|
if doctype == "Purchase Invoice":
|
||||||
frappe._dict(
|
fields = ["name", "tax_withholding_category", "base_tax_withholding_net_total"]
|
||||||
frappe.get_all(
|
else:
|
||||||
doctype,
|
fields = ["name", "tax_withholding_category"]
|
||||||
filters={"name": ("in", vouchers)},
|
|
||||||
fields=["name", "tax_withholding_category"],
|
entries = frappe.get_all(doctype, filters={"name": ("in", vouchers)}, fields=fields)
|
||||||
as_list=1,
|
|
||||||
)
|
for entry in entries:
|
||||||
)
|
tax_category_map.update({entry.name: entry.tax_withholding_category})
|
||||||
)
|
if doctype == "Purchase Invoice":
|
||||||
|
invoice_net_total_map.update({entry.name: entry.base_tax_withholding_net_total})
|
||||||
|
|
||||||
|
|
||||||
def get_tax_rate_map(filters):
|
def get_tax_rate_map(filters):
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
"tax_category",
|
"tax_category",
|
||||||
"column_break_50",
|
"column_break_50",
|
||||||
"shipping_rule",
|
"shipping_rule",
|
||||||
|
"incoterm",
|
||||||
"section_break_52",
|
"section_break_52",
|
||||||
"taxes",
|
"taxes",
|
||||||
"totals",
|
"totals",
|
||||||
@ -1249,13 +1250,19 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "column_break_103",
|
"fieldname": "column_break_103",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "incoterm",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Incoterm",
|
||||||
|
"options": "Incoterm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 105,
|
"idx": 105,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-11-17 12:34:36.033363",
|
"modified": "2022-11-17 17:28:07.729943",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order",
|
"name": "Purchase Order",
|
||||||
|
@ -44,7 +44,6 @@
|
|||||||
"discount_amount",
|
"discount_amount",
|
||||||
"base_rate_with_margin",
|
"base_rate_with_margin",
|
||||||
"sec_break2",
|
"sec_break2",
|
||||||
"apply_tds",
|
|
||||||
"rate",
|
"rate",
|
||||||
"amount",
|
"amount",
|
||||||
"item_tax_template",
|
"item_tax_template",
|
||||||
@ -54,6 +53,7 @@
|
|||||||
"pricing_rules",
|
"pricing_rules",
|
||||||
"stock_uom_rate",
|
"stock_uom_rate",
|
||||||
"is_free_item",
|
"is_free_item",
|
||||||
|
"apply_tds",
|
||||||
"section_break_29",
|
"section_break_29",
|
||||||
"net_rate",
|
"net_rate",
|
||||||
"net_amount",
|
"net_amount",
|
||||||
@ -902,7 +902,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-10-26 16:47:41.364387",
|
"modified": "2022-11-29 16:47:41.364387",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order Item",
|
"name": "Purchase Order Item",
|
||||||
|
@ -22,6 +22,13 @@ frappe.ui.form.on("Request for Quotation",{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frm.set_query('warehouse', 'items', () => ({
|
||||||
|
filters: {
|
||||||
|
company: frm.doc.company,
|
||||||
|
is_group: 0
|
||||||
|
}
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"sec_break_email_2",
|
"sec_break_email_2",
|
||||||
"message_for_supplier",
|
"message_for_supplier",
|
||||||
"terms_section_break",
|
"terms_section_break",
|
||||||
|
"incoterm",
|
||||||
"tc_name",
|
"tc_name",
|
||||||
"terms",
|
"terms",
|
||||||
"printing_settings",
|
"printing_settings",
|
||||||
@ -271,13 +272,19 @@
|
|||||||
"fieldname": "schedule_date",
|
"fieldname": "schedule_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Required Date"
|
"label": "Required Date"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "incoterm",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Incoterm",
|
||||||
|
"options": "Incoterm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-shopping-cart",
|
"icon": "fa fa-shopping-cart",
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-04-06 17:47:49.909000",
|
"modified": "2022-11-17 17:26:33.770993",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Request for Quotation",
|
"name": "Request for Quotation",
|
||||||
@ -345,5 +352,6 @@
|
|||||||
"search_fields": "status, transaction_date",
|
"search_fields": "status, transaction_date",
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC"
|
"sort_order": "DESC",
|
||||||
|
"states": []
|
||||||
}
|
}
|
@ -45,6 +45,7 @@
|
|||||||
"tax_category",
|
"tax_category",
|
||||||
"column_break_36",
|
"column_break_36",
|
||||||
"shipping_rule",
|
"shipping_rule",
|
||||||
|
"incoterm",
|
||||||
"section_break_38",
|
"section_break_38",
|
||||||
"taxes",
|
"taxes",
|
||||||
"totals",
|
"totals",
|
||||||
@ -823,6 +824,12 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "column_break_85",
|
"fieldname": "column_break_85",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "incoterm",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Incoterm",
|
||||||
|
"options": "Incoterm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-shopping-cart",
|
"icon": "fa fa-shopping-cart",
|
||||||
@ -830,7 +837,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-09-27 18:20:09.462037",
|
"modified": "2022-11-17 17:27:32.179686",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Supplier Quotation",
|
"name": "Supplier Quotation",
|
||||||
|
@ -239,6 +239,14 @@ class AccountsController(TransactionBase):
|
|||||||
else:
|
else:
|
||||||
item.set(field_map.get(self.doctype), default_deferred_account)
|
item.set(field_map.get(self.doctype), default_deferred_account)
|
||||||
|
|
||||||
|
def validate_auto_repeat_subscription_dates(self):
|
||||||
|
if (
|
||||||
|
self.get("from_date")
|
||||||
|
and self.get("to_date")
|
||||||
|
and getdate(self.from_date) > getdate(self.to_date)
|
||||||
|
):
|
||||||
|
frappe.throw(_("To Date cannot be before From Date"), title=_("Invalid Auto Repeat Date"))
|
||||||
|
|
||||||
def validate_deferred_start_and_end_date(self):
|
def validate_deferred_start_and_end_date(self):
|
||||||
for d in self.items:
|
for d in self.items:
|
||||||
if d.get("enable_deferred_revenue") or d.get("enable_deferred_expense"):
|
if d.get("enable_deferred_revenue") or d.get("enable_deferred_expense"):
|
||||||
|
@ -41,6 +41,7 @@ class BuyingController(SubcontractingController):
|
|||||||
self.validate_from_warehouse()
|
self.validate_from_warehouse()
|
||||||
self.set_supplier_address()
|
self.set_supplier_address()
|
||||||
self.validate_asset_return()
|
self.validate_asset_return()
|
||||||
|
self.validate_auto_repeat_subscription_dates()
|
||||||
|
|
||||||
if self.doctype == "Purchase Invoice":
|
if self.doctype == "Purchase Invoice":
|
||||||
self.validate_purchase_receipt_if_update_stock()
|
self.validate_purchase_receipt_if_update_stock()
|
||||||
|
@ -40,6 +40,7 @@ class SellingController(StockController):
|
|||||||
self.set_customer_address()
|
self.set_customer_address()
|
||||||
self.validate_for_duplicate_items()
|
self.validate_for_duplicate_items()
|
||||||
self.validate_target_warehouse()
|
self.validate_target_warehouse()
|
||||||
|
self.validate_auto_repeat_subscription_dates()
|
||||||
|
|
||||||
def set_missing_values(self, for_validate=False):
|
def set_missing_values(self, for_validate=False):
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ def link_open_tasks(ref_doctype, ref_docname, doc):
|
|||||||
todo_doc = frappe.get_doc("ToDo", todo.name)
|
todo_doc = frappe.get_doc("ToDo", todo.name)
|
||||||
todo_doc.reference_type = doc.doctype
|
todo_doc.reference_type = doc.doctype
|
||||||
todo_doc.reference_name = doc.name
|
todo_doc.reference_name = doc.name
|
||||||
todo_doc.db_update()
|
todo_doc.save()
|
||||||
|
|
||||||
|
|
||||||
def link_open_events(ref_doctype, ref_docname, doc):
|
def link_open_events(ref_doctype, ref_docname, doc):
|
||||||
|
@ -191,7 +191,9 @@ def get_total_pledged_security_value(loan):
|
|||||||
|
|
||||||
for security, qty in pledged_securities.items():
|
for security, qty in pledged_securities.items():
|
||||||
after_haircut_percentage = 100 - hair_cut_map.get(security)
|
after_haircut_percentage = 100 - hair_cut_map.get(security)
|
||||||
security_value += (loan_security_price_map.get(security) * qty * after_haircut_percentage) / 100
|
security_value += (
|
||||||
|
loan_security_price_map.get(security, 0) * qty * after_haircut_percentage
|
||||||
|
) / 100
|
||||||
|
|
||||||
return security_value
|
return security_value
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Warehouse",
|
"label": "For Warehouse",
|
||||||
"options": "Warehouse",
|
"options": "Warehouse",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
@ -173,7 +173,7 @@
|
|||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-08-23 18:17:58.400462",
|
"modified": "2022-11-26 14:59:25.879631",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Material Request Plan Item",
|
"name": "Material Request Plan Item",
|
||||||
@ -182,5 +182,6 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
frappe.ui.form.on('Production Plan', {
|
frappe.ui.form.on('Production Plan', {
|
||||||
|
|
||||||
before_save: function(frm) {
|
before_save(frm) {
|
||||||
// preserve temporary names on production plan item to re-link sub-assembly items
|
// preserve temporary names on production plan item to re-link sub-assembly items
|
||||||
frm.doc.po_items.forEach(item => {
|
frm.doc.po_items.forEach(item => {
|
||||||
item.temporary_name = item.name;
|
item.temporary_name = item.name;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setup: function(frm) {
|
setup(frm) {
|
||||||
frm.custom_make_buttons = {
|
frm.custom_make_buttons = {
|
||||||
'Work Order': 'Work Order / Subcontract PO',
|
'Work Order': 'Work Order / Subcontract PO',
|
||||||
'Material Request': 'Material Request',
|
'Material Request': 'Material Request',
|
||||||
@ -70,7 +70,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh(frm) {
|
||||||
if (frm.doc.docstatus === 1) {
|
if (frm.doc.docstatus === 1) {
|
||||||
frm.trigger("show_progress");
|
frm.trigger("show_progress");
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
set_field_options("projected_qty_formula", projected_qty_formula);
|
set_field_options("projected_qty_formula", projected_qty_formula);
|
||||||
},
|
},
|
||||||
|
|
||||||
close_open_production_plan: (frm, close=false) => {
|
close_open_production_plan(frm, close=false) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "set_status",
|
method: "set_status",
|
||||||
freeze: true,
|
freeze: true,
|
||||||
@ -170,7 +170,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
make_work_order: function(frm) {
|
make_work_order(frm) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "make_work_order",
|
method: "make_work_order",
|
||||||
freeze: true,
|
freeze: true,
|
||||||
@ -181,7 +181,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
make_material_request: function(frm) {
|
make_material_request(frm) {
|
||||||
|
|
||||||
frappe.confirm(__("Do you want to submit the material request"),
|
frappe.confirm(__("Do you want to submit the material request"),
|
||||||
function() {
|
function() {
|
||||||
@ -193,7 +193,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
create_material_request: function(frm, submit) {
|
create_material_request(frm, submit) {
|
||||||
frm.doc.submit_material_request = submit;
|
frm.doc.submit_material_request = submit;
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
@ -206,7 +206,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
get_sales_orders: function(frm) {
|
get_sales_orders(frm) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "get_open_sales_orders",
|
method: "get_open_sales_orders",
|
||||||
doc: frm.doc,
|
doc: frm.doc,
|
||||||
@ -216,7 +216,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
get_material_request: function(frm) {
|
get_material_request(frm) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "get_pending_material_requests",
|
method: "get_pending_material_requests",
|
||||||
doc: frm.doc,
|
doc: frm.doc,
|
||||||
@ -226,7 +226,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
get_items: function (frm) {
|
get_items(frm) {
|
||||||
frm.clear_table('prod_plan_references');
|
frm.clear_table('prod_plan_references');
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
@ -238,7 +238,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
combine_items: function (frm) {
|
combine_items(frm) {
|
||||||
frm.clear_table("prod_plan_references");
|
frm.clear_table("prod_plan_references");
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
@ -254,14 +254,14 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
combine_sub_items: (frm) => {
|
combine_sub_items(frm) {
|
||||||
if (frm.doc.sub_assembly_items.length > 0) {
|
if (frm.doc.sub_assembly_items.length > 0) {
|
||||||
frm.clear_table("sub_assembly_items");
|
frm.clear_table("sub_assembly_items");
|
||||||
frm.trigger("get_sub_assembly_items");
|
frm.trigger("get_sub_assembly_items");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
get_sub_assembly_items: function(frm) {
|
get_sub_assembly_items(frm) {
|
||||||
frm.dirty();
|
frm.dirty();
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
@ -274,9 +274,25 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
get_items_for_mr: function(frm) {
|
toggle_for_warehouse(frm) {
|
||||||
|
frm.toggle_reqd("for_warehouse", true);
|
||||||
|
},
|
||||||
|
|
||||||
|
get_items_for_mr(frm) {
|
||||||
if (!frm.doc.for_warehouse) {
|
if (!frm.doc.for_warehouse) {
|
||||||
frappe.throw(__("To make material requests, 'Make Material Request for Warehouse' field is mandatory"));
|
frm.trigger("toggle_for_warehouse");
|
||||||
|
frappe.throw(__("Select the Warehouse"));
|
||||||
|
}
|
||||||
|
|
||||||
|
frm.events.get_items_for_material_requests(frm, [{
|
||||||
|
warehouse: frm.doc.for_warehouse
|
||||||
|
}]);
|
||||||
|
},
|
||||||
|
|
||||||
|
transfer_materials(frm) {
|
||||||
|
if (!frm.doc.for_warehouse) {
|
||||||
|
frm.trigger("toggle_for_warehouse");
|
||||||
|
frappe.throw(__("Select the Warehouse"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.ignore_existing_ordered_qty) {
|
if (frm.doc.ignore_existing_ordered_qty) {
|
||||||
@ -287,18 +303,10 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
title: title,
|
title: title,
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
'label': __('Target Warehouse'),
|
'label': __('Transfer From Warehouses'),
|
||||||
'fieldtype': 'Link',
|
|
||||||
'fieldname': 'target_warehouse',
|
|
||||||
'read_only': true,
|
|
||||||
'default': frm.doc.for_warehouse
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'label': __('Source Warehouses (Optional)'),
|
|
||||||
'fieldtype': 'Table MultiSelect',
|
'fieldtype': 'Table MultiSelect',
|
||||||
'fieldname': 'warehouses',
|
'fieldname': 'warehouses',
|
||||||
'options': 'Production Plan Material Request Warehouse',
|
'options': 'Production Plan Material Request Warehouse',
|
||||||
'description': __('If source warehouse selected then system will create the material request with type Material Transfer from Source to Target warehouse. If not selected then will create the material request with type Purchase for the target warehouse.'),
|
|
||||||
get_query: function () {
|
get_query: function () {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
@ -307,6 +315,13 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'label': __('For Warehouse'),
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'fieldname': 'target_warehouse',
|
||||||
|
'read_only': true,
|
||||||
|
'default': frm.doc.for_warehouse
|
||||||
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -320,8 +335,8 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
get_items_for_material_requests: function(frm, warehouses) {
|
get_items_for_material_requests(frm, warehouses) {
|
||||||
const set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom', 'from_warehouse',
|
let set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom', 'from_warehouse',
|
||||||
'min_order_qty', 'required_bom_qty', 'quantity', 'sales_order', 'warehouse', 'projected_qty', 'ordered_qty',
|
'min_order_qty', 'required_bom_qty', 'quantity', 'sales_order', 'warehouse', 'projected_qty', 'ordered_qty',
|
||||||
'reserved_qty_for_production', 'material_request_type'];
|
'reserved_qty_for_production', 'material_request_type'];
|
||||||
|
|
||||||
@ -335,27 +350,21 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(r.message) {
|
if(r.message) {
|
||||||
frm.set_value('mr_items', []);
|
frm.set_value('mr_items', []);
|
||||||
$.each(r.message, function(i, d) {
|
r.message.forEach(row => {
|
||||||
var item = frm.add_child('mr_items');
|
let d = frm.add_child('mr_items');
|
||||||
for (let key in d) {
|
set_fields.forEach(field => {
|
||||||
if (d[key] && in_list(set_fields, key)) {
|
if (row[field]) {
|
||||||
item[key] = d[key];
|
d[field] = row[field];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
refresh_field('mr_items');
|
refresh_field('mr_items');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
for_warehouse: function(frm) {
|
download_materials_required(frm) {
|
||||||
if (frm.doc.mr_items && frm.doc.for_warehouse) {
|
|
||||||
frm.trigger("get_items_for_mr");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
download_materials_required: function(frm) {
|
|
||||||
const fields = [{
|
const fields = [{
|
||||||
fieldname: 'warehouses',
|
fieldname: 'warehouses',
|
||||||
fieldtype: 'Table MultiSelect',
|
fieldtype: 'Table MultiSelect',
|
||||||
@ -381,7 +390,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
}, __('Select Warehouses to get Stock for Materials Planning'), __('Get Stock'));
|
}, __('Select Warehouses to get Stock for Materials Planning'), __('Get Stock'));
|
||||||
},
|
},
|
||||||
|
|
||||||
show_progress: function(frm) {
|
show_progress(frm) {
|
||||||
var bars = [];
|
var bars = [];
|
||||||
var message = '';
|
var message = '';
|
||||||
var title = '';
|
var title = '';
|
||||||
@ -416,7 +425,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on("Production Plan Item", {
|
frappe.ui.form.on("Production Plan Item", {
|
||||||
item_code: function(frm, cdt, cdn) {
|
item_code(frm, cdt, cdn) {
|
||||||
const row = locals[cdt][cdn];
|
const row = locals[cdt][cdn];
|
||||||
if (row.item_code) {
|
if (row.item_code) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
@ -435,7 +444,7 @@ frappe.ui.form.on("Production Plan Item", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on("Material Request Plan Item", {
|
frappe.ui.form.on("Material Request Plan Item", {
|
||||||
warehouse: function(frm, cdt, cdn) {
|
warehouse(frm, cdt, cdn) {
|
||||||
const row = locals[cdt][cdn];
|
const row = locals[cdt][cdn];
|
||||||
if (row.warehouse && row.item_code && frm.doc.company) {
|
if (row.warehouse && row.item_code && frm.doc.company) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
"get_sub_assembly_items",
|
"get_sub_assembly_items",
|
||||||
"combine_sub_items",
|
"combine_sub_items",
|
||||||
"sub_assembly_items",
|
"sub_assembly_items",
|
||||||
|
"download_materials_request_plan_section_section",
|
||||||
|
"download_materials_required",
|
||||||
"material_request_planning",
|
"material_request_planning",
|
||||||
"include_non_stock_items",
|
"include_non_stock_items",
|
||||||
"include_subcontracted_items",
|
"include_subcontracted_items",
|
||||||
@ -45,8 +47,8 @@
|
|||||||
"ignore_existing_ordered_qty",
|
"ignore_existing_ordered_qty",
|
||||||
"column_break_25",
|
"column_break_25",
|
||||||
"for_warehouse",
|
"for_warehouse",
|
||||||
"download_materials_required",
|
|
||||||
"get_items_for_mr",
|
"get_items_for_mr",
|
||||||
|
"transfer_materials",
|
||||||
"section_break_27",
|
"section_break_27",
|
||||||
"mr_items",
|
"mr_items",
|
||||||
"other_details",
|
"other_details",
|
||||||
@ -206,7 +208,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "material_request_planning",
|
"fieldname": "material_request_planning",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Material Requirement Planning"
|
"label": "Material Request Planning"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
@ -235,12 +237,12 @@
|
|||||||
"depends_on": "eval:!doc.__islocal",
|
"depends_on": "eval:!doc.__islocal",
|
||||||
"fieldname": "download_materials_required",
|
"fieldname": "download_materials_required",
|
||||||
"fieldtype": "Button",
|
"fieldtype": "Button",
|
||||||
"label": "Download Required Materials"
|
"label": "Download Materials Request Plan"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "get_items_for_mr",
|
"fieldname": "get_items_for_mr",
|
||||||
"fieldtype": "Button",
|
"fieldtype": "Button",
|
||||||
"label": "Get Raw Materials For Production"
|
"label": "Get Raw Materials for Purchase"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_27",
|
"fieldname": "section_break_27",
|
||||||
@ -304,7 +306,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "for_warehouse",
|
"fieldname": "for_warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Make Material Request for Warehouse",
|
"label": "Raw Materials Warehouse",
|
||||||
"options": "Warehouse"
|
"options": "Warehouse"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -378,13 +380,24 @@
|
|||||||
"fieldname": "combine_sub_items",
|
"fieldname": "combine_sub_items",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Consolidate Sub Assembly Items"
|
"label": "Consolidate Sub Assembly Items"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "transfer_materials",
|
||||||
|
"fieldtype": "Button",
|
||||||
|
"label": "Get Raw Materials for Transfer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"fieldname": "download_materials_request_plan_section_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Download Materials Request Plan Section"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-calendar",
|
"icon": "fa fa-calendar",
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-03-25 09:15:25.017664",
|
"modified": "2022-11-26 14:51:08.774372",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Production Plan",
|
"name": "Production Plan",
|
||||||
|
@ -312,6 +312,9 @@ class ProductionPlan(Document):
|
|||||||
def add_items(self, items):
|
def add_items(self, items):
|
||||||
refs = {}
|
refs = {}
|
||||||
for data in items:
|
for data in items:
|
||||||
|
if not data.pending_qty:
|
||||||
|
continue
|
||||||
|
|
||||||
item_details = get_item_details(data.item_code)
|
item_details = get_item_details(data.item_code)
|
||||||
if self.combine_items:
|
if self.combine_items:
|
||||||
if item_details.bom_no in refs:
|
if item_details.bom_no in refs:
|
||||||
@ -518,6 +521,9 @@ class ProductionPlan(Document):
|
|||||||
subcontracted_po.setdefault(row.supplier, []).append(row)
|
subcontracted_po.setdefault(row.supplier, []).append(row)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if row.type_of_manufacturing == "Material Request":
|
||||||
|
continue
|
||||||
|
|
||||||
work_order_data = {
|
work_order_data = {
|
||||||
"wip_warehouse": default_warehouses.get("wip_warehouse"),
|
"wip_warehouse": default_warehouses.get("wip_warehouse"),
|
||||||
"fg_warehouse": default_warehouses.get("fg_warehouse"),
|
"fg_warehouse": default_warehouses.get("fg_warehouse"),
|
||||||
@ -1158,6 +1164,7 @@ def get_bin_details(row, company, for_warehouse=None, all_warehouse=False):
|
|||||||
|
|
||||||
subquery = frappe.qb.from_(wh).select(wh.name).where(wh.company == company)
|
subquery = frappe.qb.from_(wh).select(wh.name).where(wh.company == company)
|
||||||
|
|
||||||
|
warehouse = ""
|
||||||
if not all_warehouse:
|
if not all_warehouse:
|
||||||
warehouse = for_warehouse or row.get("source_warehouse") or row.get("default_warehouse")
|
warehouse = for_warehouse or row.get("source_warehouse") or row.get("default_warehouse")
|
||||||
|
|
||||||
@ -1223,6 +1230,21 @@ def get_items_for_material_requests(doc, warehouses=None, get_parent_warehouse_d
|
|||||||
doc["mr_items"] = []
|
doc["mr_items"] = []
|
||||||
|
|
||||||
po_items = doc.get("po_items") if doc.get("po_items") else doc.get("items")
|
po_items = doc.get("po_items") if doc.get("po_items") else doc.get("items")
|
||||||
|
|
||||||
|
if doc.get("sub_assembly_items"):
|
||||||
|
for sa_row in doc.sub_assembly_items:
|
||||||
|
sa_row = frappe._dict(sa_row)
|
||||||
|
if sa_row.type_of_manufacturing == "Material Request":
|
||||||
|
po_items.append(
|
||||||
|
frappe._dict(
|
||||||
|
{
|
||||||
|
"item_code": sa_row.production_item,
|
||||||
|
"required_qty": sa_row.qty,
|
||||||
|
"include_exploded_items": 0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Check for empty table or empty rows
|
# Check for empty table or empty rows
|
||||||
if not po_items or not [row.get("item_code") for row in po_items if row.get("item_code")]:
|
if not po_items or not [row.get("item_code") for row in po_items if row.get("item_code")]:
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
|
@ -840,6 +840,34 @@ class TestProductionPlan(FrappeTestCase):
|
|||||||
self.assertEqual(row.uom, "Nos")
|
self.assertEqual(row.uom, "Nos")
|
||||||
self.assertEqual(row.qty, 1)
|
self.assertEqual(row.qty, 1)
|
||||||
|
|
||||||
|
def test_material_request_for_sub_assembly_items(self):
|
||||||
|
from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
|
||||||
|
|
||||||
|
bom_tree = {
|
||||||
|
"Fininshed Goods1 For MR": {
|
||||||
|
"SubAssembly1 For MR": {"SubAssembly1-1 For MR": {"ChildPart1 For MR": {}}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_bom = create_nested_bom(bom_tree, prefix="")
|
||||||
|
plan = create_production_plan(
|
||||||
|
item_code=parent_bom.item, planned_qty=10, ignore_existing_ordered_qty=1, do_not_submit=1
|
||||||
|
)
|
||||||
|
|
||||||
|
plan.get_sub_assembly_items()
|
||||||
|
|
||||||
|
mr_items = []
|
||||||
|
for row in plan.sub_assembly_items:
|
||||||
|
mr_items.append(row.production_item)
|
||||||
|
row.type_of_manufacturing = "Material Request"
|
||||||
|
|
||||||
|
plan.save()
|
||||||
|
items = get_items_for_material_requests(plan.as_dict())
|
||||||
|
|
||||||
|
validate_mr_items = [d.get("item_code") for d in items]
|
||||||
|
for item_code in mr_items:
|
||||||
|
self.assertTrue(item_code in validate_mr_items)
|
||||||
|
|
||||||
|
|
||||||
def create_production_plan(**args):
|
def create_production_plan(**args):
|
||||||
"""
|
"""
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
"fieldname": "warehouse",
|
"fieldname": "warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "For Warehouse",
|
"label": "FG Warehouse",
|
||||||
"options": "Warehouse"
|
"options": "Warehouse"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -216,7 +216,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-03-24 04:54:09.940224",
|
"modified": "2022-11-25 14:15:40.061514",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Production Plan Item",
|
"name": "Production Plan Item",
|
||||||
|
@ -169,7 +169,7 @@
|
|||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Manufacturing Type",
|
"label": "Manufacturing Type",
|
||||||
"options": "In House\nSubcontract"
|
"options": "In House\nSubcontract\nMaterial Request"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "supplier",
|
"fieldname": "supplier",
|
||||||
@ -188,7 +188,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-01-30 21:31:10.527559",
|
"modified": "2022-11-28 13:50:15.116082",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Production Plan Sub Assembly Item",
|
"name": "Production Plan Sub Assembly Item",
|
||||||
|
@ -54,11 +54,11 @@ frappe.query_reports["Job Card Summary"] = {
|
|||||||
options: ["", "Open", "Work In Progress", "Completed", "On Hold"]
|
options: ["", "Open", "Work In Progress", "Completed", "On Hold"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: __("Sales Orders"),
|
label: __("Work Orders"),
|
||||||
fieldname: "sales_order",
|
fieldname: "work_order",
|
||||||
fieldtype: "MultiSelectList",
|
fieldtype: "MultiSelectList",
|
||||||
get_data: function(txt) {
|
get_data: function(txt) {
|
||||||
return frappe.db.get_link_options('Sales Order', txt);
|
return frappe.db.get_link_options('Work Order', txt);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -36,10 +36,14 @@ def get_data(filters):
|
|||||||
"total_time_in_mins",
|
"total_time_in_mins",
|
||||||
]
|
]
|
||||||
|
|
||||||
for field in ["work_order", "workstation", "operation", "status", "company"]:
|
for field in ["work_order", "production_item"]:
|
||||||
if filters.get(field):
|
if filters.get(field):
|
||||||
query_filters[field] = ("in", filters.get(field))
|
query_filters[field] = ("in", filters.get(field))
|
||||||
|
|
||||||
|
for field in ["workstation", "operation", "status", "company"]:
|
||||||
|
if filters.get(field):
|
||||||
|
query_filters[field] = filters.get(field)
|
||||||
|
|
||||||
data = frappe.get_all("Job Card", fields=fields, filters=query_filters)
|
data = frappe.get_all("Job Card", fields=fields, filters=query_filters)
|
||||||
|
|
||||||
if not data:
|
if not data:
|
||||||
|
@ -39,10 +39,14 @@ def get_data(filters):
|
|||||||
"lead_time",
|
"lead_time",
|
||||||
]
|
]
|
||||||
|
|
||||||
for field in ["sales_order", "production_item", "status", "company"]:
|
for field in ["sales_order", "production_item"]:
|
||||||
if filters.get(field):
|
if filters.get(field):
|
||||||
query_filters[field] = ("in", filters.get(field))
|
query_filters[field] = ("in", filters.get(field))
|
||||||
|
|
||||||
|
for field in ["status", "company"]:
|
||||||
|
if filters.get(field):
|
||||||
|
query_filters[field] = filters.get(field)
|
||||||
|
|
||||||
query_filters["planned_start_date"] = (">=", filters.get("from_date"))
|
query_filters["planned_start_date"] = (">=", filters.get("from_date"))
|
||||||
query_filters["planned_end_date"] = ("<=", filters.get("to_date"))
|
query_filters["planned_end_date"] = ("<=", filters.get("to_date"))
|
||||||
|
|
||||||
|
@ -317,3 +317,4 @@ erpnext.patches.v14_0.migrate_remarks_from_gl_to_payment_ledger
|
|||||||
erpnext.patches.v13_0.update_schedule_type_in_loans
|
erpnext.patches.v13_0.update_schedule_type_in_loans
|
||||||
erpnext.patches.v14_0.create_accounting_dimensions_for_asset_capitalization
|
erpnext.patches.v14_0.create_accounting_dimensions_for_asset_capitalization
|
||||||
erpnext.patches.v14_0.update_partial_tds_fields
|
erpnext.patches.v14_0.update_partial_tds_fields
|
||||||
|
erpnext.patches.v14_0.create_incoterms_and_migrate_shipment
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
from erpnext.setup.doctype.incoterm.incoterm import create_incoterms
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
create_incoterms()
|
||||||
|
migrate_shipments()
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_shipments():
|
||||||
|
if not frappe.db.count("Shipment"):
|
||||||
|
return
|
||||||
|
|
||||||
|
OLD_VALUES = [
|
||||||
|
"EXW (Ex Works)",
|
||||||
|
"FCA (Free Carrier)",
|
||||||
|
"FOB (Free On Board)",
|
||||||
|
"FAS (Free Alongside Ship)",
|
||||||
|
"CPT (Carriage Paid To)",
|
||||||
|
"CIP (Carriage and Insurance Paid to)",
|
||||||
|
"CFR (Cost and Freight)",
|
||||||
|
"DPU (Delivered At Place Unloaded)",
|
||||||
|
"DAP (Delivered At Place)",
|
||||||
|
"DDP (Delivered Duty Paid)",
|
||||||
|
]
|
||||||
|
shipment = frappe.qb.DocType("Shipment")
|
||||||
|
for old_value in OLD_VALUES:
|
||||||
|
frappe.qb.update(shipment).set(shipment.incoterm, old_value[:3]).where(
|
||||||
|
shipment.incoterm == old_value
|
||||||
|
).run()
|
@ -48,6 +48,7 @@
|
|||||||
"tax_category",
|
"tax_category",
|
||||||
"column_break_34",
|
"column_break_34",
|
||||||
"shipping_rule",
|
"shipping_rule",
|
||||||
|
"incoterm",
|
||||||
"section_break_36",
|
"section_break_36",
|
||||||
"taxes",
|
"taxes",
|
||||||
"section_break_39",
|
"section_break_39",
|
||||||
@ -1052,13 +1053,19 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "column_break_108",
|
"fieldname": "column_break_108",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "incoterm",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Incoterm",
|
||||||
|
"options": "Incoterm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-shopping-cart",
|
"icon": "fa fa-shopping-cart",
|
||||||
"idx": 82,
|
"idx": 82,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-10-11 13:06:33.479650",
|
"modified": "2022-11-17 17:20:54.984348",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Quotation",
|
"name": "Quotation",
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
"tax_category",
|
"tax_category",
|
||||||
"column_break_49",
|
"column_break_49",
|
||||||
"shipping_rule",
|
"shipping_rule",
|
||||||
|
"incoterm",
|
||||||
"section_break_40",
|
"section_break_40",
|
||||||
"taxes",
|
"taxes",
|
||||||
"section_break_43",
|
"section_break_43",
|
||||||
@ -1623,13 +1624,19 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "column_break_152",
|
"fieldname": "column_break_152",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "incoterm",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Incoterm",
|
||||||
|
"options": "Incoterm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 105,
|
"idx": 105,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-10-11 13:06:10.469796",
|
"modified": "2022-11-17 17:22:00.413878",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Sales Order",
|
"name": "Sales Order",
|
||||||
|
0
erpnext/setup/doctype/incoterm/__init__.py
Normal file
0
erpnext/setup/doctype/incoterm/__init__.py
Normal file
8
erpnext/setup/doctype/incoterm/incoterm.js
Normal file
8
erpnext/setup/doctype/incoterm/incoterm.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
// frappe.ui.form.on("Incoterm", {
|
||||||
|
// refresh(frm) {
|
||||||
|
|
||||||
|
// },
|
||||||
|
// });
|
168
erpnext/setup/doctype/incoterm/incoterm.json
Normal file
168
erpnext/setup/doctype/incoterm/incoterm.json
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"autoname": "field:code",
|
||||||
|
"creation": "2022-11-17 15:17:34.717467",
|
||||||
|
"default_view": "List",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"code",
|
||||||
|
"title",
|
||||||
|
"description"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "code",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Code",
|
||||||
|
"length": 3,
|
||||||
|
"reqd": 1,
|
||||||
|
"unique": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "title",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Title",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "description",
|
||||||
|
"fieldtype": "Long Text",
|
||||||
|
"label": "Description"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"group": "Selling",
|
||||||
|
"link_doctype": "Quotation",
|
||||||
|
"link_fieldname": "incoterm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Selling",
|
||||||
|
"link_doctype": "Sales Order",
|
||||||
|
"link_fieldname": "incoterm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Buying",
|
||||||
|
"link_doctype": "Request for Quotation",
|
||||||
|
"link_fieldname": "incoterm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Buying",
|
||||||
|
"link_doctype": "Supplier Quotation",
|
||||||
|
"link_fieldname": "incoterm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Buying",
|
||||||
|
"link_doctype": "Purchase Order",
|
||||||
|
"link_fieldname": "incoterm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Stock",
|
||||||
|
"link_doctype": "Delivery Note",
|
||||||
|
"link_fieldname": "incoterm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Stock",
|
||||||
|
"link_doctype": "Purchase Receipt",
|
||||||
|
"link_fieldname": "incoterm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Stock",
|
||||||
|
"link_doctype": "Shipment",
|
||||||
|
"link_fieldname": "incoterm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Accounts",
|
||||||
|
"link_doctype": "Sales Invoice",
|
||||||
|
"link_fieldname": "incoterm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Accounts",
|
||||||
|
"link_doctype": "Purchase Invoice",
|
||||||
|
"link_fieldname": "incoterm"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"modified": "2022-11-17 22:35:52.084553",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Setup",
|
||||||
|
"name": "Incoterm",
|
||||||
|
"naming_rule": "By fieldname",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Sales Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Purchase Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Stock Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"read": 1,
|
||||||
|
"role": "Purchase User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"read": 1,
|
||||||
|
"role": "Sales User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"read": 1,
|
||||||
|
"role": "Accounts User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"read": 1,
|
||||||
|
"role": "Stock User"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"show_title_field_in_link": 1,
|
||||||
|
"sort_field": "name",
|
||||||
|
"sort_order": "ASC",
|
||||||
|
"states": [],
|
||||||
|
"title_field": "title",
|
||||||
|
"translated_doctype": 1
|
||||||
|
}
|
24
erpnext/setup/doctype/incoterm/incoterm.py
Normal file
24
erpnext/setup/doctype/incoterm/incoterm.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
|
||||||
|
class Incoterm(Document):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def create_incoterms():
|
||||||
|
"""Create Incoterm records from incoterms.csv."""
|
||||||
|
import os
|
||||||
|
from csv import DictReader
|
||||||
|
|
||||||
|
with open(os.path.join(os.path.dirname(__file__), "incoterms.csv"), "r") as f:
|
||||||
|
for incoterm in DictReader(f):
|
||||||
|
if frappe.db.exists("Incoterm", incoterm["code"]):
|
||||||
|
continue
|
||||||
|
|
||||||
|
doc = frappe.new_doc("Incoterm")
|
||||||
|
doc.update(incoterm)
|
||||||
|
doc.save()
|
12
erpnext/setup/doctype/incoterm/incoterms.csv
Normal file
12
erpnext/setup/doctype/incoterm/incoterms.csv
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
code,title
|
||||||
|
EXW,Ex Works
|
||||||
|
FCA,Free Carrier
|
||||||
|
FAS,Free Alongside Ship
|
||||||
|
FOB,Free On Board
|
||||||
|
CPT,Carriage Paid To
|
||||||
|
CIP,Carriage and Insurance Paid to
|
||||||
|
CFR,Cost and Freight
|
||||||
|
CIF,"Cost, Insurance and Freight"
|
||||||
|
DAP,Delivered At Place
|
||||||
|
DPU,Delivered At Place Unloaded
|
||||||
|
DDP,Delivered Duty Paid
|
|
9
erpnext/setup/doctype/incoterm/test_incoterm.py
Normal file
9
erpnext/setup/doctype/incoterm/test_incoterm.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestIncoterm(FrappeTestCase):
|
||||||
|
pass
|
@ -10,6 +10,7 @@ from frappe.utils import cint
|
|||||||
|
|
||||||
from erpnext.accounts.doctype.cash_flow_mapper.default_cash_flow_mapper import DEFAULT_MAPPERS
|
from erpnext.accounts.doctype.cash_flow_mapper.default_cash_flow_mapper import DEFAULT_MAPPERS
|
||||||
from erpnext.setup.default_energy_point_rules import get_default_energy_point_rules
|
from erpnext.setup.default_energy_point_rules import get_default_energy_point_rules
|
||||||
|
from erpnext.setup.doctype.incoterm.incoterm import create_incoterms
|
||||||
|
|
||||||
from .default_success_action import get_default_success_action
|
from .default_success_action import get_default_success_action
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ def after_install():
|
|||||||
create_default_cash_flow_mapper_templates()
|
create_default_cash_flow_mapper_templates()
|
||||||
create_default_success_action()
|
create_default_success_action()
|
||||||
create_default_energy_point_rules()
|
create_default_energy_point_rules()
|
||||||
|
create_incoterms()
|
||||||
add_company_to_session_defaults()
|
add_company_to_session_defaults()
|
||||||
add_standard_navbar_items()
|
add_standard_navbar_items()
|
||||||
add_app_name()
|
add_app_name()
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -62,6 +62,7 @@
|
|||||||
"tax_category",
|
"tax_category",
|
||||||
"column_break_39",
|
"column_break_39",
|
||||||
"shipping_rule",
|
"shipping_rule",
|
||||||
|
"incoterm",
|
||||||
"section_break_41",
|
"section_break_41",
|
||||||
"taxes",
|
"taxes",
|
||||||
"section_break_44",
|
"section_break_44",
|
||||||
@ -1381,13 +1382,19 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "column_break_18",
|
"fieldname": "column_break_18",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "incoterm",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Incoterm",
|
||||||
|
"options": "Incoterm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-truck",
|
"icon": "fa fa-truck",
|
||||||
"idx": 146,
|
"idx": 146,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-10-11 13:06:58.655635",
|
"modified": "2022-11-17 17:22:42.860790",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Delivery Note",
|
"name": "Delivery Note",
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
"tax_category",
|
"tax_category",
|
||||||
"column_break_53",
|
"column_break_53",
|
||||||
"shipping_rule",
|
"shipping_rule",
|
||||||
|
"incoterm",
|
||||||
"taxes_section",
|
"taxes_section",
|
||||||
"taxes",
|
"taxes",
|
||||||
"totals",
|
"totals",
|
||||||
@ -1218,13 +1219,19 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "column_break_104",
|
"fieldname": "column_break_104",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "incoterm",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Incoterm",
|
||||||
|
"options": "Incoterm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-truck",
|
"icon": "fa fa-truck",
|
||||||
"idx": 261,
|
"idx": 261,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-10-11 13:02:31.776256",
|
"modified": "2022-11-17 17:29:30.067536",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Purchase Receipt",
|
"name": "Purchase Receipt",
|
||||||
|
@ -34,6 +34,22 @@ frappe.ui.form.on('Repost Item Valuation', {
|
|||||||
frm.trigger('setup_realtime_progress');
|
frm.trigger('setup_realtime_progress');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
based_on: function(frm) {
|
||||||
|
var fields_to_reset = [];
|
||||||
|
|
||||||
|
if (frm.doc.based_on == 'Transaction') {
|
||||||
|
fields_to_reset = ['item_code', 'warehouse'];
|
||||||
|
} else if (frm.doc.based_on == 'Item and Warehouse') {
|
||||||
|
fields_to_reset = ['voucher_type', 'voucher_no'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields_to_reset) {
|
||||||
|
fields_to_reset.forEach(field => {
|
||||||
|
frm.set_value(field, undefined);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
setup_realtime_progress: function(frm) {
|
setup_realtime_progress: function(frm) {
|
||||||
frappe.realtime.on('item_reposting_progress', data => {
|
frappe.realtime.on('item_reposting_progress', data => {
|
||||||
if (frm.doc.name !== data.name) {
|
if (frm.doc.name !== data.name) {
|
||||||
|
@ -50,13 +50,15 @@
|
|||||||
"fieldname": "posting_date",
|
"fieldname": "posting_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Posting Date",
|
"label": "Posting Date",
|
||||||
|
"read_only_depends_on": "eval: doc.based_on == \"Transaction\"",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "voucher_no.posting_time",
|
"fetch_from": "voucher_no.posting_time",
|
||||||
"fieldname": "posting_time",
|
"fieldname": "posting_time",
|
||||||
"fieldtype": "Time",
|
"fieldtype": "Time",
|
||||||
"label": "Posting Time"
|
"label": "Posting Time",
|
||||||
|
"read_only_depends_on": "eval: doc.based_on == \"Transaction\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "Queued",
|
"default": "Queued",
|
||||||
@ -195,7 +197,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-06-13 12:20:22.182322",
|
"modified": "2022-11-28 16:00:05.637440",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Repost Item Valuation",
|
"name": "Repost Item Valuation",
|
||||||
|
@ -5,7 +5,7 @@ import frappe
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.exceptions import QueryDeadlockError, QueryTimeoutError
|
from frappe.exceptions import QueryDeadlockError, QueryTimeoutError
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import cint, get_link_to_form, get_weekday, now, nowtime
|
from frappe.utils import cint, get_link_to_form, get_weekday, getdate, now, nowtime
|
||||||
from frappe.utils.user import get_users_with_role
|
from frappe.utils.user import get_users_with_role
|
||||||
from rq.timeouts import JobTimeoutException
|
from rq.timeouts import JobTimeoutException
|
||||||
|
|
||||||
@ -25,6 +25,27 @@ class RepostItemValuation(Document):
|
|||||||
self.set_status(write=False)
|
self.set_status(write=False)
|
||||||
self.reset_field_values()
|
self.reset_field_values()
|
||||||
self.set_company()
|
self.set_company()
|
||||||
|
self.validate_accounts_freeze()
|
||||||
|
|
||||||
|
def validate_accounts_freeze(self):
|
||||||
|
acc_settings = frappe.db.get_value(
|
||||||
|
"Accounts Settings",
|
||||||
|
"Accounts Settings",
|
||||||
|
["acc_frozen_upto", "frozen_accounts_modifier"],
|
||||||
|
as_dict=1,
|
||||||
|
)
|
||||||
|
if not acc_settings.acc_frozen_upto:
|
||||||
|
return
|
||||||
|
if getdate(self.posting_date) <= getdate(acc_settings.acc_frozen_upto):
|
||||||
|
if (
|
||||||
|
acc_settings.frozen_accounts_modifier
|
||||||
|
and frappe.session.user in get_users_with_role(acc_settings.frozen_accounts_modifier)
|
||||||
|
):
|
||||||
|
frappe.msgprint(_("Caution: This might alter frozen accounts."))
|
||||||
|
return
|
||||||
|
frappe.throw(
|
||||||
|
_("You cannot repost item valuation before {}").format(acc_settings.acc_frozen_upto)
|
||||||
|
)
|
||||||
|
|
||||||
def reset_field_values(self):
|
def reset_field_values(self):
|
||||||
if self.based_on == "Transaction":
|
if self.based_on == "Transaction":
|
||||||
@ -240,7 +261,7 @@ def _get_directly_dependent_vouchers(doc):
|
|||||||
def notify_error_to_stock_managers(doc, traceback):
|
def notify_error_to_stock_managers(doc, traceback):
|
||||||
recipients = get_users_with_role("Stock Manager")
|
recipients = get_users_with_role("Stock Manager")
|
||||||
if not recipients:
|
if not recipients:
|
||||||
get_users_with_role("System Manager")
|
recipients = get_users_with_role("System Manager")
|
||||||
|
|
||||||
subject = _("Error while reposting item valuation")
|
subject = _("Error while reposting item valuation")
|
||||||
message = (
|
message = (
|
||||||
|
@ -327,3 +327,26 @@ class TestRepostItemValuation(FrappeTestCase, StockTestMixin):
|
|||||||
# outstanding should not be affected
|
# outstanding should not be affected
|
||||||
sinv.reload()
|
sinv.reload()
|
||||||
self.assertEqual(sinv.outstanding_amount, 100)
|
self.assertEqual(sinv.outstanding_amount, 100)
|
||||||
|
|
||||||
|
def test_account_freeze_validation(self):
|
||||||
|
today = nowdate()
|
||||||
|
|
||||||
|
riv = frappe.get_doc(
|
||||||
|
doctype="Repost Item Valuation",
|
||||||
|
item_code="_Test Item",
|
||||||
|
warehouse="_Test Warehouse - _TC",
|
||||||
|
based_on="Item and Warehouse",
|
||||||
|
posting_date=today,
|
||||||
|
posting_time="00:01:00",
|
||||||
|
)
|
||||||
|
riv.flags.dont_run_in_test = True # keep it queued
|
||||||
|
|
||||||
|
accounts_settings = frappe.get_doc("Accounts Settings")
|
||||||
|
accounts_settings.acc_frozen_upto = today
|
||||||
|
accounts_settings.frozen_accounts_modifier = ""
|
||||||
|
accounts_settings.save()
|
||||||
|
|
||||||
|
self.assertRaises(frappe.ValidationError, riv.save)
|
||||||
|
|
||||||
|
accounts_settings.acc_frozen_upto = ""
|
||||||
|
accounts_settings.save()
|
||||||
|
@ -412,9 +412,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "incoterm",
|
"fieldname": "incoterm",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Link",
|
||||||
"label": "Incoterm",
|
"label": "Incoterm",
|
||||||
"options": "EXW (Ex Works)\nFCA (Free Carrier)\nCPT (Carriage Paid To)\nCIP (Carriage and Insurance Paid to)\nDPU (Delivered At Place Unloaded)\nDAP (Delivered At Place)\nDDP (Delivered Duty Paid)"
|
"options": "Incoterm"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "shipment_delivery_note",
|
"fieldname": "shipment_delivery_note",
|
||||||
@ -433,10 +433,11 @@
|
|||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-04-13 17:14:18.181818",
|
"modified": "2022-11-17 17:23:27.025802",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Shipment",
|
"name": "Shipment",
|
||||||
|
"naming_rule": "Expression (old style)",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
@ -470,5 +471,6 @@
|
|||||||
],
|
],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
@ -1079,7 +1079,8 @@ erpnext.stock.select_batch_and_serial_no = (frm, item) => {
|
|||||||
if (frm.doc.purpose === 'Material Receipt') return;
|
if (frm.doc.purpose === 'Material Receipt') return;
|
||||||
|
|
||||||
frappe.require("assets/erpnext/js/utils/serial_no_batch_selector.js", function() {
|
frappe.require("assets/erpnext/js/utils/serial_no_batch_selector.js", function() {
|
||||||
new erpnext.SerialNoBatchSelector({
|
if (frm.batch_selector?.dialog?.display) return;
|
||||||
|
frm.batch_selector = new erpnext.SerialNoBatchSelector({
|
||||||
frm: frm,
|
frm: frm,
|
||||||
item: item,
|
item: item,
|
||||||
warehouse_details: get_warehouse_type_and_name(item),
|
warehouse_details: get_warehouse_type_and_name(item),
|
||||||
|
@ -230,7 +230,7 @@ class StockReconciliation(StockController):
|
|||||||
|
|
||||||
if item.has_serial_no or item.has_batch_no:
|
if item.has_serial_no or item.has_batch_no:
|
||||||
has_serial_no = True
|
has_serial_no = True
|
||||||
self.get_sle_for_serialized_items(row, sl_entries)
|
self.get_sle_for_serialized_items(row, sl_entries, item)
|
||||||
else:
|
else:
|
||||||
if row.serial_no or row.batch_no:
|
if row.serial_no or row.batch_no:
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
@ -282,7 +282,7 @@ class StockReconciliation(StockController):
|
|||||||
if has_serial_no and sl_entries:
|
if has_serial_no and sl_entries:
|
||||||
self.update_valuation_rate_for_serial_no()
|
self.update_valuation_rate_for_serial_no()
|
||||||
|
|
||||||
def get_sle_for_serialized_items(self, row, sl_entries):
|
def get_sle_for_serialized_items(self, row, sl_entries, item):
|
||||||
from erpnext.stock.stock_ledger import get_previous_sle
|
from erpnext.stock.stock_ledger import get_previous_sle
|
||||||
|
|
||||||
serial_nos = get_serial_nos(row.serial_no)
|
serial_nos = get_serial_nos(row.serial_no)
|
||||||
@ -348,6 +348,9 @@ class StockReconciliation(StockController):
|
|||||||
if row.qty:
|
if row.qty:
|
||||||
args = self.get_sle_for_items(row)
|
args = self.get_sle_for_items(row)
|
||||||
|
|
||||||
|
if item.has_serial_no and item.has_batch_no:
|
||||||
|
args["qty_after_transaction"] = row.qty
|
||||||
|
|
||||||
args.update(
|
args.update(
|
||||||
{
|
{
|
||||||
"actual_qty": row.qty,
|
"actual_qty": row.qty,
|
||||||
|
@ -644,6 +644,38 @@ class TestStockReconciliation(FrappeTestCase, StockTestMixin):
|
|||||||
)
|
)
|
||||||
self.assertEqual(len(active_sr_no), 0)
|
self.assertEqual(len(active_sr_no), 0)
|
||||||
|
|
||||||
|
def test_serial_no_batch_no_item(self):
|
||||||
|
item = self.make_item(
|
||||||
|
"Test Serial No Batch No Item",
|
||||||
|
{
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"has_serial_no": 1,
|
||||||
|
"has_batch_no": 1,
|
||||||
|
"serial_no_series": "SRS9.####",
|
||||||
|
"batch_number_series": "BNS9.####",
|
||||||
|
"create_new_batch": 1,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
warehouse = "_Test Warehouse - _TC"
|
||||||
|
|
||||||
|
sr = create_stock_reconciliation(
|
||||||
|
item_code=item.name,
|
||||||
|
warehouse=warehouse,
|
||||||
|
qty=1,
|
||||||
|
rate=100,
|
||||||
|
)
|
||||||
|
|
||||||
|
sl_entry = frappe.db.get_value(
|
||||||
|
"Stock Ledger Entry",
|
||||||
|
{"voucher_type": "Stock Reconciliation", "voucher_no": sr.name},
|
||||||
|
["actual_qty", "qty_after_transaction"],
|
||||||
|
as_dict=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(flt(sl_entry.actual_qty), 1.0)
|
||||||
|
self.assertEqual(flt(sl_entry.qty_after_transaction), 1.0)
|
||||||
|
|
||||||
|
|
||||||
def create_batch_item_with_batch(item_name, batch_id):
|
def create_batch_item_with_batch(item_name, batch_id):
|
||||||
batch_item_doc = create_item(item_name, is_stock_item=1)
|
batch_item_doc = create_item(item_name, is_stock_item=1)
|
||||||
|
@ -263,8 +263,8 @@ def repost_future_sle(
|
|||||||
|
|
||||||
def validate_item_warehouse(args):
|
def validate_item_warehouse(args):
|
||||||
for field in ["item_code", "warehouse", "posting_date", "posting_time"]:
|
for field in ["item_code", "warehouse", "posting_date", "posting_time"]:
|
||||||
if not args.get(field):
|
if args.get(field) in [None, ""]:
|
||||||
validation_msg = f"The field {frappe.unscrub(args.get(field))} is required for the reposting"
|
validation_msg = f"The field {frappe.unscrub(field)} is required for the reposting"
|
||||||
frappe.throw(_(validation_msg))
|
frappe.throw(_(validation_msg))
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
<div class="product-container mt-4 {{ padding_top }} {{ info_col }}">
|
<div class="product-container mt-4 {{ padding_top }} {{ info_col }}">
|
||||||
<div class="item-content {{ 'mt-minus-2' if (show_tabs and tabs) else '' }}">
|
<div class="item-content {{ 'mt-minus-2' if (show_tabs and tabs) else '' }}">
|
||||||
<div class="product-page-content" itemscope itemtype="http://schema.org/Product">
|
<div class="product-page-content">
|
||||||
<!-- Product Specifications Table Section -->
|
<!-- Product Specifications Table Section -->
|
||||||
{% if show_tabs and tabs %}
|
{% if show_tabs and tabs %}
|
||||||
<div class="category-tabs">
|
<div class="category-tabs">
|
||||||
|
@ -9903,3 +9903,14 @@ Total Asset,Aktiva,
|
|||||||
Total Liability,Verbindlichkeiten,
|
Total Liability,Verbindlichkeiten,
|
||||||
Total Equity,Eigenkapital,
|
Total Equity,Eigenkapital,
|
||||||
Warehouse wise Stock Value,Warenwert nach Lager,
|
Warehouse wise Stock Value,Warenwert nach Lager,
|
||||||
|
Ex Works,Ab Werk,
|
||||||
|
Free Carrier,Frei Frachtführer,
|
||||||
|
Free Alongside Ship,Frei Längsseite Schiff,
|
||||||
|
Free on Board,Frei an Bord,
|
||||||
|
Carriage Paid To,Frachtfrei,
|
||||||
|
Carriage and Insurance Paid to,Frachtfrei versichert,
|
||||||
|
Cost and Freight,Kosten und Fracht,
|
||||||
|
"Cost, Insurance and Freight","Kosten, Versicherung und Fracht",
|
||||||
|
Delivered at Place,Geliefert benannter Ort,
|
||||||
|
Delivered at Place Unloaded,Geliefert benannter Ort entladen,
|
||||||
|
Delivered Duty Paid,Geliefert verzollt,
|
||||||
|
Can't render this file because it is too large.
|
Loading…
x
Reference in New Issue
Block a user