Shared Components: - Add CompanySelector.vue and PeriodSelector.vue components - Add AppHeader.vue and SlideMenu.vue layout components - Add shared stores factories (companies.js, accountingPeriod.js) - Add shared routes factories (companies.py, calendar.py) - Add shared models (company.py, calendar.py) - Add shared layout styles (header.css, navigation.css) Data Entry App: - Update CLAUDE.md with prod/test server documentation - Improve nomenclature sync service with better error handling - Update receipts router and CRUD operations - Add company/period stores using shared factories - Update App.vue layout with shared components - Fix OCRUploadZone file handling Reports App: - Refactor stores to use shared factories - Update App.vue to use shared layout components Infrastructure: - Replace start-data-entry.sh with separate dev/test scripts - Add .claude/rules for authentication, backend patterns, etc. - Add implementation plan for OCR receipt improvements - Clean up old documentation files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
197 lines
5.6 KiB
JavaScript
197 lines
5.6 KiB
JavaScript
/**
|
|
* Shared Companies Store Factory
|
|
*
|
|
* Creates a Pinia store for company selection that can be used by any ROA2WEB application.
|
|
* Each app passes its own apiService and auth store instances.
|
|
*
|
|
* Usage:
|
|
* import { createCompaniesStore } from '@shared/frontend/stores/companies';
|
|
* import { apiService } from '../services/api';
|
|
* import { useAuthStore } from './auth';
|
|
* export const useCompanyStore = createCompaniesStore(apiService, useAuthStore);
|
|
*/
|
|
|
|
import { defineStore } from "pinia";
|
|
import { ref, computed, watch } from "vue";
|
|
|
|
/**
|
|
* Factory function to create a companies store
|
|
* @param {Object} apiService - Axios instance configured for the app's API
|
|
* @param {Function} useAuthStore - Reference to the auth store function
|
|
* @returns {Function} Pinia store definition
|
|
*/
|
|
export function createCompaniesStore(apiService, useAuthStore) {
|
|
return defineStore("companies", () => {
|
|
// State
|
|
const companies = ref([]);
|
|
const selectedCompany = ref(null);
|
|
const isLoading = ref(false);
|
|
const error = ref(null);
|
|
|
|
// Initialize from localStorage - per user
|
|
const initializeSelectedCompany = () => {
|
|
const authStore = useAuthStore();
|
|
const username = authStore.user?.username;
|
|
|
|
if (!username) {
|
|
console.log("[Companies] No username available for initialization");
|
|
return null;
|
|
}
|
|
|
|
const key = `selected_company_${username}`;
|
|
const saved = localStorage.getItem(key);
|
|
if (saved) {
|
|
try {
|
|
const company = JSON.parse(saved);
|
|
console.log(`[Companies] Loaded saved company for ${username}:`, company.name);
|
|
return company;
|
|
} catch (e) {
|
|
console.error("Failed to parse saved company", e);
|
|
localStorage.removeItem(key);
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
// Watch for auth user changes to restore selected company
|
|
const authStore = useAuthStore();
|
|
watch(
|
|
() => authStore.user,
|
|
(newUser) => {
|
|
if (newUser && newUser.username && !selectedCompany.value) {
|
|
const restoredCompany = initializeSelectedCompany();
|
|
if (restoredCompany) {
|
|
selectedCompany.value = restoredCompany;
|
|
console.log("[Companies] Restored selected company:", restoredCompany.name);
|
|
}
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
// Getters
|
|
const companyList = computed(() => companies.value);
|
|
const hasCompanies = computed(() => companies.value.length > 0);
|
|
const selectedCompanyId = computed(() => selectedCompany.value?.id_firma || null);
|
|
|
|
const companyListFormatted = computed(() => {
|
|
return companies.value.map((company) => ({
|
|
...company,
|
|
displayName: company.fiscal_code
|
|
? `${company.name} (${company.fiscal_code})`
|
|
: company.name,
|
|
}));
|
|
});
|
|
|
|
// Actions
|
|
const loadCompanies = async () => {
|
|
isLoading.value = true;
|
|
error.value = null;
|
|
|
|
try {
|
|
console.log("[Companies] Loading companies...");
|
|
const response = await apiService.get("/companies");
|
|
companies.value = response.data.companies || [];
|
|
console.log("[Companies] Loaded", companies.value.length, "companies");
|
|
|
|
// Validate saved company is still accessible
|
|
if (selectedCompany.value) {
|
|
const exists = companies.value.find(
|
|
(c) => c.id_firma === selectedCompany.value.id_firma
|
|
);
|
|
if (!exists) {
|
|
console.warn("[Companies] Saved company not accessible, clearing");
|
|
clearSelectedCompany();
|
|
}
|
|
}
|
|
|
|
return { success: true };
|
|
} catch (err) {
|
|
error.value = err.response?.data?.detail || "Failed to load companies";
|
|
console.error("Failed to load companies:", err);
|
|
return { success: false, error: error.value };
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
};
|
|
|
|
const setSelectedCompany = (company) => {
|
|
selectedCompany.value = company;
|
|
|
|
const authStore = useAuthStore();
|
|
const username = authStore.user?.username;
|
|
|
|
if (!username) {
|
|
console.warn("[Companies] Cannot save - no username");
|
|
return;
|
|
}
|
|
|
|
const key = `selected_company_${username}`;
|
|
if (company) {
|
|
localStorage.setItem(key, JSON.stringify(company));
|
|
console.log(`[Companies] Saved company for ${username}:`, company.name);
|
|
} else {
|
|
localStorage.removeItem(key);
|
|
}
|
|
};
|
|
|
|
const clearSelectedCompany = () => {
|
|
selectedCompany.value = null;
|
|
|
|
const authStore = useAuthStore();
|
|
const username = authStore.user?.username;
|
|
|
|
if (username) {
|
|
const key = `selected_company_${username}`;
|
|
localStorage.removeItem(key);
|
|
}
|
|
};
|
|
|
|
const getCompanyById = (id_firma) => {
|
|
return companies.value.find(
|
|
(company) => company.id_firma === parseInt(id_firma)
|
|
);
|
|
};
|
|
|
|
const clearError = () => {
|
|
error.value = null;
|
|
};
|
|
|
|
const reset = () => {
|
|
companies.value = [];
|
|
selectedCompany.value = null;
|
|
isLoading.value = false;
|
|
error.value = null;
|
|
|
|
const authStore = useAuthStore();
|
|
const username = authStore.user?.username;
|
|
if (username) {
|
|
const key = `selected_company_${username}`;
|
|
localStorage.removeItem(key);
|
|
}
|
|
};
|
|
|
|
return {
|
|
// State
|
|
companies,
|
|
selectedCompany,
|
|
isLoading,
|
|
error,
|
|
|
|
// Getters
|
|
companyList,
|
|
companyListFormatted,
|
|
hasCompanies,
|
|
selectedCompanyId,
|
|
|
|
// Actions
|
|
loadCompanies,
|
|
setSelectedCompany,
|
|
clearSelectedCompany,
|
|
getCompanyById,
|
|
clearError,
|
|
reset,
|
|
};
|
|
});
|
|
}
|