Beispiel #1
0
class policy_line_ot(models.Model):

    _name = 'hr.policy.line.ot'

    def _tz_list(self, cr, uid, context=None):

        res = tuple()
        for name in common_timezones:
            res += ((name, name),)
        return res

    _columns = {
        'name': fields.char('Name', size=64, required=True),
        'policy_id': fields.many2one('hr.policy.ot', 'Policy'),
        'type': fields.selection([('daily', 'Daily'),
                                  ('weekly', 'Weekly'),
                                  ('restday', 'Rest Day'),
                                  ('holiday', 'Public Holiday')],
                                 'Type', required=True),
        'weekly_working_days': fields.integer('Weekly Working Days'),
        'active_after': fields.integer(
            'Active After', help="Minutes after which this policy applies"),
        'active_start_time': fields.char(
            'Active Start Time', size=5, help="Time in 24 hour time format"),
        'active_end_time': fields.char(
            'Active End Time', size=5, help="Time in 24 hour time format"),
        'tz': fields.selection(_tz_list, 'Time Zone'),
        'rate': fields.float(
            'Rate', required=True, help='Multiplier of employee wage.'),
        'code': fields.char(
            'Code', required=True, help="Use this code in the salary rules.")
    }
class nomor_faktur_pajak(osv.osv):
    _name = "nomor.faktur.pajak"
    _description = 'Nomor faktur Pajak'

    def _nomor_faktur(self, cr, uid, ids, nomorfaktur, arg, context=None):
        res = {}
        for nomor in self.browse(cr, uid, ids, context):    
            res[nomor.id] = "%s.%s.%s" % (nomor.nomor_perusahaan, nomor.tahun_penerbit, nomor.nomor_urut)
        return res
    
    _columns = {
        'nomor_perusahaan' : fields.char('Nomor Perusahaan', size=3),
        'tahun_penerbit': fields.char('Tahun Penerbit', size=2),
        'nomor_urut': fields.char('Nomor Urut', size=8),
        'name': fields.function(_nomor_faktur, type='char', string="Nomor Faktur", store=True),
        'invoice_id': fields.many2one('account.invoice','Invoice No'),
        'partner_id'    : fields.many2one('res.partner', "Customer"),
        'dpp'   : fields.float('Untaxed Amount'),
        'tax_amount': fields.float("Tax Amount"),
        'date_used' : fields.date("Used Date"),
        'company_id': fields.many2one('res.company', 'Company'),
        'currency_id': fields.many2one('res.currency', 'Currency'),
        'type'      : fields.selection([('in','Faktur Pajak Masukan'),('out','Faktur Pajak Keluaran')],'Type'),
        'status': fields.selection([('1','Used'),('0','Not Used')],'Status'),
    }
    
    _defaults = {
        'status': '0',
    }
    
    _sql_constraints = [
        ('faktur_unique', 'unique(nomor_perusahaan,tahun_penerbit,nomor_urut)', 'Number Faktur Must Be Unique.'),
    ]
Beispiel #3
0
class ProductTemplate(orm.Model):

    _inherit = 'product.template'

    _columns = {
        'date_start':
        fields.date("Start date"),
        'date_end':
        fields.date("End Date"),
        'period':
        fields.selection([('week', 'Week'), ('month', 'Month'),
                          ('year', 'Year')], 'Time Period'),
        'analysis_type':
        fields.selection([('average', 'Average'),
                          ('end_of_period', 'End of period')],
                         'Type of analysis'),
        'stock_graphic':
        fields.binary("Graph")
    }

    _defaults = {
        'date_start':
        lambda *a:
        (datetime.now() - relativedelta(months=6)).strftime('%Y-%m-%d'),
        'date_end':
        lambda *a: datetime.now().strftime('%Y-%m-%d'),
        'period':
        'month',
        'analysis_type':
        'average'
    }
Beispiel #4
0
class barcode_rule(models.Model):
    _name = 'barcode.rule'
    _order = 'sequence asc'

    @api.model
    def _encoding_selection_list(self):
        return [
                ('any', _('Any')),
                ('ean13', 'EAN-13'),
                ('ean8', 'EAN-8'),
                ('upca', 'UPC-A'),
        ]

    @api.model
    def _get_type_selection(self):
        return [('alias', _('Alias')), ('product', _('Unit Product'))]

    _columns = {
        'name':     fields.char('Rule Name', size=32, required=True, help='An internal identification for this barcode nomenclature rule'),
        'barcode_nomenclature_id':     fields.many2one('barcode.nomenclature','Barcode Nomenclature'),
        'sequence': fields.integer('Sequence', help='Used to order rules such that rules with a smaller sequence match first'),
        'encoding': fields.selection('_encoding_selection_list','Encoding',required=True,help='This rule will apply only if the barcode is encoded with the specified encoding'),
        'type':     fields.selection('_get_type_selection','Type', required=True),
        'pattern':  fields.char('Barcode Pattern', size=32, help="The barcode matching pattern", required=True),
        'alias':    fields.char('Alias',size=32,help='The matched pattern will alias to this barcode', required=True),      
    }

    _defaults = {
        'type': 'product',
        'pattern': '.*',
        'encoding': 'any',
        'alias': "0",
    }

    @api.one
    @api.constrains('pattern')
    def _check_pattern(self):
        p = self.pattern.replace("\\\\", "X").replace("\{", "X").replace("\}", "X")
        findall = re.findall("[{]|[}]", p) # p does not contain escaped { or }
        if len(findall) == 2: 
            if not re.search("[{][N]*[D]*[}]", p):
                raise ValidationError(_("There is a syntax error in the barcode pattern ") + self.pattern + _(": braces can only contain N's followed by D's."))
            elif re.search("[{][}]", p):
                raise ValidationError(_("There is a syntax error in the barcode pattern ") + self.pattern + _(": empty braces."))
        elif len(findall) != 0:
            raise ValidationError(_("There is a syntax error in the barcode pattern ") + self.pattern + _(": a rule can only contain one pair of braces."))
        elif p == '*':
            raise ValidationError(_(" '*' is not a valid Regex Barcode Pattern. Did you mean '.*' ?"))
Beispiel #5
0
class hr_salary_rule_variable(models.Model):
    _name = 'hr.salary.rule.variable'
    _description = 'Variables used on salary rules that change over the years'
    _columns = {
        'salary_rule_id':
        fields.many2one(
            'hr.salary.rule',
            'Salary Rule',
            ondelete='cascade',
            required=True,
        ),
        'date_from':
        fields.date(
            'Date From',
            required=True,
        ),
        'date_to':
        fields.date('Date To', ),
        'type':
        fields.selection([('python', 'Python Code'),
                          ('fixed', 'Fixed Amount')],
                         string='Type'),
        'python_code':
        fields.text('Python Code'),
        'fixed_amount':
        fields.float('Fixed Amount'),
    }
Beispiel #6
0
class appointment (osv.osv):
	_name = "medical.appointment"
	_inherit = "medical.appointment"

	def copy(self, cr, uid, id, default=None, context={}):
		default.update({'validity_status':'tobe'})
		return super(appointment,self).copy(cr, uid, id, default, context)
            
	def onchange_appointment_date(self, cr, uid, ids, apt_date):
		if apt_date:
			validity_date = datetime.datetime.fromtimestamp(time.mktime(time.strptime(apt_date,"%Y-%m-%d %H:%M:%S")))
			validity_date = validity_date+datetime.timedelta(days=7)
			v = {'appointment_validity_date':str(validity_date)}
			return {'value': v}
		return {}

	_columns = {
		'no_invoice' : fields.boolean ('Invoice exempt'),
		'appointment_validity_date' : fields.datetime ('Validity Date'),
		'validity_status' : fields.selection([('invoiced','Invoiced'),('tobe','To be Invoiced')],'Status'),
		'consultations' : fields.many2one ('product.product', 'Consultation Service', domain=[('type', '=', "service")], help="Consultation Services", required=True),
	}
	_defaults = {
		'validity_status': lambda *a: 'tobe',
		'no_invoice': lambda *a: True
	}
Beispiel #7
0
class policy_line_presence(models.Model):

    _name = 'hr.policy.line.presence'

    _columns = {
        'name':
        fields.char('Name', size=64, required=True),
        'policy_id':
        fields.many2one('hr.policy.presence', 'Policy'),
        'code':
        fields.char('Code',
                    required=True,
                    help="Use this code in the salary rules."),
        'rate':
        fields.float('Rate',
                     required=True,
                     help='Multiplier of employee wage.'),
        'type':
        fields.selection([('normal', 'Normal Working Hours'),
                          ('holiday', 'Holidays'), ('restday', 'Rest Days')],
                         'Type',
                         required=True),
        'active_after':
        fields.integer(
            'Active After',
            required=True,
            help='Minutes after first punch of the day in which policy will '
            'take effect.'),
        'duration':
        fields.integer('Duration', required=True, help="In minutes.")
    }

    _defaults = {
        'rate': 1.0,
    }
Beispiel #8
0
class solt_http_test(osv.osv):
    _name = 'solt.http.test'

    _columns = {
        'name':
        fields.char('URL', size=1024),
        'method':
        fields.selection([('post', 'POST'), ('get', 'GET'), ('put', 'PUT'),
                          ('patch', 'PATCH'), ('delete', 'DELETE')],
                         string='HTTP Method'),
        'user':
        fields.char('User', size=64),
        'password':
        fields.char('Password', size=64),
        'content':
        fields.text('Content'),
        'response':
        fields.text('Response'),
    }

    def action_request(self, cr, uid, ids, context=None):
        for test in self.browse(cr, uid, ids, context):
            auth = None
            if test.user and test.password:
                auth = (test.user, test.password)
            headers = {
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            }
            result = getattr(requests, test.method)(test.name,
                                                    test.content,
                                                    auth=auth,
                                                    headers=headers)
            test.write({'response': result.text})
        return True
Beispiel #9
0
class WizardReports(osv.TransientModel):
    _name = 'wiz.invoices.writeoff'
    _description = 'PDF Reports for showing all disconnection,reconnection'

    _columns = {
        'date':
        fields.date('Invoice Date', required=True),
        'cheque_no':
        fields.char('Cheque No', required=True),
        'bank_code':
        fields.selection([
            ('FBL', 'FBL'),
            ('JSBL', 'JSBL'),
        ],
                         required=True,
                         string='Bank Code'),
        'invoice_amount':
        fields.float('Invoice Amount', required=True),
        'received_amount':
        fields.float('Received Amount', required=True)
    }

    def inv_status_changed(self, central, south, north, main):
        self.env.cr.execute(
            "UPDATE account_invoice "
            "SET state='cancel', payment_received=True,courier=True" +
            ",cheque_no='" + str(self.cheque_no) + "'" +
            ",comment='Payment has been received against parent invoice therefore user cancelled this invoice' "
            "FROM res_partner WHERE account_invoice.partner_id = res_partner.id and account_invoice.state='draft' "
            + "and res_partner.bank_code='" + str(self.bank_code) + "'" +
            "and account_invoice.invoice_date='" + str(self.date) + "'" +
            "and account_invoice.amount_total='" + str(self.invoice_amount) +
            "'" + "and account_invoice.partner_id!='" + str(central) + "'" +
            "and account_invoice.partner_id != '" + str(south) + "'" +
            "and account_invoice.partner_id !='" + str(north) + "'" +
            "and account_invoice.partner_id !=" + str(main))
        return True

    @api.one
    def inv_status_change_request(self):
        if self.bank_code == 'FBL':
            fbl_central = 9464
            fbl_south = 9522
            fbl_north = 9450
            fbl_main = 9572
            result = self.inv_status_changed(fbl_central, fbl_south, fbl_north,
                                             fbl_main)
            return result

        if self.bank_code == 'JSBL':
            jsbl_central = 11056
            jsbl_south = 11057
            jsbl_north = 11058
            jsbl_main = 3349
            result = self.inv_status_changed(jsbl_central, jsbl_south,
                                             jsbl_north, jsbl_main)
            return result

        raise osv.except_osv("Done........",
                             "Records have been successfully updated")
Beispiel #10
0
class hr_warning(models.Model):

    _name = 'hr.infraction.warning'
    _description = 'Employee Warning'
    _columns = {
        'name': fields.char(
            'Subject',
            size=256,
        ),
        'date': fields.date(
            'Date Issued',
        ),
        'type': fields.selection(
            [
                ('verbal', 'Verbal'),
                ('written', 'Written'),
            ],
            'Type',
            required=True,
        ),
        'action_id': fields.many2one(
            'hr.infraction.action',
            'Action',
            ondelete='cascade',
            readonly=True,
        ),
        'infraction_id': fields.related(
            'action_id',
            'infraction_id',
            type='many2one',
            obj='hr.infraction',
            string='Infraction',
            readonly=True,
        ),
        'employee_id': fields.related(
            'infraction_id',
            'employee_id',
            type='many2one',
            obj='hr.employee',
            string='Employee',
            readonly=True,
        ),
    }

    _defaults = {
        'type': 'written',
        'date': time.strftime(DEFAULT_SERVER_DATE_FORMAT),
    }

    def unlink(self, cr, uid, ids, context=None):
        for warning in self.browse(cr, uid, ids, context=context):
            if (warning.action_id
                    and warning.action_id.infraction_id.state != 'draft'):
                raise models.except_orm(
                    _('Error'),
                    _('Warnings attached to Infractions not in "Draft" state '
                      'may not be removed.')
                )
        return super(hr_warning, self).unlink(cr, uid, ids, context=context)
Beispiel #11
0
class BmLot(models.Model):
    _name = "bm.lot"

    name = fields.Char('Lot #', size=10, required=True)
    lettable_area = fields.Float('Lettable Area (sqm)', required=True)
    rental_charge = fields.Float('Rental (/sqm/month)', required=True)
    service_charge = fields.Float('Service Charge (/sqm/month)', required=True)
    promotion_levy = fields.Float('Promotion Levy (/sqm/month)', required=True)
    state = fields.selection(AVAILABLE_STATES, 'Status', required=True, readonly=True)
class generate_faktur_pajak(osv.osv_memory):
    _name = 'generate.faktur.pajak'    
    _columns = {
            'nomor_faktur_awal' : fields.char('Nomor Faktur Awal', size=20),
            'nomor_faktur_akhir' : fields.char('Nomor Faktur Akhir', size=20),
            'strip' : fields.char('Strip', size=3),
            'dot' : fields.char('Dot', size=3),
            'strip2' : fields.char('Strip', size=3),
            'dot2' : fields.char('Dot', size=3),
            'nomor_perusahaan' : fields.char('Nomor Perusahaan', size=3, required=True),
            'nomor_awal' : fields.char('Nomor Faktur Awal', size=8, required=True),
            'nomor_akhir' : fields.char('Nomor Faktur Akhir', size=8, required=True),
            'tahun' : fields.char('Tahun Penerbit', size=2,  required=True),
            'type'      : fields.selection([('in','Faktur Pajak Masukan'),('out','Faktur Pajak Keluaran')],'Type'),
    }
    _defaults = {
        'nomor_awal': '',
        'nomor_akhir': '',
        'type': 'out',
        'nomor_faktur_awal':'Nomor Faktur Awal:',
        'nomor_faktur_akhir':'Nomor Faktur Akhir:',
        'strip': '-',
        'dot': '.',
        'strip2': '-',
        'dot2': '.',
    }
    
    def generate_faktur(self, cr, uid, ids, context=None):
        if not context: context={}
        wizard = self.browse(cr, uid, ids[0], context)
        #print "=====wizard.nomor_awal=====",wizard.nomor_awal,int(wizard.nomor_awal)
        #print "=====wizard.nomor_akhir=====",wizard.nomor_akhir,int(wizard.nomor_akhir)
        awal = int(wizard.nomor_awal)
        akhir = int(wizard.nomor_akhir)
        while (awal <= akhir):
            value = {
                'nomor_perusahaan': wizard.nomor_perusahaan,
                'tahun_penerbit': wizard.tahun,
                'nomor_urut': '%08d' % awal,
                'status': '0',
                'type': wizard.type,
            }
            self.pool.get('nomor.faktur.pajak').create(cr,uid,value,context=context)
            awal += 1
        return {'type': 'ir.actions.act_window_close'}
    
    def onchange_nomor_faktur(self, cr, uid, ids, akhir, context=None):
        res = {}
        wizard = self.browse(cr, uid, ids[0], context)
        if akhir <= wizard.nomor_awal:
            warning = {
                'title': _('Warning'),
                'message': _('Wrong Format must 15 digit'),
            }
            return {'warning': warning, 'value' : {'nomor_akhir' : False}}
        return res
Beispiel #13
0
class hr_infraction_action(models.Model):

    _name = 'hr.infraction.action'
    _description = 'Action Based on Infraction'
    _columns = {
        'infraction_id': fields.many2one(
            'hr.infraction',
            'Infraction',
            ondelete='cascade',
            required=True,
            readonly=True,
        ),
        'type': fields.selection(
            ACTION_TYPE_SELECTION,
            'Type',
            required=True,
        ),
        'memo': fields.text(
            'Notes',
        ),
        'employee_id': fields.related(
            'infraction_id',
            'employee_id',
            type='many2one',
            store=True,
            obj='hr.employee',
            string='Employee',
            readonly=True,
        ),
        'warning_id': fields.many2one(
            'hr.infraction.warning',
            'Warning',
            readonly=True,
        ),
        'transfer_id': fields.many2one(
            'hr.department.transfer',
            'Transfer',
            readonly=True,
        ),
    }
    _rec_name = 'type'

    def unlink(self, cr, uid, ids, context=None):

        for action in self.browse(cr, uid, ids, context=context):
            if action.infraction_id.state not in ['draft']:
                raise models.except_orm(
                    _('Error'),
                    _('Actions belonging to Infractions not in "Draft" state '
                      'may not be removed.')
                )

        return super(hr_infraction_action, self).unlink(
            cr, uid, ids, context=context
        )
class SaleInherit(osv.Model):
    _inherit = 'sale.order'

    _columns = {
        'state':
        fields.selection([('draft', 'Draft Quotation'),
                          ('confirm', 'Quotation Confirmed'),
                          ('sent', 'Quotation Sent'), ('cancel', 'Cancelled'),
                          ('waiting_date', 'Waiting Schedule'),
                          ('waitingapproval', 'Waiting Approval'),
                          ('progress', 'Sales Order'),
                          ('manual', 'Sale to Invoice'),
                          ('shipping_except', 'Shipping Exception'),
                          ('invoice_except', 'Invoice Exception'),
                          ('done', 'Done')],
                         required=True,
                         track_visibility='onchange'),
    }

    def action_button_confirm(self, cr, uid, ids, context=None):
        discnt = 0.0
        no_line = 0.0
        line_dicnt = 0.0
        prod_price = 0.0
        conf = self.pool.get('ir.values')
        sale_obj = self.browse(cr, uid, ids, context)
        double_valid = conf.get_default(cr, uid, 'sale.config.settings',
                                        'module_sale_discount_approval')
        if double_valid == 'True':
            min_disct = conf.get_default(cr, uid, 'sale.config.settings',
                                         'limit_discount')
            for line in sale_obj.order_line:
                no_line += 1
                discnt += line.discount
            discnt = (discnt / no_line)
            if discnt >= min_disct:
                assert len(
                    ids
                ) == 1, 'This option should only be used for a single id at a time.'
                self.signal_workflow(cr, uid, ids, 'order_toapprov')
                return True
            else:
                return super(SaleInherit, self).action_button_confirm(
                    cr, uid, ids, context)
        else:
            return super(SaleInherit,
                         self).action_button_confirm(cr, uid, ids, context)

        ####################################### workflow functions#############################################################################

    @api.one
    def wait_approval(self):

        self.state = 'waitingapproval'
        return True
class WizardMissingVisits(osv.TransientModel):
    _name = 'wiz.missing.visits'
    _description = 'Missing Visits Calculation'

    _columns = {
        'bank_code':
        fields.selection([('MBL', 'MBL'), ('SAMBA', 'SAMBA'), ('ABL', 'ABL'),
                          ('UBL', 'UBL'), ('NBP', 'NBP'), ('HBL', 'HBL')],
                         'Bank Code',
                         required=True),
    }

    _defaults = {'bank_code': 'MBL'}

    @api.multi
    def createvisits(self):
        self.env.cr.execute(
            "select bank_code,branch_code,street,city,force_code,rf_id from res_partner where rf_id is not null and bank_code="
            + "'" + self.bank_code + "'" +
            " and rf_id not in (select card_no from mutual_guard_tracking where archive_signal is null and visit_time is not null)"
        )
        missing_branches = self.env.cr.dictfetchall()

        self.env.cr.execute(
            "select visit_time,visit_time_two from mutual_guard_tracking where visit_time is null and visit_time_two is null and archive_signal is False and bank_code="
            + "'" + self.bank_code + "'")
        missing_visits_created = self.env.cr.dictfetchall()

        print ">>>>>>>>>>>>>>>>>>>Missing Visits>>>>>>>>>>>>>>>>>>>>>"
        print len(missing_visits_created)
        if (len(missing_branches) > 0):
            if (len(missing_visits_created) == 0):
                for branch in missing_branches:
                    self.env['mutual.guard.tracking'].create({
                        'bank_code':
                        branch['bank_code'],
                        'branch_code':
                        branch['branch_code'],
                        'address':
                        branch['street'],
                        'city':
                        branch['city'],
                        'force_code':
                        branch['force_code'],
                        'card_no':
                        branch['rf_id']
                    })
            else:
                raise osv.except_osv(
                    'Alert.......', 'Missing visits has been already created')

        else:
            raise osv.except_osv('Alert.......',
                                 'All branches have been first visited')
Beispiel #16
0
class labtest (osv.osv):
	_name = "medical.patient.lab.test"
	_inherit = "medical.patient.lab.test"

	_columns = {
		'no_invoice' : fields.boolean ('Invoice exempt'),
		'invoice_status' : fields.selection([('invoiced','Invoiced'),('tobe','To be Invoiced')],'Invoice Status'),
        }
    
	_defaults={
		'invoice_status': lambda *a: 'tobe',
		'no_invoice': lambda *a: True

	   }
class account_bank_statement_line(osv.osv):
    _inherit = "account.bank.statement.line"
    _description = "Bank Statement Line"
    _columns = {
        'type':
        fields.selection([('supplier', 'Supplier'), ('customer', 'Customer'),
                          ('general', 'General')], 'Type'),
        't_type':
        fields.selection([('receipt', 'Receipt'), ('payment', 'Payment')],
                         "Transaction Type"),
        't_amount':
        fields.float("Amount", digits=(16, 2)),
    }
    _defaults = {
        'date': False,
    }

    def onchange_trnstyp_amount(self, cr, uid, ids, t_type, t_amount):
        res = {}
        if t_amount:
            sign = (t_type == 'payment') and -1 or 1
            res['amount'] = t_amount * sign
        return {'value': res}
Beispiel #18
0
class patient_prescription_order (osv.osv):

	_name = "medical.prescription.order"
	_inherit = "medical.prescription.order"

		
	_columns = {
		'no_invoice' : fields.boolean ('Invoice exempt'),
		'invoice_status' : fields.selection([('invoiced','Invoiced'),('tobe','To be Invoiced')],'Invoice Status'),
		}

	_defaults = {
		'invoice_status': lambda *a: 'tobe',
		'no_invoice': lambda *a: True
                }
Beispiel #19
0
class policy_line_absence(models.Model):

    _name = 'hr.policy.line.absence'

    _columns = {
        'name':
        fields.char('Name', size=64, required=True),
        'code':
        fields.char('Code',
                    required=True,
                    help="Use this code in the salary rules."),
        'holiday_status_id':
        fields.many2one('hr.holidays.status', 'Leave', required=True),
        'policy_id':
        fields.many2one('hr.policy.absence', 'Policy'),
        'type':
        fields.selection(
            [('paid', 'Paid'), ('unpaid', 'Unpaid'), ('dock', 'Dock')],
            'Type',
            required=True,
            help="Determines how the absence will be treated in payroll. "
            "The 'Dock Salary' type will deduct money (useful for "
            "salaried employees).",
        ),
        'rate':
        fields.float('Rate',
                     required=True,
                     help='Multiplier of employee wage.'),
        'use_awol':
        fields.boolean(
            'Absent Without Leave',
            help='Use this policy to record employee time absence not covered '
            'by other leaves.')
    }

    def onchange_holiday(self, cr, uid, ids, holiday_status_id, context=None):

        res = {'value': {'name': False, 'code': False}}
        if not holiday_status_id:
            return res
        data = self.pool.get('hr.holidays.status').read(cr,
                                                        uid,
                                                        holiday_status_id,
                                                        ['name', 'code'],
                                                        context=context)
        res['value']['name'] = data['name']
        res['value']['code'] = data['code']
        return res
Beispiel #20
0
class product_product(osv.Model):
    _inherit = 'product.product'

    _columns = {
        'wk_order_allow':
        fields.selection((
            ('allow', 'Allow Order'),
            ('deny', 'Deny Orders'),
        ), 'When Product is out of Stock'),
        'wk_in_stock_msg':
        fields.char('Message'),
        'wk_out_of_stock_msg':
        fields.char('Message'),
        'wk_override_default':
        fields.boolean('Override Default Message')
    }
    _defaults = {
        'wk_order_allow': 'deny',
        'wk_in_stock_msg': 'In Stock',
        'wk_out_of_stock_msg': 'This product has gone out of Stock!'
    }
class surgery(osv.osv):
    _name = "medical.surgery"
    _description = "Surgery"
    _columns = {
        'name':
        fields.many2one(
            'medical.procedure',
            'Code',
            help=
            "Procedure Code, for example ICD-10-PCS Code 7-character string"),
        'pathology':
        fields.many2one('medical.pathology',
                        'Base condition',
                        help="Base Condition / Reason"),
        'classification':
        fields.selection([
            ('o', 'Optional'),
            ('r', 'Required'),
            ('u', 'Urgent'),
        ],
                         'Surgery Classification',
                         select=True),
        'surgeon':
        fields.many2one('medical.physician',
                        'Surgeon',
                        help="Surgeon who did the procedure"),
        'date':
        fields.datetime('Date of the surgery'),
        'age':
        fields.char(
            'Patient age',
            size=3,
            help='Patient age at the moment of the surgery. Can be estimative'
        ),
        'description':
        fields.char('Description', size=128),
        'extra_info':
        fields.text('Extra Info'),
    }
Beispiel #22
0
class product_pricelist_item(osv.osv):
    _inherit = 'product.pricelist.item'

    def _price_field_get(self, cr, uid, context=None):
        pt = self.pool.get('product.price.type')
        ids = pt.search(cr, uid, [], context=context)
        result = []
        for line in pt.browse(cr, uid, ids, context=context):
            result.append((line.id, line.name))

        result.append((-1, _('Other Pricelist')))
        result.append((-2, _('Supplier Prices on the product form')))
        result.append((-3, _('Precio fijo')))
        return result

    _columns = {
        'base':
        fields.selection(_price_field_get,
                         'Based on',
                         required=True,
                         size=-1,
                         help="Base price for computation."),
        'fixed_price':
        fields.float('Precio Fijo', digits=(9, 2)),
        'product_partner_ident':
        fields.char('Identificacion Cliente', required=True),
        'partner_desc':
        fields.char('Descripcion del Cliente', required=True),
        # 'o2s_id': fields.integer('O2s sequence'),
    }

    def product_id_change(self, cr, uid, ids, product_id, context=None):
        res = super(product_pricelist_item,
                    self).product_id_change(cr, uid, ids, product_id, context)
        if 'value' in res and product_id:
            product = self.pool.get('product.product').browse(
                cr, uid, product_id)
            res['value']['partner_desc'] = product.name
        return res
Beispiel #23
0
class restday(models.TransientModel):

    _name = 'hr.restday.wizard'
    _description = 'Schedule Template Change Wizard'

    _columns = {
        'employee_id':
        fields.many2one(
            'hr.employee',
            'Employee',
            required=True,
        ),
        'contract_id':
        fields.related(
            'employee_id',
            'contract_id',
            type='many2one',
            relation='hr.contract',
            string='Contract',
            readonly=True,
        ),
        'st_current_id':
        fields.many2one(
            'hr.schedule.template',
            'Current Template',
            readonly=True,
        ),
        'st_new_id':
        fields.many2one(
            'hr.schedule.template',
            'New Template',
        ),
        'permanent':
        fields.boolean('Make Permanent', ),
        'temp_restday':
        fields.boolean(
            'Temporary Rest Day Change',
            help="If selected, change the rest day to the specified day only "
            "for the selected schedule.",
        ),
        'dayofweek':
        fields.selection(
            [('0', 'Monday'), ('1', 'Tuesday'), ('2', 'Wednesday'),
             ('3', 'Thursday'), ('4', 'Friday'), ('5', 'Saturday'),
             ('6', 'Sunday')],
            'Rest Day',
            select=True,
        ),
        'temp_week_start':
        fields.date('Start of Week', ),
        'week_start':
        fields.date('Start of Week', ),
    }

    _defaults = {
        'temp_restday': False,
    }

    def onchange_employee(self, cr, uid, ids, ee_id, context=None):

        res = {'value': {'st_current_id': False}}
        if ee_id:
            ee = self.pool.get('hr.employee').browse(cr,
                                                     uid,
                                                     ee_id,
                                                     context=None)
            res['value'][
                'st_current_id'] = ee.contract_id.schedule_template_id.id

        return res

    def onchange_week(self, cr, uid, ids, newdate):

        res = {'value': {'week_start': newdate}}
        if newdate:
            d = datetime.strptime(newdate, "%Y-%m-%d")
            if d.weekday() != 0:
                res['value']['week_start'] = False
                return res
        return res

    def onchange_temp_week(self, cr, uid, ids, newdate):

        res = {'value': {'temp_week_start': newdate}}
        if newdate:
            d = datetime.strptime(newdate, "%Y-%m-%d")
            if d.weekday() != 0:
                res['value']['temp_week_start'] = False
                return res
        return res

    def _create_detail(self,
                       cr,
                       uid,
                       schedule,
                       actual_dayofweek,
                       template_dayofweek,
                       week_start,
                       context=None):

        # First, see if there's a schedule for the actual dayofweek.
        # If so, use it.
        #
        for worktime in schedule.template_id.worktime_ids:
            if worktime.dayofweek == actual_dayofweek:
                template_dayofweek = actual_dayofweek

        prevutcdtStart = False
        prevDayofWeek = False
        user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
        local_tz = timezone(user.tz)
        dSchedStart = datetime.strptime(schedule.date_start, OE_DFORMAT).date()
        dWeekStart = schedule.date_start < week_start and datetime.strptime(
            week_start, OE_DFORMAT).date() or dSchedStart

        for worktime in schedule.template_id.worktime_ids:

            if worktime.dayofweek != template_dayofweek:
                continue

            hour, sep, minute = worktime.hour_from.partition(':')
            toHour, toSep, toMin = worktime.hour_to.partition(':')
            if len(sep) == 0 or len(toSep) == 0:
                raise models.except_orm(
                    _('Invalid Time Format'),
                    _('The time should be entered as HH:MM'))

            # TODO - Someone affected by DST should fix this
            #
            dtStart = datetime.strptime(
                dWeekStart.strftime('%Y-%m-%d') + ' ' + hour + ':' + minute +
                ':00', '%Y-%m-%d %H:%M:%S')
            locldtStart = local_tz.localize(dtStart, is_dst=False)
            utcdtStart = locldtStart.astimezone(utc)
            if actual_dayofweek != '0':
                utcdtStart = utcdtStart + \
                    relativedelta(days=+int(actual_dayofweek))
            dDay = utcdtStart.astimezone(local_tz).date()

            # If this worktime is a continuation (i.e - after lunch) set the
            # start time based on the difference from the previous record
            #
            if prevDayofWeek and prevDayofWeek == actual_dayofweek:
                prevHour = prevutcdtStart.strftime('%H')
                prevMin = prevutcdtStart.strftime('%M')
                curHour = utcdtStart.strftime('%H')
                curMin = utcdtStart.strftime('%M')
                delta_seconds = (
                    datetime.strptime(curHour + ':' + curMin, '%H:%M') -
                    datetime.strptime(prevHour + ':' + prevMin,
                                      '%H:%M')).seconds
                utcdtStart = prevutcdtStart + timedelta(seconds=+delta_seconds)
                dDay = prevutcdtStart.astimezone(local_tz).date()

            delta_seconds = (
                datetime.strptime(toHour + ':' + toMin, '%H:%M') -
                datetime.strptime(hour + ':' + minute, '%H:%M')).seconds
            utcdtEnd = utcdtStart + timedelta(seconds=+delta_seconds)

            val = {
                'name': schedule.name,
                'dayofweek': actual_dayofweek,
                'day': dDay,
                'date_start': utcdtStart.strftime('%Y-%m-%d %H:%M:%S'),
                'date_end': utcdtEnd.strftime('%Y-%m-%d %H:%M:%S'),
                'schedule_id': schedule.id,
            }
            self.pool.get('hr.schedule').write(cr,
                                               uid,
                                               schedule.id, {
                                                   'detail_ids': [(0, 0, val)],
                                               },
                                               context=context)

            prevDayofWeek = worktime.dayofweek
            prevutcdtStart = utcdtStart

    def _change_restday(self,
                        cr,
                        uid,
                        employee_id,
                        week_start,
                        dayofweek,
                        context=None):

        sched_obj = self.pool.get('hr.schedule')
        sched_detail_obj = self.pool.get('hr.schedule.detail')

        schedule_ids = sched_obj.search(cr,
                                        uid,
                                        [('employee_id', '=', employee_id),
                                         ('date_start', '<=', week_start),
                                         ('date_end', '>=', week_start),
                                         ('state', 'not in', ['locked'])],
                                        context=context)
        sched = sched_obj.browse(cr, uid, schedule_ids[0], context=context)
        dtFirstDay = datetime.strptime(sched.detail_ids[0].date_start,
                                       OE_DTFORMAT)
        date_start = (dtFirstDay.strftime(OE_DFORMAT) < week_start
                      and week_start + ' ' + dtFirstDay.strftime('%H:%M:%S')
                      or dtFirstDay.strftime(OE_DTFORMAT))
        dtNextWeek = datetime.strptime(date_start,
                                       OE_DTFORMAT) + relativedelta(weeks=+1)

        # First get the current rest days
        rest_days = sched_obj.get_rest_days_by_id(
            cr,
            uid,
            sched.id,
            dtFirstDay.strftime(OE_DFORMAT),
            context=context)

        # Next, remove the schedule detail for the new rest day
        for dtl in sched.detail_ids:
            if (dtl.date_start < week_start or datetime.strptime(
                    dtl.date_start, OE_DTFORMAT) >= dtNextWeek):
                continue
            if dtl.dayofweek == dayofweek:
                sched_detail_obj.unlink(cr, uid, dtl.id, context=context)

        # Enter the new rest day(s)
        #
        sched_obj = self.pool.get('hr.schedule')
        nrest_days = [dayofweek] + rest_days[1:]
        dSchedStart = datetime.strptime(sched.date_start, OE_DFORMAT).date()
        dWeekStart = sched.date_start < week_start and datetime.strptime(
            week_start, OE_DFORMAT).date() or dSchedStart
        if dWeekStart == dSchedStart:
            sched_obj.add_restdays(cr,
                                   uid,
                                   sched,
                                   'restday_ids1',
                                   rest_days=nrest_days,
                                   context=context)
        elif dWeekStart == dSchedStart + relativedelta(days=+7):
            sched_obj.add_restdays(cr,
                                   uid,
                                   sched,
                                   'restday_ids2',
                                   rest_days=nrest_days,
                                   context=context)
        elif dWeekStart == dSchedStart + relativedelta(days=+14):
            sched_obj.add_restdays(cr,
                                   uid,
                                   sched,
                                   'restday_ids3',
                                   rest_days=nrest_days,
                                   context=context)
        elif dWeekStart == dSchedStart + relativedelta(days=+21):
            sched_obj.add_restdays(cr,
                                   uid,
                                   sched,
                                   'restday_ids4',
                                   rest_days=nrest_days,
                                   context=context)
        elif dWeekStart == dSchedStart + relativedelta(days=+28):
            sched_obj.add_restdays(cr,
                                   uid,
                                   sched,
                                   'restday_ids5',
                                   rest_days=nrest_days,
                                   context=context)

        # Last, add a schedule detail for the first rest day in the week using
        # the template for the new (temp) rest day
        #
        if len(rest_days) > 0:
            self._create_detail(cr,
                                uid,
                                sched,
                                str(rest_days[0]),
                                dayofweek,
                                week_start,
                                context=context)

    def _remove_add_schedule(self,
                             cr,
                             uid,
                             schedule_id,
                             week_start,
                             tpl_id,
                             context=None):
        """Remove the current schedule and add a new one in its place
        according to the new template. If the week that the change
        starts in is not at the beginning of a schedule create two
        new schedules to accommodate the truncated old one and the
        partial new one.
        """

        sched_obj = self.pool.get('hr.schedule')
        sched = sched_obj.browse(cr, uid, schedule_id, context=context)

        vals2 = False
        vals1 = {
            'name': sched.name,
            'employee_id': sched.employee_id.id,
            'template_id': tpl_id,
            'date_start': sched.date_start,
            'date_end': sched.date_end,
        }

        if week_start > sched.date_start:
            dWeekStart = datetime.strptime(week_start, '%Y-%m-%d').date()
            start_day = dWeekStart.strftime('%Y-%m-%d')
            vals1['template_id'] = sched.template_id.id
            vals1['date_end'] = (dWeekStart +
                                 relativedelta(days=-1)).strftime('%Y-%m-%d')
            vals2 = {
                'name': (sched.employee_id.name + ': ' + start_day + ' Wk ' +
                         str(dWeekStart.isocalendar()[1])),
                'employee_id':
                sched.employee_id.id,
                'template_id':
                tpl_id,
                'date_start':
                start_day,
                'date_end':
                sched.date_end,
            }

        sched_obj.unlink(cr, uid, schedule_id, context=context)
        _l.warning('vals1: %s', vals1)
        sched_obj.create(cr, uid, vals1, context=context)
        if vals2:
            _l.warning('vals2: %s', vals2)
            sched_obj.create(cr, uid, vals2, context=context)

    def _change_by_template(self,
                            cr,
                            uid,
                            employee_id,
                            week_start,
                            new_template_id,
                            doall,
                            context=None):

        sched_obj = self.pool.get('hr.schedule')

        schedule_ids = sched_obj.search(cr,
                                        uid,
                                        [('employee_id', '=', employee_id),
                                         ('date_start', '<=', week_start),
                                         ('date_end', '>=', week_start),
                                         ('state', 'not in', ['locked'])],
                                        context=context)

        # Remove the current schedule and add a new one in its place according
        # to the new template
        #
        if len(schedule_ids) > 0:
            self._remove_add_schedule(cr,
                                      uid,
                                      schedule_ids[0],
                                      week_start,
                                      new_template_id,
                                      context=context)

        # Also, change all subsequent schedules if so directed
        if doall:
            ids = sched_obj.search(cr,
                                   uid, [('employee_id', '=', employee_id),
                                         ('date_start', '>', week_start),
                                         ('state', 'not in', ['locked'])],
                                   context=context)
            for i in ids:
                self._remove_add_schedule(cr, uid, i, week_start,
                                          new_template_id, context)

    def change_restday(self, cr, uid, ids, context=None):

        data = self.read(cr, uid, ids[0], [], context=context)

        # Change the rest day for only one schedule
        if (data.get('temp_restday') and data.get('dayofweek')
                and data.get('temp_week_start')):
            self._change_restday(cr,
                                 uid,
                                 data['employee_id'][0],
                                 data['temp_week_start'],
                                 data['dayofweek'],
                                 context=context)

        # Change entire week's schedule to the chosen schedule template
        if (not data.get('temp_restday') and data.get('st_new_id')
                and data.get('week_start')):

            if data.get('week_start', False):
                self._change_by_template(cr,
                                         uid,
                                         data['employee_id'][0],
                                         data['week_start'],
                                         data['st_new_id'][0],
                                         data.get('permanent', False),
                                         context=context)

            # If this change is permanent modify employee's contract to
            # reflect the new template
            #
            if data.get('permanent', False):
                self.pool.get('hr.contract').write(
                    cr,
                    uid,
                    data['contract_id'][0], {
                        'schedule_template_id': data['st_new_id'][0],
                    },
                    context=context)

        return {
            'name': 'Change Schedule Template',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'hr.restday.wizard',
            'type': 'ir.actions.act_window',
            'target': 'new',
            'context': context
        }
Beispiel #24
0
class product_product(osv.osv):

    _inherit = "product.product"

    @api.one
    @api.onchange('lst_price') # if these fields are changed, call method
    def check_change_price(self):
        #import pdb;pdb.set_trace();
        pricelists = self.env['product.pricelist'].search([])
        pricelist = pricelists[0]

        return {}

    def product_meli_get_products( self, cr, uid, context=None ):
        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id
        product_obj = self.pool.get('product.product')
        #product = product_obj.browse(cr, uid, ids[0])

        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token

        meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

        url_login_meli = meli.auth_url(redirect_URI=REDIRECT_URI)
        #url_login_oerp = "/meli_login"

        response = meli.get("/users/"+company.mercadolibre_seller_id+"/items/search", {'access_token':meli.access_token})

        print "product_meli_get_products: " + response.content
        rjson = response.json()

        if 'error' in rjson:
            if rjson['message']=='invalid_token' or rjson['message']=='expired_token':
                ACCESS_TOKEN = ''
                REFRESH_TOKEN = ''
                company.write({'mercadolibre_access_token': ACCESS_TOKEN, 'mercadolibre_refresh_token': REFRESH_TOKEN, 'mercadolibre_code': '' } )
            return {
	        "type": "ir.actions.act_url",
	        "url": url_login_meli,
	        "target": "new",
        }

        results = rjson['results']
        if (results):
            for item_id in results:
                print item_id
                posting_id = self.pool.get('product.product').search(cr,uid,[('meli_id','=',item_id)])
                response = meli.get("/items/"+item_id, {'access_token':meli.access_token})
                rjson = response.json()
                if (posting_id):
                    print "Item already in database: " + str(posting_id[0])
                else:
                    idcreated = self.pool.get('product.product').create(cr,uid,{ 'name': rjson['title'], 'meli_id': rjson['id'] })
                    if (idcreated):
                        product = product_obj.browse(cr, uid, idcreated)
                        product_obj.product_meli_get_product( cr, uid, [idcreated] )
        return {}

    def product_meli_get_product( self, cr, uid, ids, context=None ):
        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id
        product_obj = self.pool.get('product.product')
        product = product_obj.browse(cr, uid, ids[0])

        product_template_obj = self.pool.get('product.template')
        product_template = product_template_obj.browse(cr, uid, product.product_tmpl_id.id)

        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token

        meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

        response = meli.get("/items/"+product.meli_id, {'access_token':meli.access_token})

        print "product_meli_get_product: " + response.content
        rjson = response.json()

        des = ''
        desplain = ''
        vid = ''
        if 'error' in rjson:
            return {}

        #TODO: traer la descripcion: con
        #https://api.mercadolibre.com/items/{ITEM_ID}/description?access_token=$ACCESS_TOKEN
        if rjson['descriptions']:
            response2 = meli.get("/items/"+product.meli_id+"/description", {'access_token':meli.access_token})
            rjson2 = response2.json()
            des = rjson2['text']
            desplain = rjson2['plain_text']
            if (len(des)>0):
                desplain = des

        #TODO: verificar q es un video
        if rjson['video_id']:
            vid = ''

        #TODO: traer las imagenes
        #TODO:
        pictures = rjson['pictures']
        if pictures and len(pictures):
            thumbnail_url = pictures[0]['url']
            image = urllib2.urlopen(thumbnail_url).read()
            image_base64 = base64.encodestring(image)
            product.image_medium = image_base64
            #if (len(pictures)>1):
                #complete product images:
                #delete all images...

        #categories
        mlcatid = ""
        if ('category_id' in rjson):
            category_id = rjson['category_id']
            ml_cat_id = self.pool.get('mercadolibre.category').search(cr,uid,[('meli_category_id','=',category_id)])
            if (ml_cat_id):
              print "category exists!" + str(ml_cat_id)
              mlcatid = ml_cat_id[0]
            else:
              print "Creating category: " + str(category_id)
              #https://api.mercadolibre.com/categories/MLA1743
              response_cat = meli.get("/categories/"+str(category_id), {'access_token':meli.access_token})
              rjson_cat = response_cat.json()
              print "category:" + str(rjson_cat)
              fullname = ""
              if ("path_from_root" in rjson_cat):
                  path_from_root = rjson_cat["path_from_root"]
                  for path in path_from_root:
                    fullname = fullname + "/" + path["name"]

              #fullname = fullname + "/" + rjson_cat['name']
              print "category fullname:" + fullname
              cat_fields = {
                'name': fullname,
                'meli_category_id': ''+str(category_id),
              }
              ml_cat_id = self.pool.get('mercadolibre.category').create(cr,uid,(cat_fields))
              if (ml_cat_id):
                  mlcatid = ml_cat_id

        imagen_id = ''
        if (len(rjson['pictures'])>0):
            imagen_id = rjson['pictures'][0]['id']

        meli_fields = {
            'name': str(rjson['title']),
            'meli_imagen_id': imagen_id,
            'meli_post_required': True,
            'meli_id': rjson['id'],
            'meli_permalink': rjson['permalink'],
            'meli_title': rjson['title'],
            'meli_description': desplain,
#            'meli_description_banner_id': ,
            'meli_category': mlcatid,
            'meli_listing_type': rjson['listing_type_id'],
            'meli_buying_mode':rjson['buying_mode'],
            'meli_price': str(rjson['price']),
            'meli_price_fixed': True,
            'meli_currency': rjson['currency_id'],
            'meli_condition': rjson['condition'],
            'meli_available_quantity': rjson['available_quantity'],
            'meli_warranty': rjson['warranty'],
##            'meli_imagen_logo': fields.char(string='Imagen Logo', size=256),
##            'meli_imagen_id': fields.char(string='Imagen Id', size=256),
            'meli_imagen_link': rjson['thumbnail'],
##            'meli_multi_imagen_id': fields.char(string='Multi Imagen Ids', size=512),
            'meli_video': str(vid)
        }
        tmpl_fields = {
          'name': str(rjson['title'])
        }
        product.write( meli_fields )
        product_template.write( tmpl_fields )
#{"id":"MLA639109219","site_id":"MLA","title":"Disco Vinilo Queen - Rock - A Kind Of Magic","subtitle":null,"seller_id":171329758,"category_id":"MLA2038","official_store_id":null,"price":31,"base_price":31,"original_price":null,"currency_id":"ARS","initial_quantity":5,"available_quantity":5,"sold_quantity":0,"buying_mode":"buy_it_now","listing_type_id":"free","start_time":"2016-10-17T20:36:22.000Z","stop_time":"2016-12-16T20:36:22.000Z","end_time":"2016-12-16T20:36:22.000Z","expiration_time":null,"condition":"used","permalink":"http://articulo.mercadolibre.com.ar/MLA-639109219-disco-vinilo-queen-rock-a-kind-of-magic-_JM","thumbnail":"http://mla-s1-p.mlstatic.com/256905-MLA25108641321_102016-I.jpg","secure_thumbnail":"https://mla-s1-p.mlstatic.com/256905-MLA25108641321_102016-I.jpg","pictures":[{"id":"256905-MLA25108641321_102016","url":"http://mla-s1-p.mlstatic.com/256905-MLA25108641321_102016-O.jpg","secure_url":"https://mla-s1-p.mlstatic.com/256905-MLA25108641321_102016-O.jpg","size":"500x400","max_size":"960x768","quality":""},{"id":"185215-MLA25150338489_112016","url":"http://www.mercadolibre.com/jm/img?s=STC&v=O&f=proccesing_image_es.jpg","secure_url":"https://www.mercadolibre.com/jm/img?s=STC&v=O&f=proccesing_image_es.jpg","size":"500x500","max_size":"500x500","quality":""}],"video_id":null,"descriptions":[{"id":"MLA639109219-1196717922"}],"accepts_mercadopago":true,"non_mercado_pago_payment_methods":[],"shipping":{"mode":"not_specified","local_pick_up":false,"free_shipping":false,"methods":[],"dimensions":null,"tags":[]},"international_delivery_mode":"none","seller_address":{"id":193196973,"comment":"3B","address_line":"Billinghurst 1711","zip_code":"1425","city":{"id":"TUxBQlBBTDI1MTVa","name":"Palermo"},"state":{"id":"AR-C","name":"Capital Federal"},"country":{"id":"AR","name":"Argentina"},"latitude":-34.5906131,"longitude":-58.4101982,"search_location":{"neighborhood":{"id":"TUxBQlBBTDI1MTVa","name":"Palermo"},"city":{"id":"TUxBQ0NBUGZlZG1sYQ","name":"Capital Federal"},"state":{"id":"TUxBUENBUGw3M2E1","name":"Capital Federal"}}},"seller_contact":null,"location":{},"geolocation":{"latitude":-34.5906131,"longitude":-58.4101982},"coverage_areas":[],"attributes":[],"warnings":[],"listing_source":"","variations":[],"status":"active","sub_status":[],"tags":[],"warranty":null,"catalog_product_id":null,"domain_id":null,"seller_custom_field":null,"parent_item_id":null,"differential_pricing":null,"deal_ids":[],"automatic_relist":false,"date_created":"2016-10-17T20:36:22.000Z","last_updated":"2016-11-07T21:38:10.000Z"}

        return {}

    def product_meli_login(self, cr, uid, ids, context=None ):

        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id

        REDIRECT_URI = company.mercadolibre_redirect_uri
        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET)

        url_login_meli = meli.auth_url(redirect_URI=REDIRECT_URI)
        #url_login_oerp = "/meli_login"


        return {
	        "type": "ir.actions.act_url",
	        "url": url_login_meli,
	        "target": "new",
        }

    def product_get_meli_loginstate( self, cr, uid, ids, field_name, attributes, context=None ):
        # recoger el estado y devolver True o False (meli)
        #False if logged ok
        #True if need login
        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id

        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token

        meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

        ML_state = False
        if ACCESS_TOKEN=='':
            ML_state = True
        else:
            response = meli.get("/users/me/", {'access_token':meli.access_token} )
            rjson = response.json()
            if 'error' in rjson:
                if rjson['message']=='invalid_token' or rjson['message']=='expired_token':
                    ACCESS_TOKEN = ''
                    REFRESH_TOKEN = ''
                    company.write({'mercadolibre_access_token': ACCESS_TOKEN, 'mercadolibre_refresh_token': REFRESH_TOKEN, 'mercadolibre_code': '' } )
                    ML_state = True
                    #raise osv.except_osv( _('MELI WARNING'), _('INVALID TOKEN (must login, go to Edit Company and login):  error: %s, message: %s, status: %s') % ( rjson["error"], rjson["message"],rjson["status"],))

        res = {}
        for product in self.browse(cr,uid,ids):
            res[product.id] = ML_state
        return res

    def product_meli_status_close( self, cr, uid, ids, context=None ):
        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id
        product_obj = self.pool.get('product.product')
        product = product_obj.browse(cr, uid, ids[0])

        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token

        meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

        response = meli.put("/items/"+product.meli_id, { 'status': 'closed' }, {'access_token':meli.access_token})

        #print "product_meli_status_close: " + response.content

        return {}

    def product_meli_status_pause( self, cr, uid, ids, context=None ):
        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id
        product_obj = self.pool.get('product.product')
        product = product_obj.browse(cr, uid, ids[0])

        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token

        meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

        response = meli.put("/items/"+product.meli_id, { 'status': 'paused' }, {'access_token':meli.access_token})

        #print "product_meli_status_pause: " + response.content

        return {}

    def product_meli_status_active( self, cr, uid, ids, context=None ):
        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id
        product_obj = self.pool.get('product.product')
        product = product_obj.browse(cr, uid, ids[0])

        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token

        meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

        response = meli.put("/items/"+product.meli_id, { 'status': 'active' }, {'access_token':meli.access_token})

        #print "product_meli_status_active: " + response.content

        return {}

    def product_meli_delete( self, cr, uid, ids, context=None ):

        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id
        product_obj = self.pool.get('product.product')
        product = product_obj.browse(cr, uid, ids[0])

        if product.meli_status!='closed':
            self.product_meli_status_close( cr, uid, ids, context )

        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token

        meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

        response = meli.put("/items/"+product.meli_id, { 'deleted': 'true' }, {'access_token':meli.access_token})

        #print "product_meli_delete: " + response.content
        rjson = response.json()
        ML_status = rjson["status"]
        if "error" in rjson:
            ML_status = rjson["error"]
        if "sub_status" in rjson:
            if len(rjson["sub_status"]) and rjson["sub_status"][0]=='deleted':
                product.write({ 'meli_id': '' })

        return {}

    def product_meli_upload_image( self, cr, uid, ids, context=None ):

        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id

        product_obj = self.pool.get('product.product')
        product = product_obj.browse(cr, uid, ids[0])

        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token

        #
        meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

        if product.image==None or product.image==False:
            return { 'status': 'error', 'message': 'no image to upload' }

        # print "product_meli_upload_image"
        #print "product_meli_upload_image: " + response.content
        imagebin = base64.b64decode(product.image)
        imageb64 = product.image
#       print "data:image/png;base64,"+imageb64
#       files = [ ('images', ('image_medium', imagebin, "image/png")) ]
        files = { 'file': ('image.jpg', imagebin, "image/jpeg"), }
        #print  files
        response = meli.upload("/pictures", files, { 'access_token': meli.access_token } )
       # print response.content

        rjson = response.json()
        if ("error" in rjson):
            raise osv.except_osv( _('MELI WARNING'), _('No se pudo cargar la imagen en MELI! Error: %s , Mensaje: %s, Status: %s') % ( rjson["error"], rjson["message"],rjson["status"],))
            return { 'status': 'error', 'message': 'not uploaded'}

        _logger.info( rjson )

        if ("id" in rjson):
            #guardar id
            product.write( { "meli_imagen_id": rjson["id"], "meli_imagen_link": rjson["variations"][0]["url"] })
            #asociar imagen a producto
            if product.meli_id:
                response = meli.post("/items/"+product.meli_id+"/pictures", { 'id': rjson["id"] }, { 'access_token': meli.access_token } )
            else:
                return { 'status': 'warning', 'message': 'uploaded but not assigned' }

        return { 'status': 'success', 'message': 'uploaded and assigned' }

    def product_meli_upload_multi_images( self, cr, uid, ids, context=None ):

        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id

        product_obj = self.pool.get('product.product')
        product = product_obj.browse(cr, uid, ids[0])

        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token

        #
        meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

        if product.images==None:
            return { 'status': 'error', 'message': 'no images to upload' }

        image_ids = []
        c = 0

        #loop over images
        for product_image in product.images:
            if (product_image.image):
                print "product_image.image:" + str(product_image.image)
                imagebin = base64.b64decode( product_image.image )
                #files = { 'file': ('image.png', imagebin, "image/png"), }
                files = { 'file': ('image.jpg', imagebin, "image/jpeg"), }
                response = meli.upload("/pictures", files, { 'access_token': meli.access_token } )
                print "meli upload:" + response.content
                rjson = response.json()
                if ("error" in rjson):
                    raise osv.except_osv( _('MELI WARNING'), _('No se pudo cargar la imagen en MELI! Error: %s , Mensaje: %s, Status: %s') % ( rjson["error"], rjson["message"],rjson["status"],))
                    #return { 'status': 'error', 'message': 'not uploaded'}
                else:
                    image_ids+= [ { 'id': rjson['id'] }]
                    c = c + 1
                    print "image_ids:" + str(image_ids)

        product.write( { "meli_multi_imagen_id": "%s" % (image_ids) } )

        return image_ids


    def product_on_change_meli_banner(self, cr, uid, ids, banner_id ):

        banner_obj = self.pool.get('mercadolibre.banner')

        #solo para saber si ya habia una descripcion completada
        product_obj = self.pool.get('product.product')
        if len(ids):
            product = product_obj.browse(cr, uid, ids[0])
        else:
            product = product_obj.browse(cr, uid, ids)

        banner = banner_obj.browse( cr, uid, banner_id )

        #banner.description
        _logger.info( banner.description )
        result = ""
        if (banner.description!="" and banner.description!=False and product.meli_imagen_link!=""):
            imgtag = "<img style='width: 420px; height: auto;' src='%s'/>" % ( product.meli_imagen_link )
            result = banner.description.replace( "[IMAGEN_PRODUCTO]", imgtag )
            if (result):
                _logger.info( "result: %s" % (result) )
            else:
                result = banner.description

        return { 'value': { 'meli_description' : result } }

    def product_get_meli_status( self, cr, uid, ids, field_name, attributes, context=None ):

        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id
        warningobj = self.pool.get('warning')

        product_obj = self.pool.get('product.product')
        product = product_obj.browse(cr, uid, ids[0])

        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token

        ML_status = "unknown"
        if ACCESS_TOKEN=='':
            ML_status = "unknown"
        else:
            meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)
            if product.meli_id:
                response = meli.get("/items/"+product.meli_id, {'access_token':meli.access_token} )
                rjson = response.json()
                ML_status = rjson["status"]
                if "error" in rjson:
                    ML_status = rjson["error"]
                if "sub_status" in rjson:
                    if len(rjson["sub_status"]) and rjson["sub_status"][0]=='deleted':
                        product.write({ 'meli_id': '' })

        res = {}
        for product in self.browse(cr,uid,ids):
            res[product.id] = ML_status
        return res

    def product_get_permalink( self, cr, uid, ids, field_name, attributes, context=None ):
        ML_permalink = ''

        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        company = user_obj.company_id

        product_obj = self.pool.get('product.product')
        product = product_obj.browse(cr, uid, ids[0])

        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token


        ML_permalink = ""
        if ACCESS_TOKEN=='':
            ML_permalink = ""
        else:
            meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)
            if product.meli_id:
                response = meli.get("/items/"+product.meli_id, {'access_token':meli.access_token} )
                rjson = response.json()
                if "permalink" in rjson:
                    ML_permalink = rjson["permalink"]
                if "error" in rjson:
                    ML_permalink = ""
                #if "sub_status" in rjson:
                    #if len(rjson["sub_status"]) and rjson["sub_status"][0]=='deleted':
                    #    product.write({ 'meli_id': '' })


        res = {}
        for product in self.browse(cr,uid,ids):
            res[product.id] = ML_permalink
        return res


    def product_post(self, cr, uid, ids, context=None):
        import pdb;pdb.set_trace();
#        product_ids = context['active_ids']
        product_ids = ids
        product_obj = self.pool.get('product.product')

        user_obj = self.pool.get('res.users').browse(cr, uid, uid)
        #user_obj.company_id.meli_login()
        company = user_obj.company_id
        warningobj = self.pool.get('warning')

        #company = self.pool.get('res.company').browse(cr,uid,1)

        REDIRECT_URI = company.mercadolibre_redirect_uri
        CLIENT_ID = company.mercadolibre_client_id
        CLIENT_SECRET = company.mercadolibre_secret_key
        ACCESS_TOKEN = company.mercadolibre_access_token
        REFRESH_TOKEN = company.mercadolibre_refresh_token


        meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

        if ACCESS_TOKEN=='':
            meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET)
            url_login_meli = meli.auth_url(redirect_URI=REDIRECT_URI)
            return {
                "type": "ir.actions.act_url",
                "url": url_login_meli,
                "target": "new",
            }

        for product_id in product_ids:
            product = product_obj.browse(cr,uid,product_id)

            if (product.meli_id):
                response = meli.get("/items/%s" % product.meli_id, {'access_token':meli.access_token})

            # print product.meli_category.meli_category_id

            if product.meli_title==False:
                # print 'Assigning title: product.meli_title: %s name: %s' % (product.meli_title, product.name)
                product.meli_title = product.name

            if product.meli_price==False:
                # print 'Assigning price: product.meli_price: %s standard_price: %s' % (product.meli_price, product.standard_price)
                product.meli_price = product.standard_price

            body = {
                "title": product.meli_title or '',
                "description": product.meli_description or '',
                "category_id": product.meli_category.meli_category_id or '0',
                "listing_type_id": product.meli_listing_type or '0',
                "buying_mode": product.meli_buying_mode or '',
                "price": product.meli_price  or '0',
                "currency_id": product.meli_currency  or '0',
                "condition": product.meli_condition  or '',
                "available_quantity": product.meli_available_quantity  or '0',
                "warranty": product.meli_warranty or '',
                #"pictures": [ { 'source': product.meli_imagen_logo} ] ,
                "video_id": product.meli_video  or '',
            }

            # print body

            assign_img = False and product.meli_id

            #publicando imagen cargada en OpenERP
            if product.image==None:
                return warningobj.info(cr, uid, title='MELI WARNING', message="Debe cargar una imagen de base en el producto.", message_html="" )
            elif product.meli_imagen_id==False:
                # print "try uploading image..."
                resim = product.product_meli_upload_image()
                if "status" in resim:
                    if (resim["status"]=="error" or resim["status"]=="warning"):
                        error_msg = 'MELI: mensaje de error:   ', resim
                        _logger.error(error_msg)
                    else:
                        assign_img = True and product.meli_imagen_id

            #modificando datos si ya existe el producto en MLA
            if (product.meli_id):
                body = {
                    "title": product.meli_title or '',
                    #"description": product.meli_description or '',
                    #"category_id": product.meli_category.meli_category_id,
                    #"listing_type_id": product.meli_listing_type,
                    "buying_mode": product.meli_buying_mode or '',
                    "price": product.meli_price or '0',
                    #"currency_id": product.meli_currency,
                    "condition": product.meli_condition or '',
                    "available_quantity": product.meli_available_quantity or '0',
                    "warranty": product.meli_warranty or '',
                    "pictures": [],
                    #"pictures": [ { 'source': product.meli_imagen_logo} ] ,
                    "video_id": product.meli_video or '',
                }

            #publicando multiples imagenes
            multi_images_ids = {}
            if (product.images):
                # print 'website_multi_images presente:   ', product.images
                #recorrer las imagenes y publicarlas
                multi_images_ids = product.product_meli_upload_multi_images()

            #asignando imagen de logo (por source)
            if product.meli_imagen_logo:
                if product.meli_imagen_id:
                    if 'pictures' in body.keys():
                        body["pictures"]+= [ { 'id': product.meli_imagen_id } ]
                    else:
                        body["pictures"] = [ { 'id': product.meli_imagen_id } ]

                        if (multi_images_ids):
                            if 'pictures' in body.keys():
                                body["pictures"]+= multi_images_ids
                            else:
                                body["pictures"] = multi_images_ids

                    if 'pictures' in body.keys():
                        body["pictures"]+= [ { 'source': product.meli_imagen_logo} ]
                    else:
                        body["pictures"]+= [ { 'source': product.meli_imagen_logo} ]
                else:
                    imagen_producto = ""
                    if (product.meli_description!="" and product.meli_description!=False and product.meli_imagen_link!=""):
                        imgtag = "<img style='width: 420px; height: auto;' src='%s'/>" % ( product.meli_imagen_link )
                        result = product.meli_description.replace( "[IMAGEN_PRODUCTO]", imgtag )
                        if (result):
                            _logger.info( "result: %s" % (result) )
                            product.meli_description = result
                        else:
                            result = product.meli_description



            else:
                return warningobj.info(cr, uid, title='MELI WARNING', message="Debe completar el campo 'Imagen_Logo' con el url: http://www.nuevohorizonte-sa.com.ar/images/logo1.png", message_html="")

            #check fields
            if product.meli_description==False:
                return warningobj.info(cr, uid, title='MELI WARNING', message="Debe completar el campo 'description' (en html)", message_html="")

            #put for editing, post for creating
            if product.meli_id:
                response = meli.put("/items/"+product.meli_id, body, {'access_token':meli.access_token})
            else:
                assign_img = True and product.meli_imagen_id
                response = meli.post("/items", body, {'access_token':meli.access_token})

            #check response
            # print response.content
            rjson = response.json()

            #check error
            if "error" in rjson:
                #print "Error received: %s " % rjson["error"]
                error_msg = 'MELI: mensaje de error:  %s , mensaje: %s, status: %s, cause: %s ' % (rjson["error"], rjson["message"], rjson["status"], rjson["cause"])
                _logger.error(error_msg)

                missing_fields = error_msg

                #expired token
                if "message" in rjson and (rjson["message"]=='invalid_token' or rjson["message"]=="expired_token"):
                    meli = Meli(client_id=CLIENT_ID,client_secret=CLIENT_SECRET)
                    url_login_meli = meli.auth_url(redirect_URI=REDIRECT_URI)
                    #print "url_login_meli:", url_login_meli
                    #raise osv.except_osv( _('MELI WARNING'), _('INVALID TOKEN or EXPIRED TOKEN (must login, go to Edit Company and login):  error: %s, message: %s, status: %s') % ( rjson["error"], rjson["message"],rjson["status"],))
                    return warningobj.info(cr, uid, title='MELI WARNING', message="Debe iniciar sesión en MELI.  ", message_html="")
                else:
                     #Any other errors
                    return warningobj.info(cr, uid, title='MELI WARNING', message="Completar todos los campos!  ", message_html="<br><br>"+missing_fields )

            #last modifications if response is OK
            if "id" in rjson:
                product.write( { 'meli_id': rjson["id"]} )

            posting_fields = {'posting_date': str(datetime.now()),'meli_id':rjson['id'],'product_id':product.id,'name': 'Post: ' + product.meli_title }

            posting_id = self.pool.get('mercadolibre.posting').search(cr,uid,[('meli_id','=',rjson['id'])])

            if not posting_id:
                posting_id = self.pool.get('mercadolibre.posting').create(cr,uid,(posting_fields))


        return {}

    _columns = {
    'meli_imagen_id': fields.char(string='Imagen Id', size=256),
    'meli_post_required': fields.boolean(string='Este producto es publicable en Mercado Libre'),
	'meli_id': fields.char( string='Id del item asignado por Meli', size=256),
    'meli_permalink': fields.function( product_get_permalink, method=True, type='char',  size=256, string='PermaLink in MercadoLibre' ),
	'meli_title': fields.char(string='Nombre del producto en Mercado Libre',size=256),
	'meli_description': fields.html(string='Descripción'),
    'meli_description_banner_id': fields.many2one("mercadolibre.banner","Banner"),
	'meli_category': fields.many2one("mercadolibre.category","Categoría de MercadoLibre"),
	'meli_listing_type': fields.selection([("free","Libre"),("bronze","Bronce"),("silver","Plata"),("gold","Oro"),("gold_premium","Gold Premium"),("gold_special","Gold Special"),("gold_pro","Oro Pro")], string='Tipo de lista'),
	'meli_buying_mode': fields.selection( [("buy_it_now","Compre ahora"),("classified","Clasificado")], string='Método de compra'),
	'meli_price': fields.char(string='Precio de venta', size=128),
	'meli_price_fixed': fields.boolean(string='Price is fixed'),
	'meli_currency': fields.selection([("ARS","Peso Argentino (ARS)")],string='Moneda (ARS)'),
	'meli_condition': fields.selection([ ("new", "Nuevo"), ("used", "Usado"), ("not_specified","No especificado")],'Condición del producto'),
	'meli_available_quantity': fields.integer(string='Cantidad disponible'),
	'meli_warranty': fields.char(string='Garantía', size=256),
	'meli_imagen_logo': fields.char(string='Imagen Logo', size=256),
    'meli_imagen_id': fields.char(string='Imagen Id', size=256),
    'meli_imagen_link': fields.char(string='Imagen Link', size=256),
    'meli_multi_imagen_id': fields.char(string='Multi Imagen Ids', size=512),
	'meli_video': fields.char( string='Video (id de youtube)', size=256),
	'meli_state': fields.function( product_get_meli_loginstate, method=True, type='boolean', string="Inicio de sesión requerida", store=False ),
    'meli_status': fields.function( product_get_meli_status, method=True, type='char', size=128, string="Estado del producto en MLA", store=False ),
	### Agregar imagen/archivo uno o mas, y la descripcion en HTML...
	# TODO Agregar el banner
    }

    _defaults = {
        'meli_imagen_logo': 'None',
        'meli_video': ''
    }
class xls_report(osv.osv_memory):
    _name = 'xls.report'
    _columns = {
        'partner_ids': fields.one2many('multi.partners','name','Partner IDs'),
        'region_id': fields.many2one('res.region', string="Region"),
        'type': fields.selection([('IncomeTax Report', 'IncomeTax Report'),
                                  ('Purchase Register', 'Purchase Register'),
                                  ('Sales Register', 'Sales Register'),
                                  ('Annex C', 'Annex C'),
                                  ('Collection Report', 'Collection Report'),
                                  ('Individual Aging', 'Individual Aging'),
                                  ('Monthly or Weekly Progress', 'Monthly or Weekly Progress'),
                                  ('/', '/')], 'Report Type', required=True),
        'date_from': fields.date('From', required=True),
        'date_to': fields.date('To', required=True),
        'company_id': fields.many2one('res.company', 'Company'),
        'partner_id': fields.many2one('res.partner', 'Customer', domain=[('customer','=','True')]),
    }

    _defaults = {
        'date_from': lambda *a: datetime.now().strftime('%Y-%m-%d'),
        'date_to': lambda *a: datetime.now().strftime('%Y-%m-%d'),
        'type': '/'
    }

    def check_dates(self, cr, uid, ids, context=None):
        wizard = self.browse(cr, uid, ids, context=context)[0]
        if wizard.date_from:
            if wizard.date_from > wizard.date_to:
                return False
            if wizard.date_to > fields.date.today():
                return False
        return True

    _constraints = [(check_dates,
                     'Error: Invalid Dates\nDate From must be less than Date To\nDate To must not be greater than todays date.',
                     ['date_from', 'date_to']), ]

    def report_data(self, data,account_head):
        res = {}
        for rec in data:
            partner_id = self.env['res.partner'].search([['id', '=', rec['partner_id']],])
            res = {
                'customer': partner_id.name,
                'account_head': account_head,
                'entry': rec['ref'],
                'particulars': rec['name'],
                'date': rec['date'],
                'amount': rec['debit'],
            }
        return res

    def collection_report(self):
       self.env.cr.execute("""select account_move_line.date,account_move.name as number,
       account_account.name as account_head, res_partner.name as customer,
       account_move_line.debit,account_move_line.ref
       from account_move inner join account_move_line on account_move.id = account_move_line.move_id
       inner join account_account on account_move_line.account_id = account_account.id
       inner join res_partner on account_move_line.partner_id=res_partner.id
       where account_account.type ='liquidity' and account_move.state='posted' 
       and account_move_line.debit>0 and account_move_line.date between '%s' and '%s' and account_account.company_id=%s order by account_move_line.date asc
       """%(self.date_from,self.date_to,self.company_id.id))
       result= self.env.cr.dictfetchall()
       return result

    def collection_report_region_wise(self):
        self.env.cr.execute("""select account_move_line.date,account_move.name as number,
          account_account.name as account_head, res_partner.name as customer,res_region.name as region,
          account_move_line.debit,account_move_line.ref
          from account_move inner join account_move_line on account_move.id = account_move_line.move_id
          inner join account_account on account_move_line.account_id = account_account.id
          inner join res_partner on account_move_line.partner_id=res_partner.id
          inner join res_region on res_partner.region_id = res_region.id
          where account_account.type ='liquidity' and account_move.state='posted' 
          and res_partner.region_id=%s
          and account_move_line.debit>0 and account_move_line.date between '%s' and '%s' and account_account.company_id=%s order by account_move_line.date asc
          """ % (self.region_id.id,self.date_from, self.date_to, self.company_id.id))
        result = self.env.cr.dictfetchall()
        return result

    def cal_aging_brackets(self,data):
        _list = []
        date_format = "%Y-%m-%d"
        for rec in data:
            a = datetime.strptime(rec['date_invoice'], date_format)
            b = datetime.strptime(datetime.now().strftime('%Y-%m-%d'), date_format)
            delta = b - a
            rec['days'] = delta.days
            _list.append(rec)
        return _list

    def individual_aging_report(self):
        if self.partner_id:
            self.env.cr.execute(
                    "select account_invoice.number,account_invoice.partner_id,account_invoice.date_invoice,account_invoice.residual as amount_total from account_invoice where account_invoice.date_invoice between'" + str(
                        self.date_from) + "'" + " and '" + str(
                        self.date_to) + "'" + "and state='open'" + "and account_invoice.company_id=" + str(
                        self.company_id.id) + "and account_invoice.partner_id="+str(self.partner_id.id)+"and type='out_invoice'order by account_invoice.date_invoice")
            data = self.env.cr.dictfetchall()
            res = self.cal_aging_brackets(data)
            return res
        else:
            res = []
            for partner in self.partner_ids:
                self.env.cr.execute(
                    "select account_invoice.number,account_invoice.partner_id,account_invoice.date_invoice,account_invoice.residual as amount_total from account_invoice where account_invoice.date_invoice between'" + str(
                        self.date_from) + "'" + " and '" + str(
                        self.date_to) + "'" + "and state='open'" + "and account_invoice.company_id=" + str(
                        self.company_id.id) + "and account_invoice.partner_id=" + str(
                        partner.partner_id.id) + "and type='out_invoice'order by account_invoice.date_invoice")
                data = self.env.cr.dictfetchall()
                result = self.cal_aging_brackets(data)
                res.append({'customer':partner.partner_id.name,'details':result})
            return res

    def collection_report_(self, mw_id):
        collection_amount = 0
        self.env.cr.execute("""select account_move_line.date,account_move.name as number,
                  account_account.name as account_head, res_partner.name as customer,
                  account_move_line.debit,account_move_line.ref
                  from account_move inner join account_move_line on account_move.id = account_move_line.move_id
                  inner join account_account on account_move_line.account_id = account_account.id
                  inner join res_partner on account_move_line.partner_id=res_partner.id
                  where account_account.type ='liquidity' and account_move.state='posted' and account_move_line.partner_id=%s
                  and account_move_line.debit>0 and account_move_line.date between '%s' and '%s' and account_account.company_id=%s order by account_move_line.date asc
                  """ % (mw_id,self.date_from, self.date_to, self.company_id.id))
        result = self.env.cr.dictfetchall()
        for res in result:
            collection_amount += res['debit']
        return collection_amount

    def mw_progress_report(self):
        mw_report = []
        final_res = []
        new = []
        _res = []
        result = []
        self.env.cr.execute('select id from res_partner where res_partner.customer=True')
        customers = self.env.cr.dictfetchall()
        for customer in customers:
            if self.company_id.name == 'Sara Automobiles':
                self.env.cr.execute("select sum(account_move_line.debit) - sum(account_move_line.credit) as opening from account_move_line inner join account_move on account_move_line.move_id = account_move.id where account_move_line.date < '"+str(self.date_from)+"'"+"and account_move_line.partner_id="+str(customer['id'])+"and account_move.state='posted'and account_move_line.company_id=1 and(account_move_line.account_id=8 or account_move_line.account_id=13)")
                data = self.env.cr.dictfetchall()
                if data[0]['opening']!=None:
                    data[0]['partner_id']=customer['id']
                    result.append(data)
                else:
                    data[0]['opening'] = 0
                    data[0]['partner_id'] = customer['id']
                    result.append(data)
        for records in result:
            for rec in records:
                collection = self.collection_report_(rec['partner_id'])
                rec['collection'] = collection
                _res.append(rec)
        for rec in _res:
            self.env.cr.execute("select rp.name as customer,ai.partner_id,sum(ai.amount_total) as amount_total from account_invoice as ai inner join res_partner as rp on ai.partner_id = rp.id where ai.date_invoice between'"+self.date_from+"'"+"and'"+self.date_to+"'"+"and ai.partner_id="+str(rec['partner_id'])+"group by rp.name,ai.partner_id")
            data = self.env.cr.dictfetchall()
            customer = self.env['res.partner'].search([['id', '=', rec['partner_id']], ])
            if len(data)>0:
                rec['sale_amount'] = data[0]['amount_total']
                rec['customer'] = customer.name
                new.append(rec)
            else:
                rec['sale_amount'] = 0
                rec['customer'] = customer.name
                new.append(rec)
        for i in new:
            if int(i['opening'])>0 or int(i['collection'])>0 or int(i['sale_amount'])>0:
                final_res.append(i)

        for i in final_res:
            print(i['partner_id'])
            self.env.cr.execute("""
            select sum(av.amount_total) as sales_return from account_invoice as av where av.type='out_refund' and av.partner_id=%s group by av.amount_total"""%(i['partner_id']))
            data = self.env.cr.dictfetchall()
            print(data)
            if len(data) > 0:
                i['sales_return'] = data[0]['sales_return']
                mw_report.append(i)
            else:
                i['sales_return'] = 0
                mw_report.append(i)
        return mw_report

    def print_report(self, cr, uid, ids, data, context=None):
        obj = self.browse(cr, uid, ids[0], context=context)
        if obj.type == 'Collection Report':
            if obj.region_id:
                return {
                    'type': 'ir.actions.report.xml',
                    'name': 'custom_inventory.collection_region_wise',
                    'report_name': 'custom_inventory.collection_region_wise'
                }
            else:
                return {
                    'type': 'ir.actions.report.xml',
                    'name': 'custom_inventory.collection_report',
                    'report_name': 'custom_inventory.collection_report'
                }
        elif obj.type == 'Individual Aging':
            if obj.partner_id:
                return {
                    'type': 'ir.actions.report.xml',
                    'name': 'custom_inventory.wiz_individual_aging_report',
                    'report_name': 'custom_inventory.wiz_individual_aging_report'
                }
            else:
                return {
                    'type': 'ir.actions.report.xml',
                    'name': 'custom_inventory.individual_aging_multiple_customers',
                    'report_name': 'custom_inventory.individual_aging_multiple_customers'
                }
        elif obj.type == 'Monthly or Weekly Progress':
            return {
                'type': 'ir.actions.report.xml',
                'name': 'custom_inventory.wiz_mw_progress_report',
                'report_name': 'custom_inventory.wiz_mw_progress_report'
            }

    def sales_register_report(self, cr, uid, ids, context=None):
        obj = self.browse(cr, uid, ids[0], context=context)
        cr.execute(
            "select sales_register.ntn,sales_register.nic,custom_dummy_invoice.partner_id,custom_dummy_invoice.amount_total,sales_register.products,sales_register.engine_number,sales_register.chassis_number,"
            "sales_register.sara_inv_number,sales_register.date,sales_register.excl_val,sales_register.further_tax,sales_register.sales_tax,"
            "sales_register.price_subtotal from custom_dummy_invoice_line as sales_register inner join custom_dummy_invoice on sales_register.name = custom_dummy_invoice.id where sales_register.date between'" + str(
                obj.date_from) + "'" + " and '" + str(
                obj.date_to) + "'" + "order by sales_register.date")
        data = cr.dictfetchall()
        return data

    def annex_c_report(self, cr, uid, ids, context=None):
        obj = self.browse(cr, uid, ids[0], context=context)
        cr.execute(
            "select rp.ntn,rp.nic,rp.name,rp.taxation,cdi.amount_untaxed,cdi.type,cdi.date_invoice,cdi.sara_inv_serial,cdi.amount_tax,cdi.amount_total,cdi.further_tax from custom_dummy_invoice as cdi inner join res_partner as rp on cdi.dealer_id = rp.id where cdi.date_invoice between'" + str(
                obj.date_from) + "'" + " and '" + str(
                obj.date_to) + "'" + "order by cdi.date_invoice asc")
        data = cr.dictfetchall()
        return data

    def income_tax_report(self,cr, uid, ids, context=None):
        obj = self.browse(cr, uid, ids[0], context=context)
        cr.execute(
            """
            select rp.ntn,rp.name,rp.street,rp.city,aml.date,aml.ref,aml.move_id,aml.credit from account_move_line as aml 
            inner join account_move as am on aml.move_id=am.id 
            inner join account_account as aa on aml.account_id = aa.id 
            inner join res_partner as rp on aml.partner_id = rp.id 
            inner join account_account_type as aat on aa.user_type=aat.id
            where aat.name = 'Income Tax' and aml.date between '%s' and '%s'
            """%(obj.date_from, obj.date_to))
        data = cr.dictfetchall()
        return data

    def purchase_register_report(self,cr, uid, ids, context=None):
        obj = self.browse(cr, uid, ids[0], context=context)
        cr.execute(
            "select rp.ntn,rp.name,rp.street,rp.city,av.date_invoice,av.amount_tax,av.number,av.amount_total,av.amount_untaxed,avl.name as description,avl.quantity,avl.price_unit from account_invoice as av inner join res_partner as rp on av.partner_id = rp.id "
            "inner join account_invoice_line as avl on av.id = avl.invoice_id where av.date_invoice between'" + str(
                obj.date_from) + "'" + " and '" + str(
                obj.date_to) + "'" + "and av.type='in_invoice' order by date_invoice asc")
        data = cr.dictfetchall()
        return data

    def report_xls(self, cr, uid, ids, context=None):
        date_format = "%d-%m-%Y"
        date_format_new = "%Y-%m-%d"
        if self.check_dates(cr, uid, ids, context=None):
            obj = self.browse(cr, uid, ids[0], context=context)
            fl = StringIO.StringIO()
            if context is None: context = {}
            wb = xlwt.Workbook()
            ws = wb.add_sheet('Report')
            font = xlwt.Font()
            font.bold = True
            borders = xlwt.Borders()
            bold_style = xlwt.XFStyle()
            bold_style.font = font
            new_style7 = xlwt.easyxf('font:height 210; font:name Calibri; align:wrap No;')
            borders.bottom = xlwt.Borders.THICK
            # ws.col(1).width = 500 * 12
            # ws.row(5).height = 70 * 5
            if obj.type == 'Sales Register':
                for i in range(len(sales_register)):
                     ws.write(0, i,sales_register[i], new_style7)
                data = self.sales_register_report(cr,uid,ids,context=context)
                rows = len(data)
                if rows >0:
                    for i in range(len(data)):
                        ws.write(i+1, 0, i+1, new_style7)
                        ws.write(i+1, 1, data[i]['ntn'], new_style7)
                        ws.write(i+1, 2, data[i]['nic'], new_style7)
                        ws.write(i+1, 3, data[i]['partner_id'], new_style7)
                        ws.write(i+1, 4, data[i]['products'], new_style7)
                        ws.write(i+1, 5, data[i]['engine_number'], new_style7)
                        ws.write(i+1, 6, data[i]['chassis_number'], new_style7)
                        ws.write(i+1, 7, data[i]['sara_inv_number'], new_style7)
                        ws.write(i+1, 8, datetime.strftime(datetime.strptime(data[i]['date'],date_format_new),date_format), new_style7)
                        ws.write(i+1, 9, data[i]['excl_val'], new_style7)
                        ws.write(i+1, 10, data[i]['further_tax'], new_style7)
                        ws.write(i+1, 11, data[i]['sales_tax'], new_style7)
                        ws.write(i+1, 12, data[i]['amount_total'], new_style7)

            elif obj.type == 'Purchase Register':
                for i in range(len(purchase_register)):
                    ws.write(0, i, purchase_register[i], new_style7)
                data = self.purchase_register_report(cr, uid, ids, context=context)
                rows = len(data)
                if rows > 0:
                    for i in range(len(data)):
                        ws.write(i + 1, 0, i + 1, new_style7)
                        ws.write(i + 1, 1, data[i]['ntn'], new_style7)
                        ws.write(i + 1, 2, data[i]['name'], new_style7)
                        ws.write(i + 1, 3, str(data[i]['street']) + str(data[i]['city']), new_style7)
                        ws.write(i + 1, 4, data[i]['description'], new_style7)
                        ws.write(i + 1, 5, data[i]['number'],new_style7)
                        ws.write(i + 1, 6, datetime.strftime(datetime.strptime(data[i]['date_invoice'],date_format_new),date_format), new_style7)
                        ws.write(i + 1, 7, data[i]['quantity'], new_style7)
                        ws.write(i + 1, 8, data[i]['price_unit'], new_style7)
                        ws.write(i + 1, 9, data[i]['amount_untaxed'], new_style7)
                        ws.write(i + 1, 10, data[i]['amount_tax'], new_style7)
                        ws.write(i + 1, 11, data[i]['amount_total'], new_style7)
                        ws.write(i + 1, 12, '', new_style7)

            elif obj.type == 'IncomeTax Report':
                for i in range(len(income_tax)):
                    ws.write(0, i, income_tax[i], new_style7)
                data = self.income_tax_report(cr, uid, ids, context=context)
                rows = len(data)
                if rows >0:
                    for i in range(len(data)):
                        ws.write(i+1, 0, i+1, new_style7)
                        ws.write(i+1, 1, data[i]['ntn'], new_style7)
                        ws.write(i+1, 2, data[i]['name'], new_style7)
                        ws.write(i+1, 3, str(data[i]['street'])+str(data[i]['city']), new_style7)
                        ws.write(i+1, 4, '', new_style7)
                        ws.write(i+1, 5, '', new_style7)
                        ws.write(i+1, 6, datetime.strftime(datetime.strptime(data[i]['date'],date_format_new),date_format), new_style7)
                        ws.write(i+1, 7, data[i]['ref'], new_style7)
                        ws.write(i + 1, 8, '', new_style7)
                        ws.write(i + 1, 9, '', new_style7)
                        ws.write(i+1, 10, '', new_style7)
                        ws.write(i+1, 11, data[i]['credit'], new_style7)
                        ws.write(i+1, 12, '', new_style7)

            elif obj.type == 'Annex C':
                for i in range(len(annex_c)):
                     ws.write(0, i, annex_c[i], new_style7)
                data = self.annex_c_report(cr,uid,ids,context=context)
                rows = len(data)
                if rows >0:
                    for i in range(len(data)):
                        ws.write(i+1, 0, i+1, new_style7)
                        ws.write(i+1, 1, data[i]['ntn'], new_style7)
                        ws.write(i+1, 2, data[i]['nic'], new_style7)
                        ws.write(i+1, 3, data[i]['name'], new_style7)
                        ws.write(i+1, 4, data[i]['taxation'], new_style7)
                        ws.write(i+1, 5, '', new_style7)
                        ws.write(i+1, 6, 'SI', new_style7)
                        ws.write(i+1, 7, data[i]['sara_inv_serial'], new_style7)
                        ws.write(i+1, 8, datetime.strftime(datetime.strptime(data[i]['date_invoice'],date_format_new),date_format), new_style7)
                        ws.write(i+1, 9, '', new_style7)
                        if data[i]['type'] == 'Unregistered':
                            ws.write(i+1, 10, data[i]['type'],new_style7)
                        else:
                            ws.write(i + 1, 10,'Registered',new_style7)
                        ws.write(i+1, 11, '', new_style7)
                        ws.write(i+1, 12, '', new_style7)
                        ws.write(i+1, 13, '', new_style7)
                        ws.write(i+1, 14, '', new_style7)
                        ws.write(i+1, 15, data[i]['amount_untaxed'], new_style7)
                        ws.write(i+1, 16, data[i]['amount_tax'], new_style7)
                        ws.write(i+1, 17, '', new_style7)
                        ws.write(i+1, 18, '', new_style7)
                        ws.write(i+1, 19, '', new_style7)
                        ws.write(i+1, 20, '', new_style7)
                        ws.write(i+1, 21, data[i]['further_tax'], new_style7)
                        ws.write(i+1, 22, data[i]['amount_total'], new_style7)

            wb.save(fl)
            fl.seek(0)
            buf = base64.encodestring(fl.read())
            ctx = dict(context)
            ctx.update({'file': buf})
            if context is None:
                context = {}
            data = {}
            res = self.read(cr, uid, ids, [], context=context)
            res = res and res[0] or {}
            data['form'] = res
            try:
                form_id = \
                self.pool.get('ir.model.data').get_object_reference(cr, uid, 'report_xls', 'view_xls_file_form_view')[1]
            except ValueError:
                form_id = False
            return {
                'type': 'ir.actions.act_window',
                'view_type': 'form',
                'view_mode': 'form',
                'res_model': 'demo.xls.report.file',
                'views': [(form_id, 'form')],
                'view_id': form_id,
                'targer': 'new',
                'context': ctx
            }
Beispiel #26
0
class wage_increment_run(models.Model):

    _name = 'hr.contract.wage.increment.run'
    _description = 'Wage Increment Batches'

    _inherit = ['ir.needaction_mixin']

    _columns = {
        'name':
        fields.char(
            'Name',
            size=64,
            required=True,
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'effective_date':
        fields.date(
            'Effective Date',
            required=True,
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'type':
        fields.selection(
            [
                ('fixed', 'Fixed Amount'),
                ('percent', 'Percentage'),
                ('final', 'Final Amount'),
                ('manual', 'Manual'),
            ],
            'Type',
            required=True,
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'adjustment_amount':
        fields.float(
            'Adjustment Amount',
            digits_compute=dp.get_precision('Payroll'),
            required=True,
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'increment_ids':
        fields.one2many(
            'hr.contract.wage.increment',
            'run_id',
            'Adjustments',
            required=False,
            readonly=False,
            states={
                'confirm': [('readonly', False)],
                'approve': [('readonly', True)],
                'decline': [('readonly', True)],
            },
        ),
        'state':
        fields.selection([('draft', 'Draft'), ('confirm', 'Confirmed'),
                          ('approve', 'Approved'), ('decline', 'Declined')],
                         'State',
                         readonly=True),
    }

    _defaults = {
        'state': 'draft',
    }

    def _needaction_domain_get(self, cr, uid, context=None):

        users_obj = self.pool.get('res.users')
        domain = []

        if users_obj.has_group(cr, uid, 'hr_security.group_hr_director'):
            domain = [('state', 'in', ['confirm'])]
            return domain

        return False

    def unlink(self, cr, uid, ids, context=None):

        if isinstance(ids, (int, long)):
            ids = [ids]

        for run in self.browse(cr, uid, ids, context=context):
            if run.state in ['approve']:
                raise models.except_orm(
                    _('The adjustment run cannot be deleted!'),
                    _('You may not delete a wage adjustment that is in the '
                      '%s state.') % run.state)

        return super(wage_increment_run, self).unlink(cr,
                                                      uid,
                                                      ids,
                                                      context=context)

    def _state(self, cr, uid, ids, signal, state, context=None):

        wkf = netsvc.LocalService('workflow')
        for run in self.browse(cr, uid, ids, context=context):
            [
                wkf.trg_validate(uid, 'hr.contract.wage.increment', incr.id,
                                 signal, cr) for incr in run.increment_ids
            ]
            self.write(cr, uid, run.id, {'state': state}, context=context)

        return True

    def state_confirm(self, cr, uid, ids, context=None):

        return self._state(cr, uid, ids, 'signal_confirm', 'confirm', context)

    def state_approve(self, cr, uid, ids, context=None):

        return self._state(cr, uid, ids, 'signal_approve', 'approve', context)

    def state_decline(self, cr, uid, ids, context=None):

        return self._state(cr, uid, ids, 'signal_decline', 'decline', context)
Beispiel #27
0
class wage_increment(models.Model):

    _name = 'hr.contract.wage.increment'
    _description = 'HR Contract Wage Adjustment'

    def _calculate_difference(self,
                              cr,
                              uid,
                              ids,
                              field_name,
                              args,
                              context=None):

        res = dict.fromkeys(ids)
        for incr in self.browse(cr, uid, ids, context=context):
            if incr.wage >= incr.contract_id.wage:
                percent = ((incr.wage / incr.contract_id.wage) - 1.0) * 100.0
            else:
                percent = (1.0 - (incr.wage / incr.contract_id.wage)) * -100.0
            res[incr.id] = {
                'wage_difference': incr.wage - incr.current_wage,
                'wage_difference_percent': percent,
            }

        return res

    def _get_department(self, cr, uid, ids, field_name, arg, context=None):

        res = dict.fromkeys(ids, False)
        for incr in self.browse(cr, uid, ids, context=context):
            res[incr.id] = incr.employee_id.department_id.id,

        return res

    _columns = {
        'effective_date':
        fields.date(
            'Effective Date',
            required=True,
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'wage':
        fields.float(
            'New Wage',
            digits_compute=dp.get_precision('Payroll'),
            required=True,
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'new_contract_id':
        fields.many2one(
            'hr.contract',
            'New Contract',
            readonly=True,
        ),
        'contract_id':
        fields.many2one(
            'hr.contract',
            'Contract',
            readonly=True,
        ),
        'current_wage':
        fields.related(
            'contract_id',
            'wage',
            type='float',
            string='Current Wage',
            store=True,
            readonly=True,
        ),
        'wage_difference':
        fields.function(
            _calculate_difference,
            type='float',
            method=True,
            string='Difference',
            multi='diff',
            readonly=True,
        ),
        'wage_difference_percent':
        fields.function(
            _calculate_difference,
            type='float',
            method=True,
            string='Percentage',
            multi='diff',
            readonly=True,
        ),
        'employee_id':
        fields.related(
            'contract_id',
            'employee_id',
            relation='hr.employee',
            type='many2one',
            string='Employee',
            store=True,
            readonly=True,
        ),
        'job_id':
        fields.related(
            'contract_id',
            'job_id',
            relation='hr.job',
            type='many2one',
            string='Job',
            store=True,
            readonly=True,
        ),
        'department_id':
        fields.related(
            'employee_id',
            'department_id',
            relation='hr.department',
            type='many2one',
            string='Department',
            store=True,
            readonly=True,
        ),
        'state':
        fields.selection(
            [('draft', 'Draft'), ('confirm', 'Confirmed'),
             ('approve', 'Approved'), ('decline', 'Declined')],
            'State',
            readonly=True,
        ),
        'run_id':
        fields.many2one(
            'hr.contract.wage.increment.run',
            'Batch Run',
            readonly=True,
            ondelete='cascade',
        ),
    }

    def _get_contract_data(self, cr, uid, field_list, context=None):

        if context is None:
            context = {}
        employee_id = self._get_employee(cr, uid, context=context)
        ee_data = self.pool.get('hr.employee').read(cr,
                                                    uid,
                                                    employee_id,
                                                    ['contract_id'],
                                                    context=context)
        contract_id = ee_data.get('contract_id', False)[0]
        if not contract_id:
            return False

        data = self.pool.get('hr.contract').read(cr,
                                                 uid,
                                                 contract_id,
                                                 field_list,
                                                 context=context)

        return data

    def _get_contract_id(self, cr, uid, context=None):

        data = self._get_contract_data(cr, uid, ['id'], context)
        return data.get('id', False)

    def _get_employee(self, cr, uid, context=None):

        if context is None:
            context = {}
        employee_id = context.get('active_id', False)

        return employee_id

    def _get_effective_date(self, cr, uid, context=None):

        contract_id = self._get_contract_id(cr, uid, context=context)
        if not contract_id:
            return False

        contract = self.pool.get('hr.contract').browse(cr,
                                                       uid,
                                                       contract_id,
                                                       context=context)
        if contract.pps_id:
            first_day = 1
            if contract.pps_id.type == 'monthly':
                first_day = contract.pps_id.mo_firstday
            date_format = '%Y-%m-' + first_day
            dThisMonth = datetime.now().strftime(date_format).strptime(
                DEFAULT_SERVER_DATE_FORMAT).date()
            dNextMonth = (datetime.now() + relativedelta(months=+1)).strftime(
                date_format).strptime(DEFAULT_SERVER_DATE_FORMAT).date()
            if dThisMonth < datetime.now().date():
                return dNextMonth.strftime(DEFAULT_SERVER_DATE_FORMAT)
            else:
                return dThisMonth.strftime(DEFAULT_SERVER_DATE_FORMAT)

        return False

    _defaults = {
        'contract_id': _get_contract_id,
        'employee_id': _get_employee,
        'effective_date': _get_effective_date,
        'state': 'draft',
    }

    _rec_name = 'effective_date'

    def _check_state(self, cr, uid, wage_incr, context=None):

        wage_incr_ids = self.search(
            cr,
            uid, [
                ('contract_id', '=', wage_incr.contract_id.id),
                ('state', 'in', ['draft', 'confirm', 'approved']),
                ('id', '!=', wage_incr.id),
            ],
            context=context)
        if len(wage_incr_ids) > 0:
            data = self.pool.get('hr.contract').read(cr,
                                                     uid,
                                                     wage_incr.contract_id.id,
                                                     ['name'],
                                                     context=context)
            raise models.except_orm(
                _('Warning'),
                _('There is already another wage adjustment in progress for '
                  'this contract: %s.') % (data['name']))

        contract_obj = self.pool.get('hr.contract')
        data = contract_obj.read(cr,
                                 uid,
                                 wage_incr.contract_id.id,
                                 ['state', 'date_end'],
                                 context=context)

        if data['state'] in ['draft', 'done']:
            data = self.pool.get('hr.contract').read(cr,
                                                     uid,
                                                     wage_incr.contract_id.id,
                                                     ['name'],
                                                     context=context)
            raise models.except_orm(
                _('Warning!'),
                _('The current state of the contract does not permit a wage '
                  'change: %s') % (data['name']))

        if data.get('date_end', False) and data['date_end'] != '':
            dContractEnd = datetime.strptime(data['date_end'],
                                             DEFAULT_SERVER_DATE_FORMAT)
            dEffective = datetime.strptime(wage_incr.effective_date,
                                           DEFAULT_SERVER_DATE_FORMAT)
            if dEffective >= dContractEnd:
                data = self.pool.get('hr.contract').read(
                    cr,
                    uid,
                    wage_incr.contract_id.id, ['name'],
                    context=context)
                raise models.except_orm(
                    _('Warning!'),
                    _('The contract end date is on or before the effective '
                      'date of the adjustment: %s') % (data['name']))
        return True

    def action_wage_increment(self, cr, uid, ids, context=None):

        hr_obj = self.pool.get('hr.contract')

        if isinstance(ids, (int, long)):
            ids = [ids]

        # Copy the contract and adjust start/end dates and wage accordingly.
        #
        for wi in self.browse(cr, uid, ids, context=context):

            if -0.01 < wi.wage_difference < 0.01:
                continue

            self._check_state(cr, uid, wi, context=context)

            default = {
                'wage': wi.wage,
                'date_start': wi.effective_date,
                'name': False,
                'state': False,
                'message_ids': False,
                'trial_date_start': False,
                'trial_date_end': False,
            }
            data = hr_obj.copy_data(cr,
                                    uid,
                                    wi.contract_id.id,
                                    default=default,
                                    context=context)
            notes = data.get('notes', False)
            if not notes:
                notes = ''
            notes = notes + \
                _('\nSuperceedes (because of wage adjustment) previous '
                  'contract: ') + wi.contract_id.name
            data['notes'] = notes

            c_id = hr_obj.create(cr, uid, data, context=context)
            if c_id:
                if wi.contract_id.notes:
                    notes = wi.contract_id.notes
                else:
                    notes = ''
                notes = notes + \
                    _('\nSuperceeded (for wage adjustment) by contract: ') + \
                    wi.contract_id.name
                vals = {'notes': notes, 'date_end': False}
                wkf = netsvc.LocalService('workflow')

                # Set the new contract to the appropriate state
                wkf.trg_validate(uid, 'hr.contract', c_id, 'signal_confirm',
                                 cr)

                # Terminate the current contract (and trigger appropriate state
                # change)
                vals['date_end'] = datetime.strptime(
                    wi.effective_date, '%Y-%m-%d').date() + \
                    relativedelta(days=-1)
                hr_obj.write(cr, uid, wi.contract_id.id, vals, context=context)
                wkf.trg_validate(uid, 'hr.contract', wi.contract_id.id,
                                 'signal_done', cr)

        return

    def create(self, cr, uid, vals, context=None):

        contract_id = vals.get('contract_id', False)

        if not contract_id:
            if context is not None:
                contract_id = context.get('active_id')

        data = self.pool.get('hr.contract').read(cr,
                                                 uid,
                                                 contract_id,
                                                 ['name', 'date_start'],
                                                 context=context)

        # Check that the contract start date is before the effective date
        if vals['effective_date'] <= data['date_start']:
            raise models.except_orm(
                _('Error'),
                _('The effective date of the adjustment must be after the '
                  'contract start date. Contract: %s.') % (data['name']))

        wage_incr_ids = self.search(
            cr,
            uid, [
                ('contract_id', '=', contract_id),
                ('state', 'in', ['draft', 'confirm', 'approved']),
            ],
            context=context)
        if len(wage_incr_ids) > 0:
            raise models.except_orm(
                _('Warning'),
                _('There is already another wage adjustment in progress for '
                  'this contract: %s.') % (data['name']))

        return super(wage_increment, self).create(cr,
                                                  uid,
                                                  vals,
                                                  context=context)

    def do_signal_confirm(self, cr, uid, ids, context=None):

        for wi in self.browse(cr, uid, ids, context=context):
            self._check_state(cr, uid, wi, context=context)
            self.write(cr, uid, wi.id, {'state': 'confirm'}, context=context)

    def do_signal_approve(self, cr, uid, ids, context=None):

        for i in ids:
            self.action_wage_increment(cr, uid, [i], context=context)
            self.write(cr, uid, i, {'state': 'approve'}, context=context)

    def unlink(self, cr, uid, ids, context=None):

        for incr in self.browse(cr, uid, ids, context=context):
            if incr.state in ['approve']:
                raise models.except_orm(
                    _('The record cannot be deleted!'),
                    _("""\
You may not delete a record that is in a %s state:
Employee: %s""") % (incr.state, incr.employee_id.name))

        return super(wage_increment, self).unlink(cr,
                                                  uid,
                                                  ids,
                                                  context=context)
Beispiel #28
0
class SaleQuickInvoiceConfirmLine(osv.TransientModel):
    _name = 'sale.quick.invoice.confirm.line'

    def _get_order_line_info(self,
                             cr,
                             uid,
                             ids,
                             field_name,
                             arg,
                             context=None):
        down_payment_id = self.pool['ir.values'].get_default(
            cr, uid, 'sale.config.settings', 'deposit_product_id_setting')

        res = dict(map(lambda x: (x, 0), ids))
        for line in self.browse(cr, uid, ids, context):
            if line.sale_order_line:
                sol = line.sale_order_line

                if field_name == 'product_id':
                    res[line.id] = sol.product_id.name
                if field_name == 'sequence':
                    res[line.id] = sol.sequence
                if field_name == 'price_unit':
                    res[line.id] = sol.price_unit
                if field_name == 'price_total':
                    if line.identification != 'discount':
                        res[line.id] = sol.price_unit if (
                            sol.product_id.id
                            == down_payment_id) else sol.price_total
                    else:
                        res[line.id] = sol.price_total
                if field_name == 'product_uom_qty':
                    res[line.id] = sol.product_uom_qty
                if field_name == 'qty_invoiced' and line.identification == 'commodity':
                    res[line.id] = sol.qty_invoiced
                if field_name == 'balance':
                    invoice_total = 0.0
                    for invoice in sol.invoice_lines:
                        if line.identification == 'discount':
                            invoice_total += -invoice.price_subtotal
                        else:
                            invoice_total += invoice.price_subtotal
                    res[line.id] = (
                        line.price_total - invoice_total
                    ) if line.identification == 'discount' else (
                        line.price_total - invoice_total)

        return res

    _columns = {
        'quick_invoice_line':
        fields.many2one('quick.invoice.confirm',
                        required=True,
                        ondelete='cascade'),
        'sale_order_line':
        fields.many2one('sale.order.line',
                        string='订单行ID',
                        required=True,
                        ondelete='cascade'),
        'product_id':
        fields.function(_get_order_line_info, string='产品', type='char'),
        'sequence':
        fields.function(_get_order_line_info, string='序号', type='integer'),
        'price_unit':
        fields.function(_get_order_line_info, string='单价', type='float'),
        'price_total':
        fields.function(_get_order_line_info, string='小计', type='float'),
        'product_uom_qty':
        fields.function(_get_order_line_info, string='数量', type='float'),
        'qty_invoiced':
        fields.function(_get_order_line_info, string='收款次数', type='float'),
        'balance':
        fields.function(_get_order_line_info, string='余款', type='float'),
        'amount':
        fields.float(string='本次收款'),
        'comment':
        fields.text(string='说明'),
        'invoice_number':
        fields.char(string='收据号'),
        'date_invoice':
        fields.date(string='收款日期'),
        'identification':
        fields.selection([('down_payment', '预付'), ('discount', '优惠'),
                          ('commodity', '产品')],
                         string='类型'),
    }

    @api.multi
    def create_new_invoice(self):
        imd = self.env['ir.model.data']
        action = imd.xmlid_to_object(
            'account_expend.act_sale_quick_invoice_confirm')
        form_view_id = imd.xmlid_to_res_id(
            'account_expend.view_sale_quick_invoice_confirm_line_from')

        result = {
            'res_id': self.id,
            'name': '收款信息',
            'type': action.type,
            'view_type': 'form',
            'view_model': 'form',
            'res_model': action.res_model,
            'views': [(form_view_id, 'form')],
            'views_id': form_view_id,
            'target': 'new',
        }

        return result

    @api.multi
    def confirm_cancel(self):
        qid = self.quick_invoice_line.id
        return self.env['sale.order'].confirm_cancel(qid)

    # 覆盖sale_make_invoice_advance的发票创建方法
    @api.multi
    def action_invoice_create(self,
                              order_ids,
                              order_line_id,
                              grouped=False,
                              final=False):
        inv_obj = self.env['account.invoice']
        precision = self.env['decimal.precision'].precision_get(
            'Product Unit of Measure')
        orders = self.env['sale.order'].browse(order_ids)
        invoices = {}

        for order in orders:
            group_key = order.id if grouped else (order.partner_invoice_id.id,
                                                  order.currency_id.id)

            line = self.env['sale.order.line'].browse(order_line_id)

            if line:

                # if float_is_zero(line.qty_to_invoice, precision_digits=precision):
                #     continue
                if group_key not in invoices:
                    inv_data = order._prepare_invoice()

                    if self.invoice_number:
                        inv_data['invoice_number'] = self.invoice_number
                    if self.date_invoice:
                        inv_data['date_invoice'] = self.date_invoice
                    if self.comment:
                        inv_data['comment'] = self.comment
                    # 如果产品为优惠,那么建立退款收据
                    if line.product_id.name == u'价格优惠':
                        inv_data['type'] = 'out_refund'
                    invoice = inv_obj.create(inv_data)
                    invoices[group_key] = invoice
                elif group_key in invoices:
                    vals = {}
                    if order.name not in invoices[group_key].origin.split(
                            ', '):
                        vals['origin'] = invoices[
                            group_key].origin + ', ' + order.name
                    if order.client_order_ref and order.client_order_ref not in invoices[
                            group_key].name.split(', '):
                        vals['name'] = invoices[
                            group_key].name + ', ' + order.client_order_ref

                    invoices[group_key].write(vals)

                    # if not float_is_zero(qty, precision_digits=precision):
                vals = self._prepare_invoice_line(qty=line.product_uom_qty)
                vals.update({
                    'invoice_id': invoices[group_key].id,
                    'sale_line_ids': [(6, 0, [line.id])]
                })

                self.env['account.invoice.line'].create(vals)

        if not invoices:
            raise UserError(_('There is no invoicable line.'))

        for invoice in invoices.values():
            if not invoice.invoice_line_ids:
                raise UserError(_('There is no invoicable line.'))

            if invoice.amount_untaxed < 0:
                invoice.type = 'out_refund'
                for line in invoice.invoice_line_ids:
                    line.quantity = line.quantity

            for line in invoice.invoice_line_ids:
                line._set_additional_fields(invoice)

            invoice.compute_taxes()

            # 调用验证按钮的工作流
            if invoice.state not in ('draft', 'proforma', 'proforma2'):
                pass
            invoice.signal_workflow('invoice_open')

        return [inv.id for inv in invoices.values()]

    @api.multi
    def _prepare_invoice_line(self, qty):
        sol = self.sale_order_line
        product = sol.product_id
        order_id = sol.order_id

        res = {}
        account = product.property_account_income_id or product.categ_id.property_account_income_categ_id
        if not account:
            raise UserError(_('Please define income account for this product: "%s" (id:%d) - or for its category: "%s".') % \
                            (product.name, product.id, product.categ_id.name))

        fpos = order_id.fiscal_position_id or order_id.partner_id.property_account_position_id
        if fpos:
            account = fpos.map_account(account)

        # 因为收款改为手写,当出现数量大于1时,一定有计算的必要,变为计算单价的方式
        res = {
            'name': sol.name,
            'sequence': sol.sequence,
            'origin': sol.order_id.name,
            'account_id': account.id,
            'price_unit': self.amount / qty,
            'quantity': qty,
            'price_subtotal': self.amount,
            'discount': sol.discount,
            'uom_id': sol.product_uom.id,
            'product_id': product.id or False,
            'invoice_line_tax_ids': [(6, 0, sol.tax_id.ids)],
            'account_analytic_id': sol.order_id.project_id.id,
        }

        return res

    @api.multi
    def create_invoice(self):
        if self.identification == 'commodity':
            self.amount = abs(self.amount)
        if self.amount <= 0.0:
            raise ValidationError(u'收款不能小于或等于0.0')
        if self.identification != 'discount' and self.amount > self.balance:
            raise ValidationError(u'收款不能大于余款')

        new_invoices = self.action_invoice_create(
            [self.sale_order_line.order_id.id],
            self.sale_order_line.id,
            grouped=True)

        invoices = []
        for new_invoice in new_invoices:
            self.env['account.quick.invoice.confirm.line'].create({
                'quick_invoice_line':
                self.quick_invoice_line.id,
                'invoice_id':
                new_invoice
            })

        return self.confirm_cancel()
Beispiel #29
0
class AccountQuickInvoiceConfirmLine(osv.TransientModel):
    _name = 'account.quick.invoice.confirm.line'

    def _get_invoice_info(self, cr, uid, ids, field_name, arg, context=None):
        res = dict(map(lambda x: (x, 0), ids))
        for line in self.browse(cr, uid, ids, context):
            if line.invoice_id:
                if field_name == 'invoice_line_ids':
                    invoice_text = ''
                    for invoice_line in line.invoice_id.invoice_line_ids:
                        invoice_text += invoice_line.product_id.name + u';'
                    res[line.id] = invoice_text
                if field_name == 'total':
                    invoice_total = 0.0
                    for invoice_line in line.invoice_id.invoice_line_ids:
                        invoice_total += invoice_line.price_subtotal
                    res[line.id] = invoice_total
                if field_name == 'cdate':
                    res[line.id] = line.invoice_id.create_date

        return res

    # 实体字段使用constrain获取
    @api.constrains('invoice_id')
    def _get_enity_invoice_field(self):
        self.write({
            'invoice_number': self.invoice_id.invoice_number,
            'date_invoice': self.invoice_id.date_invoice,
            'state': self.invoice_id.state
        })

    _columns = {
        'quick_invoice_line':
        fields.many2one('quick.invoice.confirm',
                        required=True,
                        ondelete='cascade',
                        readonly=True),
        'invoice_id':
        fields.many2one('account.invoice',
                        string='付款ID',
                        required=True,
                        ondelete='cascade',
                        readonly=True),
        'invoice_line_ids':
        fields.function(_get_invoice_info, type='html', string='目标产品'),
        'total':
        fields.function(_get_invoice_info, type='float', string='收款'),
        'cdate':
        fields.function(_get_invoice_info, type='datetime', string='创建时间'),
        'invoice_number':
        fields.char(string='收据号'),
        'date_invoice':
        fields.date(string='收款日期'),
        'state':
        fields.selection([('draft', '草稿'), ('proforma', '形式'),
                          ('proforma2', '形式2'), ('open', '确认(待收)'),
                          ('paid', '已收'), ('cancel', '已取消')],
                         string='状态',
                         readonly=True),
    }

    @api.multi
    def confirm_cancel(self):
        qid = self.quick_invoice_line.id
        return self.env['sale.order'].confirm_cancel(qid)

    @api.multi
    def action_invoice(self):
        vals = {}
        if self.invoice_number:
            vals['invoice_number'] = self.invoice_number
        if self.date_invoice:
            vals['date_invoice'] = self.date_invoice
        self.env['account.invoice'].browse(self.invoice_id.id).write(vals)

        imd = self.env['ir.model.data']
        action = imd.xmlid_to_object('account.action_account_invoice_payment')
        form_view_id = imd.xmlid_to_res_id(
            'account.view_account_payment_invoice_form')

        result = {
            'res_id': False,
            'name': '确认',
            'type': action.type,
            'view_type': 'form',
            'view_model': 'form',
            'res_model': action.res_model,
            'views': [(form_view_id, 'form')],
            'views_id': form_view_id,
            'context': {
                'default_invoice_ids': [(4, self.invoice_id.id, None)]
            },
            'target': 'new',
        }

        return result
Beispiel #30
0
class wolftrakglobal_report_606(osv.osv):
    _name = 'wolftrakglobal.report606'

    def _toma_default_pagos(self, cr, uid, context=None):
        return self.pool.get('account.payment').search(
            cr, uid, [])  # retorna una lista (importate)

    _columns = {
        'invoices':
        fields.many2many('account.invoice',
                         domain=[('type', '=', 'in_invoice'),
                                 ('state', '!=', 'draft'),
                                 ('company_id', '=', 3)]),
        'payments':
        fields.many2many('account.payment'),
        'dt_payments':
        fields.selection([('default', 'Default'), ('x', 'y'), ('z', 'aa')],
                         string="Fecha Pagos"),
        'desde_606':
        fields.date('Desde:'),
        'desde_str':
        fields.char(compute='_toma_desde'),
        'hasta_606':
        fields.date('Hasta:'),
        'hasta_str':
        fields.char(compute='_toma_hasta'),
        'periodo':
        fields.char(compute='_toma_periodo', string='Periodo', readonly=True),
        'cant_reg':
        fields.integer('Cantidad de registros'),
        'total_rtn':
        fields.float('ITBIS Retenido: '),
        'total_cld':
        fields.float('Total Calculado: '),
        'total_tax':
        fields.float('ITBIS Calculado: ')
    }
    _defaults = {
        'desde_606':
        lambda *a: time.strftime('%Y-%m-01'),
        'hasta_606':
        lambda *a: str(datetime.now() + relativedelta.relativedelta(
            months=+1, day=1, days=-1))[:10],
        'payments':
        _toma_default_pagos
    }

    @api.depends('hasta_606')
    def _toma_periodo(self):

        month = str(self.hasta_606[5:7])
        year = str(self.hasta_606[:4])
        self.periodo = year + month

    @api.depends('desde_606')
    def _toma_desde(self):

        year = str(self.desde_606[:4])
        month = str(self.desde_606[5:7])
        day = str(self.desde_606[8:10])
        self.desde_str = year + month + day

    @api.depends('hasta_606')
    def _toma_hasta(self):

        year = str(self.hasta_606[:4])
        month = str(self.hasta_606[5:7])
        day = str(self.hasta_606[8:10])
        self.hasta_str = year + month + day

    @api.onchange('invoices')
    def total_calculado(self):
        self.total_cld = 0.0
        self.total_tax = 0.0
        self.total_rtn = 0.0
        for value in self.invoices:
            self.total_cld += value.amount_untaxed
            self.total_tax += value.amount_tax
            self.total_rtn += float(value.tax_hold)
            self.cant_reg = len(self.invoices)