purchase.py 5.43 KB
# -*- coding: utf-8 -*-
# Copyright (C) 2016-2021: Druidoo (<http://www.druidoo.net/>)
# Copyright (C) 2021-today: Cooperatic (<http://cooperatic.fr/>)
# @author: Druidoo
# @author: Cooperatic
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html



from openerp import models, api, fields, _
from openerp.exceptions import ValidationError
import time

import logging

_logger = logging.getLogger(__name__)

class PurchaseOrder(models.Model):
    _inherit = 'purchase.order'

    date_planned = fields.Datetime(string='Scheduled Date', compute='_compute_date_planned', required=True, index=True,
                                   oldname='minimum_planned_date', store=True, copy=True)

    @api.multi
    def _consolidate_products(self):
        """
            Consolidate order lines by product.
            Raise if Tax or price different.
            @return: dict {product_id(record):[code_or_ean, qty, nb_of_packages price, taxes(records)]}
        """
        self.ensure_one()
        if not self.order_line:
            raise ValidationError(_("No lines in this order %s!") % self.name)
        lines = {}
        for line in self.order_line:
            if line.product_id in lines:
                if line.taxes_id != lines[line.product_id]['taxes_id']:
                    raise ValidationError(_("Check taxes for lines with product %s!") % line.product_id.name)
                if line.price_unit != lines[line.product_id]['price_unit']:
                    raise ValidationError(_("Check price for lines with product %s!") % line.product_id.name)
                lines[line.product_id]['quantity'] += line.product_qty
            else:

                code, origin_code = line.product_id._get_supplier_code_or_ean(line.partner_id)
                values = {
                    'code': code,
                    'origin_code': origin_code,
                    'quantity': line.product_qty,
                    'package_to_order': line.product_qty_package,
                    'price_unit': line.price_unit,
                    'taxes_id': line.taxes_id
                }
                lines.update({line.product_id: values})
        return lines

    @api.multi
    def _get_data(self, order_lines):
        """
        Order lines are parsed to generate core date (Product and Nb of packages)
        """
        self.ensure_one()
        data = """"""
        try:
            for key, val in order_lines.items():
                field_name = 'E'
                if val['origin_code'] == 'supplier':
                    field_name = 'D'
                data += field_name + val['code'] + str(int(val['package_to_order'])).zfill(3)
        except Exception as e:
            _logger.error("Error _get_data (EDI PurchaseOrder) : %s", str(e))

        return data

    @api.multi
    def _prepare_data_lines(self, lines, edi):
        """
            Data lines to send
        """
        config_obj = self.env['ir.config_parameter']

        self.ensure_one()
        data = None
        compact_data = self._get_data(lines)
        if len(compact_data) > 0:
            delivry_date_code = 'C' + edi.get_datetime_format_ddmmyyyy(self.date_planned)
            data = """%sA%sB%s%s%s""" % (edi.constant_file_start,
                                         config_obj.get_param('edi.diapar.vrp_code'),
                                         config_obj.get_param('edi.diapar.customer_code'),
                                         delivry_date_code + compact_data,
                                         edi.constant_file_end)
        return data

    @api.multi
    def _process_send_ftp(self):
        """
            Process Send FTP
        """
        self.ensure_one()
        ecs_obj = self.env['diapar.edi.config.system']
        config_obj = self.env['ir.config_parameter']
        # Consolidated lines
        lines = self._consolidate_products()

        now = time.strftime("%Y-%m-%d %H:%M:%S")
        day = now.split(' ')[0].replace('-', '')
        hour = now.split(' ')[1].replace(':', '')

        # Prepare data file
        data_lines = self._prepare_data_lines(lines, ecs_obj)
        # Params
        filename = 'LD' + day + 'H' + hour + '.C99'
        distant_folder_path = ecs_obj.csv_relative_in_path
        local_folder_path = config_obj.get_param('edi.local_folder_path')
        has_been_sent = False
        try:
            # Open FTP
            ftp = ecs_obj.ftp_connection_open()
            # Send
            ecs_obj.ftp_connection_push_order_file(ftp,
                                                   distant_folder_path,
                                                   local_folder_path,
                                                   filename,
                                                   data_lines,
                                                   encoding='utf-8')
            # Close FTP
            ecs_obj.ftp_connection_close(ftp)
            has_been_sent = True
        except Exception as e:
            _logger.error("Error while sending EDI %s : %s", filename, str(e))

        # Log
        self.env['purchase.edi.log'].create_log_history(_('Orders interface'), sent=has_been_sent)

        _logger.info("EDI PurchaseOrder filename : %s", filename)
        return True


    @api.multi
    def button_confirm(self):
        """
        Override: Send FTP.
        """
        res = super(PurchaseOrder, self).button_confirm()
        for order in self.filtered(lambda l: l.partner_id.is_edi):
            order._process_send_ftp()
        return res