Merge remote-tracking branch 'origin/dev' into formModel_mapper
gitea/salix-front/pipeline/pr-dev This commit looks good
Details
gitea/salix-front/pipeline/pr-dev This commit looks good
Details
This commit is contained in:
commit
4892e96755
285
CHANGELOG.md
285
CHANGELOG.md
|
@ -1,3 +1,288 @@
|
||||||
|
# Version 25.06 - 2025-02-18
|
||||||
|
|
||||||
|
### Added 🆕
|
||||||
|
|
||||||
|
- chore: refs #7405 remove examples documentation by:jorgep
|
||||||
|
- chore: refs #7405 remove VitePress cache files and update .gitignore by:jorgep
|
||||||
|
- chore: refs #8316 remove search and searchInfo entries from shelving in English and Spanish locales by:jtubau
|
||||||
|
- feat: #8258 added hover and description to uppercase button by:PAU ROVIRA ROSALENY
|
||||||
|
- feat: add addressFk by:Javier Segarra
|
||||||
|
- feat: add inactive car icon by:jorgep
|
||||||
|
- feat: downgrade pnpm by:Javier Segarra
|
||||||
|
- feat: new command by:Javier Segarra
|
||||||
|
- feat: refs #6629 addressObservation by:robert
|
||||||
|
- feat: refs #6629 change values by:robert
|
||||||
|
- feat: refs #6629 customerAddressEdit by:robert
|
||||||
|
- feat: refs #6629 delete consolelog by:robert
|
||||||
|
- feat: refs #6629 traduction message by:robert
|
||||||
|
- feat: refs #6629 update by:robert
|
||||||
|
- feat: refs #6822 by:robert
|
||||||
|
- feat: refs #6822 change request by:robert
|
||||||
|
- feat: refs #6822 change traduction Partial delay (origin/6822-changeTitlePartialDelay) by:robert
|
||||||
|
- feat: refs #6822 redirection by:robert
|
||||||
|
- feat: refs #6943 addressPropagate by:Javier Segarra
|
||||||
|
- feat: refs #6943 updateAndEmit param as object by:Javier Segarra
|
||||||
|
- feat: refs #7065 created unit tests for UserPanel by:provira
|
||||||
|
- feat: refs #7068 created VnVisibleColumns unit test by:Jon
|
||||||
|
- feat: refs #7103 created test for VnSearchbar by:provira
|
||||||
|
- feat: refs #7134 #7124 handle columns by:Javier Segarra
|
||||||
|
- feat: refs #7134 #7124 handle filter by:Javier Segarra
|
||||||
|
- feat: refs #7134 #7134 Create new route by:Javier Segarra
|
||||||
|
- feat: refs #7134 #7134 Create SupplierBalance layout by:Javier Segarra
|
||||||
|
- feat: refs #7134 #7134 split newPayment by:Javier Segarra
|
||||||
|
- feat: refs #7134 add bank by:Javier Segarra
|
||||||
|
- feat: refs #7134 apply supplierBalanceFilter by:Javier Segarra
|
||||||
|
- feat: refs #7134 default currency parameter by:Javier Segarra
|
||||||
|
- feat: refs #7134 minor changes by:Javier Segarra
|
||||||
|
- feat: refs #7134 order by:Javier Segarra
|
||||||
|
- feat: refs #7134 perf VnTable by:Javier Segarra
|
||||||
|
- feat: refs #7134 remove add btn by:Javier Segarra
|
||||||
|
- feat: refs #7134 unremovableParams by:Javier Segarra
|
||||||
|
- feat: refs #7134 use tableFooter by:Javier Segarra
|
||||||
|
- feat: refs #7134 use VnAccountNumber by:Javier Segarra
|
||||||
|
- feat: refs #7134 vnTable setTableFooter by:Javier Segarra
|
||||||
|
- feat: refs #7184 added myTeam filter at WorkerFilter by:Jon
|
||||||
|
- feat: refs #7196 update vite and q-calendar by:alexm
|
||||||
|
- feat: refs #7305 deleted warnings by:Jon
|
||||||
|
- feat: refs #7308 remove warning by:Javier Segarra
|
||||||
|
- feat: refs #7317 deleted warnings in fiscalData and dms by:Jon
|
||||||
|
- feat: refs #7322 add address selection for ticket transfer by:jtubau
|
||||||
|
- feat: refs #7405 add initial documentation and components for Lilium by:jorgep
|
||||||
|
- feat: refs #7405 add navigation links and documentation for useArrayData composable by:jorgep
|
||||||
|
- feat: refs #7826 add error handling and refresh icon to NavBar by:Javier Segarra
|
||||||
|
- feat: refs #8077 change request by:robert
|
||||||
|
- feat: refs #8077 changes request by:robert
|
||||||
|
- feat: refs #8077 sumDefaulter by:robert
|
||||||
|
- feat: refs #8120 added new style to summary popups by:Jon
|
||||||
|
- feat: refs #8120 use new prop in the requierd modules by:Jon
|
||||||
|
- feat: refs #8197 create advancedMenu and add in VnSection by:alexm
|
||||||
|
- feat: refs #8316 added order param by:jtubau
|
||||||
|
- feat: refs #8316 add slots on VnTable from VnFilterPanel by:alexm
|
||||||
|
- feat: refs #8316 parking inside shelving by:alexm
|
||||||
|
- feat: refs #8322 added RouteRoadmap and Agency by:provira
|
||||||
|
- feat: refs #8322 fix route.js and unify with /agency by:alexm
|
||||||
|
- feat: refs #8322 fix route.js and unify with /roadmap by:alexm
|
||||||
|
- feat: refs #8339 define global.spreview by:Javier Segarra
|
||||||
|
- feat: refs #8381 add carrier field to travel thermographs and update localization by:jgallego
|
||||||
|
- feat: refs #8387 changes by:robert
|
||||||
|
- feat: refs #8387 changes request by:robert
|
||||||
|
- feat: refs #8387 crudModel by:robert
|
||||||
|
- feat: refs #8387 refs#8387 change request by:robert
|
||||||
|
- feat: refs #8395 added computed to calculate and display amounts by:provira
|
||||||
|
- feat: refs #8395 added total column in invoiceInVat by:provira
|
||||||
|
- feat: refs #8398 modify previous changes by:robert
|
||||||
|
- feat: refs #8398 moveTicketsFuture by:robert
|
||||||
|
- feat: refs #8409 added VnSelectSupplier by:Jon
|
||||||
|
- feat: refs #8410 added new feature to module searchbar by:provira
|
||||||
|
- feat: refs #8418 add data-cy attribute for print labels button in EntryBuysTableDialog by:jtubau
|
||||||
|
- feat: refs #8450 added new version by:Jon
|
||||||
|
- feat: toCurrency in risk icon by:Javier Segarra
|
||||||
|
- feat: update quasar version by:Javier Segarra
|
||||||
|
- feat: update vitest to 1.0 by:Javier Segarra
|
||||||
|
- feat: update vue to 3.5 by:Javier Segarra
|
||||||
|
- style: customerDescriptor by:Javier Segarra
|
||||||
|
- style: refs #6943 order imports by:Javier Segarra
|
||||||
|
|
||||||
|
### Changed 📦
|
||||||
|
|
||||||
|
- feat: refs #7134 perf VnTable by:Javier Segarra
|
||||||
|
- perf: pnpm-lock by:Javier Segarra
|
||||||
|
- perf: refs #7134 #7134 changes by:Javier Segarra
|
||||||
|
- perf: refs #7134 #7134 fix filter panel by:Javier Segarra
|
||||||
|
- perf: refs #7134 #7134 global dialog newPayment and composable getRisk by:Javier Segarra
|
||||||
|
- perf: refs #7134 currencies fetch by:Javier Segarra
|
||||||
|
- perf: refs #7134 format columns by:Javier Segarra
|
||||||
|
- perf: refs #7134 imports by:Javier Segarra
|
||||||
|
- perf: refs #7134 use ForModelPopup by:Javier Segarra
|
||||||
|
- perf: refs #7134 use map-key by:Javier Segarra
|
||||||
|
- perf: refs #7134 use where to get only EUR currency by:Javier Segarra
|
||||||
|
- perf: refs #7196 update eslint by:alexm
|
||||||
|
- perf: refs #7308 call 1 time useSession by:Javier Segarra
|
||||||
|
- perf: refs #7826 code onError by:Javier Segarra
|
||||||
|
- perf: refs #7826 improve condition by:Javier Segarra
|
||||||
|
- perf: refs #8197 default is object by:alexm
|
||||||
|
- perf: refs #8197 fix and imrpove filters by:alexm
|
||||||
|
- perf: refs #8197 perf by:alexm
|
||||||
|
- perf: refs #8339 minor changes by:Javier Segarra
|
||||||
|
- perf: refs #8339 removew preview tag by:Javier Segarra
|
||||||
|
- perf: use util in OutLayout by:Javier Segarra
|
||||||
|
- perf: vitest to 0.34.0 by:Javier Segarra
|
||||||
|
- refactor: advancedMenu button inside searchbar by:alexm
|
||||||
|
- refactor: move remaining data to descriptorMenu by:Jon
|
||||||
|
- refactor: refs #6822 transferEntry moved to descriptor menu by:robert
|
||||||
|
- refactor: refs #7068 adjust variables by:Jon
|
||||||
|
- refactor: refs #7068 requested changes by:Jon
|
||||||
|
- refactor: refs #7317 requested changes by:Jon
|
||||||
|
- refactor: refs #7322 extract repeated functions and create tests by:jtubau
|
||||||
|
- refactor: refs #7322 update API functions to accept filters for enhanced data retrieval by:jtubau
|
||||||
|
- refactor: refs #7322 update getAgencies to handle client and return default agency by:jtubau
|
||||||
|
- refactor: refs #8120 change prop and classes' names by:Jon
|
||||||
|
- refactor: refs #8120 requested changes by:Jon
|
||||||
|
- refactor: refs #8120 use only defineProps by:Jon
|
||||||
|
- refactor: refs #8316 added shelvingCardBeta and localizations by:jtubau
|
||||||
|
- refactor: refs #8316 add new localization keys and update existing ones for invoiceIn components by:jtubau
|
||||||
|
- refactor: refs #8316 add new localization keys and update existing ones for invoiceOut components by:jtubau
|
||||||
|
- refactor: refs #8316 moved userFilter to array-data-props by:jtubau
|
||||||
|
- refactor: refs #8316 remove invoiceInSearchbar by:alexm
|
||||||
|
- refactor: refs #8316 remove unused ItemTypeSearchbar component by:jtubau
|
||||||
|
- refactor: refs #8316 restore exprBuilder function to filter invoice data by:jtubau
|
||||||
|
- refactor: refs #8316 restore filter for supplier and related entities in InvoiceInCard by:jtubau
|
||||||
|
- refactor: refs #8316 unify router item and itemType by:alexm
|
||||||
|
- refactor: refs #8316 update prefix casing for InvoiceIn component by:jtubau
|
||||||
|
- refactor: refs #8316 update Spanish translations for ItemsFilterPanel by:jtubau
|
||||||
|
- refactor: refs #8316 used VnSection and VnBetaCard by:jtubau
|
||||||
|
- refactor: refs #8316 used VnSection and VnCardBeta by:jtubau
|
||||||
|
- refactor: refs #8316 used VnSection and VnCardBeta on ItemCard by:jtubau
|
||||||
|
- refactor: refs #8322 changed Route component to use VnSection/VnCardBeta by:provira
|
||||||
|
- refactor: refs #8322 changed Travel component to use VnSection/VnCardBeta by:provira
|
||||||
|
- refactor: refs #8351 deleted skip and fixed TicketList e2e by:Jon
|
||||||
|
- refactor: refs #8351 put appropriate name by:Jon
|
||||||
|
- refactor: refs #8380 remove unnecessary stubs in VnImg test wrapper by:jtubau
|
||||||
|
- refactor: refs #8381 update travel data handling in TravelThermographs component by:jgallego
|
||||||
|
- refactor: refs #8409 deleted unused variable by:Jon
|
||||||
|
- refactor: refs #8409 use defineModel instead or defineProps by:Jon
|
||||||
|
- refactor: refs #8410 restructured code by:provira
|
||||||
|
- refactor: refs #8418 remove commented issue reference from myEntry.spec.js by:jtubau
|
||||||
|
- refactor: refs #8418 update data-cy attribute for print labels button in EntryBuysTableDialog by:jtubau
|
||||||
|
- refactor: refs #8418 update selector to use cy.dataCy instead cy.get by:jtubau
|
||||||
|
- refactor: request changes by:Jon
|
||||||
|
|
||||||
|
### Fixed 🛠️
|
||||||
|
|
||||||
|
- feat: refs #8322 fix route.js and unify with /agency by:alexm
|
||||||
|
- feat: refs #8322 fix route.js and unify with /roadmap by:alexm
|
||||||
|
- fix: added witdth when opening summary by:Jon
|
||||||
|
- fix: defineProps not import by:alexm
|
||||||
|
- fix: deleted duplicate request by:Jon
|
||||||
|
- fix: fixed descriptor e2e by:Jon
|
||||||
|
- fix: fixed InvoiceOutList e2e by:Jon
|
||||||
|
- fix: fixed list and e2e by:Jon
|
||||||
|
- fix: fixed pagiante by:Jon
|
||||||
|
- fix: fixed rectificative class by:Jon
|
||||||
|
- fix: fixed states column in claim list and filter by:Jon
|
||||||
|
- fix: fixed VnLocation and warnings by:Jon
|
||||||
|
- fix: fixed wagons e2e (origin/Fix-WagonModuleE2E) by:Jon
|
||||||
|
- fix: fix grid two by:carlossa
|
||||||
|
- fix: improve method (origin/warmfix_reload_scriptIsMissing) by:Javier Segarra
|
||||||
|
- fix: init by:Javier Segarra
|
||||||
|
- fix: minor cli error by:Javier Segarra
|
||||||
|
- fix: modified front to show new field by:Jon
|
||||||
|
- fix: move dialog to descriptorMenu by:Jon
|
||||||
|
- fix: refs #6553 clean pr by:carlossa
|
||||||
|
- fix: refs #6553 fix BeforeMount filters by:carlossa
|
||||||
|
- fix: refs #6553 fix front and translations by:carlossa
|
||||||
|
- fix: refs #6553 fix pr by:carlossa
|
||||||
|
- fix: refs #6553 fix PR, fix vnTableCard by:carlossa
|
||||||
|
- fix: refs #6553 fix qScrollArea by:carlossa
|
||||||
|
- fix: refs #6553 fix summary by:carlossa
|
||||||
|
- fix: refs #6553 fix user-filter by:carlossa
|
||||||
|
- fix: refs #6553 fix vnTable by:carlossa
|
||||||
|
- fix: refs #6553 fix vnTable css by:carlossa
|
||||||
|
- fix: refs #6553 front advanced by:carlossa
|
||||||
|
- fix: refs #6553 front by:carlossa
|
||||||
|
- fix: refs #6553 label css by:carlossa
|
||||||
|
- fix: refs #6553 onBeforeMount by:carlossa
|
||||||
|
- fix: refs #6943 minor changes by:Javier Segarra
|
||||||
|
- fix: refs #6943 redirect when change addressId by:Javier Segarra
|
||||||
|
- fix: refs #6943 required by:Javier Segarra
|
||||||
|
- fix: refs #7065 made consts for repeated values by:provira
|
||||||
|
- fix: refs #7065 removed unnecessary code by:provira
|
||||||
|
- fix: refs #7103 removed unused code on spies by:provira
|
||||||
|
- fix: refs #7103 updated tests for new changes by:provira
|
||||||
|
- fix: refs #7103 used consts for repeated variables by:provira
|
||||||
|
- fix: refs #7134 getRiskComposable by:Javier Segarra
|
||||||
|
- fix: refs #7134 minor change by:Javier Segarra
|
||||||
|
- fix: refs #7134 params filter by:Javier Segarra
|
||||||
|
- fix: refs #7134 remove risk by:Javier Segarra
|
||||||
|
- fix: refs #7134 remove supplierRisk by:Javier Segarra
|
||||||
|
- fix: refs #7134 solve comments by:Javier Segarra
|
||||||
|
- fix: refs #7196 not neccessary by:alexm
|
||||||
|
- fix: refs #7196 sass by:alexm
|
||||||
|
- fix: refs #7322 handle null responses in client, agency and address fetching by:jtubau
|
||||||
|
- fix: refs #7826 init by:Javier Segarra
|
||||||
|
- fix: refs #8120 ticket descriptor & summary by:Jon
|
||||||
|
- fix: refs #8172 Remove unused row and column fields from ParkingBasicData by:guillermo
|
||||||
|
- fix: refs #8197 improve code robustness by adding optional chaining and fixing syntax errors by:alexm
|
||||||
|
- fix: refs #8197 use rightMenu by:alexm
|
||||||
|
- fix: refs #8197 use RightMenu in subsections by:alexm
|
||||||
|
- fix: refs #8227 clean pr (origin/8227-warmfixRoute) by:carlossa
|
||||||
|
- fix: refs #8227 fix front descriptor, Form by:carlossa
|
||||||
|
- fix: refs #8227 warmfix by:carlossa
|
||||||
|
- fix: refs #8316 advanced-menu by:alexm
|
||||||
|
- fix: refs #8316 filter by:alexm
|
||||||
|
- fix: refs #8316 fix broken localizations for entry descriptor menu and items filter panel by:jtubau
|
||||||
|
- fix: refs #8316 icon by:alexm
|
||||||
|
- fix: refs #8316 redirections by:alexm
|
||||||
|
- fix: refs #8316 translations by:alexm
|
||||||
|
- fix: refs #8316 user-filter by:alexm
|
||||||
|
- fix: refs #8322 add userFilter by:alexm
|
||||||
|
- fix: refs #8322 filter and params by:alexm
|
||||||
|
- fix: refs #8322 fixed route creation url by:provira
|
||||||
|
- fix: refs #8322 moved filter inside array-data-props by:provira
|
||||||
|
- fix: refs #8322 use userFilter by:alexm
|
||||||
|
- fix: refs #8347 remove skip, fix unpaid by:carlossa
|
||||||
|
- fix: refs #8352 fix datacy by:carlossa
|
||||||
|
- fix: refs #8352 fix right by:carlossa
|
||||||
|
- fix: refs #8352 fix rightPanel vnLog by:carlossa
|
||||||
|
- fix: refs #8381 update travel data fetching to use correct URL and include necessary fields by:jgallego
|
||||||
|
- fix: refs #8381 update travel data reference in TravelThermographs component by:jgallego
|
||||||
|
- fix: refs #8395 update label for total column by:provira
|
||||||
|
- fix: refs #8409 deleted code due to merge by:Jon
|
||||||
|
- fix: refs #8409 deleted code of merge by:Jon
|
||||||
|
- fix: refs #8410 removed ref from searching boolean by:provira
|
||||||
|
- fix: refs #8410 removed unused code by:provira
|
||||||
|
- fix: refs #8410 removed unused condition by:provira
|
||||||
|
- fix: refs #8410 removed unused ref by:provira
|
||||||
|
- fix: refs #8410 simplified searchModule function by:provira
|
||||||
|
- fix: refs #8418 adjusted route for button click by:jtubau
|
||||||
|
- fix: refs #8418 correct casing in translation keys for supplier reference and issued date labels by:jtubau
|
||||||
|
- fix: refs #8419 modified list and fixed e2e by:Jon
|
||||||
|
- fix: refs #8420 ensure search bar is visible before typing and enable details test by:jtubau
|
||||||
|
- fix: refs #8422 fixed ItemTag e2e test not working by:provira
|
||||||
|
- fix: refs #8422 optimized get and dataCy by:provira
|
||||||
|
- fix: refs #8423 fixed zoneWarehouse e2e test not working by:provira
|
||||||
|
- fix: refs #8423 removed data-cy usage by:provira
|
||||||
|
- fix: refs #8423 used dataCy to get data-cy by:provira
|
||||||
|
- fix: refs #8524 parking section router by:alexm
|
||||||
|
- fix: refs #8524 parking test (origin/8524-devToTest, 8524-devToTest) by:alexm
|
||||||
|
- fix: remove console by:Javier Segarra
|
||||||
|
- fix: replace labels by:Javier Segarra
|
||||||
|
- fix: rightAdvancedMenu by:alexm
|
||||||
|
- fix: routeCard use customUrl by:alexm
|
||||||
|
- fix: show descriptors when click on it by:Javier Segarra
|
||||||
|
- fix: update query parameters for thermograph routing by:jgallego
|
||||||
|
- fix: update selector for buyLabel button in myEntry.spec.js (origin/fix-myEntryTest) by:jtubau
|
||||||
|
- fix: update setupNodeEvents to use async/await for plugin import by:jgallego
|
||||||
|
- fix: use model by:alexm
|
||||||
|
- fix: use rightMenu by:alexm
|
||||||
|
- fix(VnSection): destroy data when unmounted by:alexm
|
||||||
|
- fix(VnSection): refs #8197 check route by:alexm
|
||||||
|
- fix(WorkerBusiness): fix card label by:alexm
|
||||||
|
- fix: workerSummary by:alexm
|
||||||
|
- perf: refs #7134 #7134 fix filter panel by:Javier Segarra
|
||||||
|
- perf: refs #8197 fix and imrpove filters by:alexm
|
||||||
|
- refactor: refs #8316 update prefix casing for InvoiceIn component by:jtubau
|
||||||
|
- refactor: refs #8351 deleted skip and fixed TicketList e2e by:Jon
|
||||||
|
- refs #6553 fix business slot by:carlossa
|
||||||
|
- refs #6553 fix business summary by:carlossa
|
||||||
|
- refs #6553 fix business summary traductions by:carlossa
|
||||||
|
- refs #6553 fix front ibject by:carlossa
|
||||||
|
- refs #6553 fix front trad by:carlossa
|
||||||
|
- refs #6553 fix names by:carlossa
|
||||||
|
- refs #6553 fix reactivateWorker by:carlossa
|
||||||
|
- refs #6553 fix relations by:carlossa
|
||||||
|
- refs #6553 fix VnTable by:carlossa
|
||||||
|
- refs #7917 fix routeCard by:carlossa
|
||||||
|
- revert: refs #7134 change by:Javier Segarra
|
||||||
|
- revert: refs #7134 customer changes by:Javier Segarra
|
||||||
|
- revert: vitest to 0.31.1 by:Javier Segarra
|
||||||
|
- test: fix clientList spec by:Javier Segarra
|
||||||
|
- test: fix component by:Javier Segarra
|
||||||
|
- test: fix VnSearchbar by:alexm
|
||||||
|
- test: refs #6943 fix tests by:Javier Segarra
|
||||||
|
- test: refs #7308 fix axios.spec.js by:Javier Segarra
|
||||||
|
- test: refs #8524 fix by:alexm
|
||||||
|
|
||||||
# Version 25.04 - 2025-01-28
|
# Version 25.04 - 2025-01-28
|
||||||
|
|
||||||
### Added 🆕
|
### Added 🆕
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "salix-front",
|
"name": "salix-front",
|
||||||
"version": "25.08.0",
|
"version": "25.10.0",
|
||||||
"description": "Salix frontend",
|
"description": "Salix frontend",
|
||||||
"productName": "Salix",
|
"productName": "Salix",
|
||||||
"author": "Verdnatura",
|
"author": "Verdnatura",
|
||||||
|
|
|
@ -30,22 +30,5 @@ export default {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
form.addEventListener('keyup', function (evt) {
|
|
||||||
if (evt.key === 'Enter' && !that.$attrs['prevent-submit']) {
|
|
||||||
const input = evt.target;
|
|
||||||
if (input.type == 'textarea' && evt.shiftKey) {
|
|
||||||
evt.preventDefault();
|
|
||||||
let { selectionStart, selectionEnd } = input;
|
|
||||||
input.value =
|
|
||||||
input.value.substring(0, selectionStart) +
|
|
||||||
'\n' +
|
|
||||||
input.value.substring(selectionEnd);
|
|
||||||
selectionStart = selectionEnd = selectionStart + 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
evt.preventDefault();
|
|
||||||
that.onSubmit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnSelectProvince from 'src/components/VnSelectProvince.vue';
|
import VnSelectProvince from 'src/components/VnSelectProvince.vue';
|
||||||
|
@ -21,14 +20,11 @@ const postcodeFormData = reactive({
|
||||||
provinceFk: null,
|
provinceFk: null,
|
||||||
townFk: null,
|
townFk: null,
|
||||||
});
|
});
|
||||||
const townsFetchDataRef = ref(false);
|
|
||||||
const townFilter = ref({});
|
const townFilter = ref({});
|
||||||
|
|
||||||
const countriesRef = ref(false);
|
const countriesRef = ref(false);
|
||||||
const provincesOptions = ref([]);
|
const provincesOptions = ref([]);
|
||||||
const townsOptions = ref([]);
|
|
||||||
const town = ref({});
|
const town = ref({});
|
||||||
const countryFilter = ref({});
|
|
||||||
|
|
||||||
function onDataSaved(formData) {
|
function onDataSaved(formData) {
|
||||||
const newPostcode = {
|
const newPostcode = {
|
||||||
|
@ -51,7 +47,6 @@ async function setCountry(countryFk, data) {
|
||||||
data.townFk = null;
|
data.townFk = null;
|
||||||
data.provinceFk = null;
|
data.provinceFk = null;
|
||||||
data.countryFk = countryFk;
|
data.countryFk = countryFk;
|
||||||
await fetchTowns();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Province
|
// Province
|
||||||
|
@ -60,22 +55,11 @@ async function setProvince(id, data) {
|
||||||
const newProvince = provincesOptions.value.find((province) => province.id == id);
|
const newProvince = provincesOptions.value.find((province) => province.id == id);
|
||||||
if (newProvince) data.countryFk = newProvince.countryFk;
|
if (newProvince) data.countryFk = newProvince.countryFk;
|
||||||
postcodeFormData.provinceFk = id;
|
postcodeFormData.provinceFk = id;
|
||||||
await fetchTowns();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onProvinceCreated(data) {
|
async function onProvinceCreated(data) {
|
||||||
postcodeFormData.provinceFk = data.id;
|
postcodeFormData.provinceFk = data.id;
|
||||||
}
|
}
|
||||||
function provinceByCountry(countryFk = postcodeFormData.countryFk) {
|
|
||||||
return provincesOptions.value
|
|
||||||
.filter((province) => province.countryFk === countryFk)
|
|
||||||
.map(({ id }) => id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Town
|
|
||||||
async function handleTowns(data) {
|
|
||||||
townsOptions.value = data;
|
|
||||||
}
|
|
||||||
function setTown(newTown, data) {
|
function setTown(newTown, data) {
|
||||||
town.value = newTown;
|
town.value = newTown;
|
||||||
data.provinceFk = newTown?.provinceFk ?? newTown;
|
data.provinceFk = newTown?.provinceFk ?? newTown;
|
||||||
|
@ -88,18 +72,6 @@ async function onCityCreated(newTown, formData) {
|
||||||
formData.townFk = newTown;
|
formData.townFk = newTown;
|
||||||
setTown(newTown, formData);
|
setTown(newTown, formData);
|
||||||
}
|
}
|
||||||
async function fetchTowns(countryFk = postcodeFormData.countryFk) {
|
|
||||||
if (!countryFk) return;
|
|
||||||
const provinces = postcodeFormData.provinceFk
|
|
||||||
? [postcodeFormData.provinceFk]
|
|
||||||
: provinceByCountry();
|
|
||||||
townFilter.value.where = {
|
|
||||||
provinceFk: {
|
|
||||||
inq: provinces,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
await townsFetchDataRef.value?.fetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function filterTowns(name) {
|
async function filterTowns(name) {
|
||||||
if (name !== '') {
|
if (name !== '') {
|
||||||
|
@ -108,22 +80,11 @@ async function filterTowns(name) {
|
||||||
like: `%${name}%`,
|
like: `%${name}%`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
await townsFetchDataRef.value?.fetch();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
|
||||||
ref="townsFetchDataRef"
|
|
||||||
:sort-by="['name ASC']"
|
|
||||||
:limit="30"
|
|
||||||
:filter="townFilter"
|
|
||||||
@on-fetch="handleTowns"
|
|
||||||
auto-load
|
|
||||||
url="Towns/location"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormModelPopup
|
<FormModelPopup
|
||||||
url-create="postcodes"
|
url-create="postcodes"
|
||||||
model="postcode"
|
model="postcode"
|
||||||
|
@ -149,14 +110,13 @@ async function filterTowns(name) {
|
||||||
@filter="filterTowns"
|
@filter="filterTowns"
|
||||||
:tooltip="t('Create city')"
|
:tooltip="t('Create city')"
|
||||||
v-model="data.townFk"
|
v-model="data.townFk"
|
||||||
:options="townsOptions"
|
url="Towns/location"
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
:rules="validate('postcode.city')"
|
:rules="validate('postcode.city')"
|
||||||
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
|
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
|
||||||
:emit-value="false"
|
:emit-value="false"
|
||||||
required
|
required
|
||||||
data-cy="locationTown"
|
data-cy="locationTown"
|
||||||
|
sort-by="name ASC"
|
||||||
>
|
>
|
||||||
<template #option="{ itemProps, opt }">
|
<template #option="{ itemProps, opt }">
|
||||||
<QItem v-bind="itemProps">
|
<QItem v-bind="itemProps">
|
||||||
|
@ -197,16 +157,12 @@ async function filterTowns(name) {
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
ref="countriesRef"
|
ref="countriesRef"
|
||||||
:limit="30"
|
|
||||||
:filter="countryFilter"
|
|
||||||
:sort-by="['name ASC']"
|
:sort-by="['name ASC']"
|
||||||
auto-load
|
auto-load
|
||||||
url="Countries"
|
url="Countries"
|
||||||
required
|
required
|
||||||
:label="t('Country')"
|
:label="t('Country')"
|
||||||
hide-selected
|
hide-selected
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
v-model="data.countryFk"
|
v-model="data.countryFk"
|
||||||
:rules="validate('postcode.countryFk')"
|
:rules="validate('postcode.countryFk')"
|
||||||
@update:model-value="(value) => setCountry(value, data)"
|
@update:model-value="(value) => setCountry(value, data)"
|
||||||
|
|
|
@ -62,12 +62,9 @@ const where = computed(() => {
|
||||||
auto-load
|
auto-load
|
||||||
:where="where"
|
:where="where"
|
||||||
url="Autonomies/location"
|
url="Autonomies/location"
|
||||||
:sort-by="['name ASC']"
|
sort-by="name ASC"
|
||||||
:limit="30"
|
|
||||||
:label="t('Autonomy')"
|
:label="t('Autonomy')"
|
||||||
hide-selected
|
hide-selected
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
v-model="data.autonomyFk"
|
v-model="data.autonomyFk"
|
||||||
:rules="validate('province.autonomyFk')"
|
:rules="validate('province.autonomyFk')"
|
||||||
>
|
>
|
||||||
|
|
|
@ -42,7 +42,6 @@ const itemFilter = {
|
||||||
const itemFilterParams = reactive({});
|
const itemFilterParams = reactive({});
|
||||||
const closeButton = ref(null);
|
const closeButton = ref(null);
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const producersOptions = ref([]);
|
|
||||||
const ItemTypesOptions = ref([]);
|
const ItemTypesOptions = ref([]);
|
||||||
const InksOptions = ref([]);
|
const InksOptions = ref([]);
|
||||||
const tableRows = ref([]);
|
const tableRows = ref([]);
|
||||||
|
@ -121,23 +120,17 @@ const selectItem = ({ id }) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
|
||||||
url="Producers"
|
|
||||||
@on-fetch="(data) => (producersOptions = data)"
|
|
||||||
:filter="{ fields: ['id', 'name'], order: 'name ASC', limit: 30 }"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<FetchData
|
<FetchData
|
||||||
url="ItemTypes"
|
url="ItemTypes"
|
||||||
:filter="{ fields: ['id', 'name'], order: 'name ASC', limit: 30 }"
|
:filter="{ fields: ['id', 'name'], order: 'name ASC' }"
|
||||||
order="name"
|
order="name ASC"
|
||||||
@on-fetch="(data) => (ItemTypesOptions = data)"
|
@on-fetch="(data) => (ItemTypesOptions = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<FetchData
|
<FetchData
|
||||||
url="Inks"
|
url="Inks"
|
||||||
:filter="{ fields: ['id', 'name'], order: 'name ASC', limit: 30 }"
|
:filter="{ fields: ['id', 'name'], order: 'name ASC' }"
|
||||||
order="name"
|
order="name ASC"
|
||||||
@on-fetch="(data) => (InksOptions = data)"
|
@on-fetch="(data) => (InksOptions = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
|
@ -152,11 +145,11 @@ const selectItem = ({ id }) => {
|
||||||
<VnInput :label="t('entry.buys.size')" v-model="itemFilterParams.size" />
|
<VnInput :label="t('entry.buys.size')" v-model="itemFilterParams.size" />
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('globals.producer')"
|
:label="t('globals.producer')"
|
||||||
:options="producersOptions"
|
|
||||||
hide-selected
|
hide-selected
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
v-model="itemFilterParams.producerFk"
|
v-model="itemFilterParams.producerFk"
|
||||||
|
url="Producers"
|
||||||
|
:fields="['id', 'name']"
|
||||||
|
sort-by="name ASC"
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('globals.type')"
|
:label="t('globals.type')"
|
||||||
|
|
|
@ -124,7 +124,7 @@ const selectTravel = ({ id }) => {
|
||||||
<FetchData
|
<FetchData
|
||||||
url="AgencyModes"
|
url="AgencyModes"
|
||||||
@on-fetch="(data) => (agenciesOptions = data)"
|
@on-fetch="(data) => (agenciesOptions = data)"
|
||||||
:filter="{ fields: ['id', 'name'], order: 'name ASC', limit: 30 }"
|
:filter="{ fields: ['id', 'name'], order: 'name ASC' }"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<FetchData
|
<FetchData
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { onMounted, onUnmounted, computed, ref, watch, nextTick } from 'vue';
|
import { onMounted, onUnmounted, computed, ref, watch, nextTick, useAttrs } from 'vue';
|
||||||
import { onBeforeRouteLeave, useRouter, useRoute } from 'vue-router';
|
import { onBeforeRouteLeave, useRouter, useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
@ -23,6 +23,7 @@ const { validate } = useValidator();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const myForm = ref(null);
|
const myForm = ref(null);
|
||||||
|
const attrs = useAttrs();
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
url: {
|
url: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -107,14 +108,14 @@ const isLoading = ref(false);
|
||||||
const isResetting = ref(false);
|
const isResetting = ref(false);
|
||||||
const hasChanges = ref(!$props.observeFormChanges);
|
const hasChanges = ref(!$props.observeFormChanges);
|
||||||
const originalData = computed(() => state.get(modelValue));
|
const originalData = computed(() => state.get(modelValue));
|
||||||
const formData = ref({});
|
const formData = ref();
|
||||||
const defaultButtons = computed(() => ({
|
const defaultButtons = computed(() => ({
|
||||||
save: {
|
save: {
|
||||||
dataCy: 'saveDefaultBtn',
|
dataCy: 'saveDefaultBtn',
|
||||||
color: 'primary',
|
color: 'primary',
|
||||||
icon: 'save',
|
icon: 'save',
|
||||||
label: 'globals.save',
|
label: 'globals.save',
|
||||||
click: () => myForm.value.onSubmit(false),
|
click: async () => await save(),
|
||||||
type: 'submit',
|
type: 'submit',
|
||||||
},
|
},
|
||||||
reset: {
|
reset: {
|
||||||
|
@ -135,7 +136,8 @@ onMounted(async () => {
|
||||||
|
|
||||||
if (!$props.formInitialData) {
|
if (!$props.formInitialData) {
|
||||||
if ($props.autoLoad && $props.url) await fetch();
|
if ($props.autoLoad && $props.url) await fetch();
|
||||||
else if (arrayData.store.data) updateAndEmit('onFetch', arrayData.store.data);
|
else if (arrayData.store.data)
|
||||||
|
updateAndEmit('onFetch', { val: arrayData.store.data });
|
||||||
}
|
}
|
||||||
if ($props.observeFormChanges) {
|
if ($props.observeFormChanges) {
|
||||||
watch(
|
watch(
|
||||||
|
@ -155,7 +157,7 @@ onMounted(async () => {
|
||||||
if (!$props.url)
|
if (!$props.url)
|
||||||
watch(
|
watch(
|
||||||
() => arrayData.store.data,
|
() => arrayData.store.data,
|
||||||
(val) => updateAndEmit('onFetch', val),
|
(val) => updateAndEmit('onFetch', { val }),
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@ -201,15 +203,14 @@ async function fetch() {
|
||||||
});
|
});
|
||||||
if (Array.isArray(data)) data = data[0] ?? {};
|
if (Array.isArray(data)) data = data[0] ?? {};
|
||||||
|
|
||||||
updateAndEmit('onFetch', data);
|
updateAndEmit('onFetch', { val: data });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
state.set(modelValue, {});
|
state.set(modelValue, {});
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save(prevent = false) {
|
async function save() {
|
||||||
if (prevent) return;
|
|
||||||
if ($props.observeFormChanges && !hasChanges.value)
|
if ($props.observeFormChanges && !hasChanges.value)
|
||||||
return notify('globals.noChanges', 'negative');
|
return notify('globals.noChanges', 'negative');
|
||||||
|
|
||||||
|
@ -229,7 +230,11 @@ async function save(prevent = false) {
|
||||||
|
|
||||||
if ($props.urlCreate) notify('globals.dataCreated', 'positive');
|
if ($props.urlCreate) notify('globals.dataCreated', 'positive');
|
||||||
|
|
||||||
updateAndEmit('onDataSaved', formData.value, response?.data);
|
updateAndEmit('onDataSaved', {
|
||||||
|
val: formData.value,
|
||||||
|
res: response?.data,
|
||||||
|
old: originalData.value,
|
||||||
|
});
|
||||||
if ($props.reload) await arrayData.fetch({});
|
if ($props.reload) await arrayData.fetch({});
|
||||||
hasChanges.value = false;
|
hasChanges.value = false;
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -244,7 +249,7 @@ async function saveAndGo() {
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
formData.value = JSON.parse(JSON.stringify(originalData.value));
|
formData.value = JSON.parse(JSON.stringify(originalData.value));
|
||||||
updateAndEmit('onFetch', originalData.value);
|
updateAndEmit('onFetch', { val: originalData.value });
|
||||||
if ($props.observeFormChanges) {
|
if ($props.observeFormChanges) {
|
||||||
hasChanges.value = false;
|
hasChanges.value = false;
|
||||||
isResetting.value = true;
|
isResetting.value = true;
|
||||||
|
@ -266,11 +271,11 @@ function filter(value, update, filterOptions) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAndEmit(evt, val, res) {
|
function updateAndEmit(evt, { val, res, old } = { val: null, res: null, old: null }) {
|
||||||
state.set(modelValue, val);
|
state.set(modelValue, val);
|
||||||
if (!$props.url) arrayData.store.data = val;
|
if (!$props.url) arrayData.store.data = val;
|
||||||
|
|
||||||
emit(evt, state.get(modelValue), res);
|
emit(evt, state.get(modelValue), res, old);
|
||||||
}
|
}
|
||||||
|
|
||||||
function trimData(data) {
|
function trimData(data) {
|
||||||
|
@ -286,6 +291,22 @@ function onBeforeSave(formData, originalData) {
|
||||||
formData,
|
formData,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
async function onKeyup(evt) {
|
||||||
|
if (evt.key === 'Enter' && !('prevent-submit' in attrs)) {
|
||||||
|
const input = evt.target;
|
||||||
|
if (input.type == 'textarea' && evt.shiftKey) {
|
||||||
|
let { selectionStart, selectionEnd } = input;
|
||||||
|
input.value =
|
||||||
|
input.value.substring(0, selectionStart) +
|
||||||
|
'\n' +
|
||||||
|
input.value.substring(selectionEnd);
|
||||||
|
selectionStart = selectionEnd = selectionStart + 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
save,
|
save,
|
||||||
isLoading,
|
isLoading,
|
||||||
|
@ -300,12 +321,12 @@ defineExpose({
|
||||||
<QForm
|
<QForm
|
||||||
ref="myForm"
|
ref="myForm"
|
||||||
v-if="formData"
|
v-if="formData"
|
||||||
@submit="save(!!$event)"
|
@submit.prevent
|
||||||
|
@keyup.prevent="onKeyup"
|
||||||
@reset="reset"
|
@reset="reset"
|
||||||
class="q-pa-md"
|
class="q-pa-md"
|
||||||
:style="maxWidth ? 'max-width: ' + maxWidth : ''"
|
:style="maxWidth ? 'max-width: ' + maxWidth : ''"
|
||||||
id="formModel"
|
id="formModel"
|
||||||
:prevent-submit="$attrs['prevent-submit']"
|
|
||||||
:mapper="onBeforeSave"
|
:mapper="onBeforeSave"
|
||||||
>
|
>
|
||||||
<QCard>
|
<QCard>
|
||||||
|
|
|
@ -27,10 +27,15 @@ const formModelRef = ref(null);
|
||||||
const closeButton = ref(null);
|
const closeButton = ref(null);
|
||||||
const isSaveAndContinue = ref(false);
|
const isSaveAndContinue = ref(false);
|
||||||
const onDataSaved = (formData, requestResponse) => {
|
const onDataSaved = (formData, requestResponse) => {
|
||||||
if (closeButton.value && isSaveAndContinue) closeButton.value.click();
|
if (closeButton.value && !isSaveAndContinue.value) closeButton.value.click();
|
||||||
emit('onDataSaved', formData, requestResponse);
|
emit('onDataSaved', formData, requestResponse);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onClick = async (saveAndContinue) => {
|
||||||
|
isSaveAndContinue.value = saveAndContinue;
|
||||||
|
await formModelRef.value.save();
|
||||||
|
};
|
||||||
|
|
||||||
const isLoading = computed(() => formModelRef.value?.isLoading);
|
const isLoading = computed(() => formModelRef.value?.isLoading);
|
||||||
const reset = computed(() => formModelRef.value?.reset);
|
const reset = computed(() => formModelRef.value?.reset);
|
||||||
|
|
||||||
|
@ -78,10 +83,7 @@ defineExpose({
|
||||||
:flat="showSaveAndContinueBtn"
|
:flat="showSaveAndContinueBtn"
|
||||||
:label="t('globals.save')"
|
:label="t('globals.save')"
|
||||||
:title="t('globals.save')"
|
:title="t('globals.save')"
|
||||||
@click="
|
@click="onClick(false)"
|
||||||
formModelRef.save();
|
|
||||||
isSaveAndContinue = false;
|
|
||||||
"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
class="q-ml-sm"
|
class="q-ml-sm"
|
||||||
:disabled="isLoading"
|
:disabled="isLoading"
|
||||||
|
@ -99,10 +101,7 @@ defineExpose({
|
||||||
:loading="isLoading"
|
:loading="isLoading"
|
||||||
data-cy="FormModelPopup_isSaveAndContinue"
|
data-cy="FormModelPopup_isSaveAndContinue"
|
||||||
z-max
|
z-max
|
||||||
@click="
|
@click="onClick(true)"
|
||||||
isSaveAndContinue = true;
|
|
||||||
formModelRef.save();
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -121,9 +121,7 @@ const removeTag = (index, params, search) => {
|
||||||
applyTags(params, search);
|
applyTags(params, search);
|
||||||
};
|
};
|
||||||
const setCategoryList = (data) => {
|
const setCategoryList = (data) => {
|
||||||
categoryList.value = (data || [])
|
categoryList.value = (data || []).map((category) => ({
|
||||||
.filter((category) => category.display)
|
|
||||||
.map((category) => ({
|
|
||||||
...category,
|
...category,
|
||||||
icon: `vn:${(category.icon || '').split('-')[1]}`,
|
icon: `vn:${(category.icon || '').split('-')[1]}`,
|
||||||
}));
|
}));
|
||||||
|
@ -132,12 +130,16 @@ const setCategoryList = (data) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData url="ItemCategories" limit="30" auto-load @on-fetch="setCategoryList" />
|
<FetchData
|
||||||
|
url="ItemCategories"
|
||||||
|
auto-load
|
||||||
|
@on-fetch="setCategoryList"
|
||||||
|
:where="{ display: { neq: 0 } }"
|
||||||
|
/>
|
||||||
<FetchData
|
<FetchData
|
||||||
url="Tags"
|
url="Tags"
|
||||||
:filter="{ fields: ['id', 'name', 'isFree'] }"
|
:filter="{ fields: ['id', 'name', 'isFree'] }"
|
||||||
auto-load
|
auto-load
|
||||||
limit="30"
|
|
||||||
@on-fetch="(data) => (tagOptions = data)"
|
@on-fetch="(data) => (tagOptions = data)"
|
||||||
/>
|
/>
|
||||||
<VnFilterPanel
|
<VnFilterPanel
|
||||||
|
@ -195,8 +197,6 @@ const setCategoryList = (data) => {
|
||||||
:label="t('components.itemsFilterPanel.typeFk')"
|
:label="t('components.itemsFilterPanel.typeFk')"
|
||||||
v-model="params.typeFk"
|
v-model="params.typeFk"
|
||||||
:options="itemTypesOptions"
|
:options="itemTypesOptions"
|
||||||
option-value="id"
|
|
||||||
option-label="name"
|
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
|
@ -234,7 +234,6 @@ const setCategoryList = (data) => {
|
||||||
:label="t('globals.tag')"
|
:label="t('globals.tag')"
|
||||||
v-model="value.selectedTag"
|
v-model="value.selectedTag"
|
||||||
:options="tagOptions"
|
:options="tagOptions"
|
||||||
option-label="name"
|
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
|
|
|
@ -1,8 +1,22 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { toCurrency } from 'src/filters';
|
||||||
|
|
||||||
defineProps({ row: { type: Object, required: true } });
|
defineProps({ row: { type: Object, required: true } });
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<span class="q-gutter-x-xs">
|
<span class="q-gutter-x-xs">
|
||||||
|
<router-link
|
||||||
|
v-if="row.claim?.claimFk"
|
||||||
|
:to="{ name: 'ClaimBasicData', params: { id: row.claim?.claimFk } }"
|
||||||
|
class="link"
|
||||||
|
>
|
||||||
|
<QIcon name="vn:claims" size="xs">
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('ticketSale.claim') }}:
|
||||||
|
{{ row.claim?.claimFk }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
</router-link>
|
||||||
<QIcon
|
<QIcon
|
||||||
v-if="row?.risk"
|
v-if="row?.risk"
|
||||||
name="vn:risk"
|
name="vn:risk"
|
||||||
|
@ -10,7 +24,8 @@ defineProps({ row: { type: Object, required: true } });
|
||||||
size="xs"
|
size="xs"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ $t('salesTicketsTable.risk') }}: {{ row.risk - row.credit }}
|
{{ $t('salesTicketsTable.risk') }}:
|
||||||
|
{{ toCurrency(row.risk - row.credit) }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
<QIcon
|
<QIcon
|
||||||
|
@ -53,7 +68,7 @@ defineProps({ row: { type: Object, required: true } });
|
||||||
<QTooltip>{{ $t('salesTicketsTable.purchaseRequest') }}</QTooltip>
|
<QTooltip>{{ $t('salesTicketsTable.purchaseRequest') }}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
<QIcon
|
<QIcon
|
||||||
v-if="!row?.isTaxDataChecked === 0"
|
v-if="row?.isTaxDataChecked !== 0"
|
||||||
name="vn:no036"
|
name="vn:no036"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="xs"
|
size="xs"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { markRaw, computed } from 'vue';
|
import { markRaw, computed } from 'vue';
|
||||||
import { QIcon, QCheckbox, QToggle } from 'quasar';
|
import { QIcon, QToggle } from 'quasar';
|
||||||
import { dashIfEmpty } from 'src/filters';
|
import { dashIfEmpty } from 'src/filters';
|
||||||
|
|
||||||
import VnSelect from 'components/common/VnSelect.vue';
|
import VnSelect from 'components/common/VnSelect.vue';
|
||||||
|
|
|
@ -10,14 +10,15 @@ import {
|
||||||
render,
|
render,
|
||||||
inject,
|
inject,
|
||||||
useAttrs,
|
useAttrs,
|
||||||
|
nextTick,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar, date } from 'quasar';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { useFilterParams } from 'src/composables/useFilterParams';
|
import { useFilterParams } from 'src/composables/useFilterParams';
|
||||||
import { dashIfEmpty } from 'src/filters';
|
import { dashIfEmpty, toDate } from 'src/filters';
|
||||||
|
|
||||||
import CrudModel from 'src/components/CrudModel.vue';
|
import CrudModel from 'src/components/CrudModel.vue';
|
||||||
import FormModelPopup from 'components/FormModelPopup.vue';
|
import FormModelPopup from 'components/FormModelPopup.vue';
|
||||||
|
@ -164,7 +165,6 @@ const app = inject('app');
|
||||||
const editingRow = ref(null);
|
const editingRow = ref(null);
|
||||||
const editingField = ref(null);
|
const editingField = ref(null);
|
||||||
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
||||||
const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
|
|
||||||
const selectRegex = /select/;
|
const selectRegex = /select/;
|
||||||
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
|
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
|
||||||
const tableModes = [
|
const tableModes = [
|
||||||
|
@ -345,7 +345,7 @@ const clickHandler = async (event) => {
|
||||||
if (isDateElement || isTimeElement || isQselectDropDown) return;
|
if (isDateElement || isTimeElement || isQselectDropDown) return;
|
||||||
|
|
||||||
if (clickedElement === null) {
|
if (clickedElement === null) {
|
||||||
destroyInput(editingRow.value, editingField.value);
|
await destroyInput(editingRow.value, editingField.value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const rowIndex = clickedElement.getAttribute('data-row-index');
|
const rowIndex = clickedElement.getAttribute('data-row-index');
|
||||||
|
@ -353,19 +353,19 @@ const clickHandler = async (event) => {
|
||||||
const column = $props.columns.find((col) => col.name === colField);
|
const column = $props.columns.find((col) => col.name === colField);
|
||||||
|
|
||||||
if (editingRow.value !== null && editingField.value !== null) {
|
if (editingRow.value !== null && editingField.value !== null) {
|
||||||
if (editingRow.value === rowIndex && editingField.value === colField) {
|
if (editingRow.value == rowIndex && editingField.value == colField) return;
|
||||||
return;
|
|
||||||
|
await destroyInput(editingRow.value, editingField.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroyInput(editingRow.value, editingField.value);
|
if (isEditableColumn(column)) {
|
||||||
}
|
|
||||||
if (isEditableColumn(column))
|
|
||||||
await renderInput(Number(rowIndex), colField, clickedElement);
|
await renderInput(Number(rowIndex), colField, clickedElement);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async function handleTabKey(event, rowIndex, colField) {
|
async function handleTabKey(event, rowIndex, colField) {
|
||||||
if (editingRow.value == rowIndex && editingField.value == colField)
|
if (editingRow.value == rowIndex && editingField.value == colField)
|
||||||
destroyInput(editingRow.value, editingField.value);
|
await destroyInput(editingRow.value, editingField.value);
|
||||||
|
|
||||||
const direction = event.shiftKey ? -1 : 1;
|
const direction = event.shiftKey ? -1 : 1;
|
||||||
const { nextRowIndex, nextColumnName } = await handleTabNavigation(
|
const { nextRowIndex, nextColumnName } = await handleTabNavigation(
|
||||||
|
@ -425,7 +425,8 @@ async function renderInput(rowId, field, clickedElement) {
|
||||||
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
||||||
},
|
},
|
||||||
keyup: async (event) => {
|
keyup: async (event) => {
|
||||||
if (event.key === 'Enter') handleBlur(rowId, field, clickedElement);
|
if (event.key === 'Enter')
|
||||||
|
await destroyInput(rowIndex, field, clickedElement);
|
||||||
},
|
},
|
||||||
keydown: async (event) => {
|
keydown: async (event) => {
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
|
@ -434,7 +435,7 @@ async function renderInput(rowId, field, clickedElement) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
break;
|
break;
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
destroyInput(rowId, field, clickedElement);
|
await destroyInput(rowId, field, clickedElement);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -456,12 +457,13 @@ async function renderInput(rowId, field, clickedElement) {
|
||||||
node.el?.querySelector('span > div > div').focus();
|
node.el?.querySelector('span > div > div').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function destroyInput(rowIndex, field, clickedElement) {
|
async function destroyInput(rowIndex, field, clickedElement) {
|
||||||
if (!clickedElement)
|
if (!clickedElement)
|
||||||
clickedElement = document.querySelector(
|
clickedElement = document.querySelector(
|
||||||
`[data-row-index="${rowIndex}"][data-col-field="${field}"]`,
|
`[data-row-index="${rowIndex}"][data-col-field="${field}"]`,
|
||||||
);
|
);
|
||||||
if (clickedElement) {
|
if (clickedElement) {
|
||||||
|
await nextTick();
|
||||||
render(null, clickedElement);
|
render(null, clickedElement);
|
||||||
Array.from(clickedElement.childNodes).forEach((child) => {
|
Array.from(clickedElement.childNodes).forEach((child) => {
|
||||||
child.style.visibility = 'visible';
|
child.style.visibility = 'visible';
|
||||||
|
@ -473,10 +475,6 @@ function destroyInput(rowIndex, field, clickedElement) {
|
||||||
editingField.value = null;
|
editingField.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleBlur(rowIndex, field, clickedElement) {
|
|
||||||
destroyInput(rowIndex, field, clickedElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleTabNavigation(rowIndex, colName, direction) {
|
async function handleTabNavigation(rowIndex, colName, direction) {
|
||||||
const columns = $props.columns;
|
const columns = $props.columns;
|
||||||
const totalColumns = columns.length;
|
const totalColumns = columns.length;
|
||||||
|
@ -492,9 +490,7 @@ async function handleTabNavigation(rowIndex, colName, direction) {
|
||||||
if (isEditableColumn(columns[newColumnIndex])) break;
|
if (isEditableColumn(columns[newColumnIndex])) break;
|
||||||
} while (iterations < totalColumns);
|
} while (iterations < totalColumns);
|
||||||
|
|
||||||
if (iterations >= totalColumns) {
|
if (iterations >= totalColumns + 1) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (direction === 1 && newColumnIndex <= currentColumnIndex) {
|
if (direction === 1 && newColumnIndex <= currentColumnIndex) {
|
||||||
rowIndex++;
|
rowIndex++;
|
||||||
|
@ -529,11 +525,36 @@ function formatColumnValue(col, row, dashIfEmpty) {
|
||||||
} else {
|
} else {
|
||||||
return col.format(row, dashIfEmpty);
|
return col.format(row, dashIfEmpty);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (col?.component === 'date') return dashIfEmpty(toDate(row[col?.name]));
|
||||||
|
|
||||||
|
if (col?.component === 'time')
|
||||||
|
return row[col?.name] >= 5
|
||||||
|
? dashIfEmpty(date.formatDate(new Date(row[col?.name]), 'HH:mm'))
|
||||||
|
: row[col?.name];
|
||||||
|
|
||||||
|
if (selectRegex.test(col?.component) && $props.isEditable) {
|
||||||
|
const { find, url } = col.attrs;
|
||||||
|
const urlRelation = url?.charAt(0)?.toLocaleLowerCase() + url?.slice(1, -1);
|
||||||
|
|
||||||
|
if (col?.attrs.options) {
|
||||||
|
const find = col?.attrs.options.find((option) => option.id === row[col.name]);
|
||||||
|
if (!col.attrs?.optionLabel || !find) return dashIfEmpty(row[col?.name]);
|
||||||
|
return dashIfEmpty(find[col.attrs?.optionLabel ?? 'name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof row[urlRelation] == 'object') {
|
||||||
|
if (typeof find == 'object')
|
||||||
|
return dashIfEmpty(row[urlRelation][find?.label ?? 'name']);
|
||||||
|
|
||||||
|
return dashIfEmpty(row[urlRelation][col?.attrs.optionLabel ?? 'name']);
|
||||||
|
}
|
||||||
|
if (typeof row[urlRelation] == 'string') return dashIfEmpty(row[urlRelation]);
|
||||||
} else {
|
} else {
|
||||||
return dashIfEmpty(row[col?.name]);
|
return dashIfEmpty(row[col?.name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const checkbox = ref(null);
|
|
||||||
function cardClick(_, row) {
|
function cardClick(_, row) {
|
||||||
if ($props.redirect) router.push({ path: `/${$props.redirect}/${row.id}` });
|
if ($props.redirect) router.push({ path: `/${$props.redirect}/${row.id}` });
|
||||||
}
|
}
|
||||||
|
@ -620,14 +641,6 @@ function cardClick(_, row) {
|
||||||
dense
|
dense
|
||||||
:options="tableModes.filter((mode) => !mode.disable)"
|
:options="tableModes.filter((mode) => !mode.disable)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<QBtn
|
|
||||||
v-if="showRightIcon"
|
|
||||||
icon="filter_alt"
|
|
||||||
class="bg-vn-section-color q-ml-sm"
|
|
||||||
dense
|
|
||||||
@click="stateStore.toggleRightDrawer()"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #header-cell="{ col }">
|
<template #header-cell="{ col }">
|
||||||
<QTh
|
<QTh
|
||||||
|
@ -732,7 +745,11 @@ function cardClick(_, row) {
|
||||||
<span
|
<span
|
||||||
v-else
|
v-else
|
||||||
:class="hasEditableFormat(col)"
|
:class="hasEditableFormat(col)"
|
||||||
:style="col?.style ? col.style(row) : null"
|
:style="
|
||||||
|
typeof col?.style == 'function'
|
||||||
|
? col.style(row)
|
||||||
|
: col?.style
|
||||||
|
"
|
||||||
style="bottom: 0"
|
style="bottom: 0"
|
||||||
>
|
>
|
||||||
{{ formatColumnValue(col, row, dashIfEmpty) }}
|
{{ formatColumnValue(col, row, dashIfEmpty) }}
|
||||||
|
@ -759,7 +776,7 @@ function cardClick(_, row) {
|
||||||
flat
|
flat
|
||||||
dense
|
dense
|
||||||
:class="
|
:class="
|
||||||
btn.isPrimary ? 'text-primary-light' : 'color-vn-text '
|
btn.isPrimary ? 'text-primary-light' : 'color-vn-label'
|
||||||
"
|
"
|
||||||
:style="`visibility: ${
|
:style="`visibility: ${
|
||||||
((btn.show && btn.show(row)) ?? true)
|
((btn.show && btn.show(row)) ?? true)
|
||||||
|
@ -767,6 +784,7 @@ function cardClick(_, row) {
|
||||||
: 'hidden'
|
: 'hidden'
|
||||||
}`"
|
}`"
|
||||||
@click="btn.action(row)"
|
@click="btn.action(row)"
|
||||||
|
:data-cy="btn?.name ?? `tableAction-${index}`"
|
||||||
/>
|
/>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
@ -815,7 +833,7 @@ function cardClick(_, row) {
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<!-- Fields -->
|
<!-- Fields -->
|
||||||
<QCardSection
|
<QCardSection
|
||||||
class="q-pl-sm q-pr-lg q-py-xs"
|
class="q-pl-sm q-py-xs"
|
||||||
:class="$props.cardClass"
|
:class="$props.cardClass"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -862,13 +880,14 @@ function cardClick(_, row) {
|
||||||
:key="index"
|
:key="index"
|
||||||
:title="btn.title"
|
:title="btn.title"
|
||||||
:icon="btn.icon"
|
:icon="btn.icon"
|
||||||
|
data-cy="cardBtn"
|
||||||
class="q-pa-xs"
|
class="q-pa-xs"
|
||||||
flat
|
|
||||||
:class="
|
:class="
|
||||||
btn.isPrimary
|
btn.isPrimary
|
||||||
? 'text-primary-light'
|
? 'text-primary-light'
|
||||||
: 'color-vn-text '
|
: 'color-vn-label'
|
||||||
"
|
"
|
||||||
|
flat
|
||||||
@click="btn.action(row)"
|
@click="btn.action(row)"
|
||||||
/>
|
/>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
|
@ -1121,6 +1140,7 @@ es:
|
||||||
.vn-label-value {
|
.vn-label-value {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
color: var(--vn-text-color);
|
color: var(--vn-text-color);
|
||||||
.value {
|
.value {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
|
@ -57,6 +57,7 @@ describe('FormModel', () => {
|
||||||
vm.state.set(model, formInitialData);
|
vm.state.set(model, formInitialData);
|
||||||
expect(vm.hasChanges).toBe(false);
|
expect(vm.hasChanges).toBe(false);
|
||||||
|
|
||||||
|
await vm.$nextTick();
|
||||||
vm.formData.mockKey = 'newVal';
|
vm.formData.mockKey = 'newVal';
|
||||||
await vm.$nextTick();
|
await vm.$nextTick();
|
||||||
expect(vm.hasChanges).toBe(true);
|
expect(vm.hasChanges).toBe(true);
|
||||||
|
@ -94,8 +95,12 @@ describe('FormModel', () => {
|
||||||
it('should call axios.patch with the right data', async () => {
|
it('should call axios.patch with the right data', async () => {
|
||||||
const spy = vi.spyOn(axios, 'patch').mockResolvedValue({ data: {} });
|
const spy = vi.spyOn(axios, 'patch').mockResolvedValue({ data: {} });
|
||||||
const { vm } = mount({ propsData: { url, model } });
|
const { vm } = mount({ propsData: { url, model } });
|
||||||
vm.formData.mockKey = 'newVal';
|
|
||||||
|
vm.formData = {};
|
||||||
await vm.$nextTick();
|
await vm.$nextTick();
|
||||||
|
vm.formData = { mockKey: 'newVal' };
|
||||||
|
await vm.$nextTick();
|
||||||
|
|
||||||
await vm.save();
|
await vm.save();
|
||||||
expect(spy).toHaveBeenCalled();
|
expect(spy).toHaveBeenCalled();
|
||||||
vm.formData.mockKey = 'mockVal';
|
vm.formData.mockKey = 'mockVal';
|
||||||
|
|
|
@ -39,6 +39,13 @@ onBeforeMount(async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeRouteUpdate(async (to, from) => {
|
onBeforeRouteUpdate(async (to, from) => {
|
||||||
|
if (hasRouteParam(to.params)) {
|
||||||
|
const { matched } = router.currentRoute.value;
|
||||||
|
const { name } = matched.at(-3);
|
||||||
|
if (name) {
|
||||||
|
router.push({ name, params: to.params });
|
||||||
|
}
|
||||||
|
}
|
||||||
const id = to.params.id;
|
const id = to.params.id;
|
||||||
if (id !== from.params.id) await fetch(id, true);
|
if (id !== from.params.id) await fetch(id, true);
|
||||||
});
|
});
|
||||||
|
@ -50,6 +57,9 @@ async function fetch(id, append = false) {
|
||||||
else arrayData.store.url = props.url.replace(regex, `/${id}`);
|
else arrayData.store.url = props.url.replace(regex, `/${id}`);
|
||||||
await arrayData.fetch({ append, updateRouter: false });
|
await arrayData.fetch({ append, updateRouter: false });
|
||||||
}
|
}
|
||||||
|
function hasRouteParam(params, valueToCheck = ':addressId') {
|
||||||
|
return Object.values(params).includes(valueToCheck);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Teleport to="#left-panel" v-if="stateStore.isHeaderMounted()">
|
<Teleport to="#left-panel" v-if="stateStore.isHeaderMounted()">
|
||||||
|
|
|
@ -85,6 +85,7 @@ const handleModelValue = (data) => {
|
||||||
:tooltip="t('Create new location')"
|
:tooltip="t('Create new location')"
|
||||||
:rules="mixinRules"
|
:rules="mixinRules"
|
||||||
:lazy-rules="true"
|
:lazy-rules="true"
|
||||||
|
required
|
||||||
>
|
>
|
||||||
<template #form>
|
<template #form>
|
||||||
<CreateNewPostcode
|
<CreateNewPostcode
|
||||||
|
|
|
@ -193,8 +193,10 @@ const toModule = computed(() =>
|
||||||
</div>
|
</div>
|
||||||
</QItemLabel>
|
</QItemLabel>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemLabel class="subtitle" caption>
|
<QItemLabel class="subtitle">
|
||||||
#{{ getValueFromPath(subtitle) ?? entity.id }}
|
#{{ getValueFromPath(subtitle) ?? entity.id }}
|
||||||
|
</QItemLabel>
|
||||||
|
|
||||||
<QBtn
|
<QBtn
|
||||||
round
|
round
|
||||||
flat
|
flat
|
||||||
|
@ -208,7 +210,7 @@ const toModule = computed(() =>
|
||||||
{{ t('globals.copyId') }}
|
{{ t('globals.copyId') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</QItemLabel>
|
<!-- </QItemLabel> -->
|
||||||
</QItem>
|
</QItem>
|
||||||
</QList>
|
</QList>
|
||||||
<div class="list-box q-mt-xs">
|
<div class="list-box q-mt-xs">
|
||||||
|
|
|
@ -53,3 +53,8 @@ const manaCode = ref(props.manaCode);
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<i18n>
|
||||||
|
es:
|
||||||
|
Promotion mana: Maná promoción
|
||||||
|
Claim mana: Maná reclamación
|
||||||
|
</i18n>
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { describe, it, expect, vi } from 'vitest';
|
||||||
|
import { useRequired } from '../useRequired';
|
||||||
|
|
||||||
|
vi.mock('../useValidator', () => ({
|
||||||
|
useValidator: () => ({
|
||||||
|
validations: () => ({
|
||||||
|
required: vi.fn((isRequired, val) => {
|
||||||
|
if (!isRequired) return true;
|
||||||
|
return val !== null && val !== undefined && val !== '';
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('useRequired', () => {
|
||||||
|
it('should detect required when attr is boolean true', () => {
|
||||||
|
const attrs = { required: true };
|
||||||
|
const { isRequired } = useRequired(attrs);
|
||||||
|
expect(isRequired).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect required when attr is boolean false', () => {
|
||||||
|
const attrs = { required: false };
|
||||||
|
const { isRequired } = useRequired(attrs);
|
||||||
|
expect(isRequired).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect required when attr exists without value', () => {
|
||||||
|
const attrs = { required: '' };
|
||||||
|
const { isRequired } = useRequired(attrs);
|
||||||
|
expect(isRequired).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when required attr does not exist', () => {
|
||||||
|
const attrs = { someOtherAttr: 'value' };
|
||||||
|
const { isRequired } = useRequired(attrs);
|
||||||
|
expect(isRequired).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('requiredFieldRule', () => {
|
||||||
|
it('should validate required field with value', () => {
|
||||||
|
const attrs = { required: true };
|
||||||
|
const { requiredFieldRule } = useRequired(attrs);
|
||||||
|
expect(requiredFieldRule('some value')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate required field with empty value', () => {
|
||||||
|
const attrs = { required: true };
|
||||||
|
const { requiredFieldRule } = useRequired(attrs);
|
||||||
|
expect(requiredFieldRule('')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should pass validation when field is not required', () => {
|
||||||
|
const attrs = { required: false };
|
||||||
|
const { requiredFieldRule } = useRequired(attrs);
|
||||||
|
expect(requiredFieldRule('')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle null and undefined values', () => {
|
||||||
|
const attrs = { required: true };
|
||||||
|
const { requiredFieldRule } = useRequired(attrs);
|
||||||
|
expect(requiredFieldRule(null)).toBe(false);
|
||||||
|
expect(requiredFieldRule(undefined)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -7,6 +7,7 @@ export function getColAlign(col) {
|
||||||
case 'number':
|
case 'number':
|
||||||
align = 'right';
|
align = 'right';
|
||||||
break;
|
break;
|
||||||
|
case 'time':
|
||||||
case 'date':
|
case 'date':
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
align = 'center';
|
align = 'center';
|
||||||
|
|
|
@ -11,7 +11,7 @@ export async function useCau(res, message) {
|
||||||
const { config, headers, request, status, statusText, data } = res || {};
|
const { config, headers, request, status, statusText, data } = res || {};
|
||||||
const { params, url, method, signal, headers: confHeaders } = config || {};
|
const { params, url, method, signal, headers: confHeaders } = config || {};
|
||||||
const { message: resMessage, code, name } = data?.error || {};
|
const { message: resMessage, code, name } = data?.error || {};
|
||||||
delete confHeaders.Authorization;
|
delete confHeaders?.Authorization;
|
||||||
|
|
||||||
const additionalData = {
|
const additionalData = {
|
||||||
path: location.hash,
|
path: location.hash,
|
||||||
|
|
|
@ -2,14 +2,10 @@ import { useValidator } from 'src/composables/useValidator';
|
||||||
|
|
||||||
export function useRequired($attrs) {
|
export function useRequired($attrs) {
|
||||||
const { validations } = useValidator();
|
const { validations } = useValidator();
|
||||||
const hasRequired = Object.keys($attrs).includes('required');
|
const isRequired =
|
||||||
let isRequired = false;
|
typeof $attrs['required'] === 'boolean'
|
||||||
if (hasRequired) {
|
? $attrs['required']
|
||||||
const required = $attrs['required'];
|
: Object.keys($attrs).includes('required');
|
||||||
if (typeof required === 'boolean') {
|
|
||||||
isRequired = required;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const requiredFieldRule = (val) => validations().required(isRequired, val);
|
const requiredFieldRule = (val) => validations().required(isRequired, val);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -335,3 +335,7 @@ input::-webkit-inner-spin-button {
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
box-shadow: 0 4px 6px #00000000;
|
box-shadow: 0 4px 6px #00000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.containerShrinked {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ globals:
|
||||||
rowRemoved: Row removed
|
rowRemoved: Row removed
|
||||||
pleaseWait: Please wait...
|
pleaseWait: Please wait...
|
||||||
noPinnedModules: You don't have any pinned modules
|
noPinnedModules: You don't have any pinned modules
|
||||||
|
enterToConfirm: Press Enter to confirm
|
||||||
summary:
|
summary:
|
||||||
basicData: Basic data
|
basicData: Basic data
|
||||||
daysOnward: Days onward
|
daysOnward: Days onward
|
||||||
|
@ -830,6 +831,8 @@ travel:
|
||||||
CloneTravelAndEntries: Clone travel and his entries
|
CloneTravelAndEntries: Clone travel and his entries
|
||||||
deleteTravel: Delete travel
|
deleteTravel: Delete travel
|
||||||
AddEntry: Add entry
|
AddEntry: Add entry
|
||||||
|
availabled: Availabled
|
||||||
|
availabledHour: Availabled hour
|
||||||
thermographs: Thermographs
|
thermographs: Thermographs
|
||||||
hb: HB
|
hb: HB
|
||||||
basicData:
|
basicData:
|
||||||
|
|
|
@ -51,6 +51,7 @@ globals:
|
||||||
pleaseWait: Por favor espera...
|
pleaseWait: Por favor espera...
|
||||||
noPinnedModules: No has fijado ningún módulo
|
noPinnedModules: No has fijado ningún módulo
|
||||||
split: Split
|
split: Split
|
||||||
|
enterToConfirm: Pulsa Enter para confirmar
|
||||||
summary:
|
summary:
|
||||||
basicData: Datos básicos
|
basicData: Datos básicos
|
||||||
daysOnward: Días adelante
|
daysOnward: Días adelante
|
||||||
|
@ -839,6 +840,7 @@ supplier:
|
||||||
verified: Verificado
|
verified: Verificado
|
||||||
isActive: Está activo
|
isActive: Está activo
|
||||||
billingData: Forma de pago
|
billingData: Forma de pago
|
||||||
|
financialData: Datos financieros
|
||||||
payDeadline: Plazo de pago
|
payDeadline: Plazo de pago
|
||||||
payDay: Día de pago
|
payDay: Día de pago
|
||||||
account: Cuenta
|
account: Cuenta
|
||||||
|
@ -916,6 +918,8 @@ travel:
|
||||||
deleteTravel: Eliminar envío
|
deleteTravel: Eliminar envío
|
||||||
AddEntry: Añadir entrada
|
AddEntry: Añadir entrada
|
||||||
thermographs: Termógrafos
|
thermographs: Termógrafos
|
||||||
|
availabled: F. Disponible
|
||||||
|
availabledHour: Hora Disponible
|
||||||
hb: HB
|
hb: HB
|
||||||
basicData:
|
basicData:
|
||||||
daysInForward: Desplazamiento automatico (redada)
|
daysInForward: Desplazamiento automatico (redada)
|
||||||
|
|
|
@ -158,7 +158,7 @@ onMounted(() => {
|
||||||
>
|
>
|
||||||
<QItemSection>{{ t('globals.delete') }}</QItemSection>
|
<QItemSection>{{ t('globals.delete') }}</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem v-if="hasSysadminAccess" v-ripple clickable>
|
<QItem v-if="hasSysadminAccess || isHimself" v-ripple clickable>
|
||||||
<QItemSection @click="onChangePass(isHimself)">
|
<QItemSection @click="onChangePass(isHimself)">
|
||||||
{{ isHimself ? t('globals.changePass') : t('globals.setPass') }}
|
{{ isHimself ? t('globals.changePass') : t('globals.setPass') }}
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
|
|
|
@ -156,7 +156,6 @@ function onDrag() {
|
||||||
url="Claims"
|
url="Claims"
|
||||||
:filter="claimDmsFilter"
|
:filter="claimDmsFilter"
|
||||||
@on-fetch="([data]) => setClaimDms(data)"
|
@on-fetch="([data]) => setClaimDms(data)"
|
||||||
limit="20"
|
|
||||||
auto-load
|
auto-load
|
||||||
ref="claimDmsRef"
|
ref="claimDmsRef"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -17,8 +17,7 @@ const bankEntitiesRef = ref(null);
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
fields: ['id', 'bic', 'name'],
|
fields: ['id', 'bic', 'name'],
|
||||||
order: 'bic ASC',
|
order: 'bic ASC'
|
||||||
limit: 30,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getBankEntities = (data, formData) => {
|
const getBankEntities = (data, formData) => {
|
||||||
|
|
|
@ -232,7 +232,6 @@ const updateDateParams = (value, params) => {
|
||||||
:include="'category'"
|
:include="'category'"
|
||||||
:sortBy="'name ASC'"
|
:sortBy="'name ASC'"
|
||||||
dense
|
dense
|
||||||
@update:model-value="(data) => updateDateParams(data, params)"
|
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem v-bind="scope.itemProps">
|
<QItem v-bind="scope.itemProps">
|
||||||
|
@ -254,7 +253,6 @@ const updateDateParams = (value, params) => {
|
||||||
:fields="['id', 'name']"
|
:fields="['id', 'name']"
|
||||||
:sortBy="'name ASC'"
|
:sortBy="'name ASC'"
|
||||||
dense
|
dense
|
||||||
@update:model-value="(data) => updateDateParams(data, params)"
|
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
v-model="params.campaign"
|
v-model="params.campaign"
|
||||||
|
@ -303,12 +301,14 @@ en:
|
||||||
valentinesDay: Valentine's Day
|
valentinesDay: Valentine's Day
|
||||||
mothersDay: Mother's Day
|
mothersDay: Mother's Day
|
||||||
allSaints: All Saints' Day
|
allSaints: All Saints' Day
|
||||||
|
frenchMothersDay: Mother's Day in France
|
||||||
es:
|
es:
|
||||||
Enter a new search: Introduce una nueva búsqueda
|
Enter a new search: Introduce una nueva búsqueda
|
||||||
Group by items: Agrupar por artículos
|
Group by items: Agrupar por artículos
|
||||||
valentinesDay: Día de San Valentín
|
valentinesDay: Día de San Valentín
|
||||||
mothersDay: Día de la Madre
|
mothersDay: Día de la Madre
|
||||||
allSaints: Día de Todos los Santos
|
allSaints: Día de Todos los Santos
|
||||||
|
frenchMothersDay: (Francia) Día de la Madre
|
||||||
Campaign consumption: Consumo campaña
|
Campaign consumption: Consumo campaña
|
||||||
Campaign: Campaña
|
Campaign: Campaña
|
||||||
From: Desde
|
From: Desde
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
import { useQuasar } from 'quasar';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
import FormModel from 'components/FormModel.vue';
|
import FormModel from 'components/FormModel.vue';
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
|
@ -11,9 +14,12 @@ import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnLocation from 'src/components/common/VnLocation.vue';
|
import VnLocation from 'src/components/common/VnLocation.vue';
|
||||||
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
|
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
|
||||||
import { getDifferences, getUpdatedValues } from 'src/filters';
|
import { getDifferences, getUpdatedValues } from 'src/filters';
|
||||||
|
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||||
|
|
||||||
|
const quasar = useQuasar();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const { notify } = useNotify();
|
||||||
|
|
||||||
const typesTaxes = ref([]);
|
const typesTaxes = ref([]);
|
||||||
const typesTransactions = ref([]);
|
const typesTransactions = ref([]);
|
||||||
|
@ -31,6 +37,31 @@ function onBeforeSave(formData, originalData) {
|
||||||
formData,
|
formData,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkEtChanges(data, _, originalData) {
|
||||||
|
const equalizatedHasChanged = originalData.isEqualizated != data.isEqualizated;
|
||||||
|
const hasToInvoiceByAddress =
|
||||||
|
originalData.hasToInvoiceByAddress || data.hasToInvoiceByAddress;
|
||||||
|
if (equalizatedHasChanged && hasToInvoiceByAddress) {
|
||||||
|
quasar.dialog({
|
||||||
|
component: VnConfirm,
|
||||||
|
componentProps: {
|
||||||
|
title: t('You changed the equalization tax'),
|
||||||
|
message: t('Do you want to spread the change?'),
|
||||||
|
promise: () => acceptPropagate(data),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (equalizatedHasChanged) {
|
||||||
|
await acceptPropagate(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function acceptPropagate({ isEqualizated }) {
|
||||||
|
await axios.patch(`Clients/${route.params.id}/addressesPropagateRe`, {
|
||||||
|
isEqualizated,
|
||||||
|
});
|
||||||
|
notify(t('Equivalent tax spreaded'), 'warning');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -45,6 +76,8 @@ function onBeforeSave(formData, originalData) {
|
||||||
auto-load
|
auto-load
|
||||||
model="Customer"
|
model="Customer"
|
||||||
:mapper="onBeforeSave"
|
:mapper="onBeforeSave"
|
||||||
|
observe-form-changes
|
||||||
|
@on-data-saved="checkEtChanges"
|
||||||
>
|
>
|
||||||
<template #form="{ data, validate }">
|
<template #form="{ data, validate }">
|
||||||
<VnRow>
|
<VnRow>
|
||||||
|
@ -180,6 +213,9 @@ es:
|
||||||
whenActivatingIt: Al activarlo, no informar el código del país en el campo nif
|
whenActivatingIt: Al activarlo, no informar el código del país en el campo nif
|
||||||
inOrderToInvoice: Para facturar no se consulta este campo, sino el RE de consignatario. Al modificar este campo si no esta marcada la casilla Facturar por consignatario, se propagará automaticamente el cambio a todos lo consignatarios, en caso contrario preguntará al usuario si quiere o no propagar
|
inOrderToInvoice: Para facturar no se consulta este campo, sino el RE de consignatario. Al modificar este campo si no esta marcada la casilla Facturar por consignatario, se propagará automaticamente el cambio a todos lo consignatarios, en caso contrario preguntará al usuario si quiere o no propagar
|
||||||
Daily invoice: Facturación diaria
|
Daily invoice: Facturación diaria
|
||||||
|
Equivalent tax spreaded: Recargo de equivalencia propagado
|
||||||
|
You changed the equalization tax: Has cambiado el recargo de equivalencia
|
||||||
|
Do you want to spread the change?: ¿Deseas propagar el cambio a sus consignatarios?
|
||||||
en:
|
en:
|
||||||
onlyLetters: Only letters, numbers and spaces can be used
|
onlyLetters: Only letters, numbers and spaces can be used
|
||||||
whenActivatingIt: When activating it, do not enter the country code in the ID field
|
whenActivatingIt: When activating it, do not enter the country code in the ID field
|
||||||
|
|
|
@ -270,7 +270,7 @@ const sumRisk = ({ clientRisks }) => {
|
||||||
<VnTitle
|
<VnTitle
|
||||||
target="_blank"
|
target="_blank"
|
||||||
:url="`${grafanaUrl}/d/40buzE4Vk/comportamiento-pagos-clientes?orgId=1&var-clientFk=${entityId}`"
|
:url="`${grafanaUrl}/d/40buzE4Vk/comportamiento-pagos-clientes?orgId=1&var-clientFk=${entityId}`"
|
||||||
:text="t('customer.summary.payMethodFk')"
|
:text="t('customer.summary.financialData')"
|
||||||
icon="vn:grafana"
|
icon="vn:grafana"
|
||||||
/>
|
/>
|
||||||
<VnLv
|
<VnLv
|
||||||
|
|
|
@ -87,7 +87,7 @@ onMounted(async () => {
|
||||||
<FetchData
|
<FetchData
|
||||||
url="Campaigns/latest"
|
url="Campaigns/latest"
|
||||||
@on-fetch="(data) => (campaignsOptions = data)"
|
@on-fetch="(data) => (campaignsOptions = data)"
|
||||||
:filter="{ fields: ['id', 'code', 'dated'], order: 'code ASC', limit: 30 }"
|
:filter="{ fields: ['id', 'code', 'dated'], order: 'code ASC' }"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<FetchData
|
<FetchData
|
||||||
|
|
|
@ -98,7 +98,6 @@ function onAgentCreated({ id, fiscalName }, data) {
|
||||||
:rules="validate('Worker.postcode')"
|
:rules="validate('Worker.postcode')"
|
||||||
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
|
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
|
||||||
v-model="data.location"
|
v-model="data.location"
|
||||||
:required="true"
|
|
||||||
@update:model-value="(location) => handleLocation(data, location)"
|
@update:model-value="(location) => handleLocation(data, location)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -96,11 +96,11 @@ const updateObservations = async (payload) => {
|
||||||
await axios.post('AddressObservations/crud', payload);
|
await axios.post('AddressObservations/crud', payload);
|
||||||
notes.value = [];
|
notes.value = [];
|
||||||
deletes.value = [];
|
deletes.value = [];
|
||||||
toCustomerAddress();
|
|
||||||
};
|
};
|
||||||
async function updateAll({ data, payload }) {
|
async function updateAll({ data, payload }) {
|
||||||
await updateObservations(payload);
|
await updateObservations(payload);
|
||||||
await updateAddress(data);
|
await updateAddress(data);
|
||||||
|
toCustomerAddress();
|
||||||
}
|
}
|
||||||
function getPayload() {
|
function getPayload() {
|
||||||
return {
|
return {
|
||||||
|
@ -137,15 +137,12 @@ async function handleDialog(data) {
|
||||||
.onOk(async () => {
|
.onOk(async () => {
|
||||||
await updateAddressTicket();
|
await updateAddressTicket();
|
||||||
await updateAll(body);
|
await updateAll(body);
|
||||||
toCustomerAddress();
|
|
||||||
})
|
})
|
||||||
.onCancel(async () => {
|
.onCancel(async () => {
|
||||||
await updateAll(body);
|
await updateAll(body);
|
||||||
toCustomerAddress();
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
updateAll(body);
|
await updateAll(body);
|
||||||
toCustomerAddress();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +233,7 @@ function handleLocation(data, location) {
|
||||||
postcode: data.postalCode,
|
postcode: data.postalCode,
|
||||||
city: data.city,
|
city: data.city,
|
||||||
province: data.province,
|
province: data.province,
|
||||||
country: data.province.country,
|
country: data.province?.country,
|
||||||
}"
|
}"
|
||||||
@update:model-value="(location) => handleLocation(data, location)"
|
@update:model-value="(location) => handleLocation(data, location)"
|
||||||
></VnLocation>
|
></VnLocation>
|
||||||
|
|
|
@ -114,7 +114,7 @@ function onBeforeSave(data) {
|
||||||
if (isCash.value && shouldSendEmail.value && !data.email)
|
if (isCash.value && shouldSendEmail.value && !data.email)
|
||||||
return notify(t('There is no assigned email for this client'), 'negative');
|
return notify(t('There is no assigned email for this client'), 'negative');
|
||||||
|
|
||||||
data.bankFk = data.bankFk.id;
|
data.bankFk = data.bankFk?.id;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ async function getAmountPaid() {
|
||||||
:url-create="urlCreate"
|
:url-create="urlCreate"
|
||||||
:mapper="onBeforeSave"
|
:mapper="onBeforeSave"
|
||||||
@on-data-saved="onDataSaved"
|
@on-data-saved="onDataSaved"
|
||||||
:prevent-submit="true"
|
prevent-submit
|
||||||
>
|
>
|
||||||
<template #form="{ data, validate }">
|
<template #form="{ data, validate }">
|
||||||
<span ref="closeButton" class="row justify-end close-icon" v-close-popup>
|
<span ref="closeButton" class="row justify-end close-icon" v-close-popup>
|
||||||
|
|
|
@ -209,13 +209,14 @@ const columns = [
|
||||||
row['amount'] = row['quantity'] * row['buyingValue'];
|
row['amount'] = row['quantity'] * row['buyingValue'];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
width: '20px',
|
width: '30px',
|
||||||
style: (row) => {
|
style: (row) => {
|
||||||
if (row.groupingMode === 'grouping')
|
if (row.groupingMode === 'grouping')
|
||||||
return { color: 'var(--vn-label-color)' };
|
return { color: 'var(--vn-label-color)' };
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'center',
|
||||||
labelAbbreviation: 'GM',
|
labelAbbreviation: 'GM',
|
||||||
label: t('Grouping selector'),
|
label: t('Grouping selector'),
|
||||||
toolTip: t('Grouping selector'),
|
toolTip: t('Grouping selector'),
|
||||||
|
@ -249,7 +250,7 @@ const columns = [
|
||||||
toolTip: 'Grouping',
|
toolTip: 'Grouping',
|
||||||
name: 'grouping',
|
name: 'grouping',
|
||||||
component: 'number',
|
component: 'number',
|
||||||
width: '20px',
|
width: '30px',
|
||||||
create: true,
|
create: true,
|
||||||
style: (row) => {
|
style: (row) => {
|
||||||
if (row.groupingMode === 'packing') return { color: 'var(--vn-label-color)' };
|
if (row.groupingMode === 'packing') return { color: 'var(--vn-label-color)' };
|
||||||
|
@ -508,7 +509,7 @@ async function setBuyUltimate(itemFk, data) {
|
||||||
|
|
||||||
allowedKeys.forEach((key) => {
|
allowedKeys.forEach((key) => {
|
||||||
if (buyUltimateData.hasOwnProperty(key) && key !== 'entryFk') {
|
if (buyUltimateData.hasOwnProperty(key) && key !== 'entryFk') {
|
||||||
data[key] = buyUltimateData[key];
|
if (!['stickers', 'quantity'].includes(key)) data[key] = buyUltimateData[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -600,7 +601,6 @@ onMounted(() => {
|
||||||
ref="entryBuysRef"
|
ref="entryBuysRef"
|
||||||
data-key="EntryBuys"
|
data-key="EntryBuys"
|
||||||
:url="`Entries/${entityId}/getBuyList`"
|
:url="`Entries/${entityId}/getBuyList`"
|
||||||
order="name DESC"
|
|
||||||
save-url="Buys/crud"
|
save-url="Buys/crud"
|
||||||
:disable-option="{ card: true }"
|
:disable-option="{ card: true }"
|
||||||
v-model:selected="selectedRows"
|
v-model:selected="selectedRows"
|
||||||
|
@ -644,7 +644,8 @@ onMounted(() => {
|
||||||
:is-editable="editableMode"
|
:is-editable="editableMode"
|
||||||
:without-header="!editableMode"
|
:without-header="!editableMode"
|
||||||
:with-filters="editableMode"
|
:with-filters="editableMode"
|
||||||
:right-search="editableMode"
|
:right-search="false"
|
||||||
|
:right-search-icon="false"
|
||||||
:row-click="false"
|
:row-click="false"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:beforeSaveFn="beforeSave"
|
:beforeSaveFn="beforeSave"
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
import VnInput from 'components/common/VnInput.vue';
|
import VnInput from 'components/common/VnInput.vue';
|
||||||
import VnSelect from 'components/common/VnSelect.vue';
|
import VnSelect from 'components/common/VnSelect.vue';
|
||||||
|
@ -18,18 +16,10 @@ defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const itemTypeWorkersOptions = ref([]);
|
|
||||||
const tagValues = ref([]);
|
const tagValues = ref([]);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
|
||||||
url="TicketRequests/getItemTypeWorker"
|
|
||||||
limit="30"
|
|
||||||
auto-load
|
|
||||||
:filter="{ fields: ['id', 'nickname'], order: 'nickname ASC', limit: 30 }"
|
|
||||||
@on-fetch="(data) => (itemTypeWorkersOptions = data)"
|
|
||||||
/>
|
|
||||||
<ItemsFilterPanel :data-key="dataKey" :custom-tags="['tags']">
|
<ItemsFilterPanel :data-key="dataKey" :custom-tags="['tags']">
|
||||||
<template #body="{ params, searchFn }">
|
<template #body="{ params, searchFn }">
|
||||||
<QItem class="q-my-md">
|
<QItem class="q-my-md">
|
||||||
|
@ -37,9 +27,10 @@ const tagValues = ref([]);
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('components.itemsFilterPanel.salesPersonFk')"
|
:label="t('components.itemsFilterPanel.salesPersonFk')"
|
||||||
v-model="params.salesPersonFk"
|
v-model="params.salesPersonFk"
|
||||||
:options="itemTypeWorkersOptions"
|
url="TicketRequests/getItemTypeWorker"
|
||||||
option-value="id"
|
|
||||||
option-label="nickname"
|
option-label="nickname"
|
||||||
|
:fields="['id', 'nickname']"
|
||||||
|
sort-by="nickname ASC"
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
|
@ -52,8 +43,9 @@ const tagValues = ref([]);
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelectSupplier
|
<VnSelectSupplier
|
||||||
v-model="params.supplierFk"
|
v-model="params.supplierFk"
|
||||||
@update:model-value="searchFn()"
|
url="Suppliers"
|
||||||
hide-selected
|
:fields="['id', 'name', 'nickname']"
|
||||||
|
sort-by="name ASC"
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
|
|
|
@ -44,28 +44,32 @@ const entryQueryFilter = {
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
label: 'Ex',
|
labelAbbreviation: 'Ex',
|
||||||
|
label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
|
||||||
toolTip: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
|
toolTip: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
|
||||||
name: 'isExcludedFromAvailable',
|
name: 'isExcludedFromAvailable',
|
||||||
component: 'checkbox',
|
component: 'checkbox',
|
||||||
width: '35px',
|
width: '35px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Pe',
|
labelAbbreviation: 'Pe',
|
||||||
|
label: t('entry.list.tableVisibleColumns.isOrdered'),
|
||||||
toolTip: t('entry.list.tableVisibleColumns.isOrdered'),
|
toolTip: t('entry.list.tableVisibleColumns.isOrdered'),
|
||||||
name: 'isOrdered',
|
name: 'isOrdered',
|
||||||
component: 'checkbox',
|
component: 'checkbox',
|
||||||
width: '35px',
|
width: '35px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Le',
|
labelAbbreviation: 'LE',
|
||||||
|
label: t('entry.list.tableVisibleColumns.isConfirmed'),
|
||||||
toolTip: t('entry.list.tableVisibleColumns.isConfirmed'),
|
toolTip: t('entry.list.tableVisibleColumns.isConfirmed'),
|
||||||
name: 'isConfirmed',
|
name: 'isConfirmed',
|
||||||
component: 'checkbox',
|
component: 'checkbox',
|
||||||
width: '35px',
|
width: '35px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Re',
|
labelAbbreviation: 'Re',
|
||||||
|
label: t('entry.list.tableVisibleColumns.isReceived'),
|
||||||
toolTip: t('entry.list.tableVisibleColumns.isReceived'),
|
toolTip: t('entry.list.tableVisibleColumns.isReceived'),
|
||||||
name: 'isReceived',
|
name: 'isReceived',
|
||||||
component: 'checkbox',
|
component: 'checkbox',
|
||||||
|
@ -89,6 +93,7 @@ const columns = computed(() => [
|
||||||
chip: {
|
chip: {
|
||||||
condition: () => true,
|
condition: () => true,
|
||||||
},
|
},
|
||||||
|
width: '50px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('entry.list.tableVisibleColumns.supplierFk'),
|
label: t('entry.list.tableVisibleColumns.supplierFk'),
|
||||||
|
@ -99,8 +104,10 @@ const columns = computed(() => [
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'suppliers',
|
url: 'suppliers',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
|
where: { order: 'name DESC' },
|
||||||
},
|
},
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.supplierName),
|
format: (row, dashIfEmpty) => dashIfEmpty(row.supplierName),
|
||||||
|
width: '110px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -124,6 +131,7 @@ const columns = computed(() => [
|
||||||
label: 'AWB',
|
label: 'AWB',
|
||||||
name: 'awbCode',
|
name: 'awbCode',
|
||||||
component: 'input',
|
component: 'input',
|
||||||
|
width: '100px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -160,6 +168,7 @@ const columns = computed(() => [
|
||||||
component: null,
|
component: null,
|
||||||
},
|
},
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseOutName),
|
format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseOutName),
|
||||||
|
width: '65px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -175,12 +184,24 @@ const columns = computed(() => [
|
||||||
component: null,
|
component: null,
|
||||||
},
|
},
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseInName),
|
format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseInName),
|
||||||
|
width: '65px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
labelAbbreviation: t('Type'),
|
||||||
label: t('entry.list.tableVisibleColumns.entryTypeDescription'),
|
label: t('entry.list.tableVisibleColumns.entryTypeDescription'),
|
||||||
|
toolTip: t('entry.list.tableVisibleColumns.entryTypeDescription'),
|
||||||
name: 'entryTypeCode',
|
name: 'entryTypeCode',
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'entryTypes',
|
||||||
|
fields: ['code', 'description'],
|
||||||
|
optionValue: 'code',
|
||||||
|
optionLabel: 'description',
|
||||||
|
},
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
width: '65px',
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.entryTypeDescription),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'companyFk',
|
name: 'companyFk',
|
||||||
|
@ -320,4 +341,5 @@ es:
|
||||||
Search entries: Buscar entradas
|
Search entries: Buscar entradas
|
||||||
You can search by entry reference: Puedes buscar por referencia de la entrada
|
You can search by entry reference: Puedes buscar por referencia de la entrada
|
||||||
Create entry: Crear entrada
|
Create entry: Crear entrada
|
||||||
|
Type: Tipo
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -34,18 +34,20 @@ const columns = computed(() => [
|
||||||
label: t('entryStockBought.buyer'),
|
label: t('entryStockBought.buyer'),
|
||||||
isTitle: true,
|
isTitle: true,
|
||||||
component: 'select',
|
component: 'select',
|
||||||
|
isEditable: false,
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'Workers/activeWithInheritedRole',
|
url: 'Workers/activeWithInheritedRole',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name', 'nickname'],
|
||||||
where: { role: 'buyer' },
|
where: { role: 'buyer' },
|
||||||
optionFilter: 'firstName',
|
optionFilter: 'firstName',
|
||||||
optionLabel: 'name',
|
optionLabel: 'nickname',
|
||||||
optionValue: 'id',
|
optionValue: 'id',
|
||||||
useLike: false,
|
useLike: false,
|
||||||
},
|
},
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
|
width: '70px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
@ -55,6 +57,7 @@ const columns = computed(() => [
|
||||||
create: true,
|
create: true,
|
||||||
component: 'number',
|
component: 'number',
|
||||||
summation: true,
|
summation: true,
|
||||||
|
width: '60px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
@ -78,6 +81,7 @@ const columns = computed(() => [
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
title: t('entryStockBought.viewMoreDetails'),
|
title: t('entryStockBought.viewMoreDetails'),
|
||||||
|
name: 'searchBtn',
|
||||||
icon: 'search',
|
icon: 'search',
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
action: (row) => {
|
action: (row) => {
|
||||||
|
@ -91,6 +95,7 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
'data-cy': 'table-actions',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -158,7 +163,7 @@ function round(value) {
|
||||||
@on-fetch="
|
@on-fetch="
|
||||||
(data) => {
|
(data) => {
|
||||||
travel = data.find(
|
travel = data.find(
|
||||||
(data) => data.warehouseIn?.code.toLowerCase() === 'vnh'
|
(data) => data.warehouseIn?.code.toLowerCase() === 'vnh',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
@ -179,6 +184,7 @@ function round(value) {
|
||||||
@click="openDialog()"
|
@click="openDialog()"
|
||||||
:title="t('entryStockBought.editTravel')"
|
:title="t('entryStockBought.editTravel')"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
data-cy="edit-travel"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
@ -239,10 +245,11 @@ function round(value) {
|
||||||
table-height="80vh"
|
table-height="80vh"
|
||||||
auto-load
|
auto-load
|
||||||
:column-search="false"
|
:column-search="false"
|
||||||
|
:without-header="true"
|
||||||
>
|
>
|
||||||
<template #column-workerFk="{ row }">
|
<template #column-workerFk="{ row }">
|
||||||
<span class="link" @click.stop>
|
<span class="link" @click.stop>
|
||||||
{{ row?.worker?.user?.name }}
|
{{ row?.worker?.user?.nickname }}
|
||||||
<WorkerDescriptorProxy :id="row?.workerFk" />
|
<WorkerDescriptorProxy :id="row?.workerFk" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
@ -279,10 +286,11 @@ function round(value) {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.column {
|
.column {
|
||||||
|
min-width: 30%;
|
||||||
|
margin-top: 5%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-width: 35%;
|
|
||||||
}
|
}
|
||||||
.text-negative {
|
.text-negative {
|
||||||
color: $negative !important;
|
color: $negative !important;
|
||||||
|
|
|
@ -21,7 +21,7 @@ const $props = defineProps({
|
||||||
const customUrl = `StockBoughts/getStockBoughtDetail?workerFk=${$props.workerFk}&dated=${$props.dated}`;
|
const customUrl = `StockBoughts/getStockBoughtDetail?workerFk=${$props.workerFk}&dated=${$props.dated}`;
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'right',
|
||||||
label: t('Entry'),
|
label: t('Entry'),
|
||||||
name: 'entryFk',
|
name: 'entryFk',
|
||||||
isTitle: true,
|
isTitle: true,
|
||||||
|
@ -29,7 +29,7 @@ const columns = [
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'right',
|
||||||
name: 'itemFk',
|
name: 'itemFk',
|
||||||
label: t('Item'),
|
label: t('Item'),
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
|
@ -44,21 +44,21 @@ const columns = [
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'right',
|
||||||
name: 'volume',
|
name: 'volume',
|
||||||
label: t('Volume'),
|
label: t('Volume'),
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'right',
|
||||||
label: t('Packaging'),
|
label: t('Packaging'),
|
||||||
name: 'packagingFk',
|
name: 'packagingFk',
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'right',
|
||||||
label: 'Packing',
|
label: 'Packing',
|
||||||
name: 'packing',
|
name: 'packing',
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
|
@ -73,12 +73,14 @@ const columns = [
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="StockBoughtsDetail"
|
data-key="StockBoughtsDetail"
|
||||||
:url="customUrl"
|
:url="customUrl"
|
||||||
order="itemName DESC"
|
order="volume DESC"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
:disable-infinite-scroll="true"
|
:disable-infinite-scroll="true"
|
||||||
:disable-option="{ card: true }"
|
:disable-option="{ card: true }"
|
||||||
:limit="0"
|
:limit="0"
|
||||||
|
:without-header="true"
|
||||||
|
:with-filters="false"
|
||||||
auto-load
|
auto-load
|
||||||
>
|
>
|
||||||
<template #column-entryFk="{ row }">
|
<template #column-entryFk="{ row }">
|
||||||
|
@ -105,7 +107,7 @@ const columns = [
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
background-color: var(--vn-section-color);
|
background-color: var(--vn-section-color);
|
||||||
padding: 4px;
|
padding: 2%;
|
||||||
}
|
}
|
||||||
.container > div > div > .q-table__top.relative-position.row.items-center {
|
.container > div > div > .q-table__top.relative-position.row.items-center {
|
||||||
background-color: red !important;
|
background-color: red !important;
|
||||||
|
|
|
@ -7,7 +7,6 @@ import { toDate } from 'src/filters';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import { getTotal } from 'src/composables/getTotal';
|
import { getTotal } from 'src/composables/getTotal';
|
||||||
import CrudModel from 'src/components/CrudModel.vue';
|
import CrudModel from 'src/components/CrudModel.vue';
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
|
@ -22,7 +21,6 @@ const invoiceIn = computed(() => arrayData.store.data);
|
||||||
const currency = computed(() => invoiceIn.value?.currency?.code);
|
const currency = computed(() => invoiceIn.value?.currency?.code);
|
||||||
|
|
||||||
const rowsSelected = ref([]);
|
const rowsSelected = ref([]);
|
||||||
const banks = ref([]);
|
|
||||||
const invoiceInFormRef = ref();
|
const invoiceInFormRef = ref();
|
||||||
const invoiceId = +route.params.id;
|
const invoiceId = +route.params.id;
|
||||||
const filter = { where: { invoiceInFk: invoiceId } };
|
const filter = { where: { invoiceInFk: invoiceId } };
|
||||||
|
@ -41,10 +39,9 @@ const columns = computed(() => [
|
||||||
name: 'bank',
|
name: 'bank',
|
||||||
label: t('Bank'),
|
label: t('Bank'),
|
||||||
field: (row) => row.bankFk,
|
field: (row) => row.bankFk,
|
||||||
options: banks.value,
|
|
||||||
model: 'bankFk',
|
model: 'bankFk',
|
||||||
optionValue: 'id',
|
|
||||||
optionLabel: 'bank',
|
optionLabel: 'bank',
|
||||||
|
url: 'Accountings',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
tabIndex: 2,
|
tabIndex: 2,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -82,12 +79,6 @@ onBeforeMount(async () => {
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
|
||||||
url="Accountings"
|
|
||||||
auto-load
|
|
||||||
limit="30"
|
|
||||||
@on-fetch="(data) => (banks = data)"
|
|
||||||
/>
|
|
||||||
<CrudModel
|
<CrudModel
|
||||||
v-if="invoiceIn"
|
v-if="invoiceIn"
|
||||||
ref="invoiceInFormRef"
|
ref="invoiceInFormRef"
|
||||||
|
@ -117,9 +108,9 @@ onBeforeMount(async () => {
|
||||||
<QTd>
|
<QTd>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
v-model="row[col.model]"
|
v-model="row[col.model]"
|
||||||
:options="col.options"
|
:url="col.url"
|
||||||
:option-value="col.optionValue"
|
|
||||||
:option-label="col.optionLabel"
|
:option-label="col.optionLabel"
|
||||||
|
:option-value="col.optionValue"
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem v-bind="scope.itemProps">
|
<QItem v-bind="scope.itemProps">
|
||||||
|
@ -193,8 +184,7 @@ onBeforeMount(async () => {
|
||||||
:label="t('Bank')"
|
:label="t('Bank')"
|
||||||
class="full-width"
|
class="full-width"
|
||||||
v-model="props.row['bankFk']"
|
v-model="props.row['bankFk']"
|
||||||
:options="banks"
|
url="Accountings"
|
||||||
option-value="id"
|
|
||||||
option-label="bank"
|
option-label="bank"
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
|
|
|
@ -103,7 +103,7 @@ const refundInvoice = async (withWarehouse) => {
|
||||||
t('refundInvoiceSuccessMessage', {
|
t('refundInvoiceSuccessMessage', {
|
||||||
refundTicket: data[0].id,
|
refundTicket: data[0].id,
|
||||||
}),
|
}),
|
||||||
'positive'
|
'positive',
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -124,6 +124,13 @@ const showRefundInvoiceForm = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showExportationLetter = () => {
|
||||||
|
openReport(`InvoiceOuts/${$props.invoiceOutData.ref}/exportation-pdf`, {
|
||||||
|
recipientId: $props.invoiceOutData.client.id,
|
||||||
|
refFk: $props.invoiceOutData.ref,
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -172,7 +179,7 @@ const showRefundInvoiceForm = () => {
|
||||||
t('Confirm deletion'),
|
t('Confirm deletion'),
|
||||||
t('Are you sure you want to delete this invoice?'),
|
t('Are you sure you want to delete this invoice?'),
|
||||||
deleteInvoice,
|
deleteInvoice,
|
||||||
redirectToInvoiceOutList
|
redirectToInvoiceOutList,
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -185,7 +192,7 @@ const showRefundInvoiceForm = () => {
|
||||||
openConfirmationModal(
|
openConfirmationModal(
|
||||||
'',
|
'',
|
||||||
t('Are you sure you want to book this invoice?'),
|
t('Are you sure you want to book this invoice?'),
|
||||||
bookInvoice
|
bookInvoice,
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -198,7 +205,7 @@ const showRefundInvoiceForm = () => {
|
||||||
openConfirmationModal(
|
openConfirmationModal(
|
||||||
t('Generate PDF invoice document'),
|
t('Generate PDF invoice document'),
|
||||||
t('Are you sure you want to generate/regenerate the PDF invoice?'),
|
t('Are you sure you want to generate/regenerate the PDF invoice?'),
|
||||||
generateInvoicePdf
|
generateInvoicePdf,
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -226,6 +233,14 @@ const showRefundInvoiceForm = () => {
|
||||||
{{ t('Create a single ticket with all the content of the current invoice') }}
|
{{ t('Create a single ticket with all the content of the current invoice') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
<QItem
|
||||||
|
v-if="$props.invoiceOutData.serial === 'E'"
|
||||||
|
v-ripple
|
||||||
|
clickable
|
||||||
|
@click="showExportationLetter()"
|
||||||
|
>
|
||||||
|
<QItemSection>{{ t('Show CITES letter') }}</QItemSection>
|
||||||
|
</QItem>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
@ -255,7 +270,7 @@ es:
|
||||||
Create a single ticket with all the content of the current invoice: Crear un ticket único con todo el contenido de la factura actual
|
Create a single ticket with all the content of the current invoice: Crear un ticket único con todo el contenido de la factura actual
|
||||||
refundInvoiceSuccessMessage: Se ha creado el siguiente ticket de abono {refundTicket}
|
refundInvoiceSuccessMessage: Se ha creado el siguiente ticket de abono {refundTicket}
|
||||||
The email can't be empty: El email no puede estar vacío
|
The email can't be empty: El email no puede estar vacío
|
||||||
|
Show CITES letter: Ver carta CITES
|
||||||
en:
|
en:
|
||||||
refundInvoiceSuccessMessage: The following refund ticket have been created {refundTicket}
|
refundInvoiceSuccessMessage: The following refund ticket have been created {refundTicket}
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -125,7 +125,7 @@ const ticketsColumns = ref([
|
||||||
:value="toDate(invoiceOut.issued)"
|
:value="toDate(invoiceOut.issued)"
|
||||||
/>
|
/>
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('invoiceOut.summary.dued')"
|
:label="t('invoiceOut.summary.expirationDate')"
|
||||||
:value="toDate(invoiceOut.dued)"
|
:value="toDate(invoiceOut.dued)"
|
||||||
/>
|
/>
|
||||||
<VnLv :label="t('globals.created')" :value="toDate(invoiceOut.created)" />
|
<VnLv :label="t('globals.created')" :value="toDate(invoiceOut.created)" />
|
||||||
|
|
|
@ -22,7 +22,7 @@ const states = ref();
|
||||||
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
|
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
|
||||||
<template #tags="{ tag, formatFn }">
|
<template #tags="{ tag, formatFn }">
|
||||||
<div class="q-gutter-x-xs">
|
<div class="q-gutter-x-xs">
|
||||||
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
<strong>{{ t(`invoiceOut.params.${tag.label}`) }}: </strong>
|
||||||
<span>{{ formatFn(tag.value) }}</span>
|
<span>{{ formatFn(tag.value) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -84,15 +84,6 @@ const states = ref();
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<VnInputDate
|
|
||||||
v-model="params.issued"
|
|
||||||
:label="t('Issued')"
|
|
||||||
is-outlined
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
|
@ -110,37 +101,3 @@ const states = ref();
|
||||||
</template>
|
</template>
|
||||||
</VnFilterPanel>
|
</VnFilterPanel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
params:
|
|
||||||
search: Contains
|
|
||||||
clientFk: Customer
|
|
||||||
fi: FI
|
|
||||||
amount: Amount
|
|
||||||
min: Min
|
|
||||||
max: Max
|
|
||||||
hasPdf: Has PDF
|
|
||||||
issued: Issued
|
|
||||||
created: Created
|
|
||||||
dued: Dued
|
|
||||||
es:
|
|
||||||
params:
|
|
||||||
search: Contiene
|
|
||||||
clientFk: Cliente
|
|
||||||
fi: CIF
|
|
||||||
amount: Importe
|
|
||||||
min: Min
|
|
||||||
max: Max
|
|
||||||
hasPdf: Tiene PDF
|
|
||||||
issued: Emitida
|
|
||||||
created: Creada
|
|
||||||
dued: Vencida
|
|
||||||
Customer ID: ID cliente
|
|
||||||
FI: CIF
|
|
||||||
Amount: Importe
|
|
||||||
Has PDF: Tiene PDF
|
|
||||||
Issued: Fecha emisión
|
|
||||||
Created: Fecha creación
|
|
||||||
Dued: Fecha vencimiento
|
|
||||||
</i18n>
|
|
||||||
|
|
|
@ -71,14 +71,6 @@ const columns = computed(() => [
|
||||||
inWhere: true,
|
inWhere: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
name: 'issued',
|
|
||||||
label: t('invoiceOut.summary.issued'),
|
|
||||||
component: 'date',
|
|
||||||
format: (row) => toDate(row.issued),
|
|
||||||
columnField: { component: null },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'clientFk',
|
name: 'clientFk',
|
||||||
|
|
|
@ -10,6 +10,8 @@ import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vu
|
||||||
import TicketDescriptorProxy from '../Ticket/Card/TicketDescriptorProxy.vue';
|
import TicketDescriptorProxy from '../Ticket/Card/TicketDescriptorProxy.vue';
|
||||||
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
|
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
|
import InvoiceOutNegativeBasesFilter from './InvoiceOutNegativeBasesFilter.vue';
|
||||||
|
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
|
@ -97,16 +99,19 @@ const columns = computed(() => [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'isActive',
|
name: 'isActive',
|
||||||
label: t('invoiceOut.negativeBases.active'),
|
label: t('invoiceOut.negativeBases.active'),
|
||||||
|
component: 'checkbox',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'hasToInvoice',
|
name: 'hasToInvoice',
|
||||||
label: t('invoiceOut.negativeBases.hasToInvoice'),
|
label: t('invoiceOut.negativeBases.hasToInvoice'),
|
||||||
|
component: 'checkbox',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'hasVerifiedData',
|
name: 'isTaxDataChecked',
|
||||||
label: t('invoiceOut.negativeBases.verifiedData'),
|
label: t('invoiceOut.negativeBases.verifiedData'),
|
||||||
|
component: 'checkbox',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -142,7 +147,7 @@ const downloadCSV = async () => {
|
||||||
await invoiceOutGlobalStore.getNegativeBasesCsv(
|
await invoiceOutGlobalStore.getNegativeBasesCsv(
|
||||||
userParams.from,
|
userParams.from,
|
||||||
userParams.to,
|
userParams.to,
|
||||||
filterParams
|
filterParams,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -154,6 +159,11 @@ const downloadCSV = async () => {
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</template>
|
</template>
|
||||||
</VnSubToolbar>
|
</VnSubToolbar>
|
||||||
|
<RightMenu>
|
||||||
|
<template #right-panel>
|
||||||
|
<InvoiceOutNegativeBasesFilter data-key="negativeFilter" />
|
||||||
|
</template>
|
||||||
|
</RightMenu>
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="negativeFilter"
|
data-key="negativeFilter"
|
||||||
|
@ -174,6 +184,7 @@ const downloadCSV = async () => {
|
||||||
auto-load
|
auto-load
|
||||||
:is-editable="false"
|
:is-editable="false"
|
||||||
:use-model="true"
|
:use-model="true"
|
||||||
|
:right-search="false"
|
||||||
>
|
>
|
||||||
<template #column-clientId="{ row }">
|
<template #column-clientId="{ row }">
|
||||||
<span class="link" @click.stop>
|
<span class="link" @click.stop>
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -24,11 +25,11 @@ const props = defineProps({
|
||||||
>
|
>
|
||||||
<template #tags="{ tag, formatFn }">
|
<template #tags="{ tag, formatFn }">
|
||||||
<div class="q-gutter-x-xs">
|
<div class="q-gutter-x-xs">
|
||||||
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
<strong>{{ t(`invoiceOut.params.${tag.label}`) }}: </strong>
|
||||||
<span>{{ formatFn(tag.value) }}</span>
|
<span>{{ formatFn(tag.value) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ params }">
|
<template #body="{ params, searchFn }">
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
|
@ -49,38 +50,70 @@ const props = defineProps({
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnSelect
|
||||||
v-model="params.company"
|
url="Companies"
|
||||||
:label="t('globals.company')"
|
:label="t('globals.company')"
|
||||||
is-outlined
|
v-model="params.company"
|
||||||
/>
|
option-label="code"
|
||||||
|
option-value="code"
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
@update:model-value="searchFn()"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ scope.opt?.code }}
|
||||||
|
</QItemLabel>
|
||||||
|
<QItemLabel caption>
|
||||||
|
{{ `#${scope.opt?.id}` }}
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnSelect
|
||||||
|
url="Countries"
|
||||||
|
:label="t('globals.params.countryFk')"
|
||||||
v-model="params.country"
|
v-model="params.country"
|
||||||
:label="t('globals.country')"
|
option-label="name"
|
||||||
is-outlined
|
option-value="name"
|
||||||
/>
|
outlined
|
||||||
|
dense
|
||||||
|
rounded
|
||||||
|
@update:model-value="searchFn()"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ scope.opt?.name }}
|
||||||
|
</QItemLabel>
|
||||||
|
<QItemLabel caption>
|
||||||
|
{{ `#${scope.opt?.id}` }}
|
||||||
|
</QItemLabel>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
</template>
|
||||||
<QItem>
|
</VnSelect>
|
||||||
<QItemSection>
|
|
||||||
<VnInput
|
|
||||||
v-model="params.clientId"
|
|
||||||
:label="t('invoiceOut.negativeBases.clientId')"
|
|
||||||
is-outlined
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnSelect
|
||||||
v-model="params.clientSocialName"
|
url="Clients"
|
||||||
:label="t('globals.client')"
|
:label="t('globals.client')"
|
||||||
is-outlined
|
v-model="params.clientId"
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
rounded
|
||||||
|
@update:model-value="searchFn()"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
@ -90,15 +123,18 @@ const props = defineProps({
|
||||||
v-model="params.amount"
|
v-model="params.amount"
|
||||||
:label="t('globals.amount')"
|
:label="t('globals.amount')"
|
||||||
is-outlined
|
is-outlined
|
||||||
|
:positive="false"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnSelectWorker
|
||||||
v-model="params.comercialName"
|
|
||||||
:label="t('invoiceOut.negativeBases.comercial')"
|
:label="t('invoiceOut.negativeBases.comercial')"
|
||||||
|
v-model="params.workerName"
|
||||||
|
option-value="name"
|
||||||
is-outlined
|
is-outlined
|
||||||
|
@update:model-value="searchFn()"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
|
|
@ -4,7 +4,7 @@ invoiceOut:
|
||||||
params:
|
params:
|
||||||
company: Company
|
company: Company
|
||||||
country: Country
|
country: Country
|
||||||
clientId: Client ID
|
clientId: Client
|
||||||
clientSocialName: Client
|
clientSocialName: Client
|
||||||
taxableBase: Base
|
taxableBase: Base
|
||||||
ticketFk: Ticket
|
ticketFk: Ticket
|
||||||
|
@ -12,6 +12,18 @@ invoiceOut:
|
||||||
hasToInvoice: Has to invoice
|
hasToInvoice: Has to invoice
|
||||||
hasVerifiedData: Verified data
|
hasVerifiedData: Verified data
|
||||||
workerName: Worker
|
workerName: Worker
|
||||||
|
isTaxDataChecked: Verified data
|
||||||
|
amount: Amount
|
||||||
|
clientFk: Client
|
||||||
|
companyFk: Company
|
||||||
|
created: Created
|
||||||
|
dued: Dued
|
||||||
|
customsAgentFk: Custom Agent
|
||||||
|
ref: Reference
|
||||||
|
fi: FI
|
||||||
|
min: Min
|
||||||
|
max: Max
|
||||||
|
hasPdf: Has PDF
|
||||||
card:
|
card:
|
||||||
issued: Issued
|
issued: Issued
|
||||||
customerCard: Customer card
|
customerCard: Customer card
|
||||||
|
@ -19,6 +31,7 @@ invoiceOut:
|
||||||
summary:
|
summary:
|
||||||
issued: Issued
|
issued: Issued
|
||||||
dued: Due
|
dued: Due
|
||||||
|
expirationDate: Expiration date
|
||||||
booked: Booked
|
booked: Booked
|
||||||
taxBreakdown: Tax breakdown
|
taxBreakdown: Tax breakdown
|
||||||
taxableBase: Taxable base
|
taxableBase: Taxable base
|
||||||
|
@ -52,7 +65,7 @@ invoiceOut:
|
||||||
active: Active
|
active: Active
|
||||||
hasToInvoice: Has to Invoice
|
hasToInvoice: Has to Invoice
|
||||||
verifiedData: Verified Data
|
verifiedData: Verified Data
|
||||||
comercial: Commercial
|
comercial: Sales person
|
||||||
errors:
|
errors:
|
||||||
downloadCsvFailed: CSV download failed
|
downloadCsvFailed: CSV download failed
|
||||||
invoiceOutModule:
|
invoiceOutModule:
|
||||||
|
|
|
@ -4,7 +4,7 @@ invoiceOut:
|
||||||
params:
|
params:
|
||||||
company: Empresa
|
company: Empresa
|
||||||
country: País
|
country: País
|
||||||
clientId: ID del cliente
|
clientId: Cliente
|
||||||
clientSocialName: Cliente
|
clientSocialName: Cliente
|
||||||
taxableBase: Base
|
taxableBase: Base
|
||||||
ticketFk: Ticket
|
ticketFk: Ticket
|
||||||
|
@ -12,6 +12,18 @@ invoiceOut:
|
||||||
hasToInvoice: Debe facturar
|
hasToInvoice: Debe facturar
|
||||||
hasVerifiedData: Datos verificados
|
hasVerifiedData: Datos verificados
|
||||||
workerName: Comercial
|
workerName: Comercial
|
||||||
|
isTaxDataChecked: Datos comprobados
|
||||||
|
amount: Importe
|
||||||
|
clientFk: Cliente
|
||||||
|
companyFk: Empresa
|
||||||
|
created: Creada
|
||||||
|
dued: Vencida
|
||||||
|
customsAgentFk: Agente aduanas
|
||||||
|
ref: Referencia
|
||||||
|
fi: CIF
|
||||||
|
min: Min
|
||||||
|
max: Max
|
||||||
|
hasPdf: Tiene PDF
|
||||||
card:
|
card:
|
||||||
issued: Fecha emisión
|
issued: Fecha emisión
|
||||||
customerCard: Ficha del cliente
|
customerCard: Ficha del cliente
|
||||||
|
@ -19,6 +31,7 @@ invoiceOut:
|
||||||
summary:
|
summary:
|
||||||
issued: Fecha
|
issued: Fecha
|
||||||
dued: Fecha límite
|
dued: Fecha límite
|
||||||
|
expirationDate: Fecha vencimiento
|
||||||
booked: Contabilizada
|
booked: Contabilizada
|
||||||
taxBreakdown: Desglose impositivo
|
taxBreakdown: Desglose impositivo
|
||||||
taxableBase: Base imp.
|
taxableBase: Base imp.
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
import VnSelect from 'components/common/VnSelect.vue';
|
import VnSelect from 'components/common/VnSelect.vue';
|
||||||
import ItemsFilterPanel from 'src/components/ItemsFilterPanel.vue';
|
import ItemsFilterPanel from 'src/components/ItemsFilterPanel.vue';
|
||||||
|
@ -16,17 +14,9 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const itemTypeWorkersOptions = ref([]);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
|
||||||
url="TicketRequests/getItemTypeWorker"
|
|
||||||
limit="30"
|
|
||||||
auto-load
|
|
||||||
:filter="{ fields: ['id', 'nickname'], order: 'nickname ASC', limit: 30 }"
|
|
||||||
@on-fetch="(data) => (itemTypeWorkersOptions = data)"
|
|
||||||
/>
|
|
||||||
<ItemsFilterPanel :data-key="props.dataKey" :custom-tags="['tags']">
|
<ItemsFilterPanel :data-key="props.dataKey" :custom-tags="['tags']">
|
||||||
<template #body="{ params, searchFn }">
|
<template #body="{ params, searchFn }">
|
||||||
<QItem class="q-my-md">
|
<QItem class="q-my-md">
|
||||||
|
@ -34,14 +24,15 @@ const itemTypeWorkersOptions = ref([]);
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('params.buyerFk')"
|
:label="t('params.buyerFk')"
|
||||||
v-model="params.buyerFk"
|
v-model="params.buyerFk"
|
||||||
:options="itemTypeWorkersOptions"
|
url="TicketRequests/getItemTypeWorker"
|
||||||
option-value="id"
|
:fields="['id', 'nickname']"
|
||||||
option-label="nickname"
|
option-label="nickname"
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
use-input
|
use-input
|
||||||
@update:model-value="searchFn()"
|
@update:model-value="searchFn()"
|
||||||
|
sort-by="nickname ASC"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
@ -50,11 +41,10 @@ const itemTypeWorkersOptions = ref([]);
|
||||||
<VnSelect
|
<VnSelect
|
||||||
url="Warehouses"
|
url="Warehouses"
|
||||||
auto-load
|
auto-load
|
||||||
:filter="{ fields: ['id', 'name'], order: 'name ASC', limit: 30 }"
|
:fields="['id', 'name']"
|
||||||
|
sort-by="name ASC"
|
||||||
:label="t('params.warehouseFk')"
|
:label="t('params.warehouseFk')"
|
||||||
v-model="params.warehouseFk"
|
v-model="params.warehouseFk"
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
|
|
|
@ -46,7 +46,6 @@ const exprBuilder = (param, value) => {
|
||||||
url="AgencyModes"
|
url="AgencyModes"
|
||||||
:filter="{ fields: ['id', 'name'] }"
|
:filter="{ fields: ['id', 'name'] }"
|
||||||
sort-by="name ASC"
|
sort-by="name ASC"
|
||||||
limit="30"
|
|
||||||
@on-fetch="(data) => (agencyList = data)"
|
@on-fetch="(data) => (agencyList = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
|
@ -54,7 +53,6 @@ const exprBuilder = (param, value) => {
|
||||||
url="Agencies"
|
url="Agencies"
|
||||||
:filter="{ fields: ['id', 'name'] }"
|
:filter="{ fields: ['id', 'name'] }"
|
||||||
sort-by="name ASC"
|
sort-by="name ASC"
|
||||||
limit="30"
|
|
||||||
@on-fetch="(data) => (agencyAgreementList = data)"
|
@on-fetch="(data) => (agencyAgreementList = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
|
@ -120,7 +118,11 @@ const exprBuilder = (param, value) => {
|
||||||
<VnSelectSupplier
|
<VnSelectSupplier
|
||||||
:label="t('Autonomous')"
|
:label="t('Autonomous')"
|
||||||
v-model="params.supplierFk"
|
v-model="params.supplierFk"
|
||||||
hide-selected
|
url="Suppliers"
|
||||||
|
:fields="['name']"
|
||||||
|
sort-by="name ASC"
|
||||||
|
option-value="name"
|
||||||
|
option-label="name"
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
|
|
|
@ -6,6 +6,8 @@ import VnLv from 'components/ui/VnLv.vue';
|
||||||
import { dashIfEmpty, toDate } from 'src/filters';
|
import { dashIfEmpty, toDate } from 'src/filters';
|
||||||
import RouteDescriptorMenu from 'pages/Route/Card/RouteDescriptorMenu.vue';
|
import RouteDescriptorMenu from 'pages/Route/Card/RouteDescriptorMenu.vue';
|
||||||
import filter from './RouteFilter.js';
|
import filter from './RouteFilter.js';
|
||||||
|
import useCardDescription from 'src/composables/useCardDescription';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -16,7 +18,6 @@ const $props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
|
||||||
const zone = ref();
|
const zone = ref();
|
||||||
const zoneId = ref();
|
const zoneId = ref();
|
||||||
const entityId = computed(() => {
|
const entityId = computed(() => {
|
||||||
|
@ -50,9 +51,9 @@ onMounted(async () => {
|
||||||
width="lg-width"
|
width="lg-width"
|
||||||
>
|
>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<VnLv :label="t('Date')" :value="toDate(entity?.dated)" />
|
<VnLv :label="$t('Date')" :value="toDate(entity?.dated)" />
|
||||||
<VnLv :label="t('Agency')" :value="entity?.agencyMode?.name" />
|
<VnLv :label="$t('Agency')" :value="entity?.agencyMode?.name" />
|
||||||
<VnLv :label="t('Zone')" :value="zone" />
|
<VnLv :label="$t('Zone')" :value="zone" />
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="$t('Volume')"
|
:label="$t('Volume')"
|
||||||
:value="`${dashIfEmpty(entity?.m3)} / ${dashIfEmpty(
|
:value="`${dashIfEmpty(entity?.m3)} / ${dashIfEmpty(
|
||||||
|
|
|
@ -14,7 +14,6 @@ export default {
|
||||||
'started',
|
'started',
|
||||||
'finished',
|
'finished',
|
||||||
'cost',
|
'cost',
|
||||||
'zoneFk',
|
|
||||||
'isOk',
|
'isOk',
|
||||||
],
|
],
|
||||||
include: [
|
include: [
|
||||||
|
@ -23,7 +22,6 @@ export default {
|
||||||
relation: 'vehicle',
|
relation: 'vehicle',
|
||||||
scope: { fields: ['id', 'm3'] },
|
scope: { fields: ['id', 'm3'] },
|
||||||
},
|
},
|
||||||
{ relation: 'zone', scope: { fields: ['id', 'name'] } },
|
|
||||||
{
|
{
|
||||||
relation: 'worker',
|
relation: 'worker',
|
||||||
scope: {
|
scope: {
|
||||||
|
|
|
@ -28,52 +28,6 @@ const defaultInitialData = {
|
||||||
isOk: false,
|
isOk: false,
|
||||||
};
|
};
|
||||||
const maxDistance = ref();
|
const maxDistance = ref();
|
||||||
|
|
||||||
const routeFilter = {
|
|
||||||
fields: [
|
|
||||||
'id',
|
|
||||||
'workerFk',
|
|
||||||
'agencyModeFk',
|
|
||||||
'dated',
|
|
||||||
'm3',
|
|
||||||
'warehouseFk',
|
|
||||||
'description',
|
|
||||||
'vehicleFk',
|
|
||||||
'kmStart',
|
|
||||||
'kmEnd',
|
|
||||||
'started',
|
|
||||||
'finished',
|
|
||||||
'cost',
|
|
||||||
'isOk',
|
|
||||||
],
|
|
||||||
include: [
|
|
||||||
{ relation: 'agencyMode', scope: { fields: ['id', 'name'] } },
|
|
||||||
{
|
|
||||||
relation: 'vehicle',
|
|
||||||
scope: { fields: ['id', 'm3'] },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
relation: 'ticket',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'name', 'zoneFk'],
|
|
||||||
include: { relation: 'zone', scope: { fields: ['id', 'name'] } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
relation: 'worker',
|
|
||||||
scope: {
|
|
||||||
fields: ['id'],
|
|
||||||
include: {
|
|
||||||
relation: 'user',
|
|
||||||
scope: {
|
|
||||||
fields: ['id'],
|
|
||||||
include: { relation: 'emailUser', scope: { fields: ['email'] } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
const onSave = (data, response) => {
|
const onSave = (data, response) => {
|
||||||
if (isNew) {
|
if (isNew) {
|
||||||
axios.post(`Routes/${response?.id}/updateWorkCenter`);
|
axios.post(`Routes/${response?.id}/updateWorkCenter`);
|
||||||
|
|
|
@ -48,7 +48,6 @@ const onFetch = (data) => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}"
|
}"
|
||||||
limit="30"
|
|
||||||
@on-fetch="onFetch"
|
@on-fetch="onFetch"
|
||||||
/>
|
/>
|
||||||
<div :class="[isDialog ? 'column' : 'form-gap', 'full-width flex']">
|
<div :class="[isDialog ? 'column' : 'form-gap', 'full-width flex']">
|
||||||
|
|
|
@ -18,6 +18,7 @@ const onSave = (data, response) => {
|
||||||
<template>
|
<template>
|
||||||
<FormModel
|
<FormModel
|
||||||
:update-url="`Roadmaps/${$route.params?.id}`"
|
:update-url="`Roadmaps/${$route.params?.id}`"
|
||||||
|
:url="`Roadmaps/${$route.params?.id}`"
|
||||||
observe-form-changes
|
observe-form-changes
|
||||||
model="Roadmap"
|
model="Roadmap"
|
||||||
auto-load
|
auto-load
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
|
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
import VnInput from 'components/common/VnInput.vue';
|
import VnInput from 'components/common/VnInput.vue';
|
||||||
|
@ -65,6 +63,7 @@ const emit = defineEmits(['search']);
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelectSupplier
|
<VnSelectSupplier
|
||||||
:label="t('Carrier')"
|
:label="t('Carrier')"
|
||||||
|
:fields="['id', 'nickname']"
|
||||||
v-model="params.supplierFk"
|
v-model="params.supplierFk"
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
|
|
|
@ -21,6 +21,10 @@ const $props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: 'mana',
|
default: 'mana',
|
||||||
},
|
},
|
||||||
|
sale: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['save', 'cancel']);
|
const emit = defineEmits(['save', 'cancel']);
|
||||||
|
@ -29,8 +33,8 @@ const { t } = useI18n();
|
||||||
const QPopupProxyRef = ref(null);
|
const QPopupProxyRef = ref(null);
|
||||||
const manaCode = ref($props.manaCode);
|
const manaCode = ref($props.manaCode);
|
||||||
|
|
||||||
const save = () => {
|
const save = (sale = $props.sale) => {
|
||||||
emit('save');
|
emit('save', sale);
|
||||||
QPopupProxyRef.value.hide();
|
QPopupProxyRef.value.hide();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,16 +42,20 @@ const cancel = () => {
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
QPopupProxyRef.value.hide();
|
QPopupProxyRef.value.hide();
|
||||||
};
|
};
|
||||||
|
defineExpose({ save });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QPopupProxy ref="QPopupProxyRef">
|
<QPopupProxy ref="QPopupProxyRef" data-cy="ticketEditManaProxy">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<QSpinner v-if="!mana" color="primary" size="md" />
|
<QSpinner v-if="!mana" color="primary" size="md" />
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="header">Mana: {{ toCurrency(mana) }}</div>
|
<div class="header">Mana: {{ toCurrency(mana) }}</div>
|
||||||
<div class="q-pa-md">
|
<div class="q-pa-md">
|
||||||
<slot />
|
<slot :popup="QPopupProxyRef" />
|
||||||
|
<div v-if="usesMana" class="column q-gutter-y-sm q-mt-sm">
|
||||||
|
<VnUsesMana :mana-code="manaCode" />
|
||||||
|
</div>
|
||||||
<div v-if="newPrice" class="column items-center q-mt-lg">
|
<div v-if="newPrice" class="column items-center q-mt-lg">
|
||||||
<span class="text-primary">{{ t('New price') }}</span>
|
<span class="text-primary">{{ t('New price') }}</span>
|
||||||
<span class="text-subtitle1">
|
<span class="text-subtitle1">
|
||||||
|
@ -56,9 +64,6 @@ const cancel = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="usesMana" class="column q-gutter-y-sm q-mt-sm">
|
|
||||||
<VnUsesMana :mana-code="manaCode" />
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<QBtn
|
<QBtn
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|
|
@ -49,7 +49,7 @@ watch(
|
||||||
<FetchData
|
<FetchData
|
||||||
@on-fetch="(data) => (listPackagingsOptions = data)"
|
@on-fetch="(data) => (listPackagingsOptions = data)"
|
||||||
auto-load
|
auto-load
|
||||||
:filter="{ fields: ['packagingFk', 'name'], order: 'name ASC', limit: 30 }"
|
:filter="{ fields: ['packagingFk', 'name'], order: 'name ASC' }"
|
||||||
url="Packagings/listPackaging"
|
url="Packagings/listPackaging"
|
||||||
/>
|
/>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
|
|
|
@ -22,7 +22,6 @@ import { useVnConfirm } from 'composables/useVnConfirm';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import VnTable from 'src/components/VnTable/VnTable.vue';
|
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 VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||||
import TicketProblems from 'src/components/TicketProblems.vue';
|
import TicketProblems from 'src/components/TicketProblems.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||||
|
@ -33,6 +32,7 @@ const { t } = useI18n();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const { openConfirmationModal } = useVnConfirm();
|
const { openConfirmationModal } = useVnConfirm();
|
||||||
const editPriceProxyRef = ref(null);
|
const editPriceProxyRef = ref(null);
|
||||||
|
const editManaProxyRef = ref(null);
|
||||||
const stateBtnDropdownRef = ref(null);
|
const stateBtnDropdownRef = ref(null);
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const arrayData = useArrayData('Ticket');
|
const arrayData = useArrayData('Ticket');
|
||||||
|
@ -53,7 +53,6 @@ const transfer = ref({
|
||||||
sales: [],
|
sales: [],
|
||||||
});
|
});
|
||||||
const tableRef = ref([]);
|
const tableRef = ref([]);
|
||||||
const canProceed = ref();
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => route.params.id,
|
() => route.params.id,
|
||||||
|
@ -133,7 +132,6 @@ const columns = computed(() => [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('globals.amount'),
|
label: t('globals.amount'),
|
||||||
name: 'amount',
|
name: 'amount',
|
||||||
format: (row) => parseInt(row.amount * row.quantity),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -183,8 +181,6 @@ const resetChanges = async () => {
|
||||||
};
|
};
|
||||||
const rowToUpdate = ref(null);
|
const rowToUpdate = ref(null);
|
||||||
const changeQuantity = async (sale) => {
|
const changeQuantity = async (sale) => {
|
||||||
canProceed.value = await isSalePrepared(sale);
|
|
||||||
if (!canProceed.value) return;
|
|
||||||
if (
|
if (
|
||||||
!sale.itemFk ||
|
!sale.itemFk ||
|
||||||
sale.quantity == null ||
|
sale.quantity == null ||
|
||||||
|
@ -193,11 +189,21 @@ const changeQuantity = async (sale) => {
|
||||||
return;
|
return;
|
||||||
if (!sale.id) return addSale(sale);
|
if (!sale.id) return addSale(sale);
|
||||||
|
|
||||||
|
if (await isSalePrepared(sale)) {
|
||||||
|
await confirmUpdate(() => updateQuantity(sale));
|
||||||
|
} else await updateQuantity(sale);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateQuantity = async (sale) => {
|
||||||
try {
|
try {
|
||||||
|
let { quantity, id } = sale;
|
||||||
if (!rowToUpdate.value) return;
|
if (!rowToUpdate.value) return;
|
||||||
rowToUpdate.value = null;
|
rowToUpdate.value = null;
|
||||||
sale.isNew = false;
|
sale.isNew = false;
|
||||||
await updateQuantity(sale);
|
const params = { quantity: quantity };
|
||||||
|
await axios.post(`Sales/${id}/updateQuantity`, params);
|
||||||
|
notify('globals.dataSaved', 'positive');
|
||||||
|
tableRef.value.reload();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const { quantity } = tableRef.value.CrudModelRef.originalData.find(
|
const { quantity } = tableRef.value.CrudModelRef.originalData.find(
|
||||||
(s) => s.id === sale.id,
|
(s) => s.id === sale.id,
|
||||||
|
@ -207,12 +213,6 @@ const changeQuantity = async (sale) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateQuantity = async ({ quantity, id }) => {
|
|
||||||
const params = { quantity: quantity };
|
|
||||||
await axios.post(`Sales/${id}/updateQuantity`, params);
|
|
||||||
notify('globals.dataSaved', 'positive');
|
|
||||||
};
|
|
||||||
|
|
||||||
const addSale = async (sale) => {
|
const addSale = async (sale) => {
|
||||||
const params = {
|
const params = {
|
||||||
barcode: sale.itemFk,
|
barcode: sale.itemFk,
|
||||||
|
@ -237,13 +237,17 @@ const addSale = async (sale) => {
|
||||||
sale.isNew = false;
|
sale.isNew = false;
|
||||||
arrayData.fetch({});
|
arrayData.fetch({});
|
||||||
};
|
};
|
||||||
|
const changeConcept = async (sale) => {
|
||||||
|
if (await isSalePrepared(sale)) {
|
||||||
|
await confirmUpdate(() => updateConcept(sale));
|
||||||
|
} else await updateConcept(sale);
|
||||||
|
};
|
||||||
|
|
||||||
const updateConcept = async (sale) => {
|
const updateConcept = async (sale) => {
|
||||||
canProceed.value = await isSalePrepared(sale);
|
|
||||||
if (!canProceed.value) return;
|
|
||||||
const data = { newConcept: sale.concept };
|
const data = { newConcept: sale.concept };
|
||||||
await axios.post(`Sales/${sale.id}/updateConcept`, data);
|
await axios.post(`Sales/${sale.id}/updateConcept`, data);
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
|
tableRef.value.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_EDIT = {
|
const DEFAULT_EDIT = {
|
||||||
|
@ -295,33 +299,43 @@ const onOpenEditDiscountPopover = async (sale) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const changePrice = async (sale) => {
|
||||||
const updatePrice = async (sale) => {
|
|
||||||
canProceed.value = await isSalePrepared(sale);
|
|
||||||
if (!canProceed.value) return;
|
|
||||||
const newPrice = edit.value.price;
|
const newPrice = edit.value.price;
|
||||||
if (newPrice != null && newPrice != sale.price) {
|
if (newPrice != null && newPrice != sale.price) {
|
||||||
|
if (await isSalePrepared(sale)) {
|
||||||
|
await confirmUpdate(() => updatePrice(sale, newPrice));
|
||||||
|
} else updatePrice(sale, newPrice);
|
||||||
|
}
|
||||||
|
await getMana();
|
||||||
|
};
|
||||||
|
const updatePrice = async (sale, newPrice) => {
|
||||||
await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice });
|
await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice });
|
||||||
sale.price = newPrice;
|
sale.price = newPrice;
|
||||||
edit.value = { ...DEFAULT_EDIT };
|
edit.value = { ...DEFAULT_EDIT };
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
}
|
tableRef.value.reload();
|
||||||
|
|
||||||
await getMana();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeDiscount = async (sale) => {
|
const changeDiscount = async (sale) => {
|
||||||
canProceed.value = await isSalePrepared(sale);
|
|
||||||
if (!canProceed.value) return;
|
|
||||||
const newDiscount = edit.value.discount;
|
const newDiscount = edit.value.discount;
|
||||||
if (newDiscount != null && newDiscount != sale.discount) updateDiscount([sale]);
|
if (newDiscount != null && newDiscount != sale.discount) {
|
||||||
|
if (await isSalePrepared(sale))
|
||||||
|
await confirmUpdate(() => updateDiscount([sale], newDiscount));
|
||||||
|
else await updateDiscount([sale], newDiscount);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateDiscounts = async (sales, newDiscount = null) => {
|
||||||
|
const salesTracking = await fetchSalesTracking();
|
||||||
|
|
||||||
|
const someSaleIsPrepared = salesTracking.some((sale) =>
|
||||||
|
matchSale(salesTracking, sale),
|
||||||
|
);
|
||||||
|
if (someSaleIsPrepared) await confirmUpdate(() => updateDiscount(sales, newDiscount));
|
||||||
|
else updateDiscount(sales, newDiscount);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateDiscount = async (sales, newDiscount = null) => {
|
const updateDiscount = async (sales, newDiscount = null) => {
|
||||||
for (const sale of sales) {
|
|
||||||
const canProceed = await isSalePrepared(sale);
|
|
||||||
if (!canProceed) return;
|
|
||||||
}
|
|
||||||
const saleIds = sales.map((sale) => sale.id);
|
const saleIds = sales.map((sale) => sale.id);
|
||||||
const _newDiscount = newDiscount || edit.value.discount;
|
const _newDiscount = newDiscount || edit.value.discount;
|
||||||
const params = {
|
const params = {
|
||||||
|
@ -331,8 +345,7 @@ const updateDiscount = async (sales, newDiscount = null) => {
|
||||||
};
|
};
|
||||||
await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
|
await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
for (let sale of sales) sale.discount = _newDiscount;
|
tableRef.value.reload();
|
||||||
edit.value = { ...DEFAULT_EDIT };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getNewPrice = computed(() => {
|
const getNewPrice = computed(() => {
|
||||||
|
@ -425,9 +438,13 @@ onMounted(async () => {
|
||||||
const items = ref([]);
|
const items = ref([]);
|
||||||
const newRow = ref({});
|
const newRow = ref({});
|
||||||
|
|
||||||
|
const changeItem = async (sale) => {
|
||||||
|
if (await isSalePrepared(sale)) {
|
||||||
|
await confirmUpdate(() => updateItem(sale));
|
||||||
|
} else await updateItem(sale);
|
||||||
|
};
|
||||||
|
|
||||||
const updateItem = async (row) => {
|
const updateItem = async (row) => {
|
||||||
canProceed.value = await isSalePrepared(row);
|
|
||||||
if (!canProceed.value) return;
|
|
||||||
const selectedItem = items.value.find((item) => item.id === row.itemFk);
|
const selectedItem = items.value.find((item) => item.id === row.itemFk);
|
||||||
if (selectedItem) {
|
if (selectedItem) {
|
||||||
row.item = selectedItem;
|
row.item = selectedItem;
|
||||||
|
@ -471,7 +488,18 @@ const endNewRow = (row) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async function isSalePrepared(item) {
|
async function confirmUpdate(cb) {
|
||||||
|
await quasar
|
||||||
|
.dialog({
|
||||||
|
component: VnConfirm,
|
||||||
|
componentProps: {
|
||||||
|
title: t('Item prepared'),
|
||||||
|
message: t('This item is already prepared. Do you want to continue?'),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.onOk(cb);
|
||||||
|
}
|
||||||
|
async function fetchSalesTracking() {
|
||||||
const filter = {
|
const filter = {
|
||||||
params: {
|
params: {
|
||||||
where: { ticketFk: route.params.id },
|
where: { ticketFk: route.params.id },
|
||||||
|
@ -483,48 +511,37 @@ async function isSalePrepared(item) {
|
||||||
filter: JSON.stringify(filter),
|
filter: JSON.stringify(filter),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
return data;
|
||||||
const matchingSale = data.find((sale) => sale.itemFk === item.itemFk);
|
|
||||||
if (!matchingSale) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
async function isSalePrepared(sale) {
|
||||||
matchingSale.hasSaleGroupDetail ||
|
const data = await fetchSalesTracking();
|
||||||
matchingSale.isControled ||
|
return matchSale(data, sale);
|
||||||
matchingSale.isPrepared ||
|
}
|
||||||
matchingSale.isPrevious ||
|
function matchSale(data, sale) {
|
||||||
matchingSale.isPreviousSelected
|
const matchingSale = data.find(({ itemFk }) => itemFk === sale.itemFk);
|
||||||
) {
|
|
||||||
try {
|
if (!matchingSale) {
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
quasar
|
|
||||||
.dialog({
|
|
||||||
component: VnConfirm,
|
|
||||||
componentProps: {
|
|
||||||
title: t('Item prepared'),
|
|
||||||
message: t(
|
|
||||||
'This item is already prepared. Do you want to continue?',
|
|
||||||
),
|
|
||||||
data: item,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.onOk(() => resolve(true))
|
|
||||||
.onCancel(() => reject(new Error('cancelled')));
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
tableRef.value.reload();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return isPrepared(matchingSale);
|
||||||
|
}
|
||||||
|
function isPrepared(sale) {
|
||||||
|
const flagsToCheck = [
|
||||||
|
'hasSaleGroupDetail',
|
||||||
|
'isControled',
|
||||||
|
'isPrepared',
|
||||||
|
'isPrevious',
|
||||||
|
'isPreviousSelected',
|
||||||
|
];
|
||||||
|
return flagsToCheck.some((flag) => sale[flag] === 1);
|
||||||
|
}
|
||||||
watch(
|
watch(
|
||||||
() => newRow.value.itemFk,
|
() => newRow.value.itemFk,
|
||||||
(newItemFk) => {
|
(newItemFk) => {
|
||||||
if (newItemFk) {
|
if (newItemFk) {
|
||||||
updateItem(newRow.value);
|
changeItem(newRow.value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -585,7 +602,7 @@ watch(
|
||||||
:mana="mana"
|
:mana="mana"
|
||||||
:ticket-config="ticketConfig"
|
:ticket-config="ticketConfig"
|
||||||
@get-mana="getMana()"
|
@get-mana="getMana()"
|
||||||
@update-discounts="updateDiscount"
|
@update-discounts="updateDiscounts"
|
||||||
@refresh-table="resetChanges"
|
@refresh-table="resetChanges"
|
||||||
/>
|
/>
|
||||||
<QBtn
|
<QBtn
|
||||||
|
@ -716,7 +733,7 @@ watch(
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="row.itemFk"
|
v-model="row.itemFk"
|
||||||
:use-like="false"
|
:use-like="false"
|
||||||
@update:model-value="updateItem(row)"
|
@update:model-value="changeItem(row)"
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem v-bind="scope.itemProps">
|
<QItem v-bind="scope.itemProps">
|
||||||
|
@ -742,16 +759,21 @@ watch(
|
||||||
</div>
|
</div>
|
||||||
<FetchedTags :item="row" :max-length="6" />
|
<FetchedTags :item="row" :max-length="6" />
|
||||||
<QPopupProxy v-if="row.id && isTicketEditable">
|
<QPopupProxy v-if="row.id && isTicketEditable">
|
||||||
<VnInput v-model="row.concept" @change="updateConcept(row)" />
|
<VnInput
|
||||||
|
v-model="row.concept"
|
||||||
|
@keyup.enter.stop="changeConcept(row)"
|
||||||
|
:hint="t('globals.enterToConfirm')"
|
||||||
|
/>
|
||||||
</QPopupProxy>
|
</QPopupProxy>
|
||||||
</template>
|
</template>
|
||||||
<template #column-quantity="{ row }">
|
<template #column-quantity="{ row }">
|
||||||
<VnInput
|
<VnInput
|
||||||
|
data-cy="ticketSaleQuantityInput"
|
||||||
v-if="row.isNew || isTicketEditable"
|
v-if="row.isNew || isTicketEditable"
|
||||||
type="number"
|
type="number"
|
||||||
v-model.number="row.quantity"
|
v-model.number="row.quantity"
|
||||||
@blur="changeQuantity(row)"
|
@blur="changeQuantity(row)"
|
||||||
@keyup.enter="changeQuantity(row)"
|
@keyup.enter.stop="changeQuantity(row)"
|
||||||
@update:model-value="() => (rowToUpdate = row)"
|
@update:model-value="() => (rowToUpdate = row)"
|
||||||
@focus="edit.oldQuantity = row.quantity"
|
@focus="edit.oldQuantity = row.quantity"
|
||||||
/>
|
/>
|
||||||
|
@ -765,10 +787,12 @@ watch(
|
||||||
<TicketEditManaProxy
|
<TicketEditManaProxy
|
||||||
ref="editPriceProxyRef"
|
ref="editPriceProxyRef"
|
||||||
:mana="mana"
|
:mana="mana"
|
||||||
|
:sale="row"
|
||||||
:new-price="getNewPrice"
|
:new-price="getNewPrice"
|
||||||
@save="updatePrice(row)"
|
@save="changePrice"
|
||||||
>
|
>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
@keyup.enter.stop="() => editManaProxyRef.save(row)"
|
||||||
v-model.number="edit.price"
|
v-model.number="edit.price"
|
||||||
:label="t('basicData.price')"
|
:label="t('basicData.price')"
|
||||||
type="number"
|
type="number"
|
||||||
|
@ -782,27 +806,29 @@ watch(
|
||||||
<QBtn flat class="link" dense @click="onOpenEditDiscountPopover(row)">
|
<QBtn flat class="link" dense @click="onOpenEditDiscountPopover(row)">
|
||||||
{{ toPercentage(row.discount / 100) }}
|
{{ toPercentage(row.discount / 100) }}
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
|
||||||
<TicketEditManaProxy
|
<TicketEditManaProxy
|
||||||
|
ref="editManaProxyRef"
|
||||||
:mana="mana"
|
:mana="mana"
|
||||||
|
:sale="row"
|
||||||
:new-price="getNewPrice"
|
:new-price="getNewPrice"
|
||||||
:uses-mana="usesMana"
|
:uses-mana="usesMana"
|
||||||
:mana-code="manaCode"
|
:mana-code="manaCode"
|
||||||
@save="changeDiscount(row)"
|
@save="changeDiscount"
|
||||||
>
|
>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
autofocus
|
||||||
|
@keyup.enter.stop="() => editManaProxyRef.save(row)"
|
||||||
v-model.number="edit.discount"
|
v-model.number="edit.discount"
|
||||||
:label="t('ticketSale.discount')"
|
:label="t('ticketSale.discount')"
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
<div v-if="usesMana" class="column q-gutter-y-sm q-mt-sm">
|
|
||||||
<VnUsesMana :mana-code="manaCode" />
|
|
||||||
</div>
|
|
||||||
</TicketEditManaProxy>
|
</TicketEditManaProxy>
|
||||||
</template>
|
</template>
|
||||||
<span v-else>{{ toPercentage(row.discount / 100) }}</span>
|
<span v-else>{{ toPercentage(row.discount / 100) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #column-amount="{ row }">
|
<template #column-amount="{ row }">
|
||||||
{{ toCurrency(row.quantity * row.price) }}
|
{{ toCurrency(getSaleTotal(row)) }}
|
||||||
</template>
|
</template>
|
||||||
</VnTable>
|
</VnTable>
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import useNotify from 'src/composables/useNotify.js';
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
import { toDateTimeFormat } from 'src/filters/date.js';
|
import { toDateTimeFormat } from 'src/filters/date.js';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import TicketProblems from 'src/components/TicketProblems.vue';
|
||||||
|
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -286,71 +287,7 @@ watch(
|
||||||
</span>
|
</span>
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
<QIcon
|
<TicketProblems :row />
|
||||||
v-if="row.isTaxDataChecked === 0"
|
|
||||||
color="primary"
|
|
||||||
name="vn:no036"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.noVerified') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasTicketRequest"
|
|
||||||
color="primary"
|
|
||||||
name="vn:buyrequest"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.purchaseRequest') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.itemShortage"
|
|
||||||
color="primary"
|
|
||||||
name="vn:unavailable"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('ticketSale.noVisible') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.isFreezed"
|
|
||||||
color="primary"
|
|
||||||
name="vn:frozen"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.clientFrozen') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon v-if="row.risk" color="primary" name="vn:risk" size="xs">
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.risk') }}: {{ row.risk }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasComponentLack"
|
|
||||||
color="primary"
|
|
||||||
name="vn:components"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.componentLack') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasRounding"
|
|
||||||
color="primary"
|
|
||||||
name="sync_problem"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.rounding') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #column-id="{ row }">
|
<template #column-id="{ row }">
|
||||||
|
|
|
@ -9,6 +9,7 @@ import VnRow from 'components/ui/VnRow.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
|
import VnInputTime from 'components/common/VnInputTime.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -53,7 +54,16 @@ const warehousesOptionsIn = ref([]);
|
||||||
<VnInputDate v-model="data.shipped" :label="t('globals.shipped')" />
|
<VnInputDate v-model="data.shipped" :label="t('globals.shipped')" />
|
||||||
<VnInputDate v-model="data.landed" :label="t('globals.landed')" />
|
<VnInputDate v-model="data.landed" :label="t('globals.landed')" />
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
<VnRow>
|
||||||
|
<VnInputDate
|
||||||
|
v-model="data.availabled"
|
||||||
|
:label="t('travel.summary.availabled')"
|
||||||
|
/>
|
||||||
|
<VnInputTime
|
||||||
|
v-model="data.availabled"
|
||||||
|
:label="t('travel.summary.availabledHour')"
|
||||||
|
/>
|
||||||
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('globals.warehouseOut')"
|
:label="t('globals.warehouseOut')"
|
||||||
|
@ -101,10 +111,3 @@ const warehousesOptionsIn = ref([]);
|
||||||
</template>
|
</template>
|
||||||
</FormModel>
|
</FormModel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
|
||||||
es:
|
|
||||||
raidDays: El travel se desplaza automáticamente cada día para estar desde hoy al número de días indicado. Si se deja vacio no se moverá
|
|
||||||
en:
|
|
||||||
raidDays: The travel adjusts itself daily to match the number of days set, starting from today. If left blank, it won’t move
|
|
||||||
</i18n>
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ export default {
|
||||||
'agencyModeFk',
|
'agencyModeFk',
|
||||||
'isRaid',
|
'isRaid',
|
||||||
'daysInForward',
|
'daysInForward',
|
||||||
|
'availabled',
|
||||||
],
|
],
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,8 @@ import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue'
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
import { toDate, toCurrency, toCelsius } from 'src/filters';
|
import { toDate, toCurrency, toCelsius } from 'src/filters';
|
||||||
|
import { toDateTimeFormat } from 'src/filters/date.js';
|
||||||
|
import { dashIfEmpty } from 'src/filters';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
|
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
|
||||||
|
|
||||||
|
@ -333,6 +335,12 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
|
||||||
<VnLv :label="t('globals.reference')" :value="travel.ref" />
|
<VnLv :label="t('globals.reference')" :value="travel.ref" />
|
||||||
<VnLv label="m³" :value="travel.m3" />
|
<VnLv label="m³" :value="travel.m3" />
|
||||||
<VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" />
|
<VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" />
|
||||||
|
<VnLv
|
||||||
|
:label="t('travel.summary.availabled')"
|
||||||
|
:value="
|
||||||
|
dashIfEmpty(toDateTimeFormat(travel.availabled))
|
||||||
|
"
|
||||||
|
/>
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="full-width">
|
<QCard class="full-width">
|
||||||
<VnTitle :text="t('travel.summary.entries')" />
|
<VnTitle :text="t('travel.summary.entries')" />
|
||||||
|
|
|
@ -209,7 +209,7 @@ const onThermographCreated = async (data) => {
|
||||||
}"
|
}"
|
||||||
sort-by="thermographFk ASC"
|
sort-by="thermographFk ASC"
|
||||||
option-label="thermographFk"
|
option-label="thermographFk"
|
||||||
option-filter-value="id"
|
option-filter-value="thermographFk"
|
||||||
:disable="viewAction === 'edit'"
|
:disable="viewAction === 'edit'"
|
||||||
:tooltip="t('New thermograph')"
|
:tooltip="t('New thermograph')"
|
||||||
:roles-allowed-to-create="['logistic']"
|
:roles-allowed-to-create="['logistic']"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { onMounted, ref, computed, watch } from 'vue';
|
import { onMounted, ref, computed, watch } from 'vue';
|
||||||
import { QBtn } from 'quasar';
|
import { QBtn } from 'quasar';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
||||||
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
|
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
|
||||||
|
@ -22,6 +23,8 @@ import VnPopup from 'src/components/common/VnPopup.vue';
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { openReport } = usePrintService();
|
const { openReport } = usePrintService();
|
||||||
|
const route = useRoute();
|
||||||
|
const tableParams = ref();
|
||||||
|
|
||||||
const shippedFrom = ref(Date.vnNew());
|
const shippedFrom = ref(Date.vnNew());
|
||||||
const landedTo = ref(Date.vnNew());
|
const landedTo = ref(Date.vnNew());
|
||||||
|
@ -143,7 +146,7 @@ const columns = computed(() => [
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('globals.pageTitles.supplier'),
|
label: t('extraCommunity.cargoShip'),
|
||||||
field: 'cargoSupplierNickname',
|
field: 'cargoSupplierNickname',
|
||||||
name: 'cargoSupplierNickname',
|
name: 'cargoSupplierNickname',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -171,7 +174,7 @@ const columns = computed(() => [
|
||||||
? value.reduce((sum, entry) => {
|
? value.reduce((sum, entry) => {
|
||||||
return sum + (entry.invoiceAmount || 0);
|
return sum + (entry.invoiceAmount || 0);
|
||||||
}, 0)
|
}, 0)
|
||||||
: 0
|
: 0,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -200,7 +203,7 @@ const columns = computed(() => [
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('kg'),
|
label: t('extraCommunity.kg'),
|
||||||
field: 'kg',
|
field: 'kg',
|
||||||
name: 'kg',
|
name: 'kg',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -208,7 +211,7 @@ const columns = computed(() => [
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('physicKg'),
|
label: t('extraCommunity.physicKg'),
|
||||||
field: 'loadedKg',
|
field: 'loadedKg',
|
||||||
name: 'loadedKg',
|
name: 'loadedKg',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -232,7 +235,7 @@ const columns = computed(() => [
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('shipped'),
|
label: t('extraCommunity.shipped'),
|
||||||
field: 'shipped',
|
field: 'shipped',
|
||||||
name: 'shipped',
|
name: 'shipped',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -249,7 +252,7 @@ const columns = computed(() => [
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('landed'),
|
label: t('extraCommunity.landed'),
|
||||||
field: 'landed',
|
field: 'landed',
|
||||||
name: 'landed',
|
name: 'landed',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -258,7 +261,7 @@ const columns = computed(() => [
|
||||||
format: (value) => toDate(value),
|
format: (value) => toDate(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('notes'),
|
label: t('extraCommunity.notes'),
|
||||||
field: '',
|
field: '',
|
||||||
name: 'notes',
|
name: 'notes',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
@ -284,7 +287,7 @@ watch(
|
||||||
if (!arrayData.store.data) return;
|
if (!arrayData.store.data) return;
|
||||||
onStoreDataChange();
|
onStoreDataChange();
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
const openReportPdf = () => {
|
const openReportPdf = () => {
|
||||||
|
@ -451,13 +454,24 @@ const getColor = (percentage) => {
|
||||||
for (const { value, className } of travelKgPercentages.value)
|
for (const { value, className } of travelKgPercentages.value)
|
||||||
if (percentage > value) return className;
|
if (percentage > value) return className;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const filteredEntries = (entries) => {
|
||||||
|
if (!tableParams?.value?.entrySupplierFk) return entries;
|
||||||
|
return entries?.filter(
|
||||||
|
(entry) => entry.supplierFk === tableParams?.value?.entrySupplierFk,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(route, () => {
|
||||||
|
tableParams.value = JSON.parse(route.query.table);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnSearchbar
|
<VnSearchbar
|
||||||
data-key="ExtraCommunity"
|
data-key="ExtraCommunity"
|
||||||
:limit="20"
|
:limit="20"
|
||||||
:label="t('searchExtraCommunity')"
|
:label="t('extraCommunity.searchExtraCommunity')"
|
||||||
/>
|
/>
|
||||||
<RightMenu>
|
<RightMenu>
|
||||||
<template #right-panel>
|
<template #right-panel>
|
||||||
|
@ -521,7 +535,7 @@ const getColor = (percentage) => {
|
||||||
? tableColumnComponents[col.name].event(
|
? tableColumnComponents[col.name].event(
|
||||||
rows[props.rowIndex][col.field],
|
rows[props.rowIndex][col.field],
|
||||||
col.field,
|
col.field,
|
||||||
props.rowIndex
|
props.rowIndex,
|
||||||
)
|
)
|
||||||
: {}
|
: {}
|
||||||
"
|
"
|
||||||
|
@ -546,7 +560,7 @@ const getColor = (percentage) => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
link: ['id', 'cargoSupplierNickname'].includes(
|
link: ['id', 'cargoSupplierNickname'].includes(
|
||||||
col.name
|
col.name,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
|
@ -564,9 +578,8 @@ const getColor = (percentage) => {
|
||||||
</component>
|
</component>
|
||||||
</QTd>
|
</QTd>
|
||||||
</QTr>
|
</QTr>
|
||||||
|
|
||||||
<QTr
|
<QTr
|
||||||
v-for="(entry, index) in props.row.entries"
|
v-for="(entry, index) in filteredEntries(props.row.entries)"
|
||||||
:key="index"
|
:key="index"
|
||||||
:props="props"
|
:props="props"
|
||||||
class="bg-vn-secondary-row cursor-pointer"
|
class="bg-vn-secondary-row cursor-pointer"
|
||||||
|
@ -598,7 +611,7 @@ const getColor = (percentage) => {
|
||||||
name="warning"
|
name="warning"
|
||||||
color="negative"
|
color="negative"
|
||||||
size="md"
|
size="md"
|
||||||
:title="t('requiresInspection')"
|
:title="t('extraCommunity.requiresInspection')"
|
||||||
>
|
>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
</QTd>
|
</QTd>
|
||||||
|
@ -709,24 +722,3 @@ const getColor = (percentage) => {
|
||||||
width: max-content;
|
width: max-content;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
searchExtraCommunity: Search for extra community shipping
|
|
||||||
kg: BI. KG
|
|
||||||
physicKg: Phy. KG
|
|
||||||
shipped: W. shipped
|
|
||||||
landed: W. landed
|
|
||||||
requiresInspection: Requires inspection
|
|
||||||
BIP: Boder Inspection Point
|
|
||||||
notes: Notes
|
|
||||||
es:
|
|
||||||
searchExtraCommunity: Buscar por envío extra comunitario
|
|
||||||
kg: KG Bloq.
|
|
||||||
physicKg: KG físico
|
|
||||||
shipped: F. envío
|
|
||||||
landed: F. llegada
|
|
||||||
notes: Notas
|
|
||||||
Open as PDF: Abrir como PDF
|
|
||||||
requiresInspection: Requiere inspección
|
|
||||||
BIP: Punto de Inspección Fronteriza
|
|
||||||
</i18n>
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ warehouses();
|
||||||
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
|
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
|
||||||
<template #tags="{ tag, formatFn }">
|
<template #tags="{ tag, formatFn }">
|
||||||
<div class="q-gutter-x-xs">
|
<div class="q-gutter-x-xs">
|
||||||
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
<strong>{{ t(`extraCommunity.filter.${tag.label}`) }}: </strong>
|
||||||
<span>{{ formatFn(tag.value) }}</span>
|
<span>{{ formatFn(tag.value) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -92,7 +92,7 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnInput
|
||||||
:label="t('params.reference')"
|
:label="t('extraCommunity.filter.reference')"
|
||||||
v-model="params.reference"
|
v-model="params.reference"
|
||||||
is-outlined
|
is-outlined
|
||||||
/>
|
/>
|
||||||
|
@ -103,7 +103,7 @@ warehouses();
|
||||||
<QInput
|
<QInput
|
||||||
v-model="params.totalEntries"
|
v-model="params.totalEntries"
|
||||||
type="number"
|
type="number"
|
||||||
:label="t('params.totalEntries')"
|
:label="t('extraCommunity.filter.totalEntries')"
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
|
@ -133,10 +133,10 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('params.agencyModeFk')"
|
:label="t('extraCommunity.filter.agencyModeFk')"
|
||||||
v-model="params.agencyModeFk"
|
v-model="params.agencyModeFk"
|
||||||
:options="agenciesOptions"
|
:options="agenciesOptions"
|
||||||
option-value="agencyFk"
|
option-value="id"
|
||||||
option-label="name"
|
option-label="name"
|
||||||
hide-selected
|
hide-selected
|
||||||
dense
|
dense
|
||||||
|
@ -148,7 +148,7 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
:label="t('params.shippedFrom')"
|
:label="t('extraCommunity.filter.shippedFrom')"
|
||||||
v-model="params.shippedFrom"
|
v-model="params.shippedFrom"
|
||||||
@update:model-value="searchFn()"
|
@update:model-value="searchFn()"
|
||||||
is-outlined
|
is-outlined
|
||||||
|
@ -158,7 +158,7 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
:label="t('params.landedTo')"
|
:label="t('extraCommunity.filter.landedTo')"
|
||||||
v-model="params.landedTo"
|
v-model="params.landedTo"
|
||||||
@update:model-value="searchFn()"
|
@update:model-value="searchFn()"
|
||||||
is-outlined
|
is-outlined
|
||||||
|
@ -168,7 +168,7 @@ warehouses();
|
||||||
<QItem v-if="warehousesByContinent[params.continent]">
|
<QItem v-if="warehousesByContinent[params.continent]">
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('params.warehouseOutFk')"
|
:label="t('extraCommunity.filter.warehouseOutFk')"
|
||||||
v-model="params.warehouseOutFk"
|
v-model="params.warehouseOutFk"
|
||||||
:options="warehousesByContinent[params.continent]"
|
:options="warehousesByContinent[params.continent]"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
|
@ -183,7 +183,7 @@ warehouses();
|
||||||
<QItem v-else>
|
<QItem v-else>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('params.warehouseOutFk')"
|
:label="t('extraCommunity.filter.warehouseOutFk')"
|
||||||
v-model="params.warehouseOutFk"
|
v-model="params.warehouseOutFk"
|
||||||
:options="warehousesOptions"
|
:options="warehousesOptions"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
|
@ -198,7 +198,7 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('params.warehouseInFk')"
|
:label="t('extraCommunity.filter.warehouseInFk')"
|
||||||
v-model="params.warehouseInFk"
|
v-model="params.warehouseInFk"
|
||||||
:options="warehousesOptions"
|
:options="warehousesOptions"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
|
@ -213,6 +213,7 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelectSupplier
|
<VnSelectSupplier
|
||||||
|
:label="t('extraCommunity.cargoShip')"
|
||||||
v-model="params.cargoSupplierFk"
|
v-model="params.cargoSupplierFk"
|
||||||
hide-selected
|
hide-selected
|
||||||
dense
|
dense
|
||||||
|
@ -221,10 +222,21 @@ warehouses();
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<VnSelectSupplier
|
||||||
|
v-model="params.entrySupplierFk"
|
||||||
|
hide-selected
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('params.continent')"
|
:label="t('extraCommunity.filter.continent')"
|
||||||
v-model="params.continent"
|
v-model="params.continent"
|
||||||
:options="continentsOptions"
|
:options="continentsOptions"
|
||||||
option-value="code"
|
option-value="code"
|
||||||
|
@ -240,30 +252,3 @@ warehouses();
|
||||||
</template>
|
</template>
|
||||||
</VnFilterPanel>
|
</VnFilterPanel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
params:
|
|
||||||
id: Id
|
|
||||||
reference: Reference
|
|
||||||
totalEntries: Total entries
|
|
||||||
agencyModeFk: Agency
|
|
||||||
warehouseInFk: Warehouse In
|
|
||||||
warehouseOutFk: Warehouse Out
|
|
||||||
shippedFrom: Shipped from
|
|
||||||
landedTo: Landed to
|
|
||||||
cargoSupplierFk: Supplier
|
|
||||||
continent: Continent out
|
|
||||||
es:
|
|
||||||
params:
|
|
||||||
id: Id
|
|
||||||
reference: Referencia
|
|
||||||
totalEntries: Ent. totales
|
|
||||||
agencyModeFk: Agencia
|
|
||||||
warehouseInFk: Alm. entrada
|
|
||||||
warehouseOutFk: Alm. salida
|
|
||||||
shippedFrom: Llegada desde
|
|
||||||
landedTo: Llegada hasta
|
|
||||||
cargoSupplierFk: Proveedor
|
|
||||||
continent: Cont. Salida
|
|
||||||
</i18n>
|
|
||||||
|
|
|
@ -10,6 +10,9 @@ import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js';
|
||||||
import TravelFilter from './TravelFilter.vue';
|
import TravelFilter from './TravelFilter.vue';
|
||||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
import VnSection from 'src/components/common/VnSection.vue';
|
import VnSection from 'src/components/common/VnSection.vue';
|
||||||
|
import VnInputTime from 'src/components/common/VnInputTime.vue';
|
||||||
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
|
import { toDateTimeFormat } from 'src/filters/date';
|
||||||
|
|
||||||
const { viewSummary } = useSummaryDialog();
|
const { viewSummary } = useSummaryDialog();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -167,6 +170,17 @@ const columns = computed(() => [
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'availabled',
|
||||||
|
label: t('travel.summary.availabled'),
|
||||||
|
component: 'input',
|
||||||
|
columnClass: 'expand',
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(toDateTimeFormat(row.availabled)),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
align: 'right',
|
align: 'right',
|
||||||
label: '',
|
label: '',
|
||||||
|
@ -269,6 +283,16 @@ const columns = computed(() => [
|
||||||
:class="{ 'is-active': row.isReceived }"
|
:class="{ 'is-active': row.isReceived }"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #more-create-dialog="{ data }">
|
||||||
|
<VnInputDate
|
||||||
|
v-model="data.availabled"
|
||||||
|
:label="t('travel.summary.availabled')"
|
||||||
|
/>
|
||||||
|
<VnInputTime
|
||||||
|
v-model="data.availabled"
|
||||||
|
:label="t('travel.summary.availabledHour')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<template #moreFilterPanel="{ params }">
|
<template #moreFilterPanel="{ params }">
|
||||||
<VnInputNumber
|
<VnInputNumber
|
||||||
:label="t('params.scopeDays')"
|
:label="t('params.scopeDays')"
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
extraCommunity:
|
||||||
|
cargoShip: Cargo ship
|
||||||
|
searchExtraCommunity: Search for extra community shipping
|
||||||
|
kg: BI. KG
|
||||||
|
physicKg: Phy. KG
|
||||||
|
shipped: W. shipped
|
||||||
|
landed: W. landed
|
||||||
|
requiresInspection: Requires inspection
|
||||||
|
BIP: Boder Inspection Point
|
||||||
|
notes: Notes
|
||||||
|
filter:
|
||||||
|
id: Id
|
||||||
|
reference: Reference
|
||||||
|
totalEntries: Total entries
|
||||||
|
agencyModeFk: Agency
|
||||||
|
warehouseInFk: Warehouse In
|
||||||
|
warehouseOutFk: Warehouse Out
|
||||||
|
shippedFrom: Shipped from
|
||||||
|
landedTo: Landed to
|
||||||
|
cargoSupplierFk: Cargo supplier
|
||||||
|
continent: Continent out
|
||||||
|
entrySupplierFk: Supplier
|
|
@ -0,0 +1,23 @@
|
||||||
|
extraCommunity:
|
||||||
|
cargoShip: Carguera
|
||||||
|
searchExtraCommunity: Buscar por envío extra comunitario
|
||||||
|
kg: KG Bloq.
|
||||||
|
physicKg: KG físico
|
||||||
|
shipped: F. envío
|
||||||
|
landed: F. llegada
|
||||||
|
notes: Notas
|
||||||
|
Open as PDF: Abrir como PDF
|
||||||
|
requiresInspection: Requiere inspección
|
||||||
|
BIP: Punto de Inspección Fronteriza
|
||||||
|
filter:
|
||||||
|
id: Id
|
||||||
|
reference: Referencia
|
||||||
|
totalEntries: Ent. totales
|
||||||
|
agencyModeFk: Agencia
|
||||||
|
warehouseInFk: Alm. entrada
|
||||||
|
warehouseOutFk: Alm. salida
|
||||||
|
shippedFrom: Llegada desde
|
||||||
|
landedTo: Llegada hasta
|
||||||
|
cargoSupplierFk: Carguera
|
||||||
|
continent: Cont. Salida
|
||||||
|
entrySupplierFk: Proveedor
|
|
@ -53,7 +53,7 @@ const showChangePasswordDialog = () => {
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem
|
<QItem
|
||||||
v-if="!worker.user.emailVerified && user.id == worker.id"
|
v-if="!worker.user.emailVerified && user.id != worker.id"
|
||||||
v-ripple
|
v-ripple
|
||||||
clickable
|
clickable
|
||||||
@click="showChangePasswordDialog"
|
@click="showChangePasswordDialog"
|
||||||
|
|
|
@ -119,7 +119,7 @@ const columns = computed(() => [
|
||||||
:url="`Workers/${entityId}/trainingCourse`"
|
:url="`Workers/${entityId}/trainingCourse`"
|
||||||
:url-create="`Workers/${entityId}/trainingCourse`"
|
:url-create="`Workers/${entityId}/trainingCourse`"
|
||||||
save-url="TrainingCourses/crud"
|
save-url="TrainingCourses/crud"
|
||||||
:filter="courseFilter"
|
:user-filter="courseFilter"
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'trainingCourses',
|
urlCreate: 'trainingCourses',
|
||||||
title: t('Create training course'),
|
title: t('Create training course'),
|
||||||
|
|
|
@ -8,6 +8,17 @@ const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const entityId = computed(() => route.params.id);
|
const entityId = computed(() => route.params.id);
|
||||||
|
|
||||||
|
const centerFilter = {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'center',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -33,7 +44,7 @@ const columns = [
|
||||||
create: true,
|
create: true,
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'medicalCenters',
|
url: 'centers',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -84,6 +95,7 @@ const columns = [
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="WorkerMedical"
|
data-key="WorkerMedical"
|
||||||
:url="`Workers/${entityId}/medicalReview`"
|
:url="`Workers/${entityId}/medicalReview`"
|
||||||
|
:user-filter="centerFilter"
|
||||||
save-url="MedicalReviews/crud"
|
save-url="MedicalReviews/crud"
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'medicalReviews',
|
urlCreate: 'medicalReviews',
|
||||||
|
|
|
@ -176,6 +176,7 @@ const deleteRelative = async (id) => {
|
||||||
:label="t('isDescendant')"
|
:label="t('isDescendant')"
|
||||||
v-model="row.isDescendant"
|
v-model="row.isDescendant"
|
||||||
class="q-gutter-xs q-mb-xs"
|
class="q-gutter-xs q-mb-xs"
|
||||||
|
data-cy="Descendant/Ascendant"
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('disabilityGrades')"
|
:label="t('disabilityGrades')"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { computed, ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
import FormModel from 'src/components/FormModel.vue';
|
import FormModel from 'src/components/FormModel.vue';
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
|
@ -9,33 +9,23 @@ import VnInputTime from 'src/components/common/VnInputTime.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const agencyFilter = {
|
|
||||||
fields: ['id', 'name'],
|
|
||||||
order: 'name ASC',
|
|
||||||
limit: 30,
|
|
||||||
};
|
|
||||||
const agencyOptions = ref([]);
|
|
||||||
const validAddresses = ref([]);
|
const validAddresses = ref([]);
|
||||||
|
const addresses = ref([]);
|
||||||
|
|
||||||
const filterWhere = computed(() => ({
|
const setFilteredAddresses = (data) => {
|
||||||
id: { inq: validAddresses.value.map((item) => item.addressFk) },
|
const validIds = new Set(validAddresses.value.map((item) => item.addressFk));
|
||||||
}));
|
addresses.value = data.filter((address) => validIds.has(address.id));
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
|
||||||
:filter="agencyFilter"
|
|
||||||
@on-fetch="(data) => (agencyOptions = data)"
|
|
||||||
auto-load
|
|
||||||
url="AgencyModes/isActive"
|
|
||||||
/>
|
|
||||||
<FetchData
|
<FetchData
|
||||||
url="RoadmapAddresses"
|
url="RoadmapAddresses"
|
||||||
auto-load
|
auto-load
|
||||||
@on-fetch="(data) => (validAddresses = data)"
|
@on-fetch="(data) => (validAddresses = data)"
|
||||||
/>
|
/>
|
||||||
<FormModel :url="`Zones/${$route.params.id}`" auto-load data-key="Zone">
|
<FetchData url="Addresses" auto-load @on-fetch="setFilteredAddresses" />
|
||||||
|
<FormModel auto-load model="Zone">
|
||||||
<template #form="{ data, validate }">
|
<template #form="{ data, validate }">
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
@ -43,9 +33,9 @@ const filterWhere = computed(() => ({
|
||||||
:label="t('Name')"
|
:label="t('Name')"
|
||||||
clearable
|
clearable
|
||||||
v-model="data.name"
|
v-model="data.name"
|
||||||
|
:required="true"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
v-model="data.agencyModeFk"
|
v-model="data.agencyModeFk"
|
||||||
|
@ -94,7 +84,7 @@ const filterWhere = computed(() => ({
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
/>
|
/>
|
||||||
<VnInputTime v-model="data.hour" :label="t('Closing')" />
|
<VnInputTime v-model="data.hour" :label="t('Closing')" :required="true" />
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
|
||||||
<VnRow>
|
<VnRow>
|
||||||
|
@ -103,7 +93,7 @@ const filterWhere = computed(() => ({
|
||||||
:label="t('Price')"
|
:label="t('Price')"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
required="true"
|
:required="true"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
@ -111,7 +101,7 @@ const filterWhere = computed(() => ({
|
||||||
:label="t('Price optimum')"
|
:label="t('Price optimum')"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
required="true"
|
:required="true"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
@ -128,7 +118,7 @@ const filterWhere = computed(() => ({
|
||||||
v-model="data.addressFk"
|
v-model="data.addressFk"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
option-label="nickname"
|
option-label="nickname"
|
||||||
url="Addresses"
|
:options="addresses"
|
||||||
:fields="['id', 'nickname']"
|
:fields="['id', 'nickname']"
|
||||||
sort-by="id"
|
sort-by="id"
|
||||||
hide-selected
|
hide-selected
|
||||||
|
|
|
@ -38,7 +38,12 @@ const agencies = ref([]);
|
||||||
<template #body="{ params, searchFn }">
|
<template #body="{ params, searchFn }">
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput :label="t('list.name')" v-model="params.name" is-outlined />
|
<VnInput
|
||||||
|
:label="t('list.name')"
|
||||||
|
v-model="params.name"
|
||||||
|
is-outlined
|
||||||
|
data-cy="zoneFilterPanelNameInput"
|
||||||
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
|
@ -53,6 +58,7 @@ const agencies = ref([]);
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
|
data-cy="zoneFilterPanelAgencySelect"
|
||||||
>
|
>
|
||||||
</VnSelect>
|
</VnSelect>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
|
|
|
@ -65,7 +65,6 @@ const tableFilter = {
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'left',
|
|
||||||
name: 'id',
|
name: 'id',
|
||||||
label: t('list.id'),
|
label: t('list.id'),
|
||||||
chip: {
|
chip: {
|
||||||
|
@ -75,6 +74,8 @@ const columns = computed(() => [
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
inWhere: true,
|
inWhere: true,
|
||||||
},
|
},
|
||||||
|
columnClass: 'shrink-column',
|
||||||
|
component: 'number',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -106,7 +107,6 @@ const columns = computed(() => [
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row?.agencyMode?.name),
|
format: (row, dashIfEmpty) => dashIfEmpty(row?.agencyMode?.name),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
|
||||||
name: 'price',
|
name: 'price',
|
||||||
label: t('list.price'),
|
label: t('list.price'),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
@ -114,9 +114,11 @@ const columns = computed(() => [
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
inWhere: true,
|
inWhere: true,
|
||||||
},
|
},
|
||||||
|
columnClass: 'shrink-column',
|
||||||
|
component: 'number',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'center',
|
||||||
name: 'hour',
|
name: 'hour',
|
||||||
label: t('list.close'),
|
label: t('list.close'),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
@ -129,6 +131,7 @@ const columns = computed(() => [
|
||||||
label: t('list.addressFk'),
|
label: t('list.addressFk'),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
|
columnClass: 'expand',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'right',
|
align: 'right',
|
||||||
|
@ -177,6 +180,8 @@ function formatRow(row) {
|
||||||
<ZoneFilterPanel data-key="ZonesList" />
|
<ZoneFilterPanel data-key="ZonesList" />
|
||||||
</template>
|
</template>
|
||||||
</RightMenu>
|
</RightMenu>
|
||||||
|
<div class="table-container">
|
||||||
|
<div class="column items-center">
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="ZonesList"
|
data-key="ZonesList"
|
||||||
|
@ -191,6 +196,8 @@ function formatRow(row) {
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
redirect="zone"
|
redirect="zone"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
|
table-height="85vh"
|
||||||
|
order="id ASC"
|
||||||
>
|
>
|
||||||
<template #column-addressFk="{ row }">
|
<template #column-addressFk="{ row }">
|
||||||
{{ dashIfEmpty(formatRow(row)) }}
|
{{ dashIfEmpty(formatRow(row)) }}
|
||||||
|
@ -238,6 +245,8 @@ function formatRow(row) {
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VnTable>
|
</VnTable>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
@ -245,3 +254,20 @@ es:
|
||||||
Search zone: Buscar zona
|
Search zone: Buscar zona
|
||||||
You can search zones by id or name: Puedes buscar zonas por id o nombre
|
You can search zones by id or name: Puedes buscar zonas por id o nombre
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.table-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.shrink-column) {
|
||||||
|
width: 8%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -56,7 +56,7 @@ onMounted(() => weekdayStore.initStore());
|
||||||
<ZoneSearchbar />
|
<ZoneSearchbar />
|
||||||
<VnSubToolbar />
|
<VnSubToolbar />
|
||||||
<QPage class="column items-center q-pa-md">
|
<QPage class="column items-center q-pa-md">
|
||||||
<QCard class="full-width q-pa-md">
|
<QCard class="containerShrinked q-pa-md">
|
||||||
<div
|
<div
|
||||||
v-for="(detail, index) in details"
|
v-for="(detail, index) in details"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
|
|
@ -44,6 +44,8 @@ summary:
|
||||||
filterPanel:
|
filterPanel:
|
||||||
name: Name
|
name: Name
|
||||||
agencyModeFk: Agency
|
agencyModeFk: Agency
|
||||||
|
id: ID
|
||||||
|
price: Price
|
||||||
deliveryPanel:
|
deliveryPanel:
|
||||||
pickup: Pick up
|
pickup: Pick up
|
||||||
delivery: Delivery
|
delivery: Delivery
|
||||||
|
|
|
@ -45,6 +45,8 @@ summary:
|
||||||
filterPanel:
|
filterPanel:
|
||||||
name: Nombre
|
name: Nombre
|
||||||
agencyModeFk: Agencia
|
agencyModeFk: Agencia
|
||||||
|
id: ID
|
||||||
|
price: Precio
|
||||||
deliveryPanel:
|
deliveryPanel:
|
||||||
pickup: Recogida
|
pickup: Recogida
|
||||||
delivery: Entrega
|
delivery: Entrega
|
||||||
|
|
|
@ -45,7 +45,6 @@ describe('OrderCatalog', () => {
|
||||||
).type('{enter}');
|
).type('{enter}');
|
||||||
cy.get(':nth-child(1) > [data-cy="catalogFilterCategory"]').click();
|
cy.get(':nth-child(1) > [data-cy="catalogFilterCategory"]').click();
|
||||||
cy.dataCy('catalogFilterValueDialogBtn').last().click();
|
cy.dataCy('catalogFilterValueDialogBtn').last().click();
|
||||||
cy.get('[data-cy="catalogFilterValueDialogTagSelect"]').click();
|
|
||||||
cy.selectOption("[data-cy='catalogFilterValueDialogTagSelect']", 'Tallos');
|
cy.selectOption("[data-cy='catalogFilterValueDialogTagSelect']", 'Tallos');
|
||||||
cy.dataCy('catalogFilterValueDialogValueInput').find('input').focus();
|
cy.dataCy('catalogFilterValueDialogValueInput').find('input').focus();
|
||||||
cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('2');
|
cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('2');
|
||||||
|
|
|
@ -3,11 +3,46 @@ describe('Client consignee', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
cy.visit('#/customer/1110/address', {
|
cy.visit('#/customer/1107/address');
|
||||||
timeout: 5000,
|
cy.domContentLoad();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
it('Should load layout', () => {
|
it('Should load layout', () => {
|
||||||
cy.get('.q-card').should('be.visible');
|
cy.get('.q-card').should('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('check as equalizated', function () {
|
||||||
|
cy.get('.q-card__section > .address-card').then(($el) => {
|
||||||
|
let addressCards_before = $el.length;
|
||||||
|
|
||||||
|
cy.get('.q-page-sticky > div > .q-btn').click();
|
||||||
|
const addressName = 'test';
|
||||||
|
cy.dataCy('Consignee_input').type(addressName);
|
||||||
|
cy.dataCy('Location_select').click();
|
||||||
|
cy.get('[role="listbox"] .q-item:nth-child(1)').click();
|
||||||
|
cy.dataCy('Street address_input').type('TEST ADDRESS');
|
||||||
|
cy.get('.q-btn-group > .q-btn--standard').click();
|
||||||
|
cy.location('href').should('contain', '#/customer/1107/address');
|
||||||
|
cy.get('.q-card__section > .address-card').should(
|
||||||
|
'have.length',
|
||||||
|
addressCards_before + 1,
|
||||||
|
);
|
||||||
|
cy.get('.q-card__section > .address-card')
|
||||||
|
.eq(addressCards_before)
|
||||||
|
.should('be.visible')
|
||||||
|
.get('.text-weight-bold')
|
||||||
|
.eq(addressCards_before - 1)
|
||||||
|
.should('contain', addressName)
|
||||||
|
.click();
|
||||||
|
});
|
||||||
|
cy.get(
|
||||||
|
'.q-card > :nth-child(1) > :nth-child(2) > .q-checkbox > .q-checkbox__inner',
|
||||||
|
)
|
||||||
|
.should('have.class', 'q-checkbox__inner--falsy')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('.q-btn-group > .q-btn--standard > .q-btn__content').click();
|
||||||
|
cy.get(
|
||||||
|
':nth-child(2) > :nth-child(2) > .flex > .q-mr-lg > .q-checkbox__inner',
|
||||||
|
).should('have.class', 'q-checkbox__inner--truthy');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,9 +3,8 @@ describe('Client fiscal data', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
cy.visit('#/customer/1107/fiscal-data', {
|
cy.visit('#/customer/1107/fiscal-data');
|
||||||
timeout: 5000,
|
cy.domContentLoad();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
it('Should change required value when change customer', () => {
|
it('Should change required value when change customer', () => {
|
||||||
cy.get('.q-card').should('be.visible');
|
cy.get('.q-card').should('be.visible');
|
||||||
|
@ -15,4 +14,25 @@ describe('Client fiscal data', () => {
|
||||||
cy.get('.q-item > .q-item__label').should('have.text', ' #1');
|
cy.get('.q-item > .q-item__label').should('have.text', ' #1');
|
||||||
cy.dataCy('sageTaxTypeFk').filter('input').should('have.attr', 'required');
|
cy.dataCy('sageTaxTypeFk').filter('input').should('have.attr', 'required');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('check as equalizated', () => {
|
||||||
|
cy.get(
|
||||||
|
':nth-child(1) > .q-checkbox > .q-checkbox__inner > .q-checkbox__bg',
|
||||||
|
).click();
|
||||||
|
cy.get('.q-btn-group > .q-btn--standard > .q-btn__content').click();
|
||||||
|
|
||||||
|
cy.get('.q-card > :nth-child(1) > span').should(
|
||||||
|
'contain',
|
||||||
|
'You changed the equalization tax',
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get('.q-card > :nth-child(2) > span').should(
|
||||||
|
'have.text',
|
||||||
|
'Do you want to spread the change?',
|
||||||
|
);
|
||||||
|
cy.get('[data-cy="VnConfirm_confirm"] > .q-btn__content > .block').click();
|
||||||
|
cy.get(
|
||||||
|
'.bg-warning > .q-notification__wrapper > .q-notification__content > .q-notification__message',
|
||||||
|
).should('have.text', 'Equivalent tax spreaded');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -106,8 +106,9 @@ describe('Entry', () => {
|
||||||
cy.get(`td[data-col-field="${field}"][data-row-index="${row}"]`);
|
cy.get(`td[data-col-field="${field}"][data-row-index="${row}"]`);
|
||||||
const selectSpan = (field, row = 0) => selectCell(field, row).find('div > span');
|
const selectSpan = (field, row = 0) => selectCell(field, row).find('div > span');
|
||||||
const selectButton = (cySelector) => cy.get(`button[data-cy="${cySelector}"]`);
|
const selectButton = (cySelector) => cy.get(`button[data-cy="${cySelector}"]`);
|
||||||
const clickAndType = (field, value, row = 0) =>
|
const clickAndType = (field, value, row = 0) => {
|
||||||
selectCell(field, row).click().type(value);
|
selectCell(field, row).click().type(`${value}{esc}`);
|
||||||
|
};
|
||||||
const checkText = (field, expectedText, row = 0) =>
|
const checkText = (field, expectedText, row = 0) =>
|
||||||
selectCell(field, row).should('have.text', expectedText);
|
selectCell(field, row).should('have.text', expectedText);
|
||||||
const checkColor = (field, expectedColor, row = 0) =>
|
const checkColor = (field, expectedColor, row = 0) =>
|
||||||
|
@ -115,21 +116,18 @@ describe('Entry', () => {
|
||||||
|
|
||||||
createEntryAndBuy();
|
createEntryAndBuy();
|
||||||
|
|
||||||
selectCell('isIgnored')
|
selectCell('isIgnored').click().click().type('{esc}');
|
||||||
.click()
|
checkText('isIgnored', 'close');
|
||||||
.click()
|
|
||||||
.trigger('keydown', { key: 'Tab', keyCode: 9, which: 9 });
|
|
||||||
checkText('isIgnored', 'check');
|
|
||||||
checkColor('quantity', COLORS.negative);
|
|
||||||
|
|
||||||
clickAndType('stickers', '1');
|
clickAndType('stickers', '1');
|
||||||
checkText('quantity', '11');
|
checkText('stickers', '0/01');
|
||||||
checkText('amount', '550.00');
|
checkText('quantity', '1');
|
||||||
|
checkText('amount', '50.00');
|
||||||
clickAndType('packing', '2');
|
clickAndType('packing', '2');
|
||||||
checkText('packing', '12close');
|
checkText('packing', '12');
|
||||||
checkText('weight', '12.0');
|
checkText('weight', '12.0');
|
||||||
checkText('quantity', '132');
|
checkText('quantity', '12');
|
||||||
checkText('amount', '6600.00');
|
checkText('amount', '600.00');
|
||||||
checkColor('packing', COLORS.enabled);
|
checkColor('packing', COLORS.enabled);
|
||||||
|
|
||||||
selectCell('groupingMode').click().click().click();
|
selectCell('groupingMode').click().click().click();
|
||||||
|
@ -137,7 +135,7 @@ describe('Entry', () => {
|
||||||
checkColor('grouping', COLORS.enabled);
|
checkColor('grouping', COLORS.enabled);
|
||||||
|
|
||||||
selectCell('buyingValue').click().clear().type('{backspace}{backspace}1');
|
selectCell('buyingValue').click().clear().type('{backspace}{backspace}1');
|
||||||
checkText('amount', '132.00');
|
checkText('amount', '12.00');
|
||||||
checkColor('minPrice', COLORS.disable);
|
checkColor('minPrice', COLORS.disable);
|
||||||
|
|
||||||
selectCell('hasMinPrice').click().click();
|
selectCell('hasMinPrice').click().click();
|
||||||
|
@ -145,7 +143,7 @@ describe('Entry', () => {
|
||||||
selectCell('hasMinPrice').click();
|
selectCell('hasMinPrice').click();
|
||||||
|
|
||||||
cy.saveCard();
|
cy.saveCard();
|
||||||
cy.get('span[data-cy="footer-stickers"]').should('have.text', '11');
|
cy.get('span[data-cy="footer-stickers"]').should('have.text', '1');
|
||||||
cy.get('.q-notification__message').contains('Data saved');
|
cy.get('.q-notification__message').contains('Data saved');
|
||||||
|
|
||||||
selectButton('change-quantity-sign').should('be.disabled');
|
selectButton('change-quantity-sign').should('be.disabled');
|
||||||
|
@ -156,9 +154,9 @@ describe('Entry', () => {
|
||||||
|
|
||||||
selectButton('change-quantity-sign').click();
|
selectButton('change-quantity-sign').click();
|
||||||
selectButton('set-negative-quantity').click();
|
selectButton('set-negative-quantity').click();
|
||||||
checkText('quantity', '-132');
|
checkText('quantity', '-12');
|
||||||
selectButton('set-positive-quantity').click();
|
selectButton('set-positive-quantity').click();
|
||||||
checkText('quantity', '132');
|
checkText('quantity', '12');
|
||||||
checkColor('amount', COLORS.disable);
|
checkColor('amount', COLORS.disable);
|
||||||
|
|
||||||
selectButton('check-buy-amount').click();
|
selectButton('check-buy-amount').click();
|
||||||
|
|
|
@ -10,9 +10,7 @@ describe('EntryMy when is supplier', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should open buyLabel when is supplier', () => {
|
it('should open buyLabel when is supplier', () => {
|
||||||
cy.get(
|
cy.dataCy('cardBtn').eq(2).click();
|
||||||
'[to="/null/3"] > .q-card > :nth-child(2) > .q-btn > .q-btn__content > .q-icon'
|
|
||||||
).click();
|
|
||||||
cy.dataCy('printLabelsBtn').click();
|
cy.dataCy('printLabelsBtn').click();
|
||||||
cy.window().its('open').should('be.called');
|
cy.window().its('open').should('be.called');
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe('EntryStockBought', () => {
|
||||||
});
|
});
|
||||||
it('Should edit the reserved space', () => {
|
it('Should edit the reserved space', () => {
|
||||||
cy.get('.q-field__native.q-placeholder').should('have.value', '01/01/2001');
|
cy.get('.q-field__native.q-placeholder').should('have.value', '01/01/2001');
|
||||||
cy.get('td[data-col-field="reserve"]').click();
|
cy.get('[data-col-field="reserve"][data-row-index="0"]').click();
|
||||||
cy.get('input[name="reserve"]').type('10{enter}');
|
cy.get('input[name="reserve"]').type('10{enter}');
|
||||||
cy.get('button[title="Save"]').click();
|
cy.get('button[title="Save"]').click();
|
||||||
cy.get('.q-notification__message').should('have.text', 'Data saved');
|
cy.get('.q-notification__message').should('have.text', 'Data saved');
|
||||||
|
@ -16,25 +16,35 @@ describe('EntryStockBought', () => {
|
||||||
cy.get('input[aria-label="Reserve"]').type('1');
|
cy.get('input[aria-label="Reserve"]').type('1');
|
||||||
cy.get('input[aria-label="Date"]').eq(1).clear();
|
cy.get('input[aria-label="Date"]').eq(1).clear();
|
||||||
cy.get('input[aria-label="Date"]').eq(1).type('01-01');
|
cy.get('input[aria-label="Date"]').eq(1).type('01-01');
|
||||||
cy.get('input[aria-label="Buyer"]').type('buyerboss{downarrow}{enter}');
|
cy.get('input[aria-label="Buyer"]').type('buyerBossNick');
|
||||||
|
cy.get('div[role="listbox"] > div > div[role="option"]')
|
||||||
|
.eq(0)
|
||||||
|
.should('be.visible')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-cy="FormModelPopup_save"]').click();
|
||||||
cy.get('.q-notification__message').should('have.text', 'Data created');
|
cy.get('.q-notification__message').should('have.text', 'Data created');
|
||||||
|
|
||||||
|
cy.get('[data-col-field="reserve"][data-row-index="1"]').click().clear();
|
||||||
|
cy.get('[data-cy="searchBtn"]').eq(1).click();
|
||||||
|
cy.get('.q-table__bottom.row.items-center.q-table__bottom--nodata')
|
||||||
|
.should('have.text', 'warningNo data available')
|
||||||
|
.type('{esc}');
|
||||||
|
cy.get('[data-col-field="reserve"][data-row-index="1"]')
|
||||||
|
.click()
|
||||||
|
.type('{backspace}{enter}');
|
||||||
|
cy.get('[data-cy="crudModelDefaultSaveBtn"]').should('be.enabled').click();
|
||||||
|
cy.get('.q-notification__message').eq(1).should('have.text', 'Data saved');
|
||||||
});
|
});
|
||||||
it('Should check detail for the buyer', () => {
|
it('Should check detail for the buyer', () => {
|
||||||
cy.get(':nth-child(1) > .sticky > .q-btn > .q-btn__content > .q-icon').click();
|
cy.get('[data-cy="searchBtn"]').eq(0).click();
|
||||||
cy.get('tBody > tr').eq(1).its('length').should('eq', 1);
|
cy.get('tBody > tr').eq(1).its('length').should('eq', 1);
|
||||||
});
|
});
|
||||||
it('Should check detail for the buyerBoss and had no content', () => {
|
|
||||||
cy.get(':nth-child(2) > .sticky > .q-btn > .q-btn__content > .q-icon').click();
|
|
||||||
cy.get('.q-table__bottom.row.items-center.q-table__bottom--nodata').should(
|
|
||||||
'have.text',
|
|
||||||
'warningNo data available',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('Should edit travel m3 and refresh', () => {
|
it('Should edit travel m3 and refresh', () => {
|
||||||
cy.get('.vn-row > div > .q-btn > .q-btn__content > .q-icon').click();
|
cy.get('[data-cy="edit-travel"]').should('be.visible').click();
|
||||||
cy.get('input[aria-label="m3"]').clear();
|
cy.get('input[aria-label="m3"]').clear().type('60');
|
||||||
cy.get('input[aria-label="m3"]').type('60');
|
cy.get('[data-cy="FormModelPopup_save"]').click();
|
||||||
cy.get('.q-mt-lg > .q-btn--standard > .q-btn__content > .block').click();
|
|
||||||
cy.get('.vn-row > div > :nth-child(2)').should('have.text', '60');
|
cy.get('.vn-row > div > :nth-child(2)').should('have.text', '60');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,7 +36,7 @@ describe('InvoiceInVat', () => {
|
||||||
cy.get(dialogInputs).eq(0).type(randomInt);
|
cy.get(dialogInputs).eq(0).type(randomInt);
|
||||||
cy.get(dialogInputs).eq(1).type('This is a dummy expense');
|
cy.get(dialogInputs).eq(1).type('This is a dummy expense');
|
||||||
|
|
||||||
cy.get('button[type="submit"]').click();
|
cy.get('[data-cy="FormModelPopup_save"]').click();
|
||||||
cy.get('.q-notification__message').should('have.text', 'Data created');
|
cy.get('.q-notification__message').should('have.text', 'Data created');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
describe('TicketSale', () => {
|
describe('TicketSale', () => {
|
||||||
|
describe('Free ticket #31', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
cy.viewport(1920, 1080);
|
cy.viewport(1920, 1080);
|
||||||
|
@ -120,3 +121,88 @@ describe('TicketSale', () => {
|
||||||
cy.url().should('match', /\/ticket\/31\/log/);
|
cy.url().should('match', /\/ticket\/31\/log/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('Ticket prepared #23', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.login('developer');
|
||||||
|
cy.viewport(1920, 1080);
|
||||||
|
cy.visit('/#/ticket/23/sale');
|
||||||
|
});
|
||||||
|
|
||||||
|
const firstRow = 'tbody > :nth-child(1)';
|
||||||
|
|
||||||
|
const selectFirstRow = () => {
|
||||||
|
cy.waitForElement(firstRow);
|
||||||
|
cy.get(firstRow).find('.q-checkbox__inner').click();
|
||||||
|
};
|
||||||
|
|
||||||
|
it('update price', () => {
|
||||||
|
const price = Number((Math.random() * 99 + 1).toFixed(2));
|
||||||
|
cy.waitForElement(firstRow);
|
||||||
|
cy.get(':nth-child(10) > .q-btn').click();
|
||||||
|
cy.waitForElement('[data-cy="ticketEditManaProxy"]');
|
||||||
|
cy.dataCy('ticketEditManaProxy').should('exist');
|
||||||
|
cy.waitForElement('[data-cy="Price_input"]');
|
||||||
|
cy.dataCy('Price_input').clear();
|
||||||
|
cy.dataCy('Price_input').type(price);
|
||||||
|
cy.dataCy('saveManaBtn').click();
|
||||||
|
handleVnConfirm();
|
||||||
|
|
||||||
|
cy.get(':nth-child(10) > .q-btn > .q-btn__content').should(
|
||||||
|
'have.text',
|
||||||
|
`€${price}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('update dicount', () => {
|
||||||
|
const discount = Math.floor(Math.random() * 100) + 1;
|
||||||
|
selectFirstRow();
|
||||||
|
cy.get(':nth-child(11) > .q-btn').click();
|
||||||
|
cy.waitForElement('[data-cy="ticketEditManaProxy"]');
|
||||||
|
cy.dataCy('ticketEditManaProxy').should('exist');
|
||||||
|
cy.waitForElement('[data-cy="Disc_input"]');
|
||||||
|
cy.dataCy('Disc_input').clear();
|
||||||
|
cy.dataCy('Disc_input').type(discount);
|
||||||
|
cy.dataCy('saveManaBtn').click();
|
||||||
|
handleVnConfirm();
|
||||||
|
|
||||||
|
cy.get(':nth-child(11) > .q-btn > .q-btn__content').should(
|
||||||
|
'have.text',
|
||||||
|
`${discount}.00%`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('change concept', () => {
|
||||||
|
const quantity = Math.floor(Math.random() * 100) + 1;
|
||||||
|
cy.waitForElement(firstRow);
|
||||||
|
cy.get(':nth-child(8) > .row').click();
|
||||||
|
cy.get(
|
||||||
|
'.q-menu > [data-v-ca3f07a4=""] > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > [data-cy="undefined_input"]',
|
||||||
|
)
|
||||||
|
.type(quantity)
|
||||||
|
.type('{enter}');
|
||||||
|
handleVnConfirm();
|
||||||
|
|
||||||
|
cy.get(':nth-child(8) >.row').should('contain.text', `${quantity}`);
|
||||||
|
});
|
||||||
|
it('changequantity ', () => {
|
||||||
|
const quantity = Math.floor(Math.random() * 100) + 1;
|
||||||
|
cy.waitForElement(firstRow);
|
||||||
|
cy.dataCy('ticketSaleQuantityInput').clear();
|
||||||
|
cy.dataCy('ticketSaleQuantityInput').type(quantity).trigger('tab');
|
||||||
|
cy.get('.q-page > :nth-child(6)').click();
|
||||||
|
|
||||||
|
handleVnConfirm();
|
||||||
|
|
||||||
|
cy.get('[data-cy="ticketSaleQuantityInput"]')
|
||||||
|
.find('[data-cy="undefined_input"]')
|
||||||
|
.should('have.value', `${quantity}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleVnConfirm() {
|
||||||
|
cy.get('[data-cy="VnConfirm_confirm"] > .q-btn__content > .block').click();
|
||||||
|
cy.waitForElement('.q-notification__message');
|
||||||
|
|
||||||
|
cy.get('.q-notification__message').should('be.visible');
|
||||||
|
cy.checkNotification('Data saved');
|
||||||
|
}
|
||||||
|
|
|
@ -2,9 +2,24 @@ describe('WorkerCreate', () => {
|
||||||
const externalRadio = '.q-radio:nth-child(2)';
|
const externalRadio = '.q-radio:nth-child(2)';
|
||||||
const developerBossId = 120;
|
const developerBossId = 120;
|
||||||
const payMethodCross =
|
const payMethodCross =
|
||||||
'.grid-create .full-width > :nth-child(9) .q-select .q-field__append:not(.q-anchor--skip)';
|
':nth-child(9) > .q-select > .q-field__inner > .q-field__control > :nth-child(2)';
|
||||||
const saveBtn = '.q-mt-lg > .q-btn--standard';
|
const saveBtn = '.q-mt-lg > .q-btn--standard';
|
||||||
|
|
||||||
|
const internalWithOutPay = {
|
||||||
|
Fi: { val: '78457139E' },
|
||||||
|
'Web user': { val: 'manolo' },
|
||||||
|
Name: { val: 'Manolo' },
|
||||||
|
'Last name': { val: 'Hurtado' },
|
||||||
|
'Personal email': { val: 'manolo@mydomain.com' },
|
||||||
|
Company: { val: 'VNL', type: 'select' },
|
||||||
|
Street: { val: 'S/ DEFAULTWORKERSTREET' },
|
||||||
|
Location: { val: 1, type: 'select' },
|
||||||
|
Phone: { val: '123456789' },
|
||||||
|
'Worker code': { val: 'DWW' },
|
||||||
|
Boss: { val: developerBossId, type: 'select' },
|
||||||
|
Birth: { val: '11-12-2022', type: 'date' },
|
||||||
|
};
|
||||||
|
|
||||||
const internal = {
|
const internal = {
|
||||||
Fi: { val: '78457139E' },
|
Fi: { val: '78457139E' },
|
||||||
'Web user': { val: 'manolo' },
|
'Web user': { val: 'manolo' },
|
||||||
|
@ -14,6 +29,7 @@ describe('WorkerCreate', () => {
|
||||||
Company: { val: 'VNL', type: 'select' },
|
Company: { val: 'VNL', type: 'select' },
|
||||||
Street: { val: 'S/ DEFAULTWORKERSTREET' },
|
Street: { val: 'S/ DEFAULTWORKERSTREET' },
|
||||||
Location: { val: 1, type: 'select' },
|
Location: { val: 1, type: 'select' },
|
||||||
|
'Pay method': { val: 1, type: 'select' },
|
||||||
Phone: { val: '123456789' },
|
Phone: { val: '123456789' },
|
||||||
'Worker code': { val: 'DWW' },
|
'Worker code': { val: 'DWW' },
|
||||||
Boss: { val: developerBossId, type: 'select' },
|
Boss: { val: developerBossId, type: 'select' },
|
||||||
|
@ -37,17 +53,14 @@ describe('WorkerCreate', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if a pay method has not been selected', () => {
|
it('should throw an error if a pay method has not been selected', () => {
|
||||||
cy.fillInForm(internal);
|
cy.fillInForm(internalWithOutPay);
|
||||||
cy.get(payMethodCross).click();
|
cy.get(payMethodCross).click();
|
||||||
cy.get(saveBtn).click();
|
cy.get(saveBtn).click();
|
||||||
cy.checkNotification('Payment method is required');
|
cy.checkNotification('Payment method is required');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create an internal', () => {
|
it('should create an internal', () => {
|
||||||
cy.fillInForm({
|
cy.fillInForm(internal);
|
||||||
...internal,
|
|
||||||
'Pay method': { val: 'PayMethod one', type: 'select' },
|
|
||||||
});
|
|
||||||
cy.get(saveBtn).click();
|
cy.get(saveBtn).click();
|
||||||
cy.checkNotification('Data created');
|
cy.checkNotification('Data created');
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe('WorkerNotificationsManager', () => {
|
||||||
cy.visit(`/#/worker/${salesPersonId}/notifications`);
|
cy.visit(`/#/worker/${salesPersonId}/notifications`);
|
||||||
cy.get(firstAvailableNotification).click();
|
cy.get(firstAvailableNotification).click();
|
||||||
cy.checkNotification(
|
cy.checkNotification(
|
||||||
'The notification subscription of this worker cant be modified'
|
'The notification subscription of this worker cant be modified',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ describe('WorkerPit', () => {
|
||||||
const spousePensionInput = '[data-cy="Spouse Pension_input"]';
|
const spousePensionInput = '[data-cy="Spouse Pension_input"]';
|
||||||
const spousePension = '120';
|
const spousePension = '120';
|
||||||
const addRelative = '[data-cy="addRelative"]';
|
const addRelative = '[data-cy="addRelative"]';
|
||||||
const isDescendantSelect = '[data-cy="Descendant/Ascendant_select"]';
|
const isDescendantSelect = '[data-cy="Descendant/Ascendant"]';
|
||||||
|
const Descendant = 'Descendiente';
|
||||||
const birthedInput = '[data-cy="Birth Year_input"]';
|
const birthedInput = '[data-cy="Birth Year_input"]';
|
||||||
const birthed = '2002';
|
const birthed = '2002';
|
||||||
const adoptionYearInput = '[data-cy="Adoption Year_input"]';
|
const adoptionYearInput = '[data-cy="Adoption Year_input"]';
|
||||||
|
@ -28,11 +29,8 @@ describe('WorkerPit', () => {
|
||||||
cy.get(spouseNifInput).type(spouseNif);
|
cy.get(spouseNifInput).type(spouseNif);
|
||||||
cy.get(spousePensionInput).type(spousePension);
|
cy.get(spousePensionInput).type(spousePension);
|
||||||
cy.get(savePIT).click();
|
cy.get(savePIT).click();
|
||||||
});
|
|
||||||
|
|
||||||
it('complete relative', () => {
|
|
||||||
cy.get(addRelative).click();
|
cy.get(addRelative).click();
|
||||||
cy.get(isDescendantSelect).type('{downArrow}{downArrow}{enter}');
|
cy.get(isDescendantSelect).type(Descendant);
|
||||||
cy.get(birthedInput).type(birthed);
|
cy.get(birthedInput).type(birthed);
|
||||||
cy.get(adoptionYearInput).type(adoptionYear);
|
cy.get(adoptionYearInput).type(adoptionYear);
|
||||||
cy.get(saveRelative).click();
|
cy.get(saveRelative).click();
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
describe('ZoneList', () => {
|
describe('ZoneList', () => {
|
||||||
|
const agency = 'inhouse pickup';
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
|
@ -6,11 +7,15 @@ describe('ZoneList', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should filter by agency', () => {
|
it('should filter by agency', () => {
|
||||||
cy.get('input[aria-label="Agency"]').type('{downArrow}{enter}');
|
cy.dataCy('zoneFilterPanelNameInput').type('{downArrow}{enter}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should open the zone summary', () => {
|
it('should open the zone summary', () => {
|
||||||
cy.get('input[aria-label="Name"]').type('zone refund');
|
cy.dataCy('zoneFilterPanelAgencySelect').type(agency);
|
||||||
cy.get('.q-scrollarea__content > .q-btn--standard > .q-btn__content').click();
|
cy.get('.q-menu .q-item').contains(agency).click();
|
||||||
|
cy.get(':nth-child(1) > [data-col-field="agencyModeFk"]').should(
|
||||||
|
'include.text',
|
||||||
|
agency,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue