import time
import logging
import numpy as np
import emcee

import torch
import torch.nn as nn
import torch.optim as optim

from scipy import optimize

from pybnn.base_model import BaseModel
from pybnn.util.normalization import zero_mean_unit_var_normalization, zero_mean_unit_var_denormalization
from pybnn.bayesian_linear_regression import BayesianLinearRegression, Prior

class Net(nn.Module):
    def __init__(self, n_inputs, n_units=[50, 50, 50]):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(n_inputs, n_units[0])
        self.fc2 = nn.Linear(n_units[0], n_units[1])
        self.fc3 = nn.Linear(n_units[1], n_units[2])
        self.out = nn.Linear(n_units[2], 1)

    def forward(self, x):
        x = torch.tanh(self.fc1(x))
        x = torch.tanh(self.fc2(x))
        x = torch.tanh(self.fc3(x))

        return self.out(x)

    def basis_funcs(self, x):
        x = torch.tanh(self.fc1(x))
        x = torch.tanh(self.fc2(x))
        x = torch.tanh(self.fc3(x))
        return x

class DNGO(BaseModel):

    def __init__(self, batch_size=10, num_epochs=500,
                 learning_rate=0.01,
                 adapt_epoch=5000, n_units_1=50, n_units_2=50, n_units_3=50,
                 alpha=1.0, beta=1000, prior=None, do_mcmc=True,
                 n_hypers=20, chain_length=2000, burnin_steps=2000,
                 normalize_input=True, normalize_output=True, rng=None):
        """
        Deep Networks for Global Optimization [1]. This module performs
        Bayesian Linear Regression with basis function extracted from a
        feed forward neural network.

        [1] J. Snoek, O. Rippel, K. Swersky, R. Kiros, N. Satish,
            N. Sundaram, M.~M.~A. Patwary, Prabhat, R.~P. Adams
            Scalable Bayesian Optimization Using Deep Neural Networks
            Proc. of ICML'15

        Parameters
        ----------
        batch_size: int
            Batch size for training the neural network
        num_epochs: int
            Number of epochs for training
        learning_rate: float
            Initial learning rate for Adam
        adapt_epoch: int
            Defines after how many epochs the learning rate will be decayed by a factor 10
        n_units_1: int
            Number of units in layer 1
        n_units_2: int
            Number of units in layer 2
        n_units_3: int
            Number of units in layer 3
        alpha: float
            Hyperparameter of the Bayesian linear regression
        beta: float
            Hyperparameter of the Bayesian linear regression
        prior: Prior object
            Prior for alpa and beta. If set to None the default prior is used
        do_mcmc: bool
            If set to true different values for alpha and beta are sampled via MCMC from the marginal log likelihood
            Otherwise the marginal log likehood is optimized with scipy fmin function
        n_hypers : int
            Number of samples for alpha and beta
        chain_length : int
            The chain length of the MCMC sampler
        burnin_steps: int
            The number of burnin steps before the sampling procedure starts
        normalize_output : bool
            Zero mean unit variance normalization of the output values
        normalize_input : bool
            Zero mean unit variance normalization of the input values
        rng: np.random.RandomState
            Random number generator
        """

        if rng is None:
            self.rng = np.random.RandomState(np.random.randint(0, 10000))
        else:
            self.rng = rng

        self.X = None
        self.y = None
        self.network = None
        self.alpha = alpha
        self.beta = beta
        self.normalize_input = normalize_input
        self.normalize_output = normalize_output

        # MCMC hyperparameters
        self.do_mcmc = do_mcmc
        self.n_hypers = n_hypers
        self.chain_length = chain_length
        self.burned = False
        self.burnin_steps = burnin_steps
        if prior is None:
            self.prior = Prior(rng=self.rng)
        else:
            self.prior = prior

        # Network hyper parameters
        self.num_epochs = num_epochs
        self.batch_size = batch_size
        self.init_learning_rate = learning_rate

        self.n_units_1 = n_units_1
        self.n_units_2 = n_units_2
        self.n_units_3 = n_units_3
        self.adapt_epoch = adapt_epoch
        self.network = None
        self.models = []
        self.hypers = None

    @BaseModel._check_shapes_train
    def train(self, X, y, do_optimize=True):
        """
        Trains the model on the provided data.

        Parameters
        ----------
        X: np.ndarray (N, D)
            Input data points. The dimensionality of X is (N, D),
            with N as the number of points and D is the number of features.
        y: np.ndarray (N,)
            The corresponding target values.
        do_optimize: boolean
            If set to true the hyperparameters are optimized otherwise
            the default hyperparameters are used.

        """
        start_time = time.time()

        # Normalize inputs
        if self.normalize_input:
            self.X, self.X_mean, self.X_std = zero_mean_unit_var_normalization(X)
        else:
            self.X = X

        # Normalize ouputs
        if self.normalize_output:
            self.y, self.y_mean, self.y_std = zero_mean_unit_var_normalization(y)
        else:
            self.y = y

        self.y = self.y[:, None]

        # Check if we have enough points to create a minibatch otherwise use all data points
        if self.X.shape[0] <= self.batch_size:
            batch_size = self.X.shape[0]
        else:
            batch_size = self.batch_size

        # Create the neural network
        features = X.shape[1]

        self.network = Net(n_inputs=features, n_units=[self.n_units_1, self.n_units_2, self.n_units_3])

        optimizer = optim.Adam(self.network.parameters(),
                               lr=self.init_learning_rate)

        # Start training
        lc = np.zeros([self.num_epochs])
        for epoch in range(self.num_epochs):

            epoch_start_time = time.time()

            train_err = 0
            train_batches = 0

            for batch in self.iterate_minibatches(self.X, self.y,
                                                  batch_size, shuffle=True):
                inputs = torch.Tensor(batch[0])
                targets = torch.Tensor(batch[1])

                optimizer.zero_grad()
                output = self.network(inputs)
                loss = torch.nn.functional.mse_loss(output, targets)
                loss.backward()
                optimizer.step()

                train_err += loss
                train_batches += 1

            lc[epoch] = train_err / train_batches
            logging.debug("Epoch {} of {}".format(epoch + 1, self.num_epochs))
            curtime = time.time()
            epoch_time = curtime - epoch_start_time
            total_time = curtime - start_time
            logging.debug("Epoch time {:.3f}s, total time {:.3f}s".format(epoch_time, total_time))
            logging.debug("Training loss:\t\t{:.5g}".format(train_err / train_batches))

        # Design matrix
        self.Theta = self.network.basis_funcs(torch.Tensor(self.X)).data.numpy()

        if do_optimize:
            if self.do_mcmc:
                self.sampler = emcee.EnsembleSampler(self.n_hypers, 2,
                                                     self.marginal_log_likelihood)

                # Do a burn-in in the first iteration
                if not self.burned:
                    # Initialize the walkers by sampling from the prior
                    self.p0 = self.prior.sample_from_prior(self.n_hypers)
                    # Run MCMC sampling
                    result = self.sampler.run_mcmc(self.p0,
                                                   self.burnin_steps,
                                                   rstate0=self.rng)
                    self.p0 = result.coords

                    self.burned = True

                # Start sampling
                pos = self.sampler.run_mcmc(self.p0,
                                            self.chain_length,
                                            rstate0=self.rng)

                # Save the current position, it will be the startpoint in
                # the next iteration
                self.p0 = pos.coords

                # Take the last samples from each walker set them back on a linear scale
                linear_theta = np.exp(self.sampler.chain[:, -1])
                self.hypers = linear_theta
                self.hypers[:, 1] = 1 / self.hypers[:, 1]
            else:
                # Optimize hyperparameters of the Bayesian linear regression
                p0 = self.prior.sample_from_prior(n_samples=1)
                res = optimize.fmin(self.negative_mll, p0)
                self.hypers = [[np.exp(res[0]), 1 / np.exp(res[1])]]
        else:

            self.hypers = [[self.alpha, self.beta]]

        logging.info("Hypers: %s" % self.hypers)
        self.models = []
        for sample in self.hypers:
            # Instantiate a model for each hyperparameter configuration
            model = BayesianLinearRegression(alpha=sample[0],
                                             beta=sample[1],
                                             basis_func=None)
            model.train(self.Theta, self.y[:, 0], do_optimize=False)

            self.models.append(model)

    def marginal_log_likelihood(self, theta):
        """
        Log likelihood of the data marginalised over the weights w. See chapter 3.5 of
        the book by Bishop of an derivation.

        Parameters
        ----------
        theta: np.array(2,)
            The hyperparameter alpha and beta on a log scale

        Returns
        -------
        float
            lnlikelihood + prior
        """
        if np.any(theta == np.inf):
            return -np.inf

        if np.any((-10 > theta) + (theta > 10)):
            return -np.inf

        alpha = np.exp(theta[0])
        beta = 1 / np.exp(theta[1])

        D = self.Theta.shape[1]
        N = self.Theta.shape[0]

        K = beta * np.dot(self.Theta.T, self.Theta)
        K += np.eye(self.Theta.shape[1]) * alpha
        try:
            K_inv = np.linalg.inv(K)
        except np.linalg.linalg.LinAlgError:
             K_inv = np.linalg.inv(K + np.random.rand(K.shape[0], K.shape[1]) * 1e-8)

        m = beta * np.dot(K_inv, self.Theta.T)
        m = np.dot(m, self.y)

        mll = D / 2 * np.log(alpha)
        mll += N / 2 * np.log(beta)
        mll -= N / 2 * np.log(2 * np.pi)
        mll -= beta / 2. * np.linalg.norm(self.y - np.dot(self.Theta, m), 2)
        mll -= alpha / 2. * np.dot(m.T, m)
        mll -= 0.5 * np.log(np.linalg.det(K) + 1e-10)

        if np.any(np.isnan(mll)):
            return -1e25
        return mll

    def negative_mll(self, theta):
        """
        Returns the negative marginal log likelihood (for optimizing it with scipy).

        Parameters
        ----------
        theta: np.array(2,)
            The hyperparameter alpha and beta on a log scale

        Returns
        -------
        float
            negative lnlikelihood + prior
        """
        nll = -self.marginal_log_likelihood(theta)
        return nll

    def iterate_minibatches(self, inputs, targets, batchsize, shuffle=False):
        assert inputs.shape[0] == targets.shape[0], \
            "The number of training points is not the same"
        if shuffle:
            indices = np.arange(inputs.shape[0])
            self.rng.shuffle(indices)
        for start_idx in range(0, inputs.shape[0] - batchsize + 1, batchsize):
            if shuffle:
                excerpt = indices[start_idx:start_idx + batchsize]
            else:
                excerpt = slice(start_idx, start_idx + batchsize)
            yield inputs[excerpt], targets[excerpt]

    @BaseModel._check_shapes_predict
    def predict(self, X_test):
        r"""
        Returns the predictive mean and variance of the objective function at
        the given test points.

        Parameters
        ----------
        X_test: np.ndarray (N, D)
            N input test points

        Returns
        ----------
        np.array(N,)
            predictive mean
        np.array(N,)
            predictive variance

        """
        # Normalize inputs
        if self.normalize_input:
            X_, _, _ = zero_mean_unit_var_normalization(X_test, self.X_mean, self.X_std)
        else:
            X_ = X_test

        # Get features from the net

        theta = self.network.basis_funcs(torch.Tensor(X_)).data.numpy()

        # Marginalise predictions over hyperparameters of the BLR
        mu = np.zeros([len(self.models), X_test.shape[0]])
        var = np.zeros([len(self.models), X_test.shape[0]])

        for i, m in enumerate(self.models):
            mu[i], var[i] = m.predict(theta)

        # See the algorithm runtime prediction paper by Hutter et al
        # for the derivation of the total variance
        m = np.mean(mu, axis=0)
        v = np.mean(mu ** 2 + var, axis=0) - m ** 2

        # Clip negative variances and set them to the smallest
        # positive float value
        if v.shape[0] == 1:
            v = np.clip(v, np.finfo(v.dtype).eps, np.inf)
        else:
            v = np.clip(v, np.finfo(v.dtype).eps, np.inf)
            v[np.where((v < np.finfo(v.dtype).eps) & (v > -np.finfo(v.dtype).eps))] = 0

        if self.normalize_output:
            m = zero_mean_unit_var_denormalization(m, self.y_mean, self.y_std)
            v *= self.y_std ** 2

        return m, v

    def get_incumbent(self):
        """
        Returns the best observed point and its function value

        Returns
        ----------
        incumbent: ndarray (D,)
            current incumbent
        incumbent_value: ndarray (N,)
            the observed value of the incumbent
        """

        inc, inc_value = super(DNGO, self).get_incumbent()
        if self.normalize_input:
            inc = zero_mean_unit_var_denormalization(inc, self.X_mean, self.X_std)

        if self.normalize_output:
            inc_value = zero_mean_unit_var_denormalization(inc_value, self.y_mean, self.y_std)

        return inc, inc_value


import flet as ft
from database import Base
from cal import FletCalendar
from cards import AnimatedCard
from datetime import datetime
import time

base = Base('C:/Users/Сашер/Desktop/base.sqlite')

def from_unix(time):
    return datetime.utcfromtimestamp(time).strftime('%d-%m-%Y')

def main(page: ft.Page):
    page.title = "Жижки у Насика"
    page.scroll = 'always'
    page.vertical_alignment = ft.MainAxisAlignment.CENTER
    page.update()

    def from_unix(time):
        return datetime.utcfromtimestamp(time).strftime('%d-%m-%Y')

    def get_data_from_sql(base: object, is_null: bool):
        if is_null:
            test_obj = base.cur.execute("SELECT * FROM Liquids")
        else:
            test_obj = base.cur.execute("SELECT * FROM Liquids WHERE amount > 0")
        arr = []
        for i in test_obj:
            arr.append(list(i))
        del test_obj

        table = []
        for i in arr:
            temp = []
            for j in i:
                temp.append(ft.DataCell(ft.Text(str(j))))
            table.append(ft.DataRow(cells=temp, on_long_press=long_press))

        page.update()

        return table

    def long_press(e):
        id = e.control.cells[0].content.value
        amount = e.control.cells[-1].content.value
        BottomPanel(page, id, amount)

    def get_base_template():

        def bs_dismissed(e):
            print("Dismissed!")

        def show_bs(e):
            bs.open = True
            bs.update()

        def close_bs(e):
            bs.open = False
            if all([i.value for i in [brand_field, type_field, price_field, amount_field]]):
                base.cur.execute(f"INSERT INTO Liquids VALUES (NULL,'{brand_field.value}', '{type_field.value}', {int(price_field.value)}, {int(amount_field.value)})")
                base.con.commit()
                page.controls.clear()
                page.add(get_base_template())
                page.update()
            bs.update()

        brand_field = ft.TextField(suffix_text='Производитель')
        type_field = ft.TextField(suffix_text='Вкус')
        price_field = ft.TextField(suffix_text='Цена')
        amount_field = ft.TextField(suffix_text='Кол-во')

        bs = ft.BottomSheet(
            ft.Container(
                ft.Column(
                    [
                        brand_field,
                        type_field,
                        price_field,
                        amount_field,
                        ft.ElevatedButton("Добавить", on_click=close_bs),
                    ],
                    tight=True,
                ),
                padding=10,
                width=840,
                height=600,
                alignment=ft.alignment.center
            ),
            open=False,
            on_dismiss=bs_dismissed,
        )
        page.overlay.append(bs)
        def template_object():
            base_template = ft.Container(
                        width=1280,
                        height=720,
                        content=ft.DataTable(columns=[
                            ft.DataColumn(ft.Text("ID")),
                            ft.DataColumn(ft.Text("Название")),
                            ft.DataColumn(ft.Text("Вкус")),
                            ft.DataColumn(ft.Text("Цена")),
                            ft.DataColumn(ft.Text("Кол-во")),
                        ],
                        rows=get_data_from_sql(base, True),)
                    )
            page.update()
            return base_template
        base_template = template_object()
        return ft.Column([ft.ElevatedButton('Добавить новый товар',on_click=show_bs, width=1280, height=50, bgcolor=ft.colors.GREEN_800),base_template])

    def BottomPanel(page: ft.Page, id, amount):
        page.vertical_alignment = ft.MainAxisAlignment.CENTER
        def bs_dismissed(e):
            print("Dismissed!")

        def show_bs(e):
            bs.open = True
            bs.update()

        def text_on_change(e):
            page.update()

        text = ft.TextField(value=f'{amount}', text_align=ft.TextAlign.RIGHT, on_change=text_on_change, width=100)

        def close_bs(e):

            bs.open = False
            print(text.value)
            base.cur.execute(f"UPDATE Liquids SET amount = {text.value} WHERE id = {id}")
            base.con.commit()
            page.controls.clear()
            page.add(get_base_template())
            bs.update()
            page.update()

        def increase(e):
            text.value = str(int(text.value) + 1)
            page.update()

        def decrease(e):
            text.value = str(int(text.value) - 1)
            page.update()

        def delete_elem(e):

            base.cur.execute(f"DELETE FROM Liquids WHERE id = {id}")
            base.con.commit()
            close_bs(e)

        inc_butt = ft.IconButton(icon=ft.icons.ARROW_LEFT, on_click=decrease)
        dec_butt = ft.IconButton(icon=ft.icons.ARROW_RIGHT, on_click=increase)
        del_button = ft.IconButton(icon=ft.icons.DELETE, bgcolor=ft.colors.RED_900, on_click=delete_elem)

        bs = ft.BottomSheet(
            ft.Container(
                ft.Column(
                    [
                        ft.Text(f"Редактировать кол-во: {id}"),
                        ft.Row([inc_butt, text, dec_butt, del_button]),
                        ft.ElevatedButton("Сохранить", on_click=close_bs),
                    ],
                    tight=True,
                    alignment=ft.alignment.center_right
                ),
                padding=10,
                width=700,
                height=200,
                alignment=ft.alignment.center_right

            ),
            open=True,
            on_dismiss=bs_dismissed,

        )
        page.overlay.append(bs)
        page.add(ft.ElevatedButton("Display bottom sheet", on_click=show_bs, visible=False))

    def get_date():
        return str(datetime.today().month)+ '-' + str(datetime.today().day) + '-' + str(datetime.today().year)

    task_date = ft.TextField(suffix_text='Дата', value=get_date())
    daily_task = ft.TextField(suffix_text='Заметка')

    def close_dlg(e: object):

        def save_task(date, text):
            with open(f'daily/{date}.txt', 'w', encoding='utf-8') as file:
                file.write(text)
                file.close()

        dlg.open = False
        save_task(task_date.value, daily_task.value)
        page.update()

    dlg = ft.AlertDialog(
        title=ft.Text('Добавление новой записи'), on_dismiss=close_dlg,
        content=ft.Column([task_date, daily_task, ft.ElevatedButton('Сохранить', on_click=close_dlg)])
    )

    def open_dlg(e):
        page.dialog = dlg
        dlg.open = True
        page.update()

    def change_content(e):

        page.controls.clear()
        nav_dest = e.control.selected_index

        if nav_dest == 0:

            class State:
                toggle = True

            s = State()

            chart_data_raw = list(base.cur.execute("SELECT * FROM Transactions"))
            bar_pos = list(set([i[2] for i in chart_data_raw]))
            print(bar_pos)
            print(chart_data_raw)

            data_0 = []

            data_1 = [
                ft.LineChartData(
                    data_points=[
                        ft.LineChartDataPoint(1, 1),
                        ft.LineChartDataPoint(3, 1.5),
                        ft.LineChartDataPoint(5, 1.4),
                        ft.LineChartDataPoint(7, 3.4),
                        ft.LineChartDataPoint(10, 2),
                        ft.LineChartDataPoint(12, 2.2),
                        ft.LineChartDataPoint(13, 1.8),
                    ],
                    stroke_width=8,
                    color=ft.colors.LIGHT_GREEN,
                    curved=True,
                    stroke_cap_round=True,
                ),
                ft.LineChartData(
                    data_points=[
                        ft.LineChartDataPoint(1, 1),
                        ft.LineChartDataPoint(3, 2.8),
                        ft.LineChartDataPoint(7, 1.2),
                        ft.LineChartDataPoint(10, 2.8),
                        ft.LineChartDataPoint(12, 2.6),
                        ft.LineChartDataPoint(13, 3.9),
                    ],
                    color=ft.colors.PINK,
                    below_line_bgcolor=ft.colors.with_opacity(0, ft.colors.PINK),
                    stroke_width=8,
                    curved=True,
                    stroke_cap_round=True,
                ),
                ft.LineChartData(
                    data_points=[
                        ft.LineChartDataPoint(1, 2.8),
                        ft.LineChartDataPoint(3, 1.9),
                        ft.LineChartDataPoint(6, 3),
                        ft.LineChartDataPoint(10, 1.3),
                        ft.LineChartDataPoint(13, 2.5),
                    ],
                    color=ft.colors.CYAN,
                    stroke_width=8,
                    curved=True,
                    stroke_cap_round=True,
                ),
            ]

            data_2 = [
                ft.LineChartData(
                    data_points=[
                        ft.LineChartDataPoint(1, 1),
                        ft.LineChartDataPoint(3, 4),
                        ft.LineChartDataPoint(5, 1.8),
                        ft.LineChartDataPoint(7, 5),
                        ft.LineChartDataPoint(10, 2),
                        ft.LineChartDataPoint(12, 2.2),
                        ft.LineChartDataPoint(13, 1.8),
                    ],
                    stroke_width=4,
                    color=ft.colors.with_opacity(0.5, ft.colors.LIGHT_GREEN),
                    stroke_cap_round=True,
                ),
                ft.LineChartData(
                    data_points=[
                        ft.LineChartDataPoint(1, 1),
                        ft.LineChartDataPoint(3, 2.8),
                        ft.LineChartDataPoint(7, 1.2),
                        ft.LineChartDataPoint(10, 2.8),
                        ft.LineChartDataPoint(12, 2.6),
                        ft.LineChartDataPoint(13, 3.9),
                    ],
                    color=ft.colors.with_opacity(0.5, ft.colors.PINK),
                    below_line_bgcolor=ft.colors.with_opacity(0.2, ft.colors.PINK),
                    stroke_width=4,
                    curved=True,
                    stroke_cap_round=True,
                ),
                ft.LineChartData(
                    data_points=[
                        ft.LineChartDataPoint(1, 3.8),
                        ft.LineChartDataPoint(3, 1.9),
                        ft.LineChartDataPoint(6, 5),
                        ft.LineChartDataPoint(10, 3.3),
                        ft.LineChartDataPoint(13, 4.5),
                    ],
                    color=ft.colors.with_opacity(0.5, ft.colors.CYAN),
                    stroke_width=4,
                    stroke_cap_round=True,
                ),
            ]

            chart = ft.LineChart(
                data_series=data_1,
                border=ft.Border(
                    bottom=ft.BorderSide(4, ft.colors.with_opacity(0.5, ft.colors.ON_SURFACE))
                ),
                left_axis=ft.ChartAxis(
                    labels=[
                        ft.ChartAxisLabel(
                            value=1,
                            label=ft.Text("1m", size=14, weight=ft.FontWeight.BOLD),
                        ),
                        ft.ChartAxisLabel(
                            value=2,
                            label=ft.Text("2m", size=14, weight=ft.FontWeight.BOLD),
                        ),
                        ft.ChartAxisLabel(
                            value=3,
                            label=ft.Text("3m", size=14, weight=ft.FontWeight.BOLD),
                        ),
                        ft.ChartAxisLabel(
                            value=4,
                            label=ft.Text("4m", size=14, weight=ft.FontWeight.BOLD),
                        ),
                        ft.ChartAxisLabel(
                            value=5,
                            label=ft.Text("5m", size=14, weight=ft.FontWeight.BOLD),
                        ),
                        ft.ChartAxisLabel(
                            value=6,
                            label=ft.Text("6m", size=14, weight=ft.FontWeight.BOLD),
                        ),
                    ],
                    labels_size=40,
                ),
                bottom_axis=ft.ChartAxis(
                    labels=[
                        ft.ChartAxisLabel(
                            value=2,
                            label=ft.Container(
                                ft.Text(
                                    "SEP",
                                    size=16,
                                    weight=ft.FontWeight.BOLD,
                                    color=ft.colors.with_opacity(0.5, ft.colors.ON_SURFACE),
                                ),
                                margin=ft.margin.only(top=10),
                            ),
                        ),
                        ft.ChartAxisLabel(
                            value=7,
                            label=ft.Container(
                                ft.Text(
                                    "OCT",
                                    size=16,
                                    weight=ft.FontWeight.BOLD,
                                    color=ft.colors.with_opacity(0.5, ft.colors.ON_SURFACE),
                                ),
                                margin=ft.margin.only(top=10),
                            ),
                        ),
                        ft.ChartAxisLabel(
                            value=12,
                            label=ft.Container(
                                ft.Text(
                                    "DEC",
                                    size=16,
                                    weight=ft.FontWeight.BOLD,
                                    color=ft.colors.with_opacity(0.5, ft.colors.ON_SURFACE),
                                ),
                                margin=ft.margin.only(top=10),
                            ),
                        ),
                    ],
                    labels_size=32,
                ),
                tooltip_bgcolor=ft.colors.with_opacity(0.8, ft.colors.BLUE_GREY),
                min_y=0,
                max_y=4,
                min_x=0,
                max_x=14,
                animate=100,
                expand=True,
            )

            def toggle_data(e):
                if s.toggle:
                    chart.data_series = data_2
                    chart.data_series[2].point = True
                    chart.max_y = 6
                    chart.interactive = False
                else:
                    chart.data_series = data_1
                    chart.max_y = 4
                    chart.interactive = True
                s.toggle = not s.toggle
                chart.update()

            page.add(ft.IconButton(ft.icons.REFRESH, on_click=toggle_data), ft.Container(content=chart, height=500))

        if nav_dest == 1:
            res = list(base.cur.execute(f"SELECT * FROM Reservation WHERE reservationUntil >= {int(time.time())}"))

            #nav_content = ft.Row([ft.Containerinf for inf ])
            print(res)
            nav_content = ft.Row([ft.Container(content=ft.Row([AnimatedCard(*inf)])) for inf in res])
            #nav_content = ft.Container(
                #content=ft.Row([AnimatedCard(*res[0])])
            #)
            page.add(nav_content)

        if nav_dest == 2:
            nav_content = get_base_template()
            page.add(nav_content)

        if nav_dest == 3:
            cal = FletCalendar(page)
            nav_content = ft.Container(
                content= ft.Column([cal, ft.ElevatedButton(text='Добавить запись', on_click=open_dlg)])
            )
            page.add(nav_content, cal.output)

    page.navigation_bar = ft.NavigationBar(
        destinations=[
            ft.NavigationDestination(
                icon=ft.icons.BAR_CHART_OUTLINED,
                selected_icon=ft.icons.BAR_CHART,
                label="График"
            ),
            ft.NavigationDestination(
                icon=ft.icons.SHOP_2_OUTLINED,
                selected_icon = ft.icons.SHOP_2,
                label="Витрина"
            ),
            ft.NavigationDestination(
                icon=ft.icons.DATA_OBJECT_OUTLINED,
                selected_icon=ft.icons.DATA_OBJECT,
                label="Редактировать базу"
            ),
            ft.NavigationDestination(
                icon=ft.icons.CALENDAR_VIEW_DAY_OUTLINED,
                selected_icon=ft.icons.CALENDAR_VIEW_DAY,
                label='Календарь',
            )
        ],
        on_change=change_content,
        selected_index=0
    )

    # a control's did_mount() is invoked right after it has been mounted
    page.navigation_bar.did_mount = lambda: synthetic_event(
        page=page, control=page.navigation_bar
    )

    # call the did_mount() once manually if you mess up the order of page.update()
    # page.navigation_bar.did_mount()
    page.update()

def synthetic_event(page: ft.Page, control: ft.NavigationBar):
    """
    Calls the control's event handler
    """
    control.on_change(
        ft.ControlEvent(
            target=control.uid,
            name="change",
            data=str(control.selected_index),
            control=control,
            page=page
        )
    )

ft.app(target=main)
base.con.close()


from django.shortcuts import render, HttpResponseRedirect
from .forms import UserRegistration
from .models import User

# Create your views here.
def index(request):
    if request.method == 'POST':
        fm = UserRegistration(request.POST)
        if fm.is_valid():
            number = fm.cleaned_data['number']
            firstname = fm.cleaned_data['firstname']
            lastname = fm.cleaned_data['lastname']
            birtday = fm.cleaned_data['birtday']
            language = fm.cleaned_data['language']
            country = fm.cleaned_data['country']
            reg = User(
                number=number, firstname=firstname, lastname=lastname,
                birtday=birtday, language=language, country=country)
            reg.save()
            fm = UserRegistration()
    else:
        fm = UserRegistration()
    stud = User.objects.all()

    return render(request, 'index.html', {
        'form': fm, 'stu':stud
    })

def update(request, id):
    if request.method == 'POST':
        pi = User.objects.get(pk=id)
        fm = UserRegistration(request.POST, instance=pi)
        if fm.is_valid():
            fm.save()
    else:
        pi = User.objects.get(pk=id)
        fm = UserRegistration(instance=pi)

    return render(request, 'update.html', {
        'form': fm
    })

def delete(request, id):
    if request.method == 'POST':
        pi = User.objects.get(pk=id)
        pi.delete()

    return HttpResponseRedirect('/')


import yaml

class CFG:
    def __init__(self, yaml_path):
        if isinstance(yaml_path, str):
            with open(yaml_path, "r") as f:
                yaml_data = yaml.safe_load(f)
        else:
            yaml_data = yaml_path

        for key, value in yaml_data.items():
            if isinstance(value, dict):
                setattr(self, key, CFG(value))
            else:
                setattr(self, key, value)

def get_config(file):
    cfg = CFG(file)
    return cfg

if __name__ == '__main__':
    cfg = get_config("./configs/PRE_CONT_UBFC.yaml")
    print(cfg)


import os
import time
import argparse
import json

import torch
import torch.nn as nn
import torch.optim as optim
# import torch.nn.functional as F
import torch.backends.cudnn as cudnn

import utils
import models
import data_loader

__all_models__ = [
    "VGG", "ResNet", "DenseNet", "ResNeXt", "MobileNet", "DPN", "EfficientNet"
    ]

def config_net(net_name="VGG"):
    assert net_name in __all_models__, "Unimplemented architecture"
    if net_name == "VGG":
        return models.VGG("VGG19")
    elif net_name == "ResNet":
        return models.ResNet18()
    elif net_name == "ResNeXt":
        return models.ResNeXt29_2x64d()
    elif net_name == "MobileNet":
        return models.MobileNetV2()
    elif net_name == "DenseNet":
        return models.DenseNet121()
    elif net_name == "DPN":
        return models.DPN92()
    elif net_name == "EfficientNet":
        return models.EfficientNetB0()

def _save_makedirs(dir_path):
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)

def main(args):
    # Set CUDA GPU
    os.environ["CUDA_VISIBLE_DEVICES"] = \
        ','.join(str(gpu) for gpu in args.visible_gpus)
    device = "cuda" if torch.cuda.is_available() else "cpu"

    # Set network
    net = config_net(args.net_name)
    net = net.to(device)
    if device == 'cuda':
        net = torch.nn.DataParallel(net)
        cudnn.benchmark = True

    # Set loss and optimizer
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(net.parameters(), lr=args.lr)
    # optimizer = optim.SGD(
    #     net.parameters(), lr=args.lr,
    #     momentum=0.9, weight_decay=5e-4)

    # Data loader
    print("Constructing data loader ...")
    data_dir = args.data_dir
    train_loader, valid_loader = data_loader.get_train_valid_loader(
        data_dir=data_dir,
        batch_size=128,
        augment=True,
        random_seed=20,
        valid_size=0.1,
        shuffle=True,
        num_workers=4,
        pin_memory=True
    )

    # Training processes
    epochs = args.epochs
    history = {"acc": [0.0] * epochs,
               "loss": [0.0] * epochs,
               "val_acc": [0.0] * epochs,
               "val_loss": [0.0] * epochs
               }

    ckpt_dir = os.path.join(args.ckpt_dir, args.net_name)
    _save_makedirs(ckpt_dir)
    best_val_acc = 0.0
    for epoch in range(epochs):
        epoch_start_time = time.time()
        train_loss = 0
        correct = 0
        total = 0
        # Training
        net.train()
        for batch_idx, (inputs, targets) in enumerate(train_loader):
            inputs, targets = inputs.to(device), targets.to(device)
            optimizer.zero_grad()
            outputs = net(inputs)
            loss = criterion(outputs, targets)
            loss.backward()
            optimizer.step()

            train_loss += loss.item()
            _, predicted = outputs.max(1)
            total += targets.size(0)
            correct += predicted.eq(targets).sum().item()

            utils.progress_bar(
                batch_idx,
                len(train_loader),
                "Loss: %.3f | Acc: %.3f%% (%d/%d)"
                % (train_loss/(batch_idx+1),
                   100.*correct/total, correct, total)
                )

        # Validation
        val_loss = 0
        val_correct = 0
        val_total = 0
        net.eval()
        for batch_idx, (inputs, targets) in enumerate(valid_loader):
            inputs, targets = inputs.to(device), targets.to(device)
            outputs = net(inputs)
            loss = criterion(outputs, targets)

            val_loss += loss.item()
            _, predicted = outputs.max(1)
            val_total += targets.size(0)
            val_correct += predicted.eq(targets).sum().item()

        train_acc = 100. * correct / total
        train_loss /= train_loader.__len__()
        val_acc = 100. * val_correct / val_total
        val_loss /= valid_loader.__len__()
        print("[%03d/%03d] %2.2f sec(s)"
              " Train Acc: %3.6f Loss: %3.6f | Val Acc: %3.6f loss: %3.6f" %
              (epoch + 1, epochs,
               time.time() - epoch_start_time,
               train_acc, train_loss, val_acc, val_loss
               ))

        history["acc"][epoch] = train_acc
        history["loss"][epoch] = train_loss
        history["val_acc"][epoch] = val_acc
        history["val_loss"][epoch] = val_loss

        # Save model checkpoints
        if val_acc > best_val_acc:
            best_val_acc = val_acc
            state = {
                'net': net.state_dict(),
                'acc': train_acc,
                'val_acc': val_acc,
                'epoch': epoch,
            }
            torch.save(
                state,
                os.path.join(ckpt_dir, "model_{:03}.pth".format(epoch+1))
                )

    # Save training history
    with open(os.path.join(ckpt_dir, "history.json"), 'w') as opf:
        json.dump(history, opf)

    # end

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="PyTorch CIFAR10 Training")

    parser.add_argument(
            "--visible_gpus",
            type=int,
            nargs='+',
            default=[0],
            help="CUDA visible gpus")

    parser.add_argument(
            "--ckpt_dir",
            type=str,
            default="./checkpoint")

    parser.add_argument(
            "--data_dir",
            type=str,
            default="../data")

    parser.add_argument(
            "--lr",
            type=float,
            default=1e-2,
            help="learning rate")

    parser.add_argument(
            "--net_name",
            type=str,
            default="VGG")

    parser.add_argument(
            "--epochs",
            type=int,
            default=100,
            help="training epochs")

    args = parser.parse_args()

    main(args)


from mutagen.easyid3 import EasyID3
import mutagen
import shutil
from os import listdir
from os.path import  join, isfile, isdir
import re
import os
# audio = EasyID3("AlbumEditor/03 Sam Concepcion, Tippy Dos Santos and Quest Dati Official Music Video Philpop 2013.mp3")
# audio['title'] = u"Example Title2"
# audio['album'] = u"My album"
# print(audio['title'])
# print(audio)
# audio.save()

# shutil.move("AlbumEditor/test1.mp3", "AlbumEditor/moved")

class PolishMp3():
    def __init__(self, album=None, artist=None):
        self.baseDir = "AlbumEditor/Rawmp3"
        # self.baseDir = "/Users/nhoj/Desktop/audios/musicdesktop/classic"
        self.MoveDir = "AlbumEditor/ReadyToExportmp3"
        # self.MoveDir = "/Volumes/version2/Third/Visual Studio Code /Python/audioConvert/AlbumEditor/moved   "
        print(self.baseDir)
        print('\n\n')
        self.album = album
        self.artist = artist
        self.getList()

    def getList(self):

        with os.scandir(self.baseDir) as entries:
            for entry in entries:
                if isfile(entry):
                    # os.system('chflags nouchg {}'.format(entry.path))
                    print('Done\n\n')
                    try:
                        print('YES')
                        print(self.baseDir)
                        print(entry.path)
                        # self.checkIfLocked(entry.name)
                        self.checkIfLocked(entry)
                        print('Done Checking Locked Status',entry.name)
                        audio = EasyID3(entry.path)
                        # audio['title'] =  ''.join([i for i in entry.name[:-4] if not i.isdigit()]).lstrip(' ')
                        # audio['title'] =  ''.join([i for i in re.sub("\s\s+", " ",re.sub('[^a-zA-Z0-9 \n\.]', ' ', entry.name[:-4])) if not i.isdigit()]).lstrip(' ').rstrip()
                        audio['title'] =  ''.join([i for i in re.sub("\s\s+", " ",re.sub(r'[^a-zA-Z0-9 \n\.]', ' ', entry.name[:-4])) if not i.isdigit()]).lstrip(' ').rstrip()
                        if self.album is not None:
                            audio['album'] = self.album
                        else:
                            audio['album'] = 'From Lenovo'
                        # audio['artist'] = 'Old Laptop'
                        if self.artist is not None:
                            audio['albumartist'] = self.artist
                        else:
                            audio['albumartist'] = 'Lenovo'
                        audio.save()
                        old_file = os.path.join(entry.path)
                        new_file = os.path.join(self.MoveDir, audio['title'][0]+entry.name[-4::])
                        os.rename(old_file, new_file)
                        print(audio['title'][0])
                        print(audio)

                    except Exception as e:

                        print('Fail')
                        print(e,'\n\n')
                        pass
                print(entry)
                print('\n')

    def checkIfLocked(self,locked_filename):
        print('checking.....',locked_filename)
        print('Dir: ',self.baseDir)
        print("TYPE: ",type(locked_filename))

        # x= os.stat(self.baseDir+'/'+locked_filename).st_flags
        try:
            x= os.stat(locked_filename).st_flags
            print('FIles is Locked: ' ,x)
            # os.stat(locked_filename).st_flags=0
            # print(os.stat(locked_filename).__format__)
            xx = os.system('chflags nouchg {}'.format(locked_filename))
        except Exception as e:
            print("Fail to Check")
            # print(e)
            pass
        # xx = os.system('chflags nouchg {}'.format(self.baseDir+'/'+locked_filename))
        print('Unlocked',os.stat(locked_filename).st_flags)

    def moveMp3(self,fileToMove):
        # shutil.move(fileToMove,self.MoveDir)
        shutil.copy(fileToMove,self.MoveDir)

PolishMp3('My First Album', 'Me Myself and I')


"""
预处理
预测未完待续...
"""

import paddle
import cv2
import skimage.measure as measure
import numpy as np

licence_plate=cv2.imread('./car_licence_test.png')

# h,w,c=licence_plate.shape
# print(h,w,c,licence_plate.shape)
# cv2.imshow('car licence',licence_plate)
# cv2.waitKey(0)

#预处理
#灰度化
gray_plate=cv2.cvtColor(licence_plate,cv2.COLOR_RGB2GRAY)
# cv2.imshow('gary',gray_plate)
# cv2.waitKey(0)

#二值化
ret,binary_plate=cv2.threshold(gray_plate,175,255,cv2.THRESH_BINARY)
# print(binary_plate.shape)
# cv2.imshow('binary',binary_plate)
# print('thresold value',ret)
# cv2.waitKey(0)

labels,labels_num=measure.label(binary_plate,return_num=True,connectivity=2)
print(labels.shape,labels_num)
# print(np.unique(labels))

dst=np.zeros_like(licence_plate,dtype='uint8')

# print((labels==1).shape)
for label in np.unique(labels):
    if label==0:
        continue

    # [b,g,r]=np.random.randint(0,256,size=(3))
    # dst[:,:,0][labels==label],dst[:,:,1][labels==label],dst[:,:,2][labels==label]=[b,g,r]
    dst[:,:,0][labels==label],dst[:,:,1][labels==label],dst[:,:,2][labels==label]=np.random.randint(0,256,size=(3))

    cv2.imshow('dst',dst)
    cv2.waitKey(1000)
    # break

# cv2.imshow('dst',dst)
cv2.waitKey(0)


"""Main entry point."""
import logging
from argparse import ArgumentParser, Namespace
from os import path
from shutil import rmtree

from beku.kuttl import renderer_from_file, expand
from .version import __version__

def parse_cli_args() -> Namespace:
    """Parse command line args."""
    parser = ArgumentParser(
        description="Kuttl test expander for the Stackable Data Platform")
    parser.add_argument(
        "-v",
        "--version",
        help="Display application version",
        action='version',
        version=f'%(prog)s {__version__}'
    )

    parser.add_argument(
        "-i",
        "--test_definition",
        help="Test definition file.",
        type=str,
        required=False,
        default="tests/test-definition.yaml",
    )
    parser.add_argument(
        "-t",
        "--template_dir",
        help="Folder with test templates.",
        type=str,
        required=False,
        default="tests/templates/kuttl",
    )
    parser.add_argument(
        "-o",
        "--output_dir",
        help="Output folder for the expanded test cases.",
        type=str,
        required=False,
        default="tests/_work",
    )

    parser.add_argument(
        "-l",
        "--log_level",
        help="Set log level.",
        type=str,
        required=False,
        choices=["debug", "info"],
        default="info",
    )

    parser.add_argument(
        "-k",
        "--kuttl_test",
        help="Kuttl test suite definition file.",
        type=str,
        required=False,
        default="tests/kuttl-test.yaml.jinja2",
    )

    parser.add_argument(
        "-s",
        "--suite",
        help="Name of the test suite to expand. Default: default",
        type=str,
        required=False,
        default="default",
    )

    return parser.parse_args()

def _cli_log_level(cli_arg: str) -> int:
    if cli_arg == "debug":
        return logging.DEBUG
    return logging.INFO

def main() -> int:
    """Main"""
    cli_args = parse_cli_args()
    logging.basicConfig(
        encoding="utf-8", level=_cli_log_level(cli_args.log_level))
    effective_test_suites = renderer_from_file(cli_args.test_definition)
    rmtree(path=cli_args.output_dir, ignore_errors=True)
    # Compatibility warning: add 'tests' to output_dir
    output_dir = path.join(cli_args.output_dir, "tests")
    return expand(cli_args.suite, effective_test_suites, cli_args.template_dir, output_dir, cli_args.kuttl_test)


import json
import pickle

survey_list = []

while True:
    name = input("What is your name?: ")
    fav_band = input("What is your favorite band?: ")
    fav_artist = input("Who is your favorite solo artist?: ")
    fav_genre = input("What is your favorite genre of music?: ")

    survey_dict = {}

    survey_dict['name'] = name
    survey_dict['band'] = fav_band
    survey_dict['artist'] = fav_artist
    survey_dict['genre'] = fav_genre

    survey_list.append(survey_dict)
    f = open("survey.json", "w")
    dictionarytoJson = json.dumps(survey_dict)
    json.dump(dictionarytoJson, f)
    print(dictionarytoJson)
    f.close()

    people = input("Is there another person?: ")
    if people == "yes" or people == "Yes":
        continue
    else:
        break


#-*- coding: UTF-8 -*-
from pynput import keyboard

from utils.keycodeutil import KeyCodeUtil
from threading import Thread
from queue import Queue

class KeyboardInterceptor(Thread):
    MSG_PRESS = 256
    MSG_PRESS_WITH_ALT = 260
    MSG_RELEASE_WITH_ALT = 261
    MSG_RELEASE = 257
    VK_BACKSLASH = 220
    # 所有有效键位
    keySet = {'a','h','j','k','l','i','o','y','p','1','2','3','4','5','6','7','8','9','0','d','e','w','r','f','c','v','shift_l','shift_r','alt','f1'}
    # 持续生效按键
    continuousSet = {'h','j','k','l','1','2','3','4','5','r','f','space','shift_l','shift_r'}
    # 按下触发键位
    pressTriggerSet = {'a','v','y','c','p','u','6','7','8','9','0'}
    # 首尾触发键位
    headTailTriggerSet = {'i','o','e','w','d'}
    #透传按键
    ignoreKeySet = {keyboard.Key.alt_l,keyboard.Key.ctrl_l,keyboard.Key.ctrl_r,keyboard.Key.enter,keyboard.Key.tab,keyboard.Key.backspace,keyboard.Key.home,keyboard.Key.end,keyboard.Key.insert,keyboard.Key.up,keyboard.Key.down,keyboard.Key.left,keyboard.Key.right}
    ignoreVKSet = None
    switchKeyMap = {'v':False}
    checkedSize = 0
    pressSet = set()
    actionQueue = None
    listener = None
    enable = False
    justEnable = False
    altLPressed = False
    ctrlPressed = False

    def __init__(self,  actionQueue: Queue):
        Thread.__init__(self)
        self.actionQueue = actionQueue
        self.ignoreVKSet = KeyCodeUtil.keys2Vks(self.ignoreKeySet)

    def run(self):
        with keyboard.Listener(win32_event_filter=self.filter, suppress=False) as self.listener:
            print('interceptor start')
            self.listener.join()

    def stop(self):
        self.actionQueue.put('_EXIT_')
        self.listener.stop()

    def filter(self,msg,data):
        # print('filter enable: %s, msg: %s, vkCode: %s, scanCode: %s, flags: %s, time: %s, dwExtraInfo: %s' % (self.enable, msg, data.vkCode, data.scanCode, data.flags, data.time, data.dwExtraInfo))
        if data.vkCode == KeyCodeUtil.key2Vk(keyboard.Key.alt_l) and msg == self.MSG_PRESS_WITH_ALT:
            self.altLPressed = True
        if data.vkCode == KeyCodeUtil.key2Vk(keyboard.Key.alt_l) and msg == self.MSG_RELEASE:
            self.altLPressed = False
        if data.vkCode == self.VK_BACKSLASH and msg == self.MSG_RELEASE_WITH_ALT and self.altLPressed == True:
            self.enable = not self.enable
            if self.enable:
                self.justEnable = True
            if self.controller != None:
               self.controller.updateUIStatus()
            #     self.listener.suppress_event()
        if data.vkCode == KeyCodeUtil.key2Vk(keyboard.Key.tab) and (msg == self.MSG_PRESS_WITH_ALT or msg == self.MSG_RELEASE_WITH_ALT) and self.altLPressed == True:
            return
        if not self.enable:
            return
        if self.justEnable and data.vkCode == KeyCodeUtil.key2Vk(keyboard.Key.alt_l) and msg == self.MSG_RELEASE:
            self.justEnable = False
            return

        if data.vkCode == KeyCodeUtil.key2Vk(keyboard.Key.ctrl_l) and msg == self.MSG_PRESS:
            self.ctrlPressed = True
        if data.vkCode == KeyCodeUtil.key2Vk(keyboard.Key.ctrl_l) and msg == self.MSG_RELEASE:
            self.ctrlPressed = False
        if self.ctrlPressed:
            return
        if (data.vkCode != KeyCodeUtil.key2Vk(keyboard.Key.ctrl_l) and data.vkCode not in self.ignoreVKSet and (msg == self.MSG_PRESS or msg == self.MSG_PRESS_WITH_ALT)):
            # print('vk2Char: %s -> %s' % (data.vkCode, KeyCodeUtil.vk2Char(data.vkCode)))
            self.on_press(KeyCodeUtil.vk2Char(data.vkCode))
            self.listener.suppress_event()
        elif (data.vkCode != KeyCodeUtil.key2Vk(keyboard.Key.ctrl_l) and data.vkCode not in self.ignoreVKSet and (msg == self.MSG_RELEASE or msg == self.MSG_RELEASE_WITH_ALT)):
            # print('vk2Char: %s -> %s' % (data.vkCode, KeyCodeUtil.vk2Char(data.vkCode)))
            self.on_release(KeyCodeUtil.vk2Char(data.vkCode))
            self.listener.suppress_event()

    def on_press(self, key):
        if key in self.continuousSet or key in self.headTailTriggerSet:
            self.actionQueue.put('_P_'+key)
        elif key in self.pressTriggerSet:
            if key not in self.switchKeyMap:
                self.actionQueue.put('_P_'+key)
            else:
                self.switchKeyMap[key] = not self.switchKeyMap[key]
                switchKey = '_O_' + key if self.switchKeyMap[key] else '_C_' + key
                self.actionQueue.put(switchKey)

    def on_release(self,key):
        if key in self.continuousSet or key in self.headTailTriggerSet:
            self.actionQueue.put('_R_'+key)
            self.pressSet.discard(key)


import pandas as pd
import numpy as np
import os
import re
import glob
from pathlib import Path
import chardet
from datetime import datetime

# EXTRACCIÓN

def importar(path):
    # Esta función importa archivos en múltiples formatos, teniendo en cuenta que si el archivo es formato xlsx
    # puede contener varias hojas con tablas. Además, si el archivo trata sobre relevamiento de precios, crea una
    # columna en la cual indica la fecha en la que se realizo el relevamiento extrayendo el valor del nombre del
    # archivo, el objetivo de esto es tener una referencia para hacer cargas incrementales.

    data = pd.DataFrame()
    with open(path, 'rb') as f:
        result = chardet.detect(f.read()) # Obtener encoding del archivo

        # IMPORTAR ARCHIVOS

        # csv
        if Path(path).suffix == '.csv':
            data = pd.read_csv(path, encoding=result['encoding'], sep=',', engine='python', decimal='.')

            data_texto = os.path.split(path)[1].split('.')[0] # Extraer el texto del cual se sacará la fecha (nombre de archivo)

            auxiliar = data_texto.split('_') # Secciono el nombre del archivo
            auxiliar = list(set(auxiliar))  # Creo una lista con los elementos únicos del nombre del archivo

            for e in auxiliar:

                if e.isdigit() == True: # Determino si en el nombre del archivo hay dígitos referentes a la fecha
                    data['fecha_semana'] = datetime.strptime(e, '%Y%m%d') # Creo la columna "fecha_semana" para tener la referencia de cuando
                                                                          # se hizo el relevamiento del precio
                else:
                    data = data

        # txt
        elif Path(path).suffix == '.txt':
            data = pd.read_table(path, encoding=result['encoding'], sep='|', engine='python')
            data_texto = os.path.split(path)[1].split('.')[0] # Extraer el texto del cual se sacará la fecha

            auxiliar = data_texto.split('_') # Secciono el nombre del archivo
            auxiliar = list(set(auxiliar))  # Creo una lista con los elementos únicos del nombre del archivo

            for e in auxiliar:

                if e.isdigit() == True: # Determino si en el nombre del archivo hay dígitos referentes a la fecha
                    data['fecha_semana'] = datetime.strptime(e, '%Y%m%d') # Creo la columna "fecha_semana" para tener la referencia de cuando
                                                                          # se hizo el relevamiento del precio
                else:
                    data = data

        # json
        elif Path(path).suffix == '.json':
            data = pd.read_json(path, encoding=result['encoding'], precise_float=True)
            data_texto = os.path.split(path)[1].split('.')[0] # Extraer el texto del cual se sacará la fecha

            auxiliar = data_texto.split('_') # Secciono el nombre del archivo
            auxiliar = list(set(auxiliar))  # Creo una lista con los elementos únicos del nombre del archivo

            for e in auxiliar:

                if e.isdigit() == True: # Determino si en el nombre del archivo hay dígitos referentes a la fecha
                    data['fecha_semana'] = datetime.strptime(e, '%Y%m%d') # Creo la columna "fecha_semana" para tener la referencia de cuando
                                                                          # se hizo el relevamiento del precio
                else:
                    data = data

        # parquet
        elif Path(path).suffix == '.parquet':

            data = pd.read_parquet(path, engine='pyarrow')
            data_texto = os.path.split(path)[1].split('.')[0].split('.')[0] # Extraer el texto del cual se sacará la fecha

            auxiliar = data_texto.split('_') # Secciono el nombre del archivo
            auxiliar = list(set(auxiliar))  # Creo una lista con los elementos únicos del nombre del archivo

            for e in auxiliar:

                if e.isdigit() == True: # Determino si en el nombre del archivo hay dígitos referentes a la fecha
                    data['fecha_semana'] = datetime.strptime(e, '%Y%m%d') # Creo la columna "fecha_semana" para tener la referencia de cuando
                                                                          # se hizo el relevamiento del precio
                else:
                    data = data

        # xlsx
        elif Path(path).suffix == '.xlsx':
            dict_aux = pd.read_excel(path, sheet_name=None) # Diccionario donde key: nombre de hoja , values: df con valores del archivo
            lst_df = []
            for key in dict_aux.keys():                     # Agrego los df a una lista

                data_fecha = key.split('_')[-1] # fecha semana de relevamiento

                if data_fecha in key:

                    df = dict_aux[key]
                    df['fecha_semana'] = datetime.strptime(data_fecha, '%Y%m%d') # Creo la columna "fecha_semana" para tener la referencia de cuando
                                                                                # se hizo el relevamiento del precio
                    lst_df.append(df)

                else:
                    df = dict_aux[key]
                    lst_df.append(df)

            data = pd.concat(lst_df, axis=0)   # Concateno los df que contiene la lista

            for col in data.columns:
                if 'fecha_semana' in col:
                    data = data.sort_values('fecha_semana')

            data.reset_index(drop=True, inplace = True)

    return data

# TRANSFORMACIÓN

# El parámetro a pasar a la función es un diccionario de dataframes

def transformacion(dicc_df):

    # REGISTROS DUPLICADOS:

    # Bucle para eliminar los resgistros duplicados
    for key in dicc_df.keys():
        dicc_df[key].drop_duplicates(inplace = True)

    # VALORES FALTANTES:

    # Bucle para eliminar las columnas categoria del dataframe producto
    for key in dicc_df.keys():
        if 'producto' in key:
            for col in dicc_df[key].columns:
                if 'categoria' in col:
                    dicc_df[key].drop(columns = col, inplace = True)

    # Hay datos de precios con valores iguales a '' los cuales deberán reemplazarse por np.nan para ser tratados como los demás valores faltantes
    # Reemplazo los valores '' por np.nan
    for key in dicc_df.keys():
        if 'precio' in key:
            for col in dicc_df[key].columns:
                if 'precio' in col:
                    dicc_df[key][col].replace('', np.nan, inplace = True)

    # Bucle para eliminar los registros con valores faltantes
    for key in dicc_df.keys():
        dicc_df[key].dropna(inplace = True)

    # NORMALIZACIÓN

    # Reemplazo id por producto_id en el df producto
    for key in dicc_df.keys():
        if 'producto' in key:
            for col in dicc_df[key].columns:
                if col == 'id':
                    dicc_df[key].rename(columns = {col:'producto_id'}, inplace = True)

    # Reemplazo id por sucursal_id en el df sucursal
    for key in dicc_df.keys():
        if 'sucursal' in key:
            for col in dicc_df[key].columns:
                if col == 'id':
                    dicc_df[key].rename(columns = {col:'sucursal_id'}, inplace = True)

    # Doy el orden correcto a las columnas de los DF de precios_semana
    for key in dicc_df.keys():
        if 'precio' in key:
            dicc_df[key] = dicc_df[key][['precio', 'producto_id', 'sucursal_id', 'fecha_semana']]

    # Cambio el tipo de dato a las columnas 'precio' a float
    for key in dicc_df.keys():
        if 'precio' in key:
            for col in dicc_df[key].columns:
                if 'precio' in col:
                    dicc_df[key][col] = dicc_df[key][col].astype(float)

    # Función para corregir errores en los id y poner el tipo de dato correcto
    def mod_id_prod(x):
        if isinstance(x,str):
            x = x.split('-')[-1]
        elif isinstance(x,float):
            x = int(x)
        else:
            x=x
        return str(x).zfill(13) # Esta línea es para que los id queden con el formato de código EAN de 13 dígitos

    for key in dicc_df.keys():
        if 'precios_semana' in key or 'producto' in key:
            for col in dicc_df[key].columns:
                if col == 'producto_id':
                    dicc_df[key][col] = dicc_df[key][col].apply(mod_id_prod)

    # Función para corregir los elementos de la columna 'sucursal_id'
    # de los DF 'precios_semana' que presentan formato 'datetime'
    def mod_suc_id(x):
        if type(x) == datetime:
            x=x.strftime("%#d-%#m-%Y")
        return x

    for key in dicc_df.keys():
        if 'precio' in key:
            for col in dicc_df[key].columns:
                if 'sucursal_id' in col:
                    dicc_df[key][col] = dicc_df[key][col].apply(mod_suc_id)

    # Bucle para eliminar outliers de precios
    for key in dicc_df.keys():
        if 'precios_semana' in key:
            for col in dicc_df[key].columns:
                if 'precio' in col:
                    dicc_df[key][col] = dicc_df[key][col][dicc_df[key][col] <= 1000000]

    # REGISTROS DUPLICADOS:

    # Bucle para eliminar los resgistros duplicados
    for key in dicc_df.keys():
        dicc_df[key].drop_duplicates(inplace = True)

    # Elimino id duplicados de los DF 'producto' y 'sucursal'
    # debido a que serán primary key en la base de datos
    for key in dicc_df.keys():
        if 'producto' in key or 'sucursal' in key:
            for col in dicc_df[key].columns:
                if 'producto_id' in col or 'sucursal_id' in col:

                    dicc_df[key] = dicc_df[key].drop_duplicates(
                                    dicc_df[key].columns[dicc_df[key].columns.isin([col])],
                                    keep='first'
                                    )

    return dicc_df


from odoo import api, fields, models,_
from datetime import datetime, timedelta
from odoo.exceptions import UserError, ValidationError

class JoborderChallan(models.Model):
    _name="joborder.challan"
    _order = 'id desc'

    @api.multi
    # def unlink(self):
    #     if self.env.user.id == self.env.ref('base.user_admin').id:
    #         return super(JoborderChallan, self).unlink()
    #     else:
    #         raise ValidationError('You Can not delete a record')
    # @api.multi
    def unlink(self):
        if self.state == 'draft':
            return super(JoborderChallan, self).unlink()
        else:
            if self.state != 'draft' and self.env.user.id == self.env.ref('base.user_admin').id:
                return super(JoborderChallan, self).unlink()
            else:
                raise ValidationError('You Can not delete a record')

    @api.model
    def create(self, vals):
        challan_rec = self.env['joborder.challan'].search([('name', '=', vals['name'])])
        if challan_rec:
            raise ValidationError('Challan No Already Exist!')
        total_qty = 0
        total = 0
        seq=''
        a=''
        if vals['challan_type'] == 'regular':
            a = ''
            seq = self.env['ir.sequence'].get('job_order_challan')
        if vals['challan_type'] == 'rework':
            a = 'Rw-'
            seq = self.env['ir.sequence'].get('job_order_challan1')
        if vals['challan_type'] == 'foc':
            # a = 'Foc-'
            seq = self.env['ir.sequence'].get('job_order_challan')
        if vals['challan_type'] == 'return':
            a = 'Ret-'
            seq = self.env['ir.sequence'].get('job_order_challan3')
        if vals['challan_type'] == 'osp':
            a = 'osp-'
            seq = self.env['ir.sequence'].get('job_order_challan4')

        # vals['name']=a

        vals['name'] = a + str(seq)
        sum_id = super(JoborderChallan, self).create(vals)
        return sum_id

    def action_create_bill(self):
        data = []
        if self.challan_type not in ['foc','rework']:
            bill_rec = self.env['challan.bill']
            for line in self.challan_line:
                job_rec = self.env['job.order.line'].search([('order_id','=',line.job_order_id.id),('product_id','=',line.product_id.id)])
                # if job_rec.unit_price == 0:
                #     raise ValidationError('Bill Not Generated Autometically')
                # else:
                data.append((0,0,{
                    'party_challan':line.party_challan.id,
                    'product_id':line.product_id.id,
                    # 'part_id':line.part_id.id,
                    'part_no':line.part_no,
                    'sac_code':line.product_id.category_id.hsn_no,
                    'our_challan':self.id,
                    # val1.product_id.category_id.hsn_no
                    'qty':line.qty,
                    'unit_id':line.unit_id.id,
                    'unit_price': job_rec.unit_price,
                    # 'unit_price':line.party_challan.unit_price,
                    'tax_id':[(4,tax.id) for tax in job_rec.tax_id],
                    'price_subtotal':line.price_subtotal,
                    'qty_nos': int(line.qty) if ((line.unit_id.name.lower())[0] == 'n') else 0,
                    'qty_kg': line.qty if ((line.unit_id.name.lower())[0] != 'n') else 0,
                    'bq':line.bq
                }))
                line.bq = line.bq - line.qty
            bill_rec.create({
                'job_order_id':self.get_challna_line_po(),
                'job_order_date':self.get_challna_line_podate(),
                'vehicle_no':self.vehicle_no.id,
                'payment_term_ids':self.payment_term_recs,
                'partner_id':self.partner_id.id,
                'challan_bill_line':data,
                'challan_issue':[(6,0,[line.order_id.id])]})
            self.billed = True

    def _amount_all_wrapper(self):
        total_amount = 0.00
        for val in self:
            if val.challan_line:
                for val1 in val.challan_line:
                    total_amount = total_amount + val1.amount
                    self.amount_untaxed = total_amount

    def _tax_amount(self):
        total_tax = 0.00
        for val in self:
            if val.challan_line:
                for val1 in val.challan_line:
                    amount = 0.0
                    for val2 in val1.tax_id.children_tax_ids:
                        amount = amount + val2.amount
                    total_tax = total_tax + (val1.qty * val1.material_price)* amount / 100
                    self.tax_value = total_tax

    def _get_total_amount(self):
        total_amount = 0.00
        for val in self:
            total_amount = val.amount_untaxed + val.tax_value
            self.total_amount = total_amount

    @api.multi
    def action_fetch_receipt_data(self):
        if self.challan_line:
            for line in self.challan_line:
                line.unlink()
        data = []
        if self.challan_type == 'regular':
            final_inspection_rec = self.env['final.inspection'].search([('party_name', '=', self.partner_id.id),('is_issue','=',False),('expected_qty','>',0)])
            for rec in final_inspection_rec:
                job_rec = self.env['joborder.challan.receipt.line'].search(
                    [('order_id', '=', rec.order_ids.id), ('product_id', '=', rec.product_id.id)])
                job_work_rec = self.env['job.order.line'].search([('product_id','=',rec.product_id.id),('order_id','=',job_rec.job_order_id.id)])
                if rec.expected_qty > 0:
                    data = [(0, 0, {
                        'product_id': rec.product_id.id,
                        'name': rec.product_id.name,
                        'hsn_code': rec.product_id.hsn_code,
                        'party_challan': rec.order_ids.id,
                        'qty': rec.expected_qty,
                        'batch_no':rec.batch_no,
                        # 'part_id': line.part_id.id,
                        'part_no': rec.part_no,
                        'unit_id': rec.unit_id.id,
                        'job_order_id': job_rec.job_order_id.id,
                        'unit_price': job_work_rec.unit_price,
                        'material_price': job_work_rec.material_price,
                        'tax_id': job_work_rec.tax_id.id,
                        'joborder_challan_receipt_line_id': job_rec.id,
                        'qty_nos': int(rec.expected_qty) if ((rec.unit_id.name.lower())[0] == 'n') else 0,
                        'qty_kg': rec.expected_qty if ((rec.unit_id.name.lower())[0] != 'n') else 0,
                        # 'bq': qty
                    })]
                    self.challan_line = data

            # receipt_rec = self.env['joborder.challan.receipt'].search([('partner_id','=',self.partner_id.id)])
            # #final_inspection_rec = self.env['final.inspection'].search([('is_issue','=',False)])
            # for rec in receipt_rec:
            #     if rec.joborder_challan_receipt_lines_rec:
            #         for line in rec.joborder_challan_receipt_lines_rec:
            #             self.payment_term_recs =line.job_order_id.payment_term
            #             qty = line.production_ok_qty_line - line.production_desp_qty_line
            #             if qty > 0:
            #                 data=[(0,0,{
            #                     'product_id': line.product_id.id,
            #                     'name':line.product_id.name,
            #                     'hsn_code':line.product_id.hsn_code,
            #                     'party_challan': rec.id,
            #                     'qty': qty,
            #                     # 'part_id': line.part_id.id,
            #                     'part_no':line.part_no,
            #                     'unit_id': line.unit_id.id,
            #                     'job_order_id': line.job_order_id.id,
            #                     'unit_price': line.unit_price,
            #                     'material_price': line.material_price,
            #                     'tax_id': line.tax_id.id,
            #                     'joborder_challan_receipt_line_id':line.id,
            #                     'qty_nos':int(qty) if ((line.unit_id.name.lower())[0] =='n') else 0,
            #                     'qty_kg':qty if ((line.unit_id.name.lower())[0] !='n') else 0,
            #                     #'bq': qty
            #                 })]

        elif self.challan_type == 'return':

            inspection_rec = self.env['joborder.inspection'].search([('party_name', '=', self.partner_id.id),('is_return','=',False)])
            for rec in inspection_rec:
                job_rec = self.env['joborder.challan.receipt.line'].search([('order_id','=',rec.order_ids.id),('product_id','=',rec.product_id.id)])
                if rec.rejected_qty > 0:
                    data = [(0, 0, {
                        'product_id': rec.product_id.id,
                        'name': rec.product_id.name,
                        'hsn_code': rec.product_id.hsn_code,
                        'party_challan': rec.order_ids.id,
                        'qty': rec.rejected_qty,
                        # 'part_id': line.part_id.id,
                        'part_no': rec.part_no,
                        'unit_id': rec.unit_id.id,
                        'job_order_id': job_rec.job_order_id.id,
                        'unit_price': job_rec.unit_price,
                        'material_price': job_rec.material_price,
                        'tax_id': job_rec.tax_id.id,
                        'joborder_challan_receipt_line_id': job_rec.id,
                        'qty_nos': int(rec.rejected_qty) if ((rec.unit_id.name.lower())[0] == 'n') else 0,
                        'qty_kg': rec.rejected_qty if ((rec.unit_id.name.lower())[0] != 'n') else 0,
                        # 'bq': qty
                    })]
                    self.challan_line = data
            # final_inspection_rec = self.env['final.inspection'].search([('party_name', '=', self.partner_id.id),('is_return','=',False)])
            # for rec in final_inspection_rec:
            #     job_rec = self.env['joborder.challan.receipt.line'].search([('order_id','=',rec.order_ids.id),('product_id','=',rec.product_id.id)])
            #     if rec.rejected_qty > 0:
            #         data.append({
            #             'product_id': rec.product_id.id,
            #             'name': rec.product_id.name,
            #             'hsn_code': rec.product_id.hsn_code,
            #             'party_challan': rec.order_ids.id,
            #             'qty': rec.rejected_qty,
            #             # 'part_id': line.part_id.id,
            #             'part_no': rec.part_no,
            #             'unit_id': rec.unit_id.id,
            #             'job_order_id': job_rec.job_order_id.id,
            #             'unit_price': job_rec.unit_price,
            #             'material_price': job_rec.material_price,
            #             'tax_id': job_rec.tax_id.id,
            #             'joborder_challan_receipt_line_id': job_rec.id,
            #             'qty_nos': int(rec.rejected_qty) if ((rec.unit_id.name.lower())[0] == 'n') else 0,
            #             'qty_kg': rec.rejected_qty if ((rec.unit_id.name.lower())[0] != 'n') else 0,
            #             # 'bq': qty
            #         })
            # self.challan_line = data

    def get_time(self):
        date = datetime.today().strftime('%Y-%m-%d %H:%M:%S')
        date_time = datetime.strptime(date, '%Y-%m-%d %H:%M:%S') + timedelta(hours=5, minutes=30, seconds=0)
        date_time  = date_time .strftime('%H:%M')
        return date_time

    def _amount_all_wrapper(self):
        total_amount = 0.00
        for val in self:
            if val.challan_line:
                for val1 in val.challan_line:
                    total_amount = total_amount + val1.price_subtotal
                    self.amount_untaxed = total_amount

    def _tax_amount(self):
        total_tax = 0.00
        for val in self:
            if val.challan_line:
                for val1 in val.challan_line:
                    amount = 0.0
                    if val1.tax_id:
                        amount = amount + val1.tax_id.amt

                    total_tax = total_tax + (val1.qty * val1.material_price) * amount / 100
                    self.tax_value = total_tax

    def _get_total_amount(self):
        total_amount = 0.00
        for val in self:
            total_amount = val.amount_untaxed + val.tax_value
            self.total_amount = total_amount

    def action_fetch_data(self):
        if self.ref_challan and not self.challan_line:
            for val in self.ref_challan:
                for val1 in val.joborder_challan_receipt_lines:
                    self.env['challan.line'].create(
                        {'order_id': self.id,
                         'party_challan':val.id,
                         'product_id':val1.product_id.id,
                         # 'part_id':val1.part_id.id,
                         'part_no':val1.part_no,
                         'unit_id': val1.unit_id.id,
                         'hsn_code': val1.hsn_code,
                         'qty': val1.qty,
                         'unit_price': val1.unit_price,
                         'material_price': val1.material_price,
                         'tax_id': val1.tax_id.id,
                         })

    def action_confirm(self):
        if self.chno:
            self.name = self.chno

        for val1 in self.challan_line:
            val1.qty_nos = val1.qty if (val1.unit_id.name.lower())[0] == 'n' else 0
            val1.qty_kg = val1.qty if (val1.unit_id.name.lower())[0] != 'n' else 0
            inspection_rec = self.env['joborder.inspection'].search([('product_id','=',val1.product_id.id),('order_ids','=',val1.party_challan.id)])
            for insp in inspection_rec:
                insp.is_return=True
                insp.bq -= insp.rejected_qty

            val1.bq = val1.qty
            final_inspection_rec = self.env['final.inspection'].search(
                [('product_id','=',val1.product_id.id),('order_ids','=',val1.party_challan.id)])
            for final_rec in final_inspection_rec:
                final_rec.bq = val1.bq - final_rec.bq
                final_rec.is_issue = True
                if final_rec.bq == 0:
                    final_rec.state = 'confirm'
            sale_line_obj = self.env['joborder.challan.receipt.line'].search(
                [('product_id', '=', val1.product_id.id), ('unit_id', '=', val1.unit_id.id),
                 ('order_id', '=', val1.party_challan.id)])
            for data in sale_line_obj:
                # sale_line_obj.write({'issue_qty': data.issue_qty + val1.qty,
                #                      'bal_qtynew': data.bal_qtynew - val1.qty,
                #                      })
                sale_line_obj.write({'issue_qty': data.issue_qty + val1.qty,
                                     'bal_qtynew': (data.qty-data.issue_qty),
                                     })

                # rec_obj.write({'remaining_total': rec_obj.remaining_total - val1.qty})
        for rec in self.challan_line:

            rec.joborder_challan_receipt_line_id = sale_line_obj.id
            rec.party_challan.challan_line_ids = [(0, sale_line_obj.id, dict(
                # order_id=rec.order_id.id,
                challan_issue_id=rec.order_id.name,
                product_id=rec.product_id.id,
                unit_price=rec.unit_price,
                name=rec.name,
                tax_id=rec.tax_id.id,
                party_challan=rec.party_challan.id,
                qty=rec.qty,
                product_id1=rec.product_id1.id,
                unit_id=rec.unit_id.id,
                hsn_code=rec.hsn_code,
                # part_id=rec.part_id.id,
                part_no=rec.part_no,
                challan_reciept_id=rec.party_challan.id,
                job_order_id = rec.job_order_id.id

            ))]
        if self.partner_id.billing_mode:
            self.action_create_bill()
        # self.method_update_challan_receipt_total_iss(self.challan_line)
        self.write({'state':'confirm'})

    # def method_update_challan_receipt_total_iss(self,challanline):
    #     for lines in challanline:
    #         rec_obj = self.env['joborder.challan.receipt'].search(
    #             [('id', '=', lines.party_challan.id)])
    #
    #         rec_obj.total_iss+=lines.qty
    #         rec_obj.total_bal-=lines.qty

    # Change By Ayush
    def action_gen_invoice(self):
        action = self.env.ref('job_order_process.action_challan_bill').read()[0]
        action['domain'] = [('partner_id', '=', self.partner_id.id), ('challan_issue', '=',self.id)]
        return action

    name = fields.Char('Issue No.', required=True,default='New')
    chno = fields.Char('Issue No.Org')
    partner_id = fields.Many2one('my.partner','Party Name',required=True,)
    # date = fields.Date('Date',default=fields.Date.today(),required=True,)
    date = fields.Date(required=True, default=lambda self: self._get_current_date())
    @api.model
    def _get_current_date(self):
        """ :return current date """
        date = datetime.now() + timedelta(hours=5, minutes=30)
        date = date.date()
        return date

    remark = fields.Char('Remark')
    origin = fields.Many2one('joborder.challan.receipt', 'Refecence')
    reference_id = fields.Many2many('joborder.challan.receipt', 'Refecence')
    ref_challan = fields.Many2many('joborder.challan.receipt', string='Reference')
    challan_line = fields.One2many('challan.line','order_id','Lines')
    user_id = fields.Many2one('res.users', 'Created By', default=lambda self: self.env.user)
    amount_untaxed = fields.Float(compute = _amount_all_wrapper, string='Untaxed Amount' )
    tax_value = fields.Float(compute = _tax_amount, string='Taxes' )
    total_amount = fields.Float(compute = _get_total_amount, string='Total Amount')
    # eway_bill = fields.Char('E-way Bill No.')
    # transport = fields.Char('Transport Mode')
    vehicle_no = fields.Many2one('vehicle', 'Vehicle No')
    time = fields.Char('Time',default=get_time)
    amount_untaxed = fields.Float(compute=_amount_all_wrapper, string='Untaxed Amount')
    tax_value = fields.Float(compute=_tax_amount, string='Taxes')
    total_amount = fields.Float(compute=_get_total_amount, string='Total Amount')
    challan_type = fields.Selection([('regular', 'Regular'),('rework', 'Rework'),('foc', 'FOC'),('return','Return'),('osp','Returnable Challan')],default='regular',string='Challan Type',required=True)
    billed = fields.Boolean('Billed')
    description = fields.Char('Description')
    state = fields.Selection([
        ('draft', 'Draft'),
        ('confirm', 'Confirm'),
    ], string='Status', readonly=True, copy=False, index=True, default='draft')
    payment_term_recs = fields.Integer(string="Payment term (days)")
    job_order_challan_reference = fields.Char('Reference')
    production_challan_reference = fields.Char('Pro Reference')
    mast_oldid = fields.Integer('Mast Id')

    _sql_constraints = [
        ('name', 'unique(name,partner_id)', 'Challan  no. already exists for this party!')
    ]

#new changes ayush gupta
    def get_challna_line_po(self):
        data = []
        data_line = []
        for line in self.challan_line:
            if data_line:
                # data_line.append(line.job_order_id.name + ' dt.' + datetime.strptime(str(line.job_order_id.date),'%Y-%m-%d').strftime('%d/%m/%Y'))
                data_line.append(line.job_order_id.name)
                # podate=line.job_order_id.date
            else:
                data_line.append(line.job_order_id.name)
            #     data_line.append(line.job_order_id.name + ' dt.' + datetime.strptime(str(line.job_order_id.date),'%Y-%m-%d').strftime('%d/%m/%Y'))
            #
        data_line=set(data_line)

        s = [str(i) for i in data_line]
        res = str(",".join(set(s)))
        return res

    def get_challna_line_podate(self):
        data = []
        data_line = []
        for line in self.challan_line:
            if data_line:
                # data_line.append(line.job_order_id.name + ' dt.' + datetime.strptime(str(line.job_order_id.date),'%Y-%m-%d').strftime('%d/%m/%Y'))
                data_line.append(datetime.strptime(str(line.job_order_id.date),'%Y-%m-%d').strftime('%d/%m/%y'))
                # podate=line.job_order_id.date
            else:
                data_line.append(datetime.strptime(str(line.job_order_id.date),'%Y-%m-%d').strftime('%d/%m/%y'))
            #     data_line.append(line.job_order_id.name + ' dt.' + datetime.strptime(str(line.job_order_id.date),'%Y-%m-%d').strftime('%d/%m/%Y'))
            #
        data_line = set(data_line)
        s = [str(i) for i in data_line]
        res = str(",".join(set(s)))
        return res

    def get_receiptChallanNo(self, ReceiptChallanNO):
        if ReceiptChallanNO:
            return  ReceiptChallanNO.split('_')[0]

class ChallanLine(models.Model):
    _name = "challan.line"

    # @api.multi
    # def unlink(self):
    #     if self.env.user.id == self.env.ref('base.user_admin').id:
    #         return super(ChallanLine, self).unlink()
    #         # self.env[joborder.challan.receipt.line].get_total_balance()
    #         # print(data.qty, data.issue_qty, val1.qty, 'eeeeeeeee', (data.qty - data.issue_qty))
    #     else:
    #         raise ValidationError('You Can not delete a record')
    # @api.multi
    # def unlink(self):
    #     if self.state == 'draft':
    #         return super(ChallanLine, self).unlink()
    #     else:
    #         if self.state != 'draft' and self.env.user.id == self.env.ref('base.user_admin').id:
    #             return super(ChallanLine, self).unlink()
    #         else:
    #             raise ValidationError('You Can not delete a record')
    @api.multi
    def write(self, vals):
        for rec in self:
            if 'product_id' in vals:
                prod = self.env['my.product'].browse([vals.get('product_id')])
            else:
                prod = rec.product_id

            if 'party_challan' in vals:
                challan = self.env['joborder.challan.receipt'].browse([vals.get('party_challan')])
            else:
                challan = rec.party_challan

            for line in self.env['joborder.challan'].browse([rec.order_id.id]).challan_line:
                if (prod.id == line.product_id.id) and (challan.id == line.party_challan.id) and line.id != rec.id and line.order_id == rec.id:
                    raise UserError(_(u"Duplicate lines \nthis line already exist!\ncheck your lines again please!"))
        result = super(ChallanLine, self).write(vals)
        return result

    @api.model
    def create(self, vals):
        if vals.get('order_id', False):
            for line in self.env['joborder.challan'].browse([vals['order_id']]).challan_line:
                if (vals.get('product_id') == line.product_id.id) and (vals.get('party_challan') == line.party_challan.id):
                    raise UserError(_(u"Duplicate lines \nthis line already exist!\ncheck your lines again please!"))
        result = super(ChallanLine, self).create(vals)
        return result

    @api.onchange('job_order_id')
    def onchange_job_order_product(self):
        product_list = []
        job = []
        for val in self.env['job.order'].search([('partner_id', '=', self.order_id.partner_id.id),('state','=','confirm')]):
            job.append(val.id)
        domain = {'job_order_id':[('id','in',job)]}
        for line in self.env['joborder.challan.receipt.line'].search([('job_order_id', '=', self.job_order_id.id),('bal_qtynew','>',0)]):
            product_list.append(line.product_id.id)
        product_list = list(set(product_list))
        domain.update({'product_id': [('id', 'in', product_list)]})
        return {'domain': domain}  # ,'domain1':d

    # @api.onchange('product_id')
    # def onchange_product_id(self):
    #     product_list = []
    #     data_list = []
    #     if self.product_id:
    #         for val in self.env['joborder.challan.receipt.line'].search([('product_id', '=', self.product_id.id),('bal_qtynew','>',0)]):
    #             data_list.append(val.order_id.id)
    #         domain = {'party_challan': [('id', 'in', data_list)]}
    #
    #                 # self.process = rec.process_id.id
    #                 # self.packing_id = rec.packing_id.id
    #         return {'domain': domain}
    @api.onchange('product_id')
    def onchange_product_id(self):
        product_list = []
        data_list = []
        if self.product_id:
            for val in self.env['joborder.challan.receipt.line'].search(
                    [('product_id', '=', self.product_id.id), ('bal_qtynew', '>', 0),
                     ('order_id.partner_id', '=', self.order_id.partner_id.id),
                     ('order_id.challan_type', '=', self.order_id.challan_type)]):
                data_list.append(val.order_id.id)
            domain = {'party_challan': [('id', 'in', data_list)]}

            # self.process = rec.process_id.id
            # self.packing_id = rec.packing_id.id
            self.hsn_code=self.product_id.hsn_code
            job_rec = self.env['job.order.line'].search(
                [('order_id', '=', self.job_order_id.id), ('product_id', '=', self.product_id.id)])
            for val in job_rec:
                self.material_price=val.material_price

            return {'domain': domain}

    @api.onchange('party_challan')
    def get_product_detail(self):
        for val in self.env['joborder.challan.receipt.line'].search([('order_id', '=', self.party_challan.id)]):
            for line in val:
                if val.product_id.id == self.product_id.id:
                    if self.product_id:
                        self.unit_id = line.unit_id.id
                        # self.part_id = line.part_id.id
                        self.part_no = line.product_id.part_no if line.product_id.part_no else '',
                        # self.job_order_id = line.job_order_id.id
                        self.sac_code = line.sac_code
                        self.hsn_code = self.product_id.hsn_code
                        self.tax_id = line.tax_id.id
                        self.unit_price = line.unit_price
                        # self.material_price = self.material_price
                        self.qty = line.bal_qtynew

    @api.onchange('qty')
    def change_qty(self):
        if self.qty:
            for val in self.env['joborder.challan.receipt.line'].search([('order_id', '=', self.party_challan.id),('product_id','=',self.product_id.id)]):
                if val.product_id.id == self.product_id.id:
                    if round(self.qty,2) > val.bal_qtynew:
                        raise ValidationError('Qty is not more than %s'%val.bal_qtynew)

    @api.depends('qty','unit_price')
    def get_subtotal(self):
        total_price = 0.00
        for val in self:
            if val.qty:
                total_price = (val.qty * val.material_price)
                val.write({'price_subtotal1': total_price})
                val.price_subtotal = total_price

    order_id = fields.Many2one('joborder.challan','Id',ondelete='cascade')
    job_order_id = fields.Many2one('job.order', 'Order No.',required=True)

    party_challan =fields.Many2one('joborder.challan.receipt', 'Party Challan', ondelete='cascade')
    challan_reciept_id = fields.Many2one('joborder.challan.receipt', 'Party Challan id', ondelete='cascade')

    product_id = fields.Many2one('my.product','Product',required=True)
    product_id1 = fields.Many2one('my.vik', 'Item')
    name = fields.Char('Description',default='After Platting')
    # part_id = fields.Many2one('part.number','Part No.')
    part_no=fields.Char('Part No.')
    hsn_code = fields.Char('HSN No.')
    # unit_id = fields.Many2one('my.uom','UOM')
    unit_id = fields.Many2one('my.unit', 'UOM')
    qty = fields.Float('Quantity',digits=(10,2))

    qty_nos=fields.Integer('Qty Nos')
    qty_kg=fields.Float('Qty_Kg',digits=(10,2))
    unit_price = fields.Float('Unit Price')
    material_price = fields.Float('Material Price')

    nature_of_process = fields.Char('Nature of Process')

    tax_id = fields.Many2one('my.tax', string='Taxes',)
    price_subtotal = fields.Float(compute=get_subtotal, string='Subtotal')
    price_subtotal1 = fields.Float(string='Subtotal')
    challan_issue_id=fields.Char(string='Issue ChNo')
    # joborder_challan_receipt_line_id=fields.Integer()
    joborder_challan_receipt_line_id= fields.Many2one('joborder.challan.receipt.line', ondelete='cascade')
    bq = fields.Float('Bal qty')
    rtq = fields.Float('Return qty')
    batch_no=fields.Char('Batch No')

class MyVik(models.Model):
    _name = "my.vik"
    _order = 'name asc'

    name = fields.Char('Name')
    product_id = fields.Many2one('my.product', 'Product')
    challan_id = fields.Many2one('joborder.challan.receipt','Challan')
    qty = fields.Float('Qty')

    @api.multi
    def unlink(self):
        if self.env.user.id == self.env.ref('base.user_admin').id:
            return super(MyVik, self).unlink()
        else:
            raise ValidationError('You Can not delete a record')


import requests
from datetime import datetime

class VK:
    URL = 'https://api.vk.com/method/'

    def __init__(self, access_token, qty_photo, user_id, version='5.131'):
        self.token = access_token
        self.user_id = user_id
        self.version = version
        self.params = {'access_token': self.token, 'v': self.version}
        self.qty_photo = qty_photo

    def user_info(self, user_id):
        user_url = self.URL + 'users.get'
        user_params = {
            'user_ids': user_id
        }
        params = {**self.params, **user_params}
        response = requests.get(user_url, params).json()
        first_name = response['response'][0]['first_name']
        last_name = response['response'][0]['last_name']
        self.user_id = response['response'][0]['id']
        print(f'По введенным данным мы нашли: {first_name} {last_name} id: {self.user_id}')
        return first_name, last_name, self.user_id

    def photos_info(self):
        items = self.photos_get()['response']['items']
        photos_info = []
        likes_count = []
        repeat_likes_count = []

        for like in items:
            likes_count.append(like['likes']['count'])

        for like in likes_count:
            if likes_count.count(like) > 1:
                repeat_likes_count.append(like)

        for item in items:
            like = item['likes']['count']
            date_photo = datetime.utcfromtimestamp(item['date']).strftime('%d-%m-%Y')
            info = {
                'size': item['sizes'][-1]['type'],
                'link': item['sizes'][-1]['url']
            }

            if like in repeat_likes_count:
                info['file_name'] = f'{like}_{date_photo}.jpg'
                photos_info.append(info)
            else:
                info['file_name'] = f'{like}.jpg'
                photos_info.append(info)
        return photos_info

    def photos_get(self):
        self.user_info(self.user_id)
        album = input('Фото забираем со стены или из профиля?\n'
                      ' Введите wall или profile: ').lower()
        photos_url = self.URL + 'photos.get'
        photos_params = {
            'owner_id': self.user_id,
            'album_id': album,
            'rev': 0,
            'extended': 1,
            'count': self.qty_photo
        }

        params = {**self.params, **photos_params}
        response = requests.get(photos_url, params).json()

        return response


from vllm import LLM, SamplingParams
import torch
from constants_prompt import build_autoj_input
from zh_constants_prompt import zh_build_autoj_input
import argparse

def extract_pariwise_result(raw_output):
    raw_output = raw_output.strip()
    pos = raw_output.rfind('final decision is ')
    pred_label = -1
    if pos != -1:
        pred_rest = raw_output[pos + len('final decision is '):].strip().lower()
        if pred_rest.startswith('response 1'):
            pred_label = 0
        elif pred_rest.startswith('response 2'):
            pred_label = 1
        elif pred_rest.startswith('tie'):
            pred_label = 2
    return pred_label

def zh_extract_pariwise_result(raw_output):
    raw_output = raw_output.strip()
    pos = raw_output.rfind('最终决定是')
    pred_label = -1
    if pos != -1:
        # pred_rest = raw_output[pos + len('final decision is '):].strip().lower()
        pred_rest = raw_output[pos + len('最终决定是'):].strip()
        if pred_rest.startswith('回应1'):
            pred_label = 0
        elif pred_rest.startswith('回应2'):
            pred_label = 1
        elif pred_rest.startswith('平局'):
            pred_label = 2
    return pred_label

def extract_single_rating(score_output):
    if "Rating: [[" in score_output:
        pos = score_output.rfind("Rating: [[")
        pos2 = score_output.find("]]", pos)
        assert pos != -1 and pos2 != -1
        return float(score_output[pos + len("Rating: [["):pos2].strip())
    else:
        return 0.0

def zh_extract_single_rating(score_output):
    if "评分:[[" in score_output:
        pos = score_output.rfind("评分:[[")
        pos2 = score_output.find("]]", pos)
        assert pos != -1 and pos2 != -1
        return float(score_output[pos + len("评分:[["):pos2].strip())
    elif "打分:[[" in score_output:
        pos = score_output.rfind("打分:[[")
        pos2 = score_output.find("]]", pos)
        assert pos != -1 and pos2 != -1
        return float(score_output[pos + len("打分:[["):pos2].strip())
    else:
        return 0.0

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("--language", type=str, default="Chinese", help="Choose Chinese or English evaluation")
    args = parser.parse_args()
    assert args.language == "Chinese" or args.language == "English"
    num_gpus = torch.cuda.device_count()
    model_name_or_dir = "GAIR/autoj-bilingual-6b"  # or "local path to auto-j"
    llm = LLM(model=model_name_or_dir, tensor_parallel_size=num_gpus,)
    sampling_params = SamplingParams(temperature=0.0, top_p=1.0, max_tokens=1024)

    if args.language == "Chinese":
        # input_single = zh_build_autoj_input(prompt="中国的首都是哪里？",
        #                                 resp1="中国的首都是上海。",
        #                                 protocol="zh_single")
        input_pairwise = zh_build_autoj_input(prompt="中国的首都是哪里?",
                                        resp1="中国的首都是北京。",
                                        resp2="中国的首都是上海。",
                                        protocol="zh_pairwise_tie")
        input = input_pairwise  # or input_single
        # input = input_single

        outputs = llm.generate(input, sampling_params)

        judgment = outputs[0].outputs[0].text

        print(judgment)

        evaluation_result = zh_extract_pariwise_result(judgment)
        # single_score = zh_extract_single_rating(judgment)
        # print(single_score)

        print(evaluation_result)

    elif args.language == "English":
        input_pairwise = build_autoj_input(prompt="What's the capital of the United States?",
                                       resp1="The capital of the United States is New York.",
                                       resp2="The captical of the United States is Washington D.C.",
                                       protocol="pairwise_tie")

            # input = input_pairwise  # or input_single
        input = input_pairwise

        outputs = llm.generate(input, sampling_params)

        judgment = outputs[0].outputs[0].text

        print(judgment)

        evaluation_result = extract_pariwise_result(judgment)

        print(evaluation_result)