384 lines
11 KiB
JavaScript
384 lines
11 KiB
JavaScript
import ngModule from '../module';
|
|
import './style.scss';
|
|
|
|
class Controller {
|
|
constructor($scope, $state, $http, vnApp, $translate) {
|
|
this.$scope = $scope;
|
|
this.vnApp = vnApp;
|
|
this.$translate = $translate;
|
|
this.$state = $state;
|
|
this.$stateParams = $state.params;
|
|
this.$http = $http;
|
|
this.deletable = false;
|
|
this.edit = {};
|
|
this.moreOptions = [
|
|
{callback: this.markAsReserved, name: 'Mark as reserved'},
|
|
{callback: this.unmarkAsReserved, name: 'Unmark as reserved'},
|
|
{callback: this.showEditDialog, name: 'Update discount', show: () => !this.hasInvoice()},
|
|
{callback: this.createClaim, name: 'Add claim'},
|
|
{callback: this.showSMSDialog, name: 'Send SMS'}
|
|
];
|
|
|
|
this.imagesPath = '//verdnatura.es/vn-image-data/catalog';
|
|
}
|
|
|
|
set sales(value) {
|
|
this._sales = value;
|
|
this.refreshTotal();
|
|
}
|
|
|
|
get sales() {
|
|
return this._sales;
|
|
}
|
|
|
|
refreshTotal() {
|
|
this.loadSubTotal();
|
|
this.loadVAT();
|
|
}
|
|
|
|
loadSubTotal() {
|
|
if (!this.$stateParams.id || !this.sales) return;
|
|
this.$http.get(`/api/Tickets/${this.$stateParams.id}/subtotal`).then(res => {
|
|
this.subtotal = res.data || 0.0;
|
|
});
|
|
}
|
|
|
|
getSaleTotal(sale) {
|
|
return sale.quantity * sale.price * ((100 - sale.discount) / 100);
|
|
}
|
|
|
|
loadVAT() {
|
|
this.VAT = 0.0;
|
|
if (!this.$stateParams.id || !this.sales) return;
|
|
this.$http.get(`/api/Tickets/${this.$stateParams.id}/getVAT`).then(res => {
|
|
this.VAT = res.data || 0.0;
|
|
});
|
|
}
|
|
|
|
get total() {
|
|
return this.subtotal + this.VAT;
|
|
}
|
|
|
|
onMoreOpen() {
|
|
let options = this.moreOptions.filter(option => {
|
|
const hasShowProperty = Object.hasOwnProperty.call(option, 'show');
|
|
const shouldShow = !hasShowProperty || option.show === true ||
|
|
typeof option.show === 'function' && option.show();
|
|
|
|
return (shouldShow && (option.always || this.isChecked));
|
|
});
|
|
this.$scope.moreButton.data = options;
|
|
}
|
|
|
|
onMoreChange(callback) {
|
|
callback.call(this);
|
|
}
|
|
|
|
get isEditable() {
|
|
try {
|
|
return !this.ticket.state.state.alertLevel;
|
|
} catch (e) {}
|
|
|
|
return true;
|
|
}
|
|
|
|
get isChecked() {
|
|
if (this.sales) {
|
|
for (let instance of this.sales)
|
|
if (instance.checked) return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
getCheckedLines() {
|
|
let lines = [];
|
|
let data = this.sales;
|
|
if (data) {
|
|
for (let i = 0; i < data.length; i++) {
|
|
if (data[i].checked)
|
|
lines.push({id: data[i].id, instance: i});
|
|
}
|
|
}
|
|
return lines;
|
|
}
|
|
|
|
onStateOkClick() {
|
|
let filter = {where: {code: 'OK'}, fields: ['id']};
|
|
let json = encodeURIComponent(JSON.stringify(filter));
|
|
this.$http.get(`/api/States?filter=${json}`).then(res => {
|
|
this.onStateChange(res.data[0].id);
|
|
});
|
|
}
|
|
|
|
onStateChange(value) {
|
|
let params = {ticketFk: this.$state.params.id, stateFk: value};
|
|
this.$http.post(`/api/TicketTrackings/changeState`, params).then(() => {
|
|
this.card.reload();
|
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
|
});
|
|
}
|
|
|
|
onRemoveLinesClick(response) {
|
|
if (response === 'ACCEPT') {
|
|
let sales = this.getCheckedLines();
|
|
let params = {sales: sales, actualTicketFk: this.ticket.id};
|
|
let query = `/api/Sales/removes`;
|
|
this.$http.post(query, params).then(() => {
|
|
this.removeInstances(sales);
|
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
|
});
|
|
}
|
|
}
|
|
|
|
removeInstances(instances) {
|
|
for (let i of instances)
|
|
this.sales.splice(i.instance, 1);
|
|
this.refreshTotal();
|
|
}
|
|
|
|
showRemoveLinesDialog() {
|
|
this.$scope.deleteLines.show();
|
|
}
|
|
|
|
showTransferPopover(event) {
|
|
let filter = {clientFk: this.ticket.clientFk, ticketFk: this.ticket.id};
|
|
let json = encodeURIComponent(JSON.stringify(filter));
|
|
let query = `/api/Tickets/threeLastActive?filter=${json}`;
|
|
this.$http.get(query).then(res => {
|
|
this.lastThreeTickets = res.data;
|
|
});
|
|
this.$scope.transfer.parent = event.target;
|
|
this.$scope.transfer.show();
|
|
}
|
|
|
|
|
|
checkEmptiness(receiverTicketId) {
|
|
let sales = this.getCheckedLines();
|
|
let areAllSalesSelected = sales.length === this.$scope.model.data.length;
|
|
this.receiverTicketId = receiverTicketId;
|
|
|
|
|
|
if (areAllSalesSelected) {
|
|
let query = `/api/Tickets/${this.ticket.id}/checkEmptiness`;
|
|
this.$http.get(query).then(res => {
|
|
if (res.data)
|
|
this.$scope.deleteTicket.show();
|
|
if (!res.data)
|
|
this.moveLines(false);
|
|
});
|
|
}
|
|
|
|
if (!areAllSalesSelected)
|
|
this.moveLines(false);
|
|
}
|
|
|
|
moveLines(removeEmptyTicket) {
|
|
let sales = this.getCheckedLines();
|
|
|
|
let currentTicketData = {
|
|
currentTicketId: this.ticket.id,
|
|
clientFk: this.ticket.clientFk,
|
|
addressFk: this.ticket.addressFk,
|
|
agencyModeFk: this.ticket.agencyModeFk,
|
|
warehouseFk: this.ticket.warehouseFk
|
|
};
|
|
|
|
let params = {
|
|
currentTicket: currentTicketData,
|
|
receiverTicket: this.receiverTicketId ? {id: this.receiverTicketId} : currentTicketData,
|
|
sales: sales,
|
|
removeEmptyTicket: removeEmptyTicket
|
|
};
|
|
|
|
this.$http.post(`/api/Sales/moveToTicket`, params).then(res => {
|
|
if (res.data) {
|
|
this.receiverTicketId = null;
|
|
this.goToTicket(res.data.id);
|
|
}
|
|
});
|
|
}
|
|
|
|
createClaim() {
|
|
let claim = {
|
|
ticketFk: this.ticket.id,
|
|
clientFk: this.ticket.clientFk,
|
|
ticketCreated: this.ticket.shipped
|
|
};
|
|
let sales = this.getCheckedLines();
|
|
for (let i = 0; i < sales.length; i++)
|
|
sales[i].quantity = this.sales[sales[i].instance].quantity;
|
|
this.$http.post(`/api/Claims/createFromSales`, {claim: claim, sales: sales}).then(res => {
|
|
this.$state.go('claim.card.basicData', {id: res.data.id});
|
|
});
|
|
}
|
|
|
|
goToTicket(ticketID) {
|
|
this.$state.go('ticket.card.sale', {id: ticketID});
|
|
}
|
|
|
|
// Slesperson Mana
|
|
getManaSalespersonMana() {
|
|
this.$http.get(`/api/Tickets/${this.$state.params.id}/getSalesPersonMana`).then(res => {
|
|
this.mana = res.data;
|
|
});
|
|
}
|
|
|
|
// Item Descriptor
|
|
showDescriptor(event, itemFk) {
|
|
this.quicklinks = {
|
|
btnThree: {
|
|
icon: 'icon-transaction',
|
|
state: `item.card.diary({
|
|
id: ${itemFk},
|
|
warehouseFk: ${this.ticket.warehouseFk},
|
|
ticketFk: ${this.ticket.id}
|
|
})`,
|
|
tooltip: 'Item diary'
|
|
}
|
|
};
|
|
this.$scope.descriptor.itemFk = itemFk;
|
|
this.$scope.descriptor.parent = event.target;
|
|
this.$scope.descriptor.show();
|
|
}
|
|
|
|
onDescriptorLoad() {
|
|
this.$scope.popover.relocate();
|
|
}
|
|
|
|
showEditPricePopover(event, sale) {
|
|
this.sale = sale;
|
|
this.editedPrice = this.sale.price;
|
|
this.edit = {
|
|
ticketFk: this.ticket.id,
|
|
id: sale.id,
|
|
quantity: sale.quantity
|
|
};
|
|
this.$scope.editPricePopover.parent = event.target;
|
|
this.$scope.editPricePopover.show();
|
|
}
|
|
|
|
updatePrice() {
|
|
if (this.editedPrice != this.sale.price) {
|
|
this.$http.post(`/api/Sales/${this.edit.id}/updatePrice`, {newPrice: this.editedPrice}).then(() => {
|
|
this.sale.price = this.edit.price;
|
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
|
this.$scope.model.refresh();
|
|
});
|
|
}
|
|
|
|
this.$scope.editPricePopover.hide();
|
|
}
|
|
|
|
showEditPopover(event, sale) {
|
|
this.sale = sale;
|
|
this.edit = [{
|
|
ticketFk: this.ticket.id,
|
|
id: sale.id,
|
|
quantity: sale.quantity,
|
|
price: sale.price,
|
|
discount: sale.discount
|
|
}];
|
|
this.$scope.editPopover.parent = event.target;
|
|
this.$scope.editPopover.show();
|
|
}
|
|
|
|
showEditDialog() {
|
|
this.edit = this.getCheckedLines();
|
|
this.$scope.editDialog.show();
|
|
}
|
|
|
|
hideEditDialog() {
|
|
this.$scope.model.refresh();
|
|
this.$scope.editDialog.hide();
|
|
}
|
|
|
|
hideEditPopover() {
|
|
this.$scope.model.refresh();
|
|
this.$scope.editPopover.hide();
|
|
}
|
|
|
|
updateQuantity(id, quantity) {
|
|
this.$http.post(`/api/Sales/${id}/updateQuantity`, {quantity: parseInt(quantity)}).then(() => {
|
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
|
}).catch(e => {
|
|
this.vnApp.showError(e.data.error.message);
|
|
}).finally(() => {
|
|
this.$scope.model.refresh();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Unmark sale as reserved
|
|
*/
|
|
unmarkAsReserved() {
|
|
this.setReserved(false);
|
|
}
|
|
|
|
/**
|
|
* Mark sale as reserved
|
|
*/
|
|
markAsReserved() {
|
|
this.setReserved(true);
|
|
}
|
|
|
|
setReserved(reserved) {
|
|
let sales = this.getCheckedLines();
|
|
let params = {sales: sales, ticketFk: this.ticket.id, reserved: reserved};
|
|
|
|
this.$http.post(`/api/Sales/reserve`, params).then(() => {
|
|
this.$scope.model.refresh();
|
|
});
|
|
}
|
|
|
|
newOrderFromTicket() {
|
|
this.$http.post(`/api/Orders/newFromTicket`, {ticketFk: this.ticket.id}).then(res => {
|
|
this.$state.go('order.card.catalog', {id: res.data});
|
|
this.vnApp.showSuccess(this.$translate.instant('Order created'));
|
|
});
|
|
}
|
|
|
|
showSMSDialog() {
|
|
const address = this.ticket.address;
|
|
const lines = this.getCheckedLines();
|
|
const items = lines.map(line => {
|
|
const instance = this.sales[line.instance];
|
|
return `${instance.quantity} ${instance.concept}`;
|
|
});
|
|
const notAvailables = items.join(', ');
|
|
const params = {
|
|
ticketFk: this.ticket.id,
|
|
created: this.ticket.created,
|
|
notAvailables
|
|
};
|
|
this.newSMS = {
|
|
destinationFk: this.ticket.clientFk,
|
|
destination: address.mobile || null,
|
|
message: this.$translate.instant('SMSAvailability', params)
|
|
};
|
|
this.$scope.sms.open();
|
|
}
|
|
|
|
/**
|
|
* Returns if the current ticket
|
|
* is already invoiced
|
|
* @return {Boolean} - True if invoiced
|
|
*/
|
|
hasInvoice() {
|
|
return this.ticket.refFk !== null;
|
|
}
|
|
}
|
|
|
|
Controller.$inject = ['$scope', '$state', '$http', 'vnApp', '$translate'];
|
|
|
|
ngModule.component('vnTicketSale', {
|
|
template: require('./index.html'),
|
|
controller: Controller,
|
|
bindings: {
|
|
ticket: '<'
|
|
},
|
|
require: {
|
|
card: '?^vnTicketCard'
|
|
}
|
|
});
|