Compare commits
196 Commits
7984-addCu
...
dev
Author | SHA1 | Date |
---|---|---|
Jon Elias | 909e6674d6 | |
Jon Elias | 0fe63abba6 | |
PAU ROVIRA ROSALENY | 5ae5cec9f9 | |
PAU ROVIRA ROSALENY | a09f430c60 | |
Jon Elias | 0fcd969c97 | |
Jon Elias | e710d45011 | |
Carlos Satorres | ccff995680 | |
Carlos Satorres | d94cd801cc | |
PAU ROVIRA ROSALENY | 4eebfd8769 | |
PAU ROVIRA ROSALENY | 39d6e818f5 | |
PAU ROVIRA ROSALENY | f69ed548f0 | |
Jon Elias | f6439ed356 | |
Jon Elias | fea59a729e | |
Jon Elias | c2a6dd7979 | |
PAU ROVIRA ROSALENY | 5b2987c95e | |
PAU ROVIRA ROSALENY | bd2db2ef58 | |
Jon Elias | 4246275759 | |
Jon Elias | f70dd41a37 | |
PAU ROVIRA ROSALENY | 023593eb45 | |
Jon Elias | 67872aca10 | |
Jon Elias | 59ca61c96f | |
PAU ROVIRA ROSALENY | e5a449c80c | |
PAU ROVIRA ROSALENY | 0de8af81d3 | |
PAU ROVIRA ROSALENY | 6cd0df04e6 | |
PAU ROVIRA ROSALENY | e13f46613f | |
Jorge Penadés | f3042b0326 | |
Jorge Penadés | b383efd99a | |
Jon Elias | 22ae08863b | |
PAU ROVIRA ROSALENY | 374118133a | |
Jon Elias | 788c6e8b61 | |
Jon Elias | 7547461282 | |
Jon Elias | ed211ba14b | |
PAU ROVIRA ROSALENY | 860f92cb42 | |
PAU ROVIRA ROSALENY | b2414f861b | |
PAU ROVIRA ROSALENY | 42e46a88fb | |
Jorge Penadés | c0e3a14e8b | |
Jorge Penadés | 7759a49f3a | |
PAU ROVIRA ROSALENY | 0d7d60a1e8 | |
PAU ROVIRA ROSALENY | 3e8b35e2e1 | |
PAU ROVIRA ROSALENY | 47603d1315 | |
PAU ROVIRA ROSALENY | 983b91fbdd | |
PAU ROVIRA ROSALENY | f6fc19f210 | |
PAU ROVIRA ROSALENY | ed0f33dbc5 | |
Carlos Satorres | 962ae4ca96 | |
Jon Elias | caffb672bc | |
Jon Elias | 6522df24b4 | |
Javier Segarra | b90f6b037c | |
Jon Elias | 71b5b8d47a | |
Javier Segarra | 68d1e1662e | |
Javier Segarra | dd3059b609 | |
Javier Segarra | ae0f08b2c6 | |
Javier Segarra | ebf2345fea | |
Javier Segarra | 96b05de066 | |
Javier Segarra | b7a841d998 | |
Javier Segarra | 8c680b375a | |
Javier Segarra | dc65f7ad20 | |
Javier Segarra | b87191c4d9 | |
Jon Elias | 8ada6bd3e3 | |
Jon Elias | 613ebc0eb4 | |
Javier Segarra | 2fb7db051c | |
Javier Segarra | 2be0f515c8 | |
PAU ROVIRA ROSALENY | 9c790f734c | |
PAU ROVIRA ROSALENY | 2dbda38ae7 | |
PAU ROVIRA ROSALENY | 95f96d7ebd | |
PAU ROVIRA ROSALENY | a013152a09 | |
Javier Segarra | d749f52771 | |
Javier Segarra | 01c4553e5f | |
PAU ROVIRA ROSALENY | 1a3446dd07 | |
Jon Elias | a8b28de2a4 | |
Jon Elias | db99a22254 | |
PAU ROVIRA ROSALENY | 7748df1384 | |
Jorge Penadés | 30f61f970b | |
Carlos Satorres | 4034320ff7 | |
Carlos Satorres | c64aad02e1 | |
Jorge Penadés | 02494d4bed | |
Jorge Penadés | 01e9ae2dce | |
Javier Segarra | 3a8c35521e | |
Jon Elias | 3aa8acf02a | |
Jon Elias | 0db556a97b | |
Jon Elias | 8642089bc7 | |
Javier Segarra | 0aa9975535 | |
Javier Segarra | 24c62b4533 | |
Javier Segarra | 94d471e20f | |
Javier Segarra | 0c714d2c04 | |
Jorge Penadés | cbcb2f2c71 | |
Jorge Penadés | 04a6a49565 | |
Jorge Penadés | 8d8944afb3 | |
Jon Elias | 13b0becb6e | |
Jon Elias | ac998d33aa | |
Javier Segarra | 31a5dd653c | |
PAU ROVIRA ROSALENY | 6cba927ebc | |
Carlos Satorres | 1ee8b68fce | |
Carlos Satorres | b7e71044b0 | |
Carlos Satorres | c8fe115fec | |
Carlos Satorres | 7144bb3871 | |
Javier Segarra | 390c530d39 | |
Javier Segarra | 023d232ab5 | |
Javier Segarra | 44c7b87726 | |
Javier Segarra | ae19e8b3c6 | |
Javier Segarra | b74ee04557 | |
Javier Segarra | 100e3b4d72 | |
Javier Segarra | ea9e099523 | |
Carlos Satorres | 46cdd9e62b | |
Carlos Satorres | 3fc7f34899 | |
Carlos Satorres | 38a180f92b | |
Carlos Satorres | 72f141315e | |
Carlos Satorres | 55dda496f3 | |
Javier Segarra | b2b36289c7 | |
Javier Segarra | 06eb72764d | |
Javier Segarra | 3e4934fae1 | |
Javier Segarra | 2f3c5245c0 | |
Javier Segarra | 5af5c518b5 | |
Javier Segarra | 21cc6b3ecd | |
Javier Segarra | 252dd21492 | |
Javier Segarra | a8e1bdc684 | |
Javier Segarra | edceac850d | |
Javier Segarra | fce1068fbb | |
Javier Segarra | 1f1fc4d6b9 | |
Javier Segarra | 9fcea12580 | |
Carlos Satorres | 57aa38c84c | |
Carlos Satorres | f8428a5591 | |
Carlos Satorres | 5a869f0722 | |
Javier Segarra | 6c96089445 | |
Carlos Satorres | f904c8cfd2 | |
Carlos Satorres | 8aba370063 | |
Carlos Satorres | b479ce83e0 | |
Carlos Satorres | 3e16357878 | |
Carlos Satorres | 66db2f0bd7 | |
Carlos Satorres | f139be4fcd | |
Carlos Satorres | 3dbace5336 | |
Carlos Satorres | 63fb45b22d | |
Carlos Satorres | 916842ba93 | |
Carlos Satorres | 9ab6ac9718 | |
Javier Segarra | cf6cf11179 | |
Javier Segarra | 7b170f05bf | |
Javier Segarra | 0b767ff812 | |
Javier Segarra | a86b9067e2 | |
Javier Segarra | 3aa8b568c4 | |
Javier Segarra | 7630e6dfe4 | |
Javier Segarra | 800eac4e24 | |
Javier Segarra | 1a2046be74 | |
Carlos Satorres | 950bd5f3a7 | |
Carlos Satorres | 7619a5b4f5 | |
Carlos Satorres | 96e942af11 | |
Carlos Satorres | 3a060c9c6a | |
Javier Segarra | 9121e79533 | |
Javier Segarra | 34d08e4bfe | |
Javier Segarra | db00be75ad | |
Javier Segarra | 4fc3e1fabb | |
Javier Segarra | a5f41871ae | |
Javier Segarra | 494482b6a8 | |
Javier Segarra | c0d8bf3a48 | |
Javier Segarra | 994a22a195 | |
Javier Segarra | e948253bea | |
Javier Segarra | 09804e06c7 | |
Javier Segarra | 78e70f2b69 | |
Javier Segarra | 7325be2366 | |
Javier Segarra | 3404bc6d0b | |
Javier Segarra | 218f45c289 | |
Javier Segarra | 7b8093c048 | |
Javier Segarra | da99d82504 | |
Javier Segarra | 8d2ad235fb | |
Javier Segarra | 4d602aadfd | |
Carlos Satorres | f903432e74 | |
Carlos Satorres | 04d30186c2 | |
Carlos Satorres | f7fb18cf0a | |
Carlos Satorres | 02129591cf | |
Carlos Satorres | bf4d11545d | |
Carlos Satorres | 70847176ca | |
Carlos Satorres | 97ce44242c | |
Carlos Satorres | c75e4cbf95 | |
Carlos Satorres | 60e9accd99 | |
Carlos Satorres | 00cd6feb12 | |
Carlos Satorres | 8f925401d5 | |
Carlos Satorres | 8363f813de | |
Carlos Satorres | 68d1d0dbb0 | |
Carlos Satorres | 0e7abe5fa4 | |
Carlos Satorres | 9c5620f340 | |
Carlos Satorres | 41e1d365f3 | |
Carlos Satorres | b6836fc59e | |
Alex Moreno | 81591b4f67 | |
Alex Moreno | 83a0ec7eb8 | |
Alex Moreno | 8d60754682 | |
Alex Moreno | ba57c2fcd9 | |
Carlos Satorres | 8490f24438 | |
Carlos Satorres | db3ff0416c | |
Carlos Satorres | d7044cfdcc | |
Carlos Satorres | f4792d7921 | |
Carlos Satorres | 960129f86c | |
Carlos Satorres | 6e261b7793 | |
Carlos Satorres | 4b44b9a979 | |
Carlos Satorres | 8f1ddb08b3 | |
Carlos Satorres | 330b1c1ec2 | |
Carlos Satorres | 6205feaca4 | |
Carlos Satorres | 0e691436e9 | |
Carlos Satorres | 81e6870f71 |
|
@ -31,3 +31,7 @@ yarn-error.log*
|
|||
# Cypress directories and files
|
||||
/test/cypress/videos
|
||||
/test/cypress/screenshots
|
||||
|
||||
# VitePress directories and files
|
||||
/docs/.vitepress/cache
|
||||
/docs/.vuepress
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import { defineConfig } from 'vitepress';
|
||||
|
||||
// https://vitepress.dev/reference/site-config
|
||||
export default defineConfig({
|
||||
title: 'Lilium',
|
||||
description: 'Lilium docs',
|
||||
themeConfig: {
|
||||
// https://vitepress.dev/reference/default-theme-config
|
||||
nav: [
|
||||
{ text: 'Home', link: '/' },
|
||||
{ text: 'Components', link: '/components/vnInput' },
|
||||
{ text: 'Composables', link: '/composables/useArrayData' },
|
||||
],
|
||||
|
||||
sidebar: [
|
||||
{
|
||||
items: [
|
||||
{
|
||||
text: 'Components',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [{ text: 'VnInput', link: '/components/vnInput' }],
|
||||
},
|
||||
{
|
||||
text: 'Composables',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: 'useArrayData', link: '/composables/useArrayData' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
socialLinks: [{ icon: 'github', link: 'https://github.com/vuejs/vitepress' }],
|
||||
},
|
||||
});
|
|
@ -0,0 +1,136 @@
|
|||
# VnInput
|
||||
|
||||
`VnInput` is a custom input component that provides various useful features such as validation, input clearing, and more.
|
||||
|
||||
## Props
|
||||
|
||||
### `modelValue`
|
||||
|
||||
- **Type:** `String | Number`
|
||||
- **Default:** `null`
|
||||
- **Description:** The value of the model bound to the component.
|
||||
|
||||
### `isOutlined`
|
||||
|
||||
- **Type:** `Boolean`
|
||||
- **Default:** `false`
|
||||
- **Description:** If `true`, the component is rendered with an outlined style.
|
||||
|
||||
### `info`
|
||||
|
||||
- **Type:** `String`
|
||||
- **Default:** `''`
|
||||
- **Description:** Additional information displayed alongside the component.
|
||||
|
||||
### `clearable`
|
||||
|
||||
- **Type:** `Boolean`
|
||||
- **Default:** `true`
|
||||
- **Description:** If `true`, the component shows a button to clear the input.
|
||||
|
||||
### `emptyToNull`
|
||||
|
||||
- **Type:** `Boolean`
|
||||
- **Default:** `true`
|
||||
- **Description:** If `true`, converts empty inputs to `null`.
|
||||
|
||||
### `insertable`
|
||||
|
||||
- **Type:** `Boolean`
|
||||
- **Default:** `false`
|
||||
- **Description:** If `true`, allows the insertion of new values.
|
||||
|
||||
### `maxlength`
|
||||
|
||||
- **Type:** `Number`
|
||||
- **Default:** `null`
|
||||
- **Description:** The maximum number of characters allowed in the input.
|
||||
|
||||
### `uppercase`
|
||||
|
||||
- **Type:** `Boolean`
|
||||
- **Default:** `false`
|
||||
- **Description:** If `true`, converts the input text to uppercase.
|
||||
|
||||
## Emits
|
||||
|
||||
### `update:modelValue`
|
||||
|
||||
- **Description:** Emits the updated model value.
|
||||
- **Behavior:** This event is emitted whenever the input value changes. It is used to update the model value bound to the component.
|
||||
|
||||
### `update:options`
|
||||
|
||||
- **Description:** Emits the updated options.
|
||||
- **Behavior:** This event is emitted when the component's options change. It is useful for components with dynamic options.
|
||||
|
||||
### `keyup.enter`
|
||||
|
||||
- **Description:** Emits an event when the Enter key is pressed.
|
||||
- **Behavior:** This event is emitted whenever the Enter key is pressed while the input is focused. It can be used to handle specific actions when the input is confirmed.
|
||||
|
||||
### `remove`
|
||||
|
||||
- **Description:** Emits an event to remove the current value.
|
||||
- **Behavior:** This event is emitted when the clear button (close icon) is clicked. It is used to handle the removal of the current input value.
|
||||
|
||||
## Functions
|
||||
|
||||
### `focus`
|
||||
|
||||
- **Description:** Focuses the input.
|
||||
- **Behavior:** This function is exposed so it can be called from outside the component. It uses `vnInputRef.value.focus()` to focus the input.
|
||||
|
||||
### `handleKeydown`
|
||||
|
||||
- **Description:** Handles the `keydown` event of the input.
|
||||
- **Behavior:** This function is called whenever a key is pressed while the input is focused. If the pressed key is `Backspace`, it does nothing. If `insertable` is `true` and the pressed key is a number, it calls `handleInsertMode`.
|
||||
|
||||
### `handleInsertMode`
|
||||
|
||||
- **Description:** Handles the insertion mode of values.
|
||||
- **Behavior:** This function is called when `insertable` is `true` and a numeric key is pressed. It inserts the value at the cursor position and updates the input value. Then, it moves the cursor to the correct position.
|
||||
|
||||
### `handleUppercase`
|
||||
|
||||
- **Description:** Converts the input value to uppercase.
|
||||
- **Behavior:** This function is called when the uppercase icon is clicked. It converts the current input value to uppercase.
|
||||
|
||||
## Usage
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<VnInput
|
||||
v-model="inputValue"
|
||||
:isOutlined="true"
|
||||
info="Additional information"
|
||||
:clearable="true"
|
||||
:emptyToNull="true"
|
||||
:insertable="false"
|
||||
:maxlength="50"
|
||||
:uppercase="true"
|
||||
@update:modelValue="handleUpdate"
|
||||
@keyup.enter="handleEnter"
|
||||
@remove="handleRemove"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
|
||||
const inputValue = ref('');
|
||||
|
||||
const handleUpdate = (value) => {
|
||||
console.log('Updated value:', value);
|
||||
};
|
||||
|
||||
const handleEnter = () => {
|
||||
console.log('Enter pressed');
|
||||
};
|
||||
|
||||
const handleRemove = () => {
|
||||
console.log('Value removed');
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,215 @@
|
|||
# useArrayData
|
||||
|
||||
`useArrayData` is a composable function that provides a set of utilities for managing array data in a Vue component. It leverages Pinia for state management and provides various methods for fetching, filtering, and manipulating data.
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
|
||||
const {
|
||||
fetch,
|
||||
applyFilter,
|
||||
addFilter,
|
||||
getCurrentFilter,
|
||||
setCurrentFilter,
|
||||
addFilterWhere,
|
||||
addOrder,
|
||||
deleteOrder,
|
||||
refresh,
|
||||
destroy,
|
||||
loadMore,
|
||||
store,
|
||||
totalRows,
|
||||
updateStateParams,
|
||||
isLoading,
|
||||
deleteOption,
|
||||
reset,
|
||||
resetPagination,
|
||||
} = useArrayData('myKey', userOptions);
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
### `key`
|
||||
|
||||
- **Type:** `String`
|
||||
- **Description:** A unique key to identify the data store.
|
||||
|
||||
### `userOptions`
|
||||
|
||||
- **Type:** `Object`
|
||||
- **Description:** An object containing user-defined options for configuring the data store.
|
||||
|
||||
## Methods
|
||||
|
||||
### `fetch`
|
||||
|
||||
Fetches data from the server.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- **`options`** : An object with the following properties:
|
||||
- `append` (Boolean): Whether to append the fetched data to the existing data.
|
||||
- `updateRouter` (Boolean): Whether to update the router with the current filter.
|
||||
|
||||
#### Returns
|
||||
|
||||
- **`Promise`** : A promise that resolves with the fetched data.
|
||||
|
||||
### `applyFilter`
|
||||
|
||||
Applies a filter to the data.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- **`filter`** : An object containing the filter criteria.
|
||||
- **`params`** : Additional parameters for the filter.
|
||||
- **`fetchOptions`** : Options for the fetch method.
|
||||
|
||||
#### Returns
|
||||
|
||||
- **`Promise`** : A promise that resolves with the filtered data.
|
||||
|
||||
### `addFilter`
|
||||
|
||||
Adds a filter to the existing filters.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- **`filter`** : An object containing the filter criteria.
|
||||
- **`params`** : Additional parameters for the filter.
|
||||
|
||||
#### Returns
|
||||
|
||||
- **`Promise`** : A promise that resolves with the updated filter and parameters.
|
||||
|
||||
### `getCurrentFilter`
|
||||
|
||||
Gets the current filter applied to the data.
|
||||
|
||||
#### Returns
|
||||
|
||||
- **`Object`** : The current filter and parameters.
|
||||
|
||||
### `setCurrentFilter`
|
||||
|
||||
Sets the current filter for the data.
|
||||
|
||||
#### Returns
|
||||
|
||||
- **`Object`** : The current filter and parameters.
|
||||
|
||||
### `addFilterWhere`
|
||||
|
||||
Adds a `where` clause to the existing filters.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- **`where`** : An object containing the `where` clause.
|
||||
|
||||
#### Returns
|
||||
|
||||
- **`Promise`** : A promise that resolves when the filter is applied.
|
||||
|
||||
### `addOrder`
|
||||
|
||||
Adds an order to the existing orders.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- **`field`** : The field to order by.
|
||||
- **`direction`** : The direction of the order (`ASC` or `DESC`).
|
||||
|
||||
#### Returns
|
||||
|
||||
- **`Promise`** : A promise that resolves with the updated order.
|
||||
|
||||
### `deleteOrder`
|
||||
|
||||
Deletes an order from the existing orders.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- **`field`** : The field to delete the order for.
|
||||
|
||||
#### Returns
|
||||
|
||||
- **`Promise`** : A promise that resolves when the order is deleted.
|
||||
|
||||
### `refresh`
|
||||
|
||||
Refreshes the data by re-fetching it from the server.
|
||||
|
||||
#### Returns
|
||||
|
||||
- **`Promise`** : A promise that resolves with the refreshed data.
|
||||
|
||||
### `destroy`
|
||||
|
||||
Destroys the data store for the given key.
|
||||
|
||||
### `loadMore`
|
||||
|
||||
Loads more data by incrementing the pagination.
|
||||
|
||||
#### Returns
|
||||
|
||||
- **`Promise`** : A promise that resolves with the additional data.
|
||||
|
||||
### `updateStateParams`
|
||||
|
||||
Updates the state parameters with the given data.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- **`data`** : The data to update the state parameters with.
|
||||
|
||||
### `deleteOption`
|
||||
|
||||
Deletes an option from the store.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- **`option`** : The option to delete.
|
||||
|
||||
### `reset`
|
||||
|
||||
Resets the store to its default state.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- **`opts`** : An array of options to reset.
|
||||
|
||||
### `resetPagination`
|
||||
|
||||
Resets the pagination for the store.
|
||||
|
||||
## Computed Properties
|
||||
|
||||
### `totalRows`
|
||||
|
||||
- **Description:** The total number of rows in the data.
|
||||
- **Type:** `Number`
|
||||
|
||||
### `isLoading`
|
||||
|
||||
- **Description:** Whether the data is currently being loaded.
|
||||
- **Type:** `Boolean`
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
|
||||
const userOptions = {
|
||||
url: '/api/data',
|
||||
limit: 10,
|
||||
};
|
||||
|
||||
const arrayData = useArrayData('myKey', userOptions);
|
||||
</script>
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
```
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
# https://vitepress.dev/reference/default-theme-home-page
|
||||
layout: home
|
||||
|
||||
hero:
|
||||
name: 'Lilium'
|
||||
text: 'Lilium docs'
|
||||
tagline: Powered by Verdnatura
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Docs
|
||||
link: /components/vnInput
|
||||
---
|
142
package.json
142
package.json
|
@ -1,70 +1,74 @@
|
|||
{
|
||||
"name": "salix-front",
|
||||
"version": "25.06.0",
|
||||
"description": "Salix frontend",
|
||||
"productName": "Salix",
|
||||
"author": "Verdnatura",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@8.15.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"resetDatabase": "cd ../salix && gulp docker",
|
||||
"lint": "eslint --ext .js,.vue ./",
|
||||
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
|
||||
"test:e2e": "cypress open",
|
||||
"test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run",
|
||||
"test": "echo \"See package.json => scripts for available tests.\" && exit 0",
|
||||
"test:unit": "vitest",
|
||||
"test:unit:ci": "vitest run",
|
||||
"commitlint": "commitlint --edit",
|
||||
"prepare": "npx husky install",
|
||||
"addReferenceTag": "node .husky/addReferenceTag.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@quasar/cli": "^2.4.1",
|
||||
"@quasar/extras": "^1.16.16",
|
||||
"axios": "^1.4.0",
|
||||
"chromium": "^3.0.3",
|
||||
"croppie": "^2.6.5",
|
||||
"moment": "^2.30.1",
|
||||
"pinia": "^2.1.3",
|
||||
"quasar": "^2.17.7",
|
||||
"validator": "^13.9.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-i18n": "^9.3.0",
|
||||
"vue-router": "^4.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.2.1",
|
||||
"@commitlint/config-conventional": "^19.1.0",
|
||||
"@intlify/unplugin-vue-i18n": "^0.8.2",
|
||||
"@pinia/testing": "^0.1.2",
|
||||
"@quasar/app-vite": "^2.0.8",
|
||||
"@quasar/quasar-app-extension-qcalendar": "^4.0.2",
|
||||
"@quasar/quasar-app-extension-testing-unit-vitest": "^0.4.0",
|
||||
"@vue/test-utils": "^2.4.4",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"cypress": "^13.6.6",
|
||||
"cypress-mochawesome-reporter": "^3.8.2",
|
||||
"eslint": "^9.18.0",
|
||||
"eslint-config-prettier": "^10.0.1",
|
||||
"eslint-plugin-cypress": "^4.1.0",
|
||||
"eslint-plugin-vue": "^9.32.0",
|
||||
"husky": "^8.0.0",
|
||||
"postcss": "^8.4.23",
|
||||
"prettier": "^3.4.2",
|
||||
"sass": "^1.83.4",
|
||||
"vitest": "^0.34.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20 || ^18 || ^16",
|
||||
"npm": ">= 8.1.2",
|
||||
"yarn": ">= 1.21.1",
|
||||
"bun": ">= 1.0.25"
|
||||
},
|
||||
"overrides": {
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"vite": "^6.0.11",
|
||||
"vitest": "^0.31.1"
|
||||
}
|
||||
}
|
||||
"name": "salix-front",
|
||||
"version": "25.06.0",
|
||||
"description": "Salix frontend",
|
||||
"productName": "Salix",
|
||||
"author": "Verdnatura",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@8.15.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"resetDatabase": "cd ../salix && gulp docker",
|
||||
"lint": "eslint --ext .js,.vue ./",
|
||||
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
|
||||
"test:e2e": "cypress open",
|
||||
"test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run",
|
||||
"test": "echo \"See package.json => scripts for available tests.\" && exit 0",
|
||||
"test:unit": "vitest",
|
||||
"test:unit:ci": "vitest run",
|
||||
"commitlint": "commitlint --edit",
|
||||
"prepare": "npx husky install",
|
||||
"addReferenceTag": "node .husky/addReferenceTag.js",
|
||||
"docs:dev": "vitepress dev docs",
|
||||
"docs:build": "vitepress build docs",
|
||||
"docs:preview": "vitepress preview docs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@quasar/cli": "^2.4.1",
|
||||
"@quasar/extras": "^1.16.16",
|
||||
"axios": "^1.4.0",
|
||||
"chromium": "^3.0.3",
|
||||
"croppie": "^2.6.5",
|
||||
"moment": "^2.30.1",
|
||||
"pinia": "^2.1.3",
|
||||
"quasar": "^2.17.7",
|
||||
"validator": "^13.9.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-i18n": "^9.3.0",
|
||||
"vue-router": "^4.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.2.1",
|
||||
"@commitlint/config-conventional": "^19.1.0",
|
||||
"@intlify/unplugin-vue-i18n": "^0.8.2",
|
||||
"@pinia/testing": "^0.1.2",
|
||||
"@quasar/app-vite": "^2.0.8",
|
||||
"@quasar/quasar-app-extension-qcalendar": "^4.0.2",
|
||||
"@quasar/quasar-app-extension-testing-unit-vitest": "^0.4.0",
|
||||
"@vue/test-utils": "^2.4.4",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"cypress": "^13.6.6",
|
||||
"cypress-mochawesome-reporter": "^3.8.2",
|
||||
"eslint": "^9.18.0",
|
||||
"eslint-config-prettier": "^10.0.1",
|
||||
"eslint-plugin-cypress": "^4.1.0",
|
||||
"eslint-plugin-vue": "^9.32.0",
|
||||
"husky": "^8.0.0",
|
||||
"postcss": "^8.4.23",
|
||||
"prettier": "^3.4.2",
|
||||
"sass": "^1.83.4",
|
||||
"vitepress": "^1.6.3",
|
||||
"vitest": "^0.34.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20 || ^18 || ^16",
|
||||
"npm": ">= 8.1.2",
|
||||
"yarn": ">= 1.21.1",
|
||||
"bun": ">= 1.0.25"
|
||||
},
|
||||
"overrides": {
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"vite": "^6.0.11",
|
||||
"vitest": "^0.31.1"
|
||||
}
|
||||
}
|
772
pnpm-lock.yaml
772
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,6 @@
|
|||
export default [
|
||||
{
|
||||
path: '/api',
|
||||
rule: { target: 'http://0.0.0.0:3000' },
|
||||
},
|
||||
];
|
|
@ -179,7 +179,6 @@ export default configure(function (/* ctx */) {
|
|||
'render', // keep this as last one
|
||||
],
|
||||
},
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli/developing-pwa/configuring-pwa
|
||||
pwa: {
|
||||
workboxMode: 'generateSW', // or 'injectManifest'
|
||||
|
|
|
@ -31,7 +31,6 @@ const props = defineProps({
|
|||
const route = useRoute();
|
||||
|
||||
const itemTypesOptions = ref([]);
|
||||
const suppliersOptions = ref([]);
|
||||
const tagOptions = ref([]);
|
||||
const tagValues = ref([]);
|
||||
const categoryList = ref(null);
|
||||
|
@ -40,13 +39,13 @@ const selectedTypeFk = ref(getParamWhere(route.query.table, 'typeFk', false));
|
|||
|
||||
const selectedCategory = computed(() => {
|
||||
return (categoryList.value || []).find(
|
||||
(category) => category?.id === selectedCategoryFk.value
|
||||
(category) => category?.id === selectedCategoryFk.value,
|
||||
);
|
||||
});
|
||||
|
||||
const selectedType = computed(() => {
|
||||
return (itemTypesOptions.value || []).find(
|
||||
(type) => type?.id === selectedTypeFk.value
|
||||
(type) => type?.id === selectedTypeFk.value,
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -134,13 +133,6 @@ const setCategoryList = (data) => {
|
|||
|
||||
<template>
|
||||
<FetchData url="ItemCategories" limit="30" auto-load @on-fetch="setCategoryList" />
|
||||
<FetchData
|
||||
url="Suppliers"
|
||||
limit="30"
|
||||
auto-load
|
||||
:filter="{ fields: ['id', 'name', 'nickname'], order: 'name ASC', limit: 30 }"
|
||||
@on-fetch="(data) => (suppliersOptions = data)"
|
||||
/>
|
||||
<FetchData
|
||||
url="Tags"
|
||||
:filter="{ fields: ['id', 'name', 'isFree'] }"
|
||||
|
|
|
@ -10,12 +10,13 @@ import routes from 'src/router/modules';
|
|||
import LeftMenuItem from './LeftMenuItem.vue';
|
||||
import LeftMenuItemGroup from './LeftMenuItemGroup.vue';
|
||||
import VnInput from './common/VnInput.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const quasar = useQuasar();
|
||||
const navigation = useNavigationStore();
|
||||
|
||||
const router = useRouter();
|
||||
const props = defineProps({
|
||||
source: {
|
||||
type: String,
|
||||
|
@ -174,6 +175,10 @@ function normalize(text) {
|
|||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.toLowerCase();
|
||||
}
|
||||
const searchModule = () => {
|
||||
const [item] = filteredItems.value;
|
||||
if (item) router.push({ name: item.name });
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -188,10 +193,11 @@ function normalize(text) {
|
|||
filled
|
||||
dense
|
||||
autofocus
|
||||
@keyup.enter.stop="searchModule()"
|
||||
/>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
<template v-if="filteredPinnedModules.size">
|
||||
<template v-if="filteredPinnedModules.size && !search">
|
||||
<LeftMenuItem
|
||||
v-for="[key, pinnedModule] of filteredPinnedModules"
|
||||
:key="key"
|
||||
|
@ -215,11 +221,11 @@ function normalize(text) {
|
|||
</LeftMenuItem>
|
||||
<QSeparator />
|
||||
</template>
|
||||
<template v-for="item in filteredItems" :key="item.name">
|
||||
<template v-for="(item, index) in filteredItems" :key="item.name">
|
||||
<template
|
||||
v-if="item.children && !filteredPinnedModules.has(item.name)"
|
||||
v-if="search ||item.children && !filteredPinnedModules.has(item.name)"
|
||||
>
|
||||
<LeftMenuItem :item="item" group="modules">
|
||||
<LeftMenuItem :item="item" group="modules" :class="search && index === 0 ? 'searched' : ''">
|
||||
<template #side>
|
||||
<QBtn
|
||||
v-if="item.isPinned === true"
|
||||
|
@ -336,6 +342,9 @@ function normalize(text) {
|
|||
.header {
|
||||
color: var(--vn-label-color);
|
||||
}
|
||||
.searched{
|
||||
background-color: var(--vn-section-hover-color);
|
||||
}
|
||||
</style>
|
||||
<i18n>
|
||||
es:
|
||||
|
|
|
@ -20,6 +20,7 @@ const appName = 'Lilium';
|
|||
const pinnedModulesRef = ref();
|
||||
|
||||
onMounted(() => stateStore.setMounted());
|
||||
const refresh = () => window.location.reload();
|
||||
</script>
|
||||
<template>
|
||||
<QHeader color="white" elevated>
|
||||
|
@ -64,6 +65,13 @@ onMounted(() => stateStore.setMounted());
|
|||
<QSpace />
|
||||
<div class="q-pl-sm q-gutter-sm row items-center no-wrap">
|
||||
<div id="actions-prepend"></div>
|
||||
<QIcon
|
||||
name="refresh"
|
||||
size="md"
|
||||
color="red"
|
||||
v-if="state.get('error')"
|
||||
@click="refresh"
|
||||
/>
|
||||
<QBtn
|
||||
:class="{ 'q-pa-none': quasar.platform.is.mobile }"
|
||||
id="pinnedModules"
|
||||
|
|
|
@ -47,8 +47,6 @@ const darkMode = computed({
|
|||
},
|
||||
});
|
||||
|
||||
const foreignCurrency = ref();
|
||||
|
||||
const user = state.getUser();
|
||||
const warehousesData = ref();
|
||||
const companiesData = ref();
|
||||
|
@ -60,8 +58,6 @@ onMounted(async () => {
|
|||
});
|
||||
|
||||
function updatePreferences() {
|
||||
foreignCurrency.value = user.value.foreignCurrency;
|
||||
|
||||
if (user.value.darkMode !== null) {
|
||||
darkMode.value = user.value.darkMode;
|
||||
}
|
||||
|
@ -120,11 +116,6 @@ async function saveUserData(param, value) {
|
|||
}
|
||||
}
|
||||
|
||||
async function saveCurrency(value) {
|
||||
user.value.foreignCurrency = value;
|
||||
useState().setUser(user.value);
|
||||
}
|
||||
|
||||
const onDataSaved = () => {
|
||||
notify('globals.dataSaved', 'positive');
|
||||
};
|
||||
|
@ -178,14 +169,6 @@ const onDataError = () => {
|
|||
color="primary"
|
||||
unchecked-icon="light_mode"
|
||||
/>
|
||||
<QToggle
|
||||
v-model="foreignCurrency"
|
||||
:label="t(`globals.foreignCurrency`)"
|
||||
@update:model-value="saveCurrency"
|
||||
color="primary"
|
||||
unchecked-icon="euro_symbol"
|
||||
checked-icon="currency_exchange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<QSeparator vertical inset class="q-mx-lg" />
|
||||
|
|
|
@ -12,7 +12,6 @@ import VnInputDate from 'components/common/VnInputDate.vue';
|
|||
import VnInputTime from 'components/common/VnInputTime.vue';
|
||||
import VnComponent from 'components/common/VnComponent.vue';
|
||||
import VnUserLink from 'components/ui/VnUserLink.vue';
|
||||
import VnCurrency from '../ui/VnCurrency.vue';
|
||||
|
||||
const model = defineModel(undefined, { required: true });
|
||||
const $props = defineProps({
|
||||
|
@ -132,9 +131,6 @@ const defaultComponents = {
|
|||
userLink: {
|
||||
component: markRaw(VnUserLink),
|
||||
},
|
||||
currency: {
|
||||
component: markRaw(VnCurrency),
|
||||
},
|
||||
};
|
||||
|
||||
const value = computed(() => {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
export default function (initialFooter, data) {
|
||||
const footer = data.reduce(
|
||||
(acc, row) => {
|
||||
Object.entries(initialFooter).forEach(([key, initialValue]) => {
|
||||
acc[key] += row?.[key] !== undefined ? row[key] : initialValue;
|
||||
});
|
||||
return acc;
|
||||
},
|
||||
{ ...initialFooter }
|
||||
);
|
||||
return footer;
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
<script setup>
|
||||
import VnSelect from 'components/common/VnSelect.vue';
|
||||
import axios from 'axios';
|
||||
import { onMounted } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { watch } from 'vue';
|
||||
|
||||
const model = defineModel({
|
||||
type: [String, Number, Object],
|
||||
default: null,
|
||||
});
|
||||
|
||||
const clientId = defineModel('clientId', {
|
||||
type: Number,
|
||||
default: null,
|
||||
});
|
||||
|
||||
const companyList = ref([]);
|
||||
onMounted(async () => {
|
||||
companyList.value = (await axios.get('Companies')).data;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => clientId.value,
|
||||
async (newId) => {
|
||||
if (!newId) return;
|
||||
const { data } = await axios.get(`Clients/${newId}`, {
|
||||
fields: ['defaultCompanyFk'],
|
||||
});
|
||||
model.value = data.defaultCompanyFk;
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnSelect
|
||||
:label="$t('globals.company')"
|
||||
v-bind="$attrs"
|
||||
v-model="model"
|
||||
:options="companyList"
|
||||
option-label="code"
|
||||
/>
|
||||
</template>
|
|
@ -1,57 +0,0 @@
|
|||
<script setup>
|
||||
import VnSelect from 'components/common/VnSelect.vue';
|
||||
import axios from 'axios';
|
||||
import { onMounted } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { watch } from 'vue';
|
||||
|
||||
const model = defineModel({
|
||||
type: Number,
|
||||
default: null,
|
||||
});
|
||||
|
||||
const clientId = defineModel('clientId', {
|
||||
type: Number,
|
||||
default: null,
|
||||
});
|
||||
|
||||
const currencyList = ref([]);
|
||||
|
||||
const emit = defineEmits(['newValue']);
|
||||
|
||||
onMounted(async () => {
|
||||
currencyList.value = (await axios.get('Currencies')).data;
|
||||
emitCurrency(model.value);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => clientId.value,
|
||||
async (newId) => {
|
||||
if (!newId) return;
|
||||
const { data } = await axios.get(`Clients/${newId}`, {
|
||||
fields: ['defaultCurrencyFk'],
|
||||
});
|
||||
model.value = data.defaultCurrencyFk;
|
||||
}
|
||||
);
|
||||
|
||||
function emitCurrency(id) {
|
||||
if (!id) return;
|
||||
emit(
|
||||
'newValue',
|
||||
currencyList.value?.find((c) => c.id == id)
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnSelect
|
||||
:label="$t('globals.currency')"
|
||||
v-bind="$attrs"
|
||||
v-model="model"
|
||||
:options="currencyList"
|
||||
option-label="name"
|
||||
option-caption="code"
|
||||
@update:model-value="(id) => emitCurrency(id)"
|
||||
/>
|
||||
</template>
|
|
@ -0,0 +1,35 @@
|
|||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import VnSelect from 'components/common/VnSelect.vue';
|
||||
|
||||
const model = defineModel({ type: [String, Number, Object] });
|
||||
const url = 'Suppliers';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnSelect
|
||||
:label="$t('globals.supplier')"
|
||||
v-bind="$attrs"
|
||||
v-model="model"
|
||||
:url="url"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
:fields="['id', 'name', 'nickname', 'nif']"
|
||||
sort-by="name ASC"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>
|
||||
{{ scope.opt?.name }}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{
|
||||
`#${scope.opt?.id} , ${scope.opt?.nickname} (${scope.opt?.nif})`
|
||||
}}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
</template>
|
|
@ -53,6 +53,7 @@ const url = computed(() => {
|
|||
:fields="['id', 'name', 'nickname', 'code']"
|
||||
:filter-options="['id', 'name', 'nickname', 'code']"
|
||||
sort-by="nickname ASC"
|
||||
data-cy="vnWorkerSelect"
|
||||
>
|
||||
<template #prepend v-if="$props.hasAvatar">
|
||||
<VnAvatar :worker-id="value" color="primary" v-bind="$attrs" />
|
||||
|
|
|
@ -17,10 +17,6 @@ const $props = defineProps({
|
|||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
userFilter: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
|
@ -62,7 +58,6 @@ onBeforeMount(async () => {
|
|||
arrayData = useArrayData($props.dataKey, {
|
||||
url: $props.url,
|
||||
filter: $props.filter,
|
||||
userFilter: $props.userFilter,
|
||||
skip: 0,
|
||||
});
|
||||
store = arrayData.store;
|
||||
|
@ -78,7 +73,7 @@ onBeforeMount(async () => {
|
|||
() => [$props.url, $props.filter],
|
||||
async () => {
|
||||
if (!isSameDataKey.value) await getData();
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -113,7 +108,7 @@ const iconModule = computed(() => route.matched[1].meta.icon);
|
|||
const toModule = computed(() =>
|
||||
route.matched[1].path.split('/').length > 2
|
||||
? route.matched[1].redirect
|
||||
: route.matched[1].children[0].redirect,
|
||||
: route.matched[1].children[0].redirect
|
||||
);
|
||||
</script>
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ import VnLv from 'components/ui/VnLv.vue';
|
|||
import VnImg from 'src/components/ui/VnImg.vue';
|
||||
import OrderCatalogItemDialog from 'pages/Order/Card/OrderCatalogItemDialog.vue';
|
||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||
import VnCurrency from './VnCurrency.vue';
|
||||
|
||||
import { toCurrency } from 'filters/index';
|
||||
|
||||
const DEFAULT_PRICE_KG = 0;
|
||||
|
||||
|
@ -60,7 +61,7 @@ const card = toRef(props, 'item');
|
|||
<div class="price">
|
||||
<p v-if="isCatalog">
|
||||
{{ card.available }} {{ t('to') }}
|
||||
<VnCurrency :model="card" array-data-model="Order" />
|
||||
{{ toCurrency(card.price) }}
|
||||
</p>
|
||||
<slot name="price" />
|
||||
<QIcon v-if="isCatalog" name="add_circle" class="icon">
|
||||
|
@ -80,12 +81,7 @@ const card = toRef(props, 'item');
|
|||
</div>
|
||||
<p v-if="card.priceKg" class="price-kg">
|
||||
{{ t('price-kg') }}
|
||||
<VnCurrency
|
||||
v-model="card"
|
||||
array-data-model="Order"
|
||||
local-field="priceKg"
|
||||
foreign-field="foreignPriceKg"
|
||||
/>
|
||||
{{ toCurrency(card.priceKg) || DEFAULT_PRICE_KG }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
<script setup>
|
||||
import { toCurrency } from 'src/filters';
|
||||
import { watch, ref } from 'vue';
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
import { useState } from 'src/composables/useState';
|
||||
|
||||
const $props = defineProps({
|
||||
model: {
|
||||
type: Object,
|
||||
required: true,
|
||||
description: 'object to use foreignField and localField',
|
||||
},
|
||||
currencyCode: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
foreignField: {
|
||||
type: [String, undefined],
|
||||
default: undefined,
|
||||
},
|
||||
localField: {
|
||||
type: String,
|
||||
default: 'price',
|
||||
},
|
||||
arrayDataModel: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
description: 'find currency code in array data model',
|
||||
},
|
||||
});
|
||||
|
||||
const state = useState();
|
||||
const user = state.getUser();
|
||||
|
||||
const toCurrencyLabel = ref();
|
||||
const foreignValue = ref();
|
||||
const localValue = ref();
|
||||
const currency = ref();
|
||||
|
||||
watch(
|
||||
() => $props.model,
|
||||
() => calculate(),
|
||||
{ immediate: true, deep: true },
|
||||
);
|
||||
|
||||
function calculate() {
|
||||
if (!$props.model) return;
|
||||
|
||||
currency.value = $props.currencyCode;
|
||||
if ($props.arrayDataModel) {
|
||||
const arrayData = $props.arrayDataModel && useArrayData($props.arrayDataModel);
|
||||
currency.value = arrayData.store.data?.currency?.code;
|
||||
}
|
||||
foreignValue.value = $props.model[getForeignFieldComputed()];
|
||||
localValue.value = $props.model?.[$props.localField];
|
||||
|
||||
toCurrencyLabel.value = toCurrency(
|
||||
foreignValue.value ?? localValue.value,
|
||||
currency.value,
|
||||
);
|
||||
}
|
||||
|
||||
function getForeignFieldComputed() {
|
||||
return (
|
||||
$props.foreignField ??
|
||||
'foreign' + $props.localField.charAt(0).toUpperCase() + $props.localField.slice(1)
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span :title="toCurrencyLabel">
|
||||
<template v-if="currency && (localValue || localValue === 0)">
|
||||
{{
|
||||
foreignValue && user.foreignCurrency
|
||||
? toCurrencyLabel
|
||||
: toCurrency(localValue)
|
||||
}}
|
||||
</template>
|
||||
<template v-else>-</template>
|
||||
</span>
|
||||
</template>
|
|
@ -123,7 +123,7 @@ watch(
|
|||
() => props.data,
|
||||
() => {
|
||||
store.data = props.data;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
|
@ -132,12 +132,12 @@ watch(
|
|||
if (!mounted.value) return;
|
||||
emit('onChange', data);
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => [props.url, props.filter],
|
||||
([url, filter]) => mounted.value && fetch({ url, filter })
|
||||
([url, filter]) => mounted.value && fetch({ url, filter }),
|
||||
);
|
||||
const addFilter = async (filter, params) => {
|
||||
await arrayData.addFilter({ filter, params });
|
||||
|
@ -198,7 +198,7 @@ function endPagination() {
|
|||
async function onLoad(index, done) {
|
||||
if (!store.data || !mounted.value) return done();
|
||||
|
||||
if (store.data.length === 0 || !props.url) return done(false);
|
||||
if (store.data.length === 0 || !arrayData.store.url) return done(false);
|
||||
|
||||
pagination.value.page = pagination.value.page + 1;
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ export function useSession() {
|
|||
const { data: isValidToken } = await axios.get('VnUsers/validateToken');
|
||||
if (isValidToken)
|
||||
destroyTokenPromises = Object.entries(tokens).map(([key, url]) =>
|
||||
destroyToken(url, storage, key),
|
||||
destroyToken(url, storage, key)
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
|
@ -75,7 +75,6 @@ export function useSession() {
|
|||
nickname: '',
|
||||
lang: '',
|
||||
darkMode: null,
|
||||
foreignCurrency: true,
|
||||
});
|
||||
|
||||
stopRenewer();
|
||||
|
|
|
@ -10,7 +10,6 @@ const user = ref({
|
|||
darkMode: null,
|
||||
companyFk: null,
|
||||
warehouseFk: null,
|
||||
foreignCurrency: true,
|
||||
});
|
||||
if (sessionStorage.getItem('user'))
|
||||
user.value = JSON.parse(sessionStorage.getItem('user'));
|
||||
|
|
|
@ -22,7 +22,7 @@ export function useVnConfirm() {
|
|||
{ customHTML: () => h(component, props) }
|
||||
),
|
||||
}).onOk(async () => {
|
||||
if (successFn) await successFn();
|
||||
if (successFn) successFn();
|
||||
});
|
||||
};
|
||||
|
||||
|
|
Binary file not shown.
|
@ -127,6 +127,7 @@
|
|||
<glyph unicode="" glyph-name="stowaway" d="M1006.933 452.267l-260.267 106.667 29.867 29.867c4.267 4.267 4.267 12.8 4.267 17.067-4.267 4.267-8.533 8.533-12.8 8.533h-157.867c0 93.867 76.8 157.867 174.933 157.867 4.267 0 8.533 4.267 12.8 8.533s4.267 8.533 0 17.067l-81.067 153.6c-4.267 0-12.8 4.267-17.067 4.267-46.933 0-93.867-17.067-132.267-42.667-21.333-17.067-42.667-38.4-55.467-59.733-12.8 21.333-29.867 42.667-55.467 59.733-34.133 12.8-81.067 34.133-128 34.133-4.267 0-12.8-4.267-12.8-8.533l-85.333-153.6c-4.267-4.267-4.267-4.267 0-12.8 4.267-4.267 8.533-8.533 12.8-8.533 98.133 0 174.933-59.733 174.933-153.6v0h-140.8c-4.267 0-12.8-4.267-12.8-8.533-8.533-4.267-4.267-17.067 0-21.333l21.333-21.333-277.333-110.933c-8.533-8.533-12.8-12.8-8.533-21.333 0-8.533 8.533-12.8 17.067-12.8v0l98.133 4.267-81.067-85.333c0-4.267-4.267-8.533 0-12.8 0-4.267 4.267-8.533 8.533-8.533l85.333-34.133v-179.2c0-8.533 4.267-12.8 8.533-12.8l358.4-145.067h8.533l358.4 145.067c4.267 4.267 8.533 8.533 8.533 12.8v179.2l85.333 34.133c4.267 0 8.533 4.267 8.533 8.533s0 8.533-4.267 12.8l-68.267 98.133 102.4-4.267c8.533 0 12.8 4.267 17.067 12.8 8.533 0 4.267 4.267-4.267 12.8zM110.933 456.533l196.267 76.8 8.533-8.533-166.4-64-38.4-4.267zM153.6 285.867v0l-68.267 34.133 68.267 98.133 328.533-132.267-68.267-98.133-260.267 98.133zM490.667-29.867l-328.533 132.267v153.6l243.2-98.133h12.8c0 0 0 0 4.267 0v0c0 0 4.267 0 4.267 4.267l64 85.333c0-4.267 0-277.333 0-277.333zM490.667 324.267l-298.667 115.2 149.333 64 153.6-157.867v-17.067h-4.267zM529.067 337.067l157.867 157.867 140.8-55.467-298.667-115.2c0 0 0 12.8 0 12.8zM849.067 102.4l-328.533-132.267v281.6l64-85.333c0 0 0-4.267 4.267-4.267v0h17.067l243.2 98.133v-157.867zM938.667 324.267l-324.267-132.267-68.267 98.133 328.533 132.267 64-98.133zM870.4 460.8l-157.867 64 12.8 8.533 187.733-76.8-42.667 4.267z" />
|
||||
<glyph unicode="" glyph-name="supplier" d="M797.867 405.333l98.133 34.133 21.333-59.733-98.133-34.133-21.333 59.733zM1019.733 341.333c-4.267-8.533-8.533-12.8-17.067-17.067l-332.8-119.467c4.267-4.267 8.533-12.8 12.8-17.067l277.333 102.4 21.333-59.733-277.333-102.4c0-8.533 4.267-12.8 4.267-21.333 0-85.333-68.267-157.867-157.867-157.867-85.333 0-157.867 68.267-157.867 157.867 0 55.467 29.867 106.667 72.533 132.267l-217.6 610.133c-8.533 25.6-38.4 42.667-68.267 29.867l-157.867-55.467-21.333 59.733 157.867 59.733c59.733 17.067 123.733-12.8 149.333-72.533l221.867-614.4c8.533 0 12.8 0 21.333 4.267l-119.467 332.8c-4.267 17.067 4.267 34.133 17.067 38.4l136.533 51.2c0 0 0 0 0 0l115.2 42.667c0 0 0 0 0 0l136.533 51.2c8.533 4.267 17.067 4.267 25.6 0s12.8-8.533 17.067-17.067l145.067-396.8c0-4.267 0-12.8-4.267-21.333zM695.467 657.067l-59.733-21.333 8.533-21.333 59.733 21.333-8.533 21.333zM644.267 106.667c0 51.2-42.667 93.867-93.867 93.867s-93.867-42.667-93.867-93.867c0-51.2 42.667-93.867 93.867-93.867s93.867 38.4 93.867 93.867zM951.467 371.2l-119.467 332.8-76.8-29.867 17.067-51.2c4.267-8.533 4.267-17.067 0-25.6s-8.533-12.8-17.067-17.067l-115.2-42.667c-4.267 0-8.533 0-12.8 0-12.8 0-25.6 8.533-29.867 21.333l-17.067 51.2-76.8-29.867 119.467-332.8 328.533 123.733z" />
|
||||
<glyph unicode="" glyph-name="supplierfalse" d="M198.827 882.773c22.187 0.427 41.813-14.080 48.64-34.133l8.107-22.187 105.813-105.813-54.187 149.333c-25.6 59.733-89.6 89.6-149.333 72.533l-13.653-5.12 54.613-54.613zM708.693 129.28l-173.653 173.653 15.36-43.093c-8.533-4.267-12.8-4.267-21.333-4.267l-29.867 83.2-108.373 108.373 74.24-208.64c-42.667-25.6-72.533-76.8-72.533-132.267 0-89.6 72.533-157.867 157.867-157.867 89.6 0 157.867 72.533 157.867 157.867 0 8.533-4.267 12.8-4.267 21.333l4.693 1.707zM550.4 12.373c-51.2 0-93.867 42.667-93.867 93.867s42.667 93.867 93.867 93.867 93.867-42.667 93.867-93.867c0-55.467-42.667-93.867-93.867-93.867zM960 289.707l-122.453-45.227 49.493-49.067 94.293 34.56zM504.32 577.707l-0.853 2.133 76.8 29.867 17.067-51.2c4.267-12.8 17.067-21.333 29.867-21.333 4.267 0 8.533 0 12.8 0l115.2 42.667c8.533 4.267 12.8 8.533 17.067 17.067s4.267 17.067 0 25.6l-17.067 51.2 76.8 29.867 119.467-332.8-174.507-65.707 45.653-45.653 180.053 64.427c8.533 4.267 12.8 8.533 17.067 17.067s4.267 17.067 4.267 21.333l-145.067 396.8c-4.267 8.533-8.533 12.8-17.067 17.067s-17.067 4.267-25.6 0l-136.533-51.2-115.2-42.667-134.4-50.347 54.187-54.187zM695.467 656.64l8.533-21.333-59.733-21.333-8.533 21.333 59.733 21.333zM896 439.040l-98.133-34.133 21.333-59.733 98.133 34.133zM39.253 960c-9.813 0-20.053-3.84-27.733-11.52-15.36-15.787-15.36-40.533 0-55.893l945.493-945.067c7.68-7.68 17.493-11.52 27.733-11.52 9.813 0 20.053 3.84 27.733 11.52 15.36 15.787 15.36 40.533 0 55.893l-945.493 945.067c-7.68 7.68-17.493 11.52-27.733 11.52z" />
|
||||
<glyph unicode="" glyph-name="inactive-car" d="M1024 900.267l-59.733 59.733-964.267-964.267 59.733-59.733 964.267 964.267zM0 55.893v448.853l119.467 341.333c5.547 17.067 15.787 30.72 30.72 41.387 14.507 10.24 31.147 15.787 49.067 15.787h625.92c6.827 0 13.653-0.853 20.053-2.133l-111.36-111.36h-514.987l-59.733-170.667h403.2l-113.92-113.92h-334.507v-284.587h50.773l-164.693-164.693zM316.587 423.253c8.96-8.96 15.787-19.627 19.627-30.72l-110.080-110.080c-11.52 4.267-21.76 10.667-30.72 19.627-16.64 16.64-24.747 36.693-24.747 60.587s8.107 43.947 24.747 60.587c16.64 16.64 36.693 24.747 60.587 24.747s43.947-8.107 60.587-24.747zM768 277.333c-23.893 0-43.947 8.107-60.587 24.747s-24.747 36.693-24.747 60.587 8.107 43.947 24.747 60.587c16.64 16.64 36.693 24.747 60.587 24.747s43.947-8.107 60.587-24.747c16.64-16.64 24.747-36.693 24.747-60.587s-8.107-43.947-24.747-60.587c-16.64-16.64-36.693-24.747-60.587-24.747zM936.96 753.067l87.040-248.32v-455.253c0-16.213-5.547-29.44-16.213-40.533s-24.32-16.213-40.533-16.213h-56.747c-16.213 0-29.44 5.547-40.533 16.213s-16.213 24.32-16.213 40.533v56.747h-563.2l113.92 113.92h505.6v284.587h-221.44l113.92 113.92h61.867l-16.213 46.080 88.32 88.32z" />
|
||||
<glyph unicode="" glyph-name="tags" d="M729.6 960c-42.667 0-89.6 0-132.267 0-21.333 0-38.4-8.533-51.2-21.333-140.8-140.8-281.6-281.6-422.4-422.4-25.6-25.6-25.6-51.2 0-76.8 93.867-93.867 187.733-187.733 281.6-281.6 25.6-25.6 51.2-25.6 76.8 0 140.8 140.8 281.6 281.6 422.4 422.4 17.067 12.8 21.333 29.867 21.333 51.2 0 93.867 0 183.467 0 277.333 0 34.133-17.067 51.2-51.2 51.2-51.2 0-98.133 0-145.067 0zM682.667 763.733c0 25.6 17.067 46.933 42.667 46.933s46.933-21.333 46.933-46.933c0-25.6-21.333-46.933-46.933-46.933-21.333 0-42.667 21.333-42.667 46.933zM878.933 482.133c4.267-12.8 0-21.333-8.533-29.867-34.133-51.2-64-98.133-98.133-149.333-76.8-115.2-153.6-234.667-230.4-349.867-12.8-17.067-21.333-21.333-38.4-8.533-115.2 76.8-226.133 149.333-337.067 226.133-17.067 8.533-17.067 21.333-8.533 38.4 12.8 21.333 29.867 46.933 42.667 68.267 8.533 12.8 8.533 12.8 17.067 0 55.467-55.467 115.2-115.2 170.667-170.667 8.533-8.533 17.067-17.067 29.867-21.333 29.867-12.8 55.467-4.267 76.8 21.333 123.733 123.733 247.467 247.467 371.2 371.2 4.267 4.267 4.267 8.533 8.533 12.8 0-8.533 0-8.533 4.267-8.533z" />
|
||||
<glyph unicode="" glyph-name="tax" d="M448 192c0 174.933 145.067 320 320 320 76.8 0 145.067-25.6 196.267-68.267v324.267c4.267 51.2-38.4 98.133-93.867 98.133h-204.8c-21.333 55.467-72.533 93.867-136.533 93.867s-115.2-38.4-136.533-98.133h-209.067c-55.467 0-98.133-42.667-98.133-93.867v-674.133c0-51.2 42.667-98.133 98.133-98.133h332.8c-42.667 55.467-68.267 123.733-68.267 196.267zM529.067 861.867c29.867 0 46.933-21.333 46.933-46.933 0-29.867-25.6-46.933-46.933-46.933-29.867 0-46.933 21.333-46.933 46.933-4.267 29.867 17.067 46.933 46.933 46.933zM708.267 247.467c-8.533 0-12.8 4.267-17.067 8.533s-8.533 8.533-8.533 17.067v17.067c0 8.533 0 12.8 4.267 17.067s8.533 8.533 17.067 8.533c8.533 0 12.8-4.267 17.067-8.533s4.267-12.8 4.267-17.067v-12.8c4.267-21.333-4.267-29.867-17.067-29.867zM870.4 132.267c4.267-4.267 4.267-12.8 4.267-17.067v-21.333c0-12.8-8.533-21.333-21.333-21.333-8.533 0-12.8 4.267-17.067 8.533s-8.533 12.8-8.533 17.067v17.067c0 8.533 4.267 12.8 8.533 17.067s8.533 8.533 17.067 8.533c8.533 0 12.8-4.267 17.067-8.533zM768 448c-140.8 0-256-115.2-256-256s115.2-256 256-256 256 115.2 256 256-115.2 256-256 256zM635.733 273.067v17.067c0 21.333 4.267 34.133 17.067 46.933s29.867 17.067 51.2 17.067c21.333 0 38.4-4.267 51.2-17.067s17.067-29.867 17.067-46.933v-17.067c0-21.333-4.267-34.133-17.067-46.933s-29.867-17.067-51.2-17.067-38.4 4.267-51.2 17.067c-8.533 12.8-17.067 29.867-17.067 46.933zM721.067 59.733l-34.133 17.067 153.6 243.2 34.133-17.067-153.6-243.2zM925.867 98.133c0-21.333-4.267-34.133-17.067-46.933s-29.867-17.067-51.2-17.067-38.4 4.267-51.2 17.067c-12.8 12.8-21.333 25.6-21.333 46.933v17.067c0 21.333 4.267 34.133 17.067 46.933s29.867 17.067 51.2 17.067 38.4-4.267 51.2-17.067c12.8-12.8 17.067-29.867 17.067-46.933v-17.067h4.267z" />
|
||||
<glyph unicode="" glyph-name="thermometer" d="M641.567 326.792v35.527h64.784v25.078h-64.784v119.118h64.784v25.078h-64.784v119.118h64.784v25.078h-64.784v121.208h64.784v25.078h-64.784v8.359c0 71.053-58.514 129.567-129.567 129.567s-129.567-58.514-129.567-129.567v-503.641c-54.335-39.706-87.771-104.49-87.771-173.453 0-119.118 96.131-217.339 217.339-217.339 119.118 0 217.339 96.131 217.339 217.339 0 66.873-33.437 131.657-87.771 173.453zM512-28.473c-100.31 0-179.722 81.502-179.722 179.722 0 64.784 33.437 123.298 87.771 154.645v524.539c0 50.155 41.796 91.951 91.951 91.951s91.951-41.796 91.951-91.951v-522.449c54.335-31.347 87.771-89.861 87.771-154.645 0-100.31-79.412-181.812-179.722-181.812zM652.016 435.461v25.078h35.527v-25.078h-35.527zM652.016 579.657v25.078h35.527v-25.078h-35.527zM652.016 723.853v25.078h35.527v-25.078h-35.527zM568.424 284.996v543.347c0 0 0 0 0 0s0 0 0 0v0 0c0 31.347-25.078 56.424-56.424 56.424s-56.424-25.078-56.424-56.424v0-543.347c-52.245-20.898-87.771-73.143-87.771-131.657 0-79.412 64.784-144.196 144.196-144.196s144.196 64.784 144.196 144.196c0 58.514-35.527 108.669-87.771 131.657zM470.204 824.163v4.18c0 22.988 18.808 41.796 41.796 41.796s41.796-18.808 41.796-41.796v-219.429h-85.682v215.249z" />
|
||||
|
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 186 KiB |
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,10 @@
|
|||
@font-face {
|
||||
font-family: 'icon';
|
||||
src: url('fonts/icon.eot?7j3xju');
|
||||
src: url('fonts/icon.eot?7j3xju#iefix') format('embedded-opentype'),
|
||||
url('fonts/icon.ttf?7j3xju') format('truetype'),
|
||||
url('fonts/icon.woff?7j3xju') format('woff'),
|
||||
url('fonts/icon.svg?7j3xju#icon') format('svg');
|
||||
src: url('fonts/icon.eot?uocffs');
|
||||
src: url('fonts/icon.eot?uocffs#iefix') format('embedded-opentype'),
|
||||
url('fonts/icon.ttf?uocffs') format('truetype'),
|
||||
url('fonts/icon.woff?uocffs') format('woff'),
|
||||
url('fonts/icon.svg?uocffs#icon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
|
@ -25,6 +25,9 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-inactive-car:before {
|
||||
content: "\e978";
|
||||
}
|
||||
.icon-hasItemLost:before {
|
||||
content: "\e957";
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// import { useI18n } from 'vue-i18n';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
export default function (value, symbol = 'EUR', fractionSize = 2) {
|
||||
if (value == null || value === '') value = 0;
|
||||
|
||||
// const { locale } = useI18n(); // sacar en el boot, cuando se añade al user. Y aqui usarlo
|
||||
const { locale } = useI18n();
|
||||
|
||||
const options = {
|
||||
style: 'currency',
|
||||
|
@ -12,7 +12,7 @@ export default function (value, symbol = 'EUR', fractionSize = 2) {
|
|||
maximumFractionDigits: fractionSize,
|
||||
};
|
||||
|
||||
const lang = 'de';
|
||||
const lang = locale.value == 'es' ? 'de' : locale.value;
|
||||
|
||||
return new Intl.NumberFormat(lang, options).format(value);
|
||||
}
|
||||
|
|
|
@ -2,9 +2,8 @@ globals:
|
|||
lang:
|
||||
es: Spanish
|
||||
en: English
|
||||
foreignCurrency: Foreign currency
|
||||
quantity: Quantity
|
||||
language: Language
|
||||
quantity: Quantity
|
||||
entity: Entity
|
||||
preview: Preview
|
||||
user: User
|
||||
|
@ -136,7 +135,6 @@ globals:
|
|||
medium: Medium
|
||||
big: Big
|
||||
email: Email
|
||||
currency: Currency
|
||||
supplier: Supplier
|
||||
ticketList: Ticket List
|
||||
created: Created
|
||||
|
@ -328,6 +326,7 @@ globals:
|
|||
ticketsMonitor: Tickets monitor
|
||||
clientsActionsMonitor: Clients and actions
|
||||
serial: Serial
|
||||
business: Business
|
||||
medical: Mutual
|
||||
pit: IRPF
|
||||
wasteRecalc: Waste recaclulate
|
||||
|
@ -511,6 +510,24 @@ department:
|
|||
hasToSendMail: Send check-ins by email
|
||||
departmentRemoved: Department removed
|
||||
worker:
|
||||
pageTitles:
|
||||
workers: Workers
|
||||
list: List
|
||||
basicData: Basic data
|
||||
summary: Summary
|
||||
notifications: Notifications
|
||||
workerCreate: New worker
|
||||
department: Department
|
||||
pda: PDA
|
||||
notes: Notas
|
||||
dms: My documentation
|
||||
pbx: Private Branch Exchange
|
||||
log: Log
|
||||
calendar: Calendar
|
||||
timeControl: Time control
|
||||
locker: Locker
|
||||
balance: Balance
|
||||
medical: Medical
|
||||
list:
|
||||
department: Department
|
||||
schedule: Schedule
|
||||
|
@ -526,15 +543,24 @@ worker:
|
|||
role: Role
|
||||
sipExtension: Extension
|
||||
locker: Locker
|
||||
fiDueDate: FI due date
|
||||
fiDueDate: DNI expiration date
|
||||
sex: Sex
|
||||
seniority: Seniority
|
||||
seniority: Antiquity
|
||||
fi: DNI/NIE/NIF
|
||||
birth: Birth
|
||||
isFreelance: Freelance
|
||||
isSsDiscounted: SS Bonification
|
||||
hasMachineryAuthorized: Machinery authorized
|
||||
isDisable: Disable
|
||||
business: Business
|
||||
started: Started
|
||||
ended: Ended
|
||||
reasonEnd: Reason End
|
||||
department: Departament
|
||||
workerBusinessCategory: Worker Business Category
|
||||
notes: Notes
|
||||
workCenter: Center
|
||||
professionalCategory: Professional Category
|
||||
notificationsManager:
|
||||
activeNotifications: Active notifications
|
||||
availableNotifications: Available notifications
|
||||
|
@ -593,6 +619,23 @@ worker:
|
|||
sizeLimit: Size limit
|
||||
isOnReservationMode: Reservation mode
|
||||
machine: Machine
|
||||
business:
|
||||
tableVisibleColumns:
|
||||
started: Start Date
|
||||
ended: End Date
|
||||
company: Company
|
||||
reasonEnd: Reason for Termination
|
||||
department: Department
|
||||
professionalCategory: Professional Category
|
||||
calendarType: Work Calendar
|
||||
workCenter: Work Center
|
||||
payrollCategories: Contract Category
|
||||
occupationCode: Contribution Code
|
||||
rate: Rate
|
||||
businessType: Contract Type
|
||||
amount: Salary
|
||||
basicSalary: Transport Workers Salary
|
||||
notes: Notes
|
||||
wagon:
|
||||
type:
|
||||
submit: Submit
|
||||
|
|
|
@ -2,7 +2,6 @@ globals:
|
|||
lang:
|
||||
es: Español
|
||||
en: Inglés
|
||||
foreignCurrency: Moneda extranjera
|
||||
language: Idioma
|
||||
quantity: Cantidad
|
||||
entity: Entidad
|
||||
|
@ -136,7 +135,6 @@ globals:
|
|||
medium: Mediano/a
|
||||
big: Grande
|
||||
email: Correo
|
||||
currency: Moneda
|
||||
supplier: Proveedor
|
||||
ticketList: Listado de tickets
|
||||
created: Fecha creación
|
||||
|
@ -328,6 +326,7 @@ globals:
|
|||
ticketsMonitor: Monitor de tickets
|
||||
clientsActionsMonitor: Clientes y acciones
|
||||
serial: Facturas por serie
|
||||
business: Contratos
|
||||
medical: Mutua
|
||||
pit: IRPF
|
||||
wasteRecalc: Recalcular mermas
|
||||
|
@ -483,6 +482,26 @@ department:
|
|||
hasToSendMail: Enviar fichadas por mail
|
||||
departmentRemoved: Departamento eliminado
|
||||
worker:
|
||||
pageTitles:
|
||||
workers: Trabajadores
|
||||
list: Listado
|
||||
basicData: Datos básicos
|
||||
summary: Resumen
|
||||
notifications: Notificaciones
|
||||
workerCreate: Nuevo trabajador
|
||||
department: Departamentos
|
||||
pda: PDA
|
||||
notes: Notas
|
||||
dms: Mi documentación
|
||||
pbx: Centralita
|
||||
log: Historial
|
||||
calendar: Calendario
|
||||
timeControl: Control de horario
|
||||
locker: Taquilla
|
||||
balance: Balance
|
||||
business: Contrato
|
||||
formation: Formación
|
||||
medical: Mutua
|
||||
list:
|
||||
department: Departamento
|
||||
schedule: Horario
|
||||
|
@ -507,6 +526,15 @@ worker:
|
|||
isSsDiscounted: Bonificación SS
|
||||
hasMachineryAuthorized: Autorizado para maquinaria
|
||||
isDisable: Deshabilitado
|
||||
business: Contrato
|
||||
started: Antigüedad
|
||||
ended: Fin
|
||||
reasonEnd: Motivo finalización
|
||||
department: Departamento
|
||||
workerBusinessCategory: Categoria profesional
|
||||
notes: Notas
|
||||
workCenter: Centro
|
||||
professionalCategory: Categoria profesional
|
||||
notificationsManager:
|
||||
activeNotifications: Notificaciones activas
|
||||
availableNotifications: Notificaciones disponibles
|
||||
|
@ -553,6 +581,23 @@ worker:
|
|||
debit: Debe
|
||||
credit: Haber
|
||||
concept: Concepto
|
||||
business:
|
||||
tableVisibleColumns:
|
||||
started: Fecha inicio
|
||||
ended: Fecha fin
|
||||
company: Empresa
|
||||
reasonEnd: Motivo finalización
|
||||
department: Departamento
|
||||
professionalCategory: Categoria profesional
|
||||
calendarType: Calendario laboral
|
||||
workCenter: Centro
|
||||
payrollCategories: Categoria contrato
|
||||
occupationCode: Cotización
|
||||
rate: Tarifa
|
||||
businessType: Contrato
|
||||
amount: Salario
|
||||
basicSalary: Salario transportistas
|
||||
notes: Notas
|
||||
operator:
|
||||
numberOfWagons: Número de vagones
|
||||
train: tren
|
||||
|
@ -565,7 +610,6 @@ worker:
|
|||
sizeLimit: Tamaño límite
|
||||
isOnReservationMode: Modo de reserva
|
||||
machine: Máquina
|
||||
|
||||
wagon:
|
||||
type:
|
||||
submit: Guardar
|
||||
|
|
|
@ -10,8 +10,6 @@ import VnInput from 'src/components/common/VnInput.vue';
|
|||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
|
||||
import { getDifferences, getUpdatedValues } from 'src/filters';
|
||||
import VnSelectCompany from 'src/components/common/VnSelectCompany.vue';
|
||||
import VnSelectCurrency from 'src/components/common/VnSelectCurrency.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
@ -39,7 +37,7 @@ const exprBuilder = (param, value) => {
|
|||
function onBeforeSave(formData, originalData) {
|
||||
return getUpdatedValues(
|
||||
Object.keys(getDifferences(formData, originalData)),
|
||||
formData,
|
||||
formData
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
@ -144,10 +142,6 @@ function onBeforeSave(formData, originalData) {
|
|||
:input-debounce="0"
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnSelectCompany v-model="data.defaultCompanyFk" />
|
||||
<VnSelectCurrency v-model="data.defaultCurrencyFk" />
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
url="Clients"
|
||||
|
@ -166,7 +160,7 @@ function onBeforeSave(formData, originalData) {
|
|||
<QIcon name="info" class="cursor-pointer">
|
||||
<QTooltip>{{
|
||||
t(
|
||||
'In case of a company succession, specify the grantor company',
|
||||
'In case of a company succession, specify the grantor company'
|
||||
)
|
||||
}}</QTooltip>
|
||||
</QIcon>
|
||||
|
|
|
@ -15,7 +15,6 @@ import InvoiceOutDescriptorProxy from 'pages/InvoiceOut/Card/InvoiceOutDescripto
|
|||
import RouteDescriptorProxy from 'src/pages/Route/Card/RouteDescriptorProxy.vue';
|
||||
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||
import CustomerDescriptorProxy from '../Card/CustomerDescriptorProxy.vue';
|
||||
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
@ -43,7 +42,6 @@ const filter = {
|
|||
},
|
||||
},
|
||||
},
|
||||
{ relation: 'currency' },
|
||||
],
|
||||
where: { clientFk: route.params.id },
|
||||
order: ['shipped DESC', 'id'],
|
||||
|
@ -215,19 +213,9 @@ const getItemPackagingType = (ticketSales) => {
|
|||
:color="setTotalPriceColor(row)"
|
||||
text-color="black"
|
||||
>
|
||||
<VnCurrency
|
||||
:model="row"
|
||||
local-field="totalWithVat"
|
||||
:currency-code="row.currency.code"
|
||||
/>
|
||||
{{ toCurrency(row.totalWithVat) }}
|
||||
</QBadge>
|
||||
<span v-else>
|
||||
<VnCurrency
|
||||
:model="row"
|
||||
local-field="totalWithVat"
|
||||
:currency-code="row.currency.code"
|
||||
/>
|
||||
</span>
|
||||
<span v-else> {{ toCurrency(row.totalWithVat) }}</span>
|
||||
</template>
|
||||
<template #column-state="{ row }">
|
||||
<span v-if="row.invoiceOut" @click.stop>
|
||||
|
|
|
@ -10,4 +10,4 @@ import DepartmentDescriptor from 'pages/Department/Card/DepartmentDescriptor.vue
|
|||
base-url="Departments"
|
||||
:descriptor="DepartmentDescriptor"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
|
|
|
@ -12,6 +12,7 @@ import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
|
|||
import FilterTravelForm from 'src/components/FilterTravelForm.vue';
|
||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||
import { toDate } from 'src/filters';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
@ -51,28 +52,12 @@ const onFilterTravelSelected = (formData, id) => {
|
|||
>
|
||||
<template #form="{ data }">
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
:label="t('globals.supplier')"
|
||||
<VnSelectSupplier
|
||||
v-model="data.supplierFk"
|
||||
url="Suppliers"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
:fields="['id', 'nickname']"
|
||||
hide-selected
|
||||
:required="true"
|
||||
map-options
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ scope.opt?.nickname }}, {{ scope.opt?.id }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
/>
|
||||
<VnSelectDialog
|
||||
:label="t('entry.basicData.travel')"
|
||||
v-model="data.travelFk"
|
||||
|
|
|
@ -13,6 +13,7 @@ import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
|||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { useState } from 'src/composables/useState';
|
||||
import { toDate } from 'src/filters';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const state = useState();
|
||||
const { t } = useI18n();
|
||||
|
@ -26,7 +27,6 @@ const newEntryForm = reactive({
|
|||
travelFk: Number(route.query?.travelFk) || null,
|
||||
companyFk: user.value.companyFk || null,
|
||||
});
|
||||
const suppliersOptions = ref([]);
|
||||
const travelsOptions = ref([]);
|
||||
const companiesOptions = ref([]);
|
||||
|
||||
|
@ -36,13 +36,6 @@ const redirectToEntryBasicData = (_, { id }) => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
url="Suppliers"
|
||||
:filter="{ fields: ['id', 'nickname'] }"
|
||||
order="nickname"
|
||||
@on-fetch="(data) => (suppliersOptions = data)"
|
||||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
url="Travels/filter"
|
||||
:filter="{ fields: ['id', 'warehouseInName'] }"
|
||||
|
@ -79,28 +72,13 @@ const redirectToEntryBasicData = (_, { id }) => {
|
|||
>
|
||||
<template #form="{ data, validate }">
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
:label="t('Supplier')"
|
||||
<VnSelectSupplier
|
||||
class="full-width"
|
||||
v-model="data.supplierFk"
|
||||
:options="suppliersOptions"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
hide-selected
|
||||
:required="true"
|
||||
:rules="validate('entry.supplierFk')"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ scope.opt?.nickname }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
#{{ scope.opt?.id }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
|
@ -152,7 +130,6 @@ const redirectToEntryBasicData = (_, { id }) => {
|
|||
|
||||
<i18n>
|
||||
es:
|
||||
Supplier: Proveedor
|
||||
Travel: Envío
|
||||
Company: Empresa
|
||||
</i18n>
|
||||
|
|
|
@ -7,6 +7,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
|
|||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
|
@ -115,34 +116,14 @@ const companiesOptions = ref([]);
|
|||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('entryFilter.params.supplierFk')"
|
||||
<VnSelectSupplier
|
||||
v-model="params.supplierFk"
|
||||
@update:model-value="searchFn()"
|
||||
url="Suppliers"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
:fields="['id', 'name', 'nickname']"
|
||||
:filter-options="['id', 'name', 'nickname']"
|
||||
sort-by="nickname"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>
|
||||
{{ scope.opt?.name}}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ `#${scope.opt?.id } , ${ scope.opt?.nickname}` }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
|
@ -202,4 +183,4 @@ const companiesOptions = ref([]);
|
|||
</QItem>
|
||||
</template>
|
||||
</VnFilterPanel>
|
||||
</template>
|
||||
</template>
|
||||
|
|
|
@ -7,6 +7,7 @@ import VnInputDate from 'src/components/common/VnInputDate.vue';
|
|||
import VnInput from 'components/common/VnInput.vue';
|
||||
import VnSelect from 'components/common/VnSelect.vue';
|
||||
import ItemsFilterPanel from 'src/components/ItemsFilterPanel.vue';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -18,7 +19,6 @@ defineProps({
|
|||
});
|
||||
|
||||
const itemTypeWorkersOptions = ref([]);
|
||||
const suppliersOptions = ref([]);
|
||||
const tagValues = ref([]);
|
||||
</script>
|
||||
|
||||
|
@ -30,13 +30,6 @@ const tagValues = ref([]);
|
|||
:filter="{ fields: ['id', 'nickname'], order: 'nickname ASC', limit: 30 }"
|
||||
@on-fetch="(data) => (itemTypeWorkersOptions = data)"
|
||||
/>
|
||||
<FetchData
|
||||
url="Suppliers"
|
||||
limit="30"
|
||||
auto-load
|
||||
:filter="{ fields: ['id', 'name', 'nickname'], order: 'name ASC', limit: 30 }"
|
||||
@on-fetch="(data) => (suppliersOptions = data)"
|
||||
/>
|
||||
<ItemsFilterPanel :data-key="dataKey" :custom-tags="['tags']">
|
||||
<template #body="{ params, searchFn }">
|
||||
<QItem class="q-my-md">
|
||||
|
@ -57,31 +50,14 @@ const tagValues = ref([]);
|
|||
</QItem>
|
||||
<QItem class="q-my-md">
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('globals.params.supplierFk')"
|
||||
<VnSelectSupplier
|
||||
v-model="params.supplierFk"
|
||||
:options="suppliersOptions"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
@update:model-value="searchFn()"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
use-input
|
||||
@update:model-value="searchFn()"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>
|
||||
{{ scope.opt?.name}}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ `#${scope.opt?.id } , ${ scope.opt?.nickname}` }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-my-md">
|
||||
|
|
|
@ -13,6 +13,7 @@ import VnInput from 'src/components/common/VnInput.vue';
|
|||
import VnDms from 'src/components/common/VnDms.vue';
|
||||
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||
import axios from 'axios';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -115,27 +116,12 @@ function deleteFile(dmsFk) {
|
|||
>
|
||||
<template #form="{ data }">
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
:required="true"
|
||||
:label="t('supplierFk')"
|
||||
<VnSelectSupplier
|
||||
v-model="data.supplierFk"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
url="Suppliers"
|
||||
:fields="['id', 'nickname']"
|
||||
sort-by="nickname"
|
||||
hide-selected
|
||||
:is-clearable="false"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{
|
||||
`${scope.opt.id} - ${scope.opt.nickname}`
|
||||
}}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
:required="true"
|
||||
/>
|
||||
<VnInput
|
||||
clearable
|
||||
clear-icon="close"
|
||||
|
|
|
@ -226,6 +226,7 @@ const createInvoiceInCorrection = async () => {
|
|||
v-ripple
|
||||
clickable
|
||||
@click="triggerMenu('correct')"
|
||||
data-cy="createCorrectiveItem"
|
||||
>
|
||||
<QItemSection
|
||||
>{{ t('invoiceIn.descriptorMenu.createCorrective') }}...</QItemSection
|
||||
|
|
|
@ -12,6 +12,7 @@ import { useStateStore } from 'stores/useStateStore';
|
|||
import { useState } from 'src/composables/useState';
|
||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const state = useState();
|
||||
const { t } = useI18n();
|
||||
|
@ -60,28 +61,12 @@ const redirectToInvoiceInBasicData = (__, { id }) => {
|
|||
>
|
||||
<template #form="{ data, validate }">
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
url="Suppliers"
|
||||
:fields="['id', 'nickname']"
|
||||
:label="t('Supplier')"
|
||||
<VnSelectSupplier
|
||||
v-model="data.supplierFk"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
hide-selected
|
||||
:required="true"
|
||||
:rules="validate('entry.supplierFk')"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ scope.opt?.nickname }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
#{{ scope.opt?.id }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
/>
|
||||
<VnInput
|
||||
:label="t('invoiceIn.list.supplierRef')"
|
||||
v-model="data.supplierRef"
|
||||
|
@ -111,7 +96,6 @@ const redirectToInvoiceInBasicData = (__, { id }) => {
|
|||
|
||||
<i18n>
|
||||
es:
|
||||
Supplier: Proveedor
|
||||
Travel: Envío
|
||||
Company: Empresa
|
||||
</i18n>
|
||||
|
|
|
@ -6,6 +6,7 @@ import VnInputDate from 'components/common/VnInputDate.vue';
|
|||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||
import { dateRange } from 'src/filters';
|
||||
import { date } from 'quasar';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
defineProps({ dataKey: { type: String, required: true } });
|
||||
const dateFormat = 'YYYY-MM-DDTHH:mm:ss.SSSZ';
|
||||
|
@ -65,29 +66,12 @@ function handleDaysAgo(params, daysAgo) {
|
|||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
<VnSelectSupplier
|
||||
v-model="params.supplierFk"
|
||||
url="Suppliers"
|
||||
:fields="['id', 'nickname', 'name']"
|
||||
:label="getLocale('supplierFk')"
|
||||
option-label="nickname"
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>
|
||||
{{ scope.opt?.name}}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ `#${scope.opt?.id } , ${ scope.opt?.nickname}` }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
|
|
|
@ -14,6 +14,7 @@ import VnInput from 'src/components/common/VnInput.vue';
|
|||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||
import FetchData from 'src/components/FetchData.vue';
|
||||
import VnSection from 'src/components/common/VnSection.vue';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const user = useState().getUser();
|
||||
const { viewSummary } = useSummaryDialog();
|
||||
|
@ -148,7 +149,9 @@ const cols = computed(() => [
|
|||
<template #body>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
:data-key
|
||||
data-key="InvoiceInList"
|
||||
url="InvoiceIns/filter"
|
||||
:order="['issued DESC', 'id DESC']"
|
||||
:create="{
|
||||
urlCreate: 'InvoiceIns',
|
||||
title: t('globals.createInvoiceIn'),
|
||||
|
@ -168,29 +171,13 @@ const cols = computed(() => [
|
|||
</span>
|
||||
</template>
|
||||
<template #more-create-dialog="{ data }">
|
||||
<VnSelect
|
||||
<VnSelectSupplier
|
||||
v-model="data.supplierFk"
|
||||
url="Suppliers"
|
||||
:fields="['id', 'name', 'nickname']"
|
||||
:label="t('globals.supplier')"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
:filter-options="['id', 'name', 'nickname']"
|
||||
hide-selected
|
||||
:required="true"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ scope.opt?.nickname }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
#{{ scope.opt?.id }}, {{ scope.opt?.name }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
/>
|
||||
<VnInput
|
||||
:label="t('invoiceIn.list.supplierRef')"
|
||||
:label="t('invoicein.list.supplierRef')"
|
||||
v-model="data.supplierRef"
|
||||
/>
|
||||
<VnSelect
|
||||
|
@ -203,7 +190,7 @@ const cols = computed(() => [
|
|||
:required="true"
|
||||
/>
|
||||
<VnInputDate
|
||||
:label="t('invoiceIn.summary.issued')"
|
||||
:label="t('invoicein.summary.issued')"
|
||||
v-model="data.issued"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -368,7 +368,7 @@ watchEffect(selectedRows);
|
|||
<VnSelect
|
||||
url="InvoiceOutSerials"
|
||||
v-model="data.serial"
|
||||
:label="t('invoicein.serial')"
|
||||
:label="t('invoiceOutModule.serial')"
|
||||
:options="invoiceOutSerialsOptions"
|
||||
option-label="description"
|
||||
option-value="code"
|
||||
|
|
|
@ -60,6 +60,7 @@ invoiceOutModule:
|
|||
amount: Amount
|
||||
company: Company
|
||||
address: Address
|
||||
serial: Serial
|
||||
invoiceOutList:
|
||||
tableVisibleColumns:
|
||||
id: ID
|
||||
|
@ -70,4 +71,4 @@ invoiceOutList:
|
|||
invoiceOutSerial: Serial
|
||||
ticket: Ticket
|
||||
taxArea: Tax area
|
||||
customsAgent: Custom Agent
|
||||
customsAgent: Custom Agent
|
||||
|
|
|
@ -11,7 +11,7 @@ invoiceOut:
|
|||
isActive: Activo
|
||||
hasToInvoice: Debe facturar
|
||||
hasVerifiedData: Datos verificados
|
||||
workerName: Comercial
|
||||
workerName: Comercial
|
||||
card:
|
||||
issued: Fecha emisión
|
||||
customerCard: Ficha del cliente
|
||||
|
@ -54,12 +54,13 @@ invoiceOut:
|
|||
verifiedData: Datos comprobados
|
||||
comercial: Comercial
|
||||
errors:
|
||||
downloadCsvFailed: Error al descargar CSV
|
||||
downloadCsvFailed: Error al descargar CSV
|
||||
invoiceOutModule:
|
||||
customer: Cliente
|
||||
amount: Importe
|
||||
company: Empresa
|
||||
address: Consignatario
|
||||
serial: Serie
|
||||
invoiceOutList:
|
||||
tableVisibleColumns:
|
||||
id: ID
|
||||
|
@ -70,4 +71,4 @@ invoiceOutList:
|
|||
invoiceOutSerial: Serial
|
||||
ticket: Ticket
|
||||
taxArea: Area
|
||||
customsAgent: Agente de aduanas
|
||||
customsAgent: Agente de aduanas
|
||||
|
|
|
@ -12,6 +12,7 @@ import { QCheckbox } from 'quasar';
|
|||
import { useArrayData } from 'composables/useArrayData';
|
||||
import { useValidator } from 'src/composables/useValidator';
|
||||
import axios from 'axios';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -246,34 +247,14 @@ onMounted(async () => {
|
|||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('params.supplierFk')"
|
||||
<VnSelectSupplier
|
||||
v-model="params.supplierFk"
|
||||
@update:model-value="searchFn()"
|
||||
url="Suppliers"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
:fields="['id', 'name', 'nickname']"
|
||||
:filter-options="['id', 'name', 'nickname']"
|
||||
sort-by="name ASC"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>
|
||||
{{ scope.opt?.name }}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ `#${scope.opt?.id} , ${scope.opt?.nickname}` }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<!-- Tags filter -->
|
||||
|
|
|
@ -5,6 +5,9 @@ import VnTable from 'components/VnTable/VnTable.vue';
|
|||
import FetchData from 'components/FetchData.vue';
|
||||
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
|
||||
import VnSection from 'src/components/common/VnSection.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
|
||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const tableRef = ref();
|
||||
|
@ -60,20 +63,17 @@ const columns = computed(() => [
|
|||
label: t('code'),
|
||||
isTitle: true,
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'name',
|
||||
label: t('globals.name'),
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('worker'),
|
||||
name: 'workerFk',
|
||||
create: true,
|
||||
component: 'select',
|
||||
attrs: {
|
||||
url: 'Workers/search',
|
||||
|
@ -100,7 +100,6 @@ const columns = computed(() => [
|
|||
align: 'left',
|
||||
name: 'categoryFk',
|
||||
label: t('ItemCategory'),
|
||||
create: true,
|
||||
component: 'select',
|
||||
attrs: {
|
||||
options: itemCategoriesOptions.value,
|
||||
|
@ -112,7 +111,6 @@ const columns = computed(() => [
|
|||
align: 'left',
|
||||
name: 'Temperature',
|
||||
label: t('Temperature'),
|
||||
create: true,
|
||||
component: 'select',
|
||||
attrs: {
|
||||
options: temperatureOptions.value,
|
||||
|
@ -180,6 +178,29 @@ const columns = computed(() => [
|
|||
<WorkerDescriptorProxy :id="row.workerFk" />
|
||||
</span>
|
||||
</template>
|
||||
<template #more-create-dialog="{ data }">
|
||||
<VnInput v-model="data.code" :label="t('code')" data-cy="codeInput" />
|
||||
<VnInput
|
||||
v-model="data.name"
|
||||
:label="t('globals.name')"
|
||||
data-cy="nameInput"
|
||||
/>
|
||||
<VnSelectWorker v-model="data.workerFk" />
|
||||
<VnSelect
|
||||
:label="t('ItemCategory')"
|
||||
v-model="data.categoryFk"
|
||||
:options="itemCategoriesOptions"
|
||||
hide-selected
|
||||
data-cy="itemCategorySelect"
|
||||
/>
|
||||
<VnSelect
|
||||
:label="t('Temperature')"
|
||||
v-model="data.temperatureFk"
|
||||
:options="temperatureOptions"
|
||||
hide-selected
|
||||
data-cy="temperatureSelect"
|
||||
/>
|
||||
</template>
|
||||
</VnTable>
|
||||
</template>
|
||||
</VnSection>
|
||||
|
|
|
@ -10,13 +10,11 @@ import VnSelect from 'components/common/VnSelect.vue';
|
|||
import VnInput from 'components/common/VnInput.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||
import VnSelectCompany from 'src/components/common/VnSelectCompany.vue';
|
||||
import VnSelectCurrency from 'src/components/common/VnSelectCurrency.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const state = useState();
|
||||
const ORDER_MODEL = 'Order';
|
||||
const ORDER_MODEL = 'order';
|
||||
|
||||
const isNew = Boolean(!route.params.id);
|
||||
const clientList = ref([]);
|
||||
|
@ -56,6 +54,33 @@ const fetchOrderDetails = (order) => {
|
|||
fetchAgencyList(order?.landed, order?.addressFk);
|
||||
};
|
||||
|
||||
const orderFilter = {
|
||||
include: [
|
||||
{ relation: 'agencyMode', scope: { fields: ['name'] } },
|
||||
{
|
||||
relation: 'address',
|
||||
scope: { fields: ['nickname'] },
|
||||
},
|
||||
{ relation: 'rows', scope: { fields: ['id'] } },
|
||||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: [
|
||||
'salesPersonFk',
|
||||
'name',
|
||||
'isActive',
|
||||
'isFreezed',
|
||||
'isTaxDataChecked',
|
||||
],
|
||||
include: {
|
||||
relation: 'salesPersonUser',
|
||||
scope: { fields: ['id', 'name'] },
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const onClientChange = async (clientId) => {
|
||||
const { data } = await axios.get(`Clients/${clientId}`);
|
||||
await fetchAddressList(data.defaultAddressFk);
|
||||
|
@ -66,9 +91,12 @@ const onClientChange = async (clientId) => {
|
|||
<VnSubToolbar v-if="isNew" />
|
||||
<div class="q-pa-md">
|
||||
<FormModel
|
||||
:url="`Orders/${route.params.id}`"
|
||||
:url-update="`Orders/${route.params.id}/updateBasicData`"
|
||||
:model="ORDER_MODEL"
|
||||
:filter="orderFilter"
|
||||
@on-fetch="fetchOrderDetails"
|
||||
auto-load
|
||||
>
|
||||
<template #form="{ data }">
|
||||
<VnRow>
|
||||
|
@ -148,10 +176,6 @@ const onClientChange = async (clientId) => {
|
|||
"
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnSelectCompany v-model="data.companyFk" />
|
||||
<VnSelectCurrency v-model="data.currencyFk" />
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnInput
|
||||
:label="t('globals.notes')"
|
||||
|
|
|
@ -8,34 +8,5 @@ import OrderDescriptor from 'pages/Order/Card/OrderDescriptor.vue';
|
|||
data-key="Order"
|
||||
base-url="Orders"
|
||||
:descriptor="OrderDescriptor"
|
||||
:user-filter="{
|
||||
include: [
|
||||
{ relation: 'agencyMode', scope: { fields: ['name'] } },
|
||||
{
|
||||
relation: 'address',
|
||||
scope: { fields: ['nickname'] },
|
||||
},
|
||||
{ relation: 'rows', scope: { fields: ['id'] } },
|
||||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: [
|
||||
'salesPersonFk',
|
||||
'name',
|
||||
'isActive',
|
||||
'isFreezed',
|
||||
'isTaxDataChecked',
|
||||
],
|
||||
include: {
|
||||
relation: 'salesPersonUser',
|
||||
scope: { fields: ['id', 'name'] },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'currency',
|
||||
},
|
||||
],
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -22,7 +22,6 @@ const catalogParams = {
|
|||
};
|
||||
const arrayData = useArrayData(dataKey, {
|
||||
url: 'Orders/CatalogFilter',
|
||||
limit: 50,
|
||||
userParams: catalogParams,
|
||||
});
|
||||
const store = arrayData.store;
|
||||
|
@ -66,7 +65,7 @@ function extractValueTags(items) {
|
|||
.filter((k) => /^value\d+$/.test(k))
|
||||
.map((v) => x[v])
|
||||
.filter((v) => v)
|
||||
.sort()
|
||||
.sort(),
|
||||
);
|
||||
tagValue.value = resultValueTags;
|
||||
}
|
||||
|
@ -76,7 +75,7 @@ watch(
|
|||
(val) => {
|
||||
extractTags(val);
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
);
|
||||
</script>
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import { useRoute } from 'vue-router';
|
|||
import useNotify from 'composables/useNotify';
|
||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||
import { useState } from 'src/composables/useState';
|
||||
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const { notify } = useNotify();
|
||||
|
@ -74,10 +73,10 @@ const canAddToOrder = () => {
|
|||
<QMarkupTable class="shadow-0">
|
||||
<tbody>
|
||||
<tr v-for="price in prices" :key="price.warehouse">
|
||||
<td class="text-bold q-pr-md" style="width: 10%">
|
||||
<td class="text-bold q-pr-md td" style="width: 35%">
|
||||
{{ price.warehouse }}
|
||||
</td>
|
||||
<td class="text-right" style="width: 60%">
|
||||
<td class="text-right" style="width: 35%">
|
||||
<span
|
||||
class="link"
|
||||
@click.shift="
|
||||
|
@ -93,18 +92,12 @@ const canAddToOrder = () => {
|
|||
>
|
||||
{{ price.grouping }}
|
||||
</span>
|
||||
x
|
||||
<VnCurrency
|
||||
:model="price"
|
||||
array-data-model="Order"
|
||||
class="q-pr-sm"
|
||||
/>
|
||||
x {{ toCurrency(price.price) }}
|
||||
</td>
|
||||
<td style="width: 30%">
|
||||
<td class="text-right">
|
||||
<VnInputNumber
|
||||
v-model.number="price.quantity"
|
||||
:step="price.grouping"
|
||||
input-class="text-right"
|
||||
min="0"
|
||||
/>
|
||||
</td>
|
||||
|
@ -124,6 +117,12 @@ const canAddToOrder = () => {
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.td {
|
||||
width: 200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
noAmount: La cantidad no puede ser 0
|
||||
|
|
|
@ -10,7 +10,6 @@ import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
|||
import VnLv from 'src/components/ui/VnLv.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||
|
||||
const DEFAULT_ITEMS = 0;
|
||||
|
||||
|
@ -70,19 +69,19 @@ const getConfirmationValue = (isConfirmed) => {
|
|||
return t(isConfirmed ? 'globals.confirmed' : 'order.summary.notConfirmed');
|
||||
};
|
||||
|
||||
function setTotal(response) {
|
||||
total.value = response;
|
||||
state.set('orderTotal', response);
|
||||
}
|
||||
const orderTotal = computed(() => state.get('orderTotal') ?? {});
|
||||
const total = ref();
|
||||
const orderTotal = computed(() => state.get('orderTotal') ?? 0);
|
||||
const total = ref(0);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
ref="getTotalRef"
|
||||
:url="`Orders/${entityId}/getTotal`"
|
||||
@on-fetch="(response) => setTotal(response)"
|
||||
@on-fetch="
|
||||
(response) => {
|
||||
total = response;
|
||||
}
|
||||
"
|
||||
/>
|
||||
<CardDescriptor
|
||||
ref="descriptor"
|
||||
|
@ -114,16 +113,7 @@ const total = ref();
|
|||
:label="t('order.summary.items')"
|
||||
:value="(entity?.rows?.length || DEFAULT_ITEMS).toString()"
|
||||
/>
|
||||
<VnLv :label="t('order.summary.total')">
|
||||
<template #value>
|
||||
<VnCurrency
|
||||
:model="orderTotal"
|
||||
array-data-model="Order"
|
||||
local-field="total"
|
||||
foreign-field="foreignTotal"
|
||||
/>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('order.summary.total')" :value="toCurrency(orderTotal)" />
|
||||
</template>
|
||||
<template #actions="{ entity }">
|
||||
<QCardActions>
|
||||
|
|
|
@ -15,7 +15,6 @@ import VnImg from 'src/components/ui/VnImg.vue';
|
|||
import VnLv from 'src/components/ui/VnLv.vue';
|
||||
import FetchedTags from 'src/components/ui/FetchedTags.vue';
|
||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||
|
||||
const router = useRouter();
|
||||
|
@ -28,9 +27,7 @@ const tableLinesRef = ref();
|
|||
const order = ref();
|
||||
const orderSummary = ref({
|
||||
total: null,
|
||||
foreignTotal: null,
|
||||
vat: null,
|
||||
foreignVat: null,
|
||||
});
|
||||
const getTotalRef = ref();
|
||||
const getVATRef = ref();
|
||||
|
@ -93,14 +90,16 @@ const columns = computed(() => [
|
|||
},
|
||||
},
|
||||
columnFilter: false,
|
||||
cardVisible: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'id',
|
||||
label: t('lines.item'),
|
||||
chip: {
|
||||
condition: () => true,
|
||||
},
|
||||
isId: true,
|
||||
format: (row) => row?.item?.id,
|
||||
cardVisible: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
|
@ -156,12 +155,12 @@ const columns = computed(() => [
|
|||
name: 'price',
|
||||
label: t('lines.price'),
|
||||
cardVisible: true,
|
||||
format: (row) => toCurrency(row.price),
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'amount',
|
||||
label: t('lines.amount'),
|
||||
cardVisible: true,
|
||||
},
|
||||
{
|
||||
align: 'right',
|
||||
|
@ -239,7 +238,7 @@ watch(
|
|||
lineFilter.value.where.orderFk = router.currentRoute.value.params.id;
|
||||
|
||||
tableLinesRef.value.reload();
|
||||
},
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
|
@ -254,14 +253,14 @@ watch(
|
|||
ref="getTotalRef"
|
||||
:key="componentKey"
|
||||
:url="`Orders/${route.params.id}/getTotal`"
|
||||
@on-fetch="(data) => (orderSummary = { ...orderSummary, ...data })"
|
||||
@on-fetch="(data) => (orderSummary.total = data)"
|
||||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
ref="getVATRef"
|
||||
:key="componentKey"
|
||||
:url="`Orders/${route.params.id}/getVAT`"
|
||||
@on-fetch="(data) => (orderSummary = { ...orderSummary, ...data })"
|
||||
@on-fetch="(data) => (orderSummary.vat = data)"
|
||||
auto-load
|
||||
/>
|
||||
<RightMenu>
|
||||
|
@ -276,38 +275,12 @@ watch(
|
|||
<VnLv
|
||||
:label="t('subtotal') + ': '"
|
||||
:value="toCurrency(orderSummary.total - orderSummary.vat)"
|
||||
>
|
||||
<template #value>
|
||||
<VnCurrency
|
||||
:model="{
|
||||
price: orderSummary.total - orderSummary.vat,
|
||||
foreignPrice:
|
||||
orderSummary.foreignTotal - orderSummary.foreignVat,
|
||||
}"
|
||||
array-data-model="Order"
|
||||
/>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('VAT') + ': '">
|
||||
<template #value>
|
||||
<VnCurrency
|
||||
:model="orderSummary"
|
||||
array-data-model="Order"
|
||||
local-field="vat"
|
||||
foreign-field="foreignVat"
|
||||
/>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('total') + ': '">
|
||||
<template #value>
|
||||
<VnCurrency
|
||||
:model="orderSummary"
|
||||
array-data-model="Order"
|
||||
local-field="total"
|
||||
foreign-field="foreignTotal"
|
||||
/>
|
||||
</template>
|
||||
</VnLv>
|
||||
/>
|
||||
<VnLv :label="t('VAT') + ': '" :value="toCurrency(orderSummary?.vat)" />
|
||||
<VnLv
|
||||
:label="t('total') + ': '"
|
||||
:value="toCurrency(orderSummary?.total)"
|
||||
/>
|
||||
</QCard>
|
||||
</template>
|
||||
</RightMenu>
|
||||
|
@ -343,19 +316,10 @@ watch(
|
|||
{{ row?.item?.subName.toUpperCase() }}
|
||||
</div>
|
||||
</div>
|
||||
<FetchedTags :item="row?.item" :columns="3" />
|
||||
<FetchedTags :item="row?.item" />
|
||||
</template>
|
||||
<template #column-price="{ row }">
|
||||
<VnCurrency :model="row" array-data-model="Order" />
|
||||
</template>
|
||||
<template #column-amount="{ row: { price, quantity, foreignPrice } }">
|
||||
<VnCurrency
|
||||
:model="{
|
||||
price: price * quantity,
|
||||
foreignPrice: foreignPrice * quantity,
|
||||
}"
|
||||
array-data-model="Order"
|
||||
/>
|
||||
<template #column-amount="{ row }">
|
||||
{{ toCurrency(row.quantity * row.price) }}
|
||||
</template>
|
||||
<template #column-tableActions="{ row }">
|
||||
<QIcon
|
||||
|
|
|
@ -16,8 +16,6 @@ import VnTable from 'src/components/VnTable/VnTable.vue';
|
|||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
import VnSection from 'src/components/common/VnSection.vue';
|
||||
import VnSelectCurrency from 'src/components/common/VnSelectCurrency.vue';
|
||||
import VnSelectCompany from 'src/components/common/VnSelectCompany.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const { viewSummary } = useSummaryDialog();
|
||||
|
@ -155,7 +153,7 @@ onMounted(() => {
|
|||
|
||||
async function fetchClientAddress(id, formData = {}) {
|
||||
const { data } = await axios.get(
|
||||
`Clients/${id}/addresses?filter[order]=isActive DESC`,
|
||||
`Clients/${id}/addresses?filter[order]=isActive DESC`
|
||||
);
|
||||
addressOptions.value = data;
|
||||
formData.addressId = data.defaultAddressFk;
|
||||
|
@ -299,14 +297,6 @@ const getDateColor = (date) => {
|
|||
option-value="agencyModeFk"
|
||||
option-label="agencyMode"
|
||||
/>
|
||||
<VnSelectCompany
|
||||
v-model="data.companyId"
|
||||
v-model:client-id="data.clientFk"
|
||||
/>
|
||||
<VnSelectCurrency
|
||||
v-model="data.currencyId"
|
||||
v-model:client-id="data.clientFk"
|
||||
/>
|
||||
</template>
|
||||
</VnTable>
|
||||
</template>
|
||||
|
|
|
@ -6,6 +6,7 @@ import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
|
|||
import VnSelect from 'components/common/VnSelect.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import VnInput from 'components/common/VnInput.vue';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
|
@ -19,7 +20,6 @@ const emit = defineEmits(['search']);
|
|||
|
||||
const agencyList = ref([]);
|
||||
const agencyAgreementList = ref([]);
|
||||
const supplierList = ref([]);
|
||||
|
||||
const exprBuilder = (param, value) => {
|
||||
switch (param) {
|
||||
|
@ -58,14 +58,6 @@ const exprBuilder = (param, value) => {
|
|||
@on-fetch="(data) => (agencyAgreementList = data)"
|
||||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
url="Suppliers"
|
||||
:filter="{ fields: ['name'] }"
|
||||
sort-by="name ASC"
|
||||
limit="30"
|
||||
@on-fetch="(data) => (supplierList = data)"
|
||||
auto-load
|
||||
/>
|
||||
<VnFilterPanel
|
||||
:data-key="props.dataKey"
|
||||
:expr-builder="exprBuilder"
|
||||
|
@ -123,14 +115,12 @@ const exprBuilder = (param, value) => {
|
|||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-my-sm" v-if="supplierList">
|
||||
<QItem class="q-my-sm">
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
<VnSelectSupplier
|
||||
:label="t('Autonomous')"
|
||||
v-model="params.supplierFk"
|
||||
:options="supplierList"
|
||||
option-value="name"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
|
|
|
@ -6,29 +6,18 @@ import FormModel from 'components/FormModel.vue';
|
|||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import VnInput from 'components/common/VnInput.vue';
|
||||
import VnInputTime from 'components/common/VnInputTime.vue';
|
||||
import VnSelect from 'components/common/VnSelect.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import { ref } from 'vue';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const supplierList = ref([]);
|
||||
const filter = { include: [{ relation: 'supplier' }] };
|
||||
const onSave = (data, response) => {
|
||||
router.push({ name: 'RoadmapSummary', params: { id: response?.id } });
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<FetchData
|
||||
url="Suppliers"
|
||||
auto-load
|
||||
:filter="{ fields: ['id', 'nickname'] }"
|
||||
sort-by="nickname"
|
||||
limit="30"
|
||||
@on-fetch="(data) => (supplierList = data)"
|
||||
/>
|
||||
<FormModel
|
||||
:url="`Roadmaps/${route.params?.id}`"
|
||||
observe-form-changes
|
||||
|
@ -56,27 +45,14 @@ const onSave = (data, response) => {
|
|||
/>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
<VnSelectSupplier
|
||||
:label="t('Carrier')"
|
||||
v-model="data.supplierFk"
|
||||
:options="supplierList"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
emit-value
|
||||
map-options
|
||||
use-input
|
||||
:input-debounce="0"
|
||||
>
|
||||
<template #option="{ itemProps, opt }">
|
||||
<QItem v-bind="itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel
|
||||
>{{ opt.id }} - {{ opt.nickname }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
/>
|
||||
<VnInput
|
||||
v-model="data.price"
|
||||
:label="t('Price')"
|
||||
|
|
|
@ -3,9 +3,9 @@ import { ref } from 'vue';
|
|||
import { useI18n } from 'vue-i18n';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
|
||||
import VnSelect from 'components/common/VnSelect.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import VnInput from 'components/common/VnInput.vue';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
|
@ -16,19 +16,9 @@ const props = defineProps({
|
|||
});
|
||||
|
||||
const emit = defineEmits(['search']);
|
||||
|
||||
const supplierList = ref([]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
url="Suppliers"
|
||||
:filter="{ fields: ['id', 'nickname'] }"
|
||||
sort-by="nickname"
|
||||
limit="30"
|
||||
@on-fetch="(data) => (supplierList = data)"
|
||||
auto-load
|
||||
/>
|
||||
<VnFilterPanel
|
||||
:data-key="props.dataKey"
|
||||
:search-button="true"
|
||||
|
@ -71,14 +61,11 @@ const supplierList = ref([]);
|
|||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="supplierList" class="q-my-sm">
|
||||
<QItem class="q-my-sm">
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
<VnSelectSupplier
|
||||
:label="t('Carrier')"
|
||||
v-model="params.supplierFk"
|
||||
:options="supplierList"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
|
@ -86,17 +73,7 @@ const supplierList = ref([]);
|
|||
map-options
|
||||
use-input
|
||||
:input-debounce="0"
|
||||
>
|
||||
<template #option="{ itemProps, opt }">
|
||||
<QItem v-bind="itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel
|
||||
>{{ opt.id }} - {{ opt.nickname }}</QItemLabel
|
||||
>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-my-sm">
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
<script setup>
|
||||
import { computed, onBeforeMount, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
import tableFooter from 'src/components/VnTable/filters/tableFooter';
|
||||
import { dashIfEmpty, toCurrency, toDateHourMin } from 'src/filters';
|
||||
import { useState } from 'src/composables/useState';
|
||||
import { useStateStore } from 'src/stores/useStateStore';
|
||||
|
||||
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||
|
||||
import InvoiceInDescriptorProxy from 'src/pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue';
|
||||
import SupplierBalanceFilter from './SupplierBalanceFilter.vue';
|
||||
import { onMounted } from 'vue';
|
||||
import FetchData from 'src/components/FetchData.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const route = useRoute();
|
||||
const state = useState();
|
||||
const stateStore = useStateStore();
|
||||
const user = state.getUser();
|
||||
|
||||
const tableRef = ref();
|
||||
const companyId = ref();
|
||||
const companyUser = ref(user.value.companyFk);
|
||||
const balances = ref([]);
|
||||
const userParams = ref({
|
||||
supplierId: route.params.id,
|
||||
companyId: companyId.value ?? companyUser.value,
|
||||
isBooked: false,
|
||||
});
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
align: 'left',
|
||||
name: 'dated',
|
||||
label: t('Creation date'),
|
||||
format: ({ dated }) => toDateHourMin(dated),
|
||||
cardVisible: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'sref',
|
||||
label: t('Reference'),
|
||||
isTitle: true,
|
||||
class: 'extend',
|
||||
format: ({ sref }) => dashIfEmpty(sref),
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'bank',
|
||||
label: t('Bank'),
|
||||
cardVisible: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'invoiceEuros',
|
||||
label: t('Debit'),
|
||||
format: ({ invoiceEuros }) => toCurrency(invoiceEuros),
|
||||
isId: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'paymentEuros',
|
||||
label: t('Havings'),
|
||||
format: ({ paymentEuros }) => toCurrency(paymentEuros),
|
||||
cardVisible: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'euroBalance',
|
||||
label: t('Balance'),
|
||||
format: ({ euroBalance }) => toCurrency(euroBalance),
|
||||
cardVisible: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'isBooked',
|
||||
label: t('Conciliated'),
|
||||
cardVisible: true,
|
||||
},
|
||||
]);
|
||||
|
||||
onBeforeMount(() => {
|
||||
stateStore.rightDrawer = true;
|
||||
companyId.value = companyUser.value;
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
Object.assign(userParams, {
|
||||
supplierId: route.params.id,
|
||||
companyId: companyId.value ?? companyUser.value,
|
||||
isConciliated: false,
|
||||
});
|
||||
});
|
||||
|
||||
function setFooter(data) {
|
||||
const initialFooter = {
|
||||
invoiceEuros: 0,
|
||||
paymentEuros: 0,
|
||||
euroBalance: 0,
|
||||
};
|
||||
|
||||
tableRef.value.footer = tableFooter(initialFooter, data);
|
||||
}
|
||||
async function onFetch(data) {
|
||||
setFooter(data);
|
||||
return;
|
||||
}
|
||||
|
||||
function round(value) {
|
||||
return Math.round(value * 100) / 100;
|
||||
}
|
||||
const onFetchCurrencies = ([currency]) => {
|
||||
userParams.value.currencyFk = currency?.id;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QDrawer side="right" :width="265" v-model="stateStore.rightDrawer">
|
||||
<SupplierBalanceFilter data-key="SupplierBalance" />
|
||||
</QDrawer>
|
||||
<FetchData
|
||||
url="Currencies"
|
||||
:filter="{ fields: ['id', 'code'], where: { code: 'EUR' } }"
|
||||
sort-by="code"
|
||||
@on-fetch="onFetchCurrencies"
|
||||
auto-load
|
||||
/>
|
||||
<VnTable
|
||||
v-if="userParams.currencyFk"
|
||||
ref="tableRef"
|
||||
data-key="SupplierBalance"
|
||||
url="Suppliers/receipts"
|
||||
search-url="balance"
|
||||
:user-params="userParams"
|
||||
:columns="columns"
|
||||
:right-search="false"
|
||||
:is-editable="false"
|
||||
:column-search="false"
|
||||
@on-fetch="onFetch"
|
||||
:disable-option="{ card: true }"
|
||||
:footer="true"
|
||||
:order="['dated ASC']"
|
||||
data-cy="supplierBalanceTable"
|
||||
auto-load
|
||||
:map-key="false"
|
||||
>
|
||||
<template #column-balance="{ rowIndex }">
|
||||
{{ toCurrency(balances[rowIndex]?.balance) }}
|
||||
</template>
|
||||
<template #column-sref="{ row }">
|
||||
<span class="link" v-if="row.statementType === 'invoiceIn'">
|
||||
{{ dashIfEmpty(row.sref) }}
|
||||
<InvoiceInDescriptorProxy :id="row.id" />
|
||||
</span>
|
||||
<span v-else> {{ dashIfEmpty(row.sref) }}</span>
|
||||
</template>
|
||||
|
||||
<template #column-footer-invoiceEuros>
|
||||
<span>
|
||||
{{ toCurrency(round(tableRef.footer.invoiceEuros)) }}
|
||||
</span>
|
||||
</template>
|
||||
<template #column-footer-paymentEuros>
|
||||
<span>
|
||||
{{ toCurrency(round(tableRef.footer.paymentEuros)) }}
|
||||
</span>
|
||||
</template>
|
||||
<template #column-footer-euroBalance>
|
||||
<span>
|
||||
{{ toCurrency(round(tableRef.footer.euroBalance)) }}
|
||||
</span>
|
||||
</template>
|
||||
</VnTable>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Company: Empresa
|
||||
Total by company: Total por empresa
|
||||
Date: Fecha
|
||||
Creation date: Fecha de creación
|
||||
Reference: Referencia
|
||||
Bank: Caja
|
||||
Debit: Debe
|
||||
Havings: Haber
|
||||
Balance: Balance
|
||||
Conciliated: Conciliado
|
||||
</i18n>
|
|
@ -0,0 +1,121 @@
|
|||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
defineProps({
|
||||
dataKey: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnFilterPanel
|
||||
:data-key="dataKey"
|
||||
:search-button="true"
|
||||
:redirect="false"
|
||||
:unremovable-params="['supplierId', 'companyId']"
|
||||
>
|
||||
<template #tags="{ tag, formatFn }">
|
||||
<div class="q-gutter-x-xs">
|
||||
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
||||
<span>{{ formatFn(tag.value) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body="{ params, searchFn }">
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInputDate
|
||||
:label="t('params.from')"
|
||||
v-model="params.from"
|
||||
@update:model-value="searchFn()"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('params.bankFk')"
|
||||
v-model="params.bankFk"
|
||||
url="Accountings"
|
||||
option-label="bank"
|
||||
:include="{ relation: 'accountingType' }"
|
||||
sort-by="id"
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>
|
||||
{{ scope.opt.id }} {{ scope.opt.bank }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('params.currencyFk')"
|
||||
url="Currencies"
|
||||
:filter="{ fields: ['id', 'name'] }"
|
||||
order="code"
|
||||
v-model="params.currencyFk"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
v-model="params.isConciliated"
|
||||
:label="t('params.isConciliated')"
|
||||
/></QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnFilterPanel>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
en:
|
||||
params:
|
||||
search: General search
|
||||
supplierId: Supplier
|
||||
categoryId: Category
|
||||
from: From
|
||||
to: To
|
||||
isConciliated: Is conciliated
|
||||
currencyFk: Currency
|
||||
bankFk: Bank
|
||||
companyId: Comapany
|
||||
isBooked: Is booked
|
||||
es:
|
||||
params:
|
||||
supplierId: Proveedor
|
||||
isConciliated: Conciliado
|
||||
currencyFk: Moneda
|
||||
New payment: Añadir pago
|
||||
Date: Fecha
|
||||
from: Desde
|
||||
to: Hasta
|
||||
companyId: Empresa
|
||||
isBooked: Contabilizado
|
||||
bankFk: Caja
|
||||
Amount: Importe
|
||||
Reference: Referencia
|
||||
Cash: Efectivo
|
||||
</i18n>
|
|
@ -9,7 +9,6 @@ import FetchData from 'components/FetchData.vue';
|
|||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { toCurrency } from 'filters/index';
|
||||
import { useRole } from 'src/composables/useRole';
|
||||
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||
|
||||
const haveNegatives = defineModel('haveNegatives', { type: Boolean, required: true });
|
||||
const formData = defineModel({ type: Object, required: true });
|
||||
|
@ -19,7 +18,7 @@ const { t } = useI18n();
|
|||
const { hasAny } = useRole();
|
||||
|
||||
const ticketUpdateActions = ref(null);
|
||||
const rows = computed(() => formData.value?.ticket?.sales || []);
|
||||
const rows = computed(() => formData.value?.sale?.items || []);
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
|
@ -84,6 +83,20 @@ const loadDefaultTicketAction = () => {
|
|||
formData.value.option = isSalesAssistant ? 'mana' : 'renewPrices';
|
||||
};
|
||||
|
||||
const totalPrice = computed(() => {
|
||||
return rows.value.reduce((acc, item) => acc + item.price * item.quantity, 0);
|
||||
});
|
||||
|
||||
const totalNewPrice = computed(() => {
|
||||
return rows.value.reduce(
|
||||
(acc, item) => acc + item.component.newPrice * item.quantity,
|
||||
0
|
||||
);
|
||||
});
|
||||
|
||||
const totalDifference = computed(() => {
|
||||
return rows.value.reduce((acc, item) => acc + item.component?.difference || 0, 0);
|
||||
});
|
||||
const showMovableColumn = computed(() => (haveDifferences.value > 0 ? ['movable'] : []));
|
||||
const haveDifferences = computed(() => formData.value.sale?.haveDifferences);
|
||||
async function ticketHaveNegatives() {
|
||||
|
@ -128,34 +141,17 @@ onMounted(async () => {
|
|||
<QCardSection class="column items-left" horizontal>
|
||||
<span>
|
||||
{{ t('basicData.price') }}:
|
||||
<VnCurrency
|
||||
:model="formData?.ticket"
|
||||
local-field="totalUnitPrice"
|
||||
foreign-field="totalForeignUnitPrice"
|
||||
:currency-code="formData.currency.code"
|
||||
/>
|
||||
{{ toCurrency(totalPrice) }}
|
||||
</span>
|
||||
</QCardSection>
|
||||
<QCardSection class="column items-left" horizontal>
|
||||
<span>
|
||||
{{ t('basicData.newPrice') }}:
|
||||
<VnCurrency
|
||||
:model="formData?.ticket"
|
||||
local-field="totalNewPrice"
|
||||
foreign-field="totalForeignNewPrice"
|
||||
:currency-code="formData.currency.code"
|
||||
/>
|
||||
{{ t('basicData.newPrice') }}: {{ toCurrency(totalNewPrice) }}
|
||||
</span>
|
||||
</QCardSection>
|
||||
<QCardSection class="column items-left" horizontal>
|
||||
<span>
|
||||
{{ t('basicData.difference') }}:
|
||||
<VnCurrency
|
||||
:model="formData?.ticket"
|
||||
local-field="totalDifference"
|
||||
foreign-field="totalForeignDifference"
|
||||
:currency-code="formData.currency.code"
|
||||
/>
|
||||
{{ t('basicData.difference') }}: {{ toCurrency(totalDifference) }}
|
||||
</span>
|
||||
</QCardSection>
|
||||
</QCard>
|
||||
|
@ -248,33 +244,5 @@ onMounted(async () => {
|
|||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-price="{ row }">
|
||||
<QTd class="number">
|
||||
<VnCurrency
|
||||
:model="row.component"
|
||||
:currency-code="formData.currency.code"
|
||||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-newPrice="{ row }">
|
||||
<QTd class="number">
|
||||
<VnCurrency
|
||||
:model="row.component"
|
||||
:currency-code="formData.currency.code"
|
||||
local-field="newPrice"
|
||||
foreign-field="newForeignPrice"
|
||||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-difference="{ row }">
|
||||
<QTd class="number">
|
||||
<VnCurrency
|
||||
:model="row.component"
|
||||
:currency-code="formData.currency.code"
|
||||
local-field="difference"
|
||||
foreign-field="foreignDifference"
|
||||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
</QTable>
|
||||
</template>
|
||||
|
|
|
@ -15,7 +15,6 @@ import useNotify from 'src/composables/useNotify.js';
|
|||
import { useAcl } from 'src/composables/useAcl';
|
||||
import { useValidator } from 'src/composables/useValidator';
|
||||
import { toTimeFormat } from 'filters/date.js';
|
||||
import VnSelectCurrency from 'src/components/common/VnSelectCurrency.vue';
|
||||
|
||||
const formData = defineModel({
|
||||
type: Object,
|
||||
|
@ -358,7 +357,7 @@ async function getZone(options) {
|
|||
:rules="validate('basicData.alias')"
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnRow class="row q-gutter-md q-mb-md no-wrap">
|
||||
<VnSelect
|
||||
:label="t('ticketList.company')"
|
||||
v-model="formData.companyFk"
|
||||
|
@ -370,12 +369,6 @@ async function getZone(options) {
|
|||
:required="true"
|
||||
:rules="validate('ticketList.company')"
|
||||
/>
|
||||
<VnSelectCurrency
|
||||
v-model="formData.currencyFk"
|
||||
@new-value="(value) => (formData.currency = value)"
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow class="row q-gutter-md q-mb-md no-wrap">
|
||||
<VnSelect
|
||||
:label="t('basicData.agency')"
|
||||
v-model="agencyModeId"
|
||||
|
|
|
@ -6,7 +6,6 @@ import { useRoute, useRouter } from 'vue-router';
|
|||
import TicketBasicData from './TicketBasicData.vue';
|
||||
import TicketBasicDataForm from './TicketBasicDataForm.vue';
|
||||
import { useVnConfirm } from 'composables/useVnConfirm';
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
|
||||
import axios from 'axios';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
|
@ -78,13 +77,12 @@ const getPriceDifference = async () => {
|
|||
zoneId: formData.value.zoneFk,
|
||||
warehouseId: formData.value.warehouseFk,
|
||||
shipped: formData.value.shipped,
|
||||
currencyId: formData.value.currencyFk,
|
||||
};
|
||||
const { data } = await axios.post(
|
||||
`tickets/${formData.value.id}/priceDifference`,
|
||||
params,
|
||||
params
|
||||
);
|
||||
formData.value.ticket = data;
|
||||
formData.value.sale = data;
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
|
@ -104,27 +102,24 @@ const submit = async () => {
|
|||
option: formData.value.option,
|
||||
isWithoutNegatives: formData.value.withoutNegatives,
|
||||
withWarningAccept: formData.value.withWarningAccept,
|
||||
currencyFk: formData.value.currencyFk,
|
||||
keepPrice: false,
|
||||
};
|
||||
|
||||
const { data } = await axios.post(
|
||||
`tickets/${formData.value.id}/componentUpdate`,
|
||||
params,
|
||||
params
|
||||
);
|
||||
|
||||
if (!data) return;
|
||||
|
||||
const ticketToMove = data.id;
|
||||
const arrayData = useArrayData('ticketData');
|
||||
arrayData.fetch({});
|
||||
notify(t('basicData.unroutedTicket'), 'positive');
|
||||
router.push({ name: 'TicketSummary', params: { id: ticketToMove } });
|
||||
};
|
||||
|
||||
const submitWithNegatives = async () => {
|
||||
formData.value.withWarningAccept = true;
|
||||
await submit();
|
||||
submit();
|
||||
};
|
||||
|
||||
const onNextStep = async () => {
|
||||
|
@ -139,9 +134,9 @@ const onNextStep = async () => {
|
|||
openConfirmationModal(
|
||||
t('basicData.negativesConfirmTitle'),
|
||||
t('basicData.negativesConfirmMessage'),
|
||||
submitWithNegatives,
|
||||
submitWithNegatives
|
||||
);
|
||||
else await submit();
|
||||
else submit();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -98,7 +98,6 @@ const filter = {
|
|||
],
|
||||
},
|
||||
},
|
||||
{ relation: 'currency' },
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -117,7 +116,7 @@ const setData = (entity) => {
|
|||
<CardDescriptor
|
||||
module="Ticket"
|
||||
:url="`Tickets/${entityId}`"
|
||||
:userFilter="filter"
|
||||
:filter="filter"
|
||||
:title="data.title"
|
||||
:subtitle="data.subtitle"
|
||||
@on-fetch="setData"
|
||||
|
|
|
@ -3,7 +3,6 @@ import { ref } from 'vue';
|
|||
import { useI18n } from 'vue-i18n';
|
||||
import { toCurrency } from 'src/filters';
|
||||
import VnUsesMana from 'components/ui/VnUsesMana.vue';
|
||||
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||
|
||||
const $props = defineProps({
|
||||
mana: {
|
||||
|
@ -44,23 +43,15 @@ const cancel = () => {
|
|||
<template>
|
||||
<QPopupProxy ref="QPopupProxyRef">
|
||||
<div class="container">
|
||||
<QSpinner v-if="!mana && mana !== 0" color="primary" size="md" />
|
||||
<QSpinner v-if="!mana" color="primary" size="md" />
|
||||
<div v-else>
|
||||
<div class="header">
|
||||
Mana:
|
||||
<VnCurrency
|
||||
:model="{ mana }"
|
||||
local-field="mana"
|
||||
foreign-field="mana"
|
||||
arrayDataModel="ticketData"
|
||||
/>
|
||||
</div>
|
||||
<div class="header">Mana: {{ toCurrency(mana) }}</div>
|
||||
<div class="q-pa-md">
|
||||
<slot />
|
||||
<div v-if="newPrice" class="column items-center q-mt-lg">
|
||||
<span class="text-primary">{{ t('New price') }}</span>
|
||||
<span class="text-subtitle1">
|
||||
{{ toCurrency($props.newPrice) }}A
|
||||
{{ toCurrency($props.newPrice) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,13 +5,11 @@ import { useI18n } from 'vue-i18n';
|
|||
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import CatalogItem from 'components/ui/CatalogItem.vue';
|
||||
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
|
||||
import { toCurrency } from 'filters/index';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const arrayData = useArrayData('ticketData');
|
||||
const { store } = arrayData;
|
||||
|
||||
const salesFilter = {
|
||||
include: {
|
||||
|
@ -39,12 +37,7 @@ const sales = ref([]);
|
|||
<div class="q-mt-md full-width row justify-between items-center">
|
||||
<span class="text-h6">{{ sale.quantity }}</span>
|
||||
<span>{{ t('by') }}</span>
|
||||
<span class="text-h6">
|
||||
<VnCurrency
|
||||
:model="sale"
|
||||
:currency-code="store.data.currency.code"
|
||||
/>
|
||||
</span>
|
||||
<span class="text-h6">{{ toCurrency(sale?.price) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</CatalogItem>
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
<script setup>
|
||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||
const arrayData = useArrayData('ticketData');
|
||||
const store = arrayData.store;
|
||||
</script>
|
||||
<template>
|
||||
<RightMenu>
|
||||
<template #right-panel>
|
||||
<div
|
||||
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
||||
style="border: 2px solid black"
|
||||
>
|
||||
<QCardSection class="justify-end text-subtitle1" horizontal>
|
||||
<span class="q-mr-xs color-vn-label"
|
||||
>{{ $t('ticketSale.subtotal') }}:
|
||||
</span>
|
||||
<VnCurrency
|
||||
:model="store.data"
|
||||
:currency-code="store.data?.currency?.code"
|
||||
local-field="totalWithoutVat"
|
||||
foreign-field="foreignTotalWithoutVat"
|
||||
/>
|
||||
</QCardSection>
|
||||
<QCardSection class="justify-end text-subtitle1" horizontal>
|
||||
<span class="q-mr-xs color-vn-label">
|
||||
{{ $t('ticketSale.tax') }}:
|
||||
</span>
|
||||
<VnCurrency
|
||||
:model="{
|
||||
vat: store.data?.totalWithVat - store.data?.totalWithoutVat,
|
||||
foreignVat:
|
||||
store.data?.foreignTotalWithVat -
|
||||
store.data?.foreignTotalWithoutVat,
|
||||
}"
|
||||
:currency-code="store.data?.currency?.code"
|
||||
local-field="vat"
|
||||
foreign-field="foreignVat"
|
||||
/>
|
||||
</QCardSection>
|
||||
<QCardSection
|
||||
class="justify-end text-weight-bold text-subtitle1"
|
||||
horizontal
|
||||
>
|
||||
<span class="q-mr-xs color-vn-label">
|
||||
{{ $t('basicData.total') }}:
|
||||
</span>
|
||||
<VnCurrency
|
||||
:model="store.data"
|
||||
:currency-code="store.data?.currency?.code"
|
||||
local-field="totalWithVat"
|
||||
foreign-field="foreignTotalWithVat"
|
||||
/>
|
||||
</QCardSection>
|
||||
</div>
|
||||
</template>
|
||||
</RightMenu>
|
||||
</template>
|
|
@ -3,7 +3,6 @@ import { onMounted, ref, computed, watch } from 'vue';
|
|||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useState } from 'src/composables/useState';
|
||||
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import FetchedTags from 'components/ui/FetchedTags.vue';
|
||||
|
@ -25,16 +24,11 @@ import axios from 'axios';
|
|||
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||
import VnUsesMana from 'src/components/ui/VnUsesMana.vue';
|
||||
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||
import TicketRightTotals from './TicketRightTotals.vue';
|
||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const state = useState();
|
||||
const user = state.getUser();
|
||||
|
||||
const { notify } = useNotify();
|
||||
const { openConfirmationModal } = useVnConfirm();
|
||||
const editPriceProxyRef = ref(null);
|
||||
|
@ -62,7 +56,7 @@ const canProceed = ref();
|
|||
|
||||
watch(
|
||||
() => route.params.id,
|
||||
() => tableRef.value.reload(),
|
||||
() => tableRef.value.reload()
|
||||
);
|
||||
|
||||
const columns = computed(() => [
|
||||
|
@ -137,7 +131,8 @@ const columns = computed(() => [
|
|||
{
|
||||
align: 'left',
|
||||
label: t('globals.amount'),
|
||||
name: 'total',
|
||||
name: 'amount',
|
||||
format: (row) => parseInt(row.amount * row.quantity),
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
|
@ -167,6 +162,20 @@ const getConfig = async () => {
|
|||
ticketConfig.value = data;
|
||||
};
|
||||
|
||||
const onSalesFetched = (salesData) => {
|
||||
sales.value = salesData;
|
||||
for (let sale of salesData) sale.amount = getSaleTotal(sale);
|
||||
};
|
||||
|
||||
const getSaleTotal = (sale) => {
|
||||
if (sale.quantity == null || sale.price == null) return null;
|
||||
|
||||
const price = sale.quantity * sale.price;
|
||||
const discount = (sale.discount * price) / 100;
|
||||
|
||||
return price - discount;
|
||||
};
|
||||
|
||||
const resetChanges = async () => {
|
||||
arrayData.fetch({ append: false });
|
||||
tableRef.value.reload();
|
||||
|
@ -190,7 +199,7 @@ const changeQuantity = async (sale) => {
|
|||
await updateQuantity(sale);
|
||||
} catch (e) {
|
||||
const { quantity } = tableRef.value.CrudModelRef.originalData.find(
|
||||
(s) => s.id === sale.id,
|
||||
(s) => s.id === sale.id
|
||||
);
|
||||
sale.quantity = quantity;
|
||||
throw e;
|
||||
|
@ -252,9 +261,7 @@ const getUsesMana = async () => {
|
|||
};
|
||||
|
||||
const getMana = async () => {
|
||||
const { data } = await axios.get(`Tickets/${route.params.id}/getSalesPersonMana`, {
|
||||
params: { isForeign: user.value.foreignCurrency },
|
||||
});
|
||||
const { data } = await axios.get(`Tickets/${route.params.id}/getSalesPersonMana`);
|
||||
mana.value = data;
|
||||
await getUsesMana();
|
||||
};
|
||||
|
@ -266,12 +273,9 @@ const selectedValidSales = computed(() => {
|
|||
|
||||
const onOpenEditPricePopover = async (sale) => {
|
||||
await getMana();
|
||||
console.log('sale: ', sale, user.value.foreignCurrency);
|
||||
edit.value = {
|
||||
sale: JSON.parse(JSON.stringify(sale)),
|
||||
price: user.value.foreignCurrency
|
||||
? (sale.foreignPrice ?? sale.price)
|
||||
: sale.price,
|
||||
price: sale.price,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -296,18 +300,13 @@ const updatePrice = async (sale) => {
|
|||
if (!canProceed.value) return;
|
||||
const newPrice = edit.value.price;
|
||||
if (newPrice != null && newPrice != sale.price) {
|
||||
const { data } = await axios.post(`Sales/${sale.id}/updatePrice`, {
|
||||
newPrice,
|
||||
isForeign: user.value.foreignCurrency,
|
||||
});
|
||||
sale.price = data.price;
|
||||
sale.total = data.total;
|
||||
sale.foreignPrice = data.foreignPrice;
|
||||
sale.foreignTotal = data.foreignTotal;
|
||||
arrayData.fetch({ append: false });
|
||||
await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice });
|
||||
sale.price = newPrice;
|
||||
edit.value = { ...DEFAULT_EDIT };
|
||||
notify('globals.dataSaved', 'positive');
|
||||
}
|
||||
|
||||
await getMana();
|
||||
};
|
||||
|
||||
const changeDiscount = async (sale) => {
|
||||
|
@ -331,8 +330,7 @@ const updateDiscount = async (sales, newDiscount = null) => {
|
|||
};
|
||||
await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
|
||||
notify('globals.dataSaved', 'positive');
|
||||
tableRef.value.reload();
|
||||
arrayData.fetch({ append: false });
|
||||
for (let sale of sales) sale.discount = _newDiscount;
|
||||
edit.value = { ...DEFAULT_EDIT };
|
||||
};
|
||||
|
||||
|
@ -340,10 +338,7 @@ const getNewPrice = computed(() => {
|
|||
if (edit.value?.sale) {
|
||||
const sale = edit.value.sale;
|
||||
let newDiscount = sale.discount;
|
||||
let newPrice = user.value.foreignCurrency
|
||||
? (sale.foreignPrice ?? sale.price)
|
||||
: sale.price;
|
||||
// let newPrice = edit.value.price || sale.price;
|
||||
let newPrice = edit.value.price || sale.price;
|
||||
|
||||
if (edit.value.discount != null) newDiscount = edit.value.discount;
|
||||
|
||||
|
@ -439,7 +434,7 @@ const updateItem = async (row) => {
|
|||
row.price = selectedItem.price;
|
||||
row.discount = 0;
|
||||
row.quantity = 0;
|
||||
row.total = 0;
|
||||
row.amount = row.price * row.quantity;
|
||||
}
|
||||
endNewRow(selectedItem);
|
||||
};
|
||||
|
@ -460,7 +455,7 @@ const addRow = (original = null) => {
|
|||
quantity: original.quantity,
|
||||
price: original.price,
|
||||
discount: original.discount,
|
||||
total: original.total,
|
||||
amount: original.amount,
|
||||
isNew: true,
|
||||
};
|
||||
}
|
||||
|
@ -508,7 +503,7 @@ async function isSalePrepared(item) {
|
|||
componentProps: {
|
||||
title: t('Item prepared'),
|
||||
message: t(
|
||||
'This item is already prepared. Do you want to continue?',
|
||||
'This item is already prepared. Do you want to continue?'
|
||||
),
|
||||
data: item,
|
||||
},
|
||||
|
@ -530,7 +525,7 @@ watch(
|
|||
if (newItemFk) {
|
||||
updateItem(newRow.value);
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
|
@ -600,7 +595,7 @@ watch(
|
|||
openConfirmationModal(
|
||||
t('Continue anyway?'),
|
||||
t('You are going to delete lines of the ticket'),
|
||||
removeSales,
|
||||
removeSales
|
||||
)
|
||||
"
|
||||
>
|
||||
|
@ -623,7 +618,38 @@ watch(
|
|||
</QBtnGroup>
|
||||
</template>
|
||||
</VnSubToolbar>
|
||||
<TicketRightTotals />
|
||||
<RightMenu>
|
||||
<template #right-panel>
|
||||
<div
|
||||
class="q-pa-md q-mb-md q-ma-md color-vn-text"
|
||||
style="border: 2px solid black"
|
||||
>
|
||||
<QCardSection class="justify-end text-subtitle1" horizontal>
|
||||
<span class="q-mr-xs color-vn-label"
|
||||
>{{ t('ticketSale.subtotal') }}:
|
||||
</span>
|
||||
<span>{{ toCurrency(store.data?.totalWithoutVat) }}</span>
|
||||
</QCardSection>
|
||||
<QCardSection class="justify-end text-subtitle1" horizontal>
|
||||
<span class="q-mr-xs color-vn-label">
|
||||
{{ t('ticketSale.tax') }}:
|
||||
</span>
|
||||
<span>{{
|
||||
toCurrency(store.data?.totalWithVat - store.data?.totalWithoutVat)
|
||||
}}</span>
|
||||
</QCardSection>
|
||||
<QCardSection
|
||||
class="justify-end text-weight-bold text-subtitle1"
|
||||
horizontal
|
||||
>
|
||||
<span class="q-mr-xs color-vn-label">
|
||||
{{ t('basicData.total') }}:
|
||||
</span>
|
||||
<span>{{ toCurrency(store.data?.totalWithVat) }}</span>
|
||||
</QCardSection>
|
||||
</div>
|
||||
</template>
|
||||
</RightMenu>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
data-key="TicketSales"
|
||||
|
@ -639,7 +665,7 @@ watch(
|
|||
:column-search="false"
|
||||
:disable-option="{ card: true }"
|
||||
auto-load
|
||||
@on-fetch="(data) => (sales = data)"
|
||||
@on-fetch="onSalesFetched"
|
||||
:create="{
|
||||
onDataSaved: handleOnDataSave,
|
||||
}"
|
||||
|
@ -778,10 +804,7 @@ watch(
|
|||
<template #column-price="{ row }">
|
||||
<template v-if="isTicketEditable && row.id">
|
||||
<QBtn flat class="link" dense @click="onOpenEditPricePopover(row)">
|
||||
<VnCurrency
|
||||
:model="row"
|
||||
:currency-code="store.data?.currency?.code"
|
||||
/>
|
||||
{{ toCurrency(row.price) }}
|
||||
</QBtn>
|
||||
<TicketEditManaProxy
|
||||
ref="editPriceProxyRef"
|
||||
|
@ -789,12 +812,14 @@ watch(
|
|||
:new-price="getNewPrice"
|
||||
@save="updatePrice(row)"
|
||||
>
|
||||
<VnInputNumber v-model="edit.price" :label="t('basicData.price')" />
|
||||
<VnInput
|
||||
v-model.number="edit.price"
|
||||
:label="t('basicData.price')"
|
||||
type="number"
|
||||
/>
|
||||
</TicketEditManaProxy>
|
||||
</template>
|
||||
<span v-else>
|
||||
<VnCurrency :model="row" :currency-code="store.data?.currency?.code" />
|
||||
</span>
|
||||
<span v-else>{{ toCurrency(row.price) }}</span>
|
||||
</template>
|
||||
<template #column-discount="{ row }">
|
||||
<template v-if="!isLocked && row.id">
|
||||
|
@ -808,9 +833,10 @@ watch(
|
|||
:mana-code="manaCode"
|
||||
@save="changeDiscount(row)"
|
||||
>
|
||||
<VnInputNumber
|
||||
v-model="edit.discount"
|
||||
<VnInput
|
||||
v-model.number="edit.discount"
|
||||
:label="t('ticketSale.discount')"
|
||||
type="number"
|
||||
/>
|
||||
<div v-if="usesMana" class="column q-gutter-y-sm q-mt-sm">
|
||||
<VnUsesMana :mana-code="manaCode" />
|
||||
|
@ -819,12 +845,8 @@ watch(
|
|||
</template>
|
||||
<span v-else>{{ toPercentage(row.discount / 100) }}</span>
|
||||
</template>
|
||||
<template #column-total="{ row }">
|
||||
<VnCurrency
|
||||
:model="row"
|
||||
:currency-code="store.data?.currency?.code"
|
||||
local-field="total"
|
||||
/>
|
||||
<template #column-amount="{ row }">
|
||||
{{ toCurrency(row.quantity * row.price) }}
|
||||
</template>
|
||||
</VnTable>
|
||||
|
||||
|
|
|
@ -12,14 +12,10 @@ import VnInput from 'src/components/common/VnInput.vue';
|
|||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
import axios from 'axios';
|
||||
import TicketRightTotals from './TicketRightTotals.vue';
|
||||
import { useState } from 'src/composables/useState';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const state = useState();
|
||||
const user = state.getUser();
|
||||
const ticketServiceTypeFetchRef = ref(null);
|
||||
const ticketServiceCrudRef = ref(null);
|
||||
const ticketServiceOptions = ref([]);
|
||||
|
@ -44,7 +40,7 @@ watch(
|
|||
async () => {
|
||||
store.filter = crudModelFilter.value;
|
||||
await ticketServiceCrudRef.value.reload();
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(async () => await getDefaultTaxClass());
|
||||
|
@ -63,7 +59,7 @@ const createRefund = async () => {
|
|||
t('service.createRefundSuccess', {
|
||||
ticketId: refundTicket.id,
|
||||
}),
|
||||
'positive',
|
||||
'positive'
|
||||
);
|
||||
router.push({ name: 'TicketSale', params: { id: refundTicket.id } });
|
||||
};
|
||||
|
@ -134,7 +130,6 @@ async function handleSave() {
|
|||
auto-load
|
||||
url="TicketServiceTypes"
|
||||
/>
|
||||
<TicketRightTotals />
|
||||
<CrudModel
|
||||
ref="ticketServiceCrudRef"
|
||||
data-key="TicketService"
|
||||
|
@ -199,9 +194,7 @@ async function handleSave() {
|
|||
<QTd auto-width>
|
||||
<VnInput
|
||||
:label="col.label"
|
||||
v-model.number="
|
||||
row[user.foreignCurrency ? 'foreignPrice' : 'price']
|
||||
"
|
||||
v-model.number="row.price"
|
||||
type="number"
|
||||
min="0"
|
||||
@keyup.enter="handleSave"
|
||||
|
|
|
@ -20,7 +20,6 @@ import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
|
|||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
import VnToSummary from 'src/components/ui/VnToSummary.vue';
|
||||
import TicketDescriptorMenu from './TicketDescriptorMenu.vue';
|
||||
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const { notify } = useNotify();
|
||||
|
@ -271,38 +270,19 @@ onMounted(async () => {
|
|||
<QCard class="vn-one">
|
||||
<VnTitle :text="t('ticket.summary.summaryAmount')" />
|
||||
<div class="bodyCard">
|
||||
<VnLv :label="t('globals.subtotal')">
|
||||
<template #value>
|
||||
<VnCurrency
|
||||
:model="entity"
|
||||
:currency-code="entity.currency.code"
|
||||
local-field="totalWithoutVat"
|
||||
/>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('globals.vat')">
|
||||
<template #value>
|
||||
<VnCurrency
|
||||
:model="{
|
||||
vat: entity.totalWithVat - entity.totalWithoutVat,
|
||||
foreignVat:
|
||||
entity.foreignTotalWithVat -
|
||||
entity.foreignTotalWithoutVat,
|
||||
}"
|
||||
:currency-code="entity.currency.code"
|
||||
local-field="vat"
|
||||
/>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('ticket.summary.total')" style="font-weight: bold">
|
||||
<template #value>
|
||||
<VnCurrency
|
||||
:model="entity"
|
||||
:currency-code="entity.currency.code"
|
||||
local-field="totalWithVat"
|
||||
/>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv
|
||||
:label="t('globals.subtotal')"
|
||||
:value="toCurrency(entity.totalWithoutVat)"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('globals.vat')"
|
||||
:value="toCurrency(entity.totalWithVat - entity.totalWithoutVat)"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('ticket.summary.total')"
|
||||
:value="toCurrency(ticket.totalWithVat)"
|
||||
style="font-weight: bold"
|
||||
/>
|
||||
</div>
|
||||
</QCard>
|
||||
<QCard class="vn-max">
|
||||
|
@ -460,28 +440,16 @@ onMounted(async () => {
|
|||
:item="props.row.item"
|
||||
></FetchedTags>
|
||||
</QTd>
|
||||
<QTd>
|
||||
<VnCurrency
|
||||
:model="props.row"
|
||||
:currency-code="entity.currency.code"
|
||||
/>
|
||||
</QTd>
|
||||
<QTd>{{ props.row.price }} €</QTd>
|
||||
<QTd>{{ props.row.discount }} %</QTd>
|
||||
<QTd>
|
||||
<VnCurrency
|
||||
:model="{
|
||||
amount:
|
||||
props.row.quantity *
|
||||
<QTd
|
||||
>{{
|
||||
toCurrency(
|
||||
props.row.quantity *
|
||||
props.row.price *
|
||||
((100 - props.row.discount) / 100),
|
||||
foreignAmount:
|
||||
props.row.quantity *
|
||||
props.row.foreignPrice *
|
||||
((100 - props.row.discount) / 100),
|
||||
}"
|
||||
local-field="amount"
|
||||
:currency-code="entity.currency.code"
|
||||
/>
|
||||
)
|
||||
}}
|
||||
</QTd>
|
||||
<QTd>{{ dashIfEmpty(props.row.item.itemPackingTypeFk) }}</QTd>
|
||||
</QTr>
|
||||
|
@ -526,12 +494,7 @@ onMounted(async () => {
|
|||
<QTr :props="props">
|
||||
<QTd>{{ props.row.quantity }}</QTd>
|
||||
<QTd>{{ props.row.description }}</QTd>
|
||||
<QTd>
|
||||
<VnCurrency
|
||||
:model="props.row"
|
||||
:currency-code="entity.currency.code"
|
||||
/>
|
||||
</QTd>
|
||||
<QTd>{{ toCurrency(props.row.price) }}</QTd>
|
||||
<QTd>{{ props.row.taxClass.description }}</QTd>
|
||||
<QTd>{{
|
||||
toCurrency(props.row.quantity * props.row.price)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { computed, ref, onBeforeMount, markRaw } from 'vue';
|
||||
import { computed, ref, onBeforeMount } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { QChip, useQuasar } from 'quasar';
|
||||
import { toDate, dashIfEmpty } from 'src/filters/index';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { toDate, toCurrency, dashIfEmpty } from 'src/filters/index';
|
||||
import useNotify from 'src/composables/useNotify';
|
||||
import TicketSummary from './Card/TicketSummary.vue';
|
||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||
|
@ -22,9 +22,6 @@ import { toTimeFormat } from 'src/filters/date';
|
|||
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
||||
import TicketProblems from 'src/components/TicketProblems.vue';
|
||||
import VnSection from 'src/components/common/VnSection.vue';
|
||||
import VnSelectCompany from 'src/components/common/VnSelectCompany.vue';
|
||||
import VnSelectCurrency from 'src/components/common/VnSelectCurrency.vue';
|
||||
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||
import { getClient } from 'src/pages/Customer/composables/getClient';
|
||||
import { getAddresses } from 'src/pages/Customer/composables/getAddresses';
|
||||
import { getAgencies } from 'src/pages/Route/Agency/composables/getAgencies';
|
||||
|
@ -198,6 +195,7 @@ const columns = computed(() => [
|
|||
component: 'number',
|
||||
inWhere: true,
|
||||
},
|
||||
format: (row) => toCurrency(row.totalWithVat),
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
|
@ -247,7 +245,7 @@ const fetchAvailableAgencies = async (formData) => {
|
|||
|
||||
const defaultAgency = agenciesOptions.value.find(
|
||||
(agency) =>
|
||||
agency.agencyModeFk === selectedClient.value.defaultAddress.agencyModeFk,
|
||||
agency.agencyModeFk === selectedClient.value.defaultAddress.agencyModeFk
|
||||
);
|
||||
|
||||
if (defaultAgency) formData.agencyModeId = defaultAgency.agencyModeFk;
|
||||
|
@ -323,7 +321,7 @@ function openBalanceDialog(ticket) {
|
|||
const description = ref([]);
|
||||
const firstTicketClientId = checkedTickets[0].clientFk;
|
||||
const isSameClient = checkedTickets.every(
|
||||
(ticket) => ticket.clientFk === firstTicketClientId,
|
||||
(ticket) => ticket.clientFk === firstTicketClientId
|
||||
);
|
||||
|
||||
if (!isSameClient) {
|
||||
|
@ -362,7 +360,7 @@ async function onSubmit() {
|
|||
description: dialogData.value.value.description,
|
||||
clientFk: dialogData.value.value.clientFk,
|
||||
email: email[0].email,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (data) notify('globals.dataSaved', 'positive');
|
||||
|
@ -381,32 +379,32 @@ function setReference(data) {
|
|||
switch (data) {
|
||||
case 1:
|
||||
newDescription = `${t(
|
||||
'ticketList.creditCard',
|
||||
'ticketList.creditCard'
|
||||
)}, ${dialogData.value.value.description.replace(
|
||||
/^(Credit Card, |Cash, |Transfers, )/,
|
||||
'',
|
||||
''
|
||||
)}`;
|
||||
break;
|
||||
case 2:
|
||||
newDescription = `${t(
|
||||
'ticketList.cash',
|
||||
'ticketList.cash'
|
||||
)}, ${dialogData.value.value.description.replace(
|
||||
/^(Credit Card, |Cash, |Transfers, )/,
|
||||
'',
|
||||
''
|
||||
)}`;
|
||||
break;
|
||||
case 3:
|
||||
newDescription = `${newDescription.replace(
|
||||
/^(Credit Card, |Cash, |Transfers, )/,
|
||||
'',
|
||||
''
|
||||
)}`;
|
||||
break;
|
||||
case 4:
|
||||
newDescription = `${t(
|
||||
'ticketList.transfers',
|
||||
'ticketList.transfers'
|
||||
)}, ${dialogData.value.value.description.replace(
|
||||
/^(Credit Card, |Cash, |Transfers, )/,
|
||||
'',
|
||||
''
|
||||
)}`;
|
||||
break;
|
||||
case 3317:
|
||||
|
@ -418,10 +416,6 @@ function setReference(data) {
|
|||
|
||||
dialogData.value.value.description = newDescription;
|
||||
}
|
||||
|
||||
function isLittle(row) {
|
||||
return row.totalWithVat > 0 && row.totalWithVat < 50;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -521,18 +515,14 @@ function isLittle(row) {
|
|||
</span>
|
||||
</template>
|
||||
<template #column-totalWithVat="{ row }">
|
||||
<component
|
||||
:is="isLittle(row) ? markRaw(QChip) : 'span'"
|
||||
:class="{ 'bg-warning': isLittle(row) }"
|
||||
<QChip
|
||||
v-if="row.totalWithVat > 0 && row.totalWithVat < 50"
|
||||
class="bg-warning"
|
||||
dense
|
||||
square
|
||||
>
|
||||
<VnCurrency
|
||||
:model="row"
|
||||
:currency-code="row.currencyCode"
|
||||
local-field="totalWithVat"
|
||||
/>
|
||||
</component>
|
||||
{{ row.totalWithVat }}
|
||||
</QChip>
|
||||
</template>
|
||||
<template #more-create-dialog="{ data }">
|
||||
<VnRow>
|
||||
|
@ -620,45 +610,43 @@ function isLittle(row) {
|
|||
</VnSelect>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnInputDate
|
||||
placeholder="dd-mm-aaa"
|
||||
:label="t('globals.landed')"
|
||||
v-model="data.landed"
|
||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||
/>
|
||||
<div class="col">
|
||||
<VnInputDate
|
||||
placeholder="dd-mm-aaa"
|
||||
:label="t('globals.landed')"
|
||||
v-model="data.landed"
|
||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
url="Warehouses"
|
||||
:sort-by="['name']"
|
||||
:label="t('globals.warehouse')"
|
||||
v-model="data.warehouseId"
|
||||
:options="warehousesOptions"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
required
|
||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||
/>
|
||||
<div class="col">
|
||||
<VnSelect
|
||||
url="Warehouses"
|
||||
:sort-by="['name']"
|
||||
:label="t('globals.warehouse')"
|
||||
v-model="data.warehouseId"
|
||||
:options="warehousesOptions"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
required
|
||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
:label="t('globals.agency')"
|
||||
v-model="data.agencyModeId"
|
||||
:options="agenciesOptions"
|
||||
option-value="agencyModeFk"
|
||||
option-label="agencyMode"
|
||||
hide-selected
|
||||
/>
|
||||
<div class="col">
|
||||
<VnSelect
|
||||
:label="t('globals.agency')"
|
||||
v-model="data.agencyModeId"
|
||||
:options="agenciesOptions"
|
||||
option-value="agencyModeFk"
|
||||
option-label="agencyMode"
|
||||
hide-selected
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
<VnSelectCompany
|
||||
v-model="data.companyId"
|
||||
v-model:client-id="data.clientId"
|
||||
/>
|
||||
<VnSelectCurrency
|
||||
v-model="data.currencyId"
|
||||
v-model:client-id="data.clientId"
|
||||
/>
|
||||
</template>
|
||||
</VnTable>
|
||||
</template>
|
||||
|
|
|
@ -8,6 +8,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
|
|||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import axios from 'axios';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
|
@ -48,11 +49,11 @@ const warehouses = async () => {
|
|||
|
||||
continentsResponse.data.forEach((continent) => {
|
||||
const countriesInContinent = Object.keys(countryContinentMap).filter(
|
||||
(countryId) => countryContinentMap[countryId] === continent.id.toString()
|
||||
(countryId) => countryContinentMap[countryId] === continent.id.toString(),
|
||||
);
|
||||
|
||||
warehousesByContinent.value[continent.code] = warehousesResponse.data.filter(
|
||||
(warehouse) => countriesInContinent.includes(warehouse.countryFk.toString())
|
||||
(warehouse) => countriesInContinent.includes(warehouse.countryFk.toString()),
|
||||
);
|
||||
});
|
||||
};
|
||||
|
@ -211,30 +212,13 @@ warehouses();
|
|||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('globals.pageTitles.supplier')"
|
||||
<VnSelectSupplier
|
||||
v-model="params.cargoSupplierFk"
|
||||
url="Suppliers"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>
|
||||
{{ scope.opt?.name}}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ `#${scope.opt?.id } , ${ scope.opt?.nickname}` }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
|
|
|
@ -0,0 +1,234 @@
|
|||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
import VnTable from 'components/VnTable/VnTable.vue';
|
||||
import { toDate } from 'src/filters';
|
||||
import { useQuasar } from 'quasar';
|
||||
import axios from 'axios';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const tableRef = ref();
|
||||
const entityId = computed(() => route.params.id);
|
||||
const quasar = useQuasar();
|
||||
|
||||
async function reactivateWorker() {
|
||||
const hasToReactive = tableRef.value.CrudModelRef.formData.find(
|
||||
(data) => !data.ended
|
||||
);
|
||||
if (hasToReactive) {
|
||||
quasar
|
||||
.dialog({
|
||||
message: t('Do you want to reactivate the user?'),
|
||||
ok: {
|
||||
push: true,
|
||||
color: 'primary',
|
||||
},
|
||||
cancel: true,
|
||||
})
|
||||
.onOk(async () => {
|
||||
await axios.patch(`Workers/${entityId.value}`, {
|
||||
isDisable: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
const columns = computed(() => [
|
||||
{
|
||||
name: 'started',
|
||||
label: t('worker.business.tableVisibleColumns.started'),
|
||||
align: 'left',
|
||||
format: ({ started }) => toDate(started),
|
||||
component: 'date',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
|
||||
{
|
||||
name: 'ended',
|
||||
label: t('worker.business.tableVisibleColumns.ended'),
|
||||
align: 'left',
|
||||
format: ({ ended }) => toDate(ended),
|
||||
component: 'date',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
label: t('worker.business.tableVisibleColumns.company'),
|
||||
align: 'left',
|
||||
name: 'companyCodeFk',
|
||||
component: 'select',
|
||||
attrs: {
|
||||
url: 'Companies',
|
||||
fields: ['code'],
|
||||
optionLabel: 'code',
|
||||
optionValue: 'code',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'reasonEndFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.reasonEnd'),
|
||||
attrs: {
|
||||
url: 'BusinessReasonEnds',
|
||||
fields: ['id', 'reason'],
|
||||
optionLabel: 'reason',
|
||||
},
|
||||
cardVisible: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'departmentFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.department'),
|
||||
attrs: {
|
||||
url: 'Departments',
|
||||
fields: ['id', 'name'],
|
||||
optionLabel: 'name',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'workerBusinessProfessionalCategoryFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.professionalCategory'),
|
||||
attrs: {
|
||||
url: 'WorkerBusinessProfessionalCategories',
|
||||
fields: ['id', 'description', 'code'],
|
||||
optionLabel: 'description',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'calendarTypeFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.calendarType'),
|
||||
attrs: {
|
||||
url: 'CalendarTypes',
|
||||
fields: ['id', 'description'],
|
||||
optionLabel: 'description',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'workcenterFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.workCenter'),
|
||||
attrs: {
|
||||
url: 'WorkCenters',
|
||||
fields: ['id', 'name'],
|
||||
optionLabel: 'name',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'workerBusinessCategoryFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.payrollCategories'),
|
||||
attrs: {
|
||||
url: 'payrollCategories',
|
||||
fields: ['id', 'description'],
|
||||
optionLabel: 'description',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'occupationCodeFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.occupationCode'),
|
||||
attrs: {
|
||||
url: 'OccupationCodes',
|
||||
fields: ['code', 'name'],
|
||||
optionValue: 'code',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'rate',
|
||||
label: t('worker.business.tableVisibleColumns.rate'),
|
||||
component: 'input',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'workerBusinessTypeFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.businessType'),
|
||||
attrs: {
|
||||
url: 'WorkerBusinessTypes',
|
||||
fields: ['id', 'name'],
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('worker.business.tableVisibleColumns.amount'),
|
||||
name: 'amount',
|
||||
component: 'input',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('worker.business.tableVisibleColumns.basicSalary'),
|
||||
name: 'basicSalary',
|
||||
component: 'input',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
name: 'notes',
|
||||
label: t('worker.business.tableVisibleColumns.notes'),
|
||||
align: 'left',
|
||||
component: 'input',
|
||||
cardVisible: true,
|
||||
},
|
||||
]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
data-key="WorkerBusiness"
|
||||
:url="`Workers/${entityId}/Business`"
|
||||
save-url="/Businesses/crud"
|
||||
:create="{
|
||||
urlCreate: `Workers/${entityId}/Business`,
|
||||
title: 'Create business',
|
||||
onDataSaved: () => tableRef.reload(),
|
||||
formInitialData: {},
|
||||
}"
|
||||
order="id DESC"
|
||||
:columns="columns"
|
||||
default-mode="card"
|
||||
auto-load
|
||||
:disable-option="{ table: true }"
|
||||
:right-search="false"
|
||||
card-class="grid-two q-gutter-x-xl q-gutter-y-md q-pr-lg q-py-lg"
|
||||
:is-editable="true"
|
||||
:use-model="true"
|
||||
@save-changes="(data) => reactivateWorker(data)"
|
||||
/>
|
||||
</template>
|
||||
<i18n>
|
||||
es:
|
||||
Do you want to reactivate the user?: desea reactivar el usuario?
|
||||
</i18n>
|
|
@ -12,6 +12,7 @@ import RoleDescriptorProxy from 'src/pages/Account/Role/Card/RoleDescriptorProxy
|
|||
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
|
||||
import { useAdvancedSummary } from 'src/composables/useAdvancedSummary';
|
||||
import WorkerDescriptorMenu from './WorkerDescriptorMenu.vue';
|
||||
import axios from 'axios';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
@ -27,6 +28,76 @@ const entityId = computed(() => $props.id || route.params.id);
|
|||
const basicDataUrl = ref(null);
|
||||
const advancedSummary = ref();
|
||||
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['name', 'nickname', 'roleFk'],
|
||||
|
||||
include: [
|
||||
{
|
||||
relation: 'role',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'emailUser',
|
||||
scope: {
|
||||
fields: ['email'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'department',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'department',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'boss',
|
||||
},
|
||||
{
|
||||
relation: 'client',
|
||||
},
|
||||
{
|
||||
relation: 'sip',
|
||||
},
|
||||
{
|
||||
relation: 'business',
|
||||
scope: {
|
||||
include: [
|
||||
{
|
||||
relation: 'department',
|
||||
scope: {
|
||||
fields: ['id', 'name'],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'reasonEnd',
|
||||
scope: {
|
||||
fields: ['id', 'reason'],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'workerBusinessProfessionalCategory',
|
||||
scope: {
|
||||
fields: ['id', 'description'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
onBeforeMount(async () => {
|
||||
advancedSummary.value = await useAdvancedSummary('Workers', entityId.value);
|
||||
basicDataUrl.value = `#/worker/${entityId.value}/basic-data`;
|
||||
|
@ -37,7 +108,7 @@ onBeforeMount(async () => {
|
|||
<CardSummary
|
||||
ref="summary"
|
||||
:url="`Workers/summary`"
|
||||
:filter="{ where: { id: entityId } }"
|
||||
:user-filter="{ where: { id: entityId }, filter }"
|
||||
data-key="Worker"
|
||||
>
|
||||
<template #header="{ entity }">
|
||||
|
@ -143,6 +214,29 @@ onBeforeMount(async () => {
|
|||
</VnLv>
|
||||
<VnLv :label="t('queue')" :value="worker.sip?.queueMember?.queue" />
|
||||
</QCard>
|
||||
<QCard class="vn-one" v-if="advancedSummary">
|
||||
<VnTitle
|
||||
:url="`#/worker/${entityId}/business`"
|
||||
:text="t('worker.summary.business')"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('worker.summary.started')"
|
||||
:value="toDate(advancedSummary.currentBusiness?.started)"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('worker.summary.ended')"
|
||||
:value="toDate(advancedSummary.currentBusiness?.ended)"
|
||||
/>
|
||||
|
||||
<VnLv
|
||||
:label="t('worker.summary.reasonEnd')"
|
||||
:value="advancedSummary.currentBusiness?.reasonEnd?.reason"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('worker.summary.notes')"
|
||||
:value="advancedSummary.currentBusiness?.notes"
|
||||
/>
|
||||
</QCard>
|
||||
</template>
|
||||
</CardSummary>
|
||||
</template>
|
||||
|
|
|
@ -21,8 +21,8 @@ const { t, te } = i18n.global;
|
|||
const createHistory = process.env.SERVER
|
||||
? createMemoryHistory
|
||||
: process.env.VUE_ROUTER_MODE === 'history'
|
||||
? createWebHistory
|
||||
: createWebHashHistory;
|
||||
? createWebHistory
|
||||
: createWebHashHistory;
|
||||
|
||||
const Router = createRouter({
|
||||
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||
|
@ -99,9 +99,15 @@ export default defineRouter(function (/* { store, ssrContext } */) {
|
|||
|
||||
title += builtTitle;
|
||||
}
|
||||
|
||||
document.title = title;
|
||||
});
|
||||
|
||||
Router.onError(({ message }) => {
|
||||
const errorMessages = [
|
||||
'Failed to fetch dynamically imported module',
|
||||
'Importing a module script failed',
|
||||
];
|
||||
state.set('error', errorMessages.some(message.includes));
|
||||
});
|
||||
return Router;
|
||||
});
|
||||
|
|
|
@ -21,6 +21,7 @@ export default {
|
|||
'SupplierAccounts',
|
||||
'SupplierContacts',
|
||||
'SupplierAddresses',
|
||||
'SupplierBalance',
|
||||
'SupplierConsumption',
|
||||
'SupplierAgencyTerm',
|
||||
'SupplierDms',
|
||||
|
@ -144,6 +145,16 @@ export default {
|
|||
component: () =>
|
||||
import('src/pages/Supplier/Card/SupplierAddressesCreate.vue'),
|
||||
},
|
||||
{
|
||||
path: 'balance',
|
||||
name: 'SupplierBalance',
|
||||
meta: {
|
||||
title: 'balance',
|
||||
icon: 'balance',
|
||||
},
|
||||
component: () =>
|
||||
import('src/pages/Supplier/Card/SupplierBalance.vue'),
|
||||
},
|
||||
{
|
||||
path: 'consumption',
|
||||
name: 'SupplierConsumption',
|
||||
|
|
|
@ -9,7 +9,6 @@ const ticketCard = {
|
|||
menu: [
|
||||
'TicketBasicData',
|
||||
'TicketSale',
|
||||
'TicketService',
|
||||
'TicketLog',
|
||||
'TicketExpedition',
|
||||
'TicketDms',
|
||||
|
@ -20,6 +19,7 @@ const ticketCard = {
|
|||
'TicketVolume',
|
||||
'TicketComponents',
|
||||
'TicketPackage',
|
||||
'TicketService',
|
||||
'TicketSaleTracking',
|
||||
'TicketBoxing',
|
||||
'TicketSms',
|
||||
|
|
|
@ -8,6 +8,7 @@ const workerCard = {
|
|||
meta: {
|
||||
menu: [
|
||||
'WorkerBasicData',
|
||||
'WorkerBusiness',
|
||||
'WorkerNotes',
|
||||
'WorkerPda',
|
||||
'WorkerNotificationsManager',
|
||||
|
@ -50,6 +51,15 @@ const workerCard = {
|
|||
},
|
||||
component: () => import('src/pages/Worker/Card/WorkerBasicData.vue'),
|
||||
},
|
||||
{
|
||||
path: 'business',
|
||||
name: 'WorkerBusiness',
|
||||
meta: {
|
||||
title: 'business',
|
||||
icon: 'handshake',
|
||||
},
|
||||
component: () => import('src/pages/Worker/Card/WorkerBusiness.vue'),
|
||||
},
|
||||
{
|
||||
path: 'notes',
|
||||
name: 'NotesCard',
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
describe('Supplier Balance', () => {
|
||||
beforeEach(() => {
|
||||
cy.viewport(1920, 1080);
|
||||
cy.login('developer');
|
||||
cy.visit(`/#/supplier/1/balance`);
|
||||
});
|
||||
|
||||
it('Should load layout', () => {
|
||||
cy.get('.q-page').should('be.visible');
|
||||
});
|
||||
});
|
|
@ -3,9 +3,7 @@ describe('Client balance', () => {
|
|||
beforeEach(() => {
|
||||
cy.viewport(1280, 720);
|
||||
cy.login('developer');
|
||||
cy.visit('#/customer/1101/balance', {
|
||||
timeout: 5000,
|
||||
});
|
||||
cy.visit('#/customer/1101/balance');
|
||||
});
|
||||
it('Should load layout', () => {
|
||||
cy.get('.q-page').should('be.visible');
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
/// <reference types="cypress" />
|
||||
// https://redmine.verdnatura.es/issues/8419
|
||||
describe.skip('InvoiceInCorrective', () => {
|
||||
const createCorrective = '.q-menu > .q-list > :nth-child(6) > .q-item__section';
|
||||
const rectificativeSection = '.q-drawer-container .q-list > a:nth-child(6)';
|
||||
describe('InvoiceInCorrective', () => {
|
||||
const saveDialog = '.q-card > .q-card__actions > .q-btn--standard ';
|
||||
|
||||
it('should create a correcting invoice', () => {
|
||||
|
@ -13,13 +10,13 @@ describe.skip('InvoiceInCorrective', () => {
|
|||
|
||||
cy.openActionsDescriptor();
|
||||
|
||||
cy.get(createCorrective).click();
|
||||
cy.dataCy('createCorrectiveItem').click();
|
||||
cy.get(saveDialog).click();
|
||||
cy.wait('@corrective').then((interception) => {
|
||||
const correctingId = interception.response.body;
|
||||
cy.url().should('include', `/invoice-in/${correctingId}/summary`);
|
||||
cy.visit(`/#/invoice-in/${correctingId}/corrective`);
|
||||
});
|
||||
cy.get(rectificativeSection).click();
|
||||
cy.get('tbody > tr:visible').should('have.length', 1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
describe('InvoiceInDescriptor', () => {
|
||||
const dialogBtns = '.q-card__actions button';
|
||||
const firstDescritorOpt = '.q-menu > .q-list > :nth-child(1) > .q-item__section';
|
||||
const isBookedField = '.q-card:nth-child(3) .vn-label-value:nth-child(5) .q-checkbox';
|
||||
const book = '.summaryHeader > .no-wrap > .q-btn';
|
||||
const firstDescritorOpt = '.q-menu > .q-list > :nth-child(5) > .q-item__section';
|
||||
const checkbox = ':nth-child(5) > .q-checkbox';
|
||||
|
||||
it('should booking and unbooking the invoice properly', () => {
|
||||
cy.viewport(1280, 720);
|
||||
|
@ -9,13 +9,13 @@ describe('InvoiceInDescriptor', () => {
|
|||
cy.visit('/#/invoice-in/1/summary');
|
||||
cy.waitForElement('.q-page');
|
||||
|
||||
cy.openActionsDescriptor();
|
||||
cy.get(firstDescritorOpt).click();
|
||||
cy.get(dialogBtns).eq(1).click();
|
||||
cy.get(isBookedField).should('have.attr', 'aria-checked', 'true');
|
||||
cy.get(book).click();
|
||||
cy.dataCy('VnConfirm_confirm').click();
|
||||
cy.get(checkbox).invoke('attr', 'aria-checked').should('eq', 'true');
|
||||
|
||||
cy.dataCy('descriptor-more-opts').first().click();
|
||||
cy.get(firstDescritorOpt).click();
|
||||
cy.get(dialogBtns).eq(1).click();
|
||||
cy.get(isBookedField).should('have.attr', 'aria-checked', 'false');
|
||||
cy.dataCy('VnConfirm_confirm').click();
|
||||
cy.get(checkbox).invoke('attr', 'aria-checked').should('eq', 'false');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
/// <reference types="cypress" />
|
||||
describe('InvoiceOut list', () => {
|
||||
const invoice = {
|
||||
Ticket: { val: '8' },
|
||||
Serial: { val: 'Española rapida', type: 'select' },
|
||||
};
|
||||
const invoiceError = {
|
||||
Ticket: { val: '1' },
|
||||
Serial: { val: 'Española rapida', type: 'select' },
|
||||
};
|
||||
const serial = 'Española rapida';
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport(1920, 1080);
|
||||
|
@ -32,14 +25,16 @@ describe('InvoiceOut list', () => {
|
|||
|
||||
it('should give an error when manual invoicing a ticket that is already invoiced', () => {
|
||||
cy.dataCy('vnTableCreateBtn').click();
|
||||
cy.fillInForm(invoiceError);
|
||||
cy.dataCy('InvoiceOutCreateTicketinput').type(1);
|
||||
cy.selectOption('[data-cy="InvoiceOutCreateSerialSelect"]', serial);
|
||||
cy.dataCy('FormModelPopup_save').click();
|
||||
cy.checkNotification('This ticket is already invoiced');
|
||||
});
|
||||
|
||||
it('should create a manual invoice and enter to its summary', () => {
|
||||
cy.dataCy('vnTableCreateBtn').click();
|
||||
cy.fillInForm(invoice);
|
||||
cy.dataCy('InvoiceOutCreateTicketinput').type(8);
|
||||
cy.selectOption('[data-cy="InvoiceOutCreateSerialSelect"]', serial);
|
||||
cy.dataCy('FormModelPopup_save').click();
|
||||
cy.checkNotification('Data created');
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/// <reference types="cypress" />
|
||||
describe('Item shelving', () => {
|
||||
describe('ItemBarcodes', () => {
|
||||
beforeEach(() => {
|
||||
cy.viewport(1920, 1080);
|
||||
cy.login('developer');
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
/// <reference types="cypress" />
|
||||
describe('Item type', () => {
|
||||
const workerError = 'employeeNick';
|
||||
const worker = 'buyerNick';
|
||||
const category = 'Artificial';
|
||||
const type = 'Flower';
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport(1920, 1080);
|
||||
cy.login('developer');
|
||||
|
@ -8,32 +13,24 @@ describe('Item type', () => {
|
|||
|
||||
it('should throw an error if the code already exists', () => {
|
||||
cy.dataCy('vnTableCreateBtn').click();
|
||||
cy.get(
|
||||
'div.fit > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > [data-cy="Code_input"]'
|
||||
).type('ALS');
|
||||
cy.get(
|
||||
'div.fit > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > [data-cy="Name_input"]'
|
||||
).type('Alstroemeria');
|
||||
cy.dataCy('Worker_select').type('employeeNick');
|
||||
cy.get('.q-menu .q-item').contains('employeeNick').click();
|
||||
cy.dataCy('ItemCategory_select').type('Artificial');
|
||||
cy.get('.q-menu .q-item').contains('Artificial').click();
|
||||
cy.dataCy('codeInput').type('ALS');
|
||||
cy.dataCy('nameInput').type('Alstroemeria');
|
||||
cy.dataCy('vnWorkerSelect').type(workerError);
|
||||
cy.get('.q-menu .q-item').contains(workerError).click();
|
||||
cy.dataCy('itemCategorySelect').type(category);
|
||||
cy.get('.q-menu .q-item').contains(category).click();
|
||||
cy.dataCy('FormModelPopup_save').click();
|
||||
cy.checkNotification('An item type with the same code already exists');
|
||||
});
|
||||
|
||||
it('should create a new type', () => {
|
||||
cy.dataCy('vnTableCreateBtn').click();
|
||||
cy.get(
|
||||
'div.fit > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > [data-cy="Code_input"]'
|
||||
).type('LIL');
|
||||
cy.get(
|
||||
'div.fit > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > [data-cy="Name_input"]'
|
||||
).type('Lilium');
|
||||
cy.dataCy('Worker_select').type('buyerNick');
|
||||
cy.get('.q-menu .q-item').contains('buyerNick').click();
|
||||
cy.dataCy('ItemCategory_select').type('Flower');
|
||||
cy.get('.q-menu .q-item').contains('Flower').click();
|
||||
cy.dataCy('codeInput').type('LIL');
|
||||
cy.dataCy('nameInput').type('Lilium');
|
||||
cy.dataCy('vnWorkerSelect').type(worker);
|
||||
cy.get('.q-menu .q-item').contains(worker).click();
|
||||
cy.dataCy('itemCategorySelect').type(type);
|
||||
cy.get('.q-menu .q-item').contains(type).click();
|
||||
cy.dataCy('FormModelPopup_save').click();
|
||||
cy.checkNotification('Data created');
|
||||
});
|
||||
|
|
|
@ -14,17 +14,16 @@ describe('ZoneWarehouse', () => {
|
|||
|
||||
it('should throw an error if the warehouse chosen is already put in the zone', () => {
|
||||
cy.addBtnClick();
|
||||
cy.selectOption('[data-cy="Warehouse_select"]', 'Warehouse Two');
|
||||
cy.dataCy('Warehouse_select').type('Warehouse Two{enter}');
|
||||
cy.get(saveBtn).click();
|
||||
cy.checkNotification(dataError);
|
||||
});
|
||||
// https://redmine.verdnatura.es/issues/8425
|
||||
it.skip('should create & remove a warehouse', () => {
|
||||
|
||||
it('should create & remove a warehouse', () => {
|
||||
cy.addBtnClick();
|
||||
cy.fillInForm(data);
|
||||
cy.get(saveBtn).click();
|
||||
cy.get('.q-mt-lg > .q-btn--standard').click();
|
||||
|
||||
cy.get('tbody > :nth-child(2) > :nth-child(2) > .q-icon').click();
|
||||
cy.get('[title="Confirm"]').click();
|
||||
|
||||
|
|
Loading…
Reference in New Issue