From 2942279d7cfe72f3184a09f74e8af9ec79959494 Mon Sep 17 00:00:00 2001 From: Jeremy Rangel Date: Mon, 22 Sep 2025 16:59:02 -0700 Subject: [PATCH] Changes to text css --- .../__pycache__/hooks.cpython-310.pyc | Bin 1701 -> 1740 bytes .../fixtures/customer_custom_fields.json | 36 ++++++ .../fixtures/item_custom_fields.json | 11 ++ .../fixtures/lead_custom_fields.json | 2 +- rangeldigital/hooks.py | 3 +- rangeldigital/public/css/rangeldigital.css | 4 + rangeldigital/public/js/customer.js | 51 +++++++++ .../rangel_digital/doctype/__init__.py | 1 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 222 bytes .../doctype/customer_asset/__init__.py | 1 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 237 bytes .../customer_asset.cpython-310.pyc | Bin 0 -> 458 bytes .../customer_asset/customer_asset.json | 103 ++++++++++++++++++ .../doctype/customer_asset/customer_asset.py | 9 ++ .../__pycache__/my_open_tasks.cpython-310.pyc | Bin 0 -> 667 bytes .../my_open_tasks/my_open_tasks.json | 19 ++++ .../my_open_tasks/my_open_tasks.py | 20 ++++ .../quotations_total/quotations_total.json | 22 ++++ .../__pycache__/contact_hooks.cpython-310.pyc | Bin 976 -> 976 bytes .../find_duplicates.cpython-310.pyc | Bin 0 -> 637 bytes 20 files changed, 280 insertions(+), 2 deletions(-) create mode 100644 rangeldigital/fixtures/customer_custom_fields.json create mode 100644 rangeldigital/public/js/customer.js create mode 100644 rangeldigital/rangel_digital/doctype/__init__.py create mode 100644 rangeldigital/rangel_digital/doctype/__pycache__/__init__.cpython-310.pyc create mode 100644 rangeldigital/rangel_digital/doctype/customer_asset/__init__.py create mode 100644 rangeldigital/rangel_digital/doctype/customer_asset/__pycache__/__init__.cpython-310.pyc create mode 100644 rangeldigital/rangel_digital/doctype/customer_asset/__pycache__/customer_asset.cpython-310.pyc create mode 100644 rangeldigital/rangel_digital/doctype/customer_asset/customer_asset.json create mode 100644 rangeldigital/rangel_digital/doctype/customer_asset/customer_asset.py create mode 100644 rangeldigital/rangel_digital/number_card/my_open_tasks/__pycache__/my_open_tasks.cpython-310.pyc create mode 100644 rangeldigital/rangel_digital/number_card/my_open_tasks/my_open_tasks.json create mode 100644 rangeldigital/rangel_digital/number_card/my_open_tasks/my_open_tasks.py create mode 100644 rangeldigital/rangel_digital/number_card/quotations_total/quotations_total.json create mode 100644 rangeldigital/utilities/lead/__pycache__/find_duplicates.cpython-310.pyc diff --git a/rangeldigital/__pycache__/hooks.cpython-310.pyc b/rangeldigital/__pycache__/hooks.cpython-310.pyc index 496f9b59a1fe7a404e7085e433f03b32f237a12e..3e5ef60b0822c9cd0509b5c9d742602a934c2b90 100644 GIT binary patch delta 215 zcmZ3=dxn=cpO=@50SNB7g=aWU Generate Assets CSV" + } + + ] \ No newline at end of file diff --git a/rangeldigital/fixtures/item_custom_fields.json b/rangeldigital/fixtures/item_custom_fields.json index 487bc5f..5a74c77 100644 --- a/rangeldigital/fixtures/item_custom_fields.json +++ b/rangeldigital/fixtures/item_custom_fields.json @@ -8,5 +8,16 @@ "insert_after": "stock_uom", "label": "Manufacturer Item Code", "name": "item_manuf_item_code" + }, + { + + "doctype": "Custom Field", + "dt": "Item", + "fieldname": "manuf_product_url", + "fieldtype": "Data", + "insert_after": "manuf_item_code", + "label": "Manufacturer URL", + "name": "item_manuf_url", + "options": "URL" } ] \ No newline at end of file diff --git a/rangeldigital/fixtures/lead_custom_fields.json b/rangeldigital/fixtures/lead_custom_fields.json index 0773741..0bf90f9 100644 --- a/rangeldigital/fixtures/lead_custom_fields.json +++ b/rangeldigital/fixtures/lead_custom_fields.json @@ -185,7 +185,7 @@ "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "auto_creation_of_contact", + "insert_after": "__section_8", "is_system_generated": 1, "is_virtual": 0, "label": "Last Touch Date", diff --git a/rangeldigital/hooks.py b/rangeldigital/hooks.py index 805ef1a..381a170 100644 --- a/rangeldigital/hooks.py +++ b/rangeldigital/hooks.py @@ -15,7 +15,8 @@ override_doctype_class = { # Lead: Add javascript to add "Add to Email Campaign to Action Dropdown" doctype_js = { - "Lead": "public/js/lead.js" + "Lead": "public/js/lead.js", + "Customer": "public/js/customer.js" } # Add cron scheduler for email campaign sending # Send email at 08:15 AM every day diff --git a/rangeldigital/public/css/rangeldigital.css b/rangeldigital/public/css/rangeldigital.css index fe64118..c91ee01 100644 --- a/rangeldigital/public/css/rangeldigital.css +++ b/rangeldigital/public/css/rangeldigital.css @@ -42,6 +42,10 @@ input.form-control { border-radius:0; } +/* Text */ +a {color:white} +.from-markdown b, .from-markdown strong {color:white} + /* ------- FRAPPE ELEMENTS ------- */ /* Text */ body .text-muted {color:#cccccc!important} diff --git a/rangeldigital/public/js/customer.js b/rangeldigital/public/js/customer.js new file mode 100644 index 0000000..de5e857 --- /dev/null +++ b/rangeldigital/public/js/customer.js @@ -0,0 +1,51 @@ +frappe.ui.form.on('Customer', { + refresh: function(frm) { + // Wait for the form and its custom HTML fields to render + frappe.after_ajax(() => { + // Look for a button with the data attribute + const $btn = frm.$wrapper.find('[data-generate-customer-assets-csv]'); + + if ($btn.length) { + // Prevent double-binding + $btn.off('click').on('click', function () { + const assets = frm.doc.customer_assets || []; + + if (!assets.length) { + frappe.msgprint('No customer assets found.'); + return; + } + + const excludedFields = [ + 'owner', 'creation', 'modified', 'modified_by', 'docstatus', 'idx' + ]; + + const fields = Object.keys(assets[0]).filter( + field => !excludedFields.includes(field) + ); + + const csvRows = []; + csvRows.push(fields.join(',')); + + assets.forEach(row => { + const csvRow = fields.map(field => { + let val = row[field] || ''; + return `"${String(val).replace(/"/g, '""')}"`; + }); + csvRows.push(csvRow.join(',')); + }); + + const csvContent = csvRows.join('\n'); + const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); + const url = URL.createObjectURL(blob); + + const a = document.createElement('a'); + a.href = url; + a.download = `CustomerAssets-${frm.doc.name}.csv`; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + }); + } + }); + } +}); diff --git a/rangeldigital/rangel_digital/doctype/__init__.py b/rangeldigital/rangel_digital/doctype/__init__.py new file mode 100644 index 0000000..f102a9c --- /dev/null +++ b/rangeldigital/rangel_digital/doctype/__init__.py @@ -0,0 +1 @@ +__version__ = "0.0.1" diff --git a/rangeldigital/rangel_digital/doctype/__pycache__/__init__.cpython-310.pyc b/rangeldigital/rangel_digital/doctype/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2bbbabbecdcb087f39b90f900ee2ad6239044da GIT binary patch literal 222 zcmd1j<>g`kf>Rt}8Dc>CF^Gc<7=auIATH(r5-AK(3@MDk44O<;tOj}pdWL?QjJLSs z9R1+TlGI}Tw4%gbD_o0OWD zoS_dCDb|OmO36&mEJ@74%8Q3drsOA=R00i&kI&4@EQycTE2zB1VUwGmQks)$2Xb*S I$Q2w60Ftpio&W#< literal 0 HcmV?d00001 diff --git a/rangeldigital/rangel_digital/doctype/customer_asset/__init__.py b/rangeldigital/rangel_digital/doctype/customer_asset/__init__.py new file mode 100644 index 0000000..f102a9c --- /dev/null +++ b/rangeldigital/rangel_digital/doctype/customer_asset/__init__.py @@ -0,0 +1 @@ +__version__ = "0.0.1" diff --git a/rangeldigital/rangel_digital/doctype/customer_asset/__pycache__/__init__.cpython-310.pyc b/rangeldigital/rangel_digital/doctype/customer_asset/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3296675f4a8f47c0c54540acfd08cf7aef1ccdb0 GIT binary patch literal 237 zcmd1j<>g`kf^8gO8Dc>CF^Gc<7=auIATH(r5-AK(3@MDk44O<;tOj}pdWL?QjJLSs z9R1+TlGI}Tw4%gbD_o0OWD zoS_dCDb|OmO36&mEJ@74%8Q3drsOA=R00i2E-fy}&rL0gPb@A@EzysU&&;Un(OF|=m^*= zFSw>Fk{x_vH(6%X$2V;`)X?;0$m|P6ut0SQ8XyJLq+sJT^Xc{A`nCpp1ti|%KVGuPf@pJzr`ix?nJ4=jelU?Z7s)R;y^I`FeVWlGg;(k(;5C`@;TB0 iljGj;QI-V~VfdHM6oq9zzL?lwhX1)4nwTd1n12H}#dOyI literal 0 HcmV?d00001 diff --git a/rangeldigital/rangel_digital/doctype/customer_asset/customer_asset.json b/rangeldigital/rangel_digital/doctype/customer_asset/customer_asset.json new file mode 100644 index 0000000..0be3ef1 --- /dev/null +++ b/rangeldigital/rangel_digital/doctype/customer_asset/customer_asset.json @@ -0,0 +1,103 @@ +{ + "actions": [], + "creation": "2013-02-22 01:27:51", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + + ], + "fields": [ + { + "fieldname": "item", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Item", + "options": "Item" + }, + { + "fieldname": "item_brand", + "fieldtype": "Data", + "in_list_view": 0, + "read_only":1, + "label": "Item Brand", + "fetch_from": "item.brand" + }, + { + "fieldname": "brand", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Brand" + }, + { + "fieldname": "status", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Status", + "options": "\nIn Service\nStored\nReserved" + }, + { + "fieldname": "serial_no", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Serial Number" + }, + { + "fieldname": "location_address", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Location Address", + "options": "Address" + }, + { + "fieldname": "acquired_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Acquired Date" + }, + { + "fieldname": "eol_date", + "fieldtype": "Date", + "in_list_view": 0, + "label": "End Of Life Date" + }, + { + "fieldname": "warranty_start_date", + "fieldtype": "Date", + "in_list_view": 0, + "label": "Warranty Start Date" + }, + { + "fieldname": "warranty_end_date", + "fieldtype": "Date", + "in_list_view": 0, + "label": "Warranty End Date" + }, + { + "fieldname": "ownership_type", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Ownership Type", + "options": "Owned\nOperating Lease\nCapital Lease\nOther" + }, + { + "fieldname": "notes", + "fieldtype": "Text", + "in_list_view": 0, + "label": "Notes" + } + ], + "idx": 1, + "istable": 1, + "links": [], + "modified": "2023-11-14 18:35:30.887278", + "modified_by": "Administrator", + "module": "Rangel Digital", + "name": "Customer Asset", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "states": [], + "track_changes": 1 + } \ No newline at end of file diff --git a/rangeldigital/rangel_digital/doctype/customer_asset/customer_asset.py b/rangeldigital/rangel_digital/doctype/customer_asset/customer_asset.py new file mode 100644 index 0000000..6c182c3 --- /dev/null +++ b/rangeldigital/rangel_digital/doctype/customer_asset/customer_asset.py @@ -0,0 +1,9 @@ + +import frappe + + +from frappe.model.document import Document + + +class CustomerAsset(Document): + pass \ No newline at end of file diff --git a/rangeldigital/rangel_digital/number_card/my_open_tasks/__pycache__/my_open_tasks.cpython-310.pyc b/rangeldigital/rangel_digital/number_card/my_open_tasks/__pycache__/my_open_tasks.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5db70477bcd40c979ed65789c5a0f41700c9103b GIT binary patch literal 667 zcmZuvy>1gh5Z>MUwTTf$1e9)&xB~745JIG)AQTCWDNgH~@%fy+J!^N5$WbC8Ic=VR zAORgOK+SV(OT{ZhB4W-Vl93o`X1@8+H#4hkN24Jl`S9c2{5xmtXCG`!K*0-A`AXjFUdHz;0tlq z`(P0Q2T>8(S6&GSAv$Fr8AP7~isDNF$%Q!MryNoj!C=i{cp1>JJNrI7l=kQ()~y@Y zItzSyh|N+-hkmfv5<-VSQ0fwuA{eUr2(S2~O!(M3={oC^LRwo_ns!cRwQ^{z4_;|^ zGJ3rlzgeOl_cJV!NAIQTheSj9gM8u}EaC_F-qycmY!%m2Ib; z=^ucm?v$M|s9n+5%`PRsF>{~X)jEGmDVr~h)D^1ypmu2U8{WU}$rN=t&uNm)Z@Qqa zYA4lyqvE!xyJm`}D5ZhCSrskaRJi`8f1{_%mEWz<6eu14gpO=@50SGp`J7yf&$a{j3k$3Vn#>I@1ldG8CGqOz1Voqgb1_1w%3*G<# delta 42 wcmcb>eu14gpO=@50SL6+9Wxv@@}6L1m{S><0OK4A&Hw-a diff --git a/rangeldigital/utilities/lead/__pycache__/find_duplicates.cpython-310.pyc b/rangeldigital/utilities/lead/__pycache__/find_duplicates.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6eea627b45923f79e12f359b93562e86f2f21320 GIT binary patch literal 637 zcmZWnv5wO~5S>|XoNy5C%Bv`#azV@oL=h5{C{08Y2}O%{d;T{DI8XYXb zz$g3+T56%QE4;*|(71qN@Pm3_UJ=ee6ZAD8e?lH66b=w%4GV~Hff^a1CO?2hE#GJF zP!Du|1qXZzmy9`_C;7}Mon)i7Cf%vpZKs<3inBtbd~J=>Ar05oMdQPN+^m1W+~*W( zVt+9r4w}Q_0l(k}@mdgzNJHILao-uwg1>S_Odciah}w^+)Q6w1%IASt$_uZW+PHFI zqY35OtFAMDUk_iJrrMNL3FV(IZEG8qJIZ#^IvXt=XO41h8@I z^1!oGo`98|!`lbPty9-l%7xkFy1(B{uPO~|6IaT)LU`WAa=>)qdM1CHs_FCyG-JXu z3Q|avnZTT%Uw3oQQVN_GnIH4PTW>bB0~Xr