mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 18:54:58 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1143 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			1143 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <!--
 | |
|   - EditTransaction.vue
 | |
|   - Copyright (c) 2019 james@firefly-iii.org
 | |
|   -
 | |
|   - This file is part of Firefly III (https://github.com/firefly-iii).
 | |
|   -
 | |
|   - This program is free software: you can redistribute it and/or modify
 | |
|   - it under the terms of the GNU Affero General Public License as
 | |
|   - published by the Free Software Foundation, either version 3 of the
 | |
|   - License, or (at your option) any later version.
 | |
|   -
 | |
|   - This program is distributed in the hope that it will be useful,
 | |
|   - but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|   - GNU Affero General Public License for more details.
 | |
|   -
 | |
|   - You should have received a copy of the GNU Affero General Public License
 | |
|   - along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | |
|   -->
 | |
| 
 | |
| <template>
 | |
|     <form id="store" accept-charset="UTF-8" action="#" class="form-horizontal" enctype="multipart/form-data"
 | |
|           method="POST">
 | |
|         <input name="_token" type="hidden" value="xxx">
 | |
|         <div v-if="error_message !== ''" class="row">
 | |
|             <div class="col-lg-12">
 | |
|                 <div class="alert alert-danger alert-dismissible" role="alert">
 | |
|                     <button class="close" data-dismiss="alert" type="button"
 | |
|                             v-bind:aria-label="$t('firefly.close')"><span
 | |
|                         aria-hidden="true">×</span></button>
 | |
|                     <strong>{{ $t("firefly.flash_error") }}</strong> {{ error_message }}
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
| 
 | |
|         <div v-if="isReconciled" class="row">
 | |
|             <div class="col-lg-12">
 | |
|                 <div class="alert alert-warning" role="alert">
 | |
|                     <strong>{{ $t("firefly.flash_warning") }}</strong> {{ $t('firefly.is_reconciled_fields_dropped') }}
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
| 
 | |
|         <div v-if="success_message !== ''" class="row">
 | |
|             <div class="col-lg-12">
 | |
|                 <div class="alert alert-success alert-dismissible" role="alert">
 | |
|                     <button class="close" data-dismiss="alert" type="button"
 | |
|                             v-bind:aria-label="$t('firefly.close')"><span
 | |
|                         aria-hidden="true">×</span></button>
 | |
|                     <strong>{{ $t("firefly.flash_success") }}</strong> <span v-html="success_message"></span>
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
|         <div>
 | |
|             <div v-for="(transaction, index) in transactions" class="row">
 | |
|                 <div class="col-lg-12">
 | |
|                     <div class="box">
 | |
|                         <div class="box-header with-border">
 | |
|                             <h3 class="box-title splitTitle">
 | |
|                 <span v-if="transactions.length > 1">{{ $t('firefly.single_split') }} {{ index + 1 }} / {{
 | |
|                         transactions.length
 | |
|                     }}</span>
 | |
|                                 <span v-if="transactions.length === 1">{{
 | |
|                                         $t('firefly.transaction_journal_information')
 | |
|                                     }}</span>
 | |
|                             </h3>
 | |
|                             <div v-if="transactions.length > 1" class="box-tools pull-right">
 | |
|                                 <button class="btn btn-xs btn-danger" type="button"
 | |
|                                         v-on:click="deleteTransaction(index, $event)"><i
 | |
|                                     class="fa fa-trash"></i></button>
 | |
|                             </div>
 | |
|                         </div>
 | |
|                         <div class="box-body">
 | |
|                             <div class="row">
 | |
|                                 <div class="col-lg-4">
 | |
|                                     <transaction-description v-if="transactionType.toLowerCase() !== 'reconciliation'"
 | |
|                                                              v-model="transaction.description"
 | |
|                                                              :error="transaction.errors.description"
 | |
|                                                              :index="index"
 | |
|                                     >
 | |
|                                     </transaction-description>
 | |
|                                     <account-select v-if="transactionType.toLowerCase() !== 'reconciliation'"
 | |
|                                                     :accountName="transaction.source_account.name"
 | |
|                                                     :accountTypeFilters="transaction.source_account.allowed_types"
 | |
|                                                     :error="transaction.errors.source_account"
 | |
|                                                     :index="index"
 | |
|                                                     :transactionType="transactionType"
 | |
|                                                     inputName="source[]"
 | |
|                                                     v-bind:inputDescription="$t('firefly.source_account')"
 | |
|                                                     v-on:clear:value="clearSource(index)"
 | |
|                                                     v-on:select:account="selectedSourceAccount(index, $event)"
 | |
|                                     ></account-select>
 | |
|                                     <div v-if="transactionType.toLowerCase() === 'reconciliation'" class="form-group">
 | |
|                                         <div class="col-sm-12">
 | |
|                                             <p id="ffInput_source" class="form-control-static">
 | |
|                                                 <em>
 | |
|                                                     {{ $t('firefly.source_account_reconciliation') }}
 | |
|                                                 </em>
 | |
|                                             </p>
 | |
|                                         </div>
 | |
|                                     </div>
 | |
|                                     <account-select v-if="transactionType.toLowerCase() !== 'reconciliation'"
 | |
|                                                     :accountName="transaction.destination_account.name"
 | |
|                                                     :accountTypeFilters="transaction.destination_account.allowed_types"
 | |
|                                                     :error="transaction.errors.destination_account"
 | |
|                                                     :index="index"
 | |
|                                                     :transactionType="transactionType"
 | |
|                                                     inputName="destination[]"
 | |
|                                                     v-bind:inputDescription="$t('firefly.destination_account')"
 | |
|                                                     v-on:clear:value="clearDestination(index)"
 | |
|                                                     v-on:select:account="selectedDestinationAccount(index, $event)"
 | |
|                                     ></account-select>
 | |
|                                     <div v-if="transactionType.toLowerCase() === 'reconciliation'" class="form-group">
 | |
|                                         <div class="col-sm-12">
 | |
|                                             <p id="ffInput_dest" class="form-control-static">
 | |
|                                                 <em>
 | |
|                                                     {{ $t('firefly.destination_account_reconciliation') }}
 | |
|                                                 </em>
 | |
|                                             </p>
 | |
|                                         </div>
 | |
|                                     </div>
 | |
|                                     <standard-date
 | |
|                                         v-model="transaction.date"
 | |
|                                         :error="transaction.errors.date"
 | |
|                                         :index="index"
 | |
|                                     >
 | |
|                                     </standard-date>
 | |
|                                     <div v-if="index===0">
 | |
|                                         <transaction-type
 | |
|                                             :destination="transaction.destination_account.type"
 | |
|                                             :source="transaction.source_account.type"
 | |
|                                             v-on:set:transactionType="setTransactionType($event)"
 | |
|                                             v-on:act:limitSourceType="limitSourceType($event)"
 | |
|                                             v-on:act:limitDestinationType="limitDestinationType($event)"
 | |
|                                         ></transaction-type>
 | |
|                                     </div>
 | |
|                                 </div>
 | |
|                                 <div class="col-lg-4">
 | |
|                                     <!-- -->
 | |
|                                     <amount
 | |
|                                         v-model="transaction.amount"
 | |
|                                         :destination="transaction.destination_account"
 | |
|                                         :error="transaction.errors.amount"
 | |
|                                         :index="index"
 | |
|                                         :source="transaction.source_account"
 | |
|                                         :transactionType="transactionType"
 | |
|                                     ></amount>
 | |
|                                     <foreign-amount v-if="transactionType.toLowerCase() !== 'reconciliation'"
 | |
|                                                     v-model="transaction.foreign_amount"
 | |
|                                                     :destination="transaction.destination_account"
 | |
|                                                     :error="transaction.errors.foreign_amount"
 | |
|                                                     :no_currency="$t('firefly.none_in_select_list')"
 | |
|                                                     :source="transaction.source_account"
 | |
|                                                     :transactionType="transactionType"
 | |
|                                                     v-bind:title="$t('form.foreign_amount')"
 | |
|                                     ></foreign-amount>
 | |
|                                 </div>
 | |
|                                 <div class="col-lg-4">
 | |
|                                     <budget
 | |
|                                         v-model="transaction.budget"
 | |
|                                         :error="transaction.errors.budget_id"
 | |
|                                         :no_budget="$t('firefly.none_in_select_list')"
 | |
|                                         :transactionType="transactionType"
 | |
|                                     ></budget>
 | |
|                                     <category
 | |
|                                         v-model="transaction.category"
 | |
|                                         :error="transaction.errors.category"
 | |
|                                         :transactionType="transactionType"
 | |
|                                     ></category>
 | |
|                                     <tags
 | |
|                                         v-model="transaction.tags"
 | |
|                                         :error="transaction.errors.tags"
 | |
|                                         :tags="transaction.tags"
 | |
|                                         :transactionType="transactionType"
 | |
|                                     ></tags>
 | |
|                                     <bill
 | |
|                                         v-model="transaction.bill"
 | |
|                                         :error="transaction.errors.bill_id"
 | |
|                                         :no_bill="$t('firefly.none_in_select_list')"
 | |
|                                         :transactionType="transactionType"
 | |
|                                     ></bill>
 | |
|                                     <custom-transaction-fields
 | |
|                                         v-model="transaction.custom_fields"
 | |
|                                         :error="transaction.errors.custom_errors"
 | |
|                                     ></custom-transaction-fields>
 | |
|                                 </div>
 | |
|                             </div>
 | |
|                         </div>
 | |
|                         <div
 | |
|                             v-if="transactions.length-1 === index && transactionType.toLowerCase() !== 'reconciliation'"
 | |
|                             class="box-footer">
 | |
|                             <button class="btn btn-default" type="button" @click="addTransaction">{{
 | |
|                                     $t('firefly.add_another_split')
 | |
|                                 }}
 | |
|                             </button>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
|         <div v-if="transactions.length > 1" class="row">
 | |
|             <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
 | |
|                 <div class="box">
 | |
|                     <div class="box-header with-border">
 | |
|                         <h3 class="box-title">
 | |
|                             {{ $t('firefly.split_transaction_title') }}
 | |
|                         </h3>
 | |
|                     </div>
 | |
|                     <div class="box-body">
 | |
|                         <group-description
 | |
|                             v-model="group_title"
 | |
|                             :error="group_title_errors"
 | |
|                         ></group-description>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
|         <div class="row">
 | |
|             <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
 | |
|                 <div class="box">
 | |
|                     <div class="box-header with-border">
 | |
|                         <h3 class="box-title">
 | |
|                             {{ $t('firefly.submission') }}
 | |
|                         </h3>
 | |
|                     </div>
 | |
|                     <div class="box-body">
 | |
|                         <div class="checkbox">
 | |
|                             <label>
 | |
|                                 <input v-model="returnAfter" name="return_after" type="checkbox">
 | |
|                                 {{ $t('firefly.after_update_create_another') }}
 | |
|                             </label>
 | |
|                         </div>
 | |
|                         <div v-if="null !== transactionType && transactionType.toLowerCase() !== 'reconciliation'"
 | |
|                              class="checkbox">
 | |
|                             <label>
 | |
|                                 <input v-model="storeAsNew" name="store_as_new" type="checkbox">
 | |
|                                 {{ $t('firefly.store_as_new') }}
 | |
|                             </label>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                     <div class="box-footer">
 | |
|                         <div class="btn-group">
 | |
|                             <button id="submitButton" class="btn btn-success" @click="submit">{{
 | |
|                                     $t('firefly.update_transaction')
 | |
|                                 }}
 | |
|                             </button>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
|             <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
 | |
|                 <div class="box">
 | |
|                     <div class="box-header with-border">
 | |
|                         <h3 class="box-title">
 | |
|                             {{ $t('firefly.submission_options') }}
 | |
|                         </h3>
 | |
|                     </div>
 | |
|                     <div class="box-body">
 | |
|                         <div class="checkbox">
 | |
|                             <label>
 | |
|                                 <input v-model="applyRules" name="apply_rules" type="checkbox">
 | |
|                                 {{ $t('firefly.apply_rules_checkbox') }}
 | |
|                             </label>
 | |
|                         </div>
 | |
|                         <div class="checkbox">
 | |
|                             <label>
 | |
|                                 <input v-model="fireWebhooks" name="fire_webhooks" type="checkbox">
 | |
|                                 {{ $t('firefly.fire_webhooks_checkbox') }}
 | |
| 
 | |
|                             </label>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
|     </form>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| export default {
 | |
|     name: "EditTransaction",
 | |
|     props: {
 | |
|         groupId: Number
 | |
|     },
 | |
|     mounted() {
 | |
|         // console.log('EditTransaction: mounted()');
 | |
|         this.getGroup();
 | |
|     },
 | |
|     ready() {
 | |
|         // console.log('EditTransaction: ready()');
 | |
|     },
 | |
|     methods: {
 | |
|         positiveAmount(amount) {
 | |
|             if (amount < 0) {
 | |
|                 return amount * -1;
 | |
|             }
 | |
|             return amount;
 | |
|         },
 | |
|         roundNumber(amount, decimals) {
 | |
|             let multiplier = Math.pow(10, decimals);
 | |
|             return Math.round(amount * multiplier) / multiplier;
 | |
|         },
 | |
|         selectedSourceAccount(index, model) {
 | |
|             if (typeof model === 'string') {
 | |
|                 // cant change types, only name.
 | |
|                 // also clear ID
 | |
|                 this.transactions[index].source_account.id = null;
 | |
|                 this.transactions[index].source_account.name = model;
 | |
|                 return;
 | |
|             }
 | |
|             this.transactions[index].source_account = {
 | |
|                 id: model.id,
 | |
|                 name: model.name,
 | |
|                 type: model.type,
 | |
|                 currency_id: model.currency_id,
 | |
|                 currency_name: model.currency_name,
 | |
|                 currency_code: model.currency_code,
 | |
|                 currency_decimal_places: model.currency_decimal_places,
 | |
|                 allowed_types: this.transactions[index].source_account.allowed_types
 | |
|             };
 | |
|         },
 | |
|         selectedDestinationAccount(index, model) {
 | |
|             if (typeof model === 'string') {
 | |
|                 // cant change types, only name.
 | |
|                 // also clear ID
 | |
|                 this.transactions[index].destination_account.id = null;
 | |
|                 this.transactions[index].destination_account.name = model;
 | |
|                 return;
 | |
|             }
 | |
|             this.transactions[index].destination_account = {
 | |
|                 id: model.id,
 | |
|                 name: model.name,
 | |
|                 type: model.type,
 | |
|                 currency_id: model.currency_id,
 | |
|                 currency_name: model.currency_name,
 | |
|                 currency_code: model.currency_code,
 | |
|                 currency_decimal_places: model.currency_decimal_places,
 | |
|                 allowed_types: this.transactions[index].destination_account.allowed_types
 | |
|             };
 | |
|         },
 | |
|         clearSource(index) {
 | |
|             // reset source account:
 | |
|             this.transactions[index].source_account = {
 | |
|                 id: 0,
 | |
|                 name: '',
 | |
|                 type: '',
 | |
|                 currency_id: 0,
 | |
|                 currency_name: '',
 | |
|                 currency_code: '',
 | |
|                 currency_decimal_places: 2,
 | |
|                 allowed_types: this.transactions[index].source_account.allowed_types
 | |
|             };
 | |
|             // if there is a destination model, reset the types of the source
 | |
|             // by pretending we selected it again.
 | |
|             if (this.transactions[index].destination_account) {
 | |
|                 this.selectedDestinationAccount(index, this.transactions[index].destination_account);
 | |
|             }
 | |
|         },
 | |
|         setTransactionType(type) {
 | |
|             if (null !== type) {
 | |
|                 this.transactionType = type;
 | |
|             }
 | |
|         },
 | |
|         deleteTransaction(index, event) {
 | |
|             event.preventDefault();
 | |
|             this.transactions.splice(index, 1);
 | |
|         },
 | |
|         clearDestination(index) {
 | |
|             // console.log('clearDestination(' + index + ')');
 | |
|             // reset destination account:
 | |
|             // console.log('Destination allowed types first:');
 | |
|             // console.log(this.transactions[index].destination_account.allowed_types);
 | |
|             this.transactions[index].destination_account = {
 | |
|                 id: 0,
 | |
|                 name: '',
 | |
|                 type: '',
 | |
|                 currency_id: 0,
 | |
|                 currency_name: '',
 | |
|                 currency_code: '',
 | |
|                 currency_decimal_places: 2,
 | |
|                 allowed_types: this.transactions[index].destination_account.allowed_types
 | |
|             };
 | |
|             // reset destination allowed account types.
 | |
|             //this.transactions[index].source_account.allowed_types = [];
 | |
| 
 | |
|             // if there is a source model, reset the types of the destination
 | |
|             // by pretending we selected it again.
 | |
|             if (this.transactions[index].source_account) {
 | |
|                 this.selectedSourceAccount(index, this.transactions[index].source_account);
 | |
|             }
 | |
| 
 | |
|             // console.log('Destination allowed types after:');
 | |
|             // console.log(this.transactions[index].destination_account.allowed_types);
 | |
|         },
 | |
|         getGroup() {
 | |
|             // console.log('EditTransaction: getGroup()');
 | |
|             const page = window.location.href.split('/');
 | |
|             const groupId = parseInt(page[page.length - 1]);
 | |
| 
 | |
| 
 | |
|             const uri = './api/v1/transactions/' + groupId;
 | |
|             // console.log(uri);
 | |
| 
 | |
|             // fill in transactions array.
 | |
|             axios.get(uri)
 | |
|                 .then(response => {
 | |
|                     this.processIncomingGroup(response.data.data);
 | |
|                 })
 | |
|                 .catch(error => {
 | |
|                     console.error('Some error when getting axios');
 | |
|                     console.error(error);
 | |
|                 });
 | |
|         },
 | |
|         processIncomingGroup(data) {
 | |
|             // console.log('EditTransaction: processIncomingGroup()');
 | |
|             this.group_title = data.attributes.group_title;
 | |
|             let transactions = data.attributes.transactions.reverse();
 | |
|             for (let key in transactions) {
 | |
|                 if (transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
 | |
|                     let transaction = transactions[key];
 | |
|                     this.processIncomingGroupRow(transaction);
 | |
|                 }
 | |
| 
 | |
|             }
 | |
|         },
 | |
|         ucFirst(string) {
 | |
|             if (typeof string === 'string') {
 | |
|                 return string.charAt(0).toUpperCase() + string.slice(1);
 | |
|             }
 | |
|             return null;
 | |
|         },
 | |
|         processIncomingGroupRow(transaction) {
 | |
|             //console.log('EditTransaction: processIncomingGroupRow()');
 | |
|             this.setTransactionType(transaction.type);
 | |
| 
 | |
|             if(true === transaction.reconciled) {
 | |
|                 this.isReconciled = true;
 | |
|             }
 | |
| 
 | |
|             let newTags = [];
 | |
|             for (let key in transaction.tags) {
 | |
|                 if (transaction.tags.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
 | |
|                     newTags.push({text: transaction.tags[key], tiClasses: []});
 | |
|                 }
 | |
|             }
 | |
|             // console.log('source allowed types for a ' + transaction.type);
 | |
|             //console.log(window.expectedSourceTypes.source[transaction.type]);
 | |
|             // console.log(window.expectedSourceTypes.source[this.ucFirst(transaction.type)]);
 | |
|             // console.log('destination allowed types for a ' + transaction.type);
 | |
|             // console.log(window.expectedSourceTypes.destination[this.ucFirst(transaction.type)]);
 | |
|             if (typeof window.expectedSourceTypes === 'undefined') {
 | |
|                 console.error('window.expectedSourceTypes is unexpectedly empty.')
 | |
|             }
 | |
|             let result = {
 | |
|                 transaction_journal_id: transaction.transaction_journal_id,
 | |
|                 description: transaction.description,
 | |
|                 date: transaction.date.substring(0, 16),
 | |
|                 amount: this.roundNumber(this.positiveAmount(transaction.amount), transaction.currency_decimal_places),
 | |
|                 category: transaction.category_name,
 | |
|                 errors: {
 | |
|                     source_account: [],
 | |
|                     destination_account: [],
 | |
|                     description: [],
 | |
|                     amount: [],
 | |
|                     date: [],
 | |
|                     budget_id: [],
 | |
|                     bill_id: [],
 | |
|                     foreign_amount: [],
 | |
|                     category: [],
 | |
|                     piggy_bank: [],
 | |
|                     tags: [],
 | |
|                     // custom fields:
 | |
|                     custom_errors: {
 | |
|                         interest_date: [],
 | |
|                         book_date: [],
 | |
|                         process_date: [],
 | |
|                         due_date: [],
 | |
|                         payment_date: [],
 | |
|                         invoice_date: [],
 | |
|                         internal_reference: [],
 | |
|                         notes: [],
 | |
|                         attachments: [],
 | |
|                         external_url: [],
 | |
|                     },
 | |
|                 },
 | |
|                 budget: transaction.budget_id,
 | |
|                 bill: transaction.bill_id,
 | |
|                 tags: newTags,
 | |
|                 custom_fields: {
 | |
|                     interest_date: transaction.interest_date,
 | |
|                     book_date: transaction.book_date,
 | |
|                     process_date: transaction.process_date,
 | |
|                     due_date: transaction.due_date,
 | |
|                     payment_date: transaction.payment_date,
 | |
|                     invoice_date: transaction.invoice_date,
 | |
|                     internal_reference: transaction.internal_reference,
 | |
|                     notes: transaction.notes,
 | |
|                     external_url: transaction.external_url
 | |
|                 },
 | |
|                 foreign_amount: {
 | |
|                     amount: this.roundNumber(this.positiveAmount(transaction.foreign_amount), transaction.foreign_currency_decimal_places),
 | |
|                     currency_id: transaction.foreign_currency_id
 | |
|                 },
 | |
|                 source_account: {
 | |
|                     id: transaction.source_id,
 | |
|                     name: transaction.source_name,
 | |
|                     type: transaction.source_type,
 | |
|                     currency_id: transaction.currency_id,
 | |
|                     currency_name: transaction.currency_name,
 | |
|                     currency_code: transaction.currency_code,
 | |
|                     currency_decimal_places: transaction.currency_decimal_places,
 | |
|                     allowed_types: window.expectedSourceTypes.source[this.ucFirst(transaction.type)]
 | |
|                 },
 | |
|                 destination_account: {
 | |
|                     id: transaction.destination_id,
 | |
|                     name: transaction.destination_name,
 | |
|                     type: transaction.destination_type,
 | |
|                     currency_id: transaction.currency_id,
 | |
|                     currency_name: transaction.currency_name,
 | |
|                     currency_code: transaction.currency_code,
 | |
|                     currency_decimal_places: transaction.currency_decimal_places,
 | |
|                     allowed_types: window.expectedSourceTypes.destination[this.ucFirst(transaction.type)]
 | |
|                 }
 | |
|             };
 | |
|             if(null === transaction.foreign_amount) {
 | |
|                 result.foreign_amount.amount = '';
 | |
|             }
 | |
|             this.transactions.push(result);
 | |
|         },
 | |
|         limitSourceType: function (type) {
 | |
|             // let i;
 | |
|             // for (i = 0; i < this.transactions.length; i++) {
 | |
|             //     this.transactions[i].source_account.allowed_types = [type];
 | |
|             // }
 | |
|         },
 | |
|         limitDestinationType: function (type) {
 | |
|             // let i;
 | |
|             // for (i = 0; i < this.transactions.length; i++) {
 | |
|             //     this.transactions[i].destination_account.allowed_types = [type];
 | |
|             // }
 | |
|         },
 | |
|         convertData: function () {
 | |
|             let data = {
 | |
|                 'apply_rules': this.applyRules,
 | |
|                 'fire_webhooks': this.fireWebhooks,
 | |
|                 'transactions': [],
 | |
|             };
 | |
|             let transactionType;
 | |
|             let firstSource;
 | |
|             let firstDestination;
 | |
| 
 | |
|             if (this.transactions.length > 1) {
 | |
|                 data.group_title = this.group_title;
 | |
|             }
 | |
| 
 | |
|             // get transaction type from first transaction
 | |
|             transactionType = this.transactionType ? this.transactionType.toLowerCase() : 'invalid';
 | |
| 
 | |
|             // if the transaction type is invalid, might just be that we can deduce it from
 | |
|             // the presence of a source or destination account
 | |
|             firstSource = this.transactions[0].source_account.type;
 | |
|             firstDestination = this.transactions[0].destination_account.type;
 | |
| 
 | |
|             if ('invalid' === transactionType && ['Asset account', 'Loan', 'Debt', 'Mortgage'].includes(firstSource)) {
 | |
|                 //console.log('Assumed this is a withdrawal.');
 | |
|                 transactionType = 'withdrawal';
 | |
|             }
 | |
| 
 | |
|             if ('invalid' === transactionType && ['Asset account', 'Loan', 'Debt', 'Mortgage'].includes(firstDestination)) {
 | |
|                 //console.log('Assumed this is a deposit.');
 | |
|                 transactionType = 'deposit';
 | |
|             }
 | |
| 
 | |
|             // get currency from first transaction. overrule the rest
 | |
|             let currencyId = this.transactions[0].source_account.currency_id;
 | |
| 
 | |
|             if ('deposit' === transactionType) {
 | |
|                 currencyId = this.transactions[0].destination_account.currency_id;
 | |
|             }
 | |
|             console.log('Overruled currency ID to ' + currencyId);
 | |
| 
 | |
|             for (let key in this.transactions) {
 | |
|                 if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
 | |
|                     data.transactions.push(this.convertDataRow(this.transactions[key], key, transactionType, currencyId));
 | |
|                 }
 | |
|             }
 | |
|             //console.log(data);
 | |
| 
 | |
|             return data;
 | |
|         },
 | |
|         convertDataRow(row, index, transactionType, currencyId) {
 | |
|             let tagList = [];
 | |
|             let foreignAmount = null;
 | |
|             let foreignCurrency = null;
 | |
|             let currentArray;
 | |
|             let sourceId;
 | |
|             let sourceName;
 | |
|             let destId;
 | |
|             let destName;
 | |
|             let date;
 | |
|             sourceId = row.source_account.id;
 | |
|             sourceName = row.source_account.name;
 | |
|             destId = row.destination_account.id;
 | |
|             destName = row.destination_account.name;
 | |
| 
 | |
|             // depends on the transaction type, where we get the currency.
 | |
|             // if ('withdrawal' === transactionType || 'transfer' === transactionType) {
 | |
|             //   row.currency_id = row.source_account.currency_id;
 | |
|             //   console.log('Overruled currency ID to ' + row.currency_id);
 | |
|             // }
 | |
|             // if ('deposit' === transactionType) {
 | |
|             //   row.currency_id = row.destination_account.currency_id;
 | |
|             //   console.log('Overruled currency ID to ' + row.currency_id);
 | |
|             // }
 | |
| 
 | |
|             row.currency_id = currencyId;
 | |
|             console.log('Final currency ID = ' + currencyId);
 | |
| 
 | |
|             date = row.date;
 | |
|             if (index > 0) {
 | |
|                 date = this.transactions[0].date;
 | |
|             }
 | |
| 
 | |
|             // if type is 'withdrawal' and destination is empty, cash withdrawal.
 | |
|             if (transactionType === 'withdrawal' && '' === destName) {
 | |
|                 destId = window.cashAccountId;
 | |
|             }
 | |
| 
 | |
|             // if type is 'deposit' and source is empty, cash deposit.
 | |
|             if (transactionType === 'deposit' && '' === sourceName) {
 | |
|                 sourceId = window.cashAccountId;
 | |
|             }
 | |
| 
 | |
|             // if index is over 0 and type is withdrawal or transfer, take source from index 0.
 | |
|             if (index > 0 && (transactionType.toLowerCase() === 'withdrawal' || transactionType.toLowerCase() === 'transfer')) {
 | |
|                 sourceId = this.transactions[0].source_account.id;
 | |
|                 sourceName = this.transactions[0].source_account.name;
 | |
|             }
 | |
| 
 | |
|             // if index is over 0 and type is deposit or transfer, take destination from index 0.
 | |
|             if (index > 0 && (transactionType.toLowerCase() === 'deposit' || transactionType.toLowerCase() === 'transfer')) {
 | |
|                 destId = this.transactions[0].destination_account.id;
 | |
|                 destName = this.transactions[0].destination_account.name;
 | |
|             }
 | |
| 
 | |
|             tagList = [];
 | |
|             foreignAmount = '0';
 | |
|             // loop tags
 | |
|             for (let tagKey in row.tags) {
 | |
|                 if (row.tags.hasOwnProperty(tagKey) && /^0$|^[1-9]\d*$/.test(tagKey) && tagKey <= 4294967294) {
 | |
|                     tagList.push(row.tags[tagKey].text);
 | |
|                 }
 | |
|             }
 | |
|             // set foreign currency info:
 | |
|             if (row.foreign_amount.amount.toString() !== '' && parseFloat(row.foreign_amount.amount) !== .00) {
 | |
|                 foreignAmount = row.foreign_amount.amount;
 | |
|                 foreignCurrency = row.foreign_amount.currency_id;
 | |
|             }
 | |
|             if (foreignCurrency === row.currency_id) {
 | |
|                 foreignAmount = null;
 | |
|                 foreignCurrency = null;
 | |
|             }
 | |
| 
 | |
|             // correct some id's
 | |
|             if (0 === destId) {
 | |
|                 destId = null;
 | |
|             }
 | |
|             if (0 === sourceId) {
 | |
|                 sourceId = null;
 | |
|             }
 | |
| 
 | |
|             // parse amount, if amount has exactly one comma:
 | |
|             // solves issues with some locales.
 | |
|             if (1 === (String(row.amount).match(/\,/g) || []).length) {
 | |
|                 row.amount = String(row.amount).replace(',', '.');
 | |
|             }
 | |
| 
 | |
|             currentArray =
 | |
|                 {
 | |
|                     transaction_journal_id: row.transaction_journal_id,
 | |
|                     type: transactionType,
 | |
|                     date: date,
 | |
|                     amount: row.amount,
 | |
| 
 | |
|                     description: row.description,
 | |
| 
 | |
|                     source_id: sourceId,
 | |
|                     source_name: sourceName,
 | |
| 
 | |
|                     destination_id: destId,
 | |
|                     destination_name: destName,
 | |
| 
 | |
| 
 | |
|                     category_name: row.category,
 | |
| 
 | |
|                     interest_date: row.custom_fields.interest_date,
 | |
|                     book_date: row.custom_fields.book_date,
 | |
|                     process_date: row.custom_fields.process_date,
 | |
|                     due_date: row.custom_fields.due_date,
 | |
|                     payment_date: row.custom_fields.payment_date,
 | |
|                     invoice_date: row.custom_fields.invoice_date,
 | |
|                     internal_reference: row.custom_fields.internal_reference,
 | |
|                     external_url: row.custom_fields.external_url,
 | |
|                     notes: row.custom_fields.notes,
 | |
|                     tags: tagList
 | |
|                 };
 | |
|             // always submit foreign amount info.
 | |
|             currentArray.foreign_amount = foreignAmount;
 | |
|             currentArray.foreign_currency_id = foreignCurrency;
 | |
| 
 | |
|             // only submit currency ID when not 0:
 | |
|             if (0 !== row.currency_id && null !== row.currency_id) {
 | |
|                 currentArray.currency_id = row.currency_id;
 | |
|             }
 | |
| 
 | |
|             // set budget id and piggy ID.
 | |
|             currentArray.budget_id = parseInt(row.budget);
 | |
|             if (parseInt(row.bill) > 0) {
 | |
|                 currentArray.bill_id = parseInt(row.bill);
 | |
|             }
 | |
|             if (0 === parseInt(row.bill)) {
 | |
|                 currentArray.bill_id = null;
 | |
|             }
 | |
| 
 | |
|             if (parseInt(row.piggy_bank) > 0) {
 | |
|                 currentArray.piggy_bank_id = parseInt(row.piggy_bank);
 | |
|             }
 | |
|             if(this.isReconciled && !this.storeAsNew) {
 | |
|                 // drop content from array:
 | |
|                 delete currentArray.source_id;
 | |
|                 delete currentArray.source_name;
 | |
|                 delete currentArray.destination_id;
 | |
|                 delete currentArray.destination_name;
 | |
|                 delete currentArray.amount;
 | |
|                 delete currentArray.foreign_amount;
 | |
|                 delete currentArray.foreign_currency_id;
 | |
|                 delete currentArray.currency_id;
 | |
|                 currentArray.reconciled = true;
 | |
|             }
 | |
| 
 | |
|             return currentArray;
 | |
|         },
 | |
|         submit: function (e) {
 | |
| 
 | |
|             let button = $('#submitButton');
 | |
|             button.prop("disabled", true);
 | |
| 
 | |
|             const page = window.location.href.split('/');
 | |
|             const groupId = parseInt(page[page.length - 1]);
 | |
|             let uri = './api/v1/transactions/' + groupId + '?_token=' + document.head.querySelector('meta[name="csrf-token"]').content;
 | |
|             let method = 'PUT';
 | |
|             if (this.storeAsNew) {
 | |
|                 // other links.
 | |
|                 uri = './api/v1/transactions?_token=' + document.head.querySelector('meta[name="csrf-token"]').content;
 | |
|                 method = 'POST';
 | |
|             }
 | |
|             const data = this.convertData();
 | |
| 
 | |
|             //axios.put(uri, data)
 | |
|             axios({
 | |
|                 method: method,
 | |
|                 url: uri,
 | |
|                 data: data,
 | |
|             }).then(response => {
 | |
|                 if (0 === this.collectAttachmentData(response)) {
 | |
|                     const title = response.data.data.attributes.group_title ?? response.data.data.attributes.transactions[0].description;
 | |
|                     this.redirectUser(response.data.data.id, title);
 | |
|                 }
 | |
|             }).catch(error => {
 | |
|                 // give user errors things back.
 | |
|                 // something something render errors.
 | |
|                 this.parseErrors(error.response.data);
 | |
|                 // something.
 | |
|             });
 | |
|             if (e) {
 | |
|                 e.preventDefault();
 | |
|             }
 | |
|             button.removeAttr('disabled');
 | |
|         },
 | |
| 
 | |
|         redirectUser(groupId, title) {
 | |
|             if (this.returnAfter) {
 | |
|                 this.setDefaultErrors();
 | |
|                 // do message if update or new:
 | |
|                 if (this.storeAsNew) {
 | |
|                     this.success_message = this.$t('firefly.transaction_new_stored_link', {ID: groupId, title: this.escapeHtml(title)});
 | |
|                     this.error_message = '';
 | |
|                 } else {
 | |
|                     this.success_message = this.$t('firefly.transaction_updated_link', {ID: groupId, title: this.escapeHtml(title)});
 | |
|                     this.error_message = '';
 | |
|                 }
 | |
|             } else {
 | |
|                 if (this.storeAsNew) {
 | |
|                     window.location.href = window.previousUrl + '?transaction_group_id=' + groupId + '&message=created';
 | |
|                 } else {
 | |
|                     window.location.href = window.previousUrl + '?transaction_group_id=' + groupId + '&message=updated';
 | |
|                 }
 | |
|             }
 | |
|         },
 | |
| 
 | |
|         collectAttachmentData(response) {
 | |
|             // console.log('Now incollectAttachmentData()');
 | |
|             let groupId = response.data.data.id;
 | |
| 
 | |
|             // array of all files to be uploaded:
 | |
|             let toBeUploaded = [];
 | |
| 
 | |
|             // array with all file data.
 | |
|             let fileData = [];
 | |
| 
 | |
|             // all attachments
 | |
|             let attachments = $('input[name="attachments[]"]');
 | |
| 
 | |
|             // loop over all attachments, and add references to this array:
 | |
|             for (const key in attachments) {
 | |
|                 if (attachments.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
 | |
|                     for (const fileKey in attachments[key].files) {
 | |
|                         if (attachments[key].files.hasOwnProperty(fileKey) && /^0$|^[1-9]\d*$/.test(fileKey) && fileKey <= 4294967294) {
 | |
|                             // include journal thing.
 | |
| 
 | |
|                             let transactions = response.data.data.attributes.transactions.reverse();
 | |
| 
 | |
|                             toBeUploaded.push(
 | |
|                                 {
 | |
|                                     journal: transactions[key].transaction_journal_id,
 | |
|                                     file: attachments[key].files[fileKey]
 | |
|                                 }
 | |
|                             );
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             let count = toBeUploaded.length;
 | |
|             // console.log('Found ' + toBeUploaded.length + ' attachments.');
 | |
| 
 | |
|             // loop all uploads.
 | |
|             for (const key in toBeUploaded) {
 | |
|                 if (toBeUploaded.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
 | |
|                     // create file reader thing that will read all of these uploads
 | |
|                     (function (f, i, theParent) {
 | |
|                         let fileReader = new FileReader();
 | |
|                         fileReader.onloadend = function (evt) {
 | |
|                             if (evt.target.readyState === FileReader.DONE) { // DONE == 2
 | |
|                                 fileData.push(
 | |
|                                     {
 | |
|                                         name: toBeUploaded[key].file.name,
 | |
|                                         journal: toBeUploaded[key].journal,
 | |
|                                         content: new Blob([evt.target.result])
 | |
|                                     }
 | |
|                                 );
 | |
|                                 if (fileData.length === count) {
 | |
|                                     theParent.uploadFiles(fileData, groupId);
 | |
|                                 }
 | |
|                             }
 | |
|                         };
 | |
|                         fileReader.readAsArrayBuffer(f.file);
 | |
|                     })(toBeUploaded[key], key, this);
 | |
|                 }
 | |
|             }
 | |
|             return count;
 | |
|         },
 | |
| 
 | |
|         uploadFiles(fileData, groupId) {
 | |
|             let count = fileData.length;
 | |
|             let uploads = 0;
 | |
|             for (const key in fileData) {
 | |
|                 if (fileData.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
 | |
|                     // console.log('Creating attachment #' + key);
 | |
|                     // axios thing, + then.
 | |
|                     const uri = './api/v1/attachments';
 | |
|                     const data = {
 | |
|                         filename: fileData[key].name,
 | |
|                         attachable_type: 'TransactionJournal',
 | |
|                         attachable_id: fileData[key].journal,
 | |
|                     };
 | |
|                     axios.post(uri, data)
 | |
|                         .then(response => {
 | |
|                             // console.log('Created attachment #' + key);
 | |
|                             // console.log('Uploading attachment #' + key);
 | |
|                             const uploadUri = './api/v1/attachments/' + response.data.data.id + '/upload';
 | |
|                             axios.post(uploadUri, fileData[key].content)
 | |
|                                 .then(secondResponse => {
 | |
|                                     // console.log('Uploaded attachment #' + key);
 | |
|                                     uploads++;
 | |
|                                     if (uploads === count) {
 | |
|                                         // finally we can redirect the user onwards.
 | |
|                                         // console.log('FINAL UPLOAD');
 | |
|                                         this.redirectUser(groupId, null);
 | |
|                                     }
 | |
|                                     // console.log('Upload complete!');
 | |
|                                     return true;
 | |
|                                 }).catch(error => {
 | |
|                                 console.error('Could not upload file.');
 | |
|                                 console.error(error);
 | |
|                                 uploads++;
 | |
|                                 this.error_message = 'Could not upload attachment: ' + error;
 | |
|                                 if (uploads === count) {
 | |
|                                     this.redirectUser(groupId, null);
 | |
|                                 }
 | |
|                                 // console.error(error);
 | |
|                                 return false;
 | |
|                             });
 | |
|                         }).catch(error => {
 | |
|                         console.error('Could not create upload.');
 | |
|                         console.error(error);
 | |
|                         uploads++;
 | |
|                         if (uploads === count) {
 | |
|                             // finally we can redirect the user onwards.
 | |
|                             // console.log('FINAL UPLOAD');
 | |
|                             this.redirectUser(groupId, null);
 | |
|                         }
 | |
|                         // console.log('Upload complete!');
 | |
|                         return false;
 | |
|                     });
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|         },
 | |
| 
 | |
|         escapeHtml: function (string) {
 | |
| 
 | |
|             let entityMap = {
 | |
|                 '&': '&',
 | |
|                 '<': '<',
 | |
|                 '>': '>',
 | |
|                 '"': '"',
 | |
|                 "'": ''',
 | |
|                 '/': '/',
 | |
|                 '`': '`',
 | |
|                 '=': '='
 | |
|             };
 | |
| 
 | |
|             return String(string).replace(/[&<>"'`=\/]/g, function fromEntityMap(s) {
 | |
|                 return entityMap[s];
 | |
|             });
 | |
| 
 | |
|         },
 | |
| 
 | |
|         addTransaction: function (e) {
 | |
| 
 | |
|             this.transactions.push({
 | |
|                 transaction_journal_id: 0,
 | |
|                 description: "",
 | |
|                 date: "",
 | |
|                 amount: "",
 | |
|                 category: "",
 | |
|                 piggy_bank: 0,
 | |
|                 errors: {
 | |
|                     source_account: [],
 | |
|                     destination_account: [],
 | |
|                     description: [],
 | |
|                     amount: [],
 | |
|                     date: [],
 | |
|                     budget_id: [],
 | |
|                     bill_id: [],
 | |
|                     foreign_amount: [],
 | |
|                     category: [],
 | |
|                     piggy_bank: [],
 | |
|                     tags: [],
 | |
|                     // custom fields:
 | |
|                     custom_errors: {
 | |
|                         interest_date: [],
 | |
|                         book_date: [],
 | |
|                         process_date: [],
 | |
|                         due_date: [],
 | |
|                         payment_date: [],
 | |
|                         invoice_date: [],
 | |
|                         internal_reference: [],
 | |
|                         notes: [],
 | |
|                         attachments: [],
 | |
|                         external_url: [],
 | |
|                     },
 | |
|                 },
 | |
|                 budget: 0,
 | |
|                 bill: 0,
 | |
|                 tags: [],
 | |
|                 custom_fields: {
 | |
|                     "interest_date": "",
 | |
|                     "book_date": "",
 | |
|                     "process_date": "",
 | |
|                     "due_date": "",
 | |
|                     "payment_date": "",
 | |
|                     "invoice_date": "",
 | |
|                     "internal_reference": "",
 | |
|                     "notes": "",
 | |
|                     "attachments": [],
 | |
|                     "external_url": "",
 | |
|                 },
 | |
|                 foreign_amount: {
 | |
|                     amount: "",
 | |
|                     currency_id: 0
 | |
|                 },
 | |
|                 source_account: {
 | |
|                     id: 0,
 | |
|                     name: "",
 | |
|                     type: "",
 | |
|                     currency_id: 0,
 | |
|                     currency_name: '',
 | |
|                     currency_code: '',
 | |
|                     currency_decimal_places: 2,
 | |
|                     allowed_types: []
 | |
|                 },
 | |
|                 destination_account: {
 | |
|                     id: 0,
 | |
|                     name: "",
 | |
|                     type: "",
 | |
|                     currency_id: 0,
 | |
|                     currency_name: '',
 | |
|                     currency_code: '',
 | |
|                     currency_decimal_places: 2,
 | |
|                     allowed_types: []
 | |
|                 }
 | |
|             });
 | |
|             let count = this.transactions.length;
 | |
|             // console.log('Transactions length = ' + count);
 | |
|             // also set accounts from previous entry, if present.
 | |
|             if (this.transactions.length > 1) {
 | |
|                 // console.log('Adding split.');
 | |
|                 this.transactions[count - 1].source_account = this.transactions[count - 2].source_account;
 | |
|                 this.transactions[count - 1].destination_account = this.transactions[count - 2].destination_account;
 | |
|                 this.transactions[count - 1].date = this.transactions[count - 2].date;
 | |
|             }
 | |
|             // console.log('Transactions length now = ' + this.transactions.length);
 | |
| 
 | |
|             if (e) {
 | |
|                 e.preventDefault();
 | |
|             }
 | |
|         },
 | |
|         parseErrors: function (errors) {
 | |
|             this.setDefaultErrors();
 | |
|             this.error_message = "";
 | |
|             if (errors.message.length > 0) {
 | |
|                 this.error_message = this.$t('firefly.errors_submission');
 | |
|             } else {
 | |
|                 this.error_message = '';
 | |
|             }
 | |
|             let transactionIndex;
 | |
|             let fieldName;
 | |
| 
 | |
|             for (const key in errors.errors) {
 | |
|                 if (errors.errors.hasOwnProperty(key)) {
 | |
|                     if (key === 'group_title') {
 | |
|                         this.group_title_errors = errors.errors[key];
 | |
|                     }
 | |
|                     if (key !== 'group_title') {
 | |
|                         // lol dumbest way to explode "transactions.0.something" ever.
 | |
|                         transactionIndex = parseInt(key.split('.')[1]);
 | |
|                         fieldName = key.split('.')[2];
 | |
|                         // set error in this object thing.
 | |
|                         switch (fieldName) {
 | |
|                             case 'amount':
 | |
|                             case 'date':
 | |
|                             case 'budget_id':
 | |
|                             case 'bill_id':
 | |
|                             case 'description':
 | |
|                             case 'tags':
 | |
|                                 this.transactions[transactionIndex].errors[fieldName] = errors.errors[key];
 | |
|                                 break;
 | |
|                             case 'external_url':
 | |
|                                 //console.log('Found ext error in field "' + fieldName + '": ' + errors.errors[key]);
 | |
|                                 this.transactions[transactionIndex].errors.custom_errors[fieldName] = errors.errors[key];
 | |
|                                 break;
 | |
|                             case 'source_name':
 | |
|                             case 'source_id':
 | |
|                                 this.transactions[transactionIndex].errors.source_account =
 | |
|                                     this.transactions[transactionIndex].errors.source_account.concat(errors.errors[key]);
 | |
|                                 break;
 | |
|                             case 'destination_name':
 | |
|                             case 'destination_id':
 | |
|                                 this.transactions[transactionIndex].errors.destination_account =
 | |
|                                     this.transactions[transactionIndex].errors.destination_account.concat(errors.errors[key]);
 | |
|                                 break;
 | |
|                             case 'foreign_amount':
 | |
|                             case 'foreign_currency_id':
 | |
|                                 this.transactions[transactionIndex].errors.foreign_amount =
 | |
|                                     this.transactions[transactionIndex].errors.foreign_amount.concat(errors.errors[key]);
 | |
|                                 break;
 | |
|                         }
 | |
| 
 | |
|                         // unique some things
 | |
|                         this.transactions[transactionIndex].errors.source_account =
 | |
|                             Array.from(new Set(this.transactions[transactionIndex].errors.source_account));
 | |
|                         this.transactions[transactionIndex].errors.destination_account =
 | |
|                             Array.from(new Set(this.transactions[transactionIndex].errors.destination_account));
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         },
 | |
|         setDefaultErrors: function () {
 | |
|             for (const key in this.transactions) {
 | |
|                 if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
 | |
|                     this.transactions[key].errors = {
 | |
|                         source_account: [],
 | |
|                         destination_account: [],
 | |
|                         description: [],
 | |
|                         amount: [],
 | |
|                         date: [],
 | |
|                         budget_id: [],
 | |
|                         bill_id: [],
 | |
|                         foreign_amount: [],
 | |
|                         category: [],
 | |
|                         piggy_bank: [],
 | |
|                         tags: [],
 | |
|                         // custom fields:
 | |
|                         custom_errors: {
 | |
|                             interest_date: [],
 | |
|                             book_date: [],
 | |
|                             process_date: [],
 | |
|                             due_date: [],
 | |
|                             payment_date: [],
 | |
|                             invoice_date: [],
 | |
|                             internal_reference: [],
 | |
|                             notes: [],
 | |
|                             attachments: [],
 | |
|                             external_url: [],
 | |
|                         },
 | |
|                     };
 | |
|                 }
 | |
|             }
 | |
|         },
 | |
|     },
 | |
| 
 | |
| 
 | |
|     data() {
 | |
|         return {
 | |
|             applyRules: true,
 | |
|             fireWebhooks: true,
 | |
|             group: this.groupId,
 | |
|             error_message: "",
 | |
|             isReconciled: false,
 | |
|             success_message: "",
 | |
|             transactions: [],
 | |
|             group_title: "",
 | |
|             returnAfter: false,
 | |
|             storeAsNew: false,
 | |
|             transactionType: null,
 | |
|             group_title_errors: [],
 | |
|             resetButtonDisabled: true,
 | |
|         }
 | |
|     }
 | |
| }
 | |
| </script>
 |