Compare commits

..

15 Commits

Author SHA1 Message Date
43756952fb Merge pull request 'Creada vista para listar los cuadres de tarro #90' (#91) from view_for_jar_reconciliation_#90 into main
Reviewed-on: #91
2025-02-02 23:08:00 -05:00
6a346bdf8a #90 fix(Frontend): set default tab in Reconciliation summary. 2025-02-02 23:04:54 -05:00
2a983c8056 #90 fix(Frontend): fix datetime in Reconciliation summary. 2025-02-02 22:49:38 -05:00
2c6449c727 #90 feat(Frontend): add Purchases in cuadres_de_tarro. 2025-02-02 22:48:21 -05:00
77a0c4ac0d #90 feat(Frontend): add Purchases in cuadres_de_tarro. 2025-02-02 22:40:31 -05:00
2fcf884cce #90 feat(api): add payment method to sales. 2025-01-28 09:17:48 -05:00
75d39c6ca7 #90 feat(frontend): add modal to ReconciliationJarIndex. 2025-01-18 12:53:53 -05:00
a5d4c1977a #90 feat(frontend): minor fix. 2025-01-18 12:43:50 -05:00
d85ad7cc38 #90 feat(frontend): getReconciliation api method. 2025-01-18 12:43:01 -05:00
aa45ea44ac #90 feat(frontend): getReconciliation api method. 2025-01-18 12:42:33 -05:00
1b06818583 #90 feat(frontend): add ReconciliationJarView.vue. 2025-01-18 12:22:45 -05:00
baa0677e7a #90 feat(frontend): add cuadres_de_tarro page. 2025-01-12 01:23:17 -05:00
d9d3239662 #90 api(frontend): add getListReconcliations. 2025-01-12 01:20:33 -05:00
8bc2d02572 #90 test: minor fix. 2025-01-12 01:18:53 -05:00
c9cfc7f873 #90 feat(ReconcilaitionJar): create api view with pagination. 2025-01-12 00:24:30 -05:00
21 changed files with 1221 additions and 1454 deletions

View File

@ -2,6 +2,7 @@ from rest_framework import viewsets
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.status import HTTP_400_BAD_REQUEST from rest_framework.status import HTTP_400_BAD_REQUEST
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.pagination import PageNumberPagination
from .models import Sale, SaleLine, Customer, Product, ReconciliationJar, PaymentMethods, AdminCode from .models import Sale, SaleLine, Customer, Product, ReconciliationJar, PaymentMethods, AdminCode
from .serializers import SaleSerializer, ProductSerializer, CustomerSerializer, ReconciliationJarSerializer, PaymentMethodSerializer, SaleForRenconciliationSerializer, SaleSummarySerializer from .serializers import SaleSerializer, ProductSerializer, CustomerSerializer, ReconciliationJarSerializer, PaymentMethodSerializer, SaleForRenconciliationSerializer, SaleSummarySerializer
@ -9,6 +10,12 @@ from .serializers import SaleSerializer, ProductSerializer, CustomerSerializer,
from decimal import Decimal from decimal import Decimal
import json import json
class Pagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
class SaleView(viewsets.ModelViewSet): class SaleView(viewsets.ModelViewSet):
queryset = Sale.objects.all() queryset = Sale.objects.all()
serializer_class = SaleSerializer serializer_class = SaleSerializer
@ -131,3 +138,9 @@ class AdminCodeValidateView(APIView):
def get(self, request, code): def get(self, request, code):
codes = AdminCode.objects.filter(value=code) codes = AdminCode.objects.filter(value=code)
return Response({'validCode': bool(codes)}) return Response({'validCode': bool(codes)})
class ReconciliateJarModelView(viewsets.ModelViewSet):
queryset = ReconciliationJar.objects.all().order_by('-date_time')
pagination_class = Pagination
serializer_class = ReconciliationJarSerializer

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,5 @@
{ {
"name": "don-confiao", "name": "don-confiao",
"type": "module",
"version": "0.0.0", "version": "0.0.0",
"scripts": { "scripts": {
"dev": "vite --host 0.0.0.0", "dev": "vite --host 0.0.0.0",
@ -11,7 +10,6 @@
"dependencies": { "dependencies": {
"@mdi/font": "7.4.47", "@mdi/font": "7.4.47",
"core-js": "^3.37.1", "core-js": "^3.37.1",
"cors": "^2.8.5",
"roboto-fontface": "*", "roboto-fontface": "*",
"vee-validate": "^4.14.6", "vee-validate": "^4.14.6",
"vue": "^3.4.31", "vue": "^3.4.31",

View File

@ -29,7 +29,8 @@
menuItems: [ menuItems: [
{ title: 'Inicio', route: '/'}, { title: 'Inicio', route: '/'},
{ title: 'Comprar', route:'/comprar'}, { title: 'Comprar', route:'/comprar'},
{ title: 'Cuadrar tarro', route: '/cuadrar_tarro'} { title: 'Cuadrar tarro', route: '/cuadrar_tarro'},
{ title: 'Cuadres de tarro', route: '/cuadres_de_tarro'},
], ],
}), }),
watch: { watch: {

View File

@ -276,14 +276,7 @@
fetchProducts() { fetchProducts() {
this.api.getProducts() this.api.getProducts()
.then(data => { .then(data => {
console.log(data) this.products = data;
const transformed_products = data.map(item => ({
name: item.name,
price: item["template."]?.list_price?.decimal,
measuring_unit: item["default_uom"]?.name,
categories: []
}));
this.products = transformed_products;
}) })
.catch(error => { .catch(error => {
console.error(error); console.error(error);

View File

@ -0,0 +1,64 @@
<template>
<v-container>
<v-toolbar>
<v-toolbar-title> Cuadres del Tarro </v-toolbar-title>
</v-toolbar>
<v-card>
<v-card-text>
<v-data-table-server
v-model:items-per-page="itemsPerPage"
:headers="headers"
:items="serverItems"
:items-length="totalItems"
:loading="loading"
:search="search"
@update:options="loadItems"
>
<template v-slot:item.id="{ item }">
<v-btn @click="openSummaryModal(item.id)">{{ item.id }}</v-btn>
</template>
</v-data-table-server>
<SummaryReconciliationModal :id="selectedReconciliationId" ref="summaryModal" />
</v-card-text>
</v-card>
</v-container>
</template>
<script>
export default {
data() {
return {
api: inject('api'),
selectedReconciliationId: null,
itemsPerPage: 10,
headers: [
{ title: 'Acciones', key: 'id'},
{ title: 'Fecha', key: 'date_time'},
{ title: 'Reconciliador', key: 'reconcilier'},
{ title: 'Total Compras Efectivo', key: 'total_cash_purchases'},
{ title: 'Recogido', key: 'cash_taken'},
{ title: 'Descuadre', key: 'cash_discrepancy'},
],
search: '',
serverItems: [],
loading: true,
totalItems: 0,
}
},
methods: {
loadItems ({page, itemsPerPage}) {
this.loading = true;
this.api.getListReconcliations(page, itemsPerPage)
.then(data => {
this.serverItems = data['results'];
this.totalItems = data['count'];
this.loading = false;
})
.catch(error => console.log('Error:', error));
},
openSummaryModal(id) {
this.selectedReconciliationId = id.toString();
this.$refs.summaryModal.dialog = true;
},
},
}
</script>

View File

@ -0,0 +1,140 @@
<template>
<v-container>
<v-toolbar>
<v-toolbar-title> Cuadre de Tarro: {{ id }}</v-toolbar-title>
</v-toolbar>
<v-card>
<v-card-text>
<v-text-field
v-model="reconciliation.date_time"
label="Fecha"
required
readonly
></v-text-field>
<v-text-field
v-model="reconciliation.reconcilier"
label="Cajero"
required
readonly
></v-text-field>
<v-text-field
v-model="reconciliation.total_cash_purchases"
label="Total Ventas en efectivo"
prefix="$"
type="number"
readonly
></v-text-field>
<v-text-field
v-model="reconciliation.cash_taken"
label="Dinero Recogido"
prefix="$"
type="number"
></v-text-field>
<v-text-field
v-model="reconciliation.cash_discrepancy"
label="Descuadre"
prefix="$"
type="number"
></v-text-field>
<v-tabs v-model="tab">
<v-tab
v-for="(elements, paymentMethod) in purchases"
:key="paymentMethod"
>
{{ paymentMethod }}&nbsp; <CurrencyText :value="elements.total"</CurrencyText>
</v-tab>
</v-tabs>
<v-tabs-window v-model="tab">
<v-tabs-window-item
v-for="(elements, paymentMethod) in purchases"
:key="paymentMethod"
>
<v-table>
<thead>
<tr>
<th>Id</th>
<th>Fecha</th>
<th>Cliente</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr v-for="purchase in elements.purchases" :key="purchase.id">
<td><v-btn @click="openSummaryModal(purchase.id)">{{ purchase.id }}</v-btn></td>
<td>{{ purchase.date }}</td>
<td>{{ purchase.customer }}</td>
<td><CurrencyText :value="purchase.total"</CurrencyText></td>
</tr>
</tbody>
</v-table>
</v-tabs-window-item>
</v-tabs-window>
<SummaryPurchaseModal :id="selectedPurchaseId" ref="summaryModal" />
</v-card-text>
</v-card>
</v-container>
</template>
<script>
import { inject } from 'vue';
export default {
name: 'ReconciliationJar View',
props: {
msg: String,
id: {
type: String,
required: true
}
},
data () {
return {
tab: '0',
selectedPurchaseId: null,
api: inject('api'),
valid: null,
reconciliation: {
},
purchases: {},
};
},
created() {
if (this.id) {
this.fetchReconciliation(this.id);
} else {
console.error('No se proporcionó ID');
}
},
methods: {
fetchReconciliation(reconciliationId) {
this.api.getReconciliation(reconciliationId)
.then(data => {
this.reconciliation = data;
this.groupPurchases();
})
.catch(error => console.error(error));
},
groupPurchases() {
if (this.reconciliation.Sales) {
this.purchases = this.reconciliation.Sales.reduce((grouped, sale) => {
const paymentMethod = sale.payment_method;
if (!grouped[paymentMethod]) {
grouped[paymentMethod] = {
purchases: [],
total: 0,
};
}
grouped[paymentMethod].purchases.push(sale);
grouped[paymentMethod].total += sale.total;
return grouped;
}, {});
}
},
openSummaryModal(id) {
this.selectedPurchaseId = id;
this.$refs.summaryModal.dialog = true;
},
},
}
</script>

View File

@ -53,7 +53,7 @@
name: 'SummaryPurchase', name: 'SummaryPurchase',
props: { props: {
msg: String, msg: String,
id: String id: Number
}, },
data () { data () {
return { return {

View File

@ -0,0 +1,30 @@
<template>
<v-dialog v-model="dialog" max-width="400">
<v-card>
<v-card-text>
<SummaryPurchase :id="id"/>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn text @click="dialog = false">Cerrar</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
name: 'SummaryPurchase Modal',
props: {
id: {
type: Number,
required: true,
}
},
data() {
return {
dialog: false,
}
},
}
</script>

View File

@ -0,0 +1,31 @@
<template>
<v-dialog v-model="dialog" max-width="400">
resumen
<v-card>
<v-card-text>
<ReconciliationJarView :id="id"/>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn text @click="dialog = false">Cerrar</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
name: 'Summary Reconciliation Modal',
props: {
id: {
type: String,
required: true,
}
},
data() {
return {
dialog: false,
}
},
}
</script>

View File

@ -13,20 +13,12 @@ import ApiImplementation from './services/api-implementation';
// Composables // Composables
import { createApp } from 'vue' import { createApp } from 'vue'
import cors from 'cors';
// const cors = require('cors'); process.env.API_IMPLEMENTATION = 'django';
process.env.API_IMPLEMENTATION = 'tryton';
// process.env.API_IMPLEMENTATION = 'django';
let apiImplementation = new ApiImplementation(); let apiImplementation = new ApiImplementation();
const api = apiImplementation.getApi(); const api = apiImplementation.getApi();
const app = createApp(App); const app = createApp(App);
// app.use(cors({
// origin: '*', // Permitir todas las solicitudes de origen
// exposedHeaders: ['X-Custom-Header', 'Content-Length'], // Exponer headers específicos
// }));
app.provide('api', api); app.provide('api', api);
registerPlugins(app) registerPlugins(app)

View File

@ -0,0 +1,20 @@
<template>
<div>
<CodeDialog @code-verified="(verified) => showComponent = verified" />
</div>
<ReconciliationJarIndex v-if="showComponent" />
</template>
<script>
import CodeDialog from '../components/CodeDialog.vue'
export default {
data() {
return {
showComponent: false,
}
},
components: { CodeDialog },
methods: {},
}
</script>

View File

@ -1,5 +1,4 @@
import DjangoApi from './django-api'; import DjangoApi from './django-api';
import TrytonApiClient from './tryton-api';
import Api from './api'; import Api from './api';
class ApiImplementation { class ApiImplementation {
@ -8,13 +7,6 @@ class ApiImplementation {
let apiImplementation; let apiImplementation;
if (implementation === 'django') { if (implementation === 'django') {
apiImplementation = new DjangoApi(); apiImplementation = new DjangoApi();
} else if (implementation === 'tryton'){
const url = 'http://192.168.0.114:18030';
const key = '9a9ffc430146447d81e6698240199a4be2b0e774cb18474999d0f60e33b5b1eb1cfff9d9141346a98844879b5a9e787489c891ddc8fb45cc903b7244cab64fb1';
const db = 'tryton';
const applicationName = 'sale_don_confiao';
apiImplementation = new TrytonApiClient(
url, key, db, applicationName);
} else { } else {
throw new Error("API implementation don't configured"); throw new Error("API implementation don't configured");
} }

View File

@ -11,7 +11,6 @@ class Api {
return this.apiImplementation.getProducts(); return this.apiImplementation.getProducts();
} }
getPaymentMethods() { getPaymentMethods() {
return this.apiImplementation.getPaymentMethods(); return this.apiImplementation.getPaymentMethods();
} }
@ -24,6 +23,14 @@ class Api {
return this.apiImplementation.getPurchasesForReconciliation(); return this.apiImplementation.getPurchasesForReconciliation();
} }
getListReconcliations(page=1, itemsPerPage=10) {
return this.apiImplementation.getListReconcliations(page, itemsPerPage);
}
getReconciliation(reconciliationId) {
return this.apiImplementation.getReconciliation(reconciliationId);
}
isValidAdminCode(code) { isValidAdminCode(code) {
return this.apiImplementation.isValidAdminCode(code); return this.apiImplementation.isValidAdminCode(code);
} }

View File

@ -24,6 +24,16 @@ class DjangoApi {
return this.getRequest(url); return this.getRequest(url);
} }
getListReconcliations(page, itemsPerPage) {
const url = `/don_confiao/api/reconciliate_jar/?page=${page}&page_size=${itemsPerPage}`;
return this.getRequest(url);
}
getReconciliation(reconciliationId) {
const url = `/don_confiao/api/reconciliate_jar/${reconciliationId}/`;
return this.getRequest(url);
}
isValidAdminCode(code) { isValidAdminCode(code) {
const url = `/don_confiao/api/admin_code/validate/${code}` const url = `/don_confiao/api/admin_code/validate/${code}`
return this.getRequest(url) return this.getRequest(url)

View File

@ -1,98 +0,0 @@
class TrytonApiClient {
constructor(url, key, db, applicationName) {
this.baseUrl = `${url}/${db}/${applicationName}`;
this.headers = {
'Authorization': `Bearer ${key}`,
'Content-Type': 'application/json',
mode: 'cors'
};
}
getCustomers() {
const url = this.baseUrl + '/parties';
const customers = this.getRequest(url);
return customers;
}
getProducts() {
const url = this.baseUrl + '/products'
const products = this.getRequest(url);
return products;
}
getPaymentMethods() {
const url = '/don_confiao/payment_methods/all/select_format';
return this.getRequest(url);
}
getSummaryPurchase(purchaseId) {
const url = `/don_confiao/resumen_compra_json/${purchaseId}`;
return this.getRequest(url);
}
getPurchasesForReconciliation() {
const url = '/don_confiao/purchases/for_reconciliation';
return this.getRequest(url);
}
isValidAdminCode(code) {
const url = `/don_confiao/api/admin_code/validate/${code}`
return this.getRequest(url)
}
createPurchase(purchase) {
const url = '/don_confiao/api/sales/';
return this.postRequest(url, purchase);
}
createReconciliationJar(reconciliation) {
const url = '/don_confiao/reconciliate_jar';
return this.postRequest(url, reconciliation);
}
createCustomer(customer) {
const url = '/don_confiao/api/customers/';
return this.postRequest(url, customer);
}
getRequest(url) {
return new Promise ((resolve, reject) => {
fetch(url, {
method: 'GET',
headers: this.headers
}).then(response => response.json())
.then(data => {
resolve(data);
})
.catch(error => {
reject(error);
});
});
}
postRequest(url, content) {
return new Promise((resolve, reject) => {
fetch(url, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(content)
})
.then(response => {
if (!response.ok) {
reject(new Error(`Error ${response.status}: ${response.statusText}`));
} else {
response.json().then(data => {
if (!data) {
reject(new Error('La respuesta no es un JSON válido'));
} else {
resolve(data);
}
});
}
})
.catch(error => reject(error));
});
}
}
export default TrytonApiClient;

View File

@ -11,8 +11,6 @@ import Vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import { fileURLToPath, URL } from 'node:url' import { fileURLToPath, URL } from 'node:url'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
@ -65,19 +63,6 @@ export default defineConfig({
}, },
server: { server: {
port: 3000, port: 3000,
cors: {
origin: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
},
proxy: {
'/sale_don_confiao': {
target: "http://127.0.0.1:8000/tryton/sale_don_confiao", // Cambia esto a la URL de tu API
changeOrigin: true,
rewrite: (path) => path.replace(/^\/sale_don_confiao/, '/tryton/sale_don_confiao'), // Opcional: reescribe la ruta
ws: true
},
},
}, },
build: { build: {
outDir: '../../static/frontend/', outDir: '../../static/frontend/',

View File

@ -10,9 +10,12 @@ class SaleLineSerializer(serializers.ModelSerializer):
class SaleSerializer(serializers.ModelSerializer): class SaleSerializer(serializers.ModelSerializer):
total = serializers.ReadOnlyField(source='get_total')
class Meta: class Meta:
model = Sale model = Sale
fields = ['id', 'customer', 'date', 'saleline_set'] fields = ['id', 'customer', 'date', 'saleline_set',
'total', 'payment_method']
class ProductSerializer(serializers.ModelSerializer): class ProductSerializer(serializers.ModelSerializer):
@ -28,6 +31,8 @@ class CustomerSerializer(serializers.ModelSerializer):
class ReconciliationJarSerializer(serializers.ModelSerializer): class ReconciliationJarSerializer(serializers.ModelSerializer):
Sales = SaleSerializer(many=True, read_only=True)
class Meta: class Meta:
model = ReconciliationJar model = ReconciliationJar
fields = [ fields = [
@ -37,8 +42,10 @@ class ReconciliationJarSerializer(serializers.ModelSerializer):
'cash_taken', 'cash_taken',
'cash_discrepancy', 'cash_discrepancy',
'total_cash_purchases', 'total_cash_purchases',
'Sales',
] ]
class PaymentMethodSerializer(serializers.Serializer): class PaymentMethodSerializer(serializers.Serializer):
text = serializers.CharField() text = serializers.CharField()
value = serializers.CharField() value = serializers.CharField()
@ -49,6 +56,7 @@ class PaymentMethodSerializer(serializers.Serializer):
'value': instance[0], 'value': instance[0],
} }
class SaleForRenconciliationSerializer(serializers.Serializer): class SaleForRenconciliationSerializer(serializers.Serializer):
id = serializers.IntegerField() id = serializers.IntegerField()
date = serializers.DateTimeField() date = serializers.DateTimeField()

View File

@ -139,22 +139,7 @@ class TestJarReconcliation(TestCase):
self.assertIn('total_cash_purchases', content['error']) self.assertIn('total_cash_purchases', content['error'])
def test_create_reconciliation_with_purchases(self): def test_create_reconciliation_with_purchases(self):
url = '/don_confiao/reconciliate_jar' response = self._create_reconciliation_with_purchase()
total_purchases = (11 * 72500) + (27 * 72500)
data = {
'date_time': '2024-12-02T21:07',
'reconcilier': 'carlos',
'total_cash_purchases': total_purchases,
'cash_taken': total_purchases,
'cash_discrepancy': 0,
'cash_purchases': [
self.purchase.id,
self.purchase2.id,
self.purchase.id,
],
}
response = self.client.post(url, data=json.dumps(data).encode('utf-8'),
content_type='application/json')
rawContent = response.content.decode('utf-8') rawContent = response.content.decode('utf-8')
content = json.loads(rawContent) content = json.loads(rawContent)
@ -197,6 +182,59 @@ class TestJarReconcliation(TestCase):
purchases = Sale.objects.filter(reconciliation_id=content['id']) purchases = Sale.objects.filter(reconciliation_id=content['id'])
self.assertEqual(len(purchases), 3) self.assertEqual(len(purchases), 3)
def test_list_reconciliations(self):
self._create_simple_reconciliation()
self._create_simple_reconciliation()
url = '/don_confiao/api/reconciliate_jar/'
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
content = json.loads(response.content.decode('utf-8'))
self.assertEqual(2, content['count'])
self.assertEqual(2, len(content['results']))
self.assertEqual('2024-07-30T00:00:00Z',
content['results'][0]['date_time'])
def test_list_reconciliations_pagination(self):
self._create_simple_reconciliation()
self._create_simple_reconciliation()
url = '/don_confiao/api/reconciliate_jar/?page=2&page_size=1'
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
content = json.loads(response.content.decode('utf-8'))
self.assertEqual(1, len(content['results']))
self.assertEqual('2024-07-30T00:00:00Z',
content['results'][0]['date_time'])
def test_get_single_reconciliation(self):
createResponse = self._create_reconciliation_with_purchase()
reconciliationId = json.loads(
createResponse.content.decode('utf-8')
)['id']
self.assertGreater(reconciliationId, 0)
url = f'/don_confiao/api/reconciliate_jar/{reconciliationId}/'
response = self.client.get(url, content_type='application/json')
content = json.loads(
response.content.decode('utf-8')
)
self.assertEqual(reconciliationId, content['id'])
self.assertGreater(len(content['Sales']), 0)
self.assertIn(
self.purchase.id,
[sale['id'] for sale in content['Sales']]
)
self.assertIn(
'CASH',
[sale['payment_method'] for sale in content['Sales']]
)
def _create_simple_reconciliation(self): def _create_simple_reconciliation(self):
reconciliation = ReconciliationJar() reconciliation = ReconciliationJar()
reconciliation.date_time = "2024-07-30" reconciliation.date_time = "2024-07-30"
@ -206,3 +244,21 @@ class TestJarReconcliation(TestCase):
reconciliation.clean() reconciliation.clean()
reconciliation.save() reconciliation.save()
return reconciliation return reconciliation
def _create_reconciliation_with_purchase(self):
url = '/don_confiao/reconciliate_jar'
total_purchases = (11 * 72500) + (27 * 72500)
data = {
'date_time': '2024-12-02T21:07',
'reconcilier': 'carlos',
'total_cash_purchases': total_purchases,
'cash_taken': total_purchases,
'cash_discrepancy': 0,
'cash_purchases': [
self.purchase.id,
self.purchase2.id,
self.purchase.id,
],
}
return self.client.post(url, data=json.dumps(data).encode('utf-8'),
content_type='application/json')

View File

@ -10,7 +10,8 @@ router = DefaultRouter()
router.register(r'sales', api_views.SaleView, basename='sale') router.register(r'sales', api_views.SaleView, basename='sale')
router.register(r'customers', api_views.CustomerView, basename='customer') router.register(r'customers', api_views.CustomerView, basename='customer')
router.register(r'products', api_views.ProductView, basename='product') router.register(r'products', api_views.ProductView, basename='product')
router.register(r'reconciliate_jar', api_views.ReconciliateJarModelView,
basename='reconciliate_jar')
urlpatterns = [ urlpatterns = [
path("", views.index, name="wellcome"), path("", views.index, name="wellcome"),

View File

@ -28,10 +28,6 @@ DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = []
CORS_ALLOWED_ORIGINS = [
"http://localhost:8000",
]
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [