diff --git a/src/features/province/components/create-guilds/CreateGuilds.js b/src/features/province/components/create-guilds/CreateGuilds.js index 0cb3884..8b7f592 100644 --- a/src/features/province/components/create-guilds/CreateGuilds.js +++ b/src/features/province/components/create-guilds/CreateGuilds.js @@ -8,7 +8,7 @@ import { Dialog, DialogTitle, DialogContent, - DialogActions + DialogActions, } from "@mui/material"; import { Add as AddIcon } from "@mui/icons-material"; import { Grid } from "../../../../components/grid/Grid"; @@ -22,10 +22,6 @@ import { provinceGetFieldOfWorks } from "../../services/ProvinceGetFieldOfWorks" import { provinceGetTypeActivity } from "../../services/provinceGetTypeActivity"; import { provinceGetRegisterCodeStateService } from "../../services/province-get-register-code-state"; import { mainGetGuildsForUpdateOrCreateService } from "../../services/main-get-guilds-for-update-or-create"; -import { - slaughterGetProvinceService, - slaughterGetCitiesService -} from "../../../slaughter-house/services/slaughter-get-provinces"; import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl"; import { PersonalInfoSection } from "./components/PersonalInfoSection"; import { InquiryForm } from "./components/InquiryForm"; @@ -36,7 +32,7 @@ import { GuildInfoAccordionItem } from "./components/GuildInfoAccordionItem"; import { getValidationSchema, getInitialValues } from "./utils/formUtils"; import { mapResponseDataToFormFields, - prepareSubmitData + prepareSubmitData, } from "./utils/dataMapping"; import { handleSubmitSuccess, handleSubmitError } from "./utils/submitHandlers"; @@ -91,8 +87,6 @@ export const CreateGuilds = ({ guild, updateTable }) => { return []; }); const [cities, setCities] = useState([]); - const [provinces, setProvinces] = useState([]); - const [provinceCities, setProvinceCities] = useState([]); const [typeActivities, setTypeActivities] = useState([]); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [deleteDialogIndex, setDeleteDialogIndex] = useState(null); @@ -119,11 +113,14 @@ export const CreateGuilds = ({ guild, updateTable }) => { gender: values?.gender, first_name: values?.first_name, last_name: values?.last_name, - national_code: values?.last_name, + national_code: values?.national_code, is_alive: values?.is_alive, birth_date: values?.birth_date, father_name: values?.father_name, - mobile: values?.mobile + mobile: values?.mobile, + // Personal info city: always use current selection (guild section has city_name only) + person_city: values?.person_city, + city: values?.city, }; return prepareSubmitData( combinedValues, @@ -137,18 +134,31 @@ export const CreateGuilds = ({ guild, updateTable }) => { (result) => { if (result.payload.error) { handleSubmitError(openNotif, result.payload.error); - } else { - handleSubmitSuccess( - dispatch, - openNotif, - updateTable, - values, - result.payload?.data - ); + return; } + const data = result.payload?.data; + const hasPayloadErrors = + data?.error_count > 0 || (data?.errors?.length ?? 0) > 0; + if (hasPayloadErrors && data?.errors?.length > 0) { + const firstError = data.errors[0]; + const message = + typeof firstError === "string" + ? firstError + : firstError?.result || firstError?.message || "خطا در ثبت"; + handleSubmitError(openNotif, message); + return; + } + handleSubmitSuccess( + dispatch, + + openNotif, + updateTable, + values, + data + ); } ); - } + }, }); useEffect(() => { @@ -166,12 +176,6 @@ export const CreateGuilds = ({ guild, updateTable }) => { dispatch(provinceGetTypeActivity()).then((r) => { setTypeActivities(r.payload.data || []); }); - // Fetch provinces for province/city selection - dispatch(slaughterGetProvinceService()).then((r) => { - if (r?.payload?.data) { - setProvinces(r.payload.data); - } - }); }, []); useEffect(() => { @@ -180,13 +184,13 @@ export const CreateGuilds = ({ guild, updateTable }) => { const guildsForFormik = guildsList.map((guildItem) => { const combinedGuild = { ...guildItem, - user: guild?.user || {} + user: guild?.user || {}, }; const initialValues = getInitialValues(combinedGuild); return { steward: initialValues.steward || false, guild: initialValues.guild || false, - license_number: initialValues.license_number ?? "" + license_number: initialValues.license_number ?? "", }; }); formik.setFieldValue("guilds", guildsForFormik, false).then(() => { @@ -196,51 +200,18 @@ export const CreateGuilds = ({ guild, updateTable }) => { formik.validateForm(); }, []); - // Set province ID from state name when provinces are loaded + // Set city key from person_city name when cities are loaded (e.g. from DB/edit) useEffect(() => { - if ( - formik.values.state && - provinces.length > 0 && - !formik.values.province - ) { - const province = provinces.find((p) => p.name === formik.values.state); - if (province) { - formik.setFieldValue("province", province.key); - } - } - }, [provinces, formik.values.state, formik.values.province]); - - // Fetch cities when province is selected (slaughter API uses province name) - useEffect(() => { - if (formik.values.province) { - const provinceName = - provinces.find((p) => p.key === formik.values.province)?.name || - formik.values.province; - dispatch(slaughterGetCitiesService(provinceName)).then((r) => { - if (r?.payload?.data) { - setProvinceCities(r.payload.data); - } - }); - } else { - setProvinceCities([]); - } - }, [formik.values.province, provinces, dispatch]); - - // Set city ID from person_city name when provinceCities are loaded - useEffect(() => { - if ( - formik.values.person_city && - !formik.values.city && - provinceCities.length > 0 - ) { - const city = provinceCities.find( - (c) => c.name === formik.values.person_city + if (formik.values.person_city && !formik.values.city && cities.length > 0) { + const city = cities.find( + (c) => + (c.name || "").trim() === (formik.values.person_city || "").trim() ); if (city) { - formik.setFieldValue("city", city.key); + formik.setFieldValue("city", city.key ?? city.id ?? ""); } } - }, [provinceCities, formik.values.person_city, formik.values.city]); + }, [cities, formik.values.person_city, formik.values.city]); const mapResponseToFormFields = useCallback( (responseData) => { @@ -267,7 +238,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { const initialGuildValues = guildsData.map((guildItem) => { const combinedGuild = { ...guildItem, - user: responseData.user || {} + user: responseData.user || {}, }; return getInitialValues(combinedGuild); }); @@ -277,7 +248,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { const guildsForFormik = initialGuildValues.map((g) => ({ steward: g.steward ?? false, guild: g.guild ?? false, - license_number: g.license_number ?? "" + license_number: g.license_number ?? "", })); formik.setFieldValue("guilds", guildsForFormik, true).then(() => { formik.validateField("guilds"); @@ -307,7 +278,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { vertical: "top", horizontal: "center", msg: "لطفا کد ملی را وارد کنید", - severity: "error" + severity: "error", }); return; } @@ -317,7 +288,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { vertical: "top", horizontal: "center", msg: "لطفا کد ملی 10 رقمی معتبر وارد کنید", - severity: "error" + severity: "error", }); return; } @@ -325,7 +296,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { dispatch( mainGetGuildsForUpdateOrCreateService({ national_code: inquiryNationalCode, - update: false + update: false, }) ).then((r) => { if (r.payload.error) { @@ -338,7 +309,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { vertical: "top", horizontal: "center", msg: r.payload.error, - severity: "error" + severity: "error", }); if (!isAdmin) { return; @@ -362,7 +333,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { vertical: "top", horizontal: "center", msg: successMsg, - severity: "success" + severity: "success", }); } else { setHasInquiry(false); @@ -378,7 +349,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { openNotif, mapResponseToFormFields, isAdmin, - formik + formik, ]); const handleUpdateFromExternal = useCallback(() => { @@ -387,7 +358,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { vertical: "top", horizontal: "center", msg: "لطفا کد ملی 10 رقمی معتبر وارد کنید", - severity: "error" + severity: "error", }); return; } @@ -395,7 +366,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { dispatch( mainGetGuildsForUpdateOrCreateService({ national_code: formik.values.national_id, - update: true + update: true, }) ).then((r) => { if (r.payload.error) { @@ -404,7 +375,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { vertical: "top", horizontal: "center", msg: r.payload.error, - severity: "error" + severity: "error", }); return; } @@ -412,7 +383,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { if (r.payload.data) { const updateResponse = { ...r.payload.data, - dbRegister: false + dbRegister: false, }; mapResponseToFormFields(updateResponse); setHasInquiry(true); @@ -421,7 +392,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { vertical: "top", horizontal: "center", msg: "اطلاعات از سامانه خارجی بروزرسانی شد", - severity: "success" + severity: "success", }); } else { setHasInquiry(false); @@ -497,14 +468,14 @@ export const CreateGuilds = ({ guild, updateTable }) => { vertical: "top", horizontal: "center", msg: r.payload.error, - severity: "error" + severity: "error", }); } else { openNotif({ vertical: "top", horizontal: "center", msg: "صنف با موفقیت حذف شد", - severity: "success" + severity: "success", }); // Remove from list after successful deletion if (guildsList.length > 1) { @@ -556,7 +527,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { } newValues[index] = { ...newValues[index], - [fieldName]: value + [fieldName]: value, }; return newValues; }); @@ -574,7 +545,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { } updatedGuilds[index] = { ...updatedGuilds[index], - [fieldName]: value + [fieldName]: value, }; formik.setFieldValue("guilds", updatedGuilds, true).then(() => { formik.validateField("guilds"); @@ -615,8 +586,8 @@ export const CreateGuilds = ({ guild, updateTable }) => { : { xs: "96vw", md: "90vw", - nlg: "1280px" - } + nlg: "1280px", + }, }} > {shouldShowUpdateButton && ( @@ -645,9 +616,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { isAdmin={isAdmin} isSuperAdmin={isSuperAdmin} isKillHouse={isKillHouse} - provinces={provinces} - provinceCities={provinceCities} - guildsList={guildsList} + cities={cities} /> { guildActive={guildActive} isAdmin={isAdmin} isSuperAdmin={isSuperAdmin} - cities={ - provinceCities.length > 0 ? provinceCities : cities - } + cities={cities} typeActivities={typeActivities} onDelete={() => handleDeleteGuild(index)} canDelete={ @@ -734,7 +701,7 @@ export const CreateGuilds = ({ guild, updateTable }) => { formData={guildsList.map((guildItem, index) => { const guildValues = guildsFormValues[index]; const combinedValues = { - ...guildValues // Guild-specific info (overrides if same keys exist) + ...guildValues, // Guild-specific info (overrides if same keys exist) }; return prepareSubmitData( combinedValues, diff --git a/src/features/province/components/create-guilds/components/GuildInfoSection.js b/src/features/province/components/create-guilds/components/GuildInfoSection.js index ba1e4c0..9fc3383 100644 --- a/src/features/province/components/create-guilds/components/GuildInfoSection.js +++ b/src/features/province/components/create-guilds/components/GuildInfoSection.js @@ -161,25 +161,30 @@ export const GuildInfoSection = ({ options={ cities ? cities.map((i) => ({ - id: i.key, + id: i.id ?? i.key, label: i.name, })) : [] } - value={ - cities.find((c) => c.name === formik.values.city_name) - ? { - id: cities.find( - (c) => c.name === formik.values.city_name - )?.key, - label: formik.values.city_name, - } - : formik.values.city_name - ? { - id: null, - label: formik.values.city_name, - } - : null + value={(() => { + const c = cities?.find( + (c) => c.name === formik.values.city_name + ); + if (c) + return { + id: c.id ?? c.key, + label: formik.values.city_name, + }; + + if (formik.values.city_name) + return { + id: null, + label: formik.values.city_name, + }; + return null; + })()} + isOptionEqualToValue={(a, b) => + a?.id === b?.id || a?.label === b?.label } onChange={(e, value) => { formik.setFieldValue("city_name", value ? value.label : ""); diff --git a/src/features/province/components/create-guilds/components/PersonalInfoSection.js b/src/features/province/components/create-guilds/components/PersonalInfoSection.js index afb2282..dc83819 100644 --- a/src/features/province/components/create-guilds/components/PersonalInfoSection.js +++ b/src/features/province/components/create-guilds/components/PersonalInfoSection.js @@ -17,7 +17,6 @@ import CakeIcon from "@mui/icons-material/Cake"; import FaceIcon from "@mui/icons-material/Face"; import LocationCityIcon from "@mui/icons-material/LocationCity"; import FavoriteIcon from "@mui/icons-material/Favorite"; -import PublicIcon from "@mui/icons-material/Public"; import { Grid } from "../../../../../components/grid/Grid"; import { SPACING } from "../../../../../data/spacing"; import { LabelField } from "../../../../../components/label-field/LabelField"; @@ -35,8 +34,7 @@ export const PersonalInfoSection = ({ isAdmin, isSuperAdmin, isKillHouse, - provinces = [], - provinceCities = [], + cities = [], }) => { const getGenderDisplay = (gender) => { if (gender === "True" || gender === true) return GENDER_VALUES.MALE; @@ -307,55 +305,6 @@ export const PersonalInfoSection = ({ /> )} - - {isAdmin ? ( - ({ - id: i.key, - label: i.name, - })) - : [] - } - value={ - provinces.find((p) => p.key === formik.values.province) - ? { - id: formik.values.province, - label: - provinces.find( - (p) => p.key === formik.values.province - )?.name || "", - } - : null - } - onChange={(e, value) => { - formik.setFieldValue("province", value ? value.id : ""); - formik.setFieldValue("city", ""); - formik.setFieldValue("person_city", ""); - }} - disabled={guild} - renderInput={(params) => ( - - )} - /> - ) : ( - p.key === formik.values.province) - ?.name || - formik.values.state || - "-" - } - /> - )} - {isAdmin ? ( ({ - id: i.key, + cities + ? cities.map((i) => ({ + id: i.key ?? i.id, label: i.name, })) : [] } - value={ - provinceCities.find((c) => c.key === formik.values.city) - ? { - id: formik.values.city, - label: - provinceCities.find( - (c) => c.key === formik.values.city - )?.name || "", - } - : formik.values.person_city - ? { - id: null, - label: formik.values.person_city, - } - : null - } + value={(() => { + const c = cities.find( + (c) => (c.key ?? c.id) === formik.values.city + ); + if (c) + return { + id: c.key ?? c.id, + label: c.name, + }; + if (formik.values.person_city) + return { + id: null, + label: formik.values.person_city, + }; + return null; + })()} + isOptionEqualToValue={(a, b) => a?.id === b?.id} onChange={(e, value) => { formik.setFieldValue("city", value ? value.id : ""); formik.setFieldValue( @@ -404,7 +353,7 @@ export const PersonalInfoSection = ({ icon={LocationCityIcon} label="شهر" value={ - provinceCities.find((c) => c.key === formik.values.city) + cities.find((c) => (c.key ?? c.id) === formik.values.city) ?.name || formik.values.person_city || "-" diff --git a/src/features/province/components/create-guilds/utils/dataMapping.js b/src/features/province/components/create-guilds/utils/dataMapping.js index caaa016..f9fbc36 100644 --- a/src/features/province/components/create-guilds/utils/dataMapping.js +++ b/src/features/province/components/create-guilds/utils/dataMapping.js @@ -1,34 +1,8 @@ -/** - * Data Mapping Utilities for Create Guilds Form - * - * This module handles mapping data from three different sources: - * - * 1. EDIT MODE: Guild data passed directly as prop when editing existing guild - * - Handled by: getInitialValues() in formUtils.js - * - Data structure: guild object with nested user and address objects - * - * 2. DATABASE INQUIRY: Inquiry by national code returns data from our database - * - Handled by: extractFormFieldsFromDatabaseInquiry() - * - Condition: responseData.dbRegister === true - * - Data structure: responseData.user, responseData.guilds[] with nested address - * - * 3. EXTERNAL API INQUIRY: Inquiry by national code returns data from external system - * - Handled by: extractFormFieldsFromExternalApi() - * - Condition: responseData.dbRegister === false - * - Data structure: responseData.user, responseData.guilds[] with layerTwo object - */ - import { getRoleFromUrl } from "../../../../../utils/getRoleFromUrl"; import { normalizeExternalApiDate, normalizeDatabaseDate } from "./dateUtils"; import { formatDateForSubmit } from "./dateUtils"; /** - * Prepares form data for submission to the API - * - * Three data sources can provide the initial data: - * 1. Edit mode: Guild data passed as prop (guild parameter) - * 2. Database inquiry: Inquiry returns data from our database (hasInquiry === false) - * 3. External API inquiry: Inquiry returns data from external system (hasInquiry === true) * * @param {Object} values - Form values from Formik * @param {Object} guild - Guild data when editing existing guild (edit mode) @@ -58,12 +32,8 @@ export const prepareSubmitData = ( values.birth_date || "", hasInquiry === true ), - // city is for user info (personal info) - use person_city from personal info - city: values.person_city || values.city || "", - // city_name is for guild info + city: values.person_city || "", city_name: values.city_name || "", - // province is stored as ID when selected, or as name from state field - province: values.province || "", address: values.address || "", postalcode: values.postal_code || "", licenseNumber: values.license_number || "", @@ -87,7 +57,7 @@ export const prepareSubmitData = ( title: values.guild_name || "", role: getRoleFromUrl(), has_inquiry: hasInquiry !== null ? hasInquiry : false, - ...(values.active !== null && { active: values.active }) + ...(values.active !== null && { active: values.active }), }; if (guild) { @@ -101,10 +71,6 @@ export const prepareSubmitData = ( return baseData; }; -/** - * Extracts form field values from database inquiry response - * Data source: Inquiry national code which returns data from our database (dbRegister === true) - */ const extractFormFieldsFromDatabaseInquiry = ( responseDataFromDb, inquiryNationalCode @@ -116,8 +82,6 @@ const extractFormFieldsFromDatabaseInquiry = ( ? responseDataFromDb.guilds[0] : {}; const addressFromDb = firstGuildFromDb?.address || {}; - const provinceFromDb = addressFromDb.province || {}; - const cityFromDb = addressFromDb.city || {}; return { // Personal Information Fields @@ -128,7 +92,9 @@ const extractFormFieldsFromDatabaseInquiry = ( birth_date: normalizeDatabaseDate(userFromDb.birthday || ""), father_name: userFromDb.fatherName || "", gender: userFromDb.gender || "", + person_city: userFromDb.city || "", + city: "", is_alive: userFromDb.isAlive === false ? "خیر" @@ -140,9 +106,6 @@ const extractFormFieldsFromDatabaseInquiry = ( // Guild Information Fields guild_name: firstGuildFromDb.guildsName || "", area_activity: firstGuildFromDb.areaActivity || "", - state: provinceFromDb.name || "", - province: provinceFromDb.key || "", - city: cityFromDb.key || "", address: addressFromDb.address || "", license_expire_date: normalizeDatabaseDate( firstGuildFromDb.licenseExpireDate || "" @@ -156,7 +119,13 @@ const extractFormFieldsFromDatabaseInquiry = ( union_name: firstGuildFromDb.unionName || "", postal_code: addressFromDb.postalCode || "", phone_number: firstGuildFromDb.phoneNumber || "", - guild_national_id: firstGuildFromDb.nationalCode || "", + // nationalId (شناسه ملی شرکت) comes from guild.company_identifier when dbRegister true + guild_national_id: + firstGuildFromDb.company_identifier ?? + firstGuildFromDb.companyIdentifier ?? + firstGuildFromDb.nationalCode ?? + firstGuildFromDb.nationalId ?? + "", corporation_name: firstGuildFromDb.companyName || "", // Status Fields (is_foreign_national is at guild level in API response) @@ -187,14 +156,10 @@ const extractFormFieldsFromDatabaseInquiry = ( // Additional Database Fields company_name: firstGuildFromDb.companyName || "", company_identifier: firstGuildFromDb.companyIdentifier || "", - type_activity_name: firstGuildFromDb.typeActivity || "" + type_activity_name: firstGuildFromDb.typeActivity || "", }; }; -/** - * Extracts form field values from external API inquiry response - * Data source: Inquiry national code which doesn't return data from our database (dbRegister === false) - */ const extractFormFieldsFromExternalApi = ( responseDataFromExternalApi, inquiryNationalCode @@ -237,9 +202,7 @@ const extractFormFieldsFromExternalApi = ( // Guild Information Fields guild_name: firstGuildFromExternalApi.title || "", area_activity: firstGuildFromExternalApi.isicname || "", - state: firstGuildFromExternalApi.state || "", - province: "", // External API doesn't provide province ID - city: firstGuildFromExternalApi.city || "", + city: "", // User selects from cities list address: firstGuildFromExternalApi.address || "", license_expire_date: normalizeExternalApiDate( firstGuildFromExternalApi.licenseExpireDate || "" @@ -279,18 +242,10 @@ const extractFormFieldsFromExternalApi = ( guild: typeof firstGuildFromExternalApi.guild === "boolean" ? firstGuildFromExternalApi.guild - : false + : false, }; }; -/** - * Maps response data to form fields based on data source - * - * Three data sources: - * 1. Edit mode: Guild data passed as prop (handled by getInitialValues in formUtils.js) - * 2. Database inquiry: Inquiry national code which returns data from our database (dbRegister === true) - * 3. External API inquiry: Inquiry national code which doesn't return data from our database (dbRegister === false) - */ export const mapResponseDataToFormFields = ( responseData, inquiryNationalCode, diff --git a/src/features/province/components/create-guilds/utils/dateUtils.js b/src/features/province/components/create-guilds/utils/dateUtils.js index 76b0982..ca0f2b0 100644 --- a/src/features/province/components/create-guilds/utils/dateUtils.js +++ b/src/features/province/components/create-guilds/utils/dateUtils.js @@ -145,14 +145,61 @@ export const formatDateForSubmitDatabase = (dateString) => { return normalizedDate.replace(/-/g, "/"); }; -export const formatDateForSubmit = (dateString, isExternalApi = false) => { +/** + * Always formats date for submit as Jalali YYYY/MM/DD with English numerals. + * Used for birthDate and licenseExpireDate (and licenseIssueDate) in every scenario. + * Example: "1403/02/26", "1404/06/10" + */ +export const formatDateForSubmit = (dateString) => { if (!dateString || typeof dateString !== "string") { return ""; } - if (isExternalApi) { - return formatDateForSubmitExternal(dateString); - } else { - return formatDateForSubmitDatabase(dateString); + const normalized = convertPersianToEnglishNumerals(dateString); + + // Already Jalali (YYYY/MM/DD, year < 1500): ensure zero-padded and return + const persianPattern = /^\d{4}\/\d{1,2}\/\d{1,2}$/; + if (persianPattern.test(normalized)) { + const parts = normalized.split("/"); + const py = parseInt(parts[0], 10); + const pm = parseInt(parts[1], 10); + const pd = parseInt(parts[2], 10); + if (py < 1500 && !isNaN(py) && !isNaN(pm) && !isNaN(pd)) { + return `${py}/${String(pm).padStart(2, "0")}/${String(pd).padStart( + 2, + "0" + )}`; + } } + + // Gregorian YYYY-MM-DD or YYYY/MM/DD: convert to Jalali + const gregorianPattern = /^\d{4}[-/]\d{1,2}[-/]\d{1,2}$/; + if (gregorianPattern.test(normalized)) { + const [y, m, d] = normalized.split(/[-/]/).map((s) => parseInt(s, 10)); + if (y > 1500 && !isNaN(y) && !isNaN(m) && !isNaN(d)) { + try { + const gregorianDate = new Date(y, m - 1, d); + const jalaliStr = convertToIranianTime( + gregorianDate.toISOString().split("T")[0] + ); + return convertPersianToEnglishNumerals(jalaliStr).replace(/-/g, "/"); + } catch (e) { + console.error("Error converting to Jalali:", e); + } + } + } + + // Fallback: try parsing as date then convert to Jalali + try { + const date = new Date(normalized.replace(/\//g, "-")); + if (!isNaN(date.getTime())) { + const iso = date.toISOString().split("T")[0]; + const jalaliStr = convertToIranianTime(iso); + return convertPersianToEnglishNumerals(jalaliStr).replace(/-/g, "/"); + } + } catch (e) { + console.error("Error formatting date for submit:", e); + } + + return normalized.replace(/-/g, "/"); }; diff --git a/src/features/province/components/create-guilds/utils/formUtils.js b/src/features/province/components/create-guilds/utils/formUtils.js index 6702291..49a5fe1 100644 --- a/src/features/province/components/create-guilds/utils/formUtils.js +++ b/src/features/province/components/create-guilds/utils/formUtils.js @@ -20,7 +20,6 @@ export const getValidationSchema = (isEditMode) => last_name: yup.string(), guild_name: yup.string(), guild_category: yup.string(), - state: yup.string(), city: yup.string(), address: yup.string(), license_expire_date: yup.string(), @@ -48,14 +47,14 @@ export const getValidationSchema = (isEditMode) => license_number: yup.string().required("شماره مجوز الزامی است"), steward: yup.boolean(), - guild: yup.boolean() + guild: yup.boolean(), }) .test( "steward-guild-required", "برای هر واحد صنفی، حداقل یکی از گزینه‌های مباشر یا صنف باید انتخاب شود", (value) => value?.steward === true || value?.guild === true ) - ) + ), }); /** @@ -71,7 +70,6 @@ export const getInitialValues = (guildDataForEdit) => { // Extract user data from edit mode guild object const userDataFromEdit = guildDataForEdit?.user || {}; const addressDataFromEdit = guildDataForEdit?.address || {}; - const provinceDataFromEdit = addressDataFromEdit?.province || {}; const cityDataFromEdit = addressDataFromEdit?.city || {}; return { @@ -83,15 +81,14 @@ export const getInitialValues = (guildDataForEdit) => { birth_date: normalizeDatabaseDate(userDataFromEdit.birthday || ""), father_name: userDataFromEdit.fatherName || "", gender: userDataFromEdit.gender || "", - person_city: userDataFromEdit.city || "", + person_city: userDataFromEdit.city || cityDataFromEdit?.name || "", + city: cityDataFromEdit?.id ?? cityDataFromEdit?.key ?? "", is_alive: userDataFromEdit.isAlive || "", mobile: userDataFromEdit.mobile || "", // Guild Information Fields (from guild object in edit mode) guild_name: guildDataForEdit?.guildsName || guildDataForEdit?.name || "", area_activity: guildDataForEdit?.areaActivity || "", - state: provinceDataFromEdit.name || "", - province: provinceDataFromEdit.key || "", city_name: cityDataFromEdit.name || "", address: addressDataFromEdit.address || "", license_expire_date: normalizeDatabaseDate( @@ -103,7 +100,13 @@ export const getInitialValues = (guildDataForEdit) => { postal_code: addressDataFromEdit.postalCode || "", phone_number: guildDataForEdit?.phoneNumber || "", license_number: guildDataForEdit?.licenseNumber || "", - guild_national_id: guildDataForEdit?.nationalId || "", + // شناسه ملی شرکت: from company_identifier when dbRegister true + guild_national_id: + guildDataForEdit?.company_identifier ?? + guildDataForEdit?.companyIdentifier ?? + guildDataForEdit?.nationalCode ?? + guildDataForEdit?.nationalId ?? + "", corporation_name: guildDataForEdit?.companyName || "", license_issue_date: normalizeDatabaseDate( guildDataForEdit?.licenseIssueDate || "" @@ -154,9 +157,9 @@ export const getInitialValues = (guildDataForEdit) => { ? guildDataForEdit.guild : typeof guildDataForEdit?.isGuild === "boolean" ? guildDataForEdit.isGuild - : false - } + : false, + }, ] - : [] + : [], }; }; diff --git a/src/features/steward/components/steward-show-allocations/StewardShowAllocations.js b/src/features/steward/components/steward-show-allocations/StewardShowAllocations.js index d115c09..b069e76 100644 --- a/src/features/steward/components/steward-show-allocations/StewardShowAllocations.js +++ b/src/features/steward/components/steward-show-allocations/StewardShowAllocations.js @@ -89,7 +89,10 @@ export const StewardShowAllocations = forwardRef( const updateTable = () => { fetchApiData(1); - handleUpdate(); + // Do not call handleUpdate() here - parent's handleUpdate already calls + // updateTable() on both instances; calling handleUpdate would cause + // infinite recursion (handleUpdate → updateTable → handleUpdate → …). + // Callers that need the parent bars summary refreshed call handleUpdate explicitly. }; useImperativeHandle(ref, () => ({ @@ -264,7 +267,7 @@ export const StewardShowAllocations = forwardRef( useEffect(() => { fetchApiData(1); - }, [dispatch, selectedDate1, selectedDate2, perPage]); + }, [selectedDate1, selectedDate2, perPage]); const handleSubmit = async (event) => { event.preventDefault(); diff --git a/src/features/steward/components/steward-stock/StewardStock.js b/src/features/steward/components/steward-stock/StewardStock.js index 8644bb5..0e4b1a4 100644 --- a/src/features/steward/components/steward-stock/StewardStock.js +++ b/src/features/steward/components/steward-stock/StewardStock.js @@ -43,7 +43,7 @@ export const StewardStock = () => { useEffect(() => { handleUpdate(); - }, [dispatch]); + }, []); return (