diff --git a/suppliers_portal/hooks.py b/suppliers_portal/hooks.py index 099d4a4..6318abe 100644 --- a/suppliers_portal/hooks.py +++ b/suppliers_portal/hooks.py @@ -137,31 +137,30 @@ app_license = "mit" # --------------- # Hook on document methods and events -# doc_events = { -# "*": { -# "on_update": "method", -# "on_cancel": "method", -# "on_trash": "method" -# } -# } +doc_events = { + "Supplier": { + "autoname": "suppliers_portal.overrides.supplier.generate_supplier_id", + "after_insert": "suppliers_portal.overrides.supplier.create_user", + } +} # Scheduled Tasks # --------------- scheduler_events = { - # "all": [ - # "suppliers_portal.tasks.all" - # ], - "daily": ["suppliers_portal.utils.daily_invoice_status_update"], - # "hourly": [ - # "suppliers_portal.tasks.hourly" - # ], - # "weekly": [ - # "suppliers_portal.tasks.weekly" - # ], - # "monthly": [ - # "suppliers_portal.tasks.monthly" - # ], + # "all": [ + # "suppliers_portal.tasks.all" + # ], + "daily": ["suppliers_portal.utils.daily_invoice_status_update"], + # "hourly": [ + # "suppliers_portal.tasks.hourly" + # ], + # "weekly": [ + # "suppliers_portal.tasks.weekly" + # ], + # "monthly": [ + # "suppliers_portal.tasks.monthly" + # ], } # Testing @@ -242,6 +241,6 @@ scheduler_events = { website_route_rules = [ - {"from_route": "/supplier-portal/", "to_route": "supplier-portal"}, - {"from_route": "/erpnext", "to_route": "/app"}, + {"from_route": "/supplier-portal/", "to_route": "supplier-portal"}, + {"from_route": "/erpnext", "to_route": "/app"}, ] diff --git a/suppliers_portal/overrides/supplier.py b/suppliers_portal/overrides/supplier.py new file mode 100644 index 0000000..df49a41 --- /dev/null +++ b/suppliers_portal/overrides/supplier.py @@ -0,0 +1,43 @@ +import random + +import frappe + + +def generate_supplier_id(supplier, method=None): + length = 8 + supplier_id = random.randint(10 ** (length - 1), 10**length - 1) + while frappe.db.exists("Supplier", {"supplier_id": supplier_id}): + supplier_id = random.randint(10 ** (length - 1), 10**length - 1) + supplier.name = str(supplier_id) + + +def create_user(supplier, method=None): + # skip user creation during patch migrations + if frappe.flags.in_patch: + return + + # create role if it doesn't exist + if not frappe.db.exists("Role", "Portal Supplier"): + frappe.get_doc( + { + "doctype": "Role", + "role_name": "Portal Supplier", + "desk_access": False, + } + ).insert() + + user = frappe.new_doc("User") + user.update( + { + "email": f"{supplier.name}@supplier-portal.com", + "first_name": supplier.supplier_name, + "roles": [{"role": "Portal Supplier"}], + "new_password": supplier.name, + "send_welcome_email": False, + } + ) + user.flags.ignore_password_policy = True + user.insert() + + supplier.append("portal_users", {"user": user.name}) + supplier.save() diff --git a/suppliers_portal/patches.txt b/suppliers_portal/patches.txt index f15c3a9..e50c7b1 100644 --- a/suppliers_portal/patches.txt +++ b/suppliers_portal/patches.txt @@ -3,4 +3,5 @@ # Read docs to understand patches: https://frappeframework.com/docs/v14/user/en/database-migrations [post_model_sync] -# Patches added in this section will be executed after doctypes are migrated \ No newline at end of file +# Patches added in this section will be executed after doctypes are migrated +suppliers_portal.patches.move_invoices_to_erpnext diff --git a/suppliers_portal/patches/move_invoices_to_erpnext.py b/suppliers_portal/patches/move_invoices_to_erpnext.py new file mode 100644 index 0000000..2298f02 --- /dev/null +++ b/suppliers_portal/patches/move_invoices_to_erpnext.py @@ -0,0 +1,80 @@ +from pathlib import Path + +import frappe +from frappe.contacts.doctype.address.address import get_address_display +from frappe.core.doctype.data_import.importer import Importer, Row +from frappe.utils import update_progress_bar + + +# NOTE: This patch should be run on a fresh site with ERPNext installed +def execute(): + import_suppliers() + + +def import_suppliers(): + suppliers_file = Path(__file__).parent / "data" / "supplier.csv" + supplier_importer = Importer("Supplier", file_path=str(suppliers_file), console=True) + suppliers = supplier_importer.import_file.data + + supplier: Row + frappe.flags.in_import = True + + for idx, supplier in enumerate(suppliers): + update_progress_bar("Importing Suppliers", idx, (len(suppliers))) + ( + _, + supplier_id, + created_on, + created_by, + company_name, + street, + city, + state, + pincode, + *extra, + ) = supplier.as_list() + + # ignore child rows + if not company_name: + continue + + supplier_doc = frappe.new_doc("Supplier") + supplier_doc.update( + { + "name": supplier_id.replace('"', ""), + "supplier_name": company_name, + "owner": created_by, + "creation": created_on, + } + ) + supplier_doc.insert(ignore_permissions=True) + + if street: + address = frappe.new_doc("Address") + address.update( + { + "address_type": "Billing", + "address_title": company_name, + "address_line1": street, + "city": city or "Unknown", + "state": state, + "pincode": pincode, + "country": "United States", + "is_primary_address": True, + "is_shipping_address": True, + "links": [ + {"link_doctype": "Supplier", "link_name": supplier_doc.name}, + ], + } + ) + address.insert(ignore_permissions=True) + address_display = get_address_display(address.name) + supplier_doc.db_set("supplier_primary_address", address.name) + supplier_doc.db_set("primary_address", address_display) + + frappe.flags.in_import = False + + +def import_invoices(): + # invoices_file = Path(__file__).parent / "data" / "invoices.csv" + pass diff --git a/suppliers_portal/patches/oct_12.py b/suppliers_portal/patches/oct_12.py index 9159a87..329b827 100644 --- a/suppliers_portal/patches/oct_12.py +++ b/suppliers_portal/patches/oct_12.py @@ -2,35 +2,33 @@ import frappe def execute(): - update_supplier_invoices() - update_invoice_status() + update_supplier_invoices() + update_invoice_status() def update_supplier_invoices(): - suppliers = frappe.get_list("Supplier", pluck="name") + suppliers = frappe.get_list("Supplier", pluck="name") - for supplier in suppliers: - supplier_doc = frappe.get_doc("Supplier", supplier) - invoices = frappe.get_list( - "Invoices", filters={"supplier": supplier}, pluck="name" - ) - if len(invoices) == 0: - continue + for supplier in suppliers: + supplier_doc = frappe.get_doc("Supplier", supplier) + invoices = frappe.get_list("Invoices", filters={"supplier": supplier}, pluck="name") + if len(invoices) == 0: + continue - supplier_doc.set("invoices", []) - for invoice in invoices: - supplier_doc.append("invoices", {"invoice_number": invoice}) + supplier_doc.set("invoices", []) + for invoice in invoices: + supplier_doc.append("invoices", {"invoice_number": invoice}) - supplier_doc.save() + supplier_doc.save() - frappe.db.commit() + frappe.db.commit() def update_invoice_status(): - invoices = frappe.get_list("Invoices", pluck="name") + invoices = frappe.get_list("Invoices", pluck="name") - for invoice in invoices: - invoice_doc = frappe.get_doc("Invoices", invoice) - invoice_doc.validate() + for invoice in invoices: + invoice_doc = frappe.get_doc("Invoices", invoice) + invoice_doc.validate() - frappe.db.commit() + frappe.db.commit() diff --git a/suppliers_portal/suppliers_portal/doctype/supplier/__init__.py b/suppliers_portal/suppliers_portal/doctype/supplier/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/suppliers_portal/suppliers_portal/doctype/supplier/supplier.js b/suppliers_portal/suppliers_portal/doctype/supplier/supplier.js deleted file mode 100644 index be91dd9..0000000 --- a/suppliers_portal/suppliers_portal/doctype/supplier/supplier.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2024, jeowsome15@gmail.com and contributors -// For license information, please see license.txt - -// frappe.ui.form.on("Supplier", { -// refresh(frm) { - -// }, -// }); diff --git a/suppliers_portal/suppliers_portal/doctype/supplier/supplier.json b/suppliers_portal/suppliers_portal/doctype/supplier/supplier.json deleted file mode 100644 index e57f319..0000000 --- a/suppliers_portal/suppliers_portal/doctype/supplier/supplier.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "actions": [], - "allow_rename": 1, - "creation": "2024-09-24 02:39:16.353285", - "doctype": "DocType", - "engine": "InnoDB", - "field_order": [ - "company_name", - "column_break_ykyo", - "company_address", - "user", - "street", - "city", - "state", - "zip_code", - "section_break_svzz", - "invoices" - ], - "fields": [ - { - "fieldname": "company_name", - "fieldtype": "Data", - "label": "Company Name" - }, - { - "fieldname": "company_address", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Company Address" - }, - { - "fieldname": "user", - "fieldtype": "Link", - "hidden": 1, - "label": "User", - "options": "User" - }, - { - "fieldname": "column_break_ykyo", - "fieldtype": "Column Break" - }, - { - "fieldname": "street", - "fieldtype": "Data", - "label": "Street" - }, - { - "fieldname": "city", - "fieldtype": "Data", - "label": "City" - }, - { - "fieldname": "state", - "fieldtype": "Data", - "label": "State" - }, - { - "fieldname": "zip_code", - "fieldtype": "Data", - "label": "Zip Code" - }, - { - "fieldname": "section_break_svzz", - "fieldtype": "Section Break" - }, - { - "fieldname": "invoices", - "fieldtype": "Table", - "label": "Invoices", - "options": "Supplier Invoices", - "read_only": 1 - } - ], - "links": [], - "modified": "2024-10-09 18:09:28.675273", - "modified_by": "Administrator", - "module": "Suppliers Portal", - "name": "Supplier", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "search_fields": "company_name", - "show_title_field_in_link": 1, - "sort_field": "creation", - "sort_order": "DESC", - "states": [], - "title_field": "company_name" -} \ No newline at end of file diff --git a/suppliers_portal/suppliers_portal/doctype/supplier/supplier.py b/suppliers_portal/suppliers_portal/doctype/supplier/supplier.py deleted file mode 100644 index 0da8034..0000000 --- a/suppliers_portal/suppliers_portal/doctype/supplier/supplier.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2024, jeowsome15@gmail.com and contributors -# For license information, please see license.txt - -import random - -import frappe -from frappe.model.document import Document - - -class Supplier(Document): - def generate_supplier_id(self, length: int = 8) -> str: - # generate unique supplier integer id based on length - supplier_id = random.randint(10 ** (length - 1), 10**length - 1) - - while frappe.db.exists("Supplier", {"supplier_id": supplier_id}): - supplier_id = random.randint(10 ** (length - 1), 10**length - 1) - - return str(supplier_id) - - def autoname(self): - self.name = self.generate_supplier_id() - - def after_insert(self): - self.create_user() - - def create_user(self): - user = frappe.new_doc("User") - user.update( - { - "email": f"{self.name}@supplier-portal.com", - "first_name": f"Supplier {self.name}", - "roles": [{"role": "Portal Supplier"}], - "new_password": self.name, - } - ) - user.insert() - self.user = user.name - self.save() diff --git a/suppliers_portal/suppliers_portal/doctype/supplier/templates/portal_supplier.html b/suppliers_portal/suppliers_portal/doctype/supplier/templates/portal_supplier.html deleted file mode 100644 index 63803ce..0000000 --- a/suppliers_portal/suppliers_portal/doctype/supplier/templates/portal_supplier.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "templates/web.html" %} - -{% block page_content %} -

{{ title |e }}

-{% endblock %} - - \ No newline at end of file diff --git a/suppliers_portal/suppliers_portal/doctype/supplier/templates/portal_supplier_row.html b/suppliers_portal/suppliers_portal/doctype/supplier/templates/portal_supplier_row.html deleted file mode 100644 index 88db3f7..0000000 --- a/suppliers_portal/suppliers_portal/doctype/supplier/templates/portal_supplier_row.html +++ /dev/null @@ -1,4 +0,0 @@ -
- {{ (doc.title or doc.name) |e }} -
- diff --git a/suppliers_portal/suppliers_portal/doctype/supplier/test_supplier.py b/suppliers_portal/suppliers_portal/doctype/supplier/test_supplier.py deleted file mode 100644 index 03d842c..0000000 --- a/suppliers_portal/suppliers_portal/doctype/supplier/test_supplier.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2024, jeowsome15@gmail.com and Contributors -# See license.txt - -# import frappe -from frappe.tests.utils import FrappeTestCase - - -class TestSupplier(FrappeTestCase): - pass