Newer
Older
make_invoice / app / src / components / table-record.js
import Vue from '../../../node_modules/vue/dist/vue.js';

Vue.component('table-record', {
    data: function () {
        return {
            working_time: 0.0, // 演算処理をする前の勤務時間
            below_time:0.0,
            above_time: 0.0,
            is_hovering: false,
        };
    },
    props: {
        pos: {
            type: Number,
            required: true
        },
        basic_info: {
            type: Object,
            required: true
        }
    },
    template: `
    <tr @mouseover="is_hovering = true" @mouseout="is_hovering = false" :class="{'is-selected': is_hovering}">
        <th>{{ pos + 1 }}</th>
        <td>{{ basic_info.location_name }}</td>
        <td>{{ basic_info.staff_name }}</td>
        <td>{{ basic_info.customer_name }}</td>
        <td>{{ basic_info.price }}</td>
        <td>{{ basic_info.lower_limit }}</td>
        <td>{{ basic_info.upper_limit }}</td>
        <td>
            <div class="control">
                <div class="select is-small">
                    <select @change="change_working_time">
                        <option value="">選択してください</option>
                        <option value="0">15分単位で切り捨て</option>
                        <option value="1">30分単位で切り捨て</option>
                    </select>
                </div>            
            </div>
        </td>
        <td>{{ working_time }}</td>
        <td>{{ basic_info.cost_below_limit }}</td>
        <td>{{ below_time }}</td>
        <td>{{ calc_below_cost }}</td>
        <td>{{ basic_info.cost_above_limit }}</td>
        <td>{{ above_time }}</td>
        <td>{{ calc_above_cost }}</td>
        <td>{{ calc_invoice_price }}</td>
    </tr>
    `,
    created: function () {
        // ファイルが一つでも存在しないと途中で処理が止まるので注意
        this.working_time = require('../assets/times/' + this.basic_info.staff_name + '.txt').default;
    },
    computed: {
        calc_below_time: function () {
            const below_time = this.basic_info.lower_limit - this.working_time;
            return (below_time > 0) ? below_time : 0;
        },
        calc_below_cost: function () {
            if (this.calc_below_time > 0) {
                const price = this.calc_below_time * replace_price_str_to_int(this.basic_info.cost_below_limit);
                return replace_int_to_price_str(price);
            }

            return 0;
        },
        calc_above_time: function () {
            const above_time = this.working_time - this.basic_info.upper_limit;
            return (above_time > 0) ? above_time : 0;
        },
        calc_above_cost: function () {
            if (this.calc_above_time > 0) {
                const price = this.calc_above_time * replace_price_str_to_int(this.basic_info.cost_above_limit);
                return replace_int_to_price_str(price);
            }

            return 0;
        },
        calc_invoice_price: function () {
            const price = replace_price_str_to_int(this.basic_info.price)
            const price_below = replace_price_str_to_int(this.calc_below_cost);
            const price_above = replace_price_str_to_int(this.calc_above_cost);
            

            if (price_below > 0) {
                return replace_int_to_price_str(price - price_below);
            }

            if (price_above > 0) {
                return replace_int_to_price_str(price + price_above);
            }

            return this.basic_info.price;
        }
    },
    methods: {
        change_working_time: function (event) {
            switch (event.target.value) {
                case "":
                    console.log('何も処理をしない');
                    break;
                case "0":
                    // 控除の算出
                    if (this.calc_below_time > 0) {
                        this.below_time = calc_working_time_by_select(this.calc_below_time, 15);
                    }
                    // 超過の算出
                    if (this.calc_above_time > 0) {
                        this.above_time = calc_working_time_by_select(this.calc_above_time, 15);
                    }

                    break;
                case "1":
                    // 控除の算出
                    if (this.calc_below_time > 0) {
                        this.below_time = calc_working_time_by_select(this.calc_below_time, 30);
                    }
                    // 超過の算出
                    if (this.calc_above_time > 0) {
                        this.above_time = calc_working_time_by_select(this.calc_above_time, 30);
                    }

                    break;
            };
        }
    }
});

const replace_int_to_price_str = (price) => {
    return '¥' + Number(price).toLocaleString();
}

const replace_price_str_to_int = (price_str) => {
    return Number(String(price_str).replace(/[\¥, \,]/g, ''));
}

/**
 * 時間の取り扱いを加味して勤務時間を算出する。
 * @param working_time 勤務時間
 * @param valule       時間の取り扱いで指定された分数
 */
const calc_working_time_by_select = (working_time, value) => {
    const int = get_before_point(working_time);
    const dec = get_after_point(working_time);
    
    value = value / 60; // 小数に変換

    return int + Math.floor(dec / value) * value;
}

// 整数部分のみを取得
const get_before_point = (num) => {
    const arr = String(num).split('.');

    if (arr[0]) {
        return Number('' + arr[0]);
    } else {
        return 0;
    }
}

// 小数点以下のみを取得
const get_after_point = (num) => {
	const arr = String(num).split('.');

	// 小数点以下がある場合と、ない場合
	if (arr[1]){
		// 先頭に '0.' をつける
		return Number('0.' + arr[1]);
	} else {
		return 0; // 小数点以下がない場合は0を返す
	}
};