[
columnFilter: false,
cardVisible: true,
},
+ {
+ align: 'left',
+ name: 'buyerId',
+ label: t('customer.params.buyerId'),
+ component: 'select',
+ attrs: {
+ url: 'TicketRequests/getItemTypeWorker',
+ optionLabel: 'nickname',
+ optionValue: 'id',
+
+ fields: ['id', 'nickname'],
+ sortBy: ['nickname ASC'],
+ optionFilter: 'firstName',
+ },
+ cardVisible: false,
+ visible: false,
+ },
{
name: 'description',
align: 'left',
@@ -74,6 +91,7 @@ const columns = computed(() => [
name: 'quantity',
label: t('globals.quantity'),
cardVisible: true,
+ visible: true,
columnFilter: {
inWhere: true,
},
@@ -138,11 +156,11 @@ const updateDateParams = (value, params) => {
const campaign = campaignList.value.find((c) => c.id === value);
if (!campaign) return;
- const { dated, previousDays, scopeDays } = campaign;
- const _date = new Date(dated);
- const [from, to] = dateRange(_date);
- params.from = new Date(from.setDate(from.getDate() - previousDays)).toISOString();
- params.to = new Date(to.setDate(to.getDate() + scopeDays)).toISOString();
+ const { dated, scopeDays } = campaign;
+ const from = new Date(dated);
+ from.setDate(from.getDate() - scopeDays);
+ params.from = from;
+ params.to = dated;
return params;
};
@@ -205,24 +223,57 @@ const updateDateParams = (value, params) => {
updateDateParams(data, params)"
>
-
- {{ scope.opt?.code }}
- {{
- new Date(scope.opt?.dated).getFullYear()
- }}
+ {{ scope.opt?.name }}
+ {{
+ scope.opt?.category?.name
+ }}
+
+
+
+
+
updateDateParams(data, params)"
+ />
+ updateDateParams(data, params)"
+ dense
+ >
+
+
+
+ {{ t(scope.opt?.code) }}
+
+ {{ new Date(scope.opt?.dated).getFullYear() }}
+
@@ -247,7 +298,19 @@ const updateDateParams = (value, params) => {
+en:
+
+ valentinesDay: Valentine's Day
+ mothersDay: Mother's Day
+ allSaints: All Saints' Day
es:
Enter a new search: Introduce una nueva búsqueda
Group by items: Agrupar por artículos
+ valentinesDay: Día de San Valentín
+ mothersDay: Día de la Madre
+ allSaints: Día de Todos los Santos
+ Campaign consumption: Consumo campaña
+ Campaign: Campaña
+ From: Desde
+ To: Hasta
diff --git a/src/pages/Customer/Card/CustomerDescriptor.vue b/src/pages/Customer/Card/CustomerDescriptor.vue
index a646ad299..a4da925fa 100644
--- a/src/pages/Customer/Card/CustomerDescriptor.vue
+++ b/src/pages/Customer/Card/CustomerDescriptor.vue
@@ -110,7 +110,21 @@ const debtWarning = computed(() => {
>
{{ t('customer.card.isDisabled') }}
-
+
+
+ {{ t('Allowed substitution') }}
+
+
{{ t('customer.card.isFrozen') }}
{
.join('&');
useOpenURL(`/#/${type}/list?${params}`);
};
+const updateSubstitutionAllowed = async () => {
+ try {
+ await axios.patch(`Clients/${route.params.id}`, {
+ substitutionAllowed: !$props.customer.substitutionAllowed,
+ });
+ notify('globals.notificationSent', 'positive');
+ } catch (error) {
+ notify(error.message, 'positive');
+ }
+};
@@ -69,6 +79,13 @@ const openCreateForm = (type) => {
{{ t('globals.pageTitles.createTicket') }}
+
+ {{
+ $props.customer.substitutionAllowed
+ ? t('Disable substitution')
+ : t('Allow substitution')
+ }}
+
{{ t('Send SMS') }}
diff --git a/src/pages/Customer/Card/CustomerFiscalData.vue b/src/pages/Customer/Card/CustomerFiscalData.vue
index b256c001a..bd887acb7 100644
--- a/src/pages/Customer/Card/CustomerFiscalData.vue
+++ b/src/pages/Customer/Card/CustomerFiscalData.vue
@@ -9,6 +9,7 @@ import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnLocation from 'src/components/common/VnLocation.vue';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
const { t } = useI18n();
const route = useRoute();
@@ -110,14 +111,11 @@ function handleLocation(data, location) {
-
-
-
-
- {{ t('whenActivatingIt') }}
-
-
-
+
@@ -129,17 +127,11 @@ function handleLocation(data, location) {
-
-
-
-
- {{ t('inOrderToInvoice') }}
-
-
-
+
diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue
index eae97d1be..21de8fa9b 100644
--- a/src/pages/Customer/CustomerFilter.vue
+++ b/src/pages/Customer/CustomerFilter.vue
@@ -1,4 +1,3 @@
-
+
+
+
+
+
+
+
+ {{ statusConditionalValue(row) }}%
+
+
+
+ {{ row.longName }}
+
+
+
+
+
+
+ {{ row.value5 }}
+
+
+ {{ row.value6 }}
+
+
+ {{ row.value7 }}
+
+
+ {{ row.counter }}
+
+
+ {{ row.minQuantity }}
+
+
+
+
+ {{
+ toCurrency(row.price2)
+ }}
+
+
+
+
+
diff --git a/src/pages/Item/components/ItemProposalProxy.vue b/src/pages/Item/components/ItemProposalProxy.vue
new file mode 100644
index 000000000..7da0ce398
--- /dev/null
+++ b/src/pages/Item/components/ItemProposalProxy.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+ {{ $t('Item proposal') }}
+
+
+
+
+ {
+ emit('itemReplaced', data);
+ dialogRef.hide();
+ }
+ "
+ >
+
+
+
+
diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml
index bc73abb12..d74ef9cbc 100644
--- a/src/pages/Item/locale/en.yml
+++ b/src/pages/Item/locale/en.yml
@@ -130,6 +130,7 @@ item:
origin: Orig.
userName: Buyer
weight: Weight
+ color: Color
weightByPiece: Weight/stem
stemMultiplier: Multiplier
producer: Producer
@@ -215,4 +216,24 @@ item:
specie: Specie
search: 'Search item'
searchInfo: 'You can search by id'
- regularizeStock: Regularize stock
\ No newline at end of file
+ regularizeStock: Regularize stock
+itemProposal: Items proposal
+proposal:
+ difference: Difference
+ title: Items proposal
+ itemFk: Item
+ longName: Name
+ subName: Producer
+ value5: value5
+ value6: value6
+ value7: value7
+ value8: value8
+ available: Available
+ minQuantity: minQuantity
+ price2: Price
+ located: Located
+ counter: Counter
+ groupingPrice: Grouping Price
+ itemOldPrice: itemOld Price
+ status: State
+ quantityToReplace: Quanity to replace
diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml
index dd5074f5f..5ab0b1bb6 100644
--- a/src/pages/Item/locale/es.yml
+++ b/src/pages/Item/locale/es.yml
@@ -135,6 +135,7 @@ item:
size: Medida
origin: Orig.
weight: Peso
+ color: Color
weightByPiece: Peso/tallo
userName: Comprador
stemMultiplier: Multiplicador
@@ -220,5 +221,30 @@ item:
achieved: 'Conseguido'
concept: 'Concepto'
state: 'Estado'
- search: 'Buscar artículo'
- searchInfo: 'Puedes buscar por id'
+itemProposal: Artículos similares
+proposal:
+ substitutionAvailable: Sustitución disponible
+ notSubstitutionAvailableByPrice: Sustitución no disponible, 30% de diferencia por precio o cantidad
+ compatibility: Compatibilidad
+ title: Items de sustitución para los tickets seleccionados
+ itemFk: Item
+ longName: Nombre
+ subName: Productor
+ value5: value5
+ value6: value6
+ value7: value7
+ value8: value8
+ available: Disponible
+ minQuantity: Min. cantidad
+ price2: Precio
+ located: Ubicado
+ counter: Contador
+ difference: Diferencial
+ groupingPrice: Precio Grouping
+ itemOldPrice: Precio itemOld
+ status: Estado
+ quantityToReplace: Cantidad a reemplazar
+ replace: Sustituir
+ replaceAndConfirm: Sustituir y confirmar precio
+search: 'Buscar artículo'
+searchInfo: 'Puedes buscar por id'
diff --git a/src/pages/Order/Card/OrderLines.vue b/src/pages/Order/Card/OrderLines.vue
index 6153b2d3e..1b864de6f 100644
--- a/src/pages/Order/Card/OrderLines.vue
+++ b/src/pages/Order/Card/OrderLines.vue
@@ -238,7 +238,7 @@ watch(
lineFilter.value.where.orderFk = router.currentRoute.value.params.id;
tableLinesRef.value.reload();
- }
+ },
);
diff --git a/src/pages/Supplier/Card/SupplierFiscalData.vue b/src/pages/Supplier/Card/SupplierFiscalData.vue
index e569eb236..ecee5b76b 100644
--- a/src/pages/Supplier/Card/SupplierFiscalData.vue
+++ b/src/pages/Supplier/Card/SupplierFiscalData.vue
@@ -10,6 +10,7 @@ import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnLocation from 'src/components/common/VnLocation.vue';
import VnAccountNumber from 'src/components/common/VnAccountNumber.vue';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
const route = useRoute();
const { t } = useI18n();
@@ -182,18 +183,11 @@ function handleLocation(data, location) {
v-model="data.isTrucker"
:label="t('supplier.fiscalData.isTrucker')"
/>
-
-
-
-
- {{
- t(
- 'When activating it, do not enter the country code in the ID field.'
- )
- }}
-
-
-
+
@@ -201,6 +195,8 @@ function handleLocation(data, location) {
+en:
+ whenActivatingIt: When activating it, do not enter the country code in the ID field.
es:
- When activating it, do not enter the country code in the ID field.: Al activarlo, no informar el código del país en el campo nif
+ whenActivatingIt: Al activarlo, no informar el código del país en el campo nif.
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
index 44f2bf7fb..055c9a0ff 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
@@ -9,6 +9,7 @@ import FetchData from 'components/FetchData.vue';
import { useStateStore } from 'stores/useStateStore';
import { toCurrency } from 'filters/index';
import { useRole } from 'src/composables/useRole';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
const haveNegatives = defineModel('have-negatives', { type: Boolean, required: true });
const formData = defineModel({ type: Object, required: true });
@@ -182,22 +183,19 @@ onMounted(async () => {
-
-
-
- {{ t('basicData.withoutNegativesInfo') }}
-
-
diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index 97d87ccf8..004bcbe79 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -14,7 +14,7 @@ import VnImg from 'src/components/ui/VnImg.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import TicketSaleMoreActions from './TicketSaleMoreActions.vue';
-import TicketTransfer from './TicketTransfer.vue';
+import TicketTransferProxy from './TicketTransferProxy.vue';
import { toCurrency, toPercentage } from 'src/filters';
import { useArrayData } from 'composables/useArrayData';
@@ -609,8 +609,9 @@ watch(
@click="setTransferParams()"
data-cy="ticketSaleTransferBtn"
>
-
{{ t('Transfer lines') }}
-
{{ t('ticketSale.transferLines') }}
+
+import { ref } from 'vue';
+
+import VnInputDate from 'src/components/common/VnInputDate.vue';
+import split from './components/split';
+const emit = defineEmits(['ticketTransfered']);
+
+const $props = defineProps({
+ ticket: {
+ type: [Array, Object],
+ default: () => {},
+ },
+});
+
+const splitDate = ref(Date.vnNew());
+
+const splitSelectedRows = async () => {
+ const tickets = Array.isArray($props.ticket) ? $props.ticket : [$props.ticket];
+ await split(tickets, splitDate.value);
+ emit('ticketTransfered', tickets);
+};
+
+
+
+
+
+
+
+
+es:
+ Sales to transfer: Líneas a transferir
+ Destination ticket: Ticket destinatario
+
diff --git a/src/pages/Ticket/Card/TicketTransfer.vue b/src/pages/Ticket/Card/TicketTransfer.vue
index 005d74a0e..ffa964c92 100644
--- a/src/pages/Ticket/Card/TicketTransfer.vue
+++ b/src/pages/Ticket/Card/TicketTransfer.vue
@@ -1,11 +1,11 @@
-
-
-
-
-
-
-
-
-
-
- handleRowClick(row)"
- >
-
-
-
- {{ row.nickname }}
- {{ row.name }}
- {{ row.street }}
- {{ row.postalCode }}
- {{ row.city }}
-
-
- {{ row.nickname }}
- {{ row.name }}
- {{ row.street }}
- {{ row.postalCode }}
- {{ row.city }}
-
-
-
+
+
+
+
+
+
+
+
+ handleRowClick(row)"
+ :no-data-label="t('globals.noResults')"
+ :pagination="{ rowsPerPage: 0 }"
+ >
+
+
+
+ {{ row.nickname }}
+ {{ row.name }}
+ {{ row.street }}
+ {{ row.postalCode }}
+ {{ row.city }}
+
+
+ {{ row.nickname }}
+ {{ row.name }}
+ {{ row.street }}
+ {{ row.postalCode }}
+ {{ row.city }}
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
es:
Sales to transfer: Líneas a transferir
Destination ticket: Ticket destinatario
- Transfer to ticket: Transferir a ticket
- New ticket: Nuevo ticket
diff --git a/src/pages/Ticket/Card/TicketTransferProxy.vue b/src/pages/Ticket/Card/TicketTransferProxy.vue
new file mode 100644
index 000000000..3f3f018df
--- /dev/null
+++ b/src/pages/Ticket/Card/TicketTransferProxy.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/Ticket/Card/components/split.js b/src/pages/Ticket/Card/components/split.js
new file mode 100644
index 000000000..afa1d5cd6
--- /dev/null
+++ b/src/pages/Ticket/Card/components/split.js
@@ -0,0 +1,22 @@
+import axios from 'axios';
+import notifyResults from 'src/utils/notifyResults';
+
+export default async function (data, date) {
+ const reducedData = data.reduce((acc, item) => {
+ const existing = acc.find(({ ticketFk }) => ticketFk === item.id);
+ if (existing) {
+ existing.sales.push(item.saleFk);
+ } else {
+ acc.push({ ticketFk: item.id, sales: [item.saleFk], date });
+ }
+ return acc;
+ }, []);
+
+ const promises = reducedData.map((params) => axios.post(`Tickets/split`, params));
+
+ const results = await Promise.allSettled(promises);
+
+ notifyResults(results, 'ticketFk');
+
+ return results;
+}
diff --git a/src/pages/Ticket/Negative/TicketLackDetail.vue b/src/pages/Ticket/Negative/TicketLackDetail.vue
new file mode 100644
index 000000000..dcf835d03
--- /dev/null
+++ b/src/pages/Ticket/Negative/TicketLackDetail.vue
@@ -0,0 +1,198 @@
+
+
+
+ (editableStates = data)"
+ auto-load
+ />
+ (item = data)"
+ auto-load
+ />
+
+
+ (selectedRows = value)"
+ >
+
+
+
+
+
+
+
+ {{ t('ticketSale.transferLines') }}
+
+
+
+
+
+
+ {{ t('itemProposal') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/Ticket/Negative/TicketLackFilter.vue b/src/pages/Ticket/Negative/TicketLackFilter.vue
new file mode 100644
index 000000000..3762f453d
--- /dev/null
+++ b/src/pages/Ticket/Negative/TicketLackFilter.vue
@@ -0,0 +1,175 @@
+
+
+
+ (warehouses = data)" auto-load />
+ (categoriesOptions = data)"
+ auto-load
+ />
+
+ (itemTypesOptions = data)"
+ auto-load
+ />
+
+
+
+
+ {{ t(`negative.${tag.label}`) }}
+ {{ formatFn(tag.value) }}
+
+
+
+
+
+
+ {
+ setUserParams(params);
+ }
+ "
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ onCategoryChange($event, searchFn)
+ "
+ :options="categoriesOptions"
+ option-value="id"
+ option-label="name"
+ hide-selected
+ dense
+ outlined
+ rounded
+ />
+
+
+
+
+
+
+
+
+
+ {{ scope.opt?.name }}
+ {{
+ scope.opt?.category?.name
+ }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/Ticket/Negative/TicketLackList.vue b/src/pages/Ticket/Negative/TicketLackList.vue
new file mode 100644
index 000000000..851cf40f4
--- /dev/null
+++ b/src/pages/Ticket/Negative/TicketLackList.vue
@@ -0,0 +1,227 @@
+
+
+
+
+
+
+
+
+ {{ filterRef }}
+
+
+
+ {{ row.itemFk }}
+
+
+
+
+ {{ row.longName }}
+
+
+
+
+
+
+
diff --git a/src/pages/Ticket/Negative/TicketLackTable.vue b/src/pages/Ticket/Negative/TicketLackTable.vue
new file mode 100644
index 000000000..c7f224c64
--- /dev/null
+++ b/src/pages/Ticket/Negative/TicketLackTable.vue
@@ -0,0 +1,362 @@
+
+
+
+ (itemLack = data[0])"
+ auto-load
+ />
+ (item = data)"
+ auto-load
+ />
+
+
+
+
+
+
+
+
+
+
+ {{ item?.longName ?? item.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('negative.detail.isBasket') }}
+
+
+ {{ t('negative.detail.hasToIgnore') }}
+
+
+ {{
+ t('negative.detail.hasObservation')
+ }}
+ {{ t('negative.detail.isRookie') }}
+
+
+ {{ t('negative.detail.peticionCompra') }}
+
+
+ {{ t('negative.detail.turno') }}
+
+
+
+
+
+ {{ row.nickname }}
+
+
+
+
+
+ {{ row.id }}
+
+
+
+
+
+
+
+
+ {{ row.zoneName }}
+
+
+
+
+
+
+
+
diff --git a/src/pages/Ticket/Negative/components/ChangeItemDialog.vue b/src/pages/Ticket/Negative/components/ChangeItemDialog.vue
new file mode 100644
index 000000000..e419b85c0
--- /dev/null
+++ b/src/pages/Ticket/Negative/components/ChangeItemDialog.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+ {{ showChangeItemDialog }}
+ {{ $t('negative.detail.modal.changeItem.title') }}
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue b/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue
new file mode 100644
index 000000000..96cbd213d
--- /dev/null
+++ b/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue
@@ -0,0 +1,84 @@
+
+
+
+
+
+ {{ $t('negative.detail.modal.changeQuantity.title') }}
+
+
+
+
+
+
+
+
diff --git a/src/pages/Ticket/Negative/components/ChangeStateDialog.vue b/src/pages/Ticket/Negative/components/ChangeStateDialog.vue
new file mode 100644
index 000000000..1acc7e0ef
--- /dev/null
+++ b/src/pages/Ticket/Negative/components/ChangeStateDialog.vue
@@ -0,0 +1,91 @@
+
+
+
+ (editableStates = data)"
+ auto-load
+ />
+
+
+ {{ $t('negative.detail.modal.changeState.title') }}
+
+
+
+
+
+
+
+
diff --git a/src/pages/Ticket/locale/en.yml b/src/pages/Ticket/locale/en.yml
index d4bfd1103..cdbb22d9b 100644
--- a/src/pages/Ticket/locale/en.yml
+++ b/src/pages/Ticket/locale/en.yml
@@ -23,6 +23,8 @@ ticketSale:
hasComponentLack: Component lack
ok: Ok
more: More
+ transferLines: Transfer lines(no basket)/ Split
+ transferBasket: Some row selected is basket
advanceTickets:
preparation: Preparation
origin: Origin
@@ -188,7 +190,6 @@ ticketList:
accountPayment: Account payment
sendDocuware: Set delivered and send delivery note(s) to the tablet
addPayment: Add payment
- date: Date
company: Company
amount: Amount
reference: Reference
@@ -202,8 +203,6 @@ ticketList:
creditCard: Credit card
transfers: Transfers
province: Province
- warehouse: Warehouse
- hour: Hour
closure: Closure
toLines: Go to lines
addressNickname: Address nickname
@@ -214,3 +213,79 @@ ticketList:
notVisible: Not visible
clientFrozen: Client frozen
componentLack: Component lack
+negative:
+ hour: Hour
+ id: Id Article
+ longName: Article
+ supplier: Supplier
+ colour: Colour
+ size: Size
+ origen: Origin
+ value: Negative
+ itemFk: Article
+ producer: Producer
+ warehouse: Warehouse
+ warehouseFk: Warehouse
+ category: Category
+ categoryFk: Family
+ type: Type
+ typeFk: Type
+ lack: Negative
+ inkFk: inkFk
+ timed: timed
+ date: Date
+ minTimed: minTimed
+ negativeAction: Negative
+ totalNegative: Total negatives
+ days: Days
+ buttonsUpdate:
+ item: Item
+ state: State
+ quantity: Quantity
+ modalOrigin:
+ title: Update negatives
+ question: Select a state to update
+ modalSplit:
+ title: Confirm split selected
+ question: Select a state to update
+ detail:
+ saleFk: Sale
+ itemFk: Article
+ ticketFk: Ticket
+ code: Code
+ nickname: Alias
+ name: Name
+ zoneName: Agency name
+ shipped: Date
+ theoreticalhour: Theoretical hour
+ agName: Agency
+ quantity: Quantity
+ alertLevelCode: Group state
+ state: State
+ peticionCompra: Ticket request
+ isRookie: Is rookie
+ turno: Turn line
+ isBasket: Basket
+ hasObservation: Has substitution
+ hasToIgnore: VIP
+ modal:
+ changeItem:
+ title: Update item reference
+ placeholder: New item
+ changeState:
+ title: Update tickets state
+ placeholder: New state
+ changeQuantity:
+ title: Update tickets quantity
+ placeholder: New quantity
+ split:
+ title: Are you sure you want to split selected tickets?
+ subTitle: Confirm split action
+ handleSplited:
+ title: Handle splited tickets
+ subTitle: Confirm date and agency
+ split:
+ ticket: Old ticket
+ newTicket: New ticket
+ status: Result
+ message: Message
diff --git a/src/pages/Ticket/locale/es.yml b/src/pages/Ticket/locale/es.yml
index ff68461fa..75d3c6a2b 100644
--- a/src/pages/Ticket/locale/es.yml
+++ b/src/pages/Ticket/locale/es.yml
@@ -127,6 +127,8 @@ ticketSale:
ok: Ok
more: Más
address: Consignatario
+ transferLines: Transferir líneas(no cesta)/ Separar
+ transferBasket: No disponible para una cesta
size: Medida
ticketComponents:
serie: Serie
@@ -213,6 +215,81 @@ ticketList:
toLines: Ir a lineas
addressNickname: Alias consignatario
ref: Referencia
+negative:
+ hour: Hora
+ id: Id Articulo
+ longName: Articulo
+ supplier: Productor
+ colour: Color
+ size: Medida
+ origen: Origen
+ value: Negativo
+ warehouseFk: Almacen
+ producer: Producer
+ category: Categoría
+ categoryFk: Familia
+ typeFk: Familia
+ warehouse: Almacen
+ lack: Negativo
+ inkFk: Color
+ timed: Hora
+ date: Fecha
+ minTimed: Hora
+ type: Tipo
+ negativeAction: Negativo
+ totalNegative: Total negativos
+ days: Rango de dias
+ buttonsUpdate:
+ item: artículo
+ state: Estado
+ quantity: Cantidad
+ modalOrigin:
+ title: Actualizar negativos
+ question: Seleccione un estado para guardar
+ modalSplit:
+ title: Confirmar acción de split
+ question: Selecciona un estado
+ detail:
+ saleFk: Línea
+ itemFk: Artículo
+ ticketFk: Ticket
+ code: code
+ nickname: Alias
+ name: Nombre
+ zoneName: Agencia
+ shipped: F. envío
+ theoreticalhour: Hora teórica
+ agName: Agencia
+ quantity: Cantidad
+ alertLevelCode: Estado agrupado
+ state: Estado
+ peticionCompra: Petición compra
+ isRookie: Cliente nuevo
+ turno: Linea turno
+ isBasket: Cesta
+ hasObservation: Tiene sustitución
+ hasToIgnore: VIP
+ modal:
+ changeItem:
+ title: Actualizar referencia artículo
+ placeholder: Nuevo articulo
+ changeState:
+ title: Actualizar estado
+ placeholder: Nuevo estado
+ changeQuantity:
+ title: Actualizar cantidad
+ placeholder: Nueva cantidad
+ split:
+ title: ¿Seguro de separar los tickets seleccionados?
+ subTitle: Confirma separar tickets seleccionados
+ handleSplited:
+ title: Gestionar tickets spliteados
+ subTitle: Confir fecha y agencia
+ split:
+ ticket: Ticket viejo
+ newTicket: Ticket nuevo
+ status: Estado
+ message: Mensaje
rounding: Redondeo
noVerifiedData: Sin datos comprobados
purchaseRequest: Petición de compra
diff --git a/src/router/modules/ticket.js b/src/router/modules/ticket.js
index e5b423f64..bfcb78787 100644
--- a/src/router/modules/ticket.js
+++ b/src/router/modules/ticket.js
@@ -192,7 +192,13 @@ export default {
icon: 'vn:ticket',
moduleName: 'Ticket',
keyBinding: 't',
- menu: ['TicketList', 'TicketAdvance', 'TicketWeekly', 'TicketFuture'],
+ menu: [
+ 'TicketList',
+ 'TicketAdvance',
+ 'TicketWeekly',
+ 'TicketFuture',
+ 'TicketNegative',
+ ],
},
component: RouterView,
redirect: { name: 'TicketMain' },
@@ -229,6 +235,32 @@ export default {
},
component: () => import('src/pages/Ticket/TicketCreate.vue'),
},
+ {
+ path: 'negative',
+ redirect: { name: 'TicketNegative' },
+ children: [
+ {
+ name: 'TicketNegative',
+ meta: {
+ title: 'negative',
+ icon: 'exposure',
+ },
+ component: () =>
+ import('src/pages/Ticket/Negative/TicketLackList.vue'),
+ path: '',
+ },
+ {
+ name: 'NegativeDetail',
+ path: ':id',
+ meta: {
+ title: 'summary',
+ icon: 'launch',
+ },
+ component: () =>
+ import('src/pages/Ticket/Negative/TicketLackDetail.vue'),
+ },
+ ],
+ },
{
path: 'weekly',
name: 'TicketWeekly',
diff --git a/src/utils/notifyResults.js b/src/utils/notifyResults.js
new file mode 100644
index 000000000..e87ad6c6f
--- /dev/null
+++ b/src/utils/notifyResults.js
@@ -0,0 +1,19 @@
+import { Notify } from 'quasar';
+
+export default function (results, key) {
+ results.forEach((result, index) => {
+ if (result.status === 'fulfilled') {
+ const data = JSON.parse(result.value.config.data);
+ Notify.create({
+ type: 'positive',
+ message: `Operación (${index + 1}) ${data[key]} completada con éxito.`,
+ });
+ } else {
+ const data = JSON.parse(result.reason.config.data);
+ Notify.create({
+ type: 'negative',
+ message: `Operación (${index + 1}) ${data[key]} fallida: ${result.reason.message}`,
+ });
+ }
+ });
+}
diff --git a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
index 2016fca6d..c6bcc37c1 100644
--- a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
@@ -1,9 +1,9 @@
///
describe('InvoiceInBasicData', () => {
- const formInputs = '.q-form > .q-card input';
const firstFormSelect = '.q-card > .vn-row:nth-child(1) > .q-select';
- const documentBtns = '[data-cy="dms-buttons"] button';
const dialogInputs = '.q-dialog input';
+ const resetBtn = '.q-btn-group--push > .q-btn--flat';
+ const getDocumentBtns = (opt) => `[data-cy="dms-buttons"] > :nth-child(${opt})`;
beforeEach(() => {
cy.login('developer');
@@ -11,13 +11,16 @@ describe('InvoiceInBasicData', () => {
});
it('should edit the provideer and supplier ref', () => {
- cy.selectOption(firstFormSelect, 'Bros');
- cy.get('[title="Reset"]').click();
- cy.get(formInputs).eq(1).type('{selectall}4739');
- cy.saveCard();
+ cy.dataCy('UnDeductibleVatSelect').type('4751000000');
+ cy.get('.q-menu .q-item').contains('4751000000').click();
+ cy.get(resetBtn).click();
- cy.get(`${firstFormSelect} input`).invoke('val').should('eq', 'Plants nick');
- cy.get(formInputs).eq(1).invoke('val').should('eq', '4739');
+ cy.waitForElement('#formModel').within(() => {
+ cy.dataCy('vnSupplierSelect').type('Bros nick');
+ })
+ cy.get('.q-menu .q-item').contains('Bros nick').click();
+ cy.saveCard();
+ cy.get(`${firstFormSelect} input`).invoke('val').should('eq', 'Bros nick');
});
it('should edit, remove and create the dms data', () => {
@@ -25,18 +28,18 @@ describe('InvoiceInBasicData', () => {
const secondInput = "I don't know what posting here!";
//edit
- cy.get(documentBtns).eq(1).click();
+ cy.get(getDocumentBtns(2)).click();
cy.get(dialogInputs).eq(0).type(`{selectall}${firtsInput}`);
cy.get('textarea').type(`{selectall}${secondInput}`);
cy.get('[data-cy="FormModelPopup_save"]').click();
- cy.get(documentBtns).eq(1).click();
+ cy.get(getDocumentBtns(2)).click();
cy.get(dialogInputs).eq(0).invoke('val').should('eq', firtsInput);
cy.get('textarea').invoke('val').should('eq', secondInput);
cy.get('[data-cy="FormModelPopup_save"]').click();
cy.checkNotification('Data saved');
//remove
- cy.get(documentBtns).eq(2).click();
+ cy.get(getDocumentBtns(3)).click();
cy.get('[data-cy="VnConfirm_confirm"]').click();
cy.checkNotification('Data saved');
diff --git a/test/cypress/integration/item/ItemProposal.spec.js b/test/cypress/integration/item/ItemProposal.spec.js
new file mode 100644
index 000000000..b3ba9f676
--- /dev/null
+++ b/test/cypress/integration/item/ItemProposal.spec.js
@@ -0,0 +1,11 @@
+///
+describe('ItemProposal', () => {
+ beforeEach(() => {
+ const ticketId = 1;
+
+ cy.login('developer');
+ cy.visit(`/#/ticket/${ticketId}/summary`);
+ });
+
+ describe('Handle item proposal selected', () => {});
+});
diff --git a/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js b/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js
new file mode 100644
index 000000000..9ea1cff63
--- /dev/null
+++ b/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js
@@ -0,0 +1,147 @@
+///
+describe('Ticket Lack detail', () => {
+ beforeEach(() => {
+ cy.login('developer');
+ cy.intercept('GET', /\/api\/Tickets\/itemLack\/5.*$/, {
+ statusCode: 200,
+ body: [
+ {
+ saleFk: 33,
+ code: 'OK',
+ ticketFk: 142,
+ nickname: 'Malibu Point',
+ shipped: '2000-12-31T23:00:00.000Z',
+ hour: 0,
+ quantity: 50,
+ agName: 'Super-Man delivery',
+ alertLevel: 0,
+ stateName: 'OK',
+ stateId: 3,
+ itemFk: 5,
+ price: 1.79,
+ alertLevelCode: 'FREE',
+ zoneFk: 9,
+ zoneName: 'Zone superMan',
+ theoreticalhour: '2011-11-01T22:59:00.000Z',
+ isRookie: 1,
+ turno: 1,
+ peticionCompra: 1,
+ hasObservation: 1,
+ hasToIgnore: 1,
+ isBasket: 1,
+ minTimed: 0,
+ customerId: 1104,
+ customerName: 'Tony Stark',
+ observationTypeCode: 'administrative',
+ },
+ ],
+ }).as('getItemLack');
+
+ cy.visit('/#/ticket/negative/5');
+ cy.wait('@getItemLack');
+ });
+ describe('Table actions', () => {
+ it.skip('should display only one row in the lack list', () => {
+ cy.location('href').should('contain', '#/ticket/negative/5');
+
+ cy.get('[data-cy="changeItem"]').should('be.disabled');
+ cy.get('[data-cy="changeState"]').should('be.disabled');
+ cy.get('[data-cy="changeQuantity"]').should('be.disabled');
+ cy.get('[data-cy="itemProposal"]').should('be.disabled');
+ cy.get('[data-cy="transferLines"]').should('be.disabled');
+ cy.get('tr.cursor-pointer > :nth-child(1)').click();
+ cy.get('[data-cy="changeItem"]').should('be.enabled');
+ cy.get('[data-cy="changeState"]').should('be.enabled');
+ cy.get('[data-cy="changeQuantity"]').should('be.enabled');
+ cy.get('[data-cy="itemProposal"]').should('be.enabled');
+ cy.get('[data-cy="transferLines"]').should('be.enabled');
+ });
+ });
+ describe('Item proposal', () => {
+ beforeEach(() => {
+ cy.get('tr.cursor-pointer > :nth-child(1)').click();
+
+ cy.intercept('GET', /\/api\/Items\/getSimilar\?.*$/, {
+ statusCode: 200,
+ body: [
+ {
+ id: 1,
+ longName: 'Ranged weapon longbow 50cm',
+ subName: 'Stark Industries',
+ tag5: 'Color',
+ value5: 'Brown',
+ match5: 0,
+ match6: 0,
+ match7: 0,
+ match8: 1,
+ tag6: 'Categoria',
+ value6: '+1 precission',
+ tag7: 'Tallos',
+ value7: '1',
+ tag8: null,
+ value8: null,
+ available: 20,
+ calc_id: 6,
+ counter: 0,
+ minQuantity: 1,
+ visible: null,
+ price2: 1,
+ },
+ {
+ id: 2,
+ longName: 'Ranged weapon longbow 100cm',
+ subName: 'Stark Industries',
+ tag5: 'Color',
+ value5: 'Brown',
+ match5: 0,
+ match6: 1,
+ match7: 0,
+ match8: 1,
+ tag6: 'Categoria',
+ value6: '+1 precission',
+ tag7: 'Tallos',
+ value7: '1',
+ tag8: null,
+ value8: null,
+ available: 50,
+ calc_id: 6,
+ counter: 1,
+ minQuantity: 5,
+ visible: null,
+ price2: 10,
+ },
+ {
+ id: 3,
+ longName: 'Ranged weapon longbow 200cm',
+ subName: 'Stark Industries',
+ tag5: 'Color',
+ value5: 'Brown',
+ match5: 1,
+ match6: 1,
+ match7: 1,
+ match8: 1,
+ tag6: 'Categoria',
+ value6: '+1 precission',
+ tag7: 'Tallos',
+ value7: '1',
+ tag8: null,
+ value8: null,
+ available: 185,
+ calc_id: 6,
+ counter: 10,
+ minQuantity: 10,
+ visible: null,
+ price2: 100,
+ },
+ ],
+ }).as('getItemGetSimilar');
+ cy.get('[data-cy="itemProposal"]').click();
+ cy.wait('@getItemGetSimilar');
+ });
+ describe('Replace item if', () => {
+ it.only('Quantity is less than available', () => {
+ cy.get(':nth-child(1) > .text-right > .q-btn').click();
+ });
+ });
+ });
+});
diff --git a/test/cypress/integration/ticket/negative/TicketLackList.spec.js b/test/cypress/integration/ticket/negative/TicketLackList.spec.js
new file mode 100644
index 000000000..01ab4f621
--- /dev/null
+++ b/test/cypress/integration/ticket/negative/TicketLackList.spec.js
@@ -0,0 +1,36 @@
+///
+describe('Ticket Lack list', () => {
+ beforeEach(() => {
+ cy.login('developer');
+ cy.intercept('GET', /Tickets\/itemLack\?.*$/, {
+ statusCode: 200,
+ body: [
+ {
+ itemFk: 5,
+ longName: 'Ranged weapon pistol 9mm',
+ warehouseFk: 1,
+ producer: null,
+ size: 15,
+ category: null,
+ warehouse: 'Warehouse One',
+ lack: -50,
+ inkFk: 'SLV',
+ timed: '2025-01-25T22:59:00.000Z',
+ minTimed: '23:59',
+ originFk: 'Holand',
+ },
+ ],
+ }).as('getLack');
+
+ cy.visit('/#/ticket/negative');
+ });
+
+ describe('Table actions', () => {
+ it('should display only one row in the lack list', () => {
+ cy.wait('@getLack', { timeout: 10000 });
+
+ cy.get('.q-virtual-scroll__content > :nth-child(1) > .sticky').click();
+ cy.location('href').should('contain', '#/ticket/negative/5');
+ });
+ });
+});