# -*- coding: utf-8 -*- from openerp import api, fields, models from openerp.exceptions import except_orm from datetime import datetime, timedelta from openerp.tools import DEFAULT_SERVER_DATE_FORMAT from dateutil.relativedelta import relativedelta import math class saleOrder(models.Model): _inherit = 'sale.order' def sale_convert_str_to_datetime(self, date): return datetime.strptime(date, DEFAULT_SERVER_DATE_FORMAT) ''' Get Sale Order ''' @api.model def getSaleOrder(self,idOrder): return[{ 'id': order.id, 'amountTotal': order.amount_total, 'dateOrder': order.date_order.split(" ")[0], 'currency': { 'id': order.pricelist_id.currency_id.id, 'symbol': order.pricelist_id.currency_id.symbol, 'decimalSeparator': order.pricelist_id.currency_id.decimal_separator, 'decimalPlaces': order.pricelist_id.currency_id.decimal_places, 'thousandsSeparator': order.pricelist_id.currency_id.thousands_separator, } } for order in self.env['sale.order'].browse(idOrder)] ''' Get Sale Term ''' @api.model def getSaleTerm(self, orderId): return [{ 'saleAmount': term.sale_amount, 'salePaymentsInit': term.sale_payments_init, 'saleResidual': term.sale_residual, 'interestQty': term.interest_qty, 'amountTotal': term.amount_total, 'dateInit': term.date_init, 'termTypeId': term.term_type_id.id, 'quotaAmount': term.quota_amount, 'quotaQty': term.quota_qty, 'interestAmount': term.interest_amount, 'lines': [{ 'number': line.number, 'cuotaNumber': line.cuota_number, 'date': line.date, 'amount': line.amount, 'days': line.days, 'value': line.value, }for line in term.lines] }for term in self.env['account.sale.term'].search([('sale_id.id', '=',orderId)])] ''' Registar entrega Inicial ''' @api.model def saleTermUpdatePaymentsInitial(self, orderId, amount): amountPayments = float(amount) qty = 0 saleOrder = self.env['sale.order'].browse(orderId) if (not saleOrder): return { 'state': False } decimalPlaces = saleOrder.pricelist_id.currency_id.decimal_places if (not decimalPlaces): decimalPlaces = 0 saleResidual = saleOrder.amount_total - amountPayments for line in saleOrder.order_line: line.write({ 'interest_amount': 0, 'price_unit': round((line.price_unit - line.amount_line_interest), decimalPlaces), 'amount_line_interest': 0 }) '''Eliminar linia de DESCUENTO ''' lineDiscount = self.env['sale.order.line'].search([('order_id', '=', saleOrder.id), ('is_discount_sale_term', '=', True)]) if (lineDiscount): lineDiscount.unlink() term = { 'sale_amount': round(saleOrder.amount_total, decimalPlaces), 'sale_payments_init': round(amountPayments, decimalPlaces), 'sale_residual': round(saleResidual, decimalPlaces), 'interest_qty': 0, 'interest_amount': 0, 'amount_total': round(saleResidual, decimalPlaces), 'sale_id': saleOrder.id, } saleTerm = self.env['account.sale.term'].search([('sale_id', '=', saleOrder.id)]) if (not saleTerm): saleTerm = saleTerm = self.env['account.sale.term'].create(term) else: saleTerm.write(term) termLines = self.env['account.sale.term.line'].search([('sale_term_id', '=', saleTerm.id),('sale_id', '=', saleOrder.id)]) if(termLines): termLines.unlink() return { 'state': True, } ''' Calcular Interes ''' @api.model def calculateInterestSale(self, orderId, qty, amountPayments,paymentsFormat): qty = float(qty) amountPayments= float(amountPayments) saleOrder = self.env['sale.order'].browse(orderId) if (not saleOrder): return { 'state': False } decimalPlaces = saleOrder.pricelist_id.currency_id.decimal_places if (not decimalPlaces): decimalPlaces = 0 for line in saleOrder.order_line: line.write({ 'interest_amount': 0, 'price_unit': round((line.price_unit - line.amount_line_interest), decimalPlaces), 'amount_line_interest': 0 }) '''Eliminar linia de DESCUENTO ''' lineDiscount = self.env['sale.order.line'].search([('order_id', '=', saleOrder.id), ('is_discount_sale_term', '=', True)]) if (lineDiscount): lineDiscount.unlink() saleResidual = saleOrder.amount_total - amountPayments amountInterest = round(( saleResidual * (qty / 100)),decimalPlaces) amountDecimal = saleResidual -int(saleResidual) newInterest = amountInterest - amountDecimal if (amountInterest < 0 ) else amountInterest saleTotal = saleResidual + newInterest term = { 'sale_amount': round(saleOrder.amount_total,decimalPlaces ), 'sale_payments_init': round(amountPayments,decimalPlaces), 'sale_residual': round(saleResidual,decimalPlaces), 'interest_qty': qty, 'interest_amount': round(newInterest, decimalPlaces), 'amount_total': round(saleTotal, decimalPlaces), 'sale_id': saleOrder.id, } saleTerm = self.env['account.sale.term'].search([('sale_id', '=', saleOrder.id)]) if (not saleTerm): saleTerm = saleTerm = self.env['account.sale.term'].create(term) else: saleTerm.write(term) termLines = self.env['account.sale.term.line'].search([('sale_term_id', '=', saleTerm.id),('sale_id', '=', saleOrder.id)]) if(termLines): termLines.unlink() return { 'state':True, 'amountInterest': newInterest, } ''' Calcular Cuota ''' @api.model def calculatePaymentTermSaleOrder(self, values): decimal_precision = self.env['decimal.precision'].precision_get('Account') order = self.env['sale.order'].browse(values['orderId']) if (not order): return False dateSale = self.sale_convert_str_to_datetime(order.date_order.split(" ")[0]) datefirst = self.sale_convert_str_to_datetime(values['dateInit']) amountOrder = order.amount_total termSale = self.env['account.sale.term'].search([('sale_id', '=', values['orderId'])]) if(termSale): amountOrder += termSale.interest_amount amountTotal = round(float(amountOrder), decimal_precision) amountPayments = round(float(values['amountPayments']), decimal_precision) amountResidual = round(float(amountTotal - amountPayments), decimal_precision) amountCuota = round(float(values['amountCuota']), decimal_precision) cuotaCant = values['qtyCuota'] if (values['qtyCuota'] > 0): amountCuota = round(float(amountResidual /values['qtyCuota']), decimal_precision) if(values['amountCuota'] > 0): cuotaCant = (amountResidual /values['amountCuota']) if (amountPayments > 0): cuotaCant +=1 termCalculator = [] cuotasCalc = math.modf(round(cuotaCant,decimal_precision)) cuotaTotal = int(cuotasCalc[1]) if (cuotasCalc[0] >= 0.1): cuotaTotal += 1 termType = self.env['account.payment.term.type'].browse(values['typeTerm']) if (not termType): return False numberCuota = 0 for cuota in xrange(int(cuotaCant)): numberCuota = cuota+1 amount = amountCuota adddaysMaturity = datefirst - dateSale date = datefirst if (numberCuota == 1 and (amountPayments > 0)): amount = amountPayments if (adddaysMaturity.days > 0): adddaysMaturity = dateSale - dateSale date = dateSale if (numberCuota >= cuotaTotal): amount = amountTotal amountTotal -= amount termCalculator.append({ 'number' : numberCuota, 'cuotaNumber': str(numberCuota)+"/"+str(cuotaTotal), 'date': date.strftime(DEFAULT_SERVER_DATE_FORMAT), 'amount': amount, 'days': adddaysMaturity.days, 'value': 'fixed' if (numberCuota < cuotaTotal) else 'balance' }) days = datefirst - dateSale if(numberCuota == 1 and (amountPayments > 0) and days.days > 0 ): continue if (termType.type_calculation == 'month' ): datefirst += relativedelta(months=termType.qty_add) else : datefirst += timedelta(days=termType.qty_add) if (amountTotal > 0 ): numberCuota +=1 adddaysMaturity = datefirst - dateSale termCalculator.append({ 'number' : numberCuota, 'cuotaNumber': str(numberCuota)+"/"+str(cuotaTotal), 'date': datefirst.strftime(DEFAULT_SERVER_DATE_FORMAT), 'amount': amountTotal, 'days': adddaysMaturity.days, 'value': 'fixed' if (numberCuota < cuotaTotal) else 'balance' }) termLines = self.env['account.sale.term.line'].search([('sale_id', '=', values['orderId'])]) if(termLines): termLines.unlink() linesTerm= [] for line in termCalculator: linesTerm.append([0,False,{ 'sale_id': values['orderId'], 'number': line['number'], 'cuota_number': line['cuotaNumber'], 'date': line['date'], 'amount': line['amount'], 'days': line['days'], 'value': line['value'], }]) if (not termSale): termSale = self.env['account.sale.term'].create({ 'date_init': values['dateInit'], 'term_type_id': values['typeTerm'], 'quota_amount': values['amountCuota'], 'quota_qty': values['qtyCuota'], 'lines': linesTerm, 'sale_id': values['orderId'], 'sale_amount': order.amount_total, 'sale_payments_init': 0, 'sale_residual': order.amount_total, 'interest_qty': 0, 'interest_amount': 0, 'amount_total': order.amount_total, }) else: termSale = termSale.write({ 'date_init': values['dateInit'], 'term_type_id': values['typeTerm'], 'quota_amount': values['amountCuota'], 'quota_qty': values['qtyCuota'], 'lines': linesTerm, 'sale_id': values['orderId'], }) return termCalculator ''' Payments Term ''' @api.model def accountPaymentTermConfiguratorSale(self, values, orderId): # import web_pdb; web_pdb.set_trace() resUser = self.env.user if (not resUser): return { 'state': False, 'message': 'No fue posible localizar el usuario.' } saleOrder = self.env['sale.order'].browse(orderId) if (not saleOrder): return { 'state': False, 'message': 'No fue posible localizar el numero de orden.' } # import web_pdb; web_pdb.set_trace() saleTerm = self.env['account.sale.term'].search([('sale_id.id', '=', saleOrder.id)]) if (not saleTerm): return { 'state': False, 'message': 'No fue posible localizar Termino de pago configurable.' } decimalPlaces = saleOrder.pricelist_id.currency_id.decimal_places if (not decimalPlaces): decimalPlaces = 0 ''' Actualizar el interes por item ''' for line in saleOrder.order_line: line.write({ 'interest_amount': saleTerm.interest_qty, 'amount_line_interest':round((line.price_unit * (saleTerm.interest_qty / 100)), decimalPlaces), 'price_unit': round((line.price_unit * (1 + (saleTerm.interest_qty / 100))), decimalPlaces), }) '''Eliminar linia de DESCUENTO ''' lineDiscount = self.env['sale.order.line'].search([('order_id', '=', saleOrder.id), ('is_discount_sale_term', '=', True)]) if (lineDiscount): lineDiscount.unlink() ''' Crear el descuento por la entrega inicial''' if (saleTerm.interest_qty > 0 and saleTerm.sale_payments_init > 0 ): interestLine = { 'order_id': saleOrder.id, 'name': "Amortización de interés por entrega inicial de %s" %(saleTerm.sale_payments_init), 'price_unit': -round((saleTerm.sale_payments_init * (saleTerm.interest_qty / 100)), decimalPlaces), 'price_subtotal': -round((saleTerm.sale_payments_init * (saleTerm.interest_qty / 100)), decimalPlaces), 'is_discount_sale_term': True, } line = self.env['sale.order.line'].create(interestLine) '''consultar sale term line''' saleTermLine = self.env['account.sale.term.line'].search([('sale_id', '=', orderId)]) if (not saleTermLine): return { 'state': False, 'message': 'No fue posible localizar la configuracion de las cuota.' } '''Eliminar las linea del termino de pago''' term = self.env['account.payment.term'].search([('config', '=', True),('user_term', '=', resUser.id),('type_operation', '=', 'sale')]) if (term): term.unlink() line = [] for configTerm in saleTermLine: line.append([0,False,{ 'value': configTerm.value, 'days': configTerm.days, 'value_amount': configTerm.amount if (configTerm.value == 'fixed') else 0 }]) term = self.env['account.payment.term'].create({ 'name': 'Plazos Configurables %s - %s'%('Ventas', resUser.name), 'type_operation': 'sale', 'user_term': resUser.id, 'config': True, 'line_ids': line, }) ''' Actualizar condiciones de pago en la venta ''' saleOrder.write({'payment_term': term.id}) saleTerm.write({'state': 'posted'}) return { 'state': True, 'message': 'Condiciones de pago configurado con éxito' }