Merge branch 'develop' into lcv_multicurrency
This commit is contained in:
commit
7aa16bafff
@ -21,6 +21,7 @@
|
|||||||
"book_asset_depreciation_entry_automatically",
|
"book_asset_depreciation_entry_automatically",
|
||||||
"add_taxes_from_item_tax_template",
|
"add_taxes_from_item_tax_template",
|
||||||
"automatically_fetch_payment_terms",
|
"automatically_fetch_payment_terms",
|
||||||
|
"delete_linked_ledger_entries",
|
||||||
"deferred_accounting_settings_section",
|
"deferred_accounting_settings_section",
|
||||||
"automatically_process_deferred_accounting_entry",
|
"automatically_process_deferred_accounting_entry",
|
||||||
"book_deferred_entries_based_on",
|
"book_deferred_entries_based_on",
|
||||||
@ -219,6 +220,12 @@
|
|||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Book Deferred Entries Based On",
|
"label": "Book Deferred Entries Based On",
|
||||||
"options": "Days\nMonths"
|
"options": "Days\nMonths"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "delete_linked_ledger_entries",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Delete Accounting and Stock Ledger Entries on deletion of Transaction"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "icon-cog",
|
"icon": "icon-cog",
|
||||||
@ -226,7 +233,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-10-13 11:32:52.268826",
|
"modified": "2021-01-05 13:04:00.118892",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
|
@ -275,8 +275,11 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
|||||||
|
|
||||||
supplier: function() {
|
supplier: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
if(this.frm.updating_party_details)
|
|
||||||
|
// Do not update if inter company reference is there as the details will already be updated
|
||||||
|
if(this.frm.updating_party_details || this.frm.doc.inter_company_invoice_reference)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
erpnext.utils.get_party_details(this.frm, "erpnext.accounts.party.get_party_details",
|
erpnext.utils.get_party_details(this.frm, "erpnext.accounts.party.get_party_details",
|
||||||
{
|
{
|
||||||
posting_date: this.frm.doc.posting_date,
|
posting_date: this.frm.doc.posting_date,
|
||||||
|
@ -57,8 +57,8 @@
|
|||||||
"set_warehouse",
|
"set_warehouse",
|
||||||
"rejected_warehouse",
|
"rejected_warehouse",
|
||||||
"col_break_warehouse",
|
"col_break_warehouse",
|
||||||
|
"set_from_warehouse",
|
||||||
"is_subcontracted",
|
"is_subcontracted",
|
||||||
"supplier_warehouse",
|
|
||||||
"items_section",
|
"items_section",
|
||||||
"update_stock",
|
"update_stock",
|
||||||
"scan_barcode",
|
"scan_barcode",
|
||||||
@ -515,6 +515,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "update_stock",
|
"depends_on": "update_stock",
|
||||||
|
"description": "Sets 'Accepted Warehouse' in each row of the items table.",
|
||||||
"fieldname": "set_warehouse",
|
"fieldname": "set_warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Set Accepted Warehouse",
|
"label": "Set Accepted Warehouse",
|
||||||
@ -543,17 +544,6 @@
|
|||||||
"options": "No\nYes",
|
"options": "No\nYes",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"depends_on": "eval:doc.is_subcontracted==\"Yes\"",
|
|
||||||
"fieldname": "supplier_warehouse",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Supplier Warehouse",
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Warehouse",
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_width": "50px",
|
|
||||||
"width": "50px"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "items_section",
|
"fieldname": "items_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
@ -1232,7 +1222,9 @@
|
|||||||
"fieldname": "inter_company_invoice_reference",
|
"fieldname": "inter_company_invoice_reference",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Inter Company Invoice Reference",
|
"label": "Inter Company Invoice Reference",
|
||||||
|
"no_copy": 1,
|
||||||
"options": "Sales Invoice",
|
"options": "Sales Invoice",
|
||||||
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1356,13 +1348,25 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Represents Company",
|
"label": "Represents Company",
|
||||||
"options": "Company"
|
"options": "Company"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.update_stock && (doc.is_subcontracted==\"Yes\" || doc.is_internal_supplier)",
|
||||||
|
"description": "Sets 'From Warehouse' in each row of the items table.",
|
||||||
|
"fieldname": "set_from_warehouse",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Set From Warehouse",
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "Warehouse",
|
||||||
|
"print_hide": 1,
|
||||||
|
"print_width": "50px",
|
||||||
|
"width": "50px"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 204,
|
"idx": 204,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-12-11 12:46:12.796378",
|
"modified": "2020-12-26 20:49:03.305063",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Invoice",
|
"name": "Purchase Invoice",
|
||||||
|
@ -511,8 +511,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
voucher_wise_stock_value = {}
|
voucher_wise_stock_value = {}
|
||||||
if self.update_stock:
|
if self.update_stock:
|
||||||
for d in frappe.get_all('Stock Ledger Entry',
|
for d in frappe.get_all('Stock Ledger Entry',
|
||||||
fields = ["voucher_detail_no", "stock_value_difference"], filters={'voucher_no': self.name}):
|
fields = ["voucher_detail_no", "stock_value_difference", "warehouse"], filters={'voucher_no': self.name}):
|
||||||
voucher_wise_stock_value.setdefault(d.voucher_detail_no, d.stock_value_difference)
|
voucher_wise_stock_value.setdefault((d.voucher_detail_no, d.warehouse), d.stock_value_difference)
|
||||||
|
|
||||||
valuation_tax_accounts = [d.account_head for d in self.get("taxes")
|
valuation_tax_accounts = [d.account_head for d in self.get("taxes")
|
||||||
if d.category in ('Valuation', 'Total and Valuation')
|
if d.category in ('Valuation', 'Total and Valuation')
|
||||||
@ -563,6 +563,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
if not self.is_internal_transfer():
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": item.expense_account,
|
"account": item.expense_account,
|
||||||
@ -625,6 +626,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
if expense_booked_in_pr:
|
if expense_booked_in_pr:
|
||||||
expense_account = service_received_but_not_billed_account
|
expense_account = service_received_but_not_billed_account
|
||||||
|
|
||||||
|
if not self.is_internal_transfer():
|
||||||
gl_entries.append(self.get_gl_dict({
|
gl_entries.append(self.get_gl_dict({
|
||||||
"account": expense_account,
|
"account": expense_account,
|
||||||
"against": self.supplier,
|
"against": self.supplier,
|
||||||
@ -796,10 +798,10 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
# Stock ledger value is not matching with the warehouse amount
|
# Stock ledger value is not matching with the warehouse amount
|
||||||
if (self.update_stock and voucher_wise_stock_value.get(item.name) and
|
if (self.update_stock and voucher_wise_stock_value.get(item.name) and
|
||||||
warehouse_debit_amount != flt(voucher_wise_stock_value.get(item.name), net_amt_precision)):
|
warehouse_debit_amount != flt(voucher_wise_stock_value.get((item.name, item.warehouse)), net_amt_precision)):
|
||||||
|
|
||||||
cost_of_goods_sold_account = self.get_company_default("default_expense_account")
|
cost_of_goods_sold_account = self.get_company_default("default_expense_account")
|
||||||
stock_amount = flt(voucher_wise_stock_value.get(item.name), net_amt_precision)
|
stock_amount = flt(voucher_wise_stock_value.get((item.name, item.warehouse)), net_amt_precision)
|
||||||
stock_adjustment_amt = warehouse_debit_amount - stock_amount
|
stock_adjustment_amt = warehouse_debit_amount - stock_amount
|
||||||
|
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "hash",
|
"autoname": "hash",
|
||||||
"creation": "2013-05-22 12:43:10",
|
"creation": "2013-05-22 12:43:10",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -87,6 +88,7 @@
|
|||||||
"po_detail",
|
"po_detail",
|
||||||
"purchase_receipt",
|
"purchase_receipt",
|
||||||
"pr_detail",
|
"pr_detail",
|
||||||
|
"sales_invoice_item",
|
||||||
"item_weight_details",
|
"item_weight_details",
|
||||||
"weight_per_unit",
|
"weight_per_unit",
|
||||||
"total_weight",
|
"total_weight",
|
||||||
@ -553,8 +555,8 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Brand",
|
"label": "Brand",
|
||||||
"print_hide": 1,
|
"options": "Brand",
|
||||||
"options": "Brand"
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "item_code.item_group",
|
"fetch_from": "item_code.item_group",
|
||||||
@ -562,9 +564,9 @@
|
|||||||
"fieldname": "item_group",
|
"fieldname": "item_group",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Item Group",
|
"label": "Item Group",
|
||||||
|
"options": "Item Group",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1,
|
"read_only": 1
|
||||||
"options": "Item Group"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Tax detail table fetched from item master as a string and stored in this field.\nUsed for Taxes and Charges",
|
"description": "Tax detail table fetched from item master as a string and stored in this field.\nUsed for Taxes and Charges",
|
||||||
@ -759,10 +761,11 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:parent.is_internal_supplier && parent.update_stock",
|
||||||
"fieldname": "from_warehouse",
|
"fieldname": "from_warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"ignore_user_permissions": 1,
|
"ignore_user_permissions": 1,
|
||||||
"label": "Supplier Warehouse",
|
"label": "From Warehouse",
|
||||||
"options": "Warehouse"
|
"options": "Warehouse"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -779,11 +782,20 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "sales_invoice_item",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Sales Invoice Item",
|
||||||
|
"no_copy": 1,
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2020-08-20 11:48:01.398356",
|
"links": [],
|
||||||
|
"modified": "2020-12-26 17:20:36.415791",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Invoice Item",
|
"name": "Purchase Invoice Item",
|
||||||
|
@ -130,16 +130,15 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
|
|
||||||
this.set_default_print_format();
|
this.set_default_print_format();
|
||||||
if (doc.docstatus == 1 && !doc.inter_company_invoice_reference) {
|
if (doc.docstatus == 1 && !doc.inter_company_invoice_reference) {
|
||||||
frappe.model.with_doc("Customer", me.frm.doc.customer, function() {
|
let internal = me.frm.doc.is_internal_customer;
|
||||||
var customer = frappe.model.get_doc("Customer", me.frm.doc.customer);
|
if (internal) {
|
||||||
var internal = customer.is_internal_customer;
|
let button_label = (me.frm.doc.company === me.frm.doc.represents_company) ? "Internal Purchase Invoice" :
|
||||||
var disabled = customer.disabled;
|
"Inter Company Purchase Invoice";
|
||||||
if (internal == 1 && disabled == 0) {
|
|
||||||
me.frm.add_custom_button("Inter Company Invoice", function() {
|
me.frm.add_custom_button(button_label, function() {
|
||||||
me.make_inter_company_invoice();
|
me.make_inter_company_invoice();
|
||||||
}, __('Create'));
|
}, __('Create'));
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -60,6 +60,8 @@
|
|||||||
"ignore_pricing_rule",
|
"ignore_pricing_rule",
|
||||||
"sec_warehouse",
|
"sec_warehouse",
|
||||||
"set_warehouse",
|
"set_warehouse",
|
||||||
|
"column_break_55",
|
||||||
|
"set_target_warehouse",
|
||||||
"items_section",
|
"items_section",
|
||||||
"update_stock",
|
"update_stock",
|
||||||
"scan_barcode",
|
"scan_barcode",
|
||||||
@ -1969,13 +1971,24 @@
|
|||||||
"label": "Represents Company",
|
"label": "Represents Company",
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_55",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval: doc.is_internal_customer && doc.update_stock",
|
||||||
|
"fieldname": "set_target_warehouse",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Set Target Warehouse",
|
||||||
|
"options": "Warehouse"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 181,
|
"idx": 181,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-12-11 12:48:31.769958",
|
"modified": "2020-12-25 22:57:32.555067",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice",
|
"name": "Sales Invoice",
|
||||||
|
@ -6,7 +6,7 @@ import frappe, erpnext
|
|||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from frappe.utils import cint, flt, getdate, add_days, cstr, nowdate, get_link_to_form, formatdate
|
from frappe.utils import cint, flt, getdate, add_days, cstr, nowdate, get_link_to_form, formatdate
|
||||||
from frappe import _, msgprint, throw
|
from frappe import _, msgprint, throw
|
||||||
from erpnext.accounts.party import get_party_account, get_due_date
|
from erpnext.accounts.party import get_party_account, get_due_date, get_party_details
|
||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
from erpnext.controllers.selling_controller import SellingController
|
from erpnext.controllers.selling_controller import SellingController
|
||||||
from erpnext.accounts.utils import get_account_currency
|
from erpnext.accounts.utils import get_account_currency
|
||||||
@ -21,6 +21,8 @@ from erpnext.accounts.general_ledger import get_round_off_account_and_cost_cente
|
|||||||
from erpnext.accounts.doctype.loyalty_program.loyalty_program import \
|
from erpnext.accounts.doctype.loyalty_program.loyalty_program import \
|
||||||
get_loyalty_program_details_with_points, get_loyalty_details, validate_loyalty_points
|
get_loyalty_program_details_with_points, get_loyalty_details, validate_loyalty_points
|
||||||
from erpnext.accounts.deferred_revenue import validate_service_stop_date
|
from erpnext.accounts.deferred_revenue import validate_service_stop_date
|
||||||
|
from frappe.model.utils import get_fetch_values
|
||||||
|
from frappe.contacts.doctype.address.address import get_address_display
|
||||||
|
|
||||||
from erpnext.healthcare.utils import manage_invoice_submit_cancel
|
from erpnext.healthcare.utils import manage_invoice_submit_cancel
|
||||||
|
|
||||||
@ -1534,7 +1536,7 @@ def validate_inter_company_transaction(doc, doctype):
|
|||||||
details = get_inter_company_details(doc, doctype)
|
details = get_inter_company_details(doc, doctype)
|
||||||
price_list = doc.selling_price_list if doctype in ["Sales Invoice", "Sales Order", "Delivery Note"] else doc.buying_price_list
|
price_list = doc.selling_price_list if doctype in ["Sales Invoice", "Sales Order", "Delivery Note"] else doc.buying_price_list
|
||||||
valid_price_list = frappe.db.get_value("Price List", {"name": price_list, "buying": 1, "selling": 1})
|
valid_price_list = frappe.db.get_value("Price List", {"name": price_list, "buying": 1, "selling": 1})
|
||||||
if not valid_price_list:
|
if not valid_price_list and not doc.is_internal_transfer():
|
||||||
frappe.throw(_("Selected Price List should have buying and selling fields checked."))
|
frappe.throw(_("Selected Price List should have buying and selling fields checked."))
|
||||||
|
|
||||||
party = details.get("party")
|
party = details.get("party")
|
||||||
@ -1557,6 +1559,7 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
|||||||
if doctype in ["Sales Invoice", "Sales Order"]:
|
if doctype in ["Sales Invoice", "Sales Order"]:
|
||||||
source_doc = frappe.get_doc(doctype, source_name)
|
source_doc = frappe.get_doc(doctype, source_name)
|
||||||
target_doctype = "Purchase Invoice" if doctype == "Sales Invoice" else "Purchase Order"
|
target_doctype = "Purchase Invoice" if doctype == "Sales Invoice" else "Purchase Order"
|
||||||
|
target_detail_field = "sales_invoice_item" if doctype == "Sales Invoice" else "sales_order_item"
|
||||||
source_document_warehouse_field = 'target_warehouse'
|
source_document_warehouse_field = 'target_warehouse'
|
||||||
target_document_warehouse_field = 'from_warehouse'
|
target_document_warehouse_field = 'from_warehouse'
|
||||||
else:
|
else:
|
||||||
@ -1570,6 +1573,7 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
|||||||
|
|
||||||
def set_missing_values(source, target):
|
def set_missing_values(source, target):
|
||||||
target.run_method("set_missing_values")
|
target.run_method("set_missing_values")
|
||||||
|
set_purchase_references(target)
|
||||||
|
|
||||||
def update_details(source_doc, target_doc, source_parent):
|
def update_details(source_doc, target_doc, source_parent):
|
||||||
target_doc.inter_company_invoice_reference = source_doc.name
|
target_doc.inter_company_invoice_reference = source_doc.name
|
||||||
@ -1577,19 +1581,38 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
|||||||
currency = frappe.db.get_value('Supplier', details.get('party'), 'default_currency')
|
currency = frappe.db.get_value('Supplier', details.get('party'), 'default_currency')
|
||||||
target_doc.company = details.get("company")
|
target_doc.company = details.get("company")
|
||||||
target_doc.supplier = details.get("party")
|
target_doc.supplier = details.get("party")
|
||||||
|
target_doc.is_internal_supplier = 1
|
||||||
|
target_doc.ignore_pricing_rule = 1
|
||||||
target_doc.buying_price_list = source_doc.selling_price_list
|
target_doc.buying_price_list = source_doc.selling_price_list
|
||||||
|
|
||||||
|
# Invert Addresses
|
||||||
|
update_address(target_doc, 'supplier_address', 'address_display', source_doc.company_address)
|
||||||
|
update_address(target_doc, 'shipping_address', 'shipping_address_display', source_doc.customer_address)
|
||||||
|
|
||||||
if currency:
|
if currency:
|
||||||
target_doc.currency = currency
|
target_doc.currency = currency
|
||||||
|
|
||||||
|
update_taxes(target_doc, party=target_doc.supplier, party_type='Supplier', company=target_doc.company,
|
||||||
|
doctype=target_doc.doctype, party_address=target_doc.supplier_address,
|
||||||
|
company_address=target_doc.shipping_address)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
currency = frappe.db.get_value('Customer', details.get('party'), 'default_currency')
|
currency = frappe.db.get_value('Customer', details.get('party'), 'default_currency')
|
||||||
target_doc.company = details.get("company")
|
target_doc.company = details.get("company")
|
||||||
target_doc.customer = details.get("party")
|
target_doc.customer = details.get("party")
|
||||||
target_doc.selling_price_list = source_doc.buying_price_list
|
target_doc.selling_price_list = source_doc.buying_price_list
|
||||||
|
|
||||||
|
update_address(target_doc, 'company_address', 'company_address_display', source_doc.supplier_address)
|
||||||
|
update_address(target_doc, 'shipping_address_name', 'shipping_address', source_doc.shipping_address)
|
||||||
|
update_address(target_doc, 'customer_address', 'address_display', source_doc.shipping_address)
|
||||||
|
|
||||||
if currency:
|
if currency:
|
||||||
target_doc.currency = currency
|
target_doc.currency = currency
|
||||||
|
|
||||||
|
update_taxes(target_doc, party=target_doc.customer, party_type='Customer', company=target_doc.company,
|
||||||
|
doctype=target_doc.doctype, party_address=target_doc.customer_address,
|
||||||
|
company_address=target_doc.company_address, shipping_address_name=target_doc.shipping_address_name)
|
||||||
|
|
||||||
item_field_map = {
|
item_field_map = {
|
||||||
"doctype": target_doctype + " Item",
|
"doctype": target_doctype + " Item",
|
||||||
"field_no_map": [
|
"field_no_map": [
|
||||||
@ -1597,25 +1620,33 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
|||||||
"expense_account",
|
"expense_account",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"warehouse"
|
"warehouse"
|
||||||
]
|
],
|
||||||
|
"field_map": {
|
||||||
|
'rate': 'rate',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if doctype in ["Sales Invoice", "Sales Order"]:
|
||||||
|
item_field_map["field_map"].update({
|
||||||
|
"name": target_detail_field,
|
||||||
|
})
|
||||||
|
|
||||||
if source_doc.get('update_stock'):
|
if source_doc.get('update_stock'):
|
||||||
item_field_map.update({
|
item_field_map["field_map"].update({
|
||||||
'field_map': {
|
|
||||||
source_document_warehouse_field: target_document_warehouse_field,
|
source_document_warehouse_field: target_document_warehouse_field,
|
||||||
'batch_no': 'batch_no',
|
'batch_no': 'batch_no',
|
||||||
'serial_no': 'serial_no'
|
'serial_no': 'serial_no'
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
doclist = get_mapped_doc(doctype, source_name, {
|
doclist = get_mapped_doc(doctype, source_name, {
|
||||||
doctype: {
|
doctype: {
|
||||||
"doctype": target_doctype,
|
"doctype": target_doctype,
|
||||||
"postprocess": update_details,
|
"postprocess": update_details,
|
||||||
|
"set_target_warehouse": "set_from_warehouse",
|
||||||
"field_no_map": [
|
"field_no_map": [
|
||||||
"taxes_and_charges"
|
"taxes_and_charges",
|
||||||
|
"set_warehouse",
|
||||||
|
"shipping_address"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
doctype +" Item": item_field_map
|
doctype +" Item": item_field_map
|
||||||
@ -1624,6 +1655,110 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
|||||||
|
|
||||||
return doclist
|
return doclist
|
||||||
|
|
||||||
|
def set_purchase_references(doc):
|
||||||
|
# add internal PO or PR links if any
|
||||||
|
if doc.is_internal_transfer():
|
||||||
|
if doc.doctype == 'Purchase Receipt':
|
||||||
|
so_item_map = get_delivery_note_details(doc.inter_company_invoice_reference)
|
||||||
|
|
||||||
|
if so_item_map:
|
||||||
|
pd_item_map, parent_child_map, warehouse_map = \
|
||||||
|
get_pd_details('Purchase Order Item', so_item_map, 'sales_order_item')
|
||||||
|
|
||||||
|
update_pr_items(doc, so_item_map, pd_item_map, parent_child_map, warehouse_map)
|
||||||
|
|
||||||
|
elif doc.doctype == 'Purchase Invoice':
|
||||||
|
dn_item_map, so_item_map = get_sales_invoice_details(doc.inter_company_invoice_reference)
|
||||||
|
# First check for Purchase receipt
|
||||||
|
if list(dn_item_map.values()):
|
||||||
|
pd_item_map, parent_child_map, warehouse_map = \
|
||||||
|
get_pd_details('Purchase Receipt Item', dn_item_map, 'delivery_note_item')
|
||||||
|
|
||||||
|
update_pi_items(doc, 'pr_detail', 'purchase_receipt',
|
||||||
|
dn_item_map, pd_item_map, parent_child_map, warehouse_map)
|
||||||
|
|
||||||
|
if list(so_item_map.values()):
|
||||||
|
pd_item_map, parent_child_map, warehouse_map = \
|
||||||
|
get_pd_details('Purchase Order Item', so_item_map, 'sales_order_item')
|
||||||
|
|
||||||
|
update_pi_items(doc, 'po_detail', 'purchase_order',
|
||||||
|
so_item_map, pd_item_map, parent_child_map, warehouse_map)
|
||||||
|
|
||||||
|
def update_pi_items(doc, detail_field, parent_field, sales_item_map,
|
||||||
|
purchase_item_map, parent_child_map, warehouse_map):
|
||||||
|
for item in doc.get('items'):
|
||||||
|
item.set(detail_field, purchase_item_map.get(sales_item_map.get(item.sales_invoice_item)))
|
||||||
|
item.set(parent_field, parent_child_map.get(sales_item_map.get(item.sales_invoice_item)))
|
||||||
|
if doc.update_stock:
|
||||||
|
item.warehouse = warehouse_map.get(sales_item_map.get(item.sales_invoice_item))
|
||||||
|
|
||||||
|
def update_pr_items(doc, sales_item_map, purchase_item_map, parent_child_map, warehouse_map):
|
||||||
|
for item in doc.get('items'):
|
||||||
|
item.purchase_order_item = purchase_item_map.get(sales_item_map.get(item.delivery_note_item))
|
||||||
|
item.warehouse = warehouse_map.get(sales_item_map.get(item.delivery_note_item))
|
||||||
|
item.purchase_order = parent_child_map.get(sales_item_map.get(item.delivery_note_item))
|
||||||
|
|
||||||
|
def get_delivery_note_details(internal_reference):
|
||||||
|
so_item_map = {}
|
||||||
|
|
||||||
|
si_item_details = frappe.get_all('Delivery Note Item', fields=['name', 'so_detail'],
|
||||||
|
filters={'parent': internal_reference})
|
||||||
|
|
||||||
|
for d in si_item_details:
|
||||||
|
so_item_map.setdefault(d.name, d.so_detail)
|
||||||
|
|
||||||
|
return so_item_map
|
||||||
|
|
||||||
|
def get_sales_invoice_details(internal_reference):
|
||||||
|
dn_item_map = {}
|
||||||
|
so_item_map = {}
|
||||||
|
|
||||||
|
si_item_details = frappe.get_all('Sales Invoice Item', fields=['name', 'so_detail',
|
||||||
|
'dn_detail'], filters={'parent': internal_reference})
|
||||||
|
|
||||||
|
for d in si_item_details:
|
||||||
|
if d.dn_detail:
|
||||||
|
dn_item_map.setdefault(d.name, d.dn_detail)
|
||||||
|
if d.so_detail:
|
||||||
|
so_item_map.setdefault(d.name, d.so_detail)
|
||||||
|
|
||||||
|
return dn_item_map, so_item_map
|
||||||
|
|
||||||
|
def get_pd_details(doctype, sd_detail_map, sd_detail_field):
|
||||||
|
pd_item_map = {}
|
||||||
|
accepted_warehouse_map = {}
|
||||||
|
parent_child_map = {}
|
||||||
|
|
||||||
|
pd_item_details = frappe.get_all(doctype,
|
||||||
|
fields=[sd_detail_field, 'name', 'warehouse', 'parent'], filters={sd_detail_field: ('in', list(sd_detail_map.values()))})
|
||||||
|
|
||||||
|
for d in pd_item_details:
|
||||||
|
pd_item_map.setdefault(d.get(sd_detail_field), d.name)
|
||||||
|
parent_child_map.setdefault(d.get(sd_detail_field), d.parent)
|
||||||
|
accepted_warehouse_map.setdefault(d.get(sd_detail_field), d.warehouse)
|
||||||
|
|
||||||
|
return pd_item_map, parent_child_map, accepted_warehouse_map
|
||||||
|
|
||||||
|
def update_taxes(doc, party=None, party_type=None, company=None, doctype=None, party_address=None,
|
||||||
|
company_address=None, shipping_address_name=None, master_doctype=None):
|
||||||
|
# Update Party Details
|
||||||
|
party_details = get_party_details(party=party, party_type=party_type, company=company,
|
||||||
|
doctype=doctype, party_address=party_address, company_address=company_address,
|
||||||
|
shipping_address=shipping_address_name)
|
||||||
|
|
||||||
|
# Update taxes and charges if any
|
||||||
|
doc.taxes_and_charges = party_details.get('taxes_and_charges')
|
||||||
|
doc.set('taxes', party_details.get('taxes'))
|
||||||
|
|
||||||
|
def update_address(doc, address_field, address_display_field, address_name):
|
||||||
|
doc.set(address_field, address_name)
|
||||||
|
fetch_values = get_fetch_values(doc.doctype, address_field, address_name)
|
||||||
|
|
||||||
|
for key, value in fetch_values.items():
|
||||||
|
doc.set(key, value)
|
||||||
|
|
||||||
|
doc.set(address_display_field, get_address_display(doc.get(address_field)))
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_loyalty_programs(customer):
|
def get_loyalty_programs(customer):
|
||||||
''' sets applicable loyalty program to the customer or returns a list of applicable programs '''
|
''' sets applicable loyalty program to the customer or returns a list of applicable programs '''
|
||||||
|
@ -22,6 +22,7 @@ from erpnext.regional.india.utils import get_ewb_data
|
|||||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
|
||||||
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
|
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
|
||||||
|
from erpnext.stock.utils import get_incoming_rate
|
||||||
|
|
||||||
class TestSalesInvoice(unittest.TestCase):
|
class TestSalesInvoice(unittest.TestCase):
|
||||||
def make(self):
|
def make(self):
|
||||||
@ -1770,59 +1771,82 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
self.assertEqual(target_doc.company, "_Test Company 1")
|
self.assertEqual(target_doc.company, "_Test Company 1")
|
||||||
self.assertEqual(target_doc.supplier, "_Test Internal Supplier")
|
self.assertEqual(target_doc.supplier, "_Test Internal Supplier")
|
||||||
|
|
||||||
# def test_internal_transfer_gl_entry(self):
|
def test_internal_transfer_gl_entry(self):
|
||||||
# ## Create internal transfer account
|
## Create internal transfer account
|
||||||
# account = create_account(account_name="Unrealized Profit",
|
account = create_account(account_name="Unrealized Profit",
|
||||||
# parent_account="Current Liabilities - TCP1", company="_Test Company with perpetual inventory")
|
parent_account="Current Liabilities - TCP1", company="_Test Company with perpetual inventory")
|
||||||
|
|
||||||
# frappe.db.set_value('Company', '_Test Company with perpetual inventory',
|
frappe.db.set_value('Company', '_Test Company with perpetual inventory',
|
||||||
# 'unrealized_profit_loss_account', account)
|
'unrealized_profit_loss_account', account)
|
||||||
|
|
||||||
# customer = create_internal_customer("_Test Internal Customer 2", "_Test Company with perpetual inventory",
|
customer = create_internal_customer("_Test Internal Customer 2", "_Test Company with perpetual inventory",
|
||||||
# "_Test Company with perpetual inventory")
|
"_Test Company with perpetual inventory")
|
||||||
|
|
||||||
# create_internal_supplier("_Test Internal Supplier 2", "_Test Company with perpetual inventory",
|
create_internal_supplier("_Test Internal Supplier 2", "_Test Company with perpetual inventory",
|
||||||
# "_Test Company with perpetual inventory")
|
"_Test Company with perpetual inventory")
|
||||||
|
|
||||||
# si = create_sales_invoice(
|
si = create_sales_invoice(
|
||||||
# company = "_Test Company with perpetual inventory",
|
company = "_Test Company with perpetual inventory",
|
||||||
# customer = customer,
|
customer = customer,
|
||||||
# debit_to = "Debtors - TCP1",
|
debit_to = "Debtors - TCP1",
|
||||||
# warehouse = "Stores - TCP1",
|
warehouse = "Stores - TCP1",
|
||||||
# income_account = "Sales - TCP1",
|
income_account = "Sales - TCP1",
|
||||||
# expense_account = "Cost of Goods Sold - TCP1",
|
expense_account = "Cost of Goods Sold - TCP1",
|
||||||
# cost_center = "Main - TCP1",
|
cost_center = "Main - TCP1",
|
||||||
# currency = "INR",
|
currency = "INR",
|
||||||
# do_not_save = 1
|
do_not_save = 1
|
||||||
# )
|
)
|
||||||
|
|
||||||
# si.selling_price_list = "_Test Price List Rest of the World"
|
si.selling_price_list = "_Test Price List Rest of the World"
|
||||||
# si.update_stock = 1
|
si.update_stock = 1
|
||||||
# si.items[0].target_warehouse = 'Work In Progress - TCP1'
|
si.items[0].target_warehouse = 'Work In Progress - TCP1'
|
||||||
# add_taxes(si)
|
add_taxes(si)
|
||||||
# si.save()
|
si.save()
|
||||||
# si.submit()
|
|
||||||
|
|
||||||
# target_doc = make_inter_company_transaction("Sales Invoice", si.name)
|
rate = 0.0
|
||||||
# target_doc.company = '_Test Company with perpetual inventory'
|
for d in si.get('items'):
|
||||||
# target_doc.items[0].warehouse = 'Finished Goods - TCP1'
|
rate = get_incoming_rate({
|
||||||
# add_taxes(target_doc)
|
"item_code": d.item_code,
|
||||||
# target_doc.save()
|
"warehouse": d.warehouse,
|
||||||
# target_doc.submit()
|
"posting_date": si.posting_date,
|
||||||
|
"posting_time": si.posting_time,
|
||||||
|
"qty": -1 * flt(d.get('stock_qty')),
|
||||||
|
"serial_no": d.serial_no,
|
||||||
|
"company": si.company,
|
||||||
|
"voucher_type": 'Sales Invoice',
|
||||||
|
"voucher_no": si.name,
|
||||||
|
"allow_zero_valuation": d.get("allow_zero_valuation")
|
||||||
|
}, raise_error_if_no_rate=False)
|
||||||
|
|
||||||
# si_gl_entries = [
|
rate = flt(rate, 2)
|
||||||
# ["_Test Account Excise Duty - TCP1", 0.0, 12.0, nowdate()],
|
|
||||||
# ["Unrealized Profit - TCP1", 12.0, 0.0, nowdate()]
|
|
||||||
# ]
|
|
||||||
|
|
||||||
# check_gl_entries(self, si.name, si_gl_entries, add_days(nowdate(), -1))
|
si.submit()
|
||||||
|
|
||||||
# pi_gl_entries = [
|
target_doc = make_inter_company_transaction("Sales Invoice", si.name)
|
||||||
# ["_Test Account Excise Duty - TCP1", 12.0 , 0.0, nowdate()],
|
target_doc.company = '_Test Company with perpetual inventory'
|
||||||
# ["Unrealized Profit - TCP1", 0.0, 12.0, nowdate()]
|
target_doc.items[0].warehouse = 'Finished Goods - TCP1'
|
||||||
# ]
|
add_taxes(target_doc)
|
||||||
|
target_doc.save()
|
||||||
|
target_doc.submit()
|
||||||
|
|
||||||
# check_gl_entries(self, target_doc.name, pi_gl_entries, add_days(nowdate(), -1))
|
tax_amount = flt(rate * (12/100), 2)
|
||||||
|
si_gl_entries = [
|
||||||
|
["_Test Account Excise Duty - TCP1", 0.0, tax_amount, nowdate()],
|
||||||
|
["Unrealized Profit - TCP1", tax_amount, 0.0, nowdate()]
|
||||||
|
]
|
||||||
|
|
||||||
|
check_gl_entries(self, si.name, si_gl_entries, add_days(nowdate(), -1))
|
||||||
|
|
||||||
|
pi_gl_entries = [
|
||||||
|
["_Test Account Excise Duty - TCP1", tax_amount , 0.0, nowdate()],
|
||||||
|
["Unrealized Profit - TCP1", 0.0, tax_amount, nowdate()]
|
||||||
|
]
|
||||||
|
|
||||||
|
# Sale and Purchase both should be at valuation rate
|
||||||
|
self.assertEqual(si.items[0].rate, rate)
|
||||||
|
self.assertEqual(target_doc.items[0].rate, rate)
|
||||||
|
|
||||||
|
check_gl_entries(self, target_doc.name, pi_gl_entries, add_days(nowdate(), -1))
|
||||||
|
|
||||||
def test_eway_bill_json(self):
|
def test_eway_bill_json(self):
|
||||||
si = make_sales_invoice_for_ewaybill()
|
si = make_sales_invoice_for_ewaybill()
|
||||||
|
@ -565,11 +565,12 @@
|
|||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval: parent.is_internal_customer && parent.update_stock",
|
||||||
"fieldname": "target_warehouse",
|
"fieldname": "target_warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"ignore_user_permissions": 1,
|
"ignore_user_permissions": 1,
|
||||||
"label": "Customer Warehouse (Optional)",
|
"label": "Target Warehouse",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Warehouse",
|
"options": "Warehouse",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
@ -815,7 +816,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-09-23 19:59:04.879322",
|
"modified": "2020-12-26 17:25:04.090630",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice Item",
|
"name": "Sales Invoice Item",
|
||||||
|
@ -34,6 +34,9 @@ def valdiate_taxes_and_charges_template(doc):
|
|||||||
|
|
||||||
validate_disabled(doc)
|
validate_disabled(doc)
|
||||||
|
|
||||||
|
# Validate with existing taxes and charges template for unique tax category
|
||||||
|
validate_for_tax_category(doc)
|
||||||
|
|
||||||
for tax in doc.get("taxes"):
|
for tax in doc.get("taxes"):
|
||||||
validate_taxes_and_charges(tax)
|
validate_taxes_and_charges(tax)
|
||||||
validate_inclusive_tax(tax, doc)
|
validate_inclusive_tax(tax, doc)
|
||||||
@ -41,3 +44,7 @@ def valdiate_taxes_and_charges_template(doc):
|
|||||||
def validate_disabled(doc):
|
def validate_disabled(doc):
|
||||||
if doc.is_default and doc.disabled:
|
if doc.is_default and doc.disabled:
|
||||||
frappe.throw(_("Disabled template must not be default template"))
|
frappe.throw(_("Disabled template must not be default template"))
|
||||||
|
|
||||||
|
def validate_for_tax_category(doc):
|
||||||
|
if frappe.db.exists(doc.doctype, {"company": doc.company, "tax_category": doc.tax_category, "disabled": 0}):
|
||||||
|
frappe.throw(_("A template with tax category {0} already exists. Only one template is allowed with each tax category").format(frappe.bold(doc.tax_category)))
|
||||||
|
@ -49,7 +49,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
elif d.po_detail:
|
elif d.po_detail:
|
||||||
purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, []))
|
purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, []))
|
||||||
|
|
||||||
expense_account = d.expense_account or aii_account_map.get(d.company)
|
expense_account = d.unrealized_profit_loss_account or d.expense_account \
|
||||||
|
or aii_account_map.get(d.company)
|
||||||
|
|
||||||
row = {
|
row = {
|
||||||
'item_code': d.item_code,
|
'item_code': d.item_code,
|
||||||
@ -315,6 +316,7 @@ def get_items(filters, additional_query_columns):
|
|||||||
`tabPurchase Invoice Item`.`name`, `tabPurchase Invoice Item`.`parent`,
|
`tabPurchase Invoice Item`.`name`, `tabPurchase Invoice Item`.`parent`,
|
||||||
`tabPurchase Invoice`.posting_date, `tabPurchase Invoice`.credit_to, `tabPurchase Invoice`.company,
|
`tabPurchase Invoice`.posting_date, `tabPurchase Invoice`.credit_to, `tabPurchase Invoice`.company,
|
||||||
`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total,
|
`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total,
|
||||||
|
`tabPurchase Invoice`.unrealized_profit_loss_account,
|
||||||
`tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description,
|
`tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description,
|
||||||
`tabPurchase Invoice Item`.`item_name`, `tabPurchase Invoice Item`.`item_group`,
|
`tabPurchase Invoice Item`.`item_name`, `tabPurchase Invoice Item`.`item_group`,
|
||||||
`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
|
`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
|
||||||
|
@ -76,7 +76,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
'company': d.company,
|
'company': d.company,
|
||||||
'sales_order': d.sales_order,
|
'sales_order': d.sales_order,
|
||||||
'delivery_note': d.delivery_note,
|
'delivery_note': d.delivery_note,
|
||||||
'income_account': d.income_account,
|
'income_account': d.unrealized_profit_loss_account or d.income_account,
|
||||||
'cost_center': d.cost_center,
|
'cost_center': d.cost_center,
|
||||||
'stock_qty': d.stock_qty,
|
'stock_qty': d.stock_qty,
|
||||||
'stock_uom': d.stock_uom
|
'stock_uom': d.stock_uom
|
||||||
@ -379,6 +379,7 @@ def get_items(filters, additional_query_columns):
|
|||||||
select
|
select
|
||||||
`tabSales Invoice Item`.name, `tabSales Invoice Item`.parent,
|
`tabSales Invoice Item`.name, `tabSales Invoice Item`.parent,
|
||||||
`tabSales Invoice`.posting_date, `tabSales Invoice`.debit_to,
|
`tabSales Invoice`.posting_date, `tabSales Invoice`.debit_to,
|
||||||
|
`tabSales Invoice`.unrealized_profit_loss_account,
|
||||||
`tabSales Invoice`.project, `tabSales Invoice`.customer, `tabSales Invoice`.remarks,
|
`tabSales Invoice`.project, `tabSales Invoice`.customer, `tabSales Invoice`.remarks,
|
||||||
`tabSales Invoice`.territory, `tabSales Invoice`.company, `tabSales Invoice`.base_net_total,
|
`tabSales Invoice`.territory, `tabSales Invoice`.company, `tabSales Invoice`.base_net_total,
|
||||||
`tabSales Invoice Item`.item_code, `tabSales Invoice Item`.description,
|
`tabSales Invoice Item`.item_code, `tabSales Invoice Item`.description,
|
||||||
|
@ -14,13 +14,15 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
|
|
||||||
invoice_list = get_invoices(filters, additional_query_columns)
|
invoice_list = get_invoices(filters, additional_query_columns)
|
||||||
columns, expense_accounts, tax_accounts = get_columns(invoice_list, additional_table_columns)
|
columns, expense_accounts, tax_accounts, unrealized_profit_loss_accounts \
|
||||||
|
= get_columns(invoice_list, additional_table_columns)
|
||||||
|
|
||||||
if not invoice_list:
|
if not invoice_list:
|
||||||
msgprint(_("No record found"))
|
msgprint(_("No record found"))
|
||||||
return columns, invoice_list
|
return columns, invoice_list
|
||||||
|
|
||||||
invoice_expense_map = get_invoice_expense_map(invoice_list)
|
invoice_expense_map = get_invoice_expense_map(invoice_list)
|
||||||
|
internal_invoice_map = get_internal_invoice_map(invoice_list)
|
||||||
invoice_expense_map, invoice_tax_map = get_invoice_tax_map(invoice_list,
|
invoice_expense_map, invoice_tax_map = get_invoice_tax_map(invoice_list,
|
||||||
invoice_expense_map, expense_accounts)
|
invoice_expense_map, expense_accounts)
|
||||||
invoice_po_pr_map = get_invoice_po_pr_map(invoice_list)
|
invoice_po_pr_map = get_invoice_po_pr_map(invoice_list)
|
||||||
@ -52,10 +54,17 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
# map expense values
|
# map expense values
|
||||||
base_net_total = 0
|
base_net_total = 0
|
||||||
for expense_acc in expense_accounts:
|
for expense_acc in expense_accounts:
|
||||||
|
if inv.is_internal_supplier and inv.company == inv.represents_company:
|
||||||
|
expense_amount = 0
|
||||||
|
else:
|
||||||
expense_amount = flt(invoice_expense_map.get(inv.name, {}).get(expense_acc))
|
expense_amount = flt(invoice_expense_map.get(inv.name, {}).get(expense_acc))
|
||||||
base_net_total += expense_amount
|
base_net_total += expense_amount
|
||||||
row.append(expense_amount)
|
row.append(expense_amount)
|
||||||
|
|
||||||
|
# Add amount in unrealized account
|
||||||
|
for account in unrealized_profit_loss_accounts:
|
||||||
|
row.append(flt(internal_invoice_map.get((inv.name, account))))
|
||||||
|
|
||||||
# net total
|
# net total
|
||||||
row.append(base_net_total or inv.base_net_total)
|
row.append(base_net_total or inv.base_net_total)
|
||||||
|
|
||||||
@ -96,7 +105,8 @@ def get_columns(invoice_list, additional_table_columns):
|
|||||||
"width": 80
|
"width": 80
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
expense_accounts = tax_accounts = expense_columns = tax_columns = []
|
expense_accounts = tax_accounts = expense_columns = tax_columns = unrealized_profit_loss_accounts = \
|
||||||
|
unrealized_profit_loss_account_columns = []
|
||||||
|
|
||||||
if invoice_list:
|
if invoice_list:
|
||||||
expense_accounts = frappe.db.sql_list("""select distinct expense_account
|
expense_accounts = frappe.db.sql_list("""select distinct expense_account
|
||||||
@ -112,17 +122,25 @@ def get_columns(invoice_list, additional_table_columns):
|
|||||||
and parent in (%s) order by account_head""" %
|
and parent in (%s) order by account_head""" %
|
||||||
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]))
|
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]))
|
||||||
|
|
||||||
|
unrealized_profit_loss_accounts = frappe.db.sql_list("""SELECT distinct unrealized_profit_loss_account
|
||||||
|
from `tabPurchase Invoice` where docstatus = 1 and name in (%s)
|
||||||
|
and ifnull(unrealized_profit_loss_account, '') != ''
|
||||||
|
order by unrealized_profit_loss_account""" %
|
||||||
|
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]))
|
||||||
|
|
||||||
expense_columns = [(account + ":Currency/currency:120") for account in expense_accounts]
|
expense_columns = [(account + ":Currency/currency:120") for account in expense_accounts]
|
||||||
|
unrealized_profit_loss_account_columns = [(account + ":Currency/currency:120") for account in unrealized_profit_loss_accounts]
|
||||||
|
|
||||||
for account in tax_accounts:
|
for account in tax_accounts:
|
||||||
if account not in expense_accounts:
|
if account not in expense_accounts:
|
||||||
tax_columns.append(account + ":Currency/currency:120")
|
tax_columns.append(account + ":Currency/currency:120")
|
||||||
|
|
||||||
columns = columns + expense_columns + [_("Net Total") + ":Currency/currency:120"] + tax_columns + \
|
columns = columns + expense_columns + unrealized_profit_loss_account_columns + \
|
||||||
|
[_("Net Total") + ":Currency/currency:120"] + tax_columns + \
|
||||||
[_("Total Tax") + ":Currency/currency:120", _("Grand Total") + ":Currency/currency:120",
|
[_("Total Tax") + ":Currency/currency:120", _("Grand Total") + ":Currency/currency:120",
|
||||||
_("Rounded Total") + ":Currency/currency:120", _("Outstanding Amount") + ":Currency/currency:120"]
|
_("Rounded Total") + ":Currency/currency:120", _("Outstanding Amount") + ":Currency/currency:120"]
|
||||||
|
|
||||||
return columns, expense_accounts, tax_accounts
|
return columns, expense_accounts, tax_accounts, unrealized_profit_loss_accounts
|
||||||
|
|
||||||
def get_conditions(filters):
|
def get_conditions(filters):
|
||||||
conditions = ""
|
conditions = ""
|
||||||
@ -199,6 +217,19 @@ def get_invoice_expense_map(invoice_list):
|
|||||||
|
|
||||||
return invoice_expense_map
|
return invoice_expense_map
|
||||||
|
|
||||||
|
def get_internal_invoice_map(invoice_list):
|
||||||
|
unrealized_amount_details = frappe.db.sql("""SELECT name, unrealized_profit_loss_account,
|
||||||
|
base_net_total as amount from `tabPurchase Invoice` where name in (%s)
|
||||||
|
and is_internal_supplier = 1 and company = represents_company""" %
|
||||||
|
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
|
||||||
|
|
||||||
|
internal_invoice_map = {}
|
||||||
|
for d in unrealized_amount_details:
|
||||||
|
if d.unrealized_profit_loss_account:
|
||||||
|
internal_invoice_map.setdefault((d.name, d.unrealized_profit_loss_account), d.amount)
|
||||||
|
|
||||||
|
return internal_invoice_map
|
||||||
|
|
||||||
def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts):
|
def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts):
|
||||||
tax_details = frappe.db.sql("""
|
tax_details = frappe.db.sql("""
|
||||||
select parent, account_head, case add_deduct_tax when "Add" then sum(base_tax_amount_after_discount_amount)
|
select parent, account_head, case add_deduct_tax when "Add" then sum(base_tax_amount_after_discount_amount)
|
||||||
|
@ -15,13 +15,14 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No
|
|||||||
if not filters: filters = frappe._dict({})
|
if not filters: filters = frappe._dict({})
|
||||||
|
|
||||||
invoice_list = get_invoices(filters, additional_query_columns)
|
invoice_list = get_invoices(filters, additional_query_columns)
|
||||||
columns, income_accounts, tax_accounts = get_columns(invoice_list, additional_table_columns)
|
columns, income_accounts, tax_accounts, unrealized_profit_loss_accounts = get_columns(invoice_list, additional_table_columns)
|
||||||
|
|
||||||
if not invoice_list:
|
if not invoice_list:
|
||||||
msgprint(_("No record found"))
|
msgprint(_("No record found"))
|
||||||
return columns, invoice_list
|
return columns, invoice_list
|
||||||
|
|
||||||
invoice_income_map = get_invoice_income_map(invoice_list)
|
invoice_income_map = get_invoice_income_map(invoice_list)
|
||||||
|
internal_invoice_map = get_internal_invoice_map(invoice_list)
|
||||||
invoice_income_map, invoice_tax_map = get_invoice_tax_map(invoice_list,
|
invoice_income_map, invoice_tax_map = get_invoice_tax_map(invoice_list,
|
||||||
invoice_income_map, income_accounts)
|
invoice_income_map, income_accounts)
|
||||||
#Cost Center & Warehouse Map
|
#Cost Center & Warehouse Map
|
||||||
@ -70,12 +71,22 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No
|
|||||||
# map income values
|
# map income values
|
||||||
base_net_total = 0
|
base_net_total = 0
|
||||||
for income_acc in income_accounts:
|
for income_acc in income_accounts:
|
||||||
|
if inv.is_internal_customer and inv.company == inv.represents_company:
|
||||||
|
income_amount = 0
|
||||||
|
else:
|
||||||
income_amount = flt(invoice_income_map.get(inv.name, {}).get(income_acc))
|
income_amount = flt(invoice_income_map.get(inv.name, {}).get(income_acc))
|
||||||
|
|
||||||
base_net_total += income_amount
|
base_net_total += income_amount
|
||||||
row.update({
|
row.update({
|
||||||
frappe.scrub(income_acc): income_amount
|
frappe.scrub(income_acc): income_amount
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Add amount in unrealized account
|
||||||
|
for account in unrealized_profit_loss_accounts:
|
||||||
|
row.update({
|
||||||
|
frappe.scrub(account): flt(internal_invoice_map.get((inv.name, account)))
|
||||||
|
})
|
||||||
|
|
||||||
# net total
|
# net total
|
||||||
row.update({'net_total': base_net_total or inv.base_net_total})
|
row.update({'net_total': base_net_total or inv.base_net_total})
|
||||||
|
|
||||||
@ -230,6 +241,8 @@ def get_columns(invoice_list, additional_table_columns):
|
|||||||
tax_accounts = []
|
tax_accounts = []
|
||||||
income_columns = []
|
income_columns = []
|
||||||
tax_columns = []
|
tax_columns = []
|
||||||
|
unrealized_profit_loss_accounts = []
|
||||||
|
unrealized_profit_loss_account_columns = []
|
||||||
|
|
||||||
if invoice_list:
|
if invoice_list:
|
||||||
income_accounts = frappe.db.sql_list("""select distinct income_account
|
income_accounts = frappe.db.sql_list("""select distinct income_account
|
||||||
@ -243,12 +256,18 @@ def get_columns(invoice_list, additional_table_columns):
|
|||||||
and parent in (%s) order by account_head""" %
|
and parent in (%s) order by account_head""" %
|
||||||
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]))
|
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]))
|
||||||
|
|
||||||
|
unrealized_profit_loss_accounts = frappe.db.sql_list("""SELECT distinct unrealized_profit_loss_account
|
||||||
|
from `tabSales Invoice` where docstatus = 1 and name in (%s)
|
||||||
|
and ifnull(unrealized_profit_loss_account, '') != ''
|
||||||
|
order by unrealized_profit_loss_account""" %
|
||||||
|
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]))
|
||||||
|
|
||||||
for account in income_accounts:
|
for account in income_accounts:
|
||||||
income_columns.append({
|
income_columns.append({
|
||||||
"label": account,
|
"label": account,
|
||||||
"fieldname": frappe.scrub(account),
|
"fieldname": frappe.scrub(account),
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"options": 'currency',
|
"options": "currency",
|
||||||
"width": 120
|
"width": 120
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -258,7 +277,16 @@ def get_columns(invoice_list, additional_table_columns):
|
|||||||
"label": account,
|
"label": account,
|
||||||
"fieldname": frappe.scrub(account),
|
"fieldname": frappe.scrub(account),
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"options": 'currency',
|
"options": "currency",
|
||||||
|
"width": 120
|
||||||
|
})
|
||||||
|
|
||||||
|
for account in unrealized_profit_loss_accounts:
|
||||||
|
unrealized_profit_loss_account_columns.append({
|
||||||
|
"label": account,
|
||||||
|
"fieldname": frappe.scrub(account),
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"options": "currency",
|
||||||
"width": 120
|
"width": 120
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -266,7 +294,7 @@ def get_columns(invoice_list, additional_table_columns):
|
|||||||
"label": _("Net Total"),
|
"label": _("Net Total"),
|
||||||
"fieldname": "net_total",
|
"fieldname": "net_total",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"options": 'currency',
|
"options": "currency",
|
||||||
"width": 120
|
"width": 120
|
||||||
}]
|
}]
|
||||||
|
|
||||||
@ -301,9 +329,10 @@ def get_columns(invoice_list, additional_table_columns):
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
columns = columns + income_columns + net_total_column + tax_columns + total_columns
|
columns = columns + income_columns + unrealized_profit_loss_account_columns + \
|
||||||
|
net_total_column + tax_columns + total_columns
|
||||||
|
|
||||||
return columns, income_accounts, tax_accounts
|
return columns, income_accounts, tax_accounts, unrealized_profit_loss_accounts
|
||||||
|
|
||||||
def get_conditions(filters):
|
def get_conditions(filters):
|
||||||
conditions = ""
|
conditions = ""
|
||||||
@ -368,7 +397,8 @@ def get_invoices(filters, additional_query_columns):
|
|||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
select name, posting_date, debit_to, project, customer,
|
select name, posting_date, debit_to, project, customer,
|
||||||
customer_name, owner, remarks, territory, tax_id, customer_group,
|
customer_name, owner, remarks, territory, tax_id, customer_group,
|
||||||
base_net_total, base_grand_total, base_rounded_total, outstanding_amount {0}
|
base_net_total, base_grand_total, base_rounded_total, outstanding_amount,
|
||||||
|
is_internal_customer, represents_company, company {0}
|
||||||
from `tabSales Invoice`
|
from `tabSales Invoice`
|
||||||
where docstatus = 1 %s order by posting_date desc, name desc""".format(additional_query_columns or '') %
|
where docstatus = 1 %s order by posting_date desc, name desc""".format(additional_query_columns or '') %
|
||||||
conditions, filters, as_dict=1)
|
conditions, filters, as_dict=1)
|
||||||
@ -385,6 +415,19 @@ def get_invoice_income_map(invoice_list):
|
|||||||
|
|
||||||
return invoice_income_map
|
return invoice_income_map
|
||||||
|
|
||||||
|
def get_internal_invoice_map(invoice_list):
|
||||||
|
unrealized_amount_details = frappe.db.sql("""SELECT name, unrealized_profit_loss_account,
|
||||||
|
base_net_total as amount from `tabSales Invoice` where name in (%s)
|
||||||
|
and is_internal_customer = 1 and company = represents_company""" %
|
||||||
|
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
|
||||||
|
|
||||||
|
internal_invoice_map = {}
|
||||||
|
for d in unrealized_amount_details:
|
||||||
|
if d.unrealized_profit_loss_account:
|
||||||
|
internal_invoice_map.setdefault((d.name, d.unrealized_profit_loss_account), d.amount)
|
||||||
|
|
||||||
|
return internal_invoice_map
|
||||||
|
|
||||||
def get_invoice_tax_map(invoice_list, invoice_income_map, income_accounts):
|
def get_invoice_tax_map(invoice_list, invoice_income_map, income_accounts):
|
||||||
tax_details = frappe.db.sql("""select parent, account_head,
|
tax_details = frappe.db.sql("""select parent, account_head,
|
||||||
sum(base_tax_amount_after_discount_amount) as tax_amount
|
sum(base_tax_amount_after_discount_amount) as tax_amount
|
||||||
|
@ -164,16 +164,16 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
|
|
||||||
if (doc.docstatus === 1 && !doc.inter_company_order_reference) {
|
if (doc.docstatus === 1 && !doc.inter_company_order_reference) {
|
||||||
let me = this;
|
let me = this;
|
||||||
frappe.model.with_doc("Supplier", me.frm.doc.supplier, () => {
|
let internal = me.frm.doc.is_internal_supplier;
|
||||||
let supplier = frappe.model.get_doc("Supplier", me.frm.doc.supplier);
|
if (internal) {
|
||||||
let internal = supplier.is_internal_supplier;
|
let button_label = (me.frm.doc.company === me.frm.doc.represents_company) ? "Internal Sales Order" :
|
||||||
let disabled = supplier.disabled;
|
"Inter Company Sales Order";
|
||||||
if (internal === 1 && disabled === 0) {
|
|
||||||
me.frm.add_custom_button("Inter Company Order", function() {
|
me.frm.add_custom_button(button_label, function() {
|
||||||
me.make_inter_company_order(me.frm);
|
me.make_inter_company_order(me.frm);
|
||||||
}, __('Create'));
|
}, __('Create'));
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +381,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
material_request_type: "Purchase",
|
material_request_type: "Purchase",
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
status: ["!=", "Stopped"],
|
status: ["!=", "Stopped"],
|
||||||
per_ordered: ["<", 99.99],
|
per_ordered: ["<", 100],
|
||||||
company: me.frm.doc.company
|
company: me.frm.doc.company
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -134,6 +134,8 @@
|
|||||||
"ref_sq",
|
"ref_sq",
|
||||||
"column_break_74",
|
"column_break_74",
|
||||||
"party_account_currency",
|
"party_account_currency",
|
||||||
|
"is_internal_supplier",
|
||||||
|
"represents_company",
|
||||||
"inter_company_order_reference"
|
"inter_company_order_reference"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
@ -1101,13 +1103,28 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "items_col_break",
|
"fieldname": "items_col_break",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fetch_from": "supplier.is_internal_supplier",
|
||||||
|
"fieldname": "is_internal_supplier",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Is Internal Supplier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fetch_from": "supplier.represents_company",
|
||||||
|
"fieldname": "represents_company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Represents Company",
|
||||||
|
"options": "Company",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 105,
|
"idx": 105,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-12-03 16:46:44.229351",
|
"modified": "2021-01-20 22:07:23.487138",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order",
|
"name": "Purchase Order",
|
||||||
|
@ -224,7 +224,7 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
|
|||||||
material_request_type: "Purchase",
|
material_request_type: "Purchase",
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
status: ["!=", "Stopped"],
|
status: ["!=", "Stopped"],
|
||||||
per_ordered: ["<", 99.99],
|
per_ordered: ["<", 100],
|
||||||
company: me.frm.doc.company
|
company: me.frm.doc.company
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -280,7 +280,7 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
|
|||||||
material_request_type: "Purchase",
|
material_request_type: "Purchase",
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
status: ["!=", "Stopped"],
|
status: ["!=", "Stopped"],
|
||||||
per_ordered: ["<", 99.99]
|
per_ordered: ["<", 100]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dialog.hide();
|
dialog.hide();
|
||||||
|
@ -52,7 +52,10 @@ class Supplier(TransactionBase):
|
|||||||
self.validate_internal_supplier()
|
self.validate_internal_supplier()
|
||||||
|
|
||||||
def validate_internal_supplier(self):
|
def validate_internal_supplier(self):
|
||||||
if self.is_internal_supplier and frappe.db.get_value("Supplier", {"represents_company": self.represents_company}, "name"):
|
internal_supplier = frappe.db.get_value("Supplier",
|
||||||
|
{"is_internal_supplier": 1, "represents_company": self.represents_company, "name": ("!=", self.name)}, "name")
|
||||||
|
|
||||||
|
if internal_supplier:
|
||||||
frappe.throw(_("Internal Supplier for company {0} already exists").format(
|
frappe.throw(_("Internal Supplier for company {0} already exists").format(
|
||||||
frappe.bold(self.represents_company)))
|
frappe.bold(self.represents_company)))
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.ext
|
|||||||
material_request_type: "Purchase",
|
material_request_type: "Purchase",
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
status: ["!=", "Stopped"],
|
status: ["!=", "Stopped"],
|
||||||
per_ordered: ["<", 99.99],
|
per_ordered: ["<", 100],
|
||||||
company: me.frm.doc.company
|
company: me.frm.doc.company
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -75,6 +75,9 @@ class AccountsController(TransactionBase):
|
|||||||
self.ensure_supplier_is_not_blocked()
|
self.ensure_supplier_is_not_blocked()
|
||||||
|
|
||||||
self.validate_date_with_fiscal_year()
|
self.validate_date_with_fiscal_year()
|
||||||
|
self.validate_inter_company_reference()
|
||||||
|
|
||||||
|
self.set_incoming_rate()
|
||||||
|
|
||||||
if self.meta.get_field("currency"):
|
if self.meta.get_field("currency"):
|
||||||
self.calculate_taxes_and_totals()
|
self.calculate_taxes_and_totals()
|
||||||
@ -119,6 +122,12 @@ class AccountsController(TransactionBase):
|
|||||||
def before_cancel(self):
|
def before_cancel(self):
|
||||||
validate_einvoice_fields(self)
|
validate_einvoice_fields(self)
|
||||||
|
|
||||||
|
def on_trash(self):
|
||||||
|
# delete sl and gl entries on deletion of transaction
|
||||||
|
if frappe.db.get_single_value('Accounts Settings', 'delete_linked_ledger_entries'):
|
||||||
|
frappe.db.sql("delete from `tabGL Entry` where voucher_type=%s and voucher_no=%s", (self.doctype, self.name))
|
||||||
|
frappe.db.sql("delete from `tabStock Ledger Entry` where voucher_type=%s and voucher_no=%s", (self.doctype, self.name))
|
||||||
|
|
||||||
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"):
|
||||||
@ -206,6 +215,17 @@ class AccountsController(TransactionBase):
|
|||||||
validate_fiscal_year(self.get(date_field), self.fiscal_year, self.company,
|
validate_fiscal_year(self.get(date_field), self.fiscal_year, self.company,
|
||||||
self.meta.get_label(date_field), self)
|
self.meta.get_label(date_field), self)
|
||||||
|
|
||||||
|
def validate_inter_company_reference(self):
|
||||||
|
if self.doctype not in ('Purchase Invoice', 'Purchase Receipt', 'Purchase Order'):
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.is_internal_transfer():
|
||||||
|
if not (self.get('inter_company_reference') or self.get('inter_company_invoice_reference')
|
||||||
|
or self.get('inter_company_order_reference')):
|
||||||
|
msg = _("Internal Sale or Delivery Reference missing. ")
|
||||||
|
msg += _("Please create purchase from internal sale or delivery document itself")
|
||||||
|
frappe.throw(msg, title=_("Internal Sales Reference Missing"))
|
||||||
|
|
||||||
def validate_due_date(self):
|
def validate_due_date(self):
|
||||||
if self.get('is_pos'): return
|
if self.get('is_pos'): return
|
||||||
|
|
||||||
@ -964,9 +984,9 @@ class AccountsController(TransactionBase):
|
|||||||
It will an internal transfer if its an internal customer and representation
|
It will an internal transfer if its an internal customer and representation
|
||||||
company is same as billing company
|
company is same as billing company
|
||||||
"""
|
"""
|
||||||
if self.doctype == 'Sales Invoice':
|
if self.doctype in ('Sales Invoice', 'Delivery Note', 'Sales Order'):
|
||||||
internal_party_field = 'is_internal_customer'
|
internal_party_field = 'is_internal_customer'
|
||||||
else:
|
elif self.doctype in ('Purchase Invoice', 'Purchase Receipt', 'Purchase Order'):
|
||||||
internal_party_field = 'is_internal_supplier'
|
internal_party_field = 'is_internal_supplier'
|
||||||
|
|
||||||
if self.get(internal_party_field) and (self.represents_company == self.company):
|
if self.get(internal_party_field) and (self.represents_company == self.company):
|
||||||
|
@ -44,7 +44,6 @@ class BuyingController(StockController):
|
|||||||
self.validate_items()
|
self.validate_items()
|
||||||
self.set_qty_as_per_stock_uom()
|
self.set_qty_as_per_stock_uom()
|
||||||
self.validate_stock_or_nonstock_items()
|
self.validate_stock_or_nonstock_items()
|
||||||
self.update_tax_category_for_internal_transfer()
|
|
||||||
self.validate_warehouse()
|
self.validate_warehouse()
|
||||||
self.validate_from_warehouse()
|
self.validate_from_warehouse()
|
||||||
self.set_supplier_address()
|
self.set_supplier_address()
|
||||||
@ -100,11 +99,6 @@ class BuyingController(StockController):
|
|||||||
msg = _('Tax Category has been changed to "Total" because all the Items are non-stock items')
|
msg = _('Tax Category has been changed to "Total" because all the Items are non-stock items')
|
||||||
self.update_tax_category(msg)
|
self.update_tax_category(msg)
|
||||||
|
|
||||||
def update_tax_category_for_internal_transfer(self):
|
|
||||||
if self.doctype == 'Purchase Invoice' and self.is_internal_transfer():
|
|
||||||
msg = _('Tax Category has been changed to "Total" as its an internal purchase.')
|
|
||||||
self.update_tax_category(msg)
|
|
||||||
|
|
||||||
def update_tax_category(self, msg):
|
def update_tax_category(self, msg):
|
||||||
tax_for_valuation = [d for d in self.get("taxes")
|
tax_for_valuation = [d for d in self.get("taxes")
|
||||||
if d.category in ["Valuation", "Valuation and Total"]]
|
if d.category in ["Valuation", "Valuation and Total"]]
|
||||||
@ -224,6 +218,48 @@ class BuyingController(StockController):
|
|||||||
else:
|
else:
|
||||||
item.valuation_rate = 0.0
|
item.valuation_rate = 0.0
|
||||||
|
|
||||||
|
def set_incoming_rate(self):
|
||||||
|
if self.doctype not in ("Purchase Receipt", "Purchase Invoice", "Purchase Order"):
|
||||||
|
return
|
||||||
|
|
||||||
|
ref_doctype_map = {
|
||||||
|
"Purchase Order": "Sales Order Item",
|
||||||
|
"Purchase Receipt": "Delivery Note Item",
|
||||||
|
"Purchase Invoice": "Sales Invoice Item",
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_doctype = ref_doctype_map.get(self.doctype)
|
||||||
|
items = self.get("items")
|
||||||
|
for d in items:
|
||||||
|
if not cint(self.get("is_return")):
|
||||||
|
# Get outgoing rate based on original item cost based on valuation method
|
||||||
|
|
||||||
|
if not d.get(frappe.scrub(ref_doctype)):
|
||||||
|
outgoing_rate = get_incoming_rate({
|
||||||
|
"item_code": d.item_code,
|
||||||
|
"warehouse": d.get('from_warehouse'),
|
||||||
|
"posting_date": self.get('posting_date') or self.get('transation_date'),
|
||||||
|
"posting_time": self.get('posting_time'),
|
||||||
|
"qty": -1 * flt(d.get('stock_qty')),
|
||||||
|
"serial_no": d.get('serial_no'),
|
||||||
|
"company": self.company,
|
||||||
|
"voucher_type": self.doctype,
|
||||||
|
"voucher_no": self.name,
|
||||||
|
"allow_zero_valuation": d.get("allow_zero_valuation")
|
||||||
|
}, raise_error_if_no_rate=False)
|
||||||
|
|
||||||
|
rate = flt(outgoing_rate * d.conversion_factor, d.precision('rate'))
|
||||||
|
else:
|
||||||
|
rate = frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), 'rate')
|
||||||
|
|
||||||
|
if self.is_internal_transfer():
|
||||||
|
if rate != d.rate:
|
||||||
|
d.rate = rate
|
||||||
|
d.discount_percentage = 0
|
||||||
|
d.discount_amount = 0
|
||||||
|
frappe.msgprint(_("Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer")
|
||||||
|
.format(d.idx), alert=1)
|
||||||
|
|
||||||
def get_supplied_items_cost(self, item_row_id, reset_outgoing_rate=True):
|
def get_supplied_items_cost(self, item_row_id, reset_outgoing_rate=True):
|
||||||
supplied_items_cost = 0.0
|
supplied_items_cost = 0.0
|
||||||
for d in self.get("supplied_items"):
|
for d in self.get("supplied_items"):
|
||||||
@ -559,6 +595,8 @@ class BuyingController(StockController):
|
|||||||
from_warehouse_sle = self.get_sl_entries(d, {
|
from_warehouse_sle = self.get_sl_entries(d, {
|
||||||
"actual_qty": -1 * pr_qty,
|
"actual_qty": -1 * pr_qty,
|
||||||
"warehouse": d.from_warehouse,
|
"warehouse": d.from_warehouse,
|
||||||
|
"outgoing_rate": d.rate,
|
||||||
|
"recalculate_rate": 1,
|
||||||
"dependant_sle_voucher_detail_no": d.name
|
"dependant_sle_voucher_detail_no": d.name
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import cint, flt, cstr, comma_or, get_link_to_form
|
from frappe.utils import cint, flt, cstr, get_link_to_form, nowtime
|
||||||
from frappe import _, throw
|
from frappe import _, throw
|
||||||
from erpnext.stock.get_item_details import get_bin_details
|
from erpnext.stock.get_item_details import get_bin_details
|
||||||
from erpnext.stock.utils import get_incoming_rate
|
from erpnext.stock.utils import get_incoming_rate
|
||||||
@ -49,7 +49,6 @@ 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.set_incoming_rate()
|
|
||||||
|
|
||||||
def set_missing_values(self, for_validate=False):
|
def set_missing_values(self, for_validate=False):
|
||||||
|
|
||||||
@ -312,7 +311,7 @@ class SellingController(StockController):
|
|||||||
sales_order.update_reserved_qty(so_item_rows)
|
sales_order.update_reserved_qty(so_item_rows)
|
||||||
|
|
||||||
def set_incoming_rate(self):
|
def set_incoming_rate(self):
|
||||||
if self.doctype not in ("Delivery Note", "Sales Invoice"):
|
if self.doctype not in ("Delivery Note", "Sales Invoice", "Sales Order"):
|
||||||
return
|
return
|
||||||
|
|
||||||
items = self.get("items") + (self.get("packed_items") or [])
|
items = self.get("items") + (self.get("packed_items") or [])
|
||||||
@ -322,15 +321,26 @@ class SellingController(StockController):
|
|||||||
d.incoming_rate = get_incoming_rate({
|
d.incoming_rate = get_incoming_rate({
|
||||||
"item_code": d.item_code,
|
"item_code": d.item_code,
|
||||||
"warehouse": d.warehouse,
|
"warehouse": d.warehouse,
|
||||||
"posting_date": self.posting_date,
|
"posting_date": self.get('posting_date') or self.get('transaction_date'),
|
||||||
"posting_time": self.posting_time,
|
"posting_time": self.get('posting_time') or nowtime(),
|
||||||
"qty": -1*flt(d.qty),
|
"qty": -1 * flt(d.get('stock_qty') or d.get('actual_qty')),
|
||||||
"serial_no": d.serial_no,
|
"serial_no": d.get('serial_no'),
|
||||||
"company": self.company,
|
"company": self.company,
|
||||||
"voucher_type": self.doctype,
|
"voucher_type": self.doctype,
|
||||||
"voucher_no": self.name,
|
"voucher_no": self.name,
|
||||||
"allow_zero_valuation": d.get("allow_zero_valuation")
|
"allow_zero_valuation": d.get("allow_zero_valuation")
|
||||||
}, raise_error_if_no_rate=False)
|
}, raise_error_if_no_rate=False)
|
||||||
|
|
||||||
|
# For internal transfers use incoming rate as the valuation rate
|
||||||
|
if self.is_internal_transfer():
|
||||||
|
rate = flt(d.incoming_rate * d.conversion_factor, d.precision('rate'))
|
||||||
|
if d.rate != rate:
|
||||||
|
d.rate = rate
|
||||||
|
d.discount_percentage = 0
|
||||||
|
d.discount_amount = 0
|
||||||
|
frappe.msgprint(_("Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer")
|
||||||
|
.format(d.idx), alert=1)
|
||||||
|
|
||||||
elif self.get("return_against"):
|
elif self.get("return_against"):
|
||||||
# Get incoming rate of return entry from reference document
|
# Get incoming rate of return entry from reference document
|
||||||
# based on original item cost as per valuation method
|
# based on original item cost as per valuation method
|
||||||
|
@ -24,6 +24,7 @@ class StockController(AccountsController):
|
|||||||
self.validate_inspection()
|
self.validate_inspection()
|
||||||
self.validate_serialized_batch()
|
self.validate_serialized_batch()
|
||||||
self.validate_customer_provided_item()
|
self.validate_customer_provided_item()
|
||||||
|
self.validate_internal_transfer()
|
||||||
self.validate_putaway_capacity()
|
self.validate_putaway_capacity()
|
||||||
|
|
||||||
def make_gl_entries(self, gl_entries=None, from_repost=False):
|
def make_gl_entries(self, gl_entries=None, from_repost=False):
|
||||||
@ -74,6 +75,7 @@ class StockController(AccountsController):
|
|||||||
warehouse_with_no_account = []
|
warehouse_with_no_account = []
|
||||||
precision = frappe.get_precision("GL Entry", "debit_in_account_currency")
|
precision = frappe.get_precision("GL Entry", "debit_in_account_currency")
|
||||||
for item_row in voucher_details:
|
for item_row in voucher_details:
|
||||||
|
|
||||||
sle_list = sle_map.get(item_row.name)
|
sle_list = sle_map.get(item_row.name)
|
||||||
if sle_list:
|
if sle_list:
|
||||||
for sle in sle_list:
|
for sle in sle_list:
|
||||||
@ -393,6 +395,32 @@ class StockController(AccountsController):
|
|||||||
if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'):
|
if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'):
|
||||||
d.allow_zero_valuation_rate = 1
|
d.allow_zero_valuation_rate = 1
|
||||||
|
|
||||||
|
def validate_internal_transfer(self):
|
||||||
|
if self.doctype in ('Sales Invoice', 'Delivery Note', 'Purchase Invoice', 'Purchase Receipt') \
|
||||||
|
and self.is_internal_transfer():
|
||||||
|
self.validate_in_transit_warehouses()
|
||||||
|
self.validate_multi_currency()
|
||||||
|
self.validate_packed_items()
|
||||||
|
|
||||||
|
def validate_in_transit_warehouses(self):
|
||||||
|
if (self.doctype == 'Sales Invoice' and self.get('update_stock')) or self.doctype == 'Delivery Note':
|
||||||
|
for item in self.get('items'):
|
||||||
|
if not item.target_warehouse:
|
||||||
|
frappe.throw(_("Row {0}: Target Warehouse is mandatory for internal transfers").format(item.idx))
|
||||||
|
|
||||||
|
if (self.doctype == 'Purchase Invoice' and self.get('update_stock')) or self.doctype == 'Purchase Receipt':
|
||||||
|
for item in self.get('items'):
|
||||||
|
if not item.from_warehouse:
|
||||||
|
frappe.throw(_("Row {0}: From Warehouse is mandatory for internal transfers").format(item.idx))
|
||||||
|
|
||||||
|
def validate_multi_currency(self):
|
||||||
|
if self.currency != self.company_currency:
|
||||||
|
frappe.throw(_("Internal transfers can only be done in company's default currency"))
|
||||||
|
|
||||||
|
def validate_packed_items(self):
|
||||||
|
if self.doctype in ('Sales Invoice', 'Delivery Note Item') and self.get('packed_items'):
|
||||||
|
frappe.throw(_("Packed Items cannot be transferred internally"))
|
||||||
|
|
||||||
def validate_putaway_capacity(self):
|
def validate_putaway_capacity(self):
|
||||||
# if over receipt is attempted while 'apply putaway rule' is disabled
|
# if over receipt is attempted while 'apply putaway rule' is disabled
|
||||||
# and if rule was applied on the transaction, validate it.
|
# and if rule was applied on the transaction, validate it.
|
||||||
|
@ -416,9 +416,6 @@ regional_overrides = {
|
|||||||
'Italy': {
|
'Italy': {
|
||||||
'erpnext.controllers.taxes_and_totals.update_itemised_tax_data': 'erpnext.regional.italy.utils.update_itemised_tax_data',
|
'erpnext.controllers.taxes_and_totals.update_itemised_tax_data': 'erpnext.regional.italy.utils.update_itemised_tax_data',
|
||||||
'erpnext.controllers.accounts_controller.validate_regional': 'erpnext.regional.italy.utils.sales_invoice_validate',
|
'erpnext.controllers.accounts_controller.validate_regional': 'erpnext.regional.italy.utils.sales_invoice_validate',
|
||||||
},
|
|
||||||
'Germany': {
|
|
||||||
'erpnext.controllers.accounts_controller.validate_regional': 'erpnext.regional.germany.accounts_controller.validate_regional',
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
user_privacy_documents = [
|
user_privacy_documents = [
|
||||||
|
@ -88,7 +88,7 @@ def get_events(start, end, filters=None):
|
|||||||
|
|
||||||
def add_assignments(events, start, end, conditions=None):
|
def add_assignments(events, start, end, conditions=None):
|
||||||
query = """select name, start_date, end_date, employee_name,
|
query = """select name, start_date, end_date, employee_name,
|
||||||
employee, docstatus
|
employee, docstatus, shift_type
|
||||||
from `tabShift Assignment` where
|
from `tabShift Assignment` where
|
||||||
start_date >= %(start_date)s
|
start_date >= %(start_date)s
|
||||||
or end_date <= %(end_date)s
|
or end_date <= %(end_date)s
|
||||||
@ -97,19 +97,41 @@ def add_assignments(events, start, end, conditions=None):
|
|||||||
if conditions:
|
if conditions:
|
||||||
query += conditions
|
query += conditions
|
||||||
|
|
||||||
for d in frappe.db.sql(query, {"start_date":start, "end_date":end}, as_dict=True):
|
records = frappe.db.sql(query, {"start_date":start, "end_date":end}, as_dict=True)
|
||||||
|
shift_timing_map = get_shift_type_timing([d.shift_type for d in records])
|
||||||
|
|
||||||
|
for d in records:
|
||||||
|
daily_event_start = d.start_date
|
||||||
|
daily_event_end = d.end_date if d.end_date else getdate()
|
||||||
|
delta = timedelta(days=1)
|
||||||
|
while daily_event_start <= daily_event_end:
|
||||||
|
start_timing = frappe.utils.get_datetime(daily_event_start)+ shift_timing_map[d.shift_type]['start_time']
|
||||||
|
end_timing = frappe.utils.get_datetime(daily_event_start)+ shift_timing_map[d.shift_type]['end_time']
|
||||||
|
daily_event_start += delta
|
||||||
e = {
|
e = {
|
||||||
"name": d.name,
|
"name": d.name,
|
||||||
"doctype": "Shift Assignment",
|
"doctype": "Shift Assignment",
|
||||||
"start_date": d.start_date,
|
"start_date": start_timing,
|
||||||
"end_date": d.end_date if d.end_date else nowdate(),
|
"end_date": end_timing,
|
||||||
"title": cstr(d.employee_name) + ": "+ \
|
"title": cstr(d.employee_name) + ": "+ \
|
||||||
cstr(d.shift_type),
|
cstr(d.shift_type),
|
||||||
"docstatus": d.docstatus
|
"docstatus": d.docstatus,
|
||||||
|
"allDay": 0
|
||||||
}
|
}
|
||||||
if e not in events:
|
if e not in events:
|
||||||
events.append(e)
|
events.append(e)
|
||||||
|
|
||||||
|
return events
|
||||||
|
|
||||||
|
def get_shift_type_timing(shift_types):
|
||||||
|
shift_timing_map = {}
|
||||||
|
data = frappe.get_all("Shift Type", filters = {"name": ("IN", shift_types)}, fields = ['name', 'start_time', 'end_time'])
|
||||||
|
|
||||||
|
for d in data:
|
||||||
|
shift_timing_map[d.name] = d
|
||||||
|
|
||||||
|
return shift_timing_map
|
||||||
|
|
||||||
|
|
||||||
def get_employee_shift(employee, for_date=nowdate(), consider_default_shift=False, next_shift_direction=None):
|
def get_employee_shift(employee, for_date=nowdate(), consider_default_shift=False, next_shift_direction=None):
|
||||||
"""Returns a Shift Type for the given employee on the given date. (excluding the holidays)
|
"""Returns a Shift Type for the given employee on the given date. (excluding the holidays)
|
||||||
|
@ -6,14 +6,8 @@ frappe.views.calendar["Shift Assignment"] = {
|
|||||||
"start": "start_date",
|
"start": "start_date",
|
||||||
"end": "end_date",
|
"end": "end_date",
|
||||||
"id": "name",
|
"id": "name",
|
||||||
"docstatus": 1
|
"docstatus": 1,
|
||||||
},
|
"allDay": "allDay",
|
||||||
options: {
|
|
||||||
header: {
|
|
||||||
left: 'prev,next today',
|
|
||||||
center: 'title',
|
|
||||||
right: 'month'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
get_events_method: "erpnext.hr.doctype.shift_assignment.shift_assignment.get_events"
|
get_events_method: "erpnext.hr.doctype.shift_assignment.shift_assignment.get_events"
|
||||||
}
|
}
|
@ -109,6 +109,14 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
item.warehouse = frm.doc.set_warehouse;
|
item.warehouse = frm.doc.set_warehouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!item.target_warehouse && frm.doc.set_target_warehouse) {
|
||||||
|
item.target_warehouse = frm.doc.set_target_warehouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item.from_warehouse && frm.doc.set_from_warehouse) {
|
||||||
|
item.from_warehouse = frm.doc.set_from_warehouse;
|
||||||
|
}
|
||||||
|
|
||||||
erpnext.accounts.dimensions.copy_dimension_from_first_row(frm, cdt, cdn, 'items');
|
erpnext.accounts.dimensions.copy_dimension_from_first_row(frm, cdt, cdn, 'items');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -227,6 +235,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.frm.trigger('set_default_internal_warehouse');
|
||||||
|
|
||||||
return frappe.run_serially([
|
return frappe.run_serially([
|
||||||
() => set_value('currency', currency),
|
() => set_value('currency', currency),
|
||||||
() => set_value('price_list_currency', currency),
|
() => set_value('price_list_currency', currency),
|
||||||
@ -658,7 +668,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
args: item_args
|
args: item_args
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
frappe.model.set_value(item.doctype, item.name, 'rate', r.message);
|
frappe.model.set_value(item.doctype, item.name, 'rate', r.message * item.conversion_factor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -724,6 +734,31 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
this.calculate_taxes_and_totals(false);
|
this.calculate_taxes_and_totals(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
update_stock: function() {
|
||||||
|
this.frm.trigger('set_default_internal_warehouse');
|
||||||
|
},
|
||||||
|
|
||||||
|
set_default_internal_warehouse: function() {
|
||||||
|
let me = this;
|
||||||
|
if ((this.frm.doc.doctype === 'Sales Invoice' && me.frm.doc.update_stock)
|
||||||
|
|| this.frm.doc.doctype == 'Delivery Note') {
|
||||||
|
if (this.frm.doc.is_internal_customer && this.frm.doc.company === this.frm.doc.represents_company) {
|
||||||
|
frappe.db.get_value('Company', this.frm.doc.company, 'default_in_transit_warehouse', function(value) {
|
||||||
|
me.frm.set_value('set_target_warehouse', value.default_in_transit_warehouse);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((this.frm.doc.doctype === 'Purchase Invoice' && me.frm.doc.update_stock)
|
||||||
|
|| this.frm.doc.doctype == 'Purchase Receipt') {
|
||||||
|
if (this.frm.doc.is_internal_supplier && this.frm.doc.company === this.frm.doc.represents_company) {
|
||||||
|
frappe.db.get_value('Company', this.frm.doc.company, 'default_in_transit_warehouse', function(value) {
|
||||||
|
me.frm.set_value('set_from_warehouse', value.default_in_transit_warehouse);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
company: function() {
|
company: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
var set_pricing = function() {
|
var set_pricing = function() {
|
||||||
@ -810,7 +845,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
in_list(['Purchase Order', 'Purchase Receipt', 'Purchase Invoice'], this.frm.doctype)) {
|
in_list(['Purchase Order', 'Purchase Receipt', 'Purchase Invoice'], this.frm.doctype)) {
|
||||||
erpnext.utils.get_shipping_address(this.frm, function(){
|
erpnext.utils.get_shipping_address(this.frm, function(){
|
||||||
set_party_account(set_pricing);
|
set_party_account(set_pricing);
|
||||||
})
|
});
|
||||||
|
|
||||||
// Get default company billing address in Purchase Invoice, Order and Receipt
|
// Get default company billing address in Purchase Invoice, Order and Receipt
|
||||||
frappe.call({
|
frappe.call({
|
||||||
@ -1977,6 +2012,14 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
this.autofill_warehouse(this.frm.doc.items, "warehouse", this.frm.doc.set_warehouse);
|
this.autofill_warehouse(this.frm.doc.items, "warehouse", this.frm.doc.set_warehouse);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set_target_warehouse: function() {
|
||||||
|
this.autofill_warehouse(this.frm.doc.items, "target_warehouse", this.frm.doc.set_target_warehouse);
|
||||||
|
},
|
||||||
|
|
||||||
|
set_from_warehouse: function() {
|
||||||
|
this.autofill_warehouse(this.frm.doc.items, "from_warehouse", this.frm.doc.set_from_warehouse);
|
||||||
|
},
|
||||||
|
|
||||||
autofill_warehouse : function (child_table, warehouse_field, warehouse) {
|
autofill_warehouse : function (child_table, warehouse_field, warehouse) {
|
||||||
if (warehouse && child_table && child_table.length) {
|
if (warehouse && child_table && child_table.length) {
|
||||||
let doctype = child_table[0].doctype;
|
let doctype = child_table[0].doctype;
|
||||||
|
@ -276,6 +276,12 @@ erpnext.utils.validate_mandatory = function(frm, label, value, trigger_on) {
|
|||||||
|
|
||||||
erpnext.utils.get_shipping_address = function(frm, callback){
|
erpnext.utils.get_shipping_address = function(frm, callback){
|
||||||
if (frm.doc.company) {
|
if (frm.doc.company) {
|
||||||
|
if (!(frm.doc.inter_com_order_reference || frm.doc.internal_invoice_reference ||
|
||||||
|
frm.doc.internal_order_reference)) {
|
||||||
|
if (callback) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.custom.address.get_shipping_address",
|
method: "erpnext.accounts.custom.address.get_shipping_address",
|
||||||
args: {
|
args: {
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
import frappe
|
|
||||||
from frappe import _
|
|
||||||
from frappe import msgprint
|
|
||||||
|
|
||||||
|
|
||||||
REQUIRED_FIELDS = {
|
|
||||||
"Sales Invoice": [
|
|
||||||
{
|
|
||||||
"field_name": "company_address",
|
|
||||||
"regulation": "§ 14 Abs. 4 Nr. 1 UStG"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field_name": "company_tax_id",
|
|
||||||
"regulation": "§ 14 Abs. 4 Nr. 2 UStG"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field_name": "taxes",
|
|
||||||
"regulation": "§ 14 Abs. 4 Nr. 8 UStG"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field_name": "customer_address",
|
|
||||||
"regulation": "§ 14 Abs. 4 Nr. 1 UStG",
|
|
||||||
"condition": "base_grand_total > 250"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def validate_regional(doc):
|
|
||||||
"""Check if required fields for this document are present."""
|
|
||||||
required_fields = REQUIRED_FIELDS.get(doc.doctype)
|
|
||||||
if not required_fields:
|
|
||||||
return
|
|
||||||
|
|
||||||
meta = frappe.get_meta(doc.doctype)
|
|
||||||
field_map = {field.fieldname: field.label for field in meta.fields}
|
|
||||||
|
|
||||||
for field in required_fields:
|
|
||||||
condition = field.get("condition")
|
|
||||||
if condition and not frappe.safe_eval(condition, doc.as_dict()):
|
|
||||||
continue
|
|
||||||
|
|
||||||
field_name = field.get("field_name")
|
|
||||||
regulation = field.get("regulation")
|
|
||||||
if field_name and not doc.get(field_name):
|
|
||||||
missing(field_map.get(field_name), regulation)
|
|
||||||
|
|
||||||
|
|
||||||
def missing(field_label, regulation):
|
|
||||||
"""Notify the user that a required field is missing."""
|
|
||||||
translated_msg = _('Remember to set {field_label}. It is required by {regulation}.', context='Specific for Germany. Example: Remember to set Company Tax ID. It is required by § 14 Abs. 4 Nr. 2 UStG.') # noqa: E501
|
|
||||||
formatted_msg = translated_msg.format(field_label=frappe.bold(_(field_label)), regulation=regulation)
|
|
||||||
msgprint(formatted_msg)
|
|
@ -1,12 +0,0 @@
|
|||||||
import frappe
|
|
||||||
import unittest
|
|
||||||
from erpnext.regional.germany.accounts_controller import validate_regional
|
|
||||||
|
|
||||||
|
|
||||||
class TestAccountsController(unittest.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.sales_invoice = frappe.get_last_doc('Sales Invoice')
|
|
||||||
|
|
||||||
def test_validate_regional(self):
|
|
||||||
validate_regional(self.sales_invoice)
|
|
@ -40,14 +40,12 @@ erpnext.setup_auto_gst_taxation = (doctype) => {
|
|||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(r.message) {
|
if(r.message) {
|
||||||
frm.set_value('taxes_and_charges', r.message.taxes_and_charges);
|
frm.set_value('taxes_and_charges', r.message.taxes_and_charges);
|
||||||
|
frm.set_value('taxes', r.message.taxes);
|
||||||
frm.set_value('place_of_supply', r.message.place_of_supply);
|
frm.set_value('place_of_supply', r.message.place_of_supply);
|
||||||
} else if (frm.doc.is_internal_supplier || frm.doc.is_internal_customer) {
|
|
||||||
frm.set_value('taxes_and_charges', '');
|
|
||||||
frm.set_value('taxes', []);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ def get_regional_address_details(party_details, doctype, company):
|
|||||||
|
|
||||||
if is_internal_transfer(party_details, doctype):
|
if is_internal_transfer(party_details, doctype):
|
||||||
party_details.taxes_and_charges = ''
|
party_details.taxes_and_charges = ''
|
||||||
party_details.taxes = ''
|
party_details.taxes = []
|
||||||
return party_details
|
return party_details
|
||||||
|
|
||||||
if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"):
|
if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"):
|
||||||
|
@ -255,6 +255,7 @@ class Gstr1Report(object):
|
|||||||
|
|
||||||
for item_code, tax_amounts in item_wise_tax_detail.items():
|
for item_code, tax_amounts in item_wise_tax_detail.items():
|
||||||
tax_rate = tax_amounts[0]
|
tax_rate = tax_amounts[0]
|
||||||
|
if tax_rate:
|
||||||
if cgst_or_sgst:
|
if cgst_or_sgst:
|
||||||
tax_rate *= 2
|
tax_rate *= 2
|
||||||
if parent not in self.cgst_sgst_invoices:
|
if parent not in self.cgst_sgst_invoices:
|
||||||
|
@ -84,7 +84,10 @@ class Customer(TransactionBase):
|
|||||||
frappe.throw(_("{0} is not a company bank account").format(frappe.bold(self.default_bank_account)))
|
frappe.throw(_("{0} is not a company bank account").format(frappe.bold(self.default_bank_account)))
|
||||||
|
|
||||||
def validate_internal_customer(self):
|
def validate_internal_customer(self):
|
||||||
if self.is_internal_customer and frappe.db.get_value('Customer', {"represents_company": self.represents_company}, "name"):
|
internal_customer = frappe.db.get_value("Customer",
|
||||||
|
{"is_internal_customer": 1, "represents_company": self.represents_company, "name": ("!=", self.name)}, "name")
|
||||||
|
|
||||||
|
if internal_customer:
|
||||||
frappe.throw(_("Internal Customer for company {0} already exists").format(
|
frappe.throw(_("Internal Customer for company {0} already exists").format(
|
||||||
frappe.bold(self.represents_company)))
|
frappe.bold(self.represents_company)))
|
||||||
|
|
||||||
|
@ -171,8 +171,10 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
|||||||
this.frm.add_custom_button(__('Request for Raw Materials'), () => this.make_raw_material_request(), __('Create'));
|
this.frm.add_custom_button(__('Request for Raw Materials'), () => this.make_raw_material_request(), __('Create'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// make purchase order
|
// Make Purchase Order
|
||||||
|
if (!this.frm.doc.is_internal_customer) {
|
||||||
this.frm.add_custom_button(__('Purchase Order'), () => this.make_purchase_order(), __('Create'));
|
this.frm.add_custom_button(__('Purchase Order'), () => this.make_purchase_order(), __('Create'));
|
||||||
|
}
|
||||||
|
|
||||||
// maintenance
|
// maintenance
|
||||||
if(flt(doc.per_delivered, 2) < 100 && (order_is_maintenance || order_is_a_custom_sale)) {
|
if(flt(doc.per_delivered, 2) < 100 && (order_is_maintenance || order_is_a_custom_sale)) {
|
||||||
@ -193,16 +195,15 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
|||||||
|
|
||||||
if (doc.docstatus === 1 && !doc.inter_company_order_reference) {
|
if (doc.docstatus === 1 && !doc.inter_company_order_reference) {
|
||||||
let me = this;
|
let me = this;
|
||||||
frappe.model.with_doc("Customer", me.frm.doc.customer, () => {
|
let internal = me.frm.doc.is_internal_customer;
|
||||||
let customer = frappe.model.get_doc("Customer", me.frm.doc.customer);
|
if (internal) {
|
||||||
let internal = customer.is_internal_customer;
|
let button_label = (me.frm.doc.company === me.frm.doc.represents_company) ? "Internal Purchase Order" :
|
||||||
let disabled = customer.disabled;
|
"Inter Company Purchase Order";
|
||||||
if (internal === 1 && disabled === 0) {
|
|
||||||
me.frm.add_custom_button("Inter Company Order", function() {
|
me.frm.add_custom_button(button_label, function() {
|
||||||
me.make_inter_company_order();
|
me.make_inter_company_order();
|
||||||
}, __('Create'));
|
}, __('Create'));
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// payment request
|
// payment request
|
||||||
|
@ -107,6 +107,8 @@
|
|||||||
"tc_name",
|
"tc_name",
|
||||||
"terms",
|
"terms",
|
||||||
"more_info",
|
"more_info",
|
||||||
|
"is_internal_customer",
|
||||||
|
"represents_company",
|
||||||
"inter_company_order_reference",
|
"inter_company_order_reference",
|
||||||
"project",
|
"project",
|
||||||
"party_account_currency",
|
"party_account_currency",
|
||||||
@ -1103,7 +1105,8 @@
|
|||||||
"hide_days": 1,
|
"hide_days": 1,
|
||||||
"hide_seconds": 1,
|
"hide_seconds": 1,
|
||||||
"label": "Inter Company Order Reference",
|
"label": "Inter Company Order Reference",
|
||||||
"options": "Purchase Order"
|
"options": "Purchase Order",
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Track this Sales Order against any Project",
|
"description": "Track this Sales Order against any Project",
|
||||||
@ -1455,13 +1458,29 @@
|
|||||||
"hide_seconds": 1,
|
"hide_seconds": 1,
|
||||||
"label": "Skip Delivery Note",
|
"label": "Skip Delivery Note",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fetch_from": "customer.is_internal_customer",
|
||||||
|
"fieldname": "is_internal_customer",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Is Internal Customer",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fetch_from": "customer.represents_company",
|
||||||
|
"fieldname": "represents_company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Represents Company",
|
||||||
|
"options": "Company",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 105,
|
"idx": 105,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-10-30 13:59:18.628077",
|
"modified": "2021-01-20 23:40:39.929296",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Sales Order",
|
"name": "Sales Order",
|
||||||
|
@ -95,15 +95,21 @@ frappe.ui.form.on("Delivery Note", {
|
|||||||
frm.page.set_inner_btn_group_as_primary(__('Create'));
|
frm.page.set_inner_btn_group_as_primary(__('Create'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.docstatus === 1 && frm.doc.is_internal_customer && !frm.doc.inter_company_reference) {
|
if (frm.doc.docstatus == 1 && !frm.doc.inter_company_reference) {
|
||||||
frm.add_custom_button(__('Purchase Receipt'), function() {
|
let internal = me.frm.doc.is_internal_customer;
|
||||||
|
if (internal) {
|
||||||
|
let button_label = (me.frm.doc.company === me.frm.doc.represents_company) ? "Internal Purchase Receipt" :
|
||||||
|
"Inter Company Purchase Receipt";
|
||||||
|
|
||||||
|
me.frm.add_custom_button(button_label, function() {
|
||||||
frappe.model.open_mapped_doc({
|
frappe.model.open_mapped_doc({
|
||||||
method: 'erpnext.stock.doctype.delivery_note.delivery_note.make_inter_company_purchase_receipt',
|
method: 'erpnext.stock.doctype.delivery_note.delivery_note.make_inter_company_purchase_receipt',
|
||||||
frm: frm,
|
frm: frm,
|
||||||
})
|
});
|
||||||
}, __('Create'));
|
}, __('Create'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on("Delivery Note Item", {
|
frappe.ui.form.on("Delivery Note Item", {
|
||||||
@ -297,15 +303,6 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
to_warehouse: function() {
|
|
||||||
let packed_items_table = this.frm.doc["packed_items"];
|
|
||||||
this.autofill_warehouse(this.frm.doc["items"], "target_warehouse", this.frm.doc.to_warehouse);
|
|
||||||
if (packed_items_table && packed_items_table.length) {
|
|
||||||
this.autofill_warehouse(packed_items_table, "target_warehouse", this.frm.doc.to_warehouse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$.extend(cur_frm.cscript, new erpnext.stock.DeliveryNoteController({frm: cur_frm}));
|
$.extend(cur_frm.cscript, new erpnext.stock.DeliveryNoteController({frm: cur_frm}));
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
"sec_warehouse",
|
"sec_warehouse",
|
||||||
"set_warehouse",
|
"set_warehouse",
|
||||||
"col_break_warehouse",
|
"col_break_warehouse",
|
||||||
"to_warehouse",
|
"set_target_warehouse",
|
||||||
"items_section",
|
"items_section",
|
||||||
"scan_barcode",
|
"scan_barcode",
|
||||||
"items",
|
"items",
|
||||||
@ -117,6 +117,7 @@
|
|||||||
"source",
|
"source",
|
||||||
"column_break5",
|
"column_break5",
|
||||||
"is_internal_customer",
|
"is_internal_customer",
|
||||||
|
"represents_company",
|
||||||
"inter_company_reference",
|
"inter_company_reference",
|
||||||
"per_billed",
|
"per_billed",
|
||||||
"customer_group",
|
"customer_group",
|
||||||
@ -502,18 +503,6 @@
|
|||||||
"fieldname": "col_break_warehouse",
|
"fieldname": "col_break_warehouse",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"description": "Required only for sample item.",
|
|
||||||
"fieldname": "to_warehouse",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"in_standard_filter": 1,
|
|
||||||
"label": "To Warehouse",
|
|
||||||
"no_copy": 1,
|
|
||||||
"oldfieldname": "to_warehouse",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "Warehouse",
|
|
||||||
"print_hide": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "items_section",
|
"fieldname": "items_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
@ -1261,13 +1250,34 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval: doc.is_internal_customer",
|
||||||
|
"fieldname": "set_target_warehouse",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Set Target Warehouse",
|
||||||
|
"no_copy": 1,
|
||||||
|
"oldfieldname": "to_warehouse",
|
||||||
|
"oldfieldtype": "Link",
|
||||||
|
"options": "Warehouse",
|
||||||
|
"print_hide": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Company which internal customer represents.",
|
||||||
|
"fetch_from": "customer.represents_company",
|
||||||
|
"fieldname": "represents_company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Represents Company",
|
||||||
|
"options": "Company",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-truck",
|
"icon": "fa fa-truck",
|
||||||
"idx": 146,
|
"idx": 146,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-11-30 12:54:45.407289",
|
"modified": "2020-12-26 17:07:59.194403",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Delivery Note",
|
"name": "Delivery Note",
|
||||||
|
@ -664,7 +664,8 @@ def make_inter_company_purchase_receipt(source_name, target_doc=None):
|
|||||||
return make_inter_company_transaction("Delivery Note", source_name, target_doc)
|
return make_inter_company_transaction("Delivery Note", source_name, target_doc)
|
||||||
|
|
||||||
def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
||||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_transaction, get_inter_company_details
|
from erpnext.accounts.doctype.sales_invoice.sales_invoice import (validate_inter_company_transaction,
|
||||||
|
get_inter_company_details, update_address, update_taxes, set_purchase_references)
|
||||||
|
|
||||||
if doctype == 'Delivery Note':
|
if doctype == 'Delivery Note':
|
||||||
source_doc = frappe.get_doc(doctype, source_name)
|
source_doc = frappe.get_doc(doctype, source_name)
|
||||||
@ -682,6 +683,7 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
|||||||
|
|
||||||
def set_missing_values(source, target):
|
def set_missing_values(source, target):
|
||||||
target.run_method("set_missing_values")
|
target.run_method("set_missing_values")
|
||||||
|
set_purchase_references(target)
|
||||||
|
|
||||||
if target.doctype == 'Purchase Receipt':
|
if target.doctype == 'Purchase Receipt':
|
||||||
master_doctype = 'Purchase Taxes and Charges Template'
|
master_doctype = 'Purchase Taxes and Charges Template'
|
||||||
@ -697,20 +699,34 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
|||||||
if target_doc.doctype == 'Purchase Receipt':
|
if target_doc.doctype == 'Purchase Receipt':
|
||||||
target_doc.company = details.get("company")
|
target_doc.company = details.get("company")
|
||||||
target_doc.supplier = details.get("party")
|
target_doc.supplier = details.get("party")
|
||||||
target_doc.supplier_address = source_doc.company_address
|
|
||||||
target_doc.shipping_address = source_doc.shipping_address_name or source_doc.customer_address
|
|
||||||
target_doc.buying_price_list = source_doc.selling_price_list
|
target_doc.buying_price_list = source_doc.selling_price_list
|
||||||
target_doc.is_internal_supplier = 1
|
target_doc.is_internal_supplier = 1
|
||||||
target_doc.inter_company_reference = source_doc.name
|
target_doc.inter_company_reference = source_doc.name
|
||||||
|
|
||||||
|
# Invert the address on target doc creation
|
||||||
|
update_address(target_doc, 'supplier_address', 'address_display', source_doc.company_address)
|
||||||
|
update_address(target_doc, 'shipping_address', 'shipping_address_display', source_doc.customer_address)
|
||||||
|
|
||||||
|
update_taxes(target_doc, party=target_doc.supplier, party_type='Supplier', company=target_doc.company,
|
||||||
|
doctype=target_doc.doctype, party_address=target_doc.supplier_address,
|
||||||
|
company_address=target_doc.shipping_address)
|
||||||
else:
|
else:
|
||||||
target_doc.company = details.get("company")
|
target_doc.company = details.get("company")
|
||||||
target_doc.customer = details.get("party")
|
target_doc.customer = details.get("party")
|
||||||
target_doc.company_address = source_doc.supplier_address
|
target_doc.company_address = source_doc.supplier_address
|
||||||
target_doc.shipping_address_name = source_doc.shipping_address
|
|
||||||
target_doc.selling_price_list = source_doc.buying_price_list
|
target_doc.selling_price_list = source_doc.buying_price_list
|
||||||
target_doc.is_internal_customer = 1
|
target_doc.is_internal_customer = 1
|
||||||
target_doc.inter_company_reference = source_doc.name
|
target_doc.inter_company_reference = source_doc.name
|
||||||
|
|
||||||
|
# Invert the address on target doc creation
|
||||||
|
update_address(target_doc, 'company_address', 'company_address_display', source_doc.supplier_address)
|
||||||
|
update_address(target_doc, 'shipping_address_name', 'shipping_address', source_doc.shipping_address)
|
||||||
|
update_address(target_doc, 'customer_address', 'address_display', source_doc.shipping_address)
|
||||||
|
|
||||||
|
update_taxes(target_doc, party=target_doc.customer, party_type='Customer', company=target_doc.company,
|
||||||
|
doctype=target_doc.doctype, party_address=target_doc.customer_address,
|
||||||
|
company_address=target_doc.company_address, shipping_address_name=target_doc.shipping_address_name)
|
||||||
|
|
||||||
doclist = get_mapped_doc(doctype, source_name, {
|
doclist = get_mapped_doc(doctype, source_name, {
|
||||||
doctype: {
|
doctype: {
|
||||||
"doctype": target_doctype,
|
"doctype": target_doctype,
|
||||||
@ -722,7 +738,10 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
|||||||
doctype +" Item": {
|
doctype +" Item": {
|
||||||
"doctype": target_doctype + " Item",
|
"doctype": target_doctype + " Item",
|
||||||
"field_map": {
|
"field_map": {
|
||||||
source_document_warehouse_field: target_document_warehouse_field
|
source_document_warehouse_field: target_document_warehouse_field,
|
||||||
|
'name': 'delivery_note_item',
|
||||||
|
'batch_no': 'batch_no',
|
||||||
|
'serial_no': 'serial_no'
|
||||||
},
|
},
|
||||||
"field_no_map": [
|
"field_no_map": [
|
||||||
"warehouse"
|
"warehouse"
|
||||||
|
@ -458,7 +458,7 @@
|
|||||||
"fieldname": "warehouse",
|
"fieldname": "warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "From Warehouse",
|
"label": "Warehouse",
|
||||||
"oldfieldname": "warehouse",
|
"oldfieldname": "warehouse",
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Warehouse",
|
"options": "Warehouse",
|
||||||
@ -467,11 +467,12 @@
|
|||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:parent.is_internal_customer",
|
||||||
"fieldname": "target_warehouse",
|
"fieldname": "target_warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"ignore_user_permissions": 1,
|
"ignore_user_permissions": 1,
|
||||||
"label": "Customer Warehouse (Optional)",
|
"label": "Target Warehouse",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Warehouse",
|
"options": "Warehouse",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
@ -748,7 +749,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-12-07 19:59:27.119856",
|
"modified": "2020-12-26 17:31:27.029803",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Delivery Note Item",
|
"name": "Delivery Note Item",
|
||||||
|
@ -106,9 +106,9 @@
|
|||||||
"item_tax_section_break",
|
"item_tax_section_break",
|
||||||
"taxes",
|
"taxes",
|
||||||
"inspection_criteria",
|
"inspection_criteria",
|
||||||
|
"quality_inspection_template",
|
||||||
"inspection_required_before_purchase",
|
"inspection_required_before_purchase",
|
||||||
"inspection_required_before_delivery",
|
"inspection_required_before_delivery",
|
||||||
"quality_inspection_template",
|
|
||||||
"manufacturing",
|
"manufacturing",
|
||||||
"default_bom",
|
"default_bom",
|
||||||
"is_sub_contracted_item",
|
"is_sub_contracted_item",
|
||||||
@ -814,7 +814,6 @@
|
|||||||
"label": "Inspection Required before Delivery"
|
"label": "Inspection Required before Delivery"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:(doc.inspection_required_before_purchase || doc.inspection_required_before_delivery)",
|
|
||||||
"fieldname": "quality_inspection_template",
|
"fieldname": "quality_inspection_template",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Quality Inspection Template",
|
"label": "Quality Inspection Template",
|
||||||
@ -1069,7 +1068,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"max_attachments": 1,
|
"max_attachments": 1,
|
||||||
"modified": "2020-08-07 14:24:58.384992",
|
"modified": "2021-01-25 20:49:50.222976",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item",
|
"name": "Item",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
frappe.listview_settings['Material Request'] = {
|
frappe.listview_settings['Material Request'] = {
|
||||||
add_fields: ["material_request_type", "status", "per_ordered", "per_received", "transfer_status"],
|
add_fields: ["material_request_type", "status", "per_ordered", "per_received", "transfer_status"],
|
||||||
get_indicator: function(doc) {
|
get_indicator: function(doc) {
|
||||||
|
var precision = frappe.defaults.get_default("float_precision");
|
||||||
if (doc.status=="Stopped") {
|
if (doc.status=="Stopped") {
|
||||||
return [__("Stopped"), "red", "status,=,Stopped"];
|
return [__("Stopped"), "red", "status,=,Stopped"];
|
||||||
} else if (doc.transfer_status && doc.docstatus != 2) {
|
} else if (doc.transfer_status && doc.docstatus != 2) {
|
||||||
@ -11,14 +12,14 @@ frappe.listview_settings['Material Request'] = {
|
|||||||
} else if (doc.transfer_status == "Completed") {
|
} else if (doc.transfer_status == "Completed") {
|
||||||
return [__("Completed"), "green"];
|
return [__("Completed"), "green"];
|
||||||
}
|
}
|
||||||
} else if(doc.docstatus==1 && flt(doc.per_ordered, 2) == 0) {
|
} else if (doc.docstatus==1 && flt(doc.per_ordered, precision) == 0) {
|
||||||
return [__("Pending"), "orange", "per_ordered,=,0"];
|
return [__("Pending"), "orange", "per_ordered,=,0"];
|
||||||
} else if(doc.docstatus==1 && flt(doc.per_ordered, 2) < 100) {
|
} else if (doc.docstatus==1 && flt(doc.per_ordered, precision) < 100) {
|
||||||
return [__("Partially ordered"), "yellow", "per_ordered,<,100"];
|
return [__("Partially ordered"), "yellow", "per_ordered,<,100"];
|
||||||
} else if(doc.docstatus==1 && flt(doc.per_ordered, 2) == 100) {
|
} else if (doc.docstatus==1 && flt(doc.per_ordered, precision) == 100) {
|
||||||
if (doc.material_request_type == "Purchase" && flt(doc.per_received, 2) < 100 && flt(doc.per_received, 2) > 0) {
|
if (doc.material_request_type == "Purchase" && flt(doc.per_received, precision) < 100 && flt(doc.per_received, precision) > 0) {
|
||||||
return [__("Partially Received"), "yellow", "per_received,<,100"];
|
return [__("Partially Received"), "yellow", "per_received,<,100"];
|
||||||
} else if (doc.material_request_type == "Purchase" && flt(doc.per_received, 2) == 100) {
|
} else if (doc.material_request_type == "Purchase" && flt(doc.per_received, precision) == 100) {
|
||||||
return [__("Received"), "green", "per_received,=,100"];
|
return [__("Received"), "green", "per_received,=,100"];
|
||||||
} else if (doc.material_request_type == "Purchase") {
|
} else if (doc.material_request_type == "Purchase") {
|
||||||
return [__("Ordered"), "green", "per_ordered,=,100"];
|
return [__("Ordered"), "green", "per_ordered,=,100"];
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
"set_warehouse",
|
"set_warehouse",
|
||||||
"rejected_warehouse",
|
"rejected_warehouse",
|
||||||
"col_break_warehouse",
|
"col_break_warehouse",
|
||||||
|
"set_from_warehouse",
|
||||||
"is_subcontracted",
|
"is_subcontracted",
|
||||||
"supplier_warehouse",
|
"supplier_warehouse",
|
||||||
"items_section",
|
"items_section",
|
||||||
@ -115,6 +116,7 @@
|
|||||||
"per_returned",
|
"per_returned",
|
||||||
"is_internal_supplier",
|
"is_internal_supplier",
|
||||||
"inter_company_reference",
|
"inter_company_reference",
|
||||||
|
"represents_company",
|
||||||
"subscription_detail",
|
"subscription_detail",
|
||||||
"auto_repeat",
|
"auto_repeat",
|
||||||
"printing_settings",
|
"printing_settings",
|
||||||
@ -1087,7 +1089,9 @@
|
|||||||
"fieldname": "inter_company_reference",
|
"fieldname": "inter_company_reference",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Inter Company Reference",
|
"label": "Inter Company Reference",
|
||||||
|
"no_copy": 1,
|
||||||
"options": "Delivery Note",
|
"options": "Delivery Note",
|
||||||
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1121,13 +1125,29 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval: doc.is_internal_supplier",
|
||||||
|
"description": "Sets 'From Warehouse' in each row of the items table.",
|
||||||
|
"fieldname": "set_from_warehouse",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Set From Warehouse",
|
||||||
|
"options": "Warehouse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fetch_from": "supplier.represents_company",
|
||||||
|
"fieldname": "represents_company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Represents Company",
|
||||||
|
"options": "Company",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-truck",
|
"icon": "fa fa-truck",
|
||||||
"idx": 261,
|
"idx": 261,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-12-08 18:31:32.234503",
|
"modified": "2020-12-26 20:49:39.106049",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Purchase Receipt",
|
"name": "Purchase Receipt",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"purchase_order_item",
|
"purchase_order_item",
|
||||||
"material_request_item",
|
"material_request_item",
|
||||||
"purchase_receipt_item",
|
"purchase_receipt_item",
|
||||||
|
"delivery_note_item",
|
||||||
"putaway_rule",
|
"putaway_rule",
|
||||||
"section_break_45",
|
"section_break_45",
|
||||||
"allow_zero_valuation_rate",
|
"allow_zero_valuation_rate",
|
||||||
@ -819,11 +820,12 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:parent.is_internal_supplier",
|
||||||
"fieldname": "from_warehouse",
|
"fieldname": "from_warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"ignore_user_permissions": 1,
|
"ignore_user_permissions": 1,
|
||||||
"label": "Supplier Warehouse",
|
"label": "From Warehouse",
|
||||||
"options": "Warehouse"
|
"options": "Warehouse"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -871,12 +873,20 @@
|
|||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Received Qty in Stock UOM",
|
"label": "Received Qty in Stock UOM",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "delivery_note_item",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Delivery Note Item",
|
||||||
|
"no_copy": 1,
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-12-09 10:00:38.204294",
|
"modified": "2020-12-26 16:50:56.479347",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Purchase Receipt Item",
|
"name": "Purchase Receipt Item",
|
||||||
|
@ -7,6 +7,14 @@ frappe.provide("erpnext.accounts.dimensions");
|
|||||||
|
|
||||||
frappe.ui.form.on('Stock Entry', {
|
frappe.ui.form.on('Stock Entry', {
|
||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
|
frm.set_indicator_formatter('item_code', function(doc) {
|
||||||
|
if (!doc.s_warehouse) {
|
||||||
|
return 'blue';
|
||||||
|
} else {
|
||||||
|
return (doc.qty<=doc.actual_qty) ? 'green' : 'orange';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
frm.set_query('work_order', function() {
|
frm.set_query('work_order', function() {
|
||||||
return {
|
return {
|
||||||
filters: [
|
filters: [
|
||||||
@ -782,15 +790,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.frm.set_indicator_formatter('item_code',
|
|
||||||
function(doc) {
|
|
||||||
if (!doc.s_warehouse) {
|
|
||||||
return 'blue';
|
|
||||||
} else {
|
|
||||||
return (doc.qty<=doc.actual_qty) ? "green" : "orange"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
this.frm.add_fetch("purchase_order", "supplier", "supplier");
|
this.frm.add_fetch("purchase_order", "supplier", "supplier");
|
||||||
|
|
||||||
frappe.dynamic_link = { doc: this.frm.doc, fieldname: 'supplier', doctype: 'Supplier' }
|
frappe.dynamic_link = { doc: this.frm.doc, fieldname: 'supplier', doctype: 'Supplier' }
|
||||||
|
@ -487,7 +487,6 @@ class update_entries_after(object):
|
|||||||
self.wh_data.valuation_rate = new_stock_value / new_stock_qty
|
self.wh_data.valuation_rate = new_stock_value / new_stock_qty
|
||||||
else:
|
else:
|
||||||
self.wh_data.valuation_rate = sle.outgoing_rate
|
self.wh_data.valuation_rate = sle.outgoing_rate
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if flt(self.wh_data.qty_after_transaction) >= 0 and sle.outgoing_rate:
|
if flt(self.wh_data.qty_after_transaction) >= 0 and sle.outgoing_rate:
|
||||||
self.wh_data.valuation_rate = sle.outgoing_rate
|
self.wh_data.valuation_rate = sle.outgoing_rate
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
<div class="col-md-{{ section.column_value }} mb-4">
|
<div class="col-md-{{ section.column_value }} mb-4">
|
||||||
<div class="card h-100 justify-content-between">
|
<div class="card h-100 justify-content-between">
|
||||||
{% if card.image %}
|
{% if card.image %}
|
||||||
<div class="website-image-lazy" data-class="card-img-top h-100" data-src="{{ card.image }}" data-alt="{{ card.title }}"></div>
|
<div class="website-image-lazy" data-class="card-img-top h-75" data-src="{{ card.image }}" data-alt="{{ card.title }}"></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">{{ card.title }}</h5>
|
<h5 class="card-title">{{ card.title }}</h5>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user