From 0ab7922cae8b124673a538769db20155faf36329 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Tue, 11 Mar 2025 18:10:36 +0000 Subject: [PATCH 01/31] feat: Reconciliation page --- beam/hooks.py | 7 ++++ beam/tests/setup.py | 1 + beam/www/beam/pages/Reconciliation.vue | 57 ++++++++++++++++++++++++++ beam/www/beam/types/frappe.ts | 15 +++++++ 4 files changed, 80 insertions(+) create mode 100644 beam/www/beam/pages/Reconciliation.vue diff --git a/beam/hooks.py b/beam/hooks.py index 70ac2bea..8b3f32b6 100644 --- a/beam/hooks.py +++ b/beam/hooks.py @@ -543,6 +543,7 @@ "PurchaseReceipt": "./beam/beam/www/beam/pages/PurchaseReceipt.vue", "Receive": "./beam/beam/www/beam/pages/Receive.vue", "Repack": "./beam/beam/www/beam/pages/Repack.vue", + "Reconciliation": "./beam/beam/www/beam/pages/Reconciliation.vue", "Ship": "./beam/beam/www/beam/pages/Ship.vue", "WorkOrder": "./beam/beam/www/beam/pages/WorkOrder.vue", "Workstation": "./beam/beam/www/beam/pages/Workstation.vue", @@ -627,6 +628,12 @@ "component": "Repack", "meta": {"requiresAuth": True, "doctype": "Stock Entry", "view": "form"}, }, + { + "path": "/stock-reconciliation", + "name": "stock-reconciliation", + "component": "Reconciliation", + "meta": {"requiresAuth": True, "doctype": "Stock Reconciliation", "view": "form"}, + }, { "path": "/:catchAll(.*)*", "name": "404", diff --git a/beam/tests/setup.py b/beam/tests/setup.py index d8a52590..9125aa48 100644 --- a/beam/tests/setup.py +++ b/beam/tests/setup.py @@ -213,6 +213,7 @@ def setup_beam_settings(settings): {"label": "Receive", "route": "#/receive", "dt": "Purchase Receipt", "component": "Receive"}, {"label": "Ship", "route": "#/ship", "dt": "Delivery Note", "component": "Ship"}, {"label": "Repack", "route": "#/repack", "dt": "Stock Entry", "component": "Repack"}, + {"label": "Reconciliation", "route": "#/stock-reconciliation", "dt": "Stock Reconciliation", "component": "Reconciliation"}, ], ) beams.save() diff --git a/beam/www/beam/pages/Reconciliation.vue b/beam/www/beam/pages/Reconciliation.vue new file mode 100644 index 00000000..715a545f --- /dev/null +++ b/beam/www/beam/pages/Reconciliation.vue @@ -0,0 +1,57 @@ + + + diff --git a/beam/www/beam/types/frappe.ts b/beam/www/beam/types/frappe.ts index b3284f5a..b297fc8b 100644 --- a/beam/www/beam/types/frappe.ts +++ b/beam/www/beam/types/frappe.ts @@ -26,6 +26,7 @@ export type ParentDoctype = StoreMetadata & { modified?: string name?: string owner?: string + company?: string } export type ChildDoctypeMeta = ParentDoctype & { @@ -59,6 +60,20 @@ export type JobCardItem = ChildDoctype & { transferred_qty?: number } +export type StockReconciliation = ParentDoctype & { + purpose: 'Stock Reconciliation' | 'Opening Stock' + + set_warehouse: string + items: StockEntryItem[] +} + +export type StockReconciliationItem = ChildDoctype & { + warehouse?: string + qty: number + valuation_rate: number + item_code: string +} + export type StockEntry = ParentDoctype & { stock_entry_type: string From 438e87277409d8238cc89e2edee39ff5014a20b4 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Tue, 11 Mar 2025 18:34:21 +0000 Subject: [PATCH 02/31] fix: unused type --- beam/www/beam/pages/Move.vue | 3 --- 1 file changed, 3 deletions(-) diff --git a/beam/www/beam/pages/Move.vue b/beam/www/beam/pages/Move.vue index 84115fa8..a1efbd61 100644 --- a/beam/www/beam/pages/Move.vue +++ b/beam/www/beam/pages/Move.vue @@ -35,9 +35,6 @@ import ControlButtons from '@/components/ControlButtons.vue' import { useBeamStore } from '@/stores/beam' import type { ControlButton, DocActionResponse, StockEntry } from '@/types' import { watch } from 'vue' -type Warehouse = { - name: string -} const store = useBeamStore() const items = ref([]) From 61ccc2e2196382ed29cc9c44e86bd8c708c52586 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Tue, 11 Mar 2025 18:34:33 +0000 Subject: [PATCH 03/31] fix: styles --- beam/www/beam/pages/Reconciliation.vue | 34 ++++++++++++++++++++------ 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/beam/www/beam/pages/Reconciliation.vue b/beam/www/beam/pages/Reconciliation.vue index 715a545f..b91a6f19 100644 --- a/beam/www/beam/pages/Reconciliation.vue +++ b/beam/www/beam/pages/Reconciliation.vue @@ -34,14 +34,14 @@ import type { ControlButton, StockReconciliation } from '@/types' const store = useBeamStore() const items = ref([]) const componentKey = ref(0) -const reconciliation = computed(() => { - const data = store.cache.mappers.reconciliation as StockReconciliation; - return { - set_warehouse: data?.set_warehouse || '', - items: data?.items || [], - purpose: data?.purpose || 'Stock Reconciliation', - }; -}); +const reconciliation = computed((): StockReconciliation => + (store.cache.mappers['reconciliation'] as StockReconciliation) || { + name: '', + purpose: 'Stock Reconciliation', + items: [], + set_warehouse: '', + } +) const warehouseList = ref([]) @@ -55,3 +55,21 @@ const clearField = () => const controlButtons = computed((): ControlButton[] => []) + From c2f0fc6e52847c3cc008a866fc39f28e23945b9c Mon Sep 17 00:00:00 2001 From: lauty95 Date: Tue, 11 Mar 2025 19:06:34 +0000 Subject: [PATCH 04/31] fix: mapper var --- beam/www/beam/pages/Reconciliation.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/beam/www/beam/pages/Reconciliation.vue b/beam/www/beam/pages/Reconciliation.vue index b91a6f19..1e06c75e 100644 --- a/beam/www/beam/pages/Reconciliation.vue +++ b/beam/www/beam/pages/Reconciliation.vue @@ -35,7 +35,7 @@ const store = useBeamStore() const items = ref([]) const componentKey = ref(0) const reconciliation = computed((): StockReconciliation => - (store.cache.mappers['reconciliation'] as StockReconciliation) || { + (store.cache.mappers['stock-reconciliation'] as StockReconciliation) || { name: '', purpose: 'Stock Reconciliation', items: [], @@ -46,12 +46,12 @@ const reconciliation = computed((): StockReconciliation => const warehouseList = ref([]) onMounted(async () => { - store.$patch(state => (state.cache.mappers.reconciliation = reconciliation.value)) + store.$patch(state => (state.cache.mappers['stock-reconciliation'] = reconciliation.value)) warehouseList.value = store.warehouseList.filter(w => !w.is_group).map(w => w.name) }) const clearField = () => - store.$patch(state => (state.cache.mappers.reconciliation['set_warehouse'] = '')) + store.$patch(state => (state.cache.mappers['stock-reconciliation']['set_warehouse'] = '')) const controlButtons = computed((): ControlButton[] => []) From 92732953e66f7df6a1eadb2ffa86aaa1eb9ca8f5 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Tue, 11 Mar 2025 19:07:27 +0000 Subject: [PATCH 05/31] feat: handling 'Stock Reconciliation Item' WH scan --- beam/www/beam/stores/scan.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/beam/www/beam/stores/scan.ts b/beam/www/beam/stores/scan.ts index 0489d18d..437aeb0e 100644 --- a/beam/www/beam/stores/scan.ts +++ b/beam/www/beam/stores/scan.ts @@ -12,6 +12,7 @@ import type { PurchaseReceipt, StockEntry, StockEntryItem, + StockReconciliation, } from '@/types/index.js' export const useScanStore = defineStore('scan', () => { @@ -175,10 +176,14 @@ export const useScanStore = defineStore('scan', () => { const set_warehouse = (barcode_context: FormContext[]) => { for (const action of barcode_context) { - if (action.doctype !== 'Stock Entry') { - return + if (action.doctype === 'Stock Reconciliation Item') { + const warehouse = action.context.doc.name; + (mappedDoc.value as StockReconciliation).set_warehouse = warehouse + store.$patch(state => (state.cache.mappers[documentId.value] = mappedDoc.value)) } + if (action.doctype !== 'Stock Entry') return + const source_warehouses = ['Material Consumption for Manufacture', 'Material Issue'] const target_warehouses = ['Material Receipt', 'Manufacture'] const both_warehouses = [ From 1dacb43af6ef3e7bed81b5852a138f8df6ce7458 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Wed, 12 Mar 2025 11:48:55 +0000 Subject: [PATCH 06/31] prettier --- beam/tests/setup.py | 7 ++++++- beam/www/beam/pages/Reconciliation.vue | 6 +++--- beam/www/beam/stores/scan.ts | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/beam/tests/setup.py b/beam/tests/setup.py index 9125aa48..2439a877 100644 --- a/beam/tests/setup.py +++ b/beam/tests/setup.py @@ -213,7 +213,12 @@ def setup_beam_settings(settings): {"label": "Receive", "route": "#/receive", "dt": "Purchase Receipt", "component": "Receive"}, {"label": "Ship", "route": "#/ship", "dt": "Delivery Note", "component": "Ship"}, {"label": "Repack", "route": "#/repack", "dt": "Stock Entry", "component": "Repack"}, - {"label": "Reconciliation", "route": "#/stock-reconciliation", "dt": "Stock Reconciliation", "component": "Reconciliation"}, + { + "label": "Reconciliation", + "route": "#/stock-reconciliation", + "dt": "Stock Reconciliation", + "component": "Reconciliation", + }, ], ) beams.save() diff --git a/beam/www/beam/pages/Reconciliation.vue b/beam/www/beam/pages/Reconciliation.vue index 1e06c75e..6aa45f2a 100644 --- a/beam/www/beam/pages/Reconciliation.vue +++ b/beam/www/beam/pages/Reconciliation.vue @@ -34,7 +34,8 @@ import type { ControlButton, StockReconciliation } from '@/types' const store = useBeamStore() const items = ref([]) const componentKey = ref(0) -const reconciliation = computed((): StockReconciliation => +const reconciliation = computed( + (): StockReconciliation => (store.cache.mappers['stock-reconciliation'] as StockReconciliation) || { name: '', purpose: 'Stock Reconciliation', @@ -50,8 +51,7 @@ onMounted(async () => { warehouseList.value = store.warehouseList.filter(w => !w.is_group).map(w => w.name) }) -const clearField = () => - store.$patch(state => (state.cache.mappers['stock-reconciliation']['set_warehouse'] = '')) +const clearField = () => store.$patch(state => (state.cache.mappers['stock-reconciliation']['set_warehouse'] = '')) const controlButtons = computed((): ControlButton[] => []) diff --git a/beam/www/beam/stores/scan.ts b/beam/www/beam/stores/scan.ts index 437aeb0e..cf7b9d04 100644 --- a/beam/www/beam/stores/scan.ts +++ b/beam/www/beam/stores/scan.ts @@ -177,8 +177,8 @@ export const useScanStore = defineStore('scan', () => { const set_warehouse = (barcode_context: FormContext[]) => { for (const action of barcode_context) { if (action.doctype === 'Stock Reconciliation Item') { - const warehouse = action.context.doc.name; - (mappedDoc.value as StockReconciliation).set_warehouse = warehouse + const warehouse = action.context.doc.name + ;(mappedDoc.value as StockReconciliation).set_warehouse = warehouse store.$patch(state => (state.cache.mappers[documentId.value] = mappedDoc.value)) } From b713ddbf267d7fbe2937b7e5e48c513842369fd6 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Fri, 30 May 2025 16:45:39 +0000 Subject: [PATCH 07/31] feat: fetching items --- beam/www/beam/pages/Reconciliation.vue | 29 ++++++++++++++++++++++---- beam/www/beam/stores/beam.ts | 22 +++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/beam/www/beam/pages/Reconciliation.vue b/beam/www/beam/pages/Reconciliation.vue index 6aa45f2a..5c1a6e6f 100644 --- a/beam/www/beam/pages/Reconciliation.vue +++ b/beam/www/beam/pages/Reconciliation.vue @@ -16,8 +16,8 @@ - -
+ +
Scan or Select Warehouses to Begin
@@ -25,8 +25,7 @@ diff --git a/beam/www/beam/components/ListItem.vue b/beam/www/beam/components/ListItem.vue new file mode 100644 index 00000000..4233868f --- /dev/null +++ b/beam/www/beam/components/ListItem.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/beam/www/beam/components/ListView.vue b/beam/www/beam/components/ListView.vue new file mode 100644 index 00000000..1fb3e263 --- /dev/null +++ b/beam/www/beam/components/ListView.vue @@ -0,0 +1,76 @@ + + + + + From b0342164629cd68c4d9a0a7e412eabb5342ea6e3 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Tue, 24 Jun 2025 14:50:19 +0000 Subject: [PATCH 13/31] logs: warehouses fetch --- beam/www/beam/stores/init.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/beam/www/beam/stores/init.ts b/beam/www/beam/stores/init.ts index d164de51..56ae8b1f 100644 --- a/beam/www/beam/stores/init.ts +++ b/beam/www/beam/stores/init.ts @@ -17,6 +17,7 @@ export const useInitStore = defineStore('init', () => { await store.setForm(resolvedRoute) await store.setMappedDoc(resolvedRoute) await store.setScanContext(resolvedRoute) + console.log('init: setting warehouses') await store.setWarehouses() // only check store actions to control toggling dirty state (vs. all state mutations); From bd95705b1a11191e3c46b222947c2998afa89913 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Tue, 24 Jun 2025 14:51:19 +0000 Subject: [PATCH 14/31] feat: buttons and listview update --- beam/www/beam/pages/Reconciliation.vue | 120 ++++++++++++++++++++++--- beam/www/beam/types/frappe.ts | 5 +- 2 files changed, 113 insertions(+), 12 deletions(-) diff --git a/beam/www/beam/pages/Reconciliation.vue b/beam/www/beam/pages/Reconciliation.vue index e098bb21..906683a3 100644 --- a/beam/www/beam/pages/Reconciliation.vue +++ b/beam/www/beam/pages/Reconciliation.vue @@ -16,7 +16,8 @@
- + {{ console.log(reconciliation) }} +
Scan or Select Warehouses to Begin
@@ -28,10 +29,10 @@ import { ref, computed, onMounted, watch } from 'vue' import ControlButtons from '@/components/ControlButtons.vue' import { useBeamStore } from '@/stores/beam' -import type { ControlButton, StockReconciliation } from '@/types' +import type { ControlButton, StockReconciliation, StockEntryItem } from '@/types' +import ListView from '@/components/ListView.vue' const store = useBeamStore() -const items = ref([]) const componentKey = ref(0) const reconciliation = computed( (): StockReconciliation => @@ -42,11 +43,17 @@ const reconciliation = computed( set_warehouse: '', } ) - +const items = computed((): StockEntryItem[] => reconciliation.value.items) const warehouseList = ref([]) +store.$subscribe(mutation => { + if (['patch function', 'patch object'].includes(mutation.type)) { + componentKey.value++ + } +}) + onMounted(async () => { - store.$patch(state => (state.cache.mappers['stock-reconciliation'] = reconciliation.value)) + store.$patch(state => (state.cache.mappers['stock-reconciliation'] as StockReconciliation) = reconciliation.value) warehouseList.value = store.warehouseList.filter(w => !w.is_group).map(w => w.name) }) @@ -54,20 +61,97 @@ const clearField = () => store.$patch(state => (state.cache.mappers['stock-recon const loadItems = async warehouse => { try { - const response = await store.getStockReconciliationItems(warehouse) + let response = await store.getStockReconciliationItems(warehouse) if (!response || response.length === 0) return - items.value = response.map(item => ({ + response = response.map(item => ({ ...item, + debounce: 1000, label: item.item_code, - count: { count: item.qty }, - description: item.stock_uom, + count: { count: item.qty, uom: item.stock_uom }, + linkComponent: 'ListCount', })) + store.$patch(state => (state.cache.mappers['stock-reconciliation'] as StockReconciliation).items = response) } catch (error) { console.error('Error loading items:', error) } } -const controlButtons = computed((): ControlButton[] => []) +type StockEntryItemWithCount = StockEntryItem & { count?: { count: number; of?: number } } +const create = async () => { + const body = { + purpose: 'Stock Reconciliation', + set_warehouse: reconciliation.value.set_warehouse, + items: (items.value as StockEntryItemWithCount[]).map(i => ({ + ...i, + qty: typeof i.count === 'object' ? i.count.count : i.qty, + })), + name: reconciliation.value.name, + } + console.log(body) + // let res + // if (body.name) { + // res = await store.update('Stock Reconciliation', body.name, body) + // } else { + // res = await store.insert('Stock Reconciliation', body) + // } + // const { data } = res + // if (data.name) { + // reconciliation.value.name = data.name + // } + // return res +} + +const submit = async () => { + if (!reconciliation.value.name) return + const res = await store.submit('Stock Reconciliation', reconciliation.value.name) + if (res?.data) { + store.$patch(state => { + (state.cache.mappers['stock-reconciliation'] as any) = { + name: '', + purpose: 'Stock Reconciliation', + items: [], + set_warehouse: '', + } + }) + // items.value = [] + } +} + +const cancel = async () => { + store.$patch(state => { + (state.cache.mappers['stock-reconciliation'] as any) = { + name: '', + purpose: 'Stock Reconciliation', + items: [], + set_warehouse: '', + } + }) + // items.value = [] +} + +const controlButtons = computed((): ControlButton[] => { + if (!items.value.length || !reconciliation.value.set_warehouse) return [] + return [ + { + label: 'SAVE', + disabled: items.value.length === 0, + color: { background: '#4791FF', text: 'var(--sc-btn-color)' }, + action: create, + }, + // { + // label: 'SUBMIT', + // disabled: !reconciliation.value.name, + // hidden: !reconciliation.value.name, + // color: { background: 'var(--sc-success)', text: 'var(--sc-btn-color)' }, + // action: submit, + // }, + // { + // label: 'CANCEL', + // color: { background: 'var(--sc-danger)', text: 'var(--sc-btn-color)' }, + // action: cancel, + // }, + ] +}) watch( () => reconciliation.value.set_warehouse, @@ -76,6 +160,22 @@ watch( loadItems(warehouse) } ) + +const updateItem = (value: StockEntryItemWithCount) => { + if (!value || !value.count || !value.count.count) return + let itemModified = false + for (const item of reconciliation.value.items) { + if (item.item_code === value.item_code && item.qty !== value.count.count) { + item.qty = value.count.count + itemModified = true + break + } + } + + if (itemModified) { + store.$patch(state => (state.cache.mappers['stock-reconciliation'] as StockEntryItem) = reconciliation.value) + } +} diff --git a/beam/www/beam/components/ListItem.vue b/beam/www/beam/components/ListItem.vue deleted file mode 100644 index 4233868f..00000000 --- a/beam/www/beam/components/ListItem.vue +++ /dev/null @@ -1,99 +0,0 @@ - - - - - diff --git a/beam/www/beam/components/ListView.vue b/beam/www/beam/components/ListView.vue deleted file mode 100644 index 1fb3e263..00000000 --- a/beam/www/beam/components/ListView.vue +++ /dev/null @@ -1,76 +0,0 @@ - - - - - diff --git a/beam/www/beam/pages/Reconciliation.vue b/beam/www/beam/pages/Reconciliation.vue index 18bb6e83..334bf616 100644 --- a/beam/www/beam/pages/Reconciliation.vue +++ b/beam/www/beam/pages/Reconciliation.vue @@ -29,7 +29,6 @@ import { ref, computed, onMounted, watch } from 'vue' import ControlButtons from '@/components/ControlButtons.vue' import { useBeamStore } from '@/stores/beam' import type { ControlButton, StockReconciliation, StockEntryItem } from '@/types' -import ListView from '@/components/ListView.vue' type StockEntryItemWithCount = StockEntryItem & { count?: { count: number; of: number; uom?: string } } const store = useBeamStore() diff --git a/package.json b/package.json index 6fac20b9..be01b96b 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@stonecrop/aform": "^0.4.11", - "@stonecrop/beam": "^0.4.11", + "@stonecrop/beam": "^0.4.20", "@vueuse/core": "^13.0.0", "acorn": "^8.14.1", "glob": "^11.0.1", diff --git a/yarn.lock b/yarn.lock index 28fde7b6..a4cd1782 100644 --- a/yarn.lock +++ b/yarn.lock @@ -184,11 +184,21 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + "@babel/helper-validator-identifier@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== +"@babel/helper-validator-identifier@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" + integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== + "@babel/helper-validator-option@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72" @@ -218,6 +228,13 @@ dependencies: "@babel/types" "^7.27.0" +"@babel/parser@^7.27.5": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.0.tgz#979829fbab51a29e13901e5a80713dbcb840825e" + integrity sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g== + dependencies: + "@babel/types" "^7.28.0" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz#cc2e53ebf0a0340777fff5ed521943e253b4d8fe" @@ -792,6 +809,14 @@ "@babel/helper-string-parser" "^7.25.9" "@babel/helper-validator-identifier" "^7.25.9" +"@babel/types@^7.28.0": + version "7.28.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.1.tgz#2aaf3c10b31ba03a77ac84f52b3912a0edef4cf9" + integrity sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@esbuild/aix-ppc64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" @@ -1145,16 +1170,16 @@ "@vueuse/core" "^12.7.0" vue "^3.5.13" -"@stonecrop/beam@^0.4.11": - version "0.4.11" - resolved "https://registry.yarnpkg.com/@stonecrop/beam/-/beam-0.4.11.tgz#e6d8b6e3c8faa3de4065caa254beac9db6813ef9" - integrity sha512-S2CSzpYW3AUIoSxCMxh9sJzZV2Bi6mDBwpqdx2VjS7wG/JVGaOEUBRs/58eTzFELR4v7OjtPy198vPPA0hZ2Lw== +"@stonecrop/beam@^0.4.20": + version "0.4.20" + resolved "https://registry.yarnpkg.com/@stonecrop/beam/-/beam-0.4.20.tgz#a7abe1a1467f6bf083ae01ca5935472b38065838" + integrity sha512-WVFyQpEIURm8BlxgnvD0fi77VJ90ttxYA2ySseP/+eMtleYEJAVEAgafYKz5nmmuqKRvq/IpJqL9axhkdUu4RA== dependencies: - "@vueuse/components" "^12.7.0" - "@vueuse/core" "^12.7.0" - mqtt "^5.10.3" + "@vueuse/components" "^13.4.0" + "@vueuse/core" "^13.4.0" + mqtt "^5.13.1" onscan.js "^1.5.2" - vue "^3.5.13" + vue "^3.5.17" "@stonecrop/themes@0.4.11": version "0.4.11" @@ -1226,7 +1251,7 @@ resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz#525433c784aed9b457aaa0ee3d92aeb71f346b63" integrity sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA== -"@types/ws@^8.5.14": +"@types/ws@^8.18.1": version "8.18.1" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== @@ -1261,6 +1286,17 @@ estree-walker "^2.0.2" source-map-js "^1.2.0" +"@vue/compiler-core@3.5.17": + version "3.5.17" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.17.tgz#23d291bd01b863da3ef2e26e7db84d8e01a9b4c5" + integrity sha512-Xe+AittLbAyV0pabcN7cP7/BenRBNcteM4aSDCtRvGw0d9OL+HG1u/XHLY/kt1q4fyMeZYXyIYrsHuPSiDPosA== + dependencies: + "@babel/parser" "^7.27.5" + "@vue/shared" "3.5.17" + entities "^4.5.0" + estree-walker "^2.0.2" + source-map-js "^1.2.1" + "@vue/compiler-dom@3.5.13": version "3.5.13" resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz#bb1b8758dbc542b3658dda973b98a1c9311a8a58" @@ -1269,6 +1305,14 @@ "@vue/compiler-core" "3.5.13" "@vue/shared" "3.5.13" +"@vue/compiler-dom@3.5.17": + version "3.5.17" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.17.tgz#7bc19a20e23b670243a64b47ce3a890239b870be" + integrity sha512-+2UgfLKoaNLhgfhV5Ihnk6wB4ljyW1/7wUIog2puUqajiC29Lp5R/IKDdkebh9jTbTogTbsgB+OY9cEWzG95JQ== + dependencies: + "@vue/compiler-core" "3.5.17" + "@vue/shared" "3.5.17" + "@vue/compiler-sfc@3.5.13", "@vue/compiler-sfc@^3.5.13": version "3.5.13" resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz#461f8bd343b5c06fac4189c4fef8af32dea82b46" @@ -1284,6 +1328,21 @@ postcss "^8.4.48" source-map-js "^1.2.0" +"@vue/compiler-sfc@3.5.17": + version "3.5.17" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.17.tgz#c518871276e26593612bdab36f3f5bcd053b13bf" + integrity sha512-rQQxbRJMgTqwRugtjw0cnyQv9cP4/4BxWfTdRBkqsTfLOHWykLzbOc3C4GGzAmdMDxhzU/1Ija5bTjMVrddqww== + dependencies: + "@babel/parser" "^7.27.5" + "@vue/compiler-core" "3.5.17" + "@vue/compiler-dom" "3.5.17" + "@vue/compiler-ssr" "3.5.17" + "@vue/shared" "3.5.17" + estree-walker "^2.0.2" + magic-string "^0.30.17" + postcss "^8.5.6" + source-map-js "^1.2.1" + "@vue/compiler-ssr@3.5.13": version "3.5.13" resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz#e771adcca6d3d000f91a4277c972a996d07f43ba" @@ -1292,6 +1351,14 @@ "@vue/compiler-dom" "3.5.13" "@vue/shared" "3.5.13" +"@vue/compiler-ssr@3.5.17": + version "3.5.17" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.17.tgz#14ba3b7bba6e0e1fd02002316263165a5d1046c7" + integrity sha512-hkDbA0Q20ZzGgpj5uZjb9rBzQtIHLS78mMilwrlpWk2Ep37DYntUz0PonQ6kr113vfOEdM+zTBuJDaceNIW0tQ== + dependencies: + "@vue/compiler-dom" "3.5.17" + "@vue/shared" "3.5.17" + "@vue/devtools-api@^6.6.4": version "6.6.4" resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343" @@ -1331,6 +1398,13 @@ dependencies: "@vue/shared" "3.5.13" +"@vue/reactivity@3.5.17": + version "3.5.17" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.17.tgz#169b5dcf96c7f23788e5ed9745ec8a7227f2125e" + integrity sha512-l/rmw2STIscWi7SNJp708FK4Kofs97zc/5aEPQh4bOsReD/8ICuBcEmS7KGwDj5ODQLYWVN2lNibKJL1z5b+Lw== + dependencies: + "@vue/shared" "3.5.17" + "@vue/runtime-core@3.5.13": version "3.5.13" resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.13.tgz#1fafa4bf0b97af0ebdd9dbfe98cd630da363a455" @@ -1339,6 +1413,14 @@ "@vue/reactivity" "3.5.13" "@vue/shared" "3.5.13" +"@vue/runtime-core@3.5.17": + version "3.5.17" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.17.tgz#b17bd41e13011e85e9b1025545292d43f5512730" + integrity sha512-QQLXa20dHg1R0ri4bjKeGFKEkJA7MMBxrKo2G+gJikmumRS7PTD4BOU9FKrDQWMKowz7frJJGqBffYMgQYS96Q== + dependencies: + "@vue/reactivity" "3.5.17" + "@vue/shared" "3.5.17" + "@vue/runtime-dom@3.5.13": version "3.5.13" resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz#610fc795de9246300e8ae8865930d534e1246215" @@ -1349,6 +1431,16 @@ "@vue/shared" "3.5.13" csstype "^3.1.3" +"@vue/runtime-dom@3.5.17": + version "3.5.17" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.17.tgz#8e325e29cd03097fe179032fc8df384a426fc83a" + integrity sha512-8El0M60TcwZ1QMz4/os2MdlQECgGoVHPuLnQBU3m9h3gdNRW9xRmI8iLS4t/22OQlOE6aJvNNlBiCzPHur4H9g== + dependencies: + "@vue/reactivity" "3.5.17" + "@vue/runtime-core" "3.5.17" + "@vue/shared" "3.5.17" + csstype "^3.1.3" + "@vue/server-renderer@3.5.13": version "3.5.13" resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.13.tgz#429ead62ee51de789646c22efe908e489aad46f7" @@ -1357,11 +1449,24 @@ "@vue/compiler-ssr" "3.5.13" "@vue/shared" "3.5.13" +"@vue/server-renderer@3.5.17": + version "3.5.17" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.17.tgz#9b8fd6a40a3d55322509fafe78ac841ede649fbe" + integrity sha512-BOHhm8HalujY6lmC3DbqF6uXN/K00uWiEeF22LfEsm9Q93XeJ/plHTepGwf6tqFcF7GA5oGSSAAUock3VvzaCA== + dependencies: + "@vue/compiler-ssr" "3.5.17" + "@vue/shared" "3.5.17" + "@vue/shared@3.5.13": version "3.5.13" resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.13.tgz#87b309a6379c22b926e696893237826f64339b6f" integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ== +"@vue/shared@3.5.17": + version "3.5.17" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.17.tgz#e8b3a41f0be76499882a89e8ed40d86a70fa4b70" + integrity sha512-CabR+UN630VnsJO/jHWYBC1YVXyMq94KKp6iF5MQgZJs5I8cmjw6oVMO1oDbtBkENSHSSn/UadWlW/OAgdmKrg== + "@vueuse/components@^12.7.0": version "12.8.2" resolved "https://registry.yarnpkg.com/@vueuse/components/-/components-12.8.2.tgz#9b896f75f95058f122810010c8025d21ed107c9c" @@ -1371,6 +1476,14 @@ "@vueuse/shared" "12.8.2" vue "^3.5.13" +"@vueuse/components@^13.4.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@vueuse/components/-/components-13.5.0.tgz#ff2a054481f22ef913f5095d0aae55404e93a57e" + integrity sha512-bU/FJNQMCxzDFp67YuxFQSV9CptHxZIgtExjFgJU8AE/gRRJMzGfPjNm+HvaVnMRl8IFFv4E+6JQV0kDu4zIpw== + dependencies: + "@vueuse/core" "13.5.0" + "@vueuse/shared" "13.5.0" + "@vueuse/core@12.8.2", "@vueuse/core@^12.7.0": version "12.8.2" resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-12.8.2.tgz#007c6dd29a7d1f6933e916e7a2f8ef3c3f968eaa" @@ -1381,6 +1494,15 @@ "@vueuse/shared" "12.8.2" vue "^3.5.13" +"@vueuse/core@13.5.0", "@vueuse/core@^13.4.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-13.5.0.tgz#1136d3db088945d7b7a2397170737d5a3e557b36" + integrity sha512-wV7z0eUpifKmvmN78UBZX8T7lMW53Nrk6JP5+6hbzrB9+cJ3jr//hUlhl9TZO/03bUkMK6gGkQpqOPWoabr72g== + dependencies: + "@types/web-bluetooth" "^0.0.21" + "@vueuse/metadata" "13.5.0" + "@vueuse/shared" "13.5.0" + "@vueuse/core@^13.0.0": version "13.0.0" resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-13.0.0.tgz#60bf419e3f9fb003b51f1dfed550afffdb1691ff" @@ -1400,6 +1522,11 @@ resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-13.0.0.tgz#f9c70e1d4958869693e6dcf385d3294cdd304b58" integrity sha512-TRNksqmvtvqsuHf7bbgH9OSXEV2b6+M3BSN4LR5oxWKykOFT9gV78+C2/0++Pq9KCp9KQ1OQDPvGlWNQpOb2Mw== +"@vueuse/metadata@13.5.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-13.5.0.tgz#18c24a32489b0a4fb9d7436efc048e836bfc4799" + integrity sha512-euhItU3b0SqXxSy8u1XHxUCdQ8M++bsRs+TYhOLDU/OykS7KvJnyIFfep0XM5WjIFry9uAPlVSjmVHiqeshmkw== + "@vueuse/shared@12.8.2": version "12.8.2" resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-12.8.2.tgz#b9e4611d0603629c8e151f982459da394e22f930" @@ -1412,6 +1539,11 @@ resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-13.0.0.tgz#4bc454ac359303904d4cf9b23e0dd265be90bf2d" integrity sha512-9MiHhAPw+sqCF/RLo8V6HsjRqEdNEWVpDLm2WBRW2G/kSQjb8X901sozXpSCaeLG0f7TEfMrT4XNaA5m1ez7Dg== +"@vueuse/shared@13.5.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-13.5.0.tgz#c36e3e0eafca9c3b92356ccef139db0df7d9905e" + integrity sha512-K7GrQIxJ/ANtucxIXbQlUHdB0TPA8c+q5i+zbrjxuhJCnJ9GtBg75sBSnvmLSxHKPg2Yo8w62PWksl9kwH0Q8g== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -2327,6 +2459,14 @@ internal-slot@^1.1.0: hasown "^2.0.2" side-channel "^1.1.0" +ip-address@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" + integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== + dependencies: + jsbn "1.1.0" + sprintf-js "^1.1.3" + is-array-buffer@^3.0.4, is-array-buffer@^3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz#65742e1e687bd2cc666253068fd8707fe4d44280" @@ -2578,6 +2718,11 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +jsbn@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== + jsesc@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" @@ -2748,7 +2893,7 @@ mlly@^1.7.4: pkg-types "^1.3.0" ufo "^1.5.4" -mqtt-packet@^9.0.1: +mqtt-packet@^9.0.2: version "9.0.2" resolved "https://registry.yarnpkg.com/mqtt-packet/-/mqtt-packet-9.0.2.tgz#fe6ae2c36fe3f269d11b3fe663b53648f3b3700a" integrity sha512-MvIY0B8/qjq7bKxdN1eD+nrljoeaai+qjLJgfRn3TiMuz0pamsIWY2bFODPZMSNmabsLANXsLl4EMoWvlaTZWA== @@ -2757,24 +2902,24 @@ mqtt-packet@^9.0.1: debug "^4.3.4" process-nextick-args "^2.0.1" -mqtt@^5.10.3: - version "5.10.4" - resolved "https://registry.yarnpkg.com/mqtt/-/mqtt-5.10.4.tgz#f4dba31c366f0c4b2df2a0a4c499e7035b4d70ff" - integrity sha512-wN+SuhT2/ZaG6NPxca0N6YtRivnMxk6VflxQUEeqDH4erKdj+wPAGhHmcTLzvqfE4sJRxrEJ+XJxUc0No0E7eQ== +mqtt@^5.13.1: + version "5.13.2" + resolved "https://registry.yarnpkg.com/mqtt/-/mqtt-5.13.2.tgz#5ae0288e699ddab688e485c93eb0f193584c985d" + integrity sha512-21E15qjFMNEddowGtLiMw4wXfzZxd3Iv+q+zC+tJSmY0flEreNgov+8SKrYcapA+pjClaqj+IgJW0jsJsHkmVQ== dependencies: "@types/readable-stream" "^4.0.18" - "@types/ws" "^8.5.14" + "@types/ws" "^8.18.1" commist "^3.2.0" concat-stream "^2.0.0" debug "^4.4.0" help-me "^5.0.0" lru-cache "^10.4.3" minimist "^1.2.8" - mqtt-packet "^9.0.1" + mqtt-packet "^9.0.2" number-allocator "^1.0.14" readable-stream "^4.7.0" - reinterval "^1.1.0" rfdc "^1.4.1" + socks "^2.8.3" split2 "^4.2.0" worker-timers "^7.1.8" ws "^8.18.0" @@ -2784,7 +2929,7 @@ ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -nanoid@^3.3.8: +nanoid@^3.3.11, nanoid@^3.3.8: version "3.3.11" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== @@ -2942,6 +3087,15 @@ postcss@^8.4.43, postcss@^8.4.48: picocolors "^1.1.1" source-map-js "^1.2.1" +postcss@^8.5.6: + version "8.5.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" + integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== + dependencies: + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" + pretty-bytes@^5.3.0: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" @@ -3090,11 +3244,6 @@ regjsparser@^0.12.0: dependencies: jsesc "~3.0.2" -reinterval@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/reinterval/-/reinterval-1.1.0.tgz#3361ecfa3ca6c18283380dd0bb9546f390f5ece7" - integrity sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ== - require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" @@ -3305,11 +3454,24 @@ signal-exit@^4.0.1: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + smob@^1.0.0: version "1.5.0" resolved "https://registry.yarnpkg.com/smob/-/smob-1.5.0.tgz#85d79a1403abf128d24d3ebc1cdc5e1a9548d3ab" integrity sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig== +socks@^2.8.3: + version "2.8.6" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.6.tgz#e335486a2552f34f932f0c27d8dbb93f2be867aa" + integrity sha512-pe4Y2yzru68lXCb38aAqRf5gvN8YdjP1lok5o0J7BOHljkyCGKVz7H3vpVIXKD27rj2giOJ7DwVyk/GWrPHDWA== + dependencies: + ip-address "^9.0.5" + smart-buffer "^4.2.0" + source-map-js@^1.2.0, source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" @@ -3350,6 +3512,11 @@ split2@^4.2.0: resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== +sprintf-js@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== + "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -3775,6 +3942,17 @@ vue@^3.5.13: "@vue/server-renderer" "3.5.13" "@vue/shared" "3.5.13" +vue@^3.5.17: + version "3.5.17" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.17.tgz#ea8a6a45abb2b0620e7d479319ce8434b55650cf" + integrity sha512-LbHV3xPN9BeljML+Xctq4lbz2lVHCR6DtbpTf5XIO6gugpXUN49j2QQPcMj086r9+AkJ0FfUT8xjulKKBkkr9g== + dependencies: + "@vue/compiler-dom" "3.5.17" + "@vue/compiler-sfc" "3.5.17" + "@vue/runtime-dom" "3.5.17" + "@vue/server-renderer" "3.5.17" + "@vue/shared" "3.5.17" + webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" From 356cbfddf62de1e5b74d765be7daa57489a9ef2e Mon Sep 17 00:00:00 2001 From: lauty95 Date: Thu, 17 Jul 2025 14:47:32 +0000 Subject: [PATCH 26/31] feat: items filtered by valuation_rate --- beam/beam/overrides/stock_reconciliation.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/beam/beam/overrides/stock_reconciliation.py b/beam/beam/overrides/stock_reconciliation.py index d934cad0..c91d23c4 100644 --- a/beam/beam/overrides/stock_reconciliation.py +++ b/beam/beam/overrides/stock_reconciliation.py @@ -24,7 +24,12 @@ def get_items( ) dimensions = get_inventory_dimensions() + filtered_items = [] + for item in items: + if item.get("valuation_rate", 0) == 0: + continue + item_defaults = get_item_defaults(item["item_code"], company) item["stock_uom"] = item_defaults.get("stock_uom") @@ -32,5 +37,7 @@ def get_items( fieldname = dim.get("fieldname") if fieldname and fieldname in item_defaults: item[fieldname] = item_defaults[fieldname] - - return items + + filtered_items.append(item) + + return filtered_items From aa88cdbb1df90e4b5d7982fbfb51752e700bdb72 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Thu, 17 Jul 2025 14:56:18 +0000 Subject: [PATCH 27/31] linters --- beam/beam/overrides/stock_reconciliation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/beam/beam/overrides/stock_reconciliation.py b/beam/beam/overrides/stock_reconciliation.py index c91d23c4..8f4f0b70 100644 --- a/beam/beam/overrides/stock_reconciliation.py +++ b/beam/beam/overrides/stock_reconciliation.py @@ -25,7 +25,7 @@ def get_items( dimensions = get_inventory_dimensions() filtered_items = [] - + for item in items: if item.get("valuation_rate", 0) == 0: continue @@ -37,7 +37,7 @@ def get_items( fieldname = dim.get("fieldname") if fieldname and fieldname in item_defaults: item[fieldname] = item_defaults[fieldname] - + filtered_items.append(item) - + return filtered_items From d9789c64c22f04af99a9cda0a862d4d4ec9f3776 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Fri, 5 Dec 2025 13:16:23 +0000 Subject: [PATCH 28/31] fix: node-version --- .github/workflows/playwright.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml index 4a58f43b..402b5816 100644 --- a/.github/workflows/playwright.yaml +++ b/.github/workflows/playwright.yaml @@ -32,7 +32,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 check-latest: true cache: 'yarn' From 57ef4caa78d2589aa898522ddfc3444fc4e399d8 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Fri, 5 Dec 2025 13:28:43 +0000 Subject: [PATCH 29/31] fix: node-version pytest --- .github/workflows/pytest.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pytest.yaml b/.github/workflows/pytest.yaml index 782381c0..315a8e4b 100644 --- a/.github/workflows/pytest.yaml +++ b/.github/workflows/pytest.yaml @@ -32,7 +32,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 check-latest: true cache: 'yarn' From dc6b4f32683c6dc8dfac9603661eb3408f210c02 Mon Sep 17 00:00:00 2001 From: lauty95 Date: Fri, 5 Dec 2025 17:43:39 +0000 Subject: [PATCH 30/31] test: useHttpStore headers and body changes --- beam/www/beam/stores/http.ts | 83 +++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/beam/www/beam/stores/http.ts b/beam/www/beam/stores/http.ts index f77276d5..38750857 100644 --- a/beam/www/beam/stores/http.ts +++ b/beam/www/beam/stores/http.ts @@ -33,26 +33,87 @@ export const useHttpStore = defineStore('http', () => { const formattedUrl = new URL(fragment, window.location.origin) return await fetch(formattedUrl, { method: 'GET', - headers: headers.value, + headers: { + 'Content-Type': 'application/json', + 'X-Frappe-CSRF-Token': frappe.csrf_token, + }, }) } const post = async (url: string, data: Record) => { const formattedUrl = new URL(url, window.location.origin) - return await fetch(formattedUrl, { - method: 'POST', - headers: headers.value, - body: JSON.stringify(data), - }) + const isFrappeMethod = url.includes('/api/method/') + + if (isFrappeMethod) { + // For Frappe methods, send as FormData + const formData = new URLSearchParams() + if (data) { + for (const [key, value] of Object.entries(data)) { + if (typeof value === 'object') { + formData.append(key, JSON.stringify(value)) + } else { + formData.append(key, String(value)) + } + } + } + return await fetch(formattedUrl, { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'X-Frappe-CSRF-Token': frappe.csrf_token, + 'X-Frappe-CMD': url.replace('/api/method/', ''), + }, + body: formData, + }) + } else { + // For REST API, send as JSON + return await fetch(formattedUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Frappe-CSRF-Token': frappe.csrf_token, + }, + body: JSON.stringify(data), + }) + } } const put = async (url: string, data: Record) => { const formattedUrl = new URL(url, window.location.origin) - return await fetch(formattedUrl, { - method: 'PUT', - headers: headers.value, - body: JSON.stringify(data), - }) + const isFrappeMethod = url.includes('/api/method/') + + if (isFrappeMethod) { + // For Frappe methods, send as FormData + const formData = new URLSearchParams() + if (data) { + for (const [key, value] of Object.entries(data)) { + if (typeof value === 'object') { + formData.append(key, JSON.stringify(value)) + } else { + formData.append(key, String(value)) + } + } + } + return await fetch(formattedUrl, { + method: 'PUT', + headers: { + 'Accept': 'application/json', + 'X-Frappe-CSRF-Token': frappe.csrf_token, + 'X-Frappe-CMD': url.replace('/api/method/', ''), + }, + body: formData, + }) + } else { + // For REST API, send as JSON + return await fetch(formattedUrl, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'X-Frappe-CSRF-Token': frappe.csrf_token, + }, + body: JSON.stringify(data), + }) + } } return { From 596c2a71b2a34177d5432096a3f52bb5d7ea6c6a Mon Sep 17 00:00:00 2001 From: lauty95 Date: Fri, 5 Dec 2025 17:54:22 +0000 Subject: [PATCH 31/31] fix: no computed header --- beam/www/beam/stores/http.ts | 96 ++++++------------------------------ 1 file changed, 16 insertions(+), 80 deletions(-) diff --git a/beam/www/beam/stores/http.ts b/beam/www/beam/stores/http.ts index 38750857..259c18f8 100644 --- a/beam/www/beam/stores/http.ts +++ b/beam/www/beam/stores/http.ts @@ -2,21 +2,12 @@ // For license information, please see license.txt import { defineStore } from 'pinia' -import { computed } from 'vue' declare const frappe: { csrf_token: string } export const useHttpStore = defineStore('http', () => { - const headers = computed(() => { - // setup as a computed property to allow Frappe to set the CSRF token - return { - 'Content-Type': 'application/json', - 'X-Frappe-CSRF-Token': frappe.csrf_token, - } - }) - const formatUrl = (url: string, params?: Record) => { let fragment: string if (params) { @@ -42,84 +33,29 @@ export const useHttpStore = defineStore('http', () => { const post = async (url: string, data: Record) => { const formattedUrl = new URL(url, window.location.origin) - const isFrappeMethod = url.includes('/api/method/') - - if (isFrappeMethod) { - // For Frappe methods, send as FormData - const formData = new URLSearchParams() - if (data) { - for (const [key, value] of Object.entries(data)) { - if (typeof value === 'object') { - formData.append(key, JSON.stringify(value)) - } else { - formData.append(key, String(value)) - } - } - } - return await fetch(formattedUrl, { - method: 'POST', - headers: { - 'Accept': 'application/json', - 'X-Frappe-CSRF-Token': frappe.csrf_token, - 'X-Frappe-CMD': url.replace('/api/method/', ''), - }, - body: formData, - }) - } else { - // For REST API, send as JSON - return await fetch(formattedUrl, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-Frappe-CSRF-Token': frappe.csrf_token, - }, - body: JSON.stringify(data), - }) - } + return await fetch(formattedUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Frappe-CSRF-Token': frappe.csrf_token, + }, + body: JSON.stringify(data), + }) } const put = async (url: string, data: Record) => { const formattedUrl = new URL(url, window.location.origin) - const isFrappeMethod = url.includes('/api/method/') - - if (isFrappeMethod) { - // For Frappe methods, send as FormData - const formData = new URLSearchParams() - if (data) { - for (const [key, value] of Object.entries(data)) { - if (typeof value === 'object') { - formData.append(key, JSON.stringify(value)) - } else { - formData.append(key, String(value)) - } - } - } - return await fetch(formattedUrl, { - method: 'PUT', - headers: { - 'Accept': 'application/json', - 'X-Frappe-CSRF-Token': frappe.csrf_token, - 'X-Frappe-CMD': url.replace('/api/method/', ''), - }, - body: formData, - }) - } else { - // For REST API, send as JSON - return await fetch(formattedUrl, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - 'X-Frappe-CSRF-Token': frappe.csrf_token, - }, - body: JSON.stringify(data), - }) - } + return await fetch(formattedUrl, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'X-Frappe-CSRF-Token': frappe.csrf_token, + }, + body: JSON.stringify(data), + }) } return { - // getters - headers, - // http actions get, post,