commit 9fde654e2f266a2951b9b7749d69a302a2156c54 Author: colaftc Date: Mon Nov 3 17:55:30 2025 +0800 init diff --git a/.env b/.env new file mode 100644 index 0000000..23e43b5 --- /dev/null +++ b/.env @@ -0,0 +1,8 @@ +SECRET_KEY=testing_$weak_secret_is_allowd +DEBUG=True +ALLOWED_HOSTS=*, +DB_HOST=localhost +DB_PORT=5432 +DB_NAME=myapp +DB_USER=postgres +DB_PASSWORD=postgres \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..505a3b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# Virtual environments +.venv diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/copilot.data.migration.agent.xml b/.idea/copilot.data.migration.agent.xml new file mode 100644 index 0000000..4ea72a9 --- /dev/null +++ b/.idea/copilot.data.migration.agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask.xml b/.idea/copilot.data.migration.ask.xml new file mode 100644 index 0000000..7ef04e2 --- /dev/null +++ b/.idea/copilot.data.migration.ask.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask2agent.xml b/.idea/copilot.data.migration.ask2agent.xml new file mode 100644 index 0000000..1f2ea11 --- /dev/null +++ b/.idea/copilot.data.migration.ask2agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.edit.xml b/.idea/copilot.data.migration.edit.xml new file mode 100644 index 0000000..8648f94 --- /dev/null +++ b/.idea/copilot.data.migration.edit.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/dataSources.local.xml b/.idea/dataSources.local.xml new file mode 100644 index 0000000..11840f5 --- /dev/null +++ b/.idea/dataSources.local.xml @@ -0,0 +1,20 @@ + + + + + + " + + + master_key + postgres + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..6289444 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + postgresql + true + org.postgresql.Driver + jdbc:postgresql://localhost:5432/myapp + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e.xml b/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e.xml new file mode 100644 index 0000000..486b3f3 --- /dev/null +++ b/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e.xml @@ -0,0 +1,5720 @@ + + + + + mdy + 1||-9223372036854775808|c|G +1||10|c|G +1||10|C|G +1||10|T|G +4||-9223372036854775808|c|G +4||10|c|G +4||10|C|G +4||10|T|G + 866 + 16.10 + 1762141219 + true ACDT +true ACSST +false ACST +false ACT +false ACWST +true ADT +true AEDT +true AESST +false AEST +false AFT +true AKDT +false AKST +true ALMST +false ALMT +false AMST +false AMT +false ANAST +false ANAT +false ARST +false ART +false AST +true AWSST +false AWST +true AZOST +false AZOT +false AZST +false AZT +false Africa/Abidjan +false Africa/Accra +false Africa/Addis_Ababa +false Africa/Algiers +false Africa/Asmara +false Africa/Asmera +false Africa/Bamako +false Africa/Bangui +false Africa/Banjul +false Africa/Bissau +false Africa/Blantyre +false Africa/Brazzaville +false Africa/Bujumbura +false Africa/Cairo +false Africa/Casablanca +false Africa/Ceuta +false Africa/Conakry +false Africa/Dakar +false Africa/Dar_es_Salaam +false Africa/Djibouti +false Africa/Douala +false Africa/El_Aaiun +false Africa/Freetown +false Africa/Gaborone +false Africa/Harare +false Africa/Johannesburg +false Africa/Juba +false Africa/Kampala +false Africa/Khartoum +false Africa/Kigali +false Africa/Kinshasa +false Africa/Lagos +false Africa/Libreville +false Africa/Lome +false Africa/Luanda +false Africa/Lubumbashi +false Africa/Lusaka +false Africa/Malabo +false Africa/Maputo +false Africa/Maseru +false Africa/Mbabane +false Africa/Mogadishu +false Africa/Monrovia +false Africa/Nairobi +false Africa/Ndjamena +false Africa/Niamey +false Africa/Nouakchott +false Africa/Ouagadougou +false Africa/Porto-Novo +false Africa/Sao_Tome +false Africa/Timbuktu +false Africa/Tripoli +false Africa/Tunis +false Africa/Windhoek +false America/Adak +false America/Anchorage +false America/Anguilla +false America/Antigua +false America/Araguaina +false America/Argentina/Buenos_Aires +false America/Argentina/Catamarca +false America/Argentina/ComodRivadavia +false America/Argentina/Cordoba +false America/Argentina/Jujuy +false America/Argentina/La_Rioja +false America/Argentina/Mendoza +false America/Argentina/Rio_Gallegos +false America/Argentina/Salta +false America/Argentina/San_Juan +false America/Argentina/San_Luis +false America/Argentina/Tucuman +false America/Argentina/Ushuaia +false America/Aruba +false America/Asuncion +false America/Atikokan +false America/Atka +false America/Bahia +false America/Bahia_Banderas +false America/Barbados +false America/Belem +false America/Belize +false America/Blanc-Sablon +false America/Boa_Vista +false America/Bogota +false America/Boise +false America/Buenos_Aires +false America/Cambridge_Bay +false America/Campo_Grande +false America/Cancun +false America/Caracas +false America/Catamarca +false America/Cayenne +false America/Cayman +false America/Chicago +false America/Chihuahua +false America/Ciudad_Juarez +false America/Coral_Harbour +false America/Cordoba +false America/Costa_Rica +false America/Coyhaique +false America/Creston +false America/Cuiaba +false America/Curacao +false America/Danmarkshavn +false America/Dawson +false America/Dawson_Creek +false America/Denver +false America/Detroit +false America/Dominica +false America/Edmonton +false America/Eirunepe +false America/El_Salvador +false America/Ensenada +false America/Fort_Nelson +false America/Fort_Wayne +false America/Fortaleza +false America/Glace_Bay +false America/Godthab +false America/Goose_Bay +false America/Grand_Turk +false America/Grenada +false America/Guadeloupe +false America/Guatemala +false America/Guayaquil +false America/Guyana +false America/Halifax +false America/Havana +false America/Hermosillo +false America/Indiana/Indianapolis +false America/Indiana/Knox +false America/Indiana/Marengo +false America/Indiana/Petersburg +false America/Indiana/Tell_City +false America/Indiana/Vevay +false America/Indiana/Vincennes +false America/Indiana/Winamac +false America/Indianapolis +false America/Inuvik +false America/Iqaluit +false America/Jamaica +false America/Jujuy +false America/Juneau +false America/Kentucky/Louisville +false America/Kentucky/Monticello +false America/Knox_IN +false America/Kralendijk +false America/La_Paz +false America/Lima +false America/Los_Angeles +false America/Louisville +false America/Lower_Princes +false America/Maceio +false America/Managua +false America/Manaus +false America/Marigot +false America/Martinique +false America/Matamoros +false America/Mazatlan +false America/Mendoza +false America/Menominee +false America/Merida +false America/Metlakatla +false America/Mexico_City +false America/Miquelon +false America/Moncton +false America/Monterrey +false America/Montevideo +false America/Montreal +false America/Montserrat +false America/Nassau +false America/New_York +false America/Nipigon +false America/Nome +false America/Noronha +false America/North_Dakota/Beulah +false America/North_Dakota/Center +false America/North_Dakota/New_Salem +false America/Nuuk +false America/Ojinaga +false America/Panama +false America/Pangnirtung +false America/Paramaribo +false America/Phoenix +false America/Port-au-Prince +false America/Port_of_Spain +false America/Porto_Acre +false America/Porto_Velho +false America/Puerto_Rico +false America/Punta_Arenas +false America/Rainy_River +false America/Rankin_Inlet +false America/Recife +false America/Regina +false America/Resolute +false America/Rio_Branco +false America/Rosario +false America/Santa_Isabel +false America/Santarem +true America/Santiago +false America/Santo_Domingo +false America/Sao_Paulo +false America/Scoresbysund +false America/Shiprock +false America/Sitka +false America/St_Barthelemy +false America/St_Johns +false America/St_Kitts +false America/St_Lucia +false America/St_Thomas +false America/St_Vincent +false America/Swift_Current +false America/Tegucigalpa +false America/Thule +false America/Thunder_Bay +false America/Tijuana +false America/Toronto +false America/Tortola +false America/Vancouver +false America/Virgin +false America/Whitehorse +false America/Winnipeg +false America/Yakutat +false America/Yellowknife +false Antarctica/Casey +false Antarctica/Davis +false Antarctica/DumontDUrville +true Antarctica/Macquarie +false Antarctica/Mawson +true Antarctica/McMurdo +false Antarctica/Palmer +false Antarctica/Rothera +true Antarctica/South_Pole +false Antarctica/Syowa +false Antarctica/Troll +false Antarctica/Vostok +false Arctic/Longyearbyen +false Asia/Aden +false Asia/Almaty +false Asia/Amman +false Asia/Anadyr +false Asia/Aqtau +false Asia/Aqtobe +false Asia/Ashgabat +false Asia/Ashkhabad +false Asia/Atyrau +false Asia/Baghdad +false Asia/Bahrain +false Asia/Baku +false Asia/Bangkok +false Asia/Barnaul +false Asia/Beirut +false Asia/Bishkek +false Asia/Brunei +false Asia/Calcutta +false Asia/Chita +false Asia/Choibalsan +false Asia/Chongqing +false Asia/Chungking +false Asia/Colombo +false Asia/Dacca +false Asia/Damascus +false Asia/Dhaka +false Asia/Dili +false Asia/Dubai +false Asia/Dushanbe +false Asia/Famagusta +false Asia/Gaza +false Asia/Harbin +false Asia/Hebron +false Asia/Ho_Chi_Minh +false Asia/Hong_Kong +false Asia/Hovd +false Asia/Irkutsk +false Asia/Istanbul +false Asia/Jakarta +false Asia/Jayapura +false Asia/Jerusalem +false Asia/Kabul +false Asia/Kamchatka +false Asia/Karachi +false Asia/Kashgar +false Asia/Kathmandu +false Asia/Katmandu +false Asia/Khandyga +false Asia/Kolkata +false Asia/Krasnoyarsk +false Asia/Kuala_Lumpur +false Asia/Kuching +false Asia/Kuwait +false Asia/Macao +false Asia/Macau +false Asia/Magadan +false Asia/Makassar +false Asia/Manila +false Asia/Muscat +false Asia/Nicosia +false Asia/Novokuznetsk +false Asia/Novosibirsk +false Asia/Omsk +false Asia/Oral +false Asia/Phnom_Penh +false Asia/Pontianak +false Asia/Pyongyang +false Asia/Qatar +false Asia/Qostanay +false Asia/Qyzylorda +false Asia/Rangoon +false Asia/Riyadh +false Asia/Saigon +false Asia/Sakhalin +false Asia/Samarkand +false Asia/Seoul +false Asia/Shanghai +false Asia/Singapore +false Asia/Srednekolymsk +false Asia/Taipei +false Asia/Tashkent +false Asia/Tbilisi +false Asia/Tehran +false Asia/Tel_Aviv +false Asia/Thimbu +false Asia/Thimphu +false Asia/Tokyo +false Asia/Tomsk +false Asia/Ujung_Pandang +false Asia/Ulaanbaatar +false Asia/Ulan_Bator +false Asia/Urumqi +false Asia/Ust-Nera +false Asia/Vientiane +false Asia/Vladivostok +false Asia/Yakutsk +false Asia/Yangon +false Asia/Yekaterinburg +false Asia/Yerevan +false Atlantic/Azores +false Atlantic/Bermuda +false Atlantic/Canary +false Atlantic/Cape_Verde +false Atlantic/Faeroe +false Atlantic/Faroe +false Atlantic/Jan_Mayen +false Atlantic/Madeira +false Atlantic/Reykjavik +false Atlantic/South_Georgia +false Atlantic/St_Helena +false Atlantic/Stanley +true Australia/ACT +true Australia/Adelaide +false Australia/Brisbane +true Australia/Broken_Hill +true Australia/Canberra +true Australia/Currie +false Australia/Darwin +false Australia/Eucla +true Australia/Hobart +true Australia/LHI +false Australia/Lindeman +true Australia/Lord_Howe +true Australia/Melbourne +true Australia/NSW +false Australia/North +false Australia/Perth +false Australia/Queensland +true Australia/South +true Australia/Sydney +true Australia/Tasmania +true Australia/Victoria +false Australia/West +true Australia/Yancowinna +true BDST +false BDT +false BNT +false BORT +false BOT +false BRA +true BRST +false BRT +true BST +false BTT +false Brazil/Acre +false Brazil/DeNoronha +false Brazil/East +false Brazil/West +true CADT +false CAST +false CCT +true CDT +true CEST +false CET +true CETDST +true CHADT +false CHAST +false CHUT +false CKT +true CLST +true CLT +false COT +false CST +false CST6CDT +false CXT +false Canada/Atlantic +false Canada/Central +false Canada/Eastern +false Canada/Mountain +false Canada/Newfoundland +false Canada/Pacific +false Canada/Saskatchewan +false Canada/Yukon +true Chile/Continental +true Chile/EasterIsland +false Cuba +false DAVT +false DDUT +true EASST +true EAST +false EAT +true EDT +true EEST +false EET +true EETDST +true EGST +false EGT +false EST +false EST5EDT +false Egypt +true Eire +false Etc/GMT +false Etc/GMT+0 +false Etc/GMT+1 +false Etc/GMT+10 +false Etc/GMT+11 +false Etc/GMT+12 +false Etc/GMT+2 +false Etc/GMT+3 +false Etc/GMT+4 +false Etc/GMT+5 +false Etc/GMT+6 +false Etc/GMT+7 +false Etc/GMT+8 +false Etc/GMT+9 +false Etc/GMT-0 +false Etc/GMT-1 +false Etc/GMT-10 +false Etc/GMT-11 +false Etc/GMT-12 +false Etc/GMT-13 +false Etc/GMT-14 +false Etc/GMT-2 +false Etc/GMT-3 +false Etc/GMT-4 +false Etc/GMT-5 +false Etc/GMT-6 +false Etc/GMT-7 +false Etc/GMT-8 +false Etc/GMT-9 +false Etc/GMT0 +false Etc/Greenwich +false Etc/UCT +false Etc/UTC +false Etc/Universal +false Etc/Zulu +false Europe/Amsterdam +false Europe/Andorra +false Europe/Astrakhan +false Europe/Athens +false Europe/Belfast +false Europe/Belgrade +false Europe/Berlin +false Europe/Bratislava +false Europe/Brussels +false Europe/Bucharest +false Europe/Budapest +false Europe/Busingen +false Europe/Chisinau +false Europe/Copenhagen +true Europe/Dublin +false Europe/Gibraltar +false Europe/Guernsey +false Europe/Helsinki +false Europe/Isle_of_Man +false Europe/Istanbul +false Europe/Jersey +false Europe/Kaliningrad +false Europe/Kiev +false Europe/Kirov +false Europe/Kyiv +false Europe/Lisbon +false Europe/Ljubljana +false Europe/London +false Europe/Luxembourg +false Europe/Madrid +false Europe/Malta +false Europe/Mariehamn +false Europe/Minsk +false Europe/Monaco +false Europe/Moscow +false Europe/Nicosia +false Europe/Oslo +false Europe/Paris +false Europe/Podgorica +false Europe/Prague +false Europe/Riga +false Europe/Rome +false Europe/Samara +false Europe/San_Marino +false Europe/Sarajevo +false Europe/Saratov +false Europe/Simferopol +false Europe/Skopje +false Europe/Sofia +false Europe/Stockholm +false Europe/Tallinn +false Europe/Tirane +false Europe/Tiraspol +false Europe/Ulyanovsk +false Europe/Uzhgorod +false Europe/Vaduz +false Europe/Vatican +false Europe/Vienna +false Europe/Vilnius +false Europe/Volgograd +false Europe/Warsaw +false Europe/Zagreb +false Europe/Zaporozhye +false Europe/Zurich +false FET +true FJST +false FJT +false FKST +false FKT +true FNST +false FNT +false Factory +false GALT +false GAMT +false GB +false GB-Eire +false GEST +false GET +false GFT +false GILT +false GMT +false GMT+0 +false GMT-0 +false GMT0 +false GYT +false Greenwich +false HKT +false HST +false Hongkong +false ICT +true IDT +false IOT +false IRKST +false IRKT +false IRT +false IST +false Iceland +false Indian/Antananarivo +false Indian/Chagos +false Indian/Christmas +false Indian/Cocos +false Indian/Comoro +false Indian/Kerguelen +false Indian/Mahe +false Indian/Maldives +false Indian/Mauritius +false Indian/Mayotte +false Indian/Reunion +false Iran +false Israel +false JAYT +false JST +false Jamaica +false Japan +true KDT +true KGST +false KGT +false KOST +false KRAST +false KRAT +false KST +false Kwajalein +true LHDT +false LHST +false LIGT +false LINT +false LKT +false Libya +false MAGST +false MAGT +false MART +false MAWT +true MDT +true MEST +true MESZ +false MET +true METDST +false MEZ +false MHT +false MMT +false MPT +true MSD +false MSK +false MST +false MST7MDT +true MUST +false MUT +false MVT +false MYT +false Mexico/BajaNorte +false Mexico/BajaSur +false Mexico/General +true NDT +false NFT +false NOVST +false NOVT +false NPT +false NST +false NUT +true NZ +true NZ-CHAT +true NZDT +false NZST +false NZT +false Navajo +false OMSST +false OMST +true PDT +false PET +false PETST +false PETT +false PGT +false PHT +true PKST +false PKT +true PMDT +false PMST +false PONT +false PRC +false PST +false PST8PDT +false PWT +true PYST +false PYT +false Pacific/Apia +true Pacific/Auckland +false Pacific/Bougainville +true Pacific/Chatham +false Pacific/Chuuk +true Pacific/Easter +false Pacific/Efate +false Pacific/Enderbury +false Pacific/Fakaofo +false Pacific/Fiji +false Pacific/Funafuti +false Pacific/Galapagos +false Pacific/Gambier +false Pacific/Guadalcanal +false Pacific/Guam +false Pacific/Honolulu +false Pacific/Johnston +false Pacific/Kanton +false Pacific/Kiritimati +false Pacific/Kosrae +false Pacific/Kwajalein +false Pacific/Majuro +false Pacific/Marquesas +false Pacific/Midway +false Pacific/Nauru +false Pacific/Niue +true Pacific/Norfolk +false Pacific/Noumea +false Pacific/Pago_Pago +false Pacific/Palau +false Pacific/Pitcairn +false Pacific/Pohnpei +false Pacific/Ponape +false Pacific/Port_Moresby +false Pacific/Rarotonga +false Pacific/Saipan +false Pacific/Samoa +false Pacific/Tahiti +false Pacific/Tarawa +false Pacific/Tongatapu +false Pacific/Truk +false Pacific/Wake +false Pacific/Wallis +false Pacific/Yap +false Poland +false Portugal +false RET +false ROC +false ROK +true SADT +false SAST +false SCT +false SGT +false Singapore +false TAHT +false TFT +false TJT +false TKT +false TMT +false TOT +false TRUT +false TVT +false Turkey +false UCT +true ULAST +false ULAT +false US/Alaska +false US/Aleutian +false US/Arizona +false US/Central +false US/East-Indiana +false US/Eastern +false US/Hawaii +false US/Indiana-Starke +false US/Michigan +false US/Mountain +false US/Pacific +false US/Samoa +false UT +false UTC +true UYST +false UYT +true UZST +false UZT +false Universal +false VET +false VLAST +false VLAT +false VOLT +false VUT +false W-SU +true WADT +false WAKT +false WAST +false WAT +true WDT +false WET +true WETDST +false WFT +true WGST +false WGT +false XJT +false YAKST +false YAKT +false YAPT +true YEKST +false YEKT +false Z +false Zulu +false posixrules + + + + 1 + 11||10|C|G +11||-9223372036854775808|U|G +11||10|U|G +2200||6171|C|G +2200||-9223372036854775808|U|G +2200||6171|U|G +13273||10|C|G +13273||-9223372036854775808|U|G +13273||10|U|G + 866 + 16384 + postgres + + + default administrative connection database + 5 + postgres + + + 4544 + + + 6304 + + + 6171 + + + 4571 + + + 3373 + 3374 +3375 +3377 + + + 6181 + + + 3374 + + + 3375 + + + 4569 + + + 4200 + + + 3377 + + + 4550 + + + 6182 + + + 4570 + + + 1 + 1 + 1 + 1 + 10 + 1 + 1 + + + 1663 + 1 + postgres + + + 1664 + 1 + postgres + + + block range index (BRIN) access method + 3580 + 1 + index + 335 + brinhandler + pg_catalog + + + b-tree index access method + 403 + 1 + index + 330 + bthandler + pg_catalog + + + GIN index access method + 2742 + 1 + index + 333 + ginhandler + pg_catalog + + + GiST index access method + 783 + 1 + index + 332 + gisthandler + pg_catalog + + + hash index access method + 405 + 1 + index + 331 + hashhandler + pg_catalog + + + heap table access method + 2 + 1 + table + 3 + heap_tableam_handler + pg_catalog + + + SP-GiST index access method + 4000 + 1 + index + 334 + spghandler + pg_catalog + + + explicit + function + 10035 + 1 + 2558 + int4 + pg_catalog + 16 + bool + pg_catalog + 23 + int4 + pg_catalog + + + assignment + function + 10201 + 1 + 2971 + text + pg_catalog + 16 + bool + pg_catalog + 1042 + bpchar + pg_catalog + + + assignment + function + 10191 + 1 + 2971 + text + pg_catalog + 16 + bool + pg_catalog + 25 + text + pg_catalog + + + assignment + function + 10196 + 1 + 2971 + text + pg_catalog + 16 + bool + pg_catalog + 1043 + varchar + pg_catalog + + + explicit + function + 10143 + 1 + 77 + int4 + pg_catalog + 18 + char + pg_catalog + 23 + int4 + pg_catalog + + + assignment + function + 10133 + 1 + 946 + text + pg_catalog + 18 + char + pg_catalog + 1043 + varchar + pg_catalog + + + implicit + function + 10131 + 1 + 946 + text + pg_catalog + 18 + char + pg_catalog + 25 + text + pg_catalog + + + assignment + function + 10132 + 1 + 860 + bpchar + pg_catalog + 18 + char + pg_catalog + 1042 + bpchar + pg_catalog + + + assignment + function + 10135 + 1 + 408 + bpchar + pg_catalog + 19 + name + pg_catalog + 1042 + bpchar + pg_catalog + + + implicit + function + 10134 + 1 + 406 + text + pg_catalog + 19 + name + pg_catalog + 25 + text + pg_catalog + + + assignment + function + 10136 + 1 + 1401 + varchar + pg_catalog + 19 + name + pg_catalog + 1043 + varchar + pg_catalog + + + implicit + function + 10090 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 2206 + regtype + pg_catalog + + + implicit + function + 10060 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 2203 + regoper + pg_catalog + + + implicit + function + 10003 + 1 + 482 + float8 + pg_catalog + 20 + int8 + pg_catalog + 701 + float8 + pg_catalog + + + implicit + function + 10069 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 2204 + regoperator + pg_catalog + + + assignment + function + 10001 + 1 + 480 + int4 + pg_catalog + 20 + int8 + pg_catalog + 23 + int4 + pg_catalog + + + implicit + function + 10044 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 24 + regproc + pg_catalog + + + implicit + function + 10113 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 4096 + regrole + pg_catalog + + + implicit + function + 10120 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 4089 + regnamespace + pg_catalog + + + implicit + function + 10002 + 1 + 652 + float4 + pg_catalog + 20 + int8 + pg_catalog + 700 + float4 + pg_catalog + + + implicit + function + 10104 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 3769 + regdictionary + pg_catalog + + + implicit + function + 10083 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 4191 + regcollation + pg_catalog + + + assignment + function + 10033 + 1 + 3812 + money + pg_catalog + 20 + int8 + pg_catalog + 790 + money + pg_catalog + + + implicit + function + 10037 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 26 + oid + pg_catalog + + + implicit + function + 10097 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 3734 + regconfig + pg_catalog + + + assignment + function + 10000 + 1 + 714 + int2 + pg_catalog + 20 + int8 + pg_catalog + 21 + int2 + pg_catalog + + + explicit + function + 10185 + 1 + 2075 + bit + pg_catalog + 20 + int8 + pg_catalog + 1560 + bit + pg_catalog + + + implicit + function + 10004 + 1 + 1781 + numeric + pg_catalog + 20 + int8 + pg_catalog + 1700 + numeric + pg_catalog + + + implicit + function + 10053 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 2202 + regprocedure + pg_catalog + + + implicit + function + 10076 + 1 + 1287 + oid + pg_catalog + 20 + int8 + pg_catalog + 2205 + regclass + pg_catalog + + + implicit + function + 10045 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 24 + regproc + pg_catalog + + + implicit + function + 10091 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 2206 + regtype + pg_catalog + + + implicit + function + 10084 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 4191 + regcollation + pg_catalog + + + implicit + function + 10070 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 2204 + regoperator + pg_catalog + + + implicit + function + 10038 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 26 + oid + pg_catalog + + + implicit + function + 10009 + 1 + 1782 + numeric + pg_catalog + 21 + int2 + pg_catalog + 1700 + numeric + pg_catalog + + + implicit + function + 10077 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 2205 + regclass + pg_catalog + + + implicit + function + 10006 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 23 + int4 + pg_catalog + + + implicit + function + 10054 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 2202 + regprocedure + pg_catalog + + + implicit + function + 10007 + 1 + 236 + float4 + pg_catalog + 21 + int2 + pg_catalog + 700 + float4 + pg_catalog + + + implicit + function + 10005 + 1 + 754 + int8 + pg_catalog + 21 + int2 + pg_catalog + 20 + int8 + pg_catalog + + + implicit + function + 10114 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 4096 + regrole + pg_catalog + + + implicit + function + 10008 + 1 + 235 + float8 + pg_catalog + 21 + int2 + pg_catalog + 701 + float8 + pg_catalog + + + implicit + function + 10105 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 3769 + regdictionary + pg_catalog + + + implicit + function + 10121 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 4089 + regnamespace + pg_catalog + + + implicit + function + 10061 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 2203 + regoper + pg_catalog + + + implicit + function + 10098 + 1 + 313 + int4 + pg_catalog + 21 + int2 + pg_catalog + 3734 + regconfig + pg_catalog + + + implicit + binary + 10078 + 1 + 23 + int4 + pg_catalog + 2205 + regclass + pg_catalog + + + implicit + binary + 10085 + 1 + 23 + int4 + pg_catalog + 4191 + regcollation + pg_catalog + + + implicit + binary + 10115 + 1 + 23 + int4 + pg_catalog + 4096 + regrole + pg_catalog + + + explicit + function + 10144 + 1 + 78 + char + pg_catalog + 23 + int4 + pg_catalog + 18 + char + pg_catalog + + + implicit + binary + 10122 + 1 + 23 + int4 + pg_catalog + 4089 + regnamespace + pg_catalog + + + implicit + function + 10010 + 1 + 481 + int8 + pg_catalog + 23 + int4 + pg_catalog + 20 + int8 + pg_catalog + + + implicit + binary + 10106 + 1 + 23 + int4 + pg_catalog + 3769 + regdictionary + pg_catalog + + + implicit + binary + 10099 + 1 + 23 + int4 + pg_catalog + 3734 + regconfig + pg_catalog + + + assignment + function + 10011 + 1 + 314 + int2 + pg_catalog + 23 + int4 + pg_catalog + 21 + int2 + pg_catalog + + + implicit + binary + 10092 + 1 + 23 + int4 + pg_catalog + 2206 + regtype + pg_catalog + + + implicit + binary + 10071 + 1 + 23 + int4 + pg_catalog + 2204 + regoperator + pg_catalog + + + implicit + binary + 10062 + 1 + 23 + int4 + pg_catalog + 2203 + regoper + pg_catalog + + + implicit + binary + 10046 + 1 + 23 + int4 + pg_catalog + 24 + regproc + pg_catalog + + + implicit + binary + 10055 + 1 + 23 + int4 + pg_catalog + 2202 + regprocedure + pg_catalog + + + explicit + function + 10034 + 1 + 2557 + bool + pg_catalog + 23 + int4 + pg_catalog + 16 + bool + pg_catalog + + + implicit + function + 10014 + 1 + 1740 + numeric + pg_catalog + 23 + int4 + pg_catalog + 1700 + numeric + pg_catalog + + + implicit + binary + 10039 + 1 + 23 + int4 + pg_catalog + 26 + oid + pg_catalog + + + explicit + function + 10186 + 1 + 1683 + bit + pg_catalog + 23 + int4 + pg_catalog + 1560 + bit + pg_catalog + + + implicit + function + 10012 + 1 + 318 + float4 + pg_catalog + 23 + int4 + pg_catalog + 700 + float4 + pg_catalog + + + implicit + function + 10013 + 1 + 316 + float8 + pg_catalog + 23 + int4 + pg_catalog + 701 + float8 + pg_catalog + + + assignment + function + 10032 + 1 + 3811 + money + pg_catalog + 23 + int4 + pg_catalog + 790 + money + pg_catalog + + + assignment + binary + 10048 + 1 + 24 + regproc + pg_catalog + 23 + int4 + pg_catalog + + + assignment + function + 10047 + 1 + 1288 + int8 + pg_catalog + 24 + regproc + pg_catalog + 20 + int8 + pg_catalog + + + implicit + binary + 10043 + 1 + 24 + regproc + pg_catalog + 26 + oid + pg_catalog + + + implicit + binary + 10049 + 1 + 24 + regproc + pg_catalog + 2202 + regprocedure + pg_catalog + + + implicit + binary + 10125 + 1 + 25 + text + pg_catalog + 1042 + bpchar + pg_catalog + + + implicit + function + 10140 + 1 + 407 + name + pg_catalog + 25 + text + pg_catalog + 19 + name + pg_catalog + + + assignment + function + 10137 + 1 + 944 + char + pg_catalog + 25 + text + pg_catalog + 18 + char + pg_catalog + + + implicit + binary + 10126 + 1 + 25 + text + pg_catalog + 1043 + varchar + pg_catalog + + + explicit + function + 10193 + 1 + 2896 + xml + pg_catalog + 25 + text + pg_catalog + 142 + xml + pg_catalog + + + implicit + function + 10109 + 1 + 1079 + regclass + pg_catalog + 25 + text + pg_catalog + 2205 + regclass + pg_catalog + + + implicit + binary + 10074 + 1 + 26 + oid + pg_catalog + 2205 + regclass + pg_catalog + + + implicit + binary + 10051 + 1 + 26 + oid + pg_catalog + 2202 + regprocedure + pg_catalog + + + implicit + binary + 10095 + 1 + 26 + oid + pg_catalog + 3734 + regconfig + pg_catalog + + + implicit + binary + 10058 + 1 + 26 + oid + pg_catalog + 2203 + regoper + pg_catalog + + + implicit + binary + 10081 + 1 + 26 + oid + pg_catalog + 4191 + regcollation + pg_catalog + + + implicit + binary + 10067 + 1 + 26 + oid + pg_catalog + 2204 + regoperator + pg_catalog + + + implicit + binary + 10042 + 1 + 26 + oid + pg_catalog + 24 + regproc + pg_catalog + + + assignment + function + 10040 + 1 + 1288 + int8 + pg_catalog + 26 + oid + pg_catalog + 20 + int8 + pg_catalog + + + implicit + binary + 10111 + 1 + 26 + oid + pg_catalog + 4096 + regrole + pg_catalog + + + implicit + binary + 10102 + 1 + 26 + oid + pg_catalog + 3769 + regdictionary + pg_catalog + + + implicit + binary + 10088 + 1 + 26 + oid + pg_catalog + 2206 + regtype + pg_catalog + + + assignment + binary + 10041 + 1 + 26 + oid + pg_catalog + 23 + int4 + pg_catalog + + + implicit + binary + 10118 + 1 + 26 + oid + pg_catalog + 4089 + regnamespace + pg_catalog + + + assignment + io + 10214 + 1 + 114 + json + pg_catalog + 3802 + jsonb + pg_catalog + + + assignment + binary + 10202 + 1 + 142 + xml + pg_catalog + 1042 + bpchar + pg_catalog + + + assignment + binary + 10197 + 1 + 142 + xml + pg_catalog + 1043 + varchar + pg_catalog + + + assignment + binary + 10192 + 1 + 142 + xml + pg_catalog + 25 + text + pg_catalog + + + implicit + binary + 10145 + 1 + 194 + pg_node_tree + pg_catalog + 25 + text + pg_catalog + + + assignment + function + 10165 + 1 + 4091 + box + pg_catalog + 600 + point + pg_catalog + 603 + box + pg_catalog + + + explicit + function + 10166 + 1 + 1532 + point + pg_catalog + 601 + lseg + pg_catalog + 600 + point + pg_catalog + + + assignment + function + 10167 + 1 + 1449 + polygon + pg_catalog + 602 + path + pg_catalog + 604 + polygon + pg_catalog + + + explicit + function + 10168 + 1 + 1534 + point + pg_catalog + 603 + box + pg_catalog + 600 + point + pg_catalog + + + explicit + function + 10171 + 1 + 1479 + circle + pg_catalog + 603 + box + pg_catalog + 718 + circle + pg_catalog + + + explicit + function + 10169 + 1 + 1541 + lseg + pg_catalog + 603 + box + pg_catalog + 601 + lseg + pg_catalog + + + assignment + function + 10170 + 1 + 1448 + polygon + pg_catalog + 603 + box + pg_catalog + 604 + polygon + pg_catalog + + + explicit + function + 10172 + 1 + 1540 + point + pg_catalog + 604 + polygon + pg_catalog + 600 + point + pg_catalog + + + explicit + function + 10175 + 1 + 1474 + circle + pg_catalog + 604 + polygon + pg_catalog + 718 + circle + pg_catalog + + + explicit + function + 10174 + 1 + 1446 + box + pg_catalog + 604 + polygon + pg_catalog + 603 + box + pg_catalog + + + assignment + function + 10173 + 1 + 1447 + path + pg_catalog + 604 + polygon + pg_catalog + 602 + path + pg_catalog + + + assignment + function + 10194 + 1 + 730 + text + pg_catalog + 650 + cidr + pg_catalog + 1043 + varchar + pg_catalog + + + assignment + function + 10199 + 1 + 730 + text + pg_catalog + 650 + cidr + pg_catalog + 1042 + bpchar + pg_catalog + + + assignment + function + 10189 + 1 + 730 + text + pg_catalog + 650 + cidr + pg_catalog + 25 + text + pg_catalog + + + implicit + binary + 10181 + 1 + 650 + cidr + pg_catalog + 869 + inet + pg_catalog + + + assignment + function + 10016 + 1 + 238 + int2 + pg_catalog + 700 + float4 + pg_catalog + 21 + int2 + pg_catalog + + + assignment + function + 10015 + 1 + 653 + int8 + pg_catalog + 700 + float4 + pg_catalog + 20 + int8 + pg_catalog + + + implicit + function + 10018 + 1 + 311 + float8 + pg_catalog + 700 + float4 + pg_catalog + 701 + float8 + pg_catalog + + + assignment + function + 10019 + 1 + 1742 + numeric + pg_catalog + 700 + float4 + pg_catalog + 1700 + numeric + pg_catalog + + + assignment + function + 10017 + 1 + 319 + int4 + pg_catalog + 700 + float4 + pg_catalog + 23 + int4 + pg_catalog + + + assignment + function + 10024 + 1 + 1743 + numeric + pg_catalog + 701 + float8 + pg_catalog + 1700 + numeric + pg_catalog + + + assignment + function + 10020 + 1 + 483 + int8 + pg_catalog + 701 + float8 + pg_catalog + 20 + int8 + pg_catalog + + + assignment + function + 10021 + 1 + 237 + int2 + pg_catalog + 701 + float8 + pg_catalog + 21 + int2 + pg_catalog + + + assignment + function + 10022 + 1 + 317 + int4 + pg_catalog + 701 + float8 + pg_catalog + 23 + int4 + pg_catalog + + + assignment + function + 10023 + 1 + 312 + float4 + pg_catalog + 701 + float8 + pg_catalog + 700 + float4 + pg_catalog + + + explicit + function + 10178 + 1 + 1544 + polygon + pg_catalog + 718 + circle + pg_catalog + 604 + polygon + pg_catalog + + + explicit + function + 10176 + 1 + 1416 + point + pg_catalog + 718 + circle + pg_catalog + 600 + point + pg_catalog + + + explicit + function + 10177 + 1 + 1480 + box + pg_catalog + 718 + circle + pg_catalog + 603 + box + pg_catalog + + + implicit + function + 10180 + 1 + 4124 + macaddr + pg_catalog + 774 + macaddr8 + pg_catalog + 829 + macaddr + pg_catalog + + + assignment + function + 10030 + 1 + 3823 + numeric + pg_catalog + 790 + money + pg_catalog + 1700 + numeric + pg_catalog + + + implicit + function + 10179 + 1 + 4123 + macaddr8 + pg_catalog + 829 + macaddr + pg_catalog + 774 + macaddr8 + pg_catalog + + + assignment + function + 10195 + 1 + 730 + text + pg_catalog + 869 + inet + pg_catalog + 1043 + varchar + pg_catalog + + + assignment + function + 10190 + 1 + 730 + text + pg_catalog + 869 + inet + pg_catalog + 25 + text + pg_catalog + + + assignment + function + 10182 + 1 + 1715 + cidr + pg_catalog + 869 + inet + pg_catalog + 650 + cidr + pg_catalog + + + assignment + function + 10200 + 1 + 730 + text + pg_catalog + 869 + inet + pg_catalog + 1042 + bpchar + pg_catalog + + + implicit + function + 10204 + 1 + 668 + bpchar + pg_catalog + 1042 + bpchar + pg_catalog + 1042 + bpchar + pg_catalog + + + implicit + function + 10128 + 1 + 401 + text + pg_catalog + 1042 + bpchar + pg_catalog + 1043 + varchar + pg_catalog + + + explicit + function + 10203 + 1 + 2896 + xml + pg_catalog + 1042 + bpchar + pg_catalog + 142 + xml + pg_catalog + + + implicit + function + 10127 + 1 + 401 + text + pg_catalog + 1042 + bpchar + pg_catalog + 25 + text + pg_catalog + + + assignment + function + 10138 + 1 + 944 + char + pg_catalog + 1042 + bpchar + pg_catalog + 18 + char + pg_catalog + + + implicit + function + 10141 + 1 + 409 + name + pg_catalog + 1042 + bpchar + pg_catalog + 19 + name + pg_catalog + + + implicit + binary + 10129 + 1 + 1043 + varchar + pg_catalog + 25 + text + pg_catalog + + + implicit + function + 10142 + 1 + 1400 + name + pg_catalog + 1043 + varchar + pg_catalog + 19 + name + pg_catalog + + + implicit + binary + 10130 + 1 + 1043 + varchar + pg_catalog + 1042 + bpchar + pg_catalog + + + explicit + function + 10198 + 1 + 2896 + xml + pg_catalog + 1043 + varchar + pg_catalog + 142 + xml + pg_catalog + + + implicit + function + 10110 + 1 + 1079 + regclass + pg_catalog + 1043 + varchar + pg_catalog + 2205 + regclass + pg_catalog + + + implicit + function + 10205 + 1 + 669 + varchar + pg_catalog + 1043 + varchar + pg_catalog + 1043 + varchar + pg_catalog + + + assignment + function + 10139 + 1 + 944 + char + pg_catalog + 1043 + varchar + pg_catalog + 18 + char + pg_catalog + + + implicit + function + 10152 + 1 + 2024 + timestamp + pg_catalog + 1082 + date + pg_catalog + 1114 + timestamp + pg_catalog + + + implicit + function + 10153 + 1 + 1174 + timestamptz + pg_catalog + 1082 + date + pg_catalog + 1184 + timestamptz + pg_catalog + + + implicit + function + 10206 + 1 + 1968 + time + pg_catalog + 1083 + time + pg_catalog + 1083 + time + pg_catalog + + + implicit + function + 10155 + 1 + 2047 + timetz + pg_catalog + 1083 + time + pg_catalog + 1266 + timetz + pg_catalog + + + implicit + function + 10154 + 1 + 1370 + interval + pg_catalog + 1083 + time + pg_catalog + 1186 + interval + pg_catalog + + + implicit + function + 10158 + 1 + 2028 + timestamptz + pg_catalog + 1114 + timestamp + pg_catalog + 1184 + timestamptz + pg_catalog + + + assignment + function + 10156 + 1 + 2029 + date + pg_catalog + 1114 + timestamp + pg_catalog + 1082 + date + pg_catalog + + + assignment + function + 10157 + 1 + 1316 + time + pg_catalog + 1114 + timestamp + pg_catalog + 1083 + time + pg_catalog + + + implicit + function + 10207 + 1 + 1961 + timestamp + pg_catalog + 1114 + timestamp + pg_catalog + 1114 + timestamp + pg_catalog + + + assignment + function + 10159 + 1 + 1178 + date + pg_catalog + 1184 + timestamptz + pg_catalog + 1082 + date + pg_catalog + + + assignment + function + 10162 + 1 + 1388 + timetz + pg_catalog + 1184 + timestamptz + pg_catalog + 1266 + timetz + pg_catalog + + + assignment + function + 10160 + 1 + 2019 + time + pg_catalog + 1184 + timestamptz + pg_catalog + 1083 + time + pg_catalog + + + assignment + function + 10161 + 1 + 2027 + timestamp + pg_catalog + 1184 + timestamptz + pg_catalog + 1114 + timestamp + pg_catalog + + + implicit + function + 10208 + 1 + 1967 + timestamptz + pg_catalog + 1184 + timestamptz + pg_catalog + 1184 + timestamptz + pg_catalog + + + implicit + function + 10209 + 1 + 1200 + interval + pg_catalog + 1186 + interval + pg_catalog + 1186 + interval + pg_catalog + + + assignment + function + 10163 + 1 + 1419 + time + pg_catalog + 1186 + interval + pg_catalog + 1083 + time + pg_catalog + + + assignment + function + 10164 + 1 + 2046 + time + pg_catalog + 1266 + timetz + pg_catalog + 1083 + time + pg_catalog + + + implicit + function + 10210 + 1 + 1969 + timetz + pg_catalog + 1266 + timetz + pg_catalog + 1266 + timetz + pg_catalog + + + explicit + function + 10187 + 1 + 2076 + int8 + pg_catalog + 1560 + bit + pg_catalog + 20 + int8 + pg_catalog + + + implicit + function + 10211 + 1 + 1685 + bit + pg_catalog + 1560 + bit + pg_catalog + 1560 + bit + pg_catalog + + + implicit + binary + 10183 + 1 + 1560 + bit + pg_catalog + 1562 + varbit + pg_catalog + + + explicit + function + 10188 + 1 + 1684 + int4 + pg_catalog + 1560 + bit + pg_catalog + 23 + int4 + pg_catalog + + + implicit + binary + 10184 + 1 + 1562 + varbit + pg_catalog + 1560 + bit + pg_catalog + + + implicit + function + 10212 + 1 + 1687 + varbit + pg_catalog + 1562 + varbit + pg_catalog + 1562 + varbit + pg_catalog + + + assignment + function + 10025 + 1 + 1779 + int8 + pg_catalog + 1700 + numeric + pg_catalog + 20 + int8 + pg_catalog + + + assignment + function + 10026 + 1 + 1783 + int2 + pg_catalog + 1700 + numeric + pg_catalog + 21 + int2 + pg_catalog + + + assignment + function + 10027 + 1 + 1744 + int4 + pg_catalog + 1700 + numeric + pg_catalog + 23 + int4 + pg_catalog + + + implicit + function + 10213 + 1 + 1703 + numeric + pg_catalog + 1700 + numeric + pg_catalog + 1700 + numeric + pg_catalog + + + implicit + function + 10029 + 1 + 1746 + float8 + pg_catalog + 1700 + numeric + pg_catalog + 701 + float8 + pg_catalog + + + assignment + function + 10031 + 1 + 3824 + money + pg_catalog + 1700 + numeric + pg_catalog + 790 + money + pg_catalog + + + implicit + function + 10028 + 1 + 1745 + float4 + pg_catalog + 1700 + numeric + pg_catalog + 700 + float4 + pg_catalog + + + assignment + binary + 10057 + 1 + 2202 + regprocedure + pg_catalog + 23 + int4 + pg_catalog + + + implicit + binary + 10052 + 1 + 2202 + regprocedure + pg_catalog + 26 + oid + pg_catalog + + + assignment + function + 10056 + 1 + 1288 + int8 + pg_catalog + 2202 + regprocedure + pg_catalog + 20 + int8 + pg_catalog + + + implicit + binary + 10050 + 1 + 2202 + regprocedure + pg_catalog + 24 + regproc + pg_catalog + + + implicit + binary + 10065 + 1 + 2203 + regoper + pg_catalog + 2204 + regoperator + pg_catalog + + + assignment + function + 10063 + 1 + 1288 + int8 + pg_catalog + 2203 + regoper + pg_catalog + 20 + int8 + pg_catalog + + + implicit + binary + 10059 + 1 + 2203 + regoper + pg_catalog + 26 + oid + pg_catalog + + + assignment + binary + 10064 + 1 + 2203 + regoper + pg_catalog + 23 + int4 + pg_catalog + + + assignment + binary + 10073 + 1 + 2204 + regoperator + pg_catalog + 23 + int4 + pg_catalog + + + implicit + binary + 10068 + 1 + 2204 + regoperator + pg_catalog + 26 + oid + pg_catalog + + + assignment + function + 10072 + 1 + 1288 + int8 + pg_catalog + 2204 + regoperator + pg_catalog + 20 + int8 + pg_catalog + + + implicit + binary + 10066 + 1 + 2204 + regoperator + pg_catalog + 2203 + regoper + pg_catalog + + + assignment + function + 10079 + 1 + 1288 + int8 + pg_catalog + 2205 + regclass + pg_catalog + 20 + int8 + pg_catalog + + + implicit + binary + 10075 + 1 + 2205 + regclass + pg_catalog + 26 + oid + pg_catalog + + + assignment + binary + 10080 + 1 + 2205 + regclass + pg_catalog + 23 + int4 + pg_catalog + + + assignment + function + 10093 + 1 + 1288 + int8 + pg_catalog + 2206 + regtype + pg_catalog + 20 + int8 + pg_catalog + + + assignment + binary + 10094 + 1 + 2206 + regtype + pg_catalog + 23 + int4 + pg_catalog + + + implicit + binary + 10089 + 1 + 2206 + regtype + pg_catalog + 26 + oid + pg_catalog + + + implicit + binary + 10146 + 1 + 3361 + pg_ndistinct + pg_catalog + 17 + bytea + pg_catalog + + + implicit + io + 10147 + 1 + 3361 + pg_ndistinct + pg_catalog + 25 + text + pg_catalog + + + implicit + binary + 10148 + 1 + 3402 + pg_dependencies + pg_catalog + 17 + bytea + pg_catalog + + + implicit + io + 10149 + 1 + 3402 + pg_dependencies + pg_catalog + 25 + text + pg_catalog + + + implicit + binary + 10096 + 1 + 3734 + regconfig + pg_catalog + 26 + oid + pg_catalog + + + assignment + function + 10100 + 1 + 1288 + int8 + pg_catalog + 3734 + regconfig + pg_catalog + 20 + int8 + pg_catalog + + + assignment + binary + 10101 + 1 + 3734 + regconfig + pg_catalog + 23 + int4 + pg_catalog + + + implicit + binary + 10103 + 1 + 3769 + regdictionary + pg_catalog + 26 + oid + pg_catalog + + + assignment + binary + 10108 + 1 + 3769 + regdictionary + pg_catalog + 23 + int4 + pg_catalog + + + assignment + function + 10107 + 1 + 1288 + int8 + pg_catalog + 3769 + regdictionary + pg_catalog + 20 + int8 + pg_catalog + + + assignment + io + 10215 + 1 + 3802 + jsonb + pg_catalog + 114 + json + pg_catalog + + + explicit + function + 10218 + 1 + 3450 + int2 + pg_catalog + 3802 + jsonb + pg_catalog + 21 + int2 + pg_catalog + + + explicit + function + 10220 + 1 + 3452 + int8 + pg_catalog + 3802 + jsonb + pg_catalog + 20 + int8 + pg_catalog + + + explicit + function + 10219 + 1 + 3451 + int4 + pg_catalog + 3802 + jsonb + pg_catalog + 23 + int4 + pg_catalog + + + explicit + function + 10216 + 1 + 3556 + bool + pg_catalog + 3802 + jsonb + pg_catalog + 16 + bool + pg_catalog + + + explicit + function + 10221 + 1 + 3453 + float4 + pg_catalog + 3802 + jsonb + pg_catalog + 700 + float4 + pg_catalog + + + explicit + function + 10217 + 1 + 3449 + numeric + pg_catalog + 3802 + jsonb + pg_catalog + 1700 + numeric + pg_catalog + + + explicit + function + 10222 + 1 + 2580 + float8 + pg_catalog + 3802 + jsonb + pg_catalog + 701 + float8 + pg_catalog + + + explicit + function + 10223 + 1 + 4281 + int4multirange + pg_catalog + 3904 + int4range + pg_catalog + 4451 + int4multirange + pg_catalog + + + explicit + function + 10225 + 1 + 4284 + nummultirange + pg_catalog + 3906 + numrange + pg_catalog + 4532 + nummultirange + pg_catalog + + + explicit + function + 10227 + 1 + 4287 + tsmultirange + pg_catalog + 3908 + tsrange + pg_catalog + 4533 + tsmultirange + pg_catalog + + + explicit + function + 10228 + 1 + 4290 + tstzmultirange + pg_catalog + 3910 + tstzrange + pg_catalog + 4534 + tstzmultirange + pg_catalog + + + explicit + function + 10226 + 1 + 4293 + datemultirange + pg_catalog + 3912 + daterange + pg_catalog + 4535 + datemultirange + pg_catalog + + + explicit + function + 10224 + 1 + 4296 + int8multirange + pg_catalog + 3926 + int8range + pg_catalog + 4536 + int8multirange + pg_catalog + + + assignment + binary + 10124 + 1 + 4089 + regnamespace + pg_catalog + 23 + int4 + pg_catalog + + + assignment + function + 10123 + 1 + 1288 + int8 + pg_catalog + 4089 + regnamespace + pg_catalog + 20 + int8 + pg_catalog + + + implicit + binary + 10119 + 1 + 4089 + regnamespace + pg_catalog + 26 + oid + pg_catalog + + + assignment + binary + 10117 + 1 + 4096 + regrole + pg_catalog + 23 + int4 + pg_catalog + + + implicit + binary + 10112 + 1 + 4096 + regrole + pg_catalog + 26 + oid + pg_catalog + + + assignment + function + 10116 + 1 + 1288 + int8 + pg_catalog + 4096 + regrole + pg_catalog + 20 + int8 + pg_catalog + + + assignment + function + 10086 + 1 + 1288 + int8 + pg_catalog + 4191 + regcollation + pg_catalog + 20 + int8 + pg_catalog + + + assignment + binary + 10087 + 1 + 4191 + regcollation + pg_catalog + 23 + int4 + pg_catalog + + + implicit + binary + 10082 + 1 + 4191 + regcollation + pg_catalog + 26 + oid + pg_catalog + + + implicit + binary + 10150 + 1 + 5017 + pg_mcv_list + pg_catalog + 17 + bytea + pg_catalog + + + implicit + io + 10151 + 1 + 5017 + pg_mcv_list + pg_catalog + 25 + text + pg_catalog + + + explicit + function + 10036 + 1 + 5071 + xid + pg_catalog + 5069 + xid8 + pg_catalog + 28 + xid + pg_catalog + + + PL/pgSQL procedural language + 13625 + 684 + 1.0 + 11 + pg_catalog + 13626 +13627 +13628 +13629 + + + dynamically-loaded C functions + 13 + 1 + fmgr_c_validator + pg_catalog + + + built-in functions + 12 + 1 + fmgr_internal_validator + pg_catalog + + + PL/pgSQL procedural language + plpgsql_call_handler + pg_catalog + plpgsql_inline_handler + pg_catalog + 13629 + 684 + 1 + plpgsql_validator + pg_catalog + + + SQL-language functions + 14 + 1 + 1 + fmgr_sql_validator + pg_catalog + + + 13273 + 530 + postgres + + + system catalog schema + 11 + 524 + postgres + + + 3 + standard public schema + 1 + 866 + 866 + 866 + 3 + 2025-11-03.05:32:46 + 2200 + 524 + pg_database_owner + + + 2 + 16411 + 1 + 1 + 745 + integer|0s + postgres + + + 2 + 16419 + 1 + 1 + 745 + bigint|0s + postgres + + + 2 + 16405 + 1 + 1 + 745 + integer|0s + postgres + + + 2 + 16433 + 1 + 1 + 745 + bigint|0s + postgres + + + 2 + 16425 + 1 + 1 + 745 + integer|0s + postgres + + + 2 + 16439 + 1 + 1 + 745 + bigint|0s + postgres + + + 2 + 16497 + 1 + 1 + 747 + integer|0s + postgres + + + 2 + 16397 + 1 + 1 + 744 + integer|0s + postgres + + + 2 + 16389 + 1 + 1 + 743 + bigint|0s + postgres + + + 2 + 16588 + 1 + 1 + 807 + bigint|0s + postgres + + + 2 + 16596 + 1 + 1 + 856 + bigint|0s + postgres + + + 2 + 16543 + 1 + 1 + 773 + bigint|0s + postgres + + + 2 + 16535 + 1 + 1 + 773 + bigint|0s + postgres + + + 2 + 16566 + 1 + 1 + 799 + bigint|0s + postgres + + + 2 + 16557 + 1 + 1 + 792 + bigint|0s + postgres + + + 2 + 16412 + 745 + 2 + postgres +
+ + 2 + 16420 + 745 + 2 + postgres +
+ + 2 + 16406 + 745 + 2 + postgres +
+ + 2 + 16426 + 758 + 2 + postgres +
+ + 2 + 16434 + 745 + 2 + postgres +
+ + 2 + 16440 + 745 + 2 + postgres +
+ + 2 + 16498 + 747 + 2 + postgres +
+ + 2 + 16398 + 745 + 2 + postgres +
+ + 2 + 16390 + 743 + 2 + postgres +
+ + 2 + 16526 + 763 + 2 + postgres +
+ + 2 + 16589 + 807 + 2 + postgres +
+ + 2 + 16597 + 856 + 2 + postgres +
+ + 2 + 16544 + 805 + 2 + postgres +
+ + 2 + 16536 + 816 + 2 + postgres +
+ + 2 + 16567 + 805 + 2 + postgres +
+ + 2 + 16558 + 805 + 2 + postgres +
+ + by-default + 1 + 1 + 745 + integer|0s + 16411 + 23 + + + 1 + 2 + 760 + varchar(150)|0s + 1043 + + + id + 1 + 16415 + 1 + 745 + 1 + 403 + + + name + 1 + 16523 + 760 + 1 + 403 + default + 100 + pg_catalog + + + name + 16525 + 760 + 403 + varchar_pattern_ops + 4218 + pg_catalog + default + 100 + pg_catalog + + + 1 + 16416 + 1 + 745 + 16415 + + + 1 + 16524 + 760 + 16523 + + + by-default + 1 + 1 + 745 + bigint|0s + 16419 + 20 + + + 1 + 2 + 745 + integer|0s + 23 + + + 1 + 3 + 745 + integer|0s + 23 + + + group_id + 1 + 1 + 16456 + 745 + 1 + 16412 + + + permission_id + 1 + 1 + 16461 + 745 + 1 + 16406 + + + id + 1 + 16423 + 1 + 745 + 1 + 403 + + + group_id +permission_id + 16454 + 745 + 1 + 403 + + + group_id + 16466 + 745 + 403 + + + permission_id + 16467 + 745 + 403 + + + 1 + 16424 + 1 + 745 + 16423 + + + 16455 + 745 + 16454 + + + by-default + 1 + 1 + 745 + integer|0s + 16405 + 23 + + + 1 + 2 + 752 + varchar(255)|0s + 1043 + + + 1 + 3 + 745 + integer|0s + 23 + + + 1 + 4 + 745 + varchar(100)|0s + 1043 + + + content_type_id + 1 + 1 + 16447 + 745 + 1 + 16398 + + + id + 1 + 16409 + 1 + 745 + 1 + 403 + + + content_type_id +codename + 16445 + 745 + 1 + 403 + +100 + +pg_catalog + +default + + + content_type_id + 16452 + 745 + 403 + + + 1 + 16410 + 1 + 745 + 16409 + + + 16446 + 745 + 16445 + + + by-default + 1 + 1 + 745 + integer|0s + 16425 + 23 + + + 1 + 2 + 745 + varchar(128)|0s + 1043 + + + 3 + 755 + timestamp with time zone|0s + 1184 + + + 1 + 4 + 745 + boolean|0s + 16 + + + 1 + 5 + 758 + varchar(150)|0s + 1043 + + + 1 + 6 + 762 + varchar(150)|0s + 1043 + + + 1 + 7 + 759 + varchar(150)|0s + 1043 + + + 1 + 8 + 753 + varchar(254)|0s + 1043 + + + 1 + 9 + 745 + boolean|0s + 16 + + + 1 + 10 + 745 + boolean|0s + 16 + + + 1 + 11 + 745 + timestamp with time zone|0s + 1184 + + + id + 1 + 16429 + 1 + 745 + 1 + 403 + + + username + 1 + 16518 + 758 + 1 + 403 + default + 100 + pg_catalog + + + username + 16520 + 758 + 403 + varchar_pattern_ops + 4218 + pg_catalog + default + 100 + pg_catalog + + + 1 + 16430 + 1 + 745 + 16429 + + + 1 + 16519 + 758 + 16518 + + + by-default + 1 + 1 + 745 + bigint|0s + 16433 + 20 + + + 1 + 2 + 745 + integer|0s + 23 + + + 1 + 3 + 745 + integer|0s + 23 + + + user_id + 1 + 1 + 16471 + 745 + 1 + 16426 + + + group_id + 1 + 1 + 16476 + 745 + 1 + 16412 + + + id + 1 + 16437 + 1 + 745 + 1 + 403 + + + user_id +group_id + 16469 + 745 + 1 + 403 + + + user_id + 16481 + 745 + 403 + + + group_id + 16482 + 745 + 403 + + + 1 + 16438 + 1 + 745 + 16437 + + + 16470 + 745 + 16469 + + + by-default + 1 + 1 + 745 + bigint|0s + 16439 + 20 + + + 1 + 2 + 745 + integer|0s + 23 + + + 1 + 3 + 745 + integer|0s + 23 + + + user_id + 1 + 1 + 16485 + 745 + 1 + 16426 + + + permission_id + 1 + 1 + 16490 + 745 + 1 + 16406 + + + id + 1 + 16443 + 1 + 745 + 1 + 403 + + + user_id +permission_id + 16483 + 745 + 1 + 403 + + + user_id + 16495 + 745 + 403 + + + permission_id + 16496 + 745 + 403 + + + 1 + 16444 + 1 + 745 + 16443 + + + 16484 + 745 + 16483 + + + action_flag + 16501 + action_flag >= 0 + 747 + + + by-default + 1 + 1 + 747 + integer|0s + 16497 + 23 + + + 1 + 2 + 747 + timestamp with time zone|0s + 1184 + + + 3 + 747 + text|0s + 25 + + + 1 + 4 + 747 + varchar(200)|0s + 1043 + + + 1 + 5 + 747 + smallint|0s + 21 + + + 1 + 6 + 747 + text|0s + 25 + + + 7 + 747 + integer|0s + 23 + + + 1 + 8 + 747 + integer|0s + 23 + + + content_type_id + 1 + 1 + 16506 + 747 + 1 + 16398 + + + user_id + 1 + 1 + 16511 + 747 + 1 + 16426 + + + id + 1 + 16504 + 1 + 747 + 1 + 403 + + + content_type_id + 16516 + 747 + 403 + + + user_id + 16517 + 747 + 403 + + + 1 + 16505 + 1 + 747 + 16504 + + + by-default + 1 + 1 + 744 + integer|0s + 16397 + 23 + + + 1 + 3 + 744 + varchar(100)|0s + 1043 + + + 1 + 4 + 744 + varchar(100)|0s + 1043 + + + id + 1 + 16401 + 1 + 744 + 1 + 403 + + + app_label +model + 16403 + 744 + 1 + 403 + 100 +100 + default +default + pg_catalog +pg_catalog + + + 1 + 16402 + 1 + 744 + 16401 + + + 16404 + 744 + 16403 + + + by-default + 1 + 1 + 743 + bigint|0s + 16389 + 20 + + + 1 + 2 + 743 + varchar(255)|0s + 1043 + + + 1 + 3 + 743 + varchar(255)|0s + 1043 + + + 1 + 4 + 743 + timestamp with time zone|0s + 1184 + + + id + 1 + 16395 + 1 + 743 + 1 + 403 + + + 1 + 16396 + 1 + 743 + 16395 + + + 1 + 1 + 763 + varchar(40)|0s + 1043 + + + 1 + 2 + 763 + text|0s + 25 + + + 1 + 3 + 763 + timestamp with time zone|0s + 1184 + + + session_key + 1 + 16531 + 1 + 763 + 1 + 403 + default + 100 + pg_catalog + + + session_key + 16533 + 763 + 403 + varchar_pattern_ops + 4218 + pg_catalog + default + 100 + pg_catalog + + + expire_date + 16534 + 763 + 403 + + + 1 + 16532 + 1 + 763 + 16531 + + + 1 + 1 + 807 + timestamp with time zone|0s + 1184 + + + 1 + 2 + 807 + timestamp with time zone|0s + 1184 + + + by-default + 1 + 3 + 807 + bigint|0s + 16588 + 20 + + + 1 + 4 + 807 + varchar(100)|0s + 1043 + + + 1 + 5 + 807 + varchar(50)|0s + 1043 + + + 6 + 807 + text|0s + 25 + + + 7 + 807 + varchar(100)|0s + 1043 + + + id + 1 + 16594 + 1 + 807 + 1 + 403 + + + 1 + 16595 + 1 + 807 + 16594 + + + 1 + 1 + 856 + timestamp with time zone|0s + 1184 + + + 1 + 2 + 856 + timestamp with time zone|0s + 1184 + + + by-default + 1 + 3 + 856 + bigint|0s + 16596 + 20 + + + 1 + 4 + 856 + varchar(20)|0s + 1043 + + + 5 + 856 + text|0s + 25 + + + id + 1 + 16602 + 1 + 856 + 1 + 403 + + + 1 + 16603 + 1 + 856 + 16602 + + + by-default + 1 + 1 + 773 + bigint|0s + 16543 + 20 + + + 1 + 2 + 773 + varchar(100)|0s + 1043 + + + 1 + 3 + 773 + varchar(100)|0s + 1043 + + + 4 + 773 + varchar(50)|0s + 1043 + + + 5 + 773 + numeric(10,2 digit)|0s + 1700 + + + 6 + 852 + numeric(10,2 digit)|0s + 1700 + + + 7 + 773 + varchar(100)|0s + 1043 + + + 8 + 773 + text|0s + 25 + + + 1 + 9 + 773 + varchar(20)|0s + 1043 + + + 1 + 10 + 773 + bigint|0s + 20 + + + 1 + 11 + 805 + timestamp with time zone|0s + 1184 + + + 1 + 12 + 805 + timestamp with time zone|0s + 1184 + + + category_id + 1 + 1 + 16551 + 773 + 1 + 16536 + + + id + 1 + 16549 + 1 + 773 + 1 + 403 + + + category_id + 16556 + 773 + 403 + + + 1 + 16550 + 1 + 773 + 16549 + + + by-default + 1 + 1 + 773 + bigint|0s + 16535 + 20 + + + 1 + 2 + 773 + varchar(100)|0s + 1043 + + + 3 + 773 + text|0s + 25 + + + 1 + 4 + 805 + timestamp with time zone|0s + 1184 + + + 1 + 5 + 805 + timestamp with time zone|0s + 1184 + + + 1 + 6 + 832 + varchar(5)|0s + 1043 + + + id + 1 + 16541 + 1 + 773 + 1 + 403 + + + 1 + 16542 + 1 + 773 + 16541 + + + by-default + 1 + 1 + 799 + bigint|0s + 16566 + 20 + + + 1 + 2 + 799 + date|0s + 1082 + + + 1 + 3 + 799 + numeric(15,2 digit)|0s + 1700 + + + 4 + 799 + text|0s + 25 + + + 1 + 5 + 799 + bigint|0s + 20 + + + 1 + 6 + 805 + timestamp with time zone|0s + 1184 + + + 1 + 7 + 805 + timestamp with time zone|0s + 1184 + + + supplier_id + 1 + 1 + 16574 + 799 + 1 + 16558 + + + id + 1 + 16572 + 1 + 799 + 1 + 403 + + + supplier_id + 16579 + 799 + 403 + + + 1 + 16573 + 1 + 799 + 16572 + + + by-default + 1 + 1 + 792 + bigint|0s + 16557 + 20 + + + 1 + 2 + 792 + varchar(100)|0s + 1043 + + + 3 + 792 + varchar(100)|0s + 1043 + + + 4 + 792 + varchar(254)|0s + 1043 + + + 5 + 792 + varchar(20)|0s + 1043 + + + 6 + 792 + text|0s + 25 + + + 7 + 792 + text|0s + 25 + + + 1 + 8 + 805 + timestamp with time zone|0s + 1184 + + + 1 + 9 + 805 + timestamp with time zone|0s + 1184 + + + id + 1 + 16563 + 1 + 792 + 1 + 403 + + + 1 + 16564 + 1 + 792 + 16563 + +
+
\ No newline at end of file diff --git a/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg.meta b/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg.meta new file mode 100644 index 0000000..8f17d58 --- /dev/null +++ b/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg.meta @@ -0,0 +1 @@ +#n:myapp \ No newline at end of file diff --git a/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg/schema/information_schema.FNRwLQ.meta b/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg/schema/information_schema.FNRwLQ.meta new file mode 100644 index 0000000..1ff3db2 --- /dev/null +++ b/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg/schema/information_schema.FNRwLQ.meta @@ -0,0 +1,2 @@ +#n:information_schema +! [null, 0, null, null, -2147483648, -2147483648] diff --git a/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg/schema/pg_catalog.0S1ZNQ.meta b/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg/schema/pg_catalog.0S1ZNQ.meta new file mode 100644 index 0000000..44e65b1 --- /dev/null +++ b/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg/schema/pg_catalog.0S1ZNQ.meta @@ -0,0 +1,2 @@ +#n:pg_catalog +! [null, 0, null, null, -2147483648, -2147483648] diff --git a/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg/schema/public.abK9xQ.meta b/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg/schema/public.abK9xQ.meta new file mode 100644 index 0000000..63df8e1 --- /dev/null +++ b/.idea/dataSources/15dcd0e2-d09f-417a-adb8-9c908c90dd7e/storage_v2/_src_/database/myapp.9Xw4Bg/schema/public.abK9xQ.meta @@ -0,0 +1,2 @@ +#n:public +! [866, 0, null, null, -2147483648, -2147483648] diff --git a/.idea/flower.iml b/.idea/flower.iml new file mode 100644 index 0000000..ae3332d --- /dev/null +++ b/.idea/flower.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..91d71a3 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..cf45279 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..6324d40 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.14 diff --git a/basic_info/__init__.py b/basic_info/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic_info/admin.py b/basic_info/admin.py new file mode 100644 index 0000000..5e6ff5d --- /dev/null +++ b/basic_info/admin.py @@ -0,0 +1,82 @@ +from django.contrib import admin +from . import models + + +@admin.register(models.Supplier) +class SupplierAdmin(admin.ModelAdmin): + list_display = ('name', 'area', 'email', 'mobile') + search_fields = ('name', 'area', 'email', 'mobile') + + +@admin.register(models.ProductCategory) +class ProductCategoryAdmin(admin.ModelAdmin): + list_display = ('name', 'product_prefix', 'description') + search_fields = ('name',) + + +@admin.register(models.Product) +class ProductAdmin(admin.ModelAdmin): + list_display = ( + 'name', + 'category', + 'human_id', + 'color', + 'width_size', + 'transform_rate', + 'single_price_in', + 'single_price_out', + ) + search_fields = ('name', 'human_id') + list_filter = ('category',) + + +@admin.register(models.BankAccount) +class BankAccountAdmin(admin.ModelAdmin): + list_display = ('name', 'auto_number') + search_fields = ('name', 'auto_number') + + +@admin.register(models.WareHouse) +class WareHouseAdmin(admin.ModelAdmin): + list_display = ('name', 'location', 'area', 'mobile') + search_fields = ('name', 'area') + + +@admin.register(models.Customer) +class CustomerAdmin(admin.ModelAdmin): + list_display = ('name', 'area', 'email', 'mobile', 'total_debt') + search_fields = ('name', 'area', 'email', 'mobile') + + @admin.display(boolean=False, description='累欠金额') + def total_debt(self, obj): + return '0 (动态逻辑字段待实现)' + + +@admin.register(models.Employee) +class EmployeeAdmin(admin.ModelAdmin): + list_display = ('name', 'mobile', 'status', 'job_type', 'sys_user') + search_fields = ('name', 'mobile') + list_filter = ( + 'job_type', + 'status', + ) + + +@admin.register(models.DeviceInfo) +class DeviceInfoAdmin(admin.ModelAdmin): + list_display = ('name', 'type', 'is_occupied', 'status') + search_fields = ('name', 'start_working_at', 'stop_working_at') + list_filter = ('type', 'status') + + +@admin.register(models.VehicleType) +class VehicleTypeAdmin(admin.ModelAdmin): + list_display = ('name', 'description') + search_fields = ('name',) + + +@admin.register(models.VehicleTransportRecord) +class VehicleTransportRecordAdmin(admin.ModelAdmin): + list_display = ('driver_name', 'contact_number', 'delivery_date') + search_fields = ('driver_name', 'contact_number') + list_filter = ('vehicle_type',) diff --git a/basic_info/apps.py b/basic_info/apps.py new file mode 100644 index 0000000..3c012f7 --- /dev/null +++ b/basic_info/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + + +class BasicInfoConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'basic_info' + verbose_name = '基础资料' diff --git a/basic_info/migrations/0001_initial.py b/basic_info/migrations/0001_initial.py new file mode 100644 index 0000000..c1ffb78 --- /dev/null +++ b/basic_info/migrations/0001_initial.py @@ -0,0 +1,133 @@ +# Generated by Django 5.2.7 on 2025-11-03 06:06 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='BankAccount', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, verbose_name='名称')), + ('auto_number', models.CharField(max_length=50, verbose_name='自动编号')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ('attachment', models.FileField(blank=True, null=True, upload_to='bank_accounts/', verbose_name='附件')), + ], + options={ + 'verbose_name': '银行账户', + 'verbose_name_plural': '银行账户', + }, + ), + migrations.CreateModel( + name='ProductCategory', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, verbose_name='类别名称')), + ('description', models.TextField(blank=True, null=True, verbose_name='类别描述')), + ('product_prefix', models.CharField(max_length=5, verbose_name='产品编号前缀')), + ], + options={ + 'verbose_name': '产品类别', + 'verbose_name_plural': '产品类别', + }, + ), + migrations.CreateModel( + name='ProductUnit', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=20, verbose_name='单位名称')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ], + options={ + 'verbose_name': '产品单位', + 'verbose_name_plural': '产品单位', + }, + ), + migrations.CreateModel( + name='Supplier', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, verbose_name='供应商名称')), + ('area', models.CharField(blank=True, max_length=100, null=True, verbose_name='地区')), + ('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='电子邮箱')), + ('mobile', models.CharField(blank=True, max_length=20, null=True, verbose_name='手机')), + ('contact', models.TextField(blank=True, null=True, verbose_name='联系人')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ], + options={ + 'verbose_name': '供应商', + 'verbose_name_plural': '供应商', + }, + ), + migrations.CreateModel( + name='WareHouse', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, verbose_name='仓库名称')), + ('location', models.CharField(blank=True, max_length=200, null=True, verbose_name='仓库地址')), + ('contact', models.CharField(blank=True, max_length=100, null=True, verbose_name='联系人')), + ('mobile', models.CharField(blank=True, max_length=20, null=True, verbose_name='手机')), + ('area', models.CharField(blank=True, max_length=100, null=True, verbose_name='地区')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ], + options={ + 'verbose_name': '仓库资料', + 'verbose_name_plural': '仓库资料', + }, + ), + migrations.CreateModel( + name='Product', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, verbose_name='产品名')), + ('human_id', models.CharField(blank=True, max_length=100, verbose_name='产品编号')), + ('color', models.CharField(blank=True, max_length=50, null=True, verbose_name='颜色')), + ('width_size', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='宽幅')), + ('single_price', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='单价')), + ('spec', models.CharField(blank=True, max_length=100, null=True, verbose_name='规格')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='products', to='basic_info.productcategory', verbose_name='产品类别')), + ('unit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='products', to='basic_info.productunit', verbose_name='单位')), + ], + options={ + 'verbose_name': '产品资料', + 'verbose_name_plural': '产品资料', + }, + ), + migrations.CreateModel( + name='PurchaseOrder', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('order_date', models.DateField(verbose_name='订单日期')), + ('total_amount', models.DecimalField(decimal_places=2, max_digits=15, verbose_name='总金额')), + ('remarks', models.TextField(blank=True, null=True, verbose_name='备注')), + ('supplier', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='purchase_orders', to='basic_info.supplier', verbose_name='供应商')), + ], + options={ + 'verbose_name': '采购单', + 'verbose_name_plural': '采购单', + }, + ), + ] diff --git a/basic_info/migrations/0002_delete_purchaseorder.py b/basic_info/migrations/0002_delete_purchaseorder.py new file mode 100644 index 0000000..dc90556 --- /dev/null +++ b/basic_info/migrations/0002_delete_purchaseorder.py @@ -0,0 +1,16 @@ +# Generated by Django 5.2.7 on 2025-11-03 06:11 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0001_initial'), + ] + + operations = [ + migrations.DeleteModel( + name='PurchaseOrder', + ), + ] diff --git a/basic_info/migrations/0003_customer.py b/basic_info/migrations/0003_customer.py new file mode 100644 index 0000000..db33b1c --- /dev/null +++ b/basic_info/migrations/0003_customer.py @@ -0,0 +1,31 @@ +# Generated by Django 5.2.7 on 2025-11-03 06:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0002_delete_purchaseorder'), + ] + + operations = [ + migrations.CreateModel( + name='Customer', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, verbose_name='客户名称')), + ('area', models.CharField(blank=True, max_length=100, null=True, verbose_name='地区')), + ('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='电子邮箱')), + ('mobile', models.CharField(blank=True, max_length=20, null=True, verbose_name='手机')), + ('contact', models.TextField(blank=True, null=True, verbose_name='联系人')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ], + options={ + 'verbose_name': '客户资料', + 'verbose_name_plural': '客户资料', + }, + ), + ] diff --git a/basic_info/migrations/0004_alter_customer_contact.py b/basic_info/migrations/0004_alter_customer_contact.py new file mode 100644 index 0000000..6114236 --- /dev/null +++ b/basic_info/migrations/0004_alter_customer_contact.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.7 on 2025-11-03 06:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0003_customer'), + ] + + operations = [ + migrations.AlterField( + model_name='customer', + name='contact', + field=models.CharField(blank=True, null=True, verbose_name='联系人'), + ), + ] diff --git a/basic_info/migrations/0005_alter_customer_mobile.py b/basic_info/migrations/0005_alter_customer_mobile.py new file mode 100644 index 0000000..f2ac2a3 --- /dev/null +++ b/basic_info/migrations/0005_alter_customer_mobile.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.7 on 2025-11-03 06:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0004_alter_customer_contact'), + ] + + operations = [ + migrations.AlterField( + model_name='customer', + name='mobile', + field=models.CharField(max_length=20, verbose_name='手机'), + ), + ] diff --git a/basic_info/migrations/0006_employee.py b/basic_info/migrations/0006_employee.py new file mode 100644 index 0000000..b6b6f1d --- /dev/null +++ b/basic_info/migrations/0006_employee.py @@ -0,0 +1,33 @@ +# Generated by Django 5.2.7 on 2025-11-03 06:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0005_alter_customer_mobile'), + ] + + operations = [ + migrations.CreateModel( + name='Employee', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, verbose_name='员工姓名')), + ('job_type', models.CharField(choices=[('打纸', '打纸'), ('滚筒', '滚筒'), ('仓库', '仓库'), ('送货', '送货')], default='打纸', max_length=20, verbose_name='职位')), + ('mobile', models.CharField(blank=True, max_length=20, null=True, verbose_name='手机')), + ('area', models.CharField(blank=True, max_length=100, null=True, verbose_name='地区')), + ('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='电子邮箱')), + ('contact', models.CharField(blank=True, null=True, verbose_name='联系人')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ('status', models.CharField(choices=[('在职', '在职'), ('离职', '离职')], default='在职', max_length=20, verbose_name='员工状态')), + ], + options={ + 'verbose_name': '员工资料', + 'verbose_name_plural': '员工资料', + }, + ), + ] diff --git a/basic_info/migrations/0007_remove_employee_contact.py b/basic_info/migrations/0007_remove_employee_contact.py new file mode 100644 index 0000000..ee38afb --- /dev/null +++ b/basic_info/migrations/0007_remove_employee_contact.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.7 on 2025-11-03 06:27 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0006_employee'), + ] + + operations = [ + migrations.RemoveField( + model_name='employee', + name='contact', + ), + ] diff --git a/basic_info/migrations/0008_remove_employee_email.py b/basic_info/migrations/0008_remove_employee_email.py new file mode 100644 index 0000000..5a6262d --- /dev/null +++ b/basic_info/migrations/0008_remove_employee_email.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.7 on 2025-11-03 06:29 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0007_remove_employee_contact'), + ] + + operations = [ + migrations.RemoveField( + model_name='employee', + name='email', + ), + ] diff --git a/basic_info/migrations/0009_employee_sys_user.py b/basic_info/migrations/0009_employee_sys_user.py new file mode 100644 index 0000000..3e36d16 --- /dev/null +++ b/basic_info/migrations/0009_employee_sys_user.py @@ -0,0 +1,21 @@ +# Generated by Django 5.2.7 on 2025-11-03 07:05 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0008_remove_employee_email'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name='employee', + name='sys_user', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='employee', to=settings.AUTH_USER_MODEL, verbose_name='系统用户'), + ), + ] diff --git a/basic_info/migrations/0010_deviceinfo.py b/basic_info/migrations/0010_deviceinfo.py new file mode 100644 index 0000000..aee3e42 --- /dev/null +++ b/basic_info/migrations/0010_deviceinfo.py @@ -0,0 +1,32 @@ +# Generated by Django 5.2.7 on 2025-11-03 07:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0009_employee_sys_user'), + ] + + operations = [ + migrations.CreateModel( + name='DeviceInfo', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, verbose_name='设备名称')), + ('type', models.CharField(choices=[('滚筒', '滚筒'), ('打印', '打印')], default='滚筒', max_length=20, verbose_name='设备类型')), + ('status', models.CharField(choices=[('使用中', '使用中'), ('停用', '停用'), ('维修中', '维修中')], default='使用中', max_length=20, verbose_name='设备状态')), + ('start_working_at', models.DateField(blank=True, null=True, verbose_name='开始服役日期')), + ('stop_working_at', models.DateField(blank=True, null=True, verbose_name='停止服役日期')), + ('is_occupied', models.BooleanField(default=False, verbose_name='是否被占用')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ], + options={ + 'verbose_name': '设备信息', + 'verbose_name_plural': '设备信息', + }, + ), + ] diff --git a/basic_info/migrations/0011_vehicletype_alter_deviceinfo_options_and_more.py b/basic_info/migrations/0011_vehicletype_alter_deviceinfo_options_and_more.py new file mode 100644 index 0000000..9108adc --- /dev/null +++ b/basic_info/migrations/0011_vehicletype_alter_deviceinfo_options_and_more.py @@ -0,0 +1,49 @@ +# Generated by Django 5.2.7 on 2025-11-03 07:26 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0010_deviceinfo'), + ] + + operations = [ + migrations.CreateModel( + name='VehicleType', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=50, verbose_name='车辆类型名称')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ], + options={ + 'verbose_name': '车辆类型', + 'verbose_name_plural': '车辆类型', + }, + ), + migrations.AlterModelOptions( + name='deviceinfo', + options={'verbose_name': '设备资料', 'verbose_name_plural': '设备资料'}, + ), + migrations.CreateModel( + name='VehicleTransportRecord', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('driver_name', models.CharField(max_length=100, verbose_name='司机姓名')), + ('contact_number', models.CharField(blank=True, max_length=20, null=True, verbose_name='联系电话')), + ('license_plate', models.CharField(blank=True, max_length=20, null=True, verbose_name='车牌号码')), + ('delivery_date', models.DateField(verbose_name='送货日期')), + ('vehicle_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='vehicles', to='basic_info.vehicletype', verbose_name='车次')), + ], + options={ + 'verbose_name': '司机车次', + 'verbose_name_plural': '司机车次', + }, + ), + ] diff --git a/basic_info/migrations/0012_alter_product_unit.py b/basic_info/migrations/0012_alter_product_unit.py new file mode 100644 index 0000000..7e3bee7 --- /dev/null +++ b/basic_info/migrations/0012_alter_product_unit.py @@ -0,0 +1,19 @@ +# Generated by Django 5.2.7 on 2025-11-03 08:58 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0011_vehicletype_alter_deviceinfo_options_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='product', + name='unit', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='products', to='basic_info.productunit', verbose_name='主单位'), + ), + ] diff --git a/basic_info/migrations/0013_remove_product_unit_product_main_unit_and_more.py b/basic_info/migrations/0013_remove_product_unit_product_main_unit_and_more.py new file mode 100644 index 0000000..925d79b --- /dev/null +++ b/basic_info/migrations/0013_remove_product_unit_product_main_unit_and_more.py @@ -0,0 +1,36 @@ +# Generated by Django 5.2.7 on 2025-11-03 09:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0012_alter_product_unit'), + ('stock', '0018_remove_inventory_unit'), + ] + + operations = [ + migrations.RemoveField( + model_name='product', + name='unit', + ), + migrations.AddField( + model_name='product', + name='main_unit', + field=models.IntegerField(choices=[(1, '米'), (2, '码'), (3, '公斤')], default=1, verbose_name='主单位'), + ), + migrations.AddField( + model_name='product', + name='sub_unit', + field=models.IntegerField(blank=True, choices=[(1, '米'), (2, '码'), (3, '公斤')], null=True, verbose_name='辅单位'), + ), + migrations.AddField( + model_name='product', + name='transform_rate', + field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, verbose_name='转换率(主单位->辅单位)'), + ), + migrations.DeleteModel( + name='ProductUnit', + ), + ] diff --git a/basic_info/migrations/0014_remove_product_main_unit_remove_product_sub_unit_and_more.py b/basic_info/migrations/0014_remove_product_main_unit_remove_product_sub_unit_and_more.py new file mode 100644 index 0000000..0119583 --- /dev/null +++ b/basic_info/migrations/0014_remove_product_main_unit_remove_product_sub_unit_and_more.py @@ -0,0 +1,31 @@ +# Generated by Django 5.2.7 on 2025-11-03 09:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0013_remove_product_unit_product_main_unit_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='product', + name='main_unit', + ), + migrations.RemoveField( + model_name='product', + name='sub_unit', + ), + migrations.AlterField( + model_name='product', + name='single_price', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='单价(米)'), + ), + migrations.AlterField( + model_name='product', + name='transform_rate', + field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, verbose_name='公斤转换率'), + ), + ] diff --git a/basic_info/migrations/0015_remove_product_single_price_product_single_price_in_and_more.py b/basic_info/migrations/0015_remove_product_single_price_product_single_price_in_and_more.py new file mode 100644 index 0000000..e5fca47 --- /dev/null +++ b/basic_info/migrations/0015_remove_product_single_price_product_single_price_in_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 5.2.7 on 2025-11-03 09:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0014_remove_product_main_unit_remove_product_sub_unit_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='product', + name='single_price', + ), + migrations.AddField( + model_name='product', + name='single_price_in', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='参考进价'), + ), + migrations.AddField( + model_name='product', + name='single_price_out', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='参考售价'), + ), + ] diff --git a/basic_info/migrations/__init__.py b/basic_info/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic_info/models.py b/basic_info/models.py new file mode 100644 index 0000000..41c6c4a --- /dev/null +++ b/basic_info/models.py @@ -0,0 +1,285 @@ +from decimal import Decimal + +from django.db import models +from flower.common import ModelBase +from django.contrib.auth.models import User + + +METER_TO_YARD_RATE = 0.9144 +YARD_TO_METER_RATE = 1.09361 + + +class VehicleType(ModelBase): + id = models.BigAutoField(primary_key=True) + name = models.CharField(max_length=50, verbose_name='车辆类型名称') + description = models.TextField(blank=True, null=True, verbose_name='备注描述') + + def __str__(self): + return self.name + + class Meta: + verbose_name = '车辆类型' + verbose_name_plural = '车辆类型' + + +class WareHouse(ModelBase): + id = models.BigAutoField(primary_key=True) + name = models.CharField(max_length=100, verbose_name='仓库名称') + location = models.CharField(max_length=200, blank=True, null=True, verbose_name='仓库地址') + contact = models.CharField(max_length=100, blank=True, null=True, verbose_name='联系人') + mobile = models.CharField(max_length=20, blank=True, null=True, verbose_name='手机') + area = models.CharField(max_length=100, blank=True, null=True, verbose_name='地区') + description = models.TextField(blank=True, null=True, verbose_name='备注描述') + + def __str__(self): + return self.name + + class Meta: + verbose_name = '仓库资料' + verbose_name_plural = '仓库资料' + + +class ProductUnitEnum(models.IntegerChoices): + METER = 1, '米' + YARD = 2, '码' + KG = 3, '公斤' + + +class Supplier(ModelBase): + id = models.BigAutoField(primary_key=True) + name = models.CharField(max_length=100, verbose_name='供应商名称') + area = models.CharField(max_length=100, blank=True, null=True, verbose_name='地区') + email = models.EmailField(blank=True, null=True, verbose_name='电子邮箱') + mobile = models.CharField(max_length=20, blank=True, null=True, verbose_name='手机') + contact = models.TextField(blank=True, null=True, verbose_name='联系人') + description = models.TextField(blank=True, null=True, verbose_name='备注描述') + + def __str__(self): + return self.name + + class Meta: + verbose_name = '供应商' + verbose_name_plural = '供应商' + + +class BankAccount(ModelBase): + id = models.BigAutoField(primary_key=True) + name = models.CharField(max_length=100, verbose_name='名称') + auto_number = models.CharField(max_length=50, verbose_name='自动编号') + description = models.TextField(blank=True, null=True, verbose_name='备注描述') + attachment = models.FileField(upload_to='bank_accounts/', blank=True, null=True, verbose_name='附件') + + def __str__(self): + return f'{self.name} - {self.auto_number}' + + class Meta: + verbose_name = '银行账户' + verbose_name_plural = '银行账户' + + +class ProductCategory(ModelBase): + id = models.BigAutoField(primary_key=True) + name = models.CharField(max_length=100, verbose_name='类别名称') + description = models.TextField(blank=True, null=True, verbose_name='类别描述') + product_prefix = models.CharField(max_length=5, verbose_name='产品编号前缀') + + def __str__(self): + return self.name + + class Meta: + verbose_name = '产品类别' + verbose_name_plural = '产品类别' + + +class Product(ModelBase): + id = models.BigAutoField(primary_key=True) + category = models.ForeignKey( + ProductCategory, + on_delete=models.PROTECT, + related_name='products', + verbose_name='产品类别', + ) + name = models.CharField(max_length=100, verbose_name='产品名') + human_id = models.CharField(max_length=100, verbose_name='产品编号', blank=True) + color = models.CharField(max_length=50, blank=True, null=True, verbose_name='颜色') + width_size = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, verbose_name='宽幅') + single_price_in = models.DecimalField( + max_digits=10, + decimal_places=2, + verbose_name='参考进价', + blank=True, + null=True, + ) + single_price_out = models.DecimalField( + max_digits=10, + decimal_places=2, + verbose_name='参考售价', + blank=True, + null=True, + ) + spec = models.CharField(max_length=100, blank=True, null=True, verbose_name='规格') + description = models.TextField(blank=True, null=True, verbose_name='备注描述') + transform_rate = models.DecimalField( + max_digits=10, + decimal_places=4, + blank=True, + null=True, + verbose_name='公斤转换率', + ) + + def __str__(self): + return self.name + + def save( + self, + *args, + force_insert=False, + force_update=False, + using=None, + update_fields=None, + ): + super().save( + *args, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) + # Generate human_id if not set after saving to get the ID + if not self.human_id and self.category: + self.human_id = f'{self.category.product_prefix}{self.id:05d}' + super().save( + *args, + force_insert=False, + force_update=False, + using=using, + update_fields=['human_id'], + ) + + class Meta: + verbose_name = '产品资料' + verbose_name_plural = '产品资料' + + +class Customer(ModelBase): + id = models.BigAutoField(primary_key=True) + name = models.CharField(max_length=100, verbose_name='客户名称') + mobile = models.CharField(max_length=20, verbose_name='手机') + area = models.CharField(max_length=100, blank=True, null=True, verbose_name='地区') + email = models.EmailField(blank=True, null=True, verbose_name='电子邮箱') + contact = models.CharField(blank=True, null=True, verbose_name='联系人') + description = models.TextField(blank=True, null=True, verbose_name='备注描述') + + def __str__(self): + return self.name + + class Meta: + verbose_name = '客户资料' + verbose_name_plural = '客户资料' + + +class EmployeeTypeEnum(models.TextChoices): + PRINTER = '打纸', '打纸' + ROLLING = '滚筒', '滚筒' + WARE = '仓库', '仓库' + DELIVERY = '送货', '送货' + + +class EmployeeStatusEnum(models.TextChoices): + ACTIVE = '在职', '在职' + INACTIVE = '离职', '离职' + + +class Employee(ModelBase): + id = models.BigAutoField(primary_key=True) + sys_user = models.OneToOneField( + User, + on_delete=models.PROTECT, + related_name='employee', + null=True, + blank=True, + verbose_name='系统用户', + ) + name = models.CharField(max_length=100, verbose_name='员工姓名') + job_type = models.CharField( + max_length=20, + choices=EmployeeTypeEnum.choices, + default=EmployeeTypeEnum.PRINTER, + verbose_name='职位', + ) + mobile = models.CharField(max_length=20, blank=True, null=True, verbose_name='手机') + area = models.CharField(max_length=100, blank=True, null=True, verbose_name='地区') + description = models.TextField(blank=True, null=True, verbose_name='备注描述') + status = models.CharField( + max_length=20, + choices=EmployeeStatusEnum.choices, + default=EmployeeStatusEnum.ACTIVE, + verbose_name='员工状态', + ) + + def __str__(self): + return self.name + + class Meta: + verbose_name = '员工资料' + verbose_name_plural = '员工资料' + + +class DeviceStatusEnum(models.TextChoices): + ACTIVE = '使用中', '使用中' + INACTIVE = '停用', '停用' + MAINTENANCE = '维修中', '维修中' + + +class DeviceTypeEnum(models.TextChoices): + ROLLING = '滚筒', '滚筒' + PRINTER = '打印', '打印' + + +class DeviceInfo(ModelBase): + id = models.BigAutoField(primary_key=True) + name = models.CharField(max_length=100, verbose_name='设备名称') + type = models.CharField( + max_length=20, + choices=DeviceTypeEnum.choices, + default=DeviceTypeEnum.ROLLING, + verbose_name='设备类型', + ) + status = models.CharField( + max_length=20, + choices=DeviceStatusEnum.choices, + default=DeviceStatusEnum.ACTIVE, + verbose_name='设备状态', + ) + start_working_at = models.DateField(blank=True, null=True, verbose_name='开始服役日期') + stop_working_at = models.DateField(blank=True, null=True, verbose_name='停止服役日期') + is_occupied = models.BooleanField(default=False, verbose_name='是否被占用') + description = models.TextField(blank=True, null=True, verbose_name='备注描述') + + def __str__(self): + return self.name + + class Meta: + verbose_name = '设备资料' + verbose_name_plural = '设备资料' + + +class VehicleTransportRecord(ModelBase): + id = models.BigAutoField(primary_key=True) + vehicle_type = models.ForeignKey( + VehicleType, + on_delete=models.PROTECT, + related_name='vehicles', + verbose_name='车次', + ) + driver_name = models.CharField(max_length=100, verbose_name='司机姓名') + contact_number = models.CharField(max_length=20, blank=True, null=True, verbose_name='联系电话') + license_plate = models.CharField(max_length=20, verbose_name='车牌号码', null=True, blank=True) + delivery_date = models.DateField(verbose_name='送货日期') + + def __str__(self): + return f'{self.vehicle_type}-{self.driver_name}-{self.delivery_date}' + + class Meta: + verbose_name = '司机车次' + verbose_name_plural = '司机车次' diff --git a/basic_info/tests.py b/basic_info/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/basic_info/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/basic_info/views.py b/basic_info/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/basic_info/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b708854 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,28 @@ +version: '3.8' + +services: + postgres: + image: postgres:16-alpine + container_name: postgres + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: myapp + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + restart: unless-stopped + + redis: + image: redis:7-alpine + container_name: redis + ports: + - "6379:6379" + volumes: + - redis_data:/data + restart: unless-stopped + +volumes: + postgres_data: + redis_data: diff --git a/flower/__init__.py b/flower/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/flower/asgi.py b/flower/asgi.py new file mode 100644 index 0000000..a9a1506 --- /dev/null +++ b/flower/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for flower project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'flower.settings') + +application = get_asgi_application() diff --git a/flower/common.py b/flower/common.py new file mode 100644 index 0000000..b05f44e --- /dev/null +++ b/flower/common.py @@ -0,0 +1,10 @@ +from django.db import models + + +class ModelBase(models.Model): + """Base model with common fields.""" + created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') + updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间') + + class Meta: + abstract = True diff --git a/flower/settings.py b/flower/settings.py new file mode 100644 index 0000000..9b73261 --- /dev/null +++ b/flower/settings.py @@ -0,0 +1,134 @@ +""" +Django settings for flower project. + +Generated by 'django-admin startproject' using Django 5.2.7. + +For more information on this file, see +https://docs.djangoproject.com/en/5.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.2/ref/settings/ +""" + +from pathlib import Path +from environ import Env + +env = Env( + DEBUG=(bool, False), +) + + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +# Initialize environment variables +Env.read_env(str(BASE_DIR / '.env')) + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = env('SECRET_KEY', default='weak_secret_key_for_dev_only') + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = env('DEBUG', default=False) + +ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=[]) + + +# Application definition + +INSTALLED_APPS = [ + 'simpleui', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'basic_info', + 'stock', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'flower.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'flower.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/5.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': env('DB_NAME'), + 'USER': env('DB_USER'), + 'PASSWORD': env('DB_PASSWORD'), + 'HOST': env('DB_HOST', default='localhost'), + 'PORT': env('DB_PORT', default='5432'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/5.2/topics/i18n/ + +LANGUAGE_CODE = 'zh-hans' +TIME_ZONE = 'Asia/Shanghai' +USE_I18N = True +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/5.2/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/flower/urls.py b/flower/urls.py new file mode 100644 index 0000000..05319c7 --- /dev/null +++ b/flower/urls.py @@ -0,0 +1,24 @@ +""" +URL configuration for flower project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/5.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path +from stock.views import router + +urlpatterns = [ + path('admin/', admin.site.urls), + path('stock/', router.urls), +] diff --git a/flower/wsgi.py b/flower/wsgi.py new file mode 100644 index 0000000..4fc8634 --- /dev/null +++ b/flower/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for flower project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'flower.settings') + +application = get_wsgi_application() diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..7bbd74c --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'flower.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..32a32fd --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,18 @@ +[project] +name = "flower" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.14" +dependencies = [ + "django>=5.2.7", + "django-cors>=0.1", + "django-environ>=0.12.0", + "django-ninja>=1.4.5", + "django-simpleui>=2025.6.24", +] + +[dependency-groups] +dev = [ + "psycopg[binary]>=3.2.12", +] diff --git a/stock/__init__.py b/stock/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/stock/admin.py b/stock/admin.py new file mode 100644 index 0000000..c76aca0 --- /dev/null +++ b/stock/admin.py @@ -0,0 +1,30 @@ +from django.contrib import admin +from . import models + + +@admin.register(models.PurchaseOrder) +class PurchaseOrderAdmin(admin.ModelAdmin): + list_display = ('id', 'supplier', 'order_date', 'total_amount') + search_fields = ('supplier__name',) + list_filter = ('order_date',) + ordering = ('-order_date',) + + +@admin.register(models.Inventory) +class InventoryAdmin(admin.ModelAdmin): + list_display = ( + 'id', + 'product', + 'product_color', + 'warehouse', + 'quantity', + 'num_of_rolls', + 'minimum_quantity', + 'updated_at', + ) + search_fields = ('product__name', 'warehouse__name') + list_filter = ('warehouse',) + + @admin.display(description='颜色') + def product_color(self, obj): + return obj.product.color diff --git a/stock/apps.py b/stock/apps.py new file mode 100644 index 0000000..e7ce37b --- /dev/null +++ b/stock/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + + +class StockConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'stock' + verbose_name = '库存相关' diff --git a/stock/migrations/0001_initial.py b/stock/migrations/0001_initial.py new file mode 100644 index 0000000..047eeca --- /dev/null +++ b/stock/migrations/0001_initial.py @@ -0,0 +1,38 @@ +# Generated by Django 5.2.7 on 2025-11-03 04:08 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='ProductCategory', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100, verbose_name='类别名称')), + ('description', models.TextField(blank=True, null=True, verbose_name='类别描述')), + ], + ), + migrations.CreateModel( + name='Product', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100, verbose_name='产品名')), + ('human_id', models.CharField(max_length=100, verbose_name='产品编号')), + ('color', models.CharField(blank=True, max_length=50, null=True, verbose_name='颜色')), + ('width_size', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='宽幅')), + ('single_price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='单价')), + ('spec', models.CharField(blank=True, max_length=100, null=True, verbose_name='规格')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ('unit', models.CharField(default='米', max_length=20, verbose_name='单位')), + ('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='products', to='stock.productcategory', verbose_name='产品类别')), + ], + ), + ] diff --git a/stock/migrations/0002_alter_product_options_alter_productcategory_options.py b/stock/migrations/0002_alter_product_options_alter_productcategory_options.py new file mode 100644 index 0000000..276b093 --- /dev/null +++ b/stock/migrations/0002_alter_product_options_alter_productcategory_options.py @@ -0,0 +1,21 @@ +# Generated by Django 5.2.7 on 2025-11-03 04:10 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='product', + options={'verbose_name': '产品资料', 'verbose_name_plural': '产品资料'}, + ), + migrations.AlterModelOptions( + name='productcategory', + options={'verbose_name': '产品类别', 'verbose_name_plural': '产品类别'}, + ), + ] diff --git a/stock/migrations/0003_supplier.py b/stock/migrations/0003_supplier.py new file mode 100644 index 0000000..29f0df2 --- /dev/null +++ b/stock/migrations/0003_supplier.py @@ -0,0 +1,29 @@ +# Generated by Django 5.2.7 on 2025-11-03 04:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0002_alter_product_options_alter_productcategory_options'), + ] + + operations = [ + migrations.CreateModel( + name='Supplier', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100, verbose_name='供应商名称')), + ('area', models.CharField(blank=True, max_length=100, null=True, verbose_name='地区')), + ('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='电子邮箱')), + ('mobile', models.CharField(blank=True, max_length=20, null=True, verbose_name='手机')), + ('contact', models.TextField(blank=True, null=True, verbose_name='联系人')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ], + options={ + 'verbose_name': '供应商', + 'verbose_name_plural': '供应商', + }, + ), + ] diff --git a/stock/migrations/0004_alter_product_id_alter_productcategory_id_and_more.py b/stock/migrations/0004_alter_product_id_alter_productcategory_id_and_more.py new file mode 100644 index 0000000..fe8843f --- /dev/null +++ b/stock/migrations/0004_alter_product_id_alter_productcategory_id_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 5.2.7 on 2025-11-03 04:24 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0003_supplier'), + ] + + operations = [ + migrations.AlterField( + model_name='product', + name='id', + field=models.BigAutoField(primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='productcategory', + name='id', + field=models.BigAutoField(primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='supplier', + name='id', + field=models.BigAutoField(primary_key=True, serialize=False), + ), + migrations.CreateModel( + name='PurchaseOrder', + fields=[ + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('order_date', models.DateField(verbose_name='订单日期')), + ('total_amount', models.DecimalField(decimal_places=2, max_digits=15, verbose_name='总金额')), + ('remarks', models.TextField(blank=True, null=True, verbose_name='备注')), + ('supplier', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='purchase_orders', to='stock.supplier', verbose_name='供应商')), + ], + options={ + 'verbose_name': '采购单', + 'verbose_name_plural': '采购单', + }, + ), + ] diff --git a/stock/migrations/0005_product_created_at_product_updated_at_and_more.py b/stock/migrations/0005_product_created_at_product_updated_at_and_more.py new file mode 100644 index 0000000..11f8ccb --- /dev/null +++ b/stock/migrations/0005_product_created_at_product_updated_at_and_more.py @@ -0,0 +1,58 @@ +# Generated by Django 5.2.7 on 2025-11-03 04:29 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0004_alter_product_id_alter_productcategory_id_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='product', + name='created_at', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now, verbose_name='创建时间'), + preserve_default=False, + ), + migrations.AddField( + model_name='product', + name='updated_at', + field=models.DateTimeField(auto_now=True, verbose_name='更新时间'), + ), + migrations.AddField( + model_name='productcategory', + name='created_at', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now, verbose_name='创建时间'), + preserve_default=False, + ), + migrations.AddField( + model_name='productcategory', + name='updated_at', + field=models.DateTimeField(auto_now=True, verbose_name='更新时间'), + ), + migrations.AddField( + model_name='purchaseorder', + name='created_at', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now, verbose_name='创建时间'), + preserve_default=False, + ), + migrations.AddField( + model_name='purchaseorder', + name='updated_at', + field=models.DateTimeField(auto_now=True, verbose_name='更新时间'), + ), + migrations.AddField( + model_name='supplier', + name='created_at', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now, verbose_name='创建时间'), + preserve_default=False, + ), + migrations.AddField( + model_name='supplier', + name='updated_at', + field=models.DateTimeField(auto_now=True, verbose_name='更新时间'), + ), + ] diff --git a/stock/migrations/0006_bankaccount.py b/stock/migrations/0006_bankaccount.py new file mode 100644 index 0000000..c2697f2 --- /dev/null +++ b/stock/migrations/0006_bankaccount.py @@ -0,0 +1,29 @@ +# Generated by Django 5.2.7 on 2025-11-03 04:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0005_product_created_at_product_updated_at_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='BankAccount', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, verbose_name='名称')), + ('auto_number', models.CharField(max_length=50, verbose_name='自动编号')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ('attachment', models.FileField(blank=True, null=True, upload_to='bank_accounts/', verbose_name='附件')), + ], + options={ + 'verbose_name': '银行账户', + 'verbose_name_plural': '银行账户', + }, + ), + ] diff --git a/stock/migrations/0007_productcategory_product_prefix.py b/stock/migrations/0007_productcategory_product_prefix.py new file mode 100644 index 0000000..d63d927 --- /dev/null +++ b/stock/migrations/0007_productcategory_product_prefix.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.7 on 2025-11-03 05:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0006_bankaccount'), + ] + + operations = [ + migrations.AddField( + model_name='productcategory', + name='product_prefix', + field=models.CharField(blank=True, max_length=5, null=True, verbose_name='产品编号前缀'), + ), + ] diff --git a/stock/migrations/0008_alter_product_human_id_and_more.py b/stock/migrations/0008_alter_product_human_id_and_more.py new file mode 100644 index 0000000..709caf9 --- /dev/null +++ b/stock/migrations/0008_alter_product_human_id_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.7 on 2025-11-03 05:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0007_productcategory_product_prefix'), + ] + + operations = [ + migrations.AlterField( + model_name='product', + name='human_id', + field=models.CharField(blank=True, max_length=100, verbose_name='产品编号'), + ), + migrations.AlterField( + model_name='productcategory', + name='product_prefix', + field=models.CharField(max_length=5, verbose_name='产品编号前缀'), + ), + ] diff --git a/stock/migrations/0009_alter_product_single_price.py b/stock/migrations/0009_alter_product_single_price.py new file mode 100644 index 0000000..97e7bd3 --- /dev/null +++ b/stock/migrations/0009_alter_product_single_price.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.7 on 2025-11-03 05:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0008_alter_product_human_id_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='product', + name='single_price', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='单价'), + ), + ] diff --git a/stock/migrations/0010_prodictunit.py b/stock/migrations/0010_prodictunit.py new file mode 100644 index 0000000..b34c4ae --- /dev/null +++ b/stock/migrations/0010_prodictunit.py @@ -0,0 +1,27 @@ +# Generated by Django 5.2.7 on 2025-11-03 05:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0009_alter_product_single_price'), + ] + + operations = [ + migrations.CreateModel( + name='ProdictUnit', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=20, verbose_name='单位名称')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ], + options={ + 'verbose_name': '产品单位', + 'verbose_name_plural': '产品单位', + }, + ), + ] diff --git a/stock/migrations/0011_alter_product_unit.py b/stock/migrations/0011_alter_product_unit.py new file mode 100644 index 0000000..2ea2926 --- /dev/null +++ b/stock/migrations/0011_alter_product_unit.py @@ -0,0 +1,19 @@ +# Generated by Django 5.2.7 on 2025-11-03 05:28 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0010_prodictunit'), + ] + + operations = [ + migrations.AlterField( + model_name='product', + name='unit', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='products', to='stock.prodictunit', verbose_name='单位'), + ), + ] diff --git a/stock/migrations/0012_rename_prodictunit_productunit.py b/stock/migrations/0012_rename_prodictunit_productunit.py new file mode 100644 index 0000000..ed71a0c --- /dev/null +++ b/stock/migrations/0012_rename_prodictunit_productunit.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.7 on 2025-11-03 05:34 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0011_alter_product_unit'), + ] + + operations = [ + migrations.RenameModel( + old_name='ProdictUnit', + new_name='ProductUnit', + ), + ] diff --git a/stock/migrations/0013_warehouse.py b/stock/migrations/0013_warehouse.py new file mode 100644 index 0000000..2adf9c9 --- /dev/null +++ b/stock/migrations/0013_warehouse.py @@ -0,0 +1,31 @@ +# Generated by Django 5.2.7 on 2025-11-03 05:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0012_rename_prodictunit_productunit'), + ] + + operations = [ + migrations.CreateModel( + name='WareHouse', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, verbose_name='仓库名称')), + ('location', models.CharField(blank=True, max_length=200, null=True, verbose_name='仓库地址')), + ('contact', models.CharField(blank=True, max_length=100, null=True, verbose_name='联系人')), + ('mobile', models.CharField(blank=True, max_length=20, null=True, verbose_name='手机')), + ('area', models.CharField(blank=True, max_length=100, null=True, verbose_name='地区')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ], + options={ + 'verbose_name': '仓库资料', + 'verbose_name_plural': '仓库资料', + }, + ), + ] diff --git a/stock/migrations/0014_delete_bankaccount_remove_product_category_and_more.py b/stock/migrations/0014_delete_bankaccount_remove_product_category_and_more.py new file mode 100644 index 0000000..4cae9a6 --- /dev/null +++ b/stock/migrations/0014_delete_bankaccount_remove_product_category_and_more.py @@ -0,0 +1,46 @@ +# Generated by Django 5.2.7 on 2025-11-03 06:06 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0013_warehouse'), + ] + + operations = [ + migrations.DeleteModel( + name='BankAccount', + ), + migrations.RemoveField( + model_name='product', + name='category', + ), + migrations.RemoveField( + model_name='product', + name='unit', + ), + migrations.RemoveField( + model_name='purchaseorder', + name='supplier', + ), + migrations.DeleteModel( + name='WareHouse', + ), + migrations.DeleteModel( + name='ProductCategory', + ), + migrations.DeleteModel( + name='Product', + ), + migrations.DeleteModel( + name='ProductUnit', + ), + migrations.DeleteModel( + name='PurchaseOrder', + ), + migrations.DeleteModel( + name='Supplier', + ), + ] diff --git a/stock/migrations/0015_initial.py b/stock/migrations/0015_initial.py new file mode 100644 index 0000000..c88e033 --- /dev/null +++ b/stock/migrations/0015_initial.py @@ -0,0 +1,33 @@ +# Generated by Django 5.2.7 on 2025-11-03 06:11 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('basic_info', '0002_delete_purchaseorder'), + ('stock', '0014_delete_bankaccount_remove_product_category_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='PurchaseOrder', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('order_date', models.DateField(verbose_name='订单日期')), + ('total_amount', models.DecimalField(decimal_places=2, max_digits=15, verbose_name='总金额')), + ('remarks', models.TextField(blank=True, null=True, verbose_name='备注')), + ('supplier', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='purchase_orders', to='basic_info.supplier', verbose_name='供应商')), + ], + options={ + 'verbose_name': '采购单', + 'verbose_name_plural': '采购单', + }, + ), + ] diff --git a/stock/migrations/0016_inventory.py b/stock/migrations/0016_inventory.py new file mode 100644 index 0000000..8e9fe97 --- /dev/null +++ b/stock/migrations/0016_inventory.py @@ -0,0 +1,34 @@ +# Generated by Django 5.2.7 on 2025-11-03 07:47 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('basic_info', '0011_vehicletype_alter_deviceinfo_options_and_more'), + ('stock', '0015_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Inventory', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('quantity', models.IntegerField(verbose_name='数量')), + ('minimum_quantity', models.IntegerField(blank=True, null=True, verbose_name='最低库存量')), + ('spec', models.CharField(blank=True, max_length=100, null=True, verbose_name='规格')), + ('description', models.TextField(blank=True, null=True, verbose_name='备注描述')), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='inventories', to='basic_info.product', verbose_name='产品')), + ('unit', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='inventories', to='basic_info.productunit', verbose_name='单位')), + ('warehouse', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='inventories', to='basic_info.warehouse', verbose_name='仓库')), + ], + options={ + 'verbose_name': '库存', + 'verbose_name_plural': '库存', + }, + ), + ] diff --git a/stock/migrations/0017_inventory_num_of_rolls_alter_inventory_quantity.py b/stock/migrations/0017_inventory_num_of_rolls_alter_inventory_quantity.py new file mode 100644 index 0000000..8809434 --- /dev/null +++ b/stock/migrations/0017_inventory_num_of_rolls_alter_inventory_quantity.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.7 on 2025-11-03 08:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0016_inventory'), + ] + + operations = [ + migrations.AddField( + model_name='inventory', + name='num_of_rolls', + field=models.IntegerField(blank=True, null=True, verbose_name='匹数'), + ), + migrations.AlterField( + model_name='inventory', + name='quantity', + field=models.IntegerField(verbose_name='库存数量'), + ), + ] diff --git a/stock/migrations/0018_remove_inventory_unit.py b/stock/migrations/0018_remove_inventory_unit.py new file mode 100644 index 0000000..ff5a3e1 --- /dev/null +++ b/stock/migrations/0018_remove_inventory_unit.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.7 on 2025-11-03 09:10 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0017_inventory_num_of_rolls_alter_inventory_quantity'), + ] + + operations = [ + migrations.RemoveField( + model_name='inventory', + name='unit', + ), + ] diff --git a/stock/migrations/__init__.py b/stock/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/stock/models.py b/stock/models.py new file mode 100644 index 0000000..6a7c8f6 --- /dev/null +++ b/stock/models.py @@ -0,0 +1,46 @@ +from django.db import models +from flower.common import ModelBase +from basic_info import models as basic_info_models + + +class PurchaseOrder(ModelBase): + id = models.BigAutoField(primary_key=True) + supplier = models.ForeignKey(basic_info_models.Supplier, on_delete=models.PROTECT, related_name='purchase_orders', verbose_name='供应商') + order_date = models.DateField(verbose_name='订单日期') + total_amount = models.DecimalField(max_digits=15, decimal_places=2, verbose_name='总金额') + remarks = models.TextField(blank=True, null=True, verbose_name='备注') + + def __str__(self): + return f'采购订单 {self.id} - {self.supplier.name}' + + class Meta: + verbose_name = '采购单' + verbose_name_plural = '采购单' + + +class Inventory(ModelBase): + id = models.BigAutoField(primary_key=True) + product = models.ForeignKey( + basic_info_models.Product, + on_delete=models.PROTECT, + related_name='inventories', + verbose_name='产品', + ) + warehouse = models.ForeignKey( + basic_info_models.WareHouse, + on_delete=models.PROTECT, + related_name='inventories', + verbose_name='仓库', + ) + quantity = models.IntegerField(verbose_name='库存数量') + num_of_rolls = models.IntegerField(null=True, blank=True, verbose_name='匹数') + minimum_quantity = models.IntegerField(null=True, blank=True, verbose_name='最低库存量') + spec = models.CharField(max_length=100, blank=True, null=True, verbose_name='规格') + description = models.TextField(blank=True, null=True, verbose_name='备注描述') + + def __str__(self): + return f'库存 {self.product.name} - 仓库: {self.warehouse.name}' + + class Meta: + verbose_name = '库存' + verbose_name_plural = '库存' diff --git a/stock/tests.py b/stock/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/stock/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/stock/views.py b/stock/views.py new file mode 100644 index 0000000..5b39dd5 --- /dev/null +++ b/stock/views.py @@ -0,0 +1,9 @@ +from ninja import NinjaAPI + + +router = NinjaAPI() + + +@router.get('/') +async def index(request): + return {'message': 'Welcome to the Stock API'} diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..c966713 --- /dev/null +++ b/uv.lock @@ -0,0 +1,218 @@ +version = 1 +revision = 3 +requires-python = ">=3.14" + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "asgiref" +version = "3.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/46/08/4dfec9b90758a59acc6be32ac82e98d1fbfc321cb5cfa410436dbacf821c/asgiref-3.10.0.tar.gz", hash = "sha256:d89f2d8cd8b56dada7d52fa7dc8075baa08fb836560710d38c292a7a3f78c04e", size = 37483, upload-time = "2025-10-05T09:15:06.557Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/9c/fc2331f538fbf7eedba64b2052e99ccf9ba9d6888e2f41441ee28847004b/asgiref-3.10.0-py3-none-any.whl", hash = "sha256:aef8a81283a34d0ab31630c9b7dfe70c812c95eba78171367ca8745e88124734", size = 24050, upload-time = "2025-10-05T09:15:05.11Z" }, +] + +[[package]] +name = "django" +version = "5.2.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asgiref" }, + { name = "sqlparse" }, + { name = "tzdata", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/96/bd84e2bb997994de8bcda47ae4560991084e86536541d7214393880f01a8/django-5.2.7.tar.gz", hash = "sha256:e0f6f12e2551b1716a95a63a1366ca91bbcd7be059862c1b18f989b1da356cdd", size = 10865812, upload-time = "2025-10-01T14:22:12.081Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/ef/81f3372b5dd35d8d354321155d1a38894b2b766f576d0abffac4d8ae78d9/django-5.2.7-py3-none-any.whl", hash = "sha256:59a13a6515f787dec9d97a0438cd2efac78c8aca1c80025244b0fe507fe0754b", size = 8307145, upload-time = "2025-10-01T14:22:49.476Z" }, +] + +[[package]] +name = "django-cors" +version = "0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/94/59b5353380df1aacd28e1efc1e77ce9925f65ef9adab6c44238daa9cefa3/django-cors-0.1.tar.gz", hash = "sha256:ba31c9455ddb848e578b26bac3634049951149775b818a35476d2b50350640c3", size = 1066, upload-time = "2012-12-04T02:52:05.092Z" } + +[[package]] +name = "django-environ" +version = "0.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/04/65d2521842c42f4716225f20d8443a50804920606aec018188bbee30a6b0/django_environ-0.12.0.tar.gz", hash = "sha256:227dc891453dd5bde769c3449cf4a74b6f2ee8f7ab2361c93a07068f4179041a", size = 56804, upload-time = "2025-01-13T17:03:37.74Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/b3/0a3bec4ecbfee960f39b1842c2f91e4754251e0a6ed443db9fe3f666ba8f/django_environ-0.12.0-py2.py3-none-any.whl", hash = "sha256:92fb346a158abda07ffe6eb23135ce92843af06ecf8753f43adf9d2366dcc0ca", size = 19957, upload-time = "2025-01-13T17:03:32.918Z" }, +] + +[[package]] +name = "django-ninja" +version = "1.4.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "django" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/9a/558489e0e25173772fbd826306b7d1777e80285b02d69e0e1aaec41e3eec/django_ninja-1.4.5.tar.gz", hash = "sha256:aa1a2ee2b22c5f1c2f4bfbc004386be7074cbfaf133680c2b359a31221965503", size = 3710511, upload-time = "2025-10-19T18:28:02.362Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/e3/168274a8def4b9a2fb2540319a68914e8e4e529cd7f7b5f1ba8939d011bc/django_ninja-1.4.5-py3-none-any.whl", hash = "sha256:d779702ddc6e17b10739049ddb075a6a1e6c6270bdc04e0b0429f6adbf670373", size = 2426449, upload-time = "2025-10-19T18:28:00.518Z" }, +] + +[[package]] +name = "django-simpleui" +version = "2025.6.24" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "django" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/97/d7/57ac337258399c33c28b5d960407e2c640f22a2edabf2e894d1b51e25fee/django-simpleui-2025.6.24.tar.gz", hash = "sha256:95d1224454a0531071ec7fcd1c6f57acf90e85160c72d6b1d23d538c3a92f4ed", size = 6483918, upload-time = "2025-06-24T06:35:27.545Z" } + +[[package]] +name = "flower" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "django" }, + { name = "django-cors" }, + { name = "django-environ" }, + { name = "django-ninja" }, + { name = "django-simpleui" }, +] + +[package.dev-dependencies] +dev = [ + { name = "psycopg", extra = ["binary"] }, +] + +[package.metadata] +requires-dist = [ + { name = "django", specifier = ">=5.2.7" }, + { name = "django-cors", specifier = ">=0.1" }, + { name = "django-environ", specifier = ">=0.12.0" }, + { name = "django-ninja", specifier = ">=1.4.5" }, + { name = "django-simpleui", specifier = ">=2025.6.24" }, +] + +[package.metadata.requires-dev] +dev = [{ name = "psycopg", extras = ["binary"], specifier = ">=3.2.12" }] + +[[package]] +name = "psycopg" +version = "3.2.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tzdata", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/77/c72d10262b872617e509a0c60445afcc4ce2cd5cd6bc1c97700246d69c85/psycopg-3.2.12.tar.gz", hash = "sha256:85c08d6f6e2a897b16280e0ff6406bef29b1327c045db06d21f364d7cd5da90b", size = 160642, upload-time = "2025-10-26T00:46:03.045Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/28/8c4f90e415411dc9c78d6ba10b549baa324659907c13f64bfe3779d4066c/psycopg-3.2.12-py3-none-any.whl", hash = "sha256:8a1611a2d4c16ae37eada46438be9029a35bb959bb50b3d0e1e93c0f3d54c9ee", size = 206765, upload-time = "2025-10-26T00:10:42.173Z" }, +] + +[package.optional-dependencies] +binary = [ + { name = "psycopg-binary", marker = "implementation_name != 'pypy'" }, +] + +[[package]] +name = "psycopg-binary" +version = "3.2.12" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/5b/76fbb40b981b73b285a00dccafc38cf67b7a9b3f7d4f2025dda7b896e7ef/psycopg_binary-3.2.12-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:dc68094e00a5a7e8c20de1d3a0d5e404a27f522e18f8eb62bbbc9f865c3c81ef", size = 4016868, upload-time = "2025-10-26T00:31:29.974Z" }, + { url = "https://files.pythonhosted.org/packages/0e/08/8841ae3e2d1a3228e79eaaf5b7f991d15f0a231bb5031a114305b19724b1/psycopg_binary-3.2.12-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2d55009eeddbef54c711093c986daaf361d2c4210aaa1ee905075a3b97a62441", size = 4090508, upload-time = "2025-10-26T00:32:04.192Z" }, + { url = "https://files.pythonhosted.org/packages/05/de/a41f62230cf4095ae4547eceada218cf28c17e7f94376913c1c8dde9546f/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:66a031f22e4418016990446d3e38143826f03ad811b9f78f58e2afbc1d343f7a", size = 4629788, upload-time = "2025-10-26T00:32:43.28Z" }, + { url = "https://files.pythonhosted.org/packages/45/19/529d92134eae44475f781a86d58cdf3edd0953e17c69762abf387a9f2636/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:58ed30d33c25d7dc8d2f06285e88493147c2a660cc94713e4b563a99efb80a1f", size = 4724124, upload-time = "2025-10-26T00:33:22.594Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f5/97344e87065f7c9713ce213a2cff7732936ec3af6622e4b2a88715a953f2/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e0b5ccd03ca4749b8f66f38608ccbcb415cbd130d02de5eda80d042b83bee90e", size = 4411340, upload-time = "2025-10-26T00:34:00.759Z" }, + { url = "https://files.pythonhosted.org/packages/b1/c2/34bce068f6bfb4c2e7bb1187bb64a3f3be254702b158c4ad05eacc0055cf/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:909de94de7dd4d6086098a5755562207114c9638ec42c52d84c8a440c45fe084", size = 3867815, upload-time = "2025-10-26T00:34:33.181Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a1/c647e01ab162e6bfa52380e23e486215e9d28ffd31e9cf3cb1e9ca59008b/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:7130effd0517881f3a852eff98729d51034128f0737f64f0d1c7ea8343d77bd7", size = 3541756, upload-time = "2025-10-26T00:35:08.622Z" }, + { url = "https://files.pythonhosted.org/packages/6b/d0/795bdaa8c946a7b7126bf7ca8d4371eaaa613093e3ec341a0e50f52cbee2/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:89b3c5201ca616d69ca0c3c0003ca18f7170a679c445c7e386ebfb4f29aa738e", size = 3587950, upload-time = "2025-10-26T00:35:41.183Z" }, + { url = "https://files.pythonhosted.org/packages/53/cf/10c3e95827a3ca8af332dfc471befec86e15a14dc83cee893c49a4910dad/psycopg_binary-3.2.12-cp314-cp314-win_amd64.whl", hash = "sha256:48a8e29f3e38fcf8d393b8fe460d83e39c107ad7e5e61cd3858a7569e0554a39", size = 3005787, upload-time = "2025-10-26T00:36:06.783Z" }, +] + +[[package]] +name = "pydantic" +version = "2.12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/1e/4f0a3233767010308f2fd6bd0814597e3f63f1dc98304a9112b8759df4ff/pydantic-2.12.3.tar.gz", hash = "sha256:1da1c82b0fc140bb0103bc1441ffe062154c8d38491189751ee00fd8ca65ce74", size = 819383, upload-time = "2025-10-17T15:04:21.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/6b/83661fa77dcefa195ad5f8cd9af3d1a7450fd57cc883ad04d65446ac2029/pydantic-2.12.3-py3-none-any.whl", hash = "sha256:6986454a854bc3bc6e5443e1369e06a3a456af9d339eda45510f517d9ea5c6bf", size = 462431, upload-time = "2025-10-17T15:04:19.346Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.41.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/18/d0944e8eaaa3efd0a91b0f1fc537d3be55ad35091b6a87638211ba691964/pydantic_core-2.41.4.tar.gz", hash = "sha256:70e47929a9d4a1905a67e4b687d5946026390568a8e952b92824118063cee4d5", size = 457557, upload-time = "2025-10-14T10:23:47.909Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/28/d3325da57d413b9819365546eb9a6e8b7cbd9373d9380efd5f74326143e6/pydantic_core-2.41.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:e9205d97ed08a82ebb9a307e92914bb30e18cdf6f6b12ca4bedadb1588a0bfe1", size = 2102022, upload-time = "2025-10-14T10:21:32.809Z" }, + { url = "https://files.pythonhosted.org/packages/9e/24/b58a1bc0d834bf1acc4361e61233ee217169a42efbdc15a60296e13ce438/pydantic_core-2.41.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:82df1f432b37d832709fbcc0e24394bba04a01b6ecf1ee87578145c19cde12ac", size = 1905495, upload-time = "2025-10-14T10:21:34.812Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a4/71f759cc41b7043e8ecdaab81b985a9b6cad7cec077e0b92cff8b71ecf6b/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3b4cc4539e055cfa39a3763c939f9d409eb40e85813257dcd761985a108554", size = 1956131, upload-time = "2025-10-14T10:21:36.924Z" }, + { url = "https://files.pythonhosted.org/packages/b0/64/1e79ac7aa51f1eec7c4cda8cbe456d5d09f05fdd68b32776d72168d54275/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1eb1754fce47c63d2ff57fdb88c351a6c0150995890088b33767a10218eaa4e", size = 2052236, upload-time = "2025-10-14T10:21:38.927Z" }, + { url = "https://files.pythonhosted.org/packages/e9/e3/a3ffc363bd4287b80f1d43dc1c28ba64831f8dfc237d6fec8f2661138d48/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e6ab5ab30ef325b443f379ddb575a34969c333004fca5a1daa0133a6ffaad616", size = 2223573, upload-time = "2025-10-14T10:21:41.574Z" }, + { url = "https://files.pythonhosted.org/packages/28/27/78814089b4d2e684a9088ede3790763c64693c3d1408ddc0a248bc789126/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:31a41030b1d9ca497634092b46481b937ff9397a86f9f51bd41c4767b6fc04af", size = 2342467, upload-time = "2025-10-14T10:21:44.018Z" }, + { url = "https://files.pythonhosted.org/packages/92/97/4de0e2a1159cb85ad737e03306717637842c88c7fd6d97973172fb183149/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a44ac1738591472c3d020f61c6df1e4015180d6262ebd39bf2aeb52571b60f12", size = 2063754, upload-time = "2025-10-14T10:21:46.466Z" }, + { url = "https://files.pythonhosted.org/packages/0f/50/8cb90ce4b9efcf7ae78130afeb99fd1c86125ccdf9906ef64b9d42f37c25/pydantic_core-2.41.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d72f2b5e6e82ab8f94ea7d0d42f83c487dc159c5240d8f83beae684472864e2d", size = 2196754, upload-time = "2025-10-14T10:21:48.486Z" }, + { url = "https://files.pythonhosted.org/packages/34/3b/ccdc77af9cd5082723574a1cc1bcae7a6acacc829d7c0a06201f7886a109/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:c4d1e854aaf044487d31143f541f7aafe7b482ae72a022c664b2de2e466ed0ad", size = 2137115, upload-time = "2025-10-14T10:21:50.63Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ba/e7c7a02651a8f7c52dc2cff2b64a30c313e3b57c7d93703cecea76c09b71/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b568af94267729d76e6ee5ececda4e283d07bbb28e8148bb17adad93d025d25a", size = 2317400, upload-time = "2025-10-14T10:21:52.959Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ba/6c533a4ee8aec6b812c643c49bb3bd88d3f01e3cebe451bb85512d37f00f/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6d55fb8b1e8929b341cc313a81a26e0d48aa3b519c1dbaadec3a6a2b4fcad025", size = 2312070, upload-time = "2025-10-14T10:21:55.419Z" }, + { url = "https://files.pythonhosted.org/packages/22/ae/f10524fcc0ab8d7f96cf9a74c880243576fd3e72bd8ce4f81e43d22bcab7/pydantic_core-2.41.4-cp314-cp314-win32.whl", hash = "sha256:5b66584e549e2e32a1398df11da2e0a7eff45d5c2d9db9d5667c5e6ac764d77e", size = 1982277, upload-time = "2025-10-14T10:21:57.474Z" }, + { url = "https://files.pythonhosted.org/packages/b4/dc/e5aa27aea1ad4638f0c3fb41132f7eb583bd7420ee63204e2d4333a3bbf9/pydantic_core-2.41.4-cp314-cp314-win_amd64.whl", hash = "sha256:557a0aab88664cc552285316809cab897716a372afaf8efdbef756f8b890e894", size = 2024608, upload-time = "2025-10-14T10:21:59.557Z" }, + { url = "https://files.pythonhosted.org/packages/3e/61/51d89cc2612bd147198e120a13f150afbf0bcb4615cddb049ab10b81b79e/pydantic_core-2.41.4-cp314-cp314-win_arm64.whl", hash = "sha256:3f1ea6f48a045745d0d9f325989d8abd3f1eaf47dd00485912d1a3a63c623a8d", size = 1967614, upload-time = "2025-10-14T10:22:01.847Z" }, + { url = "https://files.pythonhosted.org/packages/0d/c2/472f2e31b95eff099961fa050c376ab7156a81da194f9edb9f710f68787b/pydantic_core-2.41.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6c1fe4c5404c448b13188dd8bd2ebc2bdd7e6727fa61ff481bcc2cca894018da", size = 1876904, upload-time = "2025-10-14T10:22:04.062Z" }, + { url = "https://files.pythonhosted.org/packages/4a/07/ea8eeb91173807ecdae4f4a5f4b150a520085b35454350fc219ba79e66a3/pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:523e7da4d43b113bf8e7b49fa4ec0c35bf4fe66b2230bfc5c13cc498f12c6c3e", size = 1882538, upload-time = "2025-10-14T10:22:06.39Z" }, + { url = "https://files.pythonhosted.org/packages/1e/29/b53a9ca6cd366bfc928823679c6a76c7a4c69f8201c0ba7903ad18ebae2f/pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5729225de81fb65b70fdb1907fcf08c75d498f4a6f15af005aabb1fdadc19dfa", size = 2041183, upload-time = "2025-10-14T10:22:08.812Z" }, + { url = "https://files.pythonhosted.org/packages/c7/3d/f8c1a371ceebcaf94d6dd2d77c6cf4b1c078e13a5837aee83f760b4f7cfd/pydantic_core-2.41.4-cp314-cp314t-win_amd64.whl", hash = "sha256:de2cfbb09e88f0f795fd90cf955858fc2c691df65b1f21f0aa00b99f3fbc661d", size = 1993542, upload-time = "2025-10-14T10:22:11.332Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ac/9fc61b4f9d079482a290afe8d206b8f490e9fd32d4fc03ed4fc698214e01/pydantic_core-2.41.4-cp314-cp314t-win_arm64.whl", hash = "sha256:d34f950ae05a83e0ede899c595f312ca976023ea1db100cd5aa188f7005e3ab0", size = 1973897, upload-time = "2025-10-14T10:22:13.444Z" }, +] + +[[package]] +name = "sqlparse" +version = "0.5.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/40/edede8dd6977b0d3da179a342c198ed100dd2aba4be081861ee5911e4da4/sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", size = 84999, upload-time = "2024-12-10T12:05:30.728Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca", size = 44415, upload-time = "2024-12-10T12:05:27.824Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "tzdata" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, +]