diff --git a/av_tools/av_tools/doctype/delivery_exchange_item/__init__.py b/av_tools/av_tools/doctype/delivery_exchange_item/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/av_tools/av_tools/doctype/delivery_exchange_item/delivery_exchange_item.js b/av_tools/av_tools/doctype/delivery_exchange_item/delivery_exchange_item.js
new file mode 100644
index 0000000..496388a
--- /dev/null
+++ b/av_tools/av_tools/doctype/delivery_exchange_item/delivery_exchange_item.js
@@ -0,0 +1,78 @@
+// Copyright (c) 2024, Aakvatech and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Delivery Exchange Item', {
+ refresh: (frm) => {
+ frm.set_query("item_exchange", "stock_items", function () {
+ var data = {
+ filters: {
+ 'is_stock_item': 1,
+ }
+ };
+ return data
+ });
+ frm.set_query("item_exchange", "non_stock_items", function () {
+ var data = {
+ filters: {
+ 'is_stock_item': 0,
+ }
+ };
+ return data
+ });
+ },
+
+ ref_docname: (frm) => {
+ if (frm.doc.ref_docname) {
+ fetch_item_details(frm)
+ }
+ }
+
+});
+
+function fetch_item_details(frm) {
+ frappe.call({
+ method: 'av_tools.av_tools.doctype.delivery_exchange_item.delivery_exchange_item.get_item_details',
+ args: {
+ 'doctype': frm.doc.ref_doctype,
+ 'doctype_id': frm.doc.ref_docname,
+ 'packed': false,
+ // 'item_code': row.item_sold_or_delivered,
+ },
+ callback: function (r) {
+ if (!r.exc) {
+ console.log(r.message);
+ frm.doc.stock_items = []
+ frm.doc.non_stock_items = []
+ frm.refresh_field("stock_items");
+ frm.refresh_field("non_stock_items");
+ for (let d of r.message) {
+ if (d.is_stock_item) {
+ let row = frm.add_child("stock_items", {
+ "item_sold_or_delivered": d.item_code,
+ "amount_exchange": d.amount,
+ "warehouse": d.warehouse,
+ "qty_sold_or_delivered": d.qty,
+ "rate_sold_or_delivered": d.rate,
+ "uom": d.uom,
+ "amount_sold_or_delivered": d.amount,
+ });
+ } else {
+ let row = frm.add_child("non_stock_items", {
+ "item_sold_or_delivered": d.item_code,
+ "amount_exchange": d.amount,
+ "warehouse": d.warehouse,
+ "qty_sold_or_delivered": d.qty,
+ "rate_sold_or_delivered": d.rate,
+ "uom": d.uom,
+ "amount_sold_or_delivered": d.amount,
+ });
+ }
+
+ frm.refresh_field("stock_items");
+ frm.refresh_field("non_stock_items");
+ }
+ }
+ }
+ });
+}
+
diff --git a/av_tools/av_tools/doctype/delivery_exchange_item/delivery_exchange_item.json b/av_tools/av_tools/doctype/delivery_exchange_item/delivery_exchange_item.json
new file mode 100644
index 0000000..e3af29f
--- /dev/null
+++ b/av_tools/av_tools/doctype/delivery_exchange_item/delivery_exchange_item.json
@@ -0,0 +1,121 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "format:DEI-{YYYY}-{####}",
+ "creation": "2024-01-02 11:08:07.241357",
+ "default_view": "List",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "company",
+ "section_break_5c7ku",
+ "ref_doctype",
+ "column_break_4tsfy",
+ "ref_docname",
+ "section_break_cslzt",
+ "stock_items",
+ "non_stock_items",
+ "section_break_ade0i",
+ "remarks",
+ "column_break_qw1gs",
+ "amended_from"
+ ],
+ "fields": [
+ {
+ "fieldname": "column_break_4tsfy",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "section_break_cslzt",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Company",
+ "options": "Company",
+ "reqd": 1
+ },
+ {
+ "fieldname": "section_break_5c7ku",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "remarks",
+ "fieldtype": "Text",
+ "label": "Remarks",
+ "max_height": "60px"
+ },
+ {
+ "fieldname": "column_break_qw1gs",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "section_break_ade0i",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "stock_items",
+ "fieldtype": "Table",
+ "label": "Stock Items",
+ "options": "Delivery Exchange Item Details"
+ },
+ {
+ "fieldname": "non_stock_items",
+ "fieldtype": "Table",
+ "label": "Non Stock Items",
+ "options": "Delivery Exchange Non Stock Item Details"
+ },
+ {
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "label": "Amended From",
+ "no_copy": 1,
+ "options": "Delivery Exchange Item",
+ "print_hide": 1,
+ "read_only": 1
+ },
+ {
+ "fieldname": "ref_doctype",
+ "fieldtype": "Select",
+ "label": "Reference Doctype",
+ "options": "Sales Invoice\nDelivery Note"
+ },
+ {
+ "fieldname": "ref_docname",
+ "fieldtype": "Dynamic Link",
+ "in_list_view": 1,
+ "label": "Reference Docname",
+ "options": "ref_doctype",
+ "reqd": 1
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2024-09-23 12:38:40.465860",
+ "modified_by": "Administrator",
+ "module": "Av Tools",
+ "name": "Delivery Exchange Item",
+ "naming_rule": "Expression",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "share": 1,
+ "write": 1
+ }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
diff --git a/av_tools/av_tools/doctype/delivery_exchange_item/delivery_exchange_item.py b/av_tools/av_tools/doctype/delivery_exchange_item/delivery_exchange_item.py
new file mode 100644
index 0000000..b763976
--- /dev/null
+++ b/av_tools/av_tools/doctype/delivery_exchange_item/delivery_exchange_item.py
@@ -0,0 +1,123 @@
+# Copyright (c) 2024, Aakvatech and contributors
+# For license information, please see license.txt
+
+import frappe
+from frappe.model.document import Document
+from frappe.utils import flt, today
+
+
+class DeliveryExchangeItem(Document):
+ def validate(self):
+ msg = ""
+
+ for index, row in enumerate(self.stock_items):
+ table_name = self.stock_items[0].parentfield.replace("_", " ").title()
+ validate = get_item_details(
+ self.ref_doctype, self.ref_docname, item_code=row.item_sold_or_delivered
+ )
+ if not validate:
+ msg += f"In table {table_name}, Row {index + 1}, Item {row.item_sold_or_delivered} does not exist in {self.ref_doctype} {self.ref_docname} "
+ item_exchange_rate = frappe.db.get_value(
+ "Item Price",
+ {
+ "price_list": validate[0].selling_price_list,
+ "item_code": row.item_exchange,
+ },
+ "price_list_rate",
+ )
+ if (flt(item_exchange_rate) * flt(row.qty_sold_or_delivered)) != flt(
+ row.amount_sold_or_delivered
+ ):
+ msg += f"In table {table_name}, Row {index + 1}, Amounts for Item {row.item_sold_or_delivered} and {row.item_exchange} do not match at selling rate {validate[0].selling_price_list}"
+
+ for index, row in enumerate(self.non_stock_items):
+ table_name = self.non_stock_items[0].parentfield.replace("_", " ").title()
+ validate = get_item_details(
+ self.ref_doctype, self.ref_docname, item_code=row.item_sold_or_delivered
+ )
+ if not validate:
+ msg += f"In table {table_name}, Row {index + 1}, Item {row.item_sold_or_delivered} does not exist in {self.ref_doctype} {self.ref_docname} "
+ item_exchange_rate = frappe.db.get_value(
+ "Item Price",
+ {
+ "price_list": validate[0].selling_price_list,
+ "item_code": row.item_exchange,
+ },
+ "price_list_rate",
+ )
+ if (flt(item_exchange_rate) * flt(row.qty_sold_or_delivered)) != flt(
+ row.amount_sold_or_delivered
+ ):
+ msg += f"In table {table_name}, Row {index + 1}, Amounts for Item {row.item_sold_or_delivered} and {row.item_exchange} do not match at selling rate {validate[0].selling_price_list}"
+
+ if msg:
+ frappe.throw(f"{msg}")
+
+ def on_submit(self):
+ stock_items = []
+ if len(self.stock_items) > 0:
+ for row in self.stock_items:
+ stock_items.append(
+ {
+ "s_warehouse": row.warehouse,
+ "t_warehouse": "",
+ "item_code": row.item_exchange,
+ "qty": row.qty_sold_or_delivered,
+ "basic_rate": row.rate_sold_or_delivered,
+ "uom": row.uom,
+ }
+ )
+ stock_items.append(
+ {
+ "s_warehouse": "",
+ "t_warehouse": row.warehouse,
+ "item_code": row.item_sold_or_delivered,
+ "qty": row.qty_sold_or_delivered,
+ "basic_rate": row.rate_sold_or_delivered,
+ "set_basic_rate_manually": 1,
+ "uom": row.uom,
+ "basic_amount": row.amount_sold_or_delivered,
+ }
+ )
+ doc = frappe.get_doc(
+ {
+ "doctype": "Stock Entry",
+ "company": self.company,
+ "stock_entry_type": "Delivery Exchange",
+ "posting_date": today(),
+ "items": stock_items,
+ # "ref_doctype": self.doctype,
+ # "ref_docname": self.name,
+ }
+ )
+ doc.insert(ignore_permissions=True)
+
+
+@frappe.whitelist()
+def get_item_details(doctype, doctype_id, item_code=None):
+ condition = ""
+ if item_code:
+ condition += f"AND cdt.item_code = '{item_code}'"
+
+ return frappe.db.sql(
+ f"""
+ SELECT
+ cdt.item_code,
+ cdt.amount,
+ cdt.warehouse,
+ cdt.qty,
+ cdt.rate,
+ cdt.uom,
+ pdt.selling_price_list,
+ i.is_stock_item
+ FROM `tab{doctype}` pdt
+ INNER JOIN `tab{doctype} Item` cdt
+ ON pdt.name = cdt.parent
+ INNER JOIN `tabItem` i
+ ON i.name = cdt.item_code
+ WHERE pdt.name = '{doctype_id}'
+
+ {condition}
+ """,
+ as_dict=1,
+ )
diff --git a/av_tools/av_tools/doctype/delivery_exchange_item/test_delivery_exchange_item.py b/av_tools/av_tools/doctype/delivery_exchange_item/test_delivery_exchange_item.py
new file mode 100644
index 0000000..931c9ab
--- /dev/null
+++ b/av_tools/av_tools/doctype/delivery_exchange_item/test_delivery_exchange_item.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2024, Aakvatech and Contributors
+# See license.txt
+
+# import frappe
+from frappe.tests.utils import FrappeTestCase
+
+
+class TestDeliveryExchangeItem(FrappeTestCase):
+ pass
diff --git a/av_tools/av_tools/doctype/delivery_exchange_item_details/__init__.py b/av_tools/av_tools/doctype/delivery_exchange_item_details/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/av_tools/av_tools/doctype/delivery_exchange_item_details/delivery_exchange_item_details.json b/av_tools/av_tools/doctype/delivery_exchange_item_details/delivery_exchange_item_details.json
new file mode 100644
index 0000000..254adfb
--- /dev/null
+++ b/av_tools/av_tools/doctype/delivery_exchange_item_details/delivery_exchange_item_details.json
@@ -0,0 +1,105 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2024-01-02 11:18:19.135187",
+ "default_view": "List",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "item_sold_or_delivered",
+ "rate_sold_or_delivered",
+ "qty_sold_or_delivered",
+ "amount_sold_or_delivered",
+ "warehouse",
+ "column_break_frc89",
+ "item_exchange",
+ "amount_exchange",
+ "uom",
+ "amended_from"
+ ],
+ "fields": [
+ {
+ "fieldname": "item_sold_or_delivered",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Item Sold/Delivered",
+ "options": "Item",
+ "read_only": 1
+ },
+ {
+ "fieldname": "amount_sold_or_delivered",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Amount Sold/Delivered ",
+ "read_only": 1
+ },
+ {
+ "fieldname": "item_exchange",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Item Exchange",
+ "options": "Item",
+ "reqd": 1
+ },
+ {
+ "fieldname": "amount_exchange",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Amount Exchange",
+ "read_only": 1
+ },
+ {
+ "fieldname": "warehouse",
+ "fieldtype": "Link",
+ "label": "Warehouse",
+ "options": "Warehouse",
+ "read_only": 1
+ },
+ {
+ "fieldname": "rate_sold_or_delivered",
+ "fieldtype": "Data",
+ "label": "Rate Sold/Delivered",
+ "read_only": 1
+ },
+ {
+ "fieldname": "qty_sold_or_delivered",
+ "fieldtype": "Data",
+ "label": "Qty Sold/Delivered",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_frc89",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "uom",
+ "fieldtype": "Link",
+ "label": "UOM",
+ "options": "UOM",
+ "read_only": 1
+ },
+ {
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "label": "Amended From",
+ "no_copy": 1,
+ "options": "Delivery Exchange Item Details",
+ "print_hide": 1,
+ "read_only": 1
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "is_submittable": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2024-01-08 17:30:11.929988",
+ "modified_by": "Administrator",
+ "module": "Av Tools",
+ "name": "Delivery Exchange Item Details",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
diff --git a/av_tools/av_tools/doctype/delivery_exchange_item_details/delivery_exchange_item_details.py b/av_tools/av_tools/doctype/delivery_exchange_item_details/delivery_exchange_item_details.py
new file mode 100644
index 0000000..5100aca
--- /dev/null
+++ b/av_tools/av_tools/doctype/delivery_exchange_item_details/delivery_exchange_item_details.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2024, Aakvatech and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+class DeliveryExchangeItemDetails(Document):
+ pass
diff --git a/av_tools/av_tools/doctype/delivery_exchange_non_stock_item_details/__init__.py b/av_tools/av_tools/doctype/delivery_exchange_non_stock_item_details/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/av_tools/av_tools/doctype/delivery_exchange_non_stock_item_details/delivery_exchange_non_stock_item_details.json b/av_tools/av_tools/doctype/delivery_exchange_non_stock_item_details/delivery_exchange_non_stock_item_details.json
new file mode 100644
index 0000000..d53e4d6
--- /dev/null
+++ b/av_tools/av_tools/doctype/delivery_exchange_non_stock_item_details/delivery_exchange_non_stock_item_details.json
@@ -0,0 +1,94 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2024-01-08 12:21:31.843374",
+ "default_view": "List",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "item_sold_or_delivered",
+ "rate_sold_or_delivered",
+ "qty_sold_or_delivered",
+ "amount_sold_or_delivered",
+ "warehouse",
+ "column_break_frc89",
+ "item_exchange",
+ "amount_exchange",
+ "uom"
+ ],
+ "fields": [
+ {
+ "fieldname": "item_sold_or_delivered",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Item Sold/Delivered",
+ "options": "Item",
+ "read_only": 1
+ },
+ {
+ "fieldname": "rate_sold_or_delivered",
+ "fieldtype": "Data",
+ "label": "Rate Sold/Delivered",
+ "read_only": 1
+ },
+ {
+ "fieldname": "qty_sold_or_delivered",
+ "fieldtype": "Data",
+ "label": "Qty Sold/Delivered",
+ "read_only": 1
+ },
+ {
+ "fieldname": "amount_sold_or_delivered",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Amount Sold/Delivered ",
+ "read_only": 1
+ },
+ {
+ "fieldname": "warehouse",
+ "fieldtype": "Link",
+ "label": "Warehouse",
+ "options": "Warehouse",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_frc89",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "item_exchange",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Item Exchange",
+ "options": "Item",
+ "reqd": 1
+ },
+ {
+ "fieldname": "amount_exchange",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Amount Exchange",
+ "read_only": 1
+ },
+ {
+ "fieldname": "uom",
+ "fieldtype": "Link",
+ "label": "UOM",
+ "options": "UOM",
+ "read_only": 1
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2024-01-08 15:47:56.471503",
+ "modified_by": "Administrator",
+ "module": "Av Tools",
+ "name": "Delivery Exchange Non Stock Item Details",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
diff --git a/av_tools/av_tools/doctype/delivery_exchange_non_stock_item_details/delivery_exchange_non_stock_item_details.py b/av_tools/av_tools/doctype/delivery_exchange_non_stock_item_details/delivery_exchange_non_stock_item_details.py
new file mode 100644
index 0000000..b547961
--- /dev/null
+++ b/av_tools/av_tools/doctype/delivery_exchange_non_stock_item_details/delivery_exchange_non_stock_item_details.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2024, Aakvatech and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+class DeliveryExchangeNonStockItemDetails(Document):
+ pass
diff --git a/av_tools/patches.txt b/av_tools/patches.txt
index c1d4b1d..b49313a 100644
--- a/av_tools/patches.txt
+++ b/av_tools/patches.txt
@@ -12,4 +12,5 @@ av_tools.patches.v1_0.migrate_generic_erp_behavior_overrides
av_tools.patches.v1_0.migrate_ai_integration_site_data
av_tools.patches.v1_0.migrate_generic_technical_admin_reports
av_tools.patches.v1_0.migrate_report_extension_site_data
+av_tools.patches.v1_0.move_delivery_exchange_doctypes
av_tools.patches.v1_0.move_inter_company_transfer_feature
diff --git a/av_tools/patches/v1_0/move_delivery_exchange_doctypes.py b/av_tools/patches/v1_0/move_delivery_exchange_doctypes.py
new file mode 100644
index 0000000..f070a7d
--- /dev/null
+++ b/av_tools/patches/v1_0/move_delivery_exchange_doctypes.py
@@ -0,0 +1,14 @@
+import frappe
+
+
+DELIVERY_EXCHANGE_DOCTYPES = (
+ "Delivery Exchange Item",
+ "Delivery Exchange Item Details",
+ "Delivery Exchange Non Stock Item Details",
+)
+
+
+def execute():
+ for doctype in DELIVERY_EXCHANGE_DOCTYPES:
+ if frappe.db.exists("DocType", doctype):
+ frappe.db.set_value("DocType", doctype, "module", "Av Tools")