counters
This commit is contained in:
parent
659e1ee439
commit
c2edb2fe2a
|
@ -1,2 +1,3 @@
|
||||||
.idea/
|
.idea/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
.venv/
|
|
@ -1,18 +1,44 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from .models import Element, InventoryItem, Partner
|
from .models import Element, InventoryItem, Partner
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger("root")
|
||||||
|
|
||||||
|
|
||||||
class PartnerSerializer(serializers.ModelSerializer):
|
class PartnerSerializer(serializers.ModelSerializer):
|
||||||
|
total_inventory = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Partner
|
model = Partner
|
||||||
fields = ["id", "external_id"]
|
fields = ["id", "external_id", "name", "total_inventory"]
|
||||||
|
|
||||||
|
def get_total_inventory(self, instance):
|
||||||
|
return InventoryItem.objects.filter(partner=instance).count()
|
||||||
|
|
||||||
|
|
||||||
class InventorySerializer(serializers.ModelSerializer):
|
class InventorySerializer(serializers.ModelSerializer):
|
||||||
|
partner_name = serializers.CharField(source="partner.name", read_only=True)
|
||||||
|
total_elements = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InventoryItem
|
model = InventoryItem
|
||||||
fields = ["id", "partner"]
|
fields = ["id", "partner", "partner_name", "name", "total_elements"]
|
||||||
|
|
||||||
|
def get_total_elements(self, instance):
|
||||||
|
return Element.objects.filter(inventory=instance).count()
|
||||||
|
|
||||||
|
|
||||||
class ElementSerializer(serializers.ModelSerializer):
|
class ElementSerializer(serializers.ModelSerializer):
|
||||||
|
inventory_name = serializers.CharField(source="inventory.name", read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Element
|
model = Element
|
||||||
fields = ["id", "external_id", "element_id", "photo", "additional_text", "inventory"]
|
fields = [
|
||||||
|
"id",
|
||||||
|
"external_id",
|
||||||
|
"element_id",
|
||||||
|
"photo",
|
||||||
|
"additional_text",
|
||||||
|
"inventory",
|
||||||
|
"inventory_name",
|
||||||
|
]
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import urllib
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -24,13 +23,6 @@ class PartnerViewSet(viewsets.ModelViewSet):
|
||||||
queryset = Partner.objects.all()
|
queryset = Partner.objects.all()
|
||||||
serializer_class = PartnerSerializer
|
serializer_class = PartnerSerializer
|
||||||
|
|
||||||
def create(self, validated_data):
|
|
||||||
logger.info("create")
|
|
||||||
super().create(**validated_data)
|
|
||||||
|
|
||||||
def get(self, request, **kwargs):
|
|
||||||
logger.info("get")
|
|
||||||
|
|
||||||
@action(detail=False, methods=["get"], url_path=r"external")
|
@action(detail=False, methods=["get"], url_path=r"external")
|
||||||
def get_remote_partners(self, request):
|
def get_remote_partners(self, request):
|
||||||
params = {
|
params = {
|
||||||
|
@ -72,7 +64,7 @@ class InventoryItemViewSet(viewsets.ModelViewSet):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
queryset = InventoryItem.objects.all()
|
queryset = InventoryItem.objects.all()
|
||||||
partner = self.request.query_params.get('partner_id')
|
partner = self.request.query_params.get("partner_id")
|
||||||
if partner is not None:
|
if partner is not None:
|
||||||
queryset = queryset.filter(partner=partner)
|
queryset = queryset.filter(partner=partner)
|
||||||
return queryset
|
return queryset
|
||||||
|
@ -88,7 +80,7 @@ class ElementViewSet(viewsets.ModelViewSet):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
queryset = Element.objects.all()
|
queryset = Element.objects.all()
|
||||||
inventory = self.request.query_params.get('inventory_id')
|
inventory = self.request.query_params.get("inventory_id")
|
||||||
if inventory is not None:
|
if inventory is not None:
|
||||||
queryset = queryset.filter(inventory=inventory)
|
queryset = queryset.filter(inventory=inventory)
|
||||||
return queryset
|
return queryset
|
||||||
|
@ -105,7 +97,8 @@ class ElementViewSet(viewsets.ModelViewSet):
|
||||||
|
|
||||||
# check if inventory exist
|
# check if inventory exist
|
||||||
if (
|
if (
|
||||||
"inventory" in data
|
"inventory"
|
||||||
|
in data
|
||||||
# and InventoryItem.objects.filter(id=data["inventory"]).exists()
|
# and InventoryItem.objects.filter(id=data["inventory"]).exists()
|
||||||
):
|
):
|
||||||
inventory_object = InventoryItem.objects.get(id=data["inventory"])
|
inventory_object = InventoryItem.objects.get(id=data["inventory"])
|
||||||
|
|
4
dev.sh
4
dev.sh
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
xterm -title "To Invetory FRONT" -e "cd front && npm run dev"&
|
x-terminal-emulator -title "To Invetory FRONT" -e "cd front && npm run dev"&
|
||||||
xterm -title "To Invetory BACK" -e "poetry run task server"
|
x-terminal-emulator -title "To Invetory BACK" -e "poetry run task server"
|
|
@ -0,0 +1,6 @@
|
||||||
|
export default defineAppConfig({
|
||||||
|
ui: {
|
||||||
|
primary: 'pink',
|
||||||
|
gray: 'cool'
|
||||||
|
}
|
||||||
|
})
|
|
@ -1,13 +1,17 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import 'assets/main.scss'
|
import 'assets/main.scss'
|
||||||
|
import Logo from 'assets/logo.svg'
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
HEADER
|
<div class="logo">
|
||||||
|
<Logo />
|
||||||
|
</div>
|
||||||
|
<NuxtLink to="/">Инвентаризация</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<Sidebar/>
|
<Sidebar />
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="m15.5 17.125l4.95-4.95q.275-.275.7-.275t.7.275t.275.7t-.275.7l-5.65 5.65q-.3.3-.7.3t-.7-.3l-2.85-2.85q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275zM5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h4.175q.275-.875 1.075-1.437T12 1q1 0 1.788.563T14.85 3H19q.825 0 1.413.588T21 5v4q0 .425-.288.713T20 10t-.712-.288T19 9V5h-2v2q0 .425-.288.713T16 8H8q-.425 0-.712-.288T7 7V5H5v14h5q.425 0 .713.288T11 20t-.288.713T10 21zm7-16q.425 0 .713-.288T13 4t-.288-.712T12 3t-.712.288T11 4t.288.713T12 5"/></svg>
|
After Width: | Height: | Size: 611 B |
|
@ -24,7 +24,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
@apply col-span-12
|
@apply col-span-12 flex gap-2 p-2.5;
|
||||||
|
.logo {
|
||||||
|
@apply text-primary text-2xl
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { object, string, type InferType } from 'yup'
|
import { object, string, type InferType } from 'yup'
|
||||||
import { apiBase } from '~/helpers';
|
import { apiBase } from '~/helpers';
|
||||||
import type { ApiTypeBase, ApiTypeExternal } from '~/helpers';
|
import type { ApiTypeList, ApiTypeExternal } from '~/helpers';
|
||||||
import type { FormSubmitEvent } from '#ui/types'
|
import type { FormSubmitEvent } from '#ui/types'
|
||||||
|
|
||||||
const props = defineProps(['elements', 'partner'])
|
const props = defineProps(['elements', 'partner'])
|
||||||
|
@ -44,7 +44,7 @@ type Schema = InferType<typeof schema>
|
||||||
|
|
||||||
async function onSubmit(event: FormSubmitEvent<Schema>) {
|
async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||||||
const data = await $fetch(`${apiBase}/element/`, { method: 'POST', body: JSON.stringify(event.data) })
|
const data = await $fetch(`${apiBase}/element/`, { method: 'POST', body: JSON.stringify(event.data) })
|
||||||
const newElements = await $fetch<ApiTypeBase>(`${apiBase}/element?inventory_id=${route.params.inv_id}`, { headers })
|
const newElements = await $fetch<ApiTypeList>(`${apiBase}/element?inventory_id=${route.params.inv_id}`, { headers })
|
||||||
elements.value = newElements.results
|
elements.value = newElements.results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,3 +153,8 @@ onMounted(async () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<style scoped>
|
||||||
|
label {
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,13 +1,19 @@
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
export const apiBase = config.public.apiBase
|
export const apiBase = config.public.apiBase
|
||||||
|
|
||||||
export type ApiTypeBase = {
|
export type ApiTypeList = {
|
||||||
count: number;
|
count: number;
|
||||||
next?: any;
|
next?: any;
|
||||||
previous?: any;
|
previous?: any;
|
||||||
results: any[];
|
results: ApiTypeBase[]
|
||||||
}
|
}
|
||||||
|
export type ApiTypeBase =
|
||||||
|
ApiPartner | ApiInventory | ApiElement;
|
||||||
|
|
||||||
|
|
||||||
|
export type ApiPartner = { id: number, external_id: number }
|
||||||
|
export type ApiInventory = { id: number, partner: number }
|
||||||
|
export type ApiElement = { id: number, external_id: string, element_id: number, photo: string, additional_text: string, inventory: number }
|
||||||
export type ApiTypeExternal = {
|
export type ApiTypeExternal = {
|
||||||
'НаименованиеПолное': string;
|
'НаименованиеПолное': string;
|
||||||
Description: string;
|
Description: string;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
ssr: false,
|
ssr: false,
|
||||||
devtools: { enabled: true },
|
devtools: { enabled: true },
|
||||||
modules: ["@nuxt/ui"],
|
modules: ["@nuxt/ui", "nuxt-svgo"],
|
||||||
runtimeConfig: {
|
runtimeConfig: {
|
||||||
public: {
|
public: {
|
||||||
apiBase: '',
|
apiBase: '',
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/ui": "^2.16.0",
|
"@nuxt/ui": "^2.16.0",
|
||||||
"nuxt": "^3.11.2",
|
"nuxt": "^3.11.2",
|
||||||
|
"nuxt-svgo": "^4.0.1",
|
||||||
"vue": "^3.4.27",
|
"vue": "^3.4.27",
|
||||||
"vue-router": "^4.3.2",
|
"vue-router": "^4.3.2",
|
||||||
"yup": "^1.4.0"
|
"yup": "^1.4.0"
|
||||||
|
@ -8413,6 +8414,33 @@
|
||||||
"@nuxt/kit": "^3.11.1"
|
"@nuxt/kit": "^3.11.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/nuxt-svgo": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/nuxt-svgo/-/nuxt-svgo-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-jN82aehGXMXMkapNnk15Vr712EXtPIfG8SX8O//m5Ls/QgD7bbIMkGRbfJKfoX6a4NZm0ojkwvv/hWex8aVY/A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@nuxt/kit": "^3.4.0",
|
||||||
|
"mini-svg-data-uri": "^1.4.4",
|
||||||
|
"svgo": "^3.0.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"svgo-loader": "^4.0.0",
|
||||||
|
"vue": ">=3.2.13",
|
||||||
|
"vue-loader": "^17.0.0",
|
||||||
|
"vue-svg-loader": "0.17.0-beta.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"svgo-loader": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"vue-loader": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"vue-svg-loader": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/nypm": {
|
"node_modules/nypm": {
|
||||||
"version": "0.3.8",
|
"version": "0.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.8.tgz",
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/ui": "^2.16.0",
|
"@nuxt/ui": "^2.16.0",
|
||||||
"nuxt": "^3.11.2",
|
"nuxt": "^3.11.2",
|
||||||
|
"nuxt-svgo": "^4.0.1",
|
||||||
"vue": "^3.4.27",
|
"vue": "^3.4.27",
|
||||||
"vue-router": "^4.3.2",
|
"vue-router": "^4.3.2",
|
||||||
"yup": "^1.4.0"
|
"yup": "^1.4.0"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { apiBase } from '~/helpers';
|
import { apiBase } from '~/helpers';
|
||||||
import type { ApiTypeBase } from '~/helpers';
|
import type { ApiTypeList } from '~/helpers';
|
||||||
|
|
||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
headers.append("Content-Type", "application/json");
|
headers.append("Content-Type", "application/json");
|
||||||
|
|
||||||
const { data } = await useFetch<ApiTypeBase>(`${apiBase}/partner/`, { headers })
|
const { data } = await useFetch<ApiTypeList>(`${apiBase}/partner/`, { headers })
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { apiBase } from '~/helpers';
|
import { apiBase } from '~/helpers';
|
||||||
import type { ApiTypeBase } from '~/helpers';
|
import type { ApiPartner, ApiTypeList } from '~/helpers';
|
||||||
|
|
||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
headers.append("Content-Type", "application/json");
|
headers.append("Content-Type", "application/json");
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const { data: partner } = await useFetch<ApiTypeBase>(`${apiBase}/partner/${route.params.org_id}`, { headers })
|
const { data: partner } = await useFetch<ApiPartner>(`${apiBase}/partner/${route.params.org_id}`, { headers })
|
||||||
const { data: elements } = await useFetch<ApiTypeBase>(`${apiBase}/element?inventory_id=${route.params.inv_id}`, { headers })
|
const { data: elements } = await useFetch<ApiTypeList>(`${apiBase}/element?inventory_id=${route.params.inv_id}`, { headers })
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Edit :elements="elements?.results" :inventory="route.params.org_id" :partner="partner?.external_id"/>
|
<Edit :elements="elements?.results" :inventory="route.params.org_id" :partner="partner?.external_id"/>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { apiBase } from '~/helpers';
|
import { apiBase } from '~/helpers';
|
||||||
import type { ApiTypeBase } from '~/helpers';
|
import type { ApiTypeList } from '~/helpers';
|
||||||
|
|
||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
headers.append("Content-Type", "application/json");
|
headers.append("Content-Type", "application/json");
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const { data } = await useFetch<ApiTypeBase>(`${apiBase}/element?inventory_id=${route.params.inv_id}`, { headers })
|
const { data } = await useFetch<ApiTypeList>(`${apiBase}/element?inventory_id=${route.params.inv_id}`, { headers })
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { apiBase } from '~/helpers';
|
import { apiBase } from '~/helpers';
|
||||||
import type { ApiTypeBase } from '~/helpers';
|
import type { ApiTypeList } from '~/helpers';
|
||||||
|
|
||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
headers.append("Content-Type", "application/json");
|
headers.append("Content-Type", "application/json");
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const { data } = await useFetch<ApiTypeBase>(`${apiBase}/inventory?partner_id=${route.params.org_id}`, { headers })
|
const { data } = await useFetch<ApiTypeList>(`${apiBase}/inventory?partner_id=${route.params.org_id}`, { headers })
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<UTable :rows="data?.results">
|
<UTable :rows="data?.results">
|
||||||
|
|
Loading…
Reference in New Issue