~eduardo-bayardo-bias/openobject-addons/addons_interface

« back to all changes in this revision

Viewing changes to partner_credit_limit/sale.py

  • Committer: Eduardo Bayardo
  • Date: 2017-08-15 21:49:35 UTC
  • Revision ID: eduardo.bayardo@bias.com.mx-20170815214935-94uhog6hvq6em5mj
set correct date at sale order validation (sock.move, stock.picking)... Create Invoice defaults from pickings

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
 
6
#
 
7
#    This program is free software: you can redistribute it and/or modify
 
8
#    it under the terms of the GNU Affero General Public License as
 
9
#    published by the Free Software Foundation, either version 3 of the
 
10
#    License, or (at your option) any later version.
 
11
#
 
12
#    This program is distributed in the hope that it will be useful,
 
13
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
#    GNU Affero General Public License for more details.
 
16
#
 
17
#    You should have received a copy of the GNU Affero General Public License
 
18
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
#
 
20
##############################################################################
 
21
 
 
22
import time
 
23
import netsvc
 
24
from osv import fields, osv
 
25
from mx import DateTime
 
26
from tools import config
 
27
from tools.translate import _
 
28
import time
 
29
from datetime import datetime, timedelta
 
30
 
 
31
class sale_order(osv.osv):
 
32
    _inherit = "sale.order"
 
33
 
 
34
    _columns = {
 
35
            'copy': fields.boolean('Copy'),
 
36
            'state': fields.selection([
 
37
            ('draft', 'Quotation'),
 
38
            ('pre_approve', 'Pre-Approve'),
 
39
            ('waiting_date', 'Waiting Schedule'),
 
40
            ('manual', 'Manual In Progress'),
 
41
            ('progress', 'In Progress'),
 
42
            ('shipping_except', 'Shipping Exception'),
 
43
            ('invoice_except', 'Invoice Exception'),
 
44
            ('done', 'Done'),
 
45
            ('cancel', 'Cancelled')
 
46
            ], 'Order State', readonly=True, help="Gives the state of the quotation or sales order. \nThe exception state is automatically set when a cancel operation occurs in the invoice validation (Invoice Exception) or in the picking list process (Shipping Exception). \nThe 'Waiting Schedule' state is set when the invoice is confirmed but waiting for the scheduler to run on the date 'Ordered Date'.", select=True),
 
47
        'element': fields.char('Elemento a Colar', size=64, readonly=True, states={'draft': [('readonly', False)]}),
 
48
        }
 
49
 
 
50
    def copy(self, cr, uid, id, default=None, context=None):
 
51
        if not default:
 
52
            default = {}
 
53
        payment_term = False
 
54
        if id:
 
55
            partner_term = self.browse(cr, uid, id).partner_id.property_payment_term
 
56
            payment_term = partner_term and partner_term.id
 
57
        default.update({
 
58
            'date_order': (datetime.strptime(time.strftime('%Y-%m-%d'), '%Y-%m-%d') + timedelta(days=1)).strftime('%Y-%m-%d'),
 
59
            'payment_term': payment_term,
 
60
            'copy': True,
 
61
        })
 
62
        return super(sale_order, self).copy(cr, uid, id, default, context=context)
 
63
 
 
64
    def write(self, cr, uid, ids, vals, context=None):
 
65
        group_id = self.pool.get('sale.order.line').get_obj(cr, uid, 'res.groups', 'account_payment.group_account_payment')
 
66
        payment_group_users = [x.id for x in self.pool.get('res.groups').browse(cr, uid, group_id).users]
 
67
        so = self.browse(cr, uid, ids)[0]
 
68
        copy = so.copy
 
69
        if ('copy' in vals):
 
70
            copy = vals['copy']
 
71
        if ('payment_term' in vals) and not (uid in payment_group_users):
 
72
            raise osv.except_osv(_('Error !'), _('Solo los usuarios en el grupo Accounting / Payment pueden modificar el termino de pago.'))
 
73
        if not copy:
 
74
            if ('user_id' in vals):
 
75
                raise osv.except_osv(_('Error !'), _('El asesor comercial no se puede cambiar en el pedido de venta.'))
 
76
            if ('state' in vals):
 
77
                raise osv.except_osv(_('Error !'), _('Este pedido de venta es el acuerdo comercial y no puede cambiar de estado.'))
 
78
            if uid != so.user_id.id:
 
79
                raise osv.except_osv(_('Error !'), _('Este pedido de venta es el acuerdo comercial solo puede ser modificado por el vendedor asignado'))
 
80
        return super(sale_order, self).write(cr, uid, ids, vals, context=context)
 
81
 
 
82
    def get_saldo_credit_limit(self, cr, uid, ids, context=None):
 
83
        so = self.browse(cr, uid, ids[0], context)
 
84
        partner = so.partner_id        
 
85
        moveline_obj = self.pool.get('account.move.line')
 
86
        movelines = moveline_obj.search(cr, uid, [('partner_id', '=', partner.id),('account_id.type', 'in', ['receivable', 'payable']), ('state', '<>', 'draft'), ('reconcile_id', '=', False)])
 
87
        movelines = moveline_obj.browse(cr, uid, movelines)        
 
88
        debit, credit = 0.0, 0.0
 
89
        dias_vencimiento = True
 
90
        for line in movelines:
 
91
            credit += line.debit
 
92
            debit += line.credit
 
93
            if not (line.date_maturity <= time.strftime('%Y-%m-%d')):
 
94
                dias_vencimiento = False
 
95
        return (credit - debit), dias_vencimiento
 
96
 
 
97
    def get_partner_contado(self, cr, uid, ids, context):
 
98
        so = self.browse(cr, uid, ids[0], context)
 
99
        partner = so.partner_id
 
100
        contado = False
 
101
        payment_term = str(so.payment_term.name).lower()
 
102
        if payment_term.find('contado') >= 0:
 
103
            contado = True
 
104
        return contado
 
105
 
 
106
 
 
107
    def check_limit(self, cr, uid, ids, context={}):
 
108
        so = self.browse(cr, uid, ids[0], context)
 
109
        partner = so.partner_id
 
110
        if len([x for x in so.order_line if x.product_id.type=='product']) > 1:
 
111
            raise osv.except_osv(_("Error !"), _("Only sale orders with one line can be preaproved !"))
 
112
        if partner.over_credit:
 
113
            return True
 
114
 
 
115
        contado = self.get_partner_contado(cr, uid, ids, context)
 
116
        saldo, dias_vencimiento = self.get_saldo_credit_limit(cr, uid, ids, context)
 
117
        if contado:
 
118
            if (saldo + so.amount_total) <= 0:
 
119
                return True
 
120
            else:
 
121
                raise osv.except_osv(_("Credit Over Limits !"), _("No se puede confirmar la Venta! \n '(Total facturas con saldo pendiente - Total de pagos no aplicados + Total pedido a autorizar)' No es <= 0.0 \n  %s <= 0.0  !"%(saldo + so.amount_total) ))
 
122
        else:
 
123
            if not dias_vencimiento:
 
124
                raise osv.except_osv(_("Credit Over Limits !"), _("No se puede confirmar la Venta! \n 'Los dias del Vencimiento de La Factura no es <= Días de Plazo de Pago !"))
 
125
 
 
126
            if not ((saldo + so.amount_total) <= partner.credit_limit):
 
127
                raise osv.except_osv(_("Credit Over Limits !"), _("No se puede confirmar la Venta! \n ' (Total facturas con saldo pendiente - Total de pagos no aplicados + Total pedido a autorizar) NO es <= Limite de Credito \n %s <= %s !"%(saldo + so.amount_total, partner.credit_limit) ))
 
128
 
 
129
        return True
 
130
 
 
131
sale_order()
 
132
 
 
133
class sale_order_line(osv.osv):
 
134
    _inherit = "sale.order.line"
 
135
 
 
136
    def get_obj(self, cr, uid, model, external_id):
 
137
        # Return id from Model and External ID
 
138
        obj_id = False
 
139
        try:
 
140
            external_id = external_id.split('.')[1]
 
141
        except:
 
142
            osv.except_osv(_('Warning!'), _('Such External ID does not Exist!'))
 
143
        model_data_pool = self.pool.get('ir.model.data')
 
144
        ir_model_data_id = model_data_pool.search(cr, uid, [('model', '=', model), ('name', '=', external_id)])
 
145
        if ir_model_data_id:
 
146
            ir_model_data_obj = model_data_pool.browse(cr, uid, ir_model_data_id)[0]
 
147
            obj = self.pool.get(model).browse(cr, uid, ir_model_data_obj.res_id)
 
148
            obj_id = obj and obj.id
 
149
        else:
 
150
            osv.except_osv(_('Warning!'), _('Such External ID does not Exist!'))
 
151
        return obj_id
 
152
 
 
153
    def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
 
154
            uom=False, qty_uos=0, uos=False, name='', partner_id=False,
 
155
            lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False):
 
156
        group_id = self.get_obj(cr, uid, 'res.groups', 'base.group_sale_price_modificator')
 
157
        users = [x.id for x in self.pool.get('res.groups').browse(cr, uid, group_id).users]
 
158
        if not uid in users:
 
159
            return {}        
 
160
        res = super(sale_order_line, self).product_id_change(cr, uid, ids, pricelist, product, qty=qty,
 
161
            uom=uom, qty_uos=qty_uos, uos=uos, name=name, partner_id=partner_id,
 
162
            lang=lang, update_tax=update_tax, date_order=date_order, packaging=packaging, fiscal_position=fiscal_position, flag=flag)
 
163
        return res
 
164
 
 
165
sale_order_line()
 
166
 
 
167
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: