0
0
Fork 0

fea: stockBought add form and formDetail

This commit is contained in:
Pablo Natek 2024-08-05 15:42:57 +02:00
parent 545f7c8039
commit f2be2b4300
9 changed files with 302 additions and 11 deletions

View File

@ -107,7 +107,7 @@ const orders = ref(parseOrder(routeQuery.filter?.order));
const CrudModelRef = ref({});
const showForm = ref(false);
const splittedColumns = ref({ columns: [] });
const columnsVisibilitySkiped = ref();
const columnsVisibilitySkipped = ref();
const tableModes = [
{
icon: 'view_column',
@ -133,7 +133,7 @@ onMounted(() => {
? CARD_MODE
: $props.defaultMode;
stateStore.rightDrawer = true;
columnsVisibilitySkiped.value = [
columnsVisibilitySkipped.value = [
...splittedColumns.value.columns
.filter((c) => c.visible == false)
.map((c) => c.name),
@ -325,11 +325,11 @@ defineExpose({
<div class="q-px-md">
<CrudModel
v-bind="$attrs"
:limit="20"
:limit="$attrs.limit ?? 20"
ref="CrudModelRef"
@on-fetch="(...args) => emit('onFetch', ...args)"
:search-url="searchUrl"
:disable-infinite-scroll="isTableMode"
:disable-infinite-scroll="$attrs['disable-infinite-scroll'] ?? isTableMode"
@save-changes="reload"
:has-sub-toolbar="$attrs['hasSubToolbar'] ?? isEditable"
:auto-load="hasParams || $attrs['auto-load']"
@ -351,9 +351,8 @@ defineExpose({
:grid="!isTableMode"
table-header-class="bg-header"
card-container-class="grid-three"
flat
:style="isTableMode && `max-height: ${tableHeight}`"
virtual-scroll
:virtual-scroll="!isTableMode"
@virtual-scroll="
(event) =>
event.index > rows.length - 2 &&
@ -361,6 +360,7 @@ defineExpose({
"
@row-click="(_, row) => rowClickFunction && rowClickFunction(row)"
@update:selected="emit('update:selected', $event)"
flat
>
<template #top-left v-if="!$props.withoutHeader">
<slot name="top-left"></slot>
@ -370,7 +370,7 @@ defineExpose({
v-if="isTableMode"
v-model="splittedColumns.columns"
:table-code="tableCode ?? route.name"
:skip="columnsVisibilitySkiped"
:skip="columnsVisibilitySkipped"
/>
<QBtnToggle
v-model="mode"

View File

@ -45,7 +45,7 @@ const formattedDate = computed({
if (value) {
// parse input
if (value.includes('/')) {
if (value.length == 6) value = value + new Date().getFullYear();
if (value.length == 6) value = value + Date.vnNew().getFullYear();
if (value.length >= 10) {
if (value.at(2) == '/') value = value.split('/').reverse().join('/');
value = date.formatDate(

View File

@ -62,7 +62,7 @@ const formattedTime = computed({
function dateToTime(newDate) {
return date.formatDate(new Date(newDate), dateFormat);
}
const timeField = ref();
watch(
() => model.value,
(val) => (formattedTime.value = val),

View File

@ -142,6 +142,7 @@ globals:
dms: File management
entryCreate: New entry
latestBuys: Latest buys
reserves: Reserves
tickets: Tickets
ticketCreate: New Tickets
boxing: Boxing

View File

@ -0,0 +1,142 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useState } from 'src/composables/useState';
import { useQuasar } from 'quasar';
import VnTable from 'components/VnTable/VnTable.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import EntryStockBoughtDetail from 'src/pages/Entry/EntryStockBoughtDetail.vue';
const { t } = useI18n();
const quasar = useQuasar();
const tableRef = ref();
const state = useState();
const user = state.getUser();
const columns = [
{
align: 'left',
label: 'Id',
name: 'id',
isTitle: true,
isId: true,
columnFilter: false,
visible: false,
},
{
align: 'left',
name: 'workerFk',
label: t('Buyer'),
columnFilter: false,
},
{
align: 'left',
label: t('Reserve'),
name: 'reserve',
columnFilter: false,
create: true,
component: 'number',
},
{
align: 'left',
name: 'workerFk',
label: t('Buyer'),
component: 'select',
create: true,
visible: false,
columnFilter: false,
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name'],
where: { role: 'buyer' },
optionFilter: 'firstName',
optionLabel: 'name',
optionValue: 'id',
useLike: false,
},
},
{
align: 'left',
label: t('Bought'),
name: 'bought',
columnFilter: false,
},
{
align: 'left',
label: t('Date'),
name: 'dated',
component: 'date',
visible: false,
create: true,
},
{
align: 'left',
name: 'tableActions',
actions: [
{
title: t('More'),
icon: 'search',
isPrimary: true,
action: (row) => {
console.log('workerFk: ', row.workerFk);
quasar.dialog({
component: EntryStockBoughtDetail,
componentProps: {
workerFk: row.workerFk,
dated: row.dated,
},
maximized: true,
});
},
},
],
},
];
</script>
<template>
<VnSubToolbar />
<VnTable
ref="tableRef"
data-key="StockBoughts"
url="StockBoughts/getStockBought"
save-url="StockBoughts/crud"
order="reserve DESC"
:is-editable="true"
:disable-option="{ card: true }"
:create="{
urlCreate: 'StockBoughts',
title: t('Reserve some space'),
onDataSaved: () => tableRef.reload(),
formInitialData: {
workerFk: user.id,
dated: Date.now(),
},
}"
:columns="columns"
>
<template #column-workerFk="{ row }">
<span class="link" @click.stop>
{{ row?.worker?.user?.name }}
<WorkerDescriptorProxy :id="row?.workerFk" />
</span>
</template>
</VnTable>
</template>
<i18n>
en:
Buyer: Buyer
Reserve: Reserve
Bought: Bought
More: More
Date: Date
This buyer has already made a reservation for this date: This buyer has already made a reservation for this date
es:
Buyer: Comprador
Reserve: Reservado
Bought: Comprado
More: Más
Date: Fecha
Reserve some space: Reservar espacio
This buyer has already made a reservation for this date: Este comprador ya ha hecho una reserva para esta fecha
</i18n>

View File

@ -0,0 +1,102 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import VnTable from 'components/VnTable/VnTable.vue';
import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
const { t } = useI18n();
const tableRef = ref();
const $props = defineProps({
workerFk: {
type: Number,
required: true,
},
dated: {
type: String,
required: true,
},
});
console.log('$props: ', $props.workerFk, $props.dated);
const customUrl = `StockBoughts/getStockBoughtDetail?workerFk=${$props.workerFk}`;
const columns = [
{
align: 'left',
label: 'Entry',
name: 'entryFk',
isTitle: true,
isId: true,
columnFilter: false,
},
{
align: 'left',
name: 'itemFk',
label: t('Item'),
columnFilter: false,
},
{
align: 'left',
label: t('Name'),
name: 'itemName',
columnFilter: false,
create: true,
columnClass: 'expand',
},
{
align: 'left',
name: 'volume',
label: t('Volume'),
columnFilter: false,
},
{
align: 'left',
label: t('Packaging'),
name: 'packagingFk',
columnFilter: false,
},
{
align: 'left',
label: 'Packing',
name: 'packing',
columnFilter: false,
},
];
</script>
<template>
<QDialog>
<VnTable
ref="tableRef"
data-key="StockBoughtsDetail"
:url="customUrl"
order="itemName DESC"
:columns="columns"
:right-search="false"
:disable-infinite-scroll="true"
:disable-option="{ card: true }"
:limit="0"
auto-load
>
<template #column-entryFk="{ row }">
<span class="link" @click.stop>
{{ row?.entryFk }}
<EntryDescriptorProxy :id="row.entryFk" />
</span>
</template>
<template #column-itemName="{ row }">
<span class="link" @click.stop>
{{ row?.itemName }}
<ItemDescriptorProxy :id="row.itemFk" />
</span>
</template>
</VnTable>
</QDialog>
</template>
<i18n>
es:
Buyer: Comprador
Reserve: Reservado
Bought: Comprado
More: Más
Date: Fecha
</i18n>

View File

@ -139,7 +139,7 @@ const columns = computed(() => [
{
align: 'center',
name: 'm3',
label: 'volume',
label: t('Volume'),
cardVisible: true,
},
{
@ -379,4 +379,5 @@ es:
Route is not served: La ruta no está servida
hourStarted: Hora de inicio
hourFinished: Hora de fin
Volume: Volumen
</i18n>

View File

@ -11,7 +11,7 @@ export default {
component: RouterView,
redirect: { name: 'EntryMain' },
menus: {
main: ['EntryList', 'MyEntries', 'EntryLatestBuys'],
main: ['EntryList', 'MyEntries', 'EntryLatestBuys', 'EntryStockBought'],
card: ['EntryBasicData', 'EntryBuys', 'EntryNotes', 'EntryDms', 'EntryLog'],
},
children: [
@ -57,6 +57,15 @@ export default {
},
component: () => import('src/pages/Entry/EntryLatestBuys.vue'),
},
{
path: 'stock-Bought',
name: 'EntryStockBought',
meta: {
title: 'reserves',
icon: 'deployed_code_history',
},
component: () => import('src/pages/Entry/EntryStockBought.vue'),
},
],
},
{

View File

@ -0,0 +1,36 @@
describe('EntryStockBought', () => {
const reserveField = 'input[name="reserve"]';
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('buyer');
cy.visit(
`/#/entry/stock-Bought?table={"filter":"{}","dated":"2000-12-31T23:00:00.000Z"}`
);
});
it('Should edit the reserved space', () => {
cy.get('tBody > tr').its('length').should('eq', 1);
cy.get(reserveField).type('10{enter}');
cy.get('button[title="Save"]').click();
cy.get('.q-notification__message').should('have.text', 'Data saved');
});
it('Should add a new reserved space for buyerBoss', () => {
cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
cy.get('input[aria-label="Reserve"]').type('1');
cy.get('input[aria-label="Date"]').eq(1).clear();
cy.get('input[aria-label="Date"]').eq(1).type('01-01');
cy.get('input[aria-label="Buyer"]').type('buyerboss{downarrow}{enter}');
cy.get('.q-notification__message').should('have.text', 'Data created');
cy.get('tBody > tr').its('length').should('eq', 2);
});
it('Should check detail for the buyer', () => {
cy.get(':nth-child(1) > .sticky > .q-btn > .q-btn__content > .q-icon').click();
cy.get('tBody > tr').eq(1).its('length').should('eq', 1);
});
it('Should check detail for the buyerBoss and had no content', () => {
cy.get(':nth-child(2) > .sticky > .q-btn > .q-btn__content > .q-icon').click();
cy.get('.q-table__bottom.row.items-center.q-table__bottom--nodata').should(
'have.text',
'warningNo data available'
);
});
});