示例#1
0
class product_product_line(models.Model):
    """Product of product"""
    _name = "product.product.line"
    _description = 'product product line'

    product_line_id = fields.Many2one('rr.housekeeping.line',
                                      'Product line id')
    product_product_id = fields.Many2one('product.product',
                                         'Product',
                                         required=True)
    qty = fields.Float('Qty', size=10)
    uom = fields.Many2one('uom.uom', 'UOM')

    api.onchange('product_product_id')

    @api.onchange('product_product_id')
    def onchange_product(self):
        if self.product_product_id:
            print('product_product_id==============', self.product_product_id)
            uom = self.product_product_id.uom_id.id
            self.uom = uom

    @api.model
    def create(self, vals):
        if 'qty' in vals:
            print("---------------------------------", vals['qty'])
            if vals['qty'] <= 0.0:
                raise Warning('Product Quntity should not be 0 ')
        return super(product_product_line, self).create(vals)
示例#2
0
    def _check_ks_is_combo(self):
        """
        Manage product type: if product is combo, then product type must also be combo product
        """
        if self.ks_is_combo:
=======
    @api.onchange('is_combo', 'type')
示例#3
0
    def _onchange_partner(self):
        if self.partner_id:
            self.delivery_id = self.partner_id  # MAJ d'un autre champ
            # OU
            vals = {'delivery_id': self.partner_id.id}
            self.update(vals)
            # M2M : 2 possibilités :
            # - liste d'IDs, mais ça va AJOUTER les ids, comme (4, [IDs])
            # - [(6, 0, [IDs])], ce qui va remplacer les ids
            # (cf module product_category_tax dans akretion/odoo-usability)
            # On utilise un autre M2M pour le mettre à jour, on peut faire
            # self.champ_M2M_ids.ids -> ça donne la liste des IDs
            # M2O : recordset (ou ID)
            # O2M : exemple v10 dans purchase/models/account_invoice.py
            # méthode purchase_order_change()
            # là, Odoo va jouer automatiquement le @api.onchange du champ delivery_id
            # pas besoin d'appeler le onchange de delivery_id dans notre code
        # Here, all form values are set on self
        # assigned values are not written to DB, but returned to the client
        # It is not possible to output a warning
        # It is not possible to put a raise UserError()
        # in this function (it will crash odoo)
        res = {'warning':
            {'title': _('Be careful'),
            {'message': _('here is the msg')}}
        # pour un domaine
        res = {'domain': {
            'champ1': "[('product_id', '=', product_id)]",
            'champ2': "[]"},
            }
        # si on a besoin de changer le contexte (astuce qui peut être utile
        # pour ne pas déclancher en cascade les autres api.onchange qui filtreraient
        # sur le contexte
        self.env.context = self.with_context(olive_onchange=True).env.context
        # astuce trouvée sur https://github.com/odoo/odoo/issues/7472
        return res
        # si je n'ai ni warning ni domain, je n'ai pas besoin de faire un return

    # La fonction de calcul du champ function price_subtotal
    @api.one  # auto-loop decorator
    @api.depends('price_unit', 'discount', 'invoice_line_tax_id', 'quantity',
        'product_id', 'invoice_id.partner_id', 'invoice_id.currency_id')
    # @api.depends est utilisé pour: invalidation cache, recalcul, onchange
    # donc, maintenant, le fait d'avoir un champ calculé fait qu'il est
    # automatiquement mis à jour dans la vue quand un de ses champs 'depends'
    # est modifié ! COOOOOL !
    # ATTENTION : si chgt de @api.depends, faire -u module !
    # Pour un one2many : ne PAS juste indiquer le nom du champ o2m, sinon il ne fait rien
    # il faut aussi indiquer un champ sur le O2M. Exemple : 'line_ids.request_id'
    # Apparemment, on peut mettre dans @api.depends un champ fonction stocké et ça va bien
    # faire le recalcul en cascade
    # (ça n'a pas l'air de marcher qd on met un api.depends sur un champ non stocké)
    def _compute_price(self):
        price = self.price_unit * (1 - (self.discount or 0.0) / 100.0)
        taxes = self.invoice_line_tax_id.compute_all(price, self.quantity, product=self.product_id, partner=self.invoice_id.partner_id)
        self.price_subtotal = taxes['total']  # calcul et stockage de la valeur
        self.second_field = 'iuit'  # calcul et stockage d'un 2e champ
                                    # equivalent de multi='pouet'
        # Pour un champ O2M ou M2M, envoyer un recordset multiple ou une liste d'IDS
        # pour un champ M2O, donner le recordset ou l'ID
        if self.invoice_id:
            self.price_subtotal = self.invoice_id.currency_id.round(self.price_subtotal)
        # Pas besoin de return !
        # on ne peut PAS faire un self.write({}) dans la fonction de calcul d'un champ fonction

    # Pour un champ fonction, on peut aussi faire @api.multi:
    # untaxed = fields.Float(compute='_amounts')
    # taxes = fields.Float(compute='_amounts')
    # total = fields.Float(compute='_amounts')
    @api.multi
    @api.depends('lines.amount', 'lines.taxes')
    def _amounts(self):
        for order in self:
            order.untaxed = sum(line.amount for line in order.lines)
            order.taxes = sum(line.taxes for line in order.lines)
            order.total = order.untaxed + order + taxes

    # Champ fonction inverse='_inverse_price'
    @api.onchange('name')  # add @api.onchange on an inverse method to have it apply immediately and not upon save
    def _inverse_loud(self):
        for rec in self:
            rec.name = (rec.loud or '').lower()  # MAJ du ou des autres champs

    # Champ fonction search='_search_price'
    def _search_loud(self, operator, value):
        if value is not False:
            value = value.lower()
        today = fields.Date.context_today(self)
        self._cr.execute('SELECT id FROM [cur_obj] WHERE (fortress_type <> %s OR (fortress_type = %s AND effectivity_date is not null)) AND (end_date is null OR end_date > %s)', (today, ))
        res_ids = [x[0] for x in self._cr.fetchall()]
        res = [('id', 'in', res_ids)] # recherche sur les autres champs
        return res

    # Fonction default=_default_account
    @api.model
    def _default_account(self):
        return valeur_par_defaut
        # M2O : retourne un recordset ou un ID (ou False)
        # (NOTE: apparemment, en v8, il veut un ID)
        # OUTDATED (?) : ATTENTION, si on veut un M2O à False, il ne pas que la fonction
        #       _default_account retourne False mais self.env['..'].browse(False)
        # O2M : retourne une liste de dict contenant la valeur des champs
        # M2M : retourne un recordset multiple ?
        # date : string ou objet datetime

    # Fonction pour fields.selection
    @api.model
    def _type_list_get(self):
        return [('key1', _('String1')), ('key2', _('String2'))]

    ### CHAMPS
    # id, create_uid, write_uid, create_date et write_date
    # sont déjà utilisable dans le code python sans re-définition
    active = fields.Boolean(default=True)
    # Par défaut, string = nom du champ avec majuscule pour chaque début de mot
    login = fields.Char(
        string='Login', size=16, translate=True, required=True,
        help="My help message")
    display_name = fields.Char(
        string='Display Name', compute='_compute_display_name',
        readonly=True, store=True)
    comment = fields.Text(string='Comment', translate=True)
    html = fields.Html(string='report', translate=True)
    code_digits = fields.Integer(
        string='# of Digits', track_visibility='onchange', default=12,
        groups='base.group_user')
    # OU groups=['base.group_user', 'base.group_hr_manager']
    # groups = XMLID : restriction du read/write et invisible ds les vues ET EXPORT
    # v13: track_visibility='onchange' => tracking=X
    sequence = fields.Integer(default=10)
    # track_visibility = always ou onchange
    amount_untaxed = fields.Float(
        'Amount untaxed', digits='Product Unit of Measure',
        group_operator="avg")  # Utile pour un pourcentage par exemple
    # v13 : digits='Product Unit of Measure'
    # v12- : digits=dp.get_precision('Account')
    # digits=(precision, scale)   exemple (16, 2)
    # Scale est le nombre de chiffres après la virgule
    # quand le float est un fields.float ou un fields.function,
    # on met l'option : digits=dp.get_precision('Account')
    # Autres valeurs possibles pour get_precision : product/product_data.xml
    # Product Price, Discount, Stock Weight, Product Unit of Measure,
    # Product UoS (v8 only)
    # fields.Monetary is only in version >= 9.0
    debit = fields.Monetary(default=0.0, currency_field='company_currency_id')
    start_date = fields.Date(
        string='Start Date', copy=False, default=fields.Date.context_today,
        index=True)
    # similaire : fields.Datetime and fields.Time
    start_datetime = fields.Datetime(
        string='Start Date and Time', default=fields.Datetime.now)
    # index=True => the field will be indexed in the database
    # (much faster when you search on that field)
    type = fields.Selection([
        ('import', 'Import'),
        ('export', 'Export'),
        ], string="Type",
        default=lambda self: self._context.get('type', 'export'))
    # FIELDS.SELECTION ac selection dynamique :
    # type = fields.Selection('_type_list_get', string='Type', help='Pouet'),
    # Plus besoin de la double fonction pour que la 2e soit héritable
    # Pour ajouter des champs à un fields.Selection existant:
    # fields.Selection(
    #    selection_add=[('new_key1', 'My new key1'), ('new_key2', 'My New Key2')])
    # v14 : ondelete={"new_key1": "set default"}
    # other possible options for ondelete: set null, cascade (delete the records !)
    # Pour afficher la valeur 'lisible' du champ selection (v12+):
    # rec._fields['type'].convert_to_export(rec.type, rec)
    picture = fields.Binary(string='Picture', attachment=True)
    # Pour fields.binary, il existe une option filters='*.png, *.gif',
    # qui restreint les formats de fichiers sélectionnables dans
    # la boite de dialogue, mais ça ne marche pas en GTK (on
    # ne peut rien sélectionner) et c'est pas supporté en Web, cf
    # https://bugs.launchpad.net/openobject-server/+bug/1076895
    picture_filename = fields.Char(string='Filename')
    # Les champs "picture" et "picture_filename" sont liés ensemble dans la vue
    # via la balise filename="picture_filename" sur le champ 'picture'
    # Il faut que le champ 'picture_filename' soit présent dans la vue
    # (il peut être invisible)
    # Pour un fichier à télécharger d'Odoo, le nom du fichier aura la valeur de
    # picture_filename
    # Pour un fichier à uploader dans Odoo, 'picture_filename' vaudra le nom
    # du fichier uploadé par l'utilisateur

    # Exemple de champ fonction stocké
    price_subtotal = fields.Float(
        string='Amount', digits= dp.get_precision('Account'),
        store=True, readonly=True, compute='_compute_price')
    # Exemple de champ function non stocké avec fonction inverse
    loud = fields.Char(
        store=False, compute='_compute_loud', inverse='_inverse_loud',
        search='_search_loud')
    account_id = fields.Many2one('account.account', string='Account',
        required=True, domain=[('type', 'not in', ['view', 'closed'])],
        default=lambda self: self._default_account(),
        check_company=True)
        # L'utilisation de lambda permet d'hériter la fonction _default_account() sans
        # hériter le champ. Sinon, on peut aussi utiliser default=_default_account
        # Possibilité d'hériter un domaine:
        # domain=lambda self: [('reconcile', '=', True), ('user_type_id.id', '=', self.env.ref('account.data_account_type_current_assets').id), ('deprecated', '=', False)]
    company_id = fields.Many2one(
        'res.company', string='Company',
        ondelete='cascade', required=True,
        default=lambda self: self.env['res.company']._company_default_get()
        default=lambda self: self.env.company)  # v13
        # si on veut que tous les args soient nommés : comodel_name='res.company'
    user_id = fields.Many2one(
        'res.users', string='Salesman', default=lambda self: self.env.user)
    # ATTENTION : si j'ai déjà un domaine sur la vue,
    # c'est le domaine sur la vue qui prime !
    # ondelete='cascade' :
    # le fait de supprimer la company va supprimer l'objet courant !
    # ondelete='set null' (default)
    # si on supprime la company, le champ company_id est mis à 0
    # ondelete='restrict' :
    # si on supprime la company, ça déclanche une erreur d'intégrité !

    # Champ Relation
    company_currency_id = fields.Many2one(
        'res.currency', string='Currency', related='company_id.currency_id',
        store=True)  # option related_sudo=True by default
    # ATTENTION, en nouvelle API, on ne peut PAS faire un fields.Char qui
    # soit un related d'un fields.Selection (bloque le démarrage d'Odoo
    # sans message d'erreur !)

    line_ids = fields.One2many(
        'product.code.line', 'parent_id', string='Product lines',
        states={'done': [('readonly', True)]}, copy=True)
        # OU comodel_name='product.code.line', inverse_name='parent_id'
    # 2e arg = nom du champ sur l'objet destination qui est le M20 inverse
    # en v8 :
    # copy=True pour que les lignes soient copiées lors d'un duplicate
    # sinon, mettre copy=False (ça ne peut être qu'un booléen)
    # Valeur par défaut du paramètre "copy": True for normal fields, False for
    # one2many and computed fields, including property fields and related fields
    # ATTENTION : pour que states={} marche sur le champ A et que le
    # champ A est dans la vue tree, alors il faut que le champ "state"
    # soit aussi dans la vue tree.

    partner_ids = fields.Many2many(
        'res.partner', 'product_code_partner_rel', 'code_id', 'partner_id',
        'Related Partners')
    # 2e arg = nom de la table relation
    # 3e arg ou column1 = nom de la colonne dans la table relation
    # pour stocker l'ID du product.code
    # 4e arg ou column2 = nom de la colonne dans la table relation
    # pour stocker l'ID du res.partner
    # OU
    partner_ids = fields.Many2many(
        'res.partner', column1='code_id', column2='partner_id',
        string='Related Partners')
    # OU
    partner_ids = fields.Many2many(
        'res.partner', string='Related Partners')
    # Pour les 2 dernières définitions du M2M, il ne faut pas avoir
    # plusieurs champs M2M qui pointent du même obj vers le même obj

    # Champ property: il suffit de définit le champ comme un champ normal
    # et d'ajouter un argument company_dependent=True
    # Quand on veut lire la valeur d'un champ property dans une société
    # qui n'est pas celle de l'utilisateur, il faut passer dans le context
    # 'force_company': 8  (8 = ID de la company)
    }
示例#4
0
    def action_view_partner_invoices(self):
        self.ensure_one()
        action = self.env.ref('account.action_move_out_invoice_type').read()[0]
        action['domain'] = [
<<<<<<< HEAD
            ('type', 'in', ('out_invoice', 'out_refund')),
=======
            ('move_type', 'in', ('out_invoice', 'out_refund')),
>>>>>>> f0a66d05e70e432d35dc68c9fb1e1cc6e51b40b8
            ('partner_id', 'child_of', self.id),
        ]
        action['context'] = {'default_move_type':'out_invoice', 'move_type':'out_invoice', 'journal_type': 'sale', 'search_default_unpaid': 1}
        return action

<<<<<<< HEAD
    @api.onchange('company_id', 'parent_id')
    def _onchange_company_id(self):
        super(ResPartner, self)._onchange_company_id()
        if self.company_id:
            company = self.company_id
        else:
            company = self.env.company
        return {'domain': {'property_account_position_id': [('company_id', 'in', [company.id, False])]}}

=======
>>>>>>> f0a66d05e70e432d35dc68c9fb1e1cc6e51b40b8
    def can_edit_vat(self):
        ''' Can't edit `vat` if there is (non draft) issued invoices. '''
        can_edit_vat = super(ResPartner, self).can_edit_vat()
        if not can_edit_vat:
            return can_edit_vat
示例#5
0
class ResPartnerPermission(models.Model):
    _name = 'res.partner.permission'
    _description = 'Permisos en contactos'

    permission_entity_id = fields.Many2one('res.entity', 'Entidades')
    permission_specialty_id = fields.Many2one('res.specialty.pure',
                                              'Especialidades')
    permission_city_id = fields.Many2one('res.city', 'Ciudades')
    permission_state_id = fields.Many2one('res.country.state', 'Departamentos')
    is_permission_state = fields.Boolean('Todos los Departamentos',
                                         default="True")
    is_permission_entity = fields.Boolean('Todas las Entidades',
                                          default="True")
    is_permission_specialty = fields.Boolean('Todas las Especialidades',
                                             default="True")
    is_permission_city = fields.Boolean('Todas las Ciudades', default="True")
    partner_id = fields.Many2one('res.partner')
    permission_judged_id = fields.Many2one('res.partner', string="Despacho")
    is_permission_judged_id = fields.Boolean(string="Todos los Despachos",
                                             default="True")
    #permission_rol_id = fields.Many2one('res.partner.permission.group', string='Permission Rol')
    endpoint_key = fields.Char(string="Cadena Endpoint",
                               compute="_compute_endpoint_key")

    api.onchange('permission_entity_id', 'permission_specialty_id',
                 'permission_city_id', 'permission_state_id',
                 'is_permission_state', 'is_permission_entity',
                 'is_permission_specialty', 'is_permission_city')

    def _compute_endpoint_key(self):
        for rec in self:
            key = ''
            if rec.is_permission_state:
                key += 'ALL'
            elif not rec.is_permission_state and rec.permission_city_id and not rec.permission_state_id:
                key += rec.permission_city_id.zipcode
            elif not rec.is_permission_state and not rec.permission_city_id and rec.permission_state_id:
                key += rec.permission_state_id.dane_code

            if rec.is_permission_entity:
                key += '-ALL'
            elif not rec.is_permission_entity and rec.permission_entity_id:
                key += '-' + rec.permission_entity_id.code

            if rec.is_permission_specialty:
                key += '-ALL'
            elif not rec.is_permission_specialty and rec.permission_specialty_id:
                key += '-' + rec.permission_specialty_id.code

            if rec.is_permission_judged_id:
                key += '-ALL'
            elif not rec.is_permission_judged_id and rec.permission_judged_id:
                key += '-' + rec.permission_judged_id.code

            rec.endpoint_key = key

    @api.model
    def create(self, vals):
        if 'permission_state_id' in vals and 'permission_city_id' in vals and 'is_permission_state' in vals:
            if vals['permission_state_id'] and vals[
                    'permission_city_id'] and not vals['is_permission_state']:
                raise UserError(
                    'Departamentos y Ciudades son excluyentes, debe dejar en blanco alguno de los dos'
                )
            if not vals['permission_state_id'] and not vals[
                    'permission_city_id'] and not vals['is_permission_state']:
                raise UserError('Seleccione un departamento o una ciudad')
        res = super(ResPartnerPermission, self).create(vals)
        return res
示例#6
0
文件: product.py 项目: dzywenji/odoo
                It can also directly be set on each product.""")
    property_stock_valuation_account_id = fields.Many2one(
        'account.account', 'Stock Valuation Account', company_dependent=True,
        domain="[('company_id', '=', allowed_company_ids[0]), ('deprecated', '=', False)]", check_company=True,
        help="""When automated inventory valuation is enabled on a product, this account will hold the current value of the products.""",)

    @api.constrains('property_stock_valuation_account_id', 'property_stock_account_output_categ_id', 'property_stock_account_input_categ_id')
    def _check_valuation_accouts(self):
        # Prevent to set the valuation account as the input or output account.
        for category in self:
            valuation_account = category.property_stock_valuation_account_id
            input_and_output_accounts = category.property_stock_account_input_categ_id | category.property_stock_account_output_categ_id
            if valuation_account and valuation_account in input_and_output_accounts:
                raise ValidationError(_('The Stock Input and/or Output accounts cannot be the same than the Stock Valuation account.'))

    @api.onchange('property_cost_method')
    def onchange_property_valuation(self):
        if not self._origin:
            # don't display the warning when creating a product category
            return
        return {
            'warning': {
                'title': _("Warning"),
                'message': _("Changing your cost method is an important change that will impact your inventory valuation. Are you sure you want to make that change?"),
            }
        }

    def write(self, vals):
        impacted_categories = {}
        move_vals_list = []
        Product = self.env['product.product']
示例#7
0
class stock_picking(models.Model):
    _inherit = 'stock.picking'

    internal_note = fields.Text(string='Internal Note', )

    def action_cancel(self):
        res = super(stock_picking, self).action_cancel()
        if res == True:
            for line in self.move_lines:
                line.write({
                    'product_uom_qty': 0,
                    'price_tax': 0,
                    'price_total': 0,
                    'price_subtotal': 0
                })
            _logger.info('===========CANCEL_DELIVERY============')
            _logger.info(self.delivery_cost)
            self.write({'delivery_cost': 0})
            _logger.info(self.delivery_cost)
        return res

    def default_start_point(self):
        address = self.env['cb.delivery.address'].search(
            [('auto_select_start_point', '=', True)], limit=1)
        if address:
            return address
        return

    start_point = fields.Many2one('cb.delivery.address',
                                  string="Điểm bắt đầu",
                                  default=default_start_point)
    end_point = fields.Many2one('cb.delivery.address', string="Điểm đến")
    payment_term_id = fields.Many2one('account.payment.term',
                                      string='Payment Term')
    delivery_service = fields.Selection([
        ('internal', "Nội bộ"),
        ('collaborators', "Cộng tác viên"),
        ('partner', "Đối tác"),
    ],
                                        default="internal",
                                        string="Dịch vụ giao hàng")
    collaborators = fields.Many2one('res.partner',
                                    string="Nhân viên giao hàng")
    delivery_fee = fields.Float('Phụ phí giao hàng')
    source_way = fields.Float('Quãng đường đi',
                              compute='_compute_way',
                              store=True)
    destination_way = fields.Float('Quãng đường về',
                                   compute='_compute_way',
                                   store=True)
    total_way = fields.Float('Tổng quãng đường',
                             compute='_compute_way',
                             store=True)

    forecast_time = fields.Char('Thời gian dự đoán',
                                compute='_compute_way',
                                store=True)

    start_time = fields.Float('Thời gian xuất phát')
    end_time = fields.Float('Thời gian trở về')
    duration_time = fields.Char('Thời gian thực tế',
                                compute='_compute_time',
                                store=True)

    postage_total = fields.Float('Tổng cước phí',
                                 compute="_compute_postage_total",
                                 store=True)
    postage_delivery = fields.Float('Phí vận chuyển',
                                    compute='_compute_way',
                                    store=True)
    postage_delivery_fee = fields.Float('Phụ phí giao hàng')

    google_map = fields.Char('Map', compute='_compute_way', store=True)

    stock_tranfer_date = fields.Datetime('Dự kiến giao hàng')

    def default_stock_live_date(self):
        return self.stock_tranfer_date

    stock_live_date = fields.Datetime('Thực tế giao hàng',
                                      default=default_stock_live_date)

    stock_outin_date = fields.Datetime('Thời gian xuất/nhập kho')

    def do_new_transfer(self):
        res = super(stock_picking, self).do_new_transfer()
        _logger.info('++++++++++++++++++++++++++++++++++++++++++')
        _logger.info(res)
        self.stock_outin_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        return res

    warehouse_name = fields.Char(string="Source Location Name",
                                 related='location_id.warehouse_name',
                                 store=True)
    warehouse_destination_name = fields.Char(
        string="Destination Location Name",
        related='location_dest_id.warehouse_name',
        store=True)

    delivery_status = fields.Selection([('pending_delivery', 'Chờ giao'),
                                        ('delivering', 'Đang giao'),
                                        ('delivered', 'Đã giao')],
                                       default="pending_delivery")

    note_stock_picking = fields.Text(string='Ghi chú',
                                     compute="_compute_get_note_stock_picking",
                                     store=True)
    customer_reference = fields.Char("Customer reference")

    customer_type = fields.Selection([('cash', 'Tiền mặt'),
                                      ('debts', 'Công nợ'),
                                      ('deposit', 'Ký gởi'),
                                      ('internal', 'Nội bộ')],
                                     compute="_compute_get_customer_type")

    amount_untaxed = fields.Float(string='Untaxed Amount',
                                  store=True,
                                  readonly=True,
                                  compute='_amount_all')
    amount_tax = fields.Float(string='Taxes',
                              store=True,
                              readonly=True,
                              compute='_amount_all')
    amount_total = fields.Float(string='Total',
                                store=True,
                                readonly=True,
                                compute='_amount_all')
    pricelist_id = fields.Many2one('product.pricelist',
                                   string='Pricelist',
                                   readonly=True,
                                   help="Pricelist for current sales order.")

    apply_discount = fields.Boolean('Apply Discount', default=False)
    discount_type_id = fields.Many2one('discount.type', 'Discount Type')
    discount_value = fields.Float('Sale Discount')
    discount_value_const = fields.Float('Sale Discount')
    discount_account = fields.Many2one('account.account', 'Discount Account')
    amount_after_discount = fields.Float('Amount After Discount',
                                         store=True,
                                         readonly=True,
                                         compute='_amount_all')

    @api.depends('discount_value', 'delivery_cost', 'move_lines.price_total')
    def _amount_all(self):
        """
        Compute the total amounts of the SO.
        """
        discount_tmp = 0.0
        delivery_cost = 0.0
        amount_untaxed = 0.0

        amount_untaxed_tmp = 0.0  #add more
        amount_tax_tmp = 0.0  #add more

        amount_tax = 0.0
        amount_after_discount = 0.0
        discount = 0.0
        for pick in self:
            amount_untaxed = amount_tax = 0.0
            for line in pick.move_lines:
                if line.product_uom_qty > 0:
                    amount_untaxed += line.price_subtotal
                    amount_tax += line.price_tax if line.price_tax != False else 0

            total_cost = amount_untaxed + amount_tax if (
                amount_untaxed + amount_tax) > 0 else 0.0
            amount_after_discount = total_cost
            discount_value = pick.discount_value
            if pick.apply_discount == True:
                discount_type_percent = self.env[
                    'ir.model.data'].xmlid_to_res_id(
                        'bi_sale_purchase_invoice_discount.discount_type_percent_id'
                    )
                discount_type_fixed = self.env['ir.model.data'].xmlid_to_res_id(
                    'bi_sale_purchase_invoice_discount.discount_type_fixed_id')

                if pick.discount_type_id.id == discount_type_fixed:
                    discount = total_cost - pick.discount_value
                    amount_after_discount = discount
                elif pick.discount_type_id.id == discount_type_percent:
                    discount_percent = total_cost * (
                        (pick.discount_value or 0.0) / 100.0)
                    discount = total_cost - discount_percent
                    amount_after_discount = discount
                else:
                    amount_after_discount = total_cost

            _logger.info(pick.picking_type_code)
            if pick.picking_type_code == 'incoming':

                pick.update({
                    'discount_tmp': 0,
                    'amount_untaxed': amount_untaxed,
                    'amount_tax': amount_tax,
                    'amount_total': amount_after_discount + delivery_cost,
                    'total_cost': total_cost,
                    'amount_after_discount': amount_after_discount
                })
            elif pick.picking_type_code == 'outgoing':
                delivery_cost = pick.delivery_cost
                if (amount_after_discount + delivery_cost) <= 0:
                    discount_tmp = abs(amount_after_discount + delivery_cost)
                    discount_value = total_cost + delivery_cost
                    # amount_after_discount -= delivery_cost

                if pick.pricelist_id:
                    amount_untaxed_tmp = pick.pricelist_id.currency_id.round(
                        amount_untaxed)
                    amount_tax_tmp = pick.pricelist_id.currency_id.round(
                        amount_tax)
                else:
                    amount_untaxed_tmp = amount_untaxed
                    amount_tax_tmp = amount_tax
                amount_untaxed = amount_untaxed_tmp if amount_untaxed_tmp > 0 else amount_untaxed
                amount_tax = amount_tax_tmp if amount_tax_tmp > 0 else amount_tax
                amount_total = amount_after_discount + delivery_cost if (
                    amount_after_discount + delivery_cost) > 0 else 0.0

                pick.update({
                    'discount_value':
                    discount_value,
                    'discount_tmp':
                    discount_tmp,
                    # 'delivery_cost': delivery_cost if pick.state != 'cancel' else 0,
                    'amount_untaxed':
                    amount_untaxed if pick.state != 'cancel' else 0,
                    'amount_tax':
                    amount_tax if pick.state != 'cancel' else 0,
                    'amount_total':
                    amount_total if pick.state != 'cancel' else 0,
                    'total_cost':
                    total_cost if pick.state != 'cancel' else 0,
                    'amount_after_discount':
                    amount_after_discount if pick.state != 'cancel' else 0
                })

    def _create_backorder(self, backorder_moves=[]):
        res = super(stock_picking, self)._create_backorder(backorder_moves)
        if res:
            do = self.search([('backorder_id', '=', self.id)], limit=1)
            if do:
                if self.apply_discount == True:
                    discount_value = self.discount_value
                    discount_type_fixed = self.env[
                        'ir.model.data'].xmlid_to_res_id(
                            'bi_sale_purchase_invoice_discount.discount_type_fixed_id'
                        )
                    if self.discount_type_id.id == discount_type_fixed:
                        if self.discount_tmp > 0:
                            discount_value = self.discount_tmp
                        else:
                            discount_value = 0.0
                    do.write({
                        'discount_value': discount_value,
                        'delivery_cost': 0.0
                    })
                    do.update_total()
                    self.update_total()
                else:
                    do.write({'delivery_cost': 0.0})
                    do.update_total()
                    self.update_total()

        return res

    def update_total(self):
        self._amount_all()
        # discount_tmp = 0.0
        # delivery_cost = 0.0
        # amount_untaxed = 0.0

        # amount_untaxed_tmp = 0.0 #add more
        # amount_tax_tmp = 0.0 #add more

        # amount_tax = 0.0
        # amount_after_discount = 0.0
        # discount = 0.0
        # amount_untaxed = amount_tax = 0.0
        # for line in self.move_lines:
        #     if line.product_uom_qty > 0:
        #         amount_untaxed += line.price_subtotal
        #         amount_tax += line.price_tax if line.price_tax != False else 0

        # total_cost = amount_untaxed + amount_tax if (amount_untaxed + amount_tax) > 0 else 0.0
        # amount_after_discount = total_cost
        # discount_value = self.discount_value
        # if self.apply_discount == True:
        #     discount_type_percent = self.env['ir.model.data'].xmlid_to_res_id('bi_sale_purchase_invoice_discount.discount_type_percent_id')
        #     discount_type_fixed = self.env['ir.model.data'].xmlid_to_res_id('bi_sale_purchase_invoice_discount.discount_type_fixed_id')
        #     discount_value = self.discount_value
        #     if self.discount_type_id.id == discount_type_fixed:
        #         discount = total_cost  - self.discount_value
        #         amount_after_discount = discount

        #     elif self.discount_type_id.id == discount_type_percent:
        #         discount_percent = total_cost * ((self.discount_value or 0.0) / 100.0)
        #         discount = total_cost - discount_percent
        #         amount_after_discount = discount
        #     else:
        #         amount_after_discount = total_cost

        # _logger.info(self.picking_type_code)
        # if self.picking_type_code == 'incoming':
        #     self.write({
        #         'discount_tmp': 0,
        #         'amount_untaxed': amount_untaxed,
        #         'amount_tax': amount_tax,
        #         'amount_total': amount_after_discount + delivery_cost,
        #         'total_cost' : total_cost,
        #         'amount_after_discount' : amount_after_discount,
        #         'no_update': 1
        #     })
        # elif self.picking_type_code == 'outgoing':
        #     delivery_cost = self.delivery_cost
        #     if (amount_after_discount + delivery_cost) < 0:
        #         discount_tmp = abs(amount_after_discount + delivery_cost)
        #         discount_value = total_cost + delivery_cost
        #         amount_after_discount -= delivery_cost
        #     if self.pricelist_id:
        #         amount_untaxed_tmp = self.pricelist_id.currency_id.round(amount_untaxed)
        #         amount_tax_tmp = self.pricelist_id.currency_id.round(amount_tax)
        #     else:
        #         amount_untaxed_tmp = amount_untaxed
        #         amount_tax_tmp = amount_tax
        #     amount_untaxed = amount_untaxed_tmp if amount_untaxed_tmp > 0 else amount_untaxed
        #     amount_tax = amount_tax_tmp if amount_tax_tmp > 0 else amount_tax
        #     amount_total = amount_after_discount + delivery_cost if (amount_after_discount + delivery_cost) > 0 else 0.0

        #     self.write({
        #         'discount_value': discount_value,
        #         'discount_tmp': discount_tmp,
        #         # 'delivery_cost': delivery_cost if self.state != 'cancel' else 0,
        #         'amount_untaxed': amount_untaxed if self.state != 'cancel' else 0,
        #         'amount_tax': amount_tax if self.state != 'cancel' else 0,
        #         'amount_total': amount_total if self.state != 'cancel' else 0,
        #         'total_cost' : total_cost if self.state != 'cancel' else 0,
        #         'amount_after_discount' : amount_after_discount if self.state != 'cancel' else 0,
        #         'no_update': 1
        #     })

    @api.model
    def create(self, vals):
        po = so = None
        if self.picking_type_code:
            if self.picking_type_code == 'incoming':
                po = self.env['purchase.order'].search(
                    [('name', '=', self.origin)], limit=1)
                # if po:
                #     vals.update({
                #         'amount_untaxed': po.amount_untaxed,
                #         'amount_tax': po.amount_tax,
                #         'amount_total': po.amount_total,
                #         'delivery_cost': 0,
                #         'discount_tmp': 0,
                #         'total_cost': po.amount_untaxed + po.amount_tax,
                #         'apply_discount': po.apply_discount,
                #         'discount_value': po.discount_value,
                #         'discount_value_const': po.discount_value,
                #         'discount_account': po.discount_account.id if po.discount_account != False else False
                #     })
            elif self.picking_type_code == 'outgoing':
                so = self.env['sale.order'].search(
                    [('name', '=', self.origin)], limit=1)
                # if so:
                #     vals.update({
                #         'amount_untaxed': so.amount_untaxed,
                #         'amount_tax': so.amount_tax,
                #         'amount_total': so.amount_total,
                #         'pricelist_id': so.pricelist_id.id if so.pricelist_id != False else False,
                #         'delivery_cost': so.delivery_cost,
                #         'discount_tmp': 0,
                #         'total_cost': so.amount_untaxed + so.amount_tax,
                #         'apply_discount': so.apply_discount,
                #         'discount_type_id': so.discount_type_id.id if so.discount_type_id != False else False,
                #         'discount_value': so.discount_value,
                #         'discount_value_const': so.discount_value,
                #         'discount_account': so.discount_account.id if so.discount_account != False else False
                #     })
        _logger.info("=============LOG====")
        _logger.info(vals)
        if vals.has_key('move_lines'):
            for index, value in enumerate(vals['move_lines']):
                if vals['move_lines'][index][2]:
                    product_id = vals['move_lines'][index][2]['product_id']
                    product = self.env['product.product'].browse(product_id)
                    vals['move_lines'][index][2][
                        'product_uom'] = product.uom_po_id.id or product.uom_id.id
        # if vals.has_key('pack_operation_product_ids'):
        #     for index,value in enumerate(vals['pack_operation_product_ids']):
        #         if vals['pack_operation_product_ids'][index][2]:
        #             product_id = vals['pack_operation_product_ids'][index][2]['product_id']
        #             product = self.env['product.product'].browse(product_id)
        #             vals['pack_operation_product_ids'][index][2]['product_uom'] = product.uom_po_id.id or product.uom_id.id
        _logger.info(vals)
        res = super(stock_picking, self).create(vals)
        if po:
            if po.delivery_status != self.state:
                po.write({'delivery_status': self.state})
        if so:
            if so.delivery_status != self.state:
                so.write({'delivery_status': self.state})
        return res

    @api.multi
    def write(self, vals):
        po = so = None
        _logger.info(vals)
        for record in self:
            if record.picking_type_code:
                if record.picking_type_code == 'incoming':
                    po = record.env['purchase.order'].search(
                        [('name', '=', record.origin)], limit=1)
                    # if po:
                    #     if vals.has_key('no_update') == False:
                    #         vals.update({
                    #             #'amount_untaxed': po.amount_untaxed,
                    #             #'amount_tax': po.amount_tax,
                    #             #'amount_total': po.amount_total,
                    #             'delivery_cost': 0,
                    #             'apply_discount': po.apply_discount,
                    #             'discount_type_id': po.discount_type_id.id if po.discount_type_id != False else False,
                    #             'discount_value': po.discount_value,
                    #             'discount_value_const': po.discount_value,
                    #             'discount_account': po.discount_account.id if po.discount_account != False else False
                    #         })
                    #     else:
                    #         del vals['no_update']
                elif record.picking_type_code == 'outgoing':
                    so = record.env['sale.order'].search(
                        [('name', '=', record.origin)], limit=1)
                    # if so:
                    #     if vals.has_key('no_update') == False:
                    #         vals.update({
                    #             #'amount_untaxed': so.amount_untaxed if record.state != 'cancel' else 0,
                    #             #'amount_tax': so.amount_tax if record.state != 'cancel' else 0,
                    #             #'amount_total': so.amount_total if record.state != 'cancel' else 0,
                    #             'delivery_cost': so.delivery_cost if record.state != 'cancel' else 0,
                    #             'apply_discount': so.apply_discount,
                    #             'discount_type_id': so.discount_type_id.id if so.discount_type_id != False else False,
                    #             'discount_value': so.discount_value,
                    #             'discount_value_const': so.discount_value,
                    #             'discount_account': so.discount_account.id if so.discount_account != False else False
                    #         })
                    #     else:
                    #         del vals['no_update']
        _logger.info("===========MOVE_LINES============")
        _logger.info(vals)
        if vals.has_key('move_lines'):
            for index, value in enumerate(vals['move_lines']):
                if vals['move_lines'][index][2] and vals['move_lines'][index][
                        2].has_key('product_id'):
                    product_id = vals['move_lines'][index][2]['product_id']
                    product = self.env['product.product'].browse(product_id)
                    vals['move_lines'][index][2][
                        'product_uom'] = product.uom_po_id.id or product.uom_id.id
        res = super(stock_picking, self).write(vals)
        for record in self:
            if po:
                if po.delivery_status != record.state:
                    po.write({'delivery_status': record.state})
            if so:
                if so.delivery_status != record.state:
                    so.write({'delivery_status': record.state})
            if vals.has_key("delivery_service") and vals.has_key(
                    "postage_delivery") and (
                        vals.get("delivery_service") == 'partner'
                        or vals.get("delivery_service") == 'internal'):
                record.write(
                    {'postage_delivery': vals.get("postage_delivery")})
        return res

    @api.onchange('delivery_service')
    def _onchange_delivery_service(self):
        if self.delivery_service != '':
            self.collaborators = None
            return {
                'domain': {
                    'collaborators':
                    [('delivery_service', '=', self.delivery_service)]
                }
            }

    pricelist_id = fields.Many2one('product.pricelist',
                                   string='Pricelist',
                                   required=True,
                                   readonly=True,
                                   states={
                                       'draft': [('readonly', False)],
                                       'sent': [('readonly', False)]
                                   },
                                   help="Pricelist for current sales order.")
    currency_id = fields.Many2one("res.currency",
                                  related='pricelist_id.currency_id',
                                  string="Currency",
                                  readonly=True,
                                  required=True)

    delivery_cost = fields.Monetary(string='Phí giao hàng',
                                    store=True,
                                    default=0,
                                    readonly=True)

    total_cost = fields.Monetary(store=True,
                                 string='Tồng tiền tạm tính',
                                 readonly=True,
                                 compute="_amount_all")
    discount_tmp = fields.Monetary(store=True,
                                   string='Giam gia con lai',
                                   readonly=True,
                                   compute="_amount_all")

    @api.onchange('start_point', 'end_point', 'delivery_service')
    def _onchange_start_end_point(self):
        if self.start_point.id > 0 and self.end_point.id > 0:
            return self.calc_way(self.start_point.name, self.end_point.name,
                                 self.delivery_service, self.start_point.id,
                                 self.end_point.id)

    @api.depends('start_point', 'end_point', 'source_way', 'destination_way',
                 'total_way', 'forecast_time', 'delivery_service')
    def _compute_way(self):
        if self.start_point.id > 0 and self.end_point.id > 0:
            ways = self.calc_way(self.start_point.name, self.end_point.name,
                                 self.delivery_service, self.start_point.id,
                                 self.end_point.id)
            self.source_way = ways['value']['source_way']
            self.destination_way = ways['value']['destination_way']
            self.total_way = ways['value']['total_way']
            self.forecast_time = ways['value']['forecast_time']
            self.postage_delivery = ways['value']['postage_delivery']
            self.google_map = ways['value']['google_map']

    def calc_way(self, start_point_name, end_point_name, delivery_service,
                 start_point_id, end_point_id):

        source_way = 0.0
        destination_way = 0.0
        total_way = 0.0
        forecast_time = '0 mins'
        postage_delivery = 0
        google_map = ''
        delivery_address_info_object = self.env['cb.delivery.address.info']
        delivery_address_info = delivery_address_info_object.search(
            [('start_point', '=', start_point_id),
             ('end_point', '=', end_point_id)],
            limit=1)
        if delivery_address_info:
            source_way = delivery_address_info.source_way
            destination_way = delivery_address_info.destination_way
            total_way = delivery_address_info.total_way
            forecast_time = delivery_address_info.forecast_time
            google_map = delivery_address_info.google_map
            if total_way > 0:
                postage_delivery = self.calc_postage_delivery(
                    total_way, delivery_service, source_way)
        else:
            distance_matrix = gmaps.distance_matrix(
                origins=start_point_name,
                destinations=end_point_name,
                mode="driving")
            _logger.info('================GOOGLE MAPS=======================')
            _logger.info(distance_matrix)
            _logger.info(distance_matrix.get('status'))
            if distance_matrix.get('status') == 'OK':
                rows = distance_matrix.get('rows')
                _logger.info(rows[0])
                elements = rows[0]['elements'][0]
                if (elements.get('status') == 'OK'):
                    duration = elements.get('duration')
                    distance = elements.get('distance')
                    source_way = round(float(distance.get('value') / 1000.0),
                                       2)
                    destination_way = source_way
                    total_way = source_way + destination_way
                    forecast_time = duration.get('text')
            if total_way > 0:
                postage_delivery = self.calc_postage_delivery(
                    total_way, delivery_service)

            google_map = "https://maps.google.com?saddr=" + str(
                start_point_name) + "&daddr=" + str(end_point_name)

            delivery_address_info_object.create({
                'name': start_point_name + end_point_name,
                'start_point': start_point_id,
                'end_point': end_point_id,
                'source_way': source_way,
                'destination_way': destination_way,
                'total_way': total_way,
                'forecast_time': forecast_time,
                'google_map': google_map,
            })
        return {
            'value': {
                'source_way': source_way,
                'destination_way': destination_way,
                'total_way': total_way,
                'forecast_time': forecast_time,
                'postage_delivery': postage_delivery,
                'google_map': google_map
            }
        }

    # duration
    @api.onchange('start_time', 'end_time')
    def _get_duration_date(self):
        durationtext = '0 mins'
        if self.start_time and self.end_time:
            return self.calc_time(self.start_time, self.end_time)
            # duration = duration.days
    @api.depends('start_time', 'end_time', 'duration_time')
    def _compute_time(self):
        time = self.calc_time(self.start_time, self.end_time)
        self.duration_time = time['value']['duration_time']

    def calc_time(self, start_time, end_time):
        duration = end_time - start_time
        _logger.info(duration)
        calcduration = duration * 60.0
        if calcduration > 60:
            intpart = int(duration)
            floatpart = duration - intpart
            durationtext = str(int(round(intpart, 2))) + ' hours'
            if (floatpart > 0):
                _logger.info(floatpart)
                durationtext = durationtext + ' ' + str(
                    int(round(floatpart * 60.0))) + ' mins'
        else:
            durationtext = str(calcduration) + ' mins'
        return {'value': {'duration_time': durationtext}}

    @api.depends('postage_delivery', 'postage_delivery_fee', 'postage_total')
    def _compute_postage_total(self):
        self.postage_total = self.postage_delivery + self.postage_delivery_fee

    @api.onchange('postage_delivery', 'postage_delivery_fee')
    def _onchange_postage(self):
        postage_total = self.postage_delivery + self.postage_delivery_fee
        return {'value': {'postage_total': postage_total}}

    def calc_postage_delivery(self, total_way, delivery_service, source_way=0):
        postage_delivery = 0
        conf = self.env['ir.config_parameter']
        if delivery_service == 'internal':
            _logger.info('internal')
            # gas = float(conf.get_param('gas_verification.gas'))
            # avggasinkm = float(conf.get_param('avggasinkm_verification.avggasinkm'))
            # if avggasinkm > 0:
            #     postage_delivery = (total_way * gas) / avggasinkm
        else:
            if delivery_service == 'collaborators':
                if source_way < 5:
                    postage_delivery = 20000
                else:
                    if source_way < 10:
                        postage_delivery = 30000
                    else:
                        if source_way < 15:
                            postage_delivery = 40000
                        else:
                            if source_way < 20:
                                postage_delivery = 50000
                            else:
                                postage_delivery = 60000

            else:
                _logger.info('partner')

        return postage_delivery

    def export_data(self, fields, data=False):
        dataindex_1 = dataindex_2 = dataindex_3 = dataindex_4 = dataindex_5 = dataindex_6 = dataindex_7 = None
        _logger.info('+' * 20)
        for index, fieldlabel in enumerate(fields):
            _logger.info(fieldlabel)
            if fieldlabel == 'stock_tranfer_date':
                dataindex_1 = index
            if fieldlabel == 'min_date':
                dataindex_2 = index
            if fieldlabel == 'stock_outin_date':
                dataindex_3 = index
            if fieldlabel == 'stock_live_date':
                dataindex_4 = index
            if fieldlabel == 'sale_id/date_order':
                dataindex_5 = index
            if fieldlabel == 'sale_id/confirmation_date':
                dataindex_6 = index
            if fieldlabel == 'sale_id/stock_tranfer_date':
                dataindex_7 = index
        res = super(stock_picking, self).export_data(fields, data)
        try:
            for index, val in enumerate(res['datas']):
                if dataindex_1:
                    service_date = res['datas'][index][dataindex_1]
                    sdate = service_date
                    if sdate:
                        sdate = str(sdate)
                        db_timezone = self.env.context.get(
                            'tz') or 'Asia/Ho_Chi_Minh'
                        dbtz = pytz.timezone(db_timezone)
                        utctz = pytz.timezone('UTC')
                        sdate_dt = datetime.strptime(sdate,
                                                     "%Y-%m-%d %H:%M:%S")
                        utctz_dt = utctz.localize(sdate_dt, is_dst=None)
                        db_dt = utctz_dt.astimezone(dbtz)
                        sdate = db_dt.strftime('%m/%d/%Y %H:%M:%S')
                        res['datas'][index][dataindex_1] = sdate
                if dataindex_2:
                    service_date = res['datas'][index][dataindex_2]
                    sdate = service_date
                    if sdate:
                        sdate = str(sdate)
                        db_timezone = self.env.context.get(
                            'tz') or 'Asia/Ho_Chi_Minh'
                        dbtz = pytz.timezone(db_timezone)
                        utctz = pytz.timezone('UTC')
                        sdate_dt = datetime.strptime(sdate,
                                                     "%Y-%m-%d %H:%M:%S")
                        utctz_dt = utctz.localize(sdate_dt, is_dst=None)
                        db_dt = utctz_dt.astimezone(dbtz)
                        sdate = db_dt.strftime('%m/%d/%Y %H:%M:%S')
                        res['datas'][index][dataindex_2] = sdate
                if dataindex_3:
                    service_date = res['datas'][index][dataindex_3]
                    sdate = service_date
                    if sdate:
                        sdate = str(sdate)
                        db_timezone = self.env.context.get(
                            'tz') or 'Asia/Ho_Chi_Minh'
                        dbtz = pytz.timezone(db_timezone)
                        utctz = pytz.timezone('UTC')
                        sdate_dt = datetime.strptime(sdate,
                                                     "%Y-%m-%d %H:%M:%S")
                        utctz_dt = utctz.localize(sdate_dt, is_dst=None)
                        db_dt = utctz_dt.astimezone(dbtz)
                        sdate = db_dt.strftime('%m/%d/%Y %H:%M:%S')
                        res['datas'][index][dataindex_3] = sdate
                if dataindex_4:
                    service_date = res['datas'][index][dataindex_4]
                    sdate = service_date
                    if sdate:
                        sdate = str(sdate)
                        db_timezone = self.env.context.get(
                            'tz') or 'Asia/Ho_Chi_Minh'
                        dbtz = pytz.timezone(db_timezone)
                        utctz = pytz.timezone('UTC')
                        sdate_dt = datetime.strptime(sdate,
                                                     "%Y-%m-%d %H:%M:%S")
                        utctz_dt = utctz.localize(sdate_dt, is_dst=None)
                        db_dt = utctz_dt.astimezone(dbtz)
                        sdate = db_dt.strftime('%m/%d/%Y %H:%M:%S')
                        res['datas'][index][dataindex_4] = sdate
                if dataindex_5:
                    service_date = res['datas'][index][dataindex_5]
                    sdate = service_date
                    if sdate:
                        sdate = str(sdate)
                        db_timezone = self.env.context.get(
                            'tz') or 'Asia/Ho_Chi_Minh'
                        dbtz = pytz.timezone(db_timezone)
                        utctz = pytz.timezone('UTC')
                        sdate_dt = datetime.strptime(sdate,
                                                     "%Y-%m-%d %H:%M:%S")
                        utctz_dt = utctz.localize(sdate_dt, is_dst=None)
                        db_dt = utctz_dt.astimezone(dbtz)
                        sdate = db_dt.strftime('%m/%d/%Y %H:%M:%S')
                        res['datas'][index][dataindex_5] = sdate
                if dataindex_6:
                    service_date = res['datas'][index][dataindex_6]
                    sdate = service_date
                    if sdate:
                        sdate = str(sdate)
                        db_timezone = self.env.context.get(
                            'tz') or 'Asia/Ho_Chi_Minh'
                        dbtz = pytz.timezone(db_timezone)
                        utctz = pytz.timezone('UTC')
                        sdate_dt = datetime.strptime(sdate,
                                                     "%Y-%m-%d %H:%M:%S")
                        utctz_dt = utctz.localize(sdate_dt, is_dst=None)
                        db_dt = utctz_dt.astimezone(dbtz)
                        sdate = db_dt.strftime('%m/%d/%Y %H:%M:%S')
                        res['datas'][index][dataindex_6] = sdate
                if dataindex_7:
                    service_date = res['datas'][index][dataindex_7]
                    sdate = service_date
                    if sdate:
                        sdate = str(sdate)
                        db_timezone = self.env.context.get(
                            'tz') or 'Asia/Ho_Chi_Minh'
                        dbtz = pytz.timezone(db_timezone)
                        utctz = pytz.timezone('UTC')
                        sdate_dt = datetime.strptime(sdate,
                                                     "%Y-%m-%d %H:%M:%S")
                        utctz_dt = utctz.localize(sdate_dt, is_dst=None)
                        db_dt = utctz_dt.astimezone(dbtz)
                        sdate = db_dt.strftime('%m/%d/%Y %H:%M:%S')
                        res['datas'][index][dataindex_7] = sdate
        except Exception:
            pass
        return res

    @api.depends('origin')
    def _compute_get_note_stock_picking(self):
        for record in self:
            if record.picking_type_code:
                if record.picking_type_code == 'incoming':
                    po = record.env['purchase.order'].search(
                        [('name', '=', record.origin)], limit=1)
                    if po:
                        record.note_stock_picking = po.notes
                elif record.picking_type_code == 'outgoing':
                    so = record.env['sale.order'].search(
                        [('name', '=', record.origin)], limit=1)
                    if so:
                        record.note_stock_picking = so.note

    @api.depends('partner_id')
    def _compute_get_customer_type(self):
        for record in self:
            if record.partner_id:
                if record.partner_id.customer_type:
                    record.customer_type = record.partner_id.customer_type

    api.onchange('partner_id')

    def _onchange_partner_id(self):
        if record.partner_id:
            if record.partner_id.customer_type:
                record.customer_type = record.partner_id.customer_type
示例#8
0
=======
        fiscal_position = self.env['account.fiscal.position'].with_company(self.company_id).get_fiscal_position(
>>>>>>> f0a66d05e70e432d35dc68c9fb1e1cc6e51b40b8
            self.partner_id.id, delivery_id=delivery_partner_id)

        if fiscal_position:
            self.fiscal_position_id = fiscal_position

    def unlink(self):
        downpayment_lines = self.mapped('line_ids.sale_line_ids').filtered(lambda line: line.is_downpayment)
        res = super(AccountMove, self).unlink()
        if downpayment_lines:
            downpayment_lines.unlink()
        return res

    @api.onchange('partner_id')
    def _onchange_partner_id(self):
        # OVERRIDE
        # Recompute 'partner_shipping_id' based on 'partner_id'.
        addr = self.partner_id.address_get(['delivery'])
        self.partner_shipping_id = addr and addr.get('delivery')

        res = super(AccountMove, self)._onchange_partner_id()

        # Recompute 'narration' based on 'company.invoice_terms'.
        if self.move_type == 'out_invoice':
            self.narration = self.company_id.with_context(lang=self.partner_id.lang).invoice_terms

        return res

    @api.onchange('invoice_user_id')