pk: pk del documento origen
        list_lines: listado de pk de lineas de origen
        MODEL_SOURCE: modelo del documento origen
        MODEL_FINAL: model del documento final
        MODEL_LINE_SOURCE: modelo de la linea origen
        MODEL_LINE_FINAL: modelo de la linea final
        url_reverse: url del destino
        related_line: campo del modelo linea final en el que irá asignada la linea origen
        related_object: campo del modelo linea final en el que irá asignado el objeto final
        msg_error_relation: Mensaje de error indicando que las lineas ya están relacionadas
        msg_error_not_found: Mensaje de error indicando que no se encuentra el objeto origen
        unique: (True/False) Indica si puede haber más de una linea asociada a otras lineas

def create_document_from_another(pk, list_lines,
                                     MODEL_SOURCE, MODEL_FINAL, MODEL_LINE_SOURCE, MODEL_LINE_FINAL,
                                     url_reverse, related_line, related_object,
                                     msg_error_relation, msg_error_not_found, unique):
        """
        pk: pk del documento origen
        list_lines: listado de pk de lineas de origen
        MODEL_SOURCE: modelo del documento origen
        MODEL_FINAL: model del documento final
        MODEL_LINE_SOURCE: modelo de la linea origen
        MODEL_LINE_FINAL: modelo de la linea final
        url_reverse: url del destino
        related_line: campo del modelo linea final en el que irá asignada la linea origen
        related_object: campo del modelo linea final en el que irá asignado el objeto final
        msg_error_relation: Mensaje de error indicando que las lineas ya están relacionadas
        msg_error_not_found: Mensaje de error indicando que no se encuentra el objeto origen
        unique: (True/False) Indica si puede haber más de una linea asociada a otras lineas
        """
        context = {}
        obj_src = MODEL_SOURCE.objects.filter(pk=pk).first()
        if list_lines and obj_src:
            # parse to int
            list_lines = [int(x) for x in list_lines]
            # list of lines objects
            if unique:
                create = not MODEL_LINE_FINAL.objects.filter(**{"{}__pk__in".format(related_line): list_lines}).exists()
            else:
                create = True

            """
            si debiendo ser filas unicas no las encuentra en el modelo final, se crea el nuevo documento
            """
            if create:
                with transaction.atomic():
                    obj_final = MODEL_FINAL()
                    obj_final.customer = obj_src.customer
                    obj_final.date = datetime.datetime.now()
                    obj_final.billing_series = obj_src.billing_series

                    if isinstance(obj_final, SalesOrder):
                        obj_final.budget = obj_src

                    obj_final.save()

                    for lb_pk in list_lines:
                        line_src = MODEL_LINE_SOURCE.objects.filter(pk=lb_pk).first()
                        if line_src:
                            line_final = MODEL_LINE_FINAL(**{"{}_id".format(related_object): obj_final.pk, related_line: line_src})
                            # line_final.order = obj_final
                            # line_final.line_budget = line_src
                            src_list_fields = [f.name for f in line_src._meta.get_fields()]
                            dst_list_fields = [f.name for f in line_final._meta.get_fields()]
                            if 'product' in src_list_fields and 'product' in dst_list_fields:
                                line_final.product = line_src.product
                            if 'description' in src_list_fields and 'description' in dst_list_fields:
                                line_final.description = line_src.description
                            if 'code' in src_list_fields and 'code' in dst_list_fields:
                                line_final.code = line_src.code
                            # if hasattr(line_src, 'line_order') and hasattr(line_final, 'line_order'):
                            if 'line_order' in src_list_fields and 'line_order' in dst_list_fields:
                                line_final.line_order = line_src.line_order
                            line_final.quantity = line_src.quantity
                            line_final.price_base = line_src.price_base
                            # if hasattr(line_src, 'price_recommended') and hasattr(line_final, 'price_recommended'):
                            if 'price_recommended' in src_list_fields and 'price_recommended' in dst_list_fields:
                                line_final.price_recommended = line_src.price_recommended
                            line_final.tax = line_src.tax
                            # line_final.type_tax = line_src.type_tax
                            line_final.discount = line_src.discount
                            if 'removed' in src_list_fields and 'removed' in dst_list_fields:
                                line_final.removed = line_src.removed
                            line_final.save()

                            if hasattr(line_src, 'line_basket_option_sales') and line_src.line_basket_option_sales.exists():
                                for opt_src in line_src.line_basket_option_sales.all():
                                    opt_dst = SalesLineOrderOption()
                                    opt_dst.line_order = line_final
                                    opt_dst.product_option = opt_src.product_option
                                    opt_dst.product_final = opt_src.product_final
                                    opt_dst.quantity = opt_src.quantity
                                    opt_dst.save()

                    # bloqueamos el documento origen
                    obj_src.lock = True
                    obj_src.save()

                    # context['url'] = reverse('ordersaless_details', kwargs={'pk': order.pk})
                    context['url'] = "{}#/{}".format(reverse(url_reverse), obj_final.pk)
                    context['obj_final'] = obj_final
            else:
                # _("Hay lineas asignadas a pedidos")
                context['error'] = msg_error_relation
        else:
            # _('Budget not found')
            context['error'] = msg_error_not_found

        return context