**
* Plugin Name: WC Fiken Invoice Import
* Description: Eksporter WooCommerce-ordrer til Fiken – automatisk, manuell og test.
* Version: 1.0.19
* Author: Ditt navn
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
define( 'FIKEN_API_BASE', 'https://api.fiken.no/api/v2' );
define( 'FIKEN_COMPANY_SLUG', 'oa-rindalsholt-merchandise' );
define( 'FIKEN_ACCESS_TOKEN', '9136752251.QwVH4disGBBHeJj8ERUZHZI7y08MgNgB' );
function fiken_log( $level, $message, $context = [] ) {
if ( ! function_exists( 'wc_get_logger' ) ) return;
wc_get_logger()->log( $level, $message . ' | ' . wp_json_encode( $context ), [ 'source' => 'fiken' ] );
}
class WC_Fiken_Full_Integration {
protected $last_error = '';
public function __construct() {
add_action( 'woocommerce_order_status_completed', [ $this, 'on_order_completed' ] );
add_action( 'admin_menu', [ $this, 'add_tools_pages' ] );
}
public function on_order_completed( $order_id ) {
$this->send_order_to_fiken( $order_id );
}
public function add_tools_pages() {
add_management_page( 'Fiken Import', 'Fiken Import', 'manage_woocommerce', 'fiken-import', [ $this, 'render_import_page' ] );
add_management_page( 'Fiken Test', 'Fiken Test', 'manage_woocommerce', 'fiken-test', [ $this, 'render_test_page' ] );
}
public function render_import_page() {
echo '
Importer fullførte ordre til Fiken
';
echo '
';
if ( ! empty( $_POST['fiken_import_date'] ) && check_admin_referer( 'fiken_import_nonce', 'fiken_import_nonce' ) ) {
$date = sanitize_text_field( $_POST['fiken_import_date'] ) . ' 00:00:00';
$this->import_since( $date );
}
echo '
';
}
protected function import_since( $datetime ) {
$orders = wc_get_orders( [
'limit' => -1,
'status' => 'completed',
'date_completed' => '>' . $datetime,
] );
echo 'Fant ' . count( $orders ) . ' ordre
';
foreach ( $orders as $order ) {
$ref = $order->get_order_number();
if ( $this->invoice_exists( $ref ) ) {
echo '- Hoppet over #' . esc_html( $ref ) . ' (duplikat)
';
continue;
}
$ok = $this->send_order_to_fiken( $order->get_id() );
if ( $ok ) {
echo '- Fakturert #' . esc_html( $ref ) . '
';
} else {
echo '- Feilet #' . esc_html( $ref ) . ' – ' . esc_html( $this->last_error ) . '
';
}
}
echo '
« Tilbake
';
}
public function render_test_page() {
echo 'Fiken Test
';
$result = '';
if ( isset( $_POST['fiken_test_order'] ) && check_admin_referer( 'fiken_test_nonce', 'fiken_test_nonce' ) ) {
$key = sanitize_text_field( $_POST['fiken_test_order'] );
$order = wc_get_order( intval( $key ) );
if ( ! $order ) {
foreach ( wc_get_orders( [ 'limit' => -1 ] ) as $o ) {
if ( (string) $o->get_order_number() === $key ) {
$order = $o;
break;
}
}
}
if ( $order ) {
$ok = $this->send_order_to_fiken( $order->get_id() );
$result = $ok
? '
'
: '
❌ Kunne ikke sende order: ' . esc_html( $this->last_error ) . '
';
} else {
$result = '
❌ Fant ikke ordre “'. esc_html( $key ) .'”.
';
}
}
echo $result;
echo '
';
}
protected function invoice_exists( $our_reference ) {
$url = FIKEN_API_BASE . "/companies/" . FIKEN_COMPANY_SLUG . "/invoices?search=" . rawurlencode( $our_reference );
$resp = wp_remote_get( $url, [
'headers' => [ 'Authorization' => 'Bearer ' . FIKEN_ACCESS_TOKEN ],
'timeout' => 15,
] );
if ( wp_remote_retrieve_response_code( $resp ) !== 200 ) {
return false;
}
$list = json_decode( wp_remote_retrieve_body( $resp ), true );
foreach ( $list as $inv ) {
if ( ! empty( $inv['ourReference'] ) && (string) $inv['ourReference'] === (string) $our_reference ) {
return true;
}
}
return false;
}
public function send_order_to_fiken( $order_id ) {
$this->last_error = '';
$order = wc_get_order( $order_id );
if ( ! $order ) {
$this->last_error = "Order $order_id ikke funnet";
return false;
}
// 1) Sikre kontakt
$contact_id = $this->ensure_contact( $order );
if ( ! $contact_id ) {
return false; // $last_error satt
}
// 2) Opprett faktura
if ( ! $this->send_invoice_to_fiken( $order, $contact_id ) ) {
return false;
}
return true;
}
protected function ensure_contact( $order ) {
$b = $order->get_address( 'billing' );
$street_full = trim( $b['address_1'] . ( $b['address_2'] ? ' ' . $b['address_2'] : '' ) );
$payload = [
'name' => trim( $b['first_name'] . ' ' . $b['last_name'] ),
'email' => $b['email'],
'phone' => $b['phone'],
'customer' => true,
'address' => [
'street' => $street_full,
'street2' => $b['address_2'] ?: '',
'postalCode' => $b['postcode'],
'city' => $b['city'],
'country' => $b['country'],
],
];
// Sjekk om eksisterende
$url = FIKEN_API_BASE . "/companies/" . FIKEN_COMPANY_SLUG . "/contacts?customer=true&search=" . rawurlencode( $payload['email'] );
$resp = wp_remote_get( $url, [ 'headers' => [ 'Authorization' => 'Bearer ' . FIKEN_ACCESS_TOKEN ], 'timeout' => 15 ] );
if ( wp_remote_retrieve_response_code( $resp ) === 200 ) {
$list = json_decode( wp_remote_retrieve_body( $resp ), true );
foreach ( $list as $c ) {
if (
$c['email'] === $payload['email'] &&
$c['phone'] === $payload['phone'] &&
$c['address']['street'] === $payload['address']['street'] &&
$c['address']['postalCode'] === $payload['address']['postalCode']
) {
return $c['contactId'];
}
}
}
// Opprett ny
$post_url = FIKEN_API_BASE . "/companies/" . FIKEN_COMPANY_SLUG . "/contacts";
$resp2 = wp_remote_post( $post_url, [
'headers' => [
'Authorization' => 'Bearer ' . FIKEN_ACCESS_TOKEN,
'Content-Type' => 'application/json',
],
'body' => wp_json_encode( $payload ),
'timeout' => 20,
] );
$code2 = wp_remote_retrieve_response_code( $resp2 );
$body2 = wp_remote_retrieve_body( $resp2 );
if ( in_array( $code2, [200,201], true ) ) {
$new = json_decode( $body2, true );
if ( empty( $new['contactId'] ) ) {
$loc = wp_remote_retrieve_header( $resp2, 'location' );
if ( preg_match( '@/contacts/(\d+)@', $loc, $m ) ) {
$new['contactId'] = $m[1];
}
}
if ( ! empty( $new['contactId'] ) ) {
return $new['contactId'];
}
}
$this->last_error = "Opprett kunde feilet: HTTP {$code2} – {$body2}";
return false;
}
protected function send_invoice_to_fiken( $order, $contact_id ) {
$date = $order->get_date_created()->date_i18n( 'Y-m-d' );
$payload = [
'customerId' => $contact_id,
'documentDate' => $date,
'issueDate' => $date,
'dueDate' => $date,
'ourReference' => $order->get_order_number(),
'cash' => false,
'bankAccountCode' => '1960:10003',
'lines' => $this->build_invoice_payload( $order ),
];
$resp = wp_remote_post( FIKEN_API_BASE . '/companies/' . FIKEN_COMPANY_SLUG . '/invoices', [
'headers' => [
'Authorization' => 'Bearer ' . FIKEN_ACCESS_TOKEN,
'Content-Type' => 'application/json',
],
'body' => wp_json_encode( $payload ),
'timeout' => 20,
] );
$code = wp_remote_retrieve_response_code( $resp );
$body = wp_remote_retrieve_body( $resp );
if ( $code !== 201 ) {
$this->last_error = "Opprett faktura feilet: HTTP {$code} – {$body}";
return false;
}
return true;
}
protected function build_invoice_payload( $order ) {
$lines = [];
// Produkter
foreach ( $order->get_items() as $item ) {
$qty = (float) $item->get_quantity();
$total = (float) $item->get_total();
$unit = round( ( $total / max(1, $qty ) ) * 100, 0 );
$vat_pct = stripos( $item->get_product()->get_sku(), 'KAMUI' ) !== false ? 0 : 25;
$acc = $vat_pct === 0 ? '3100' : '3000';
$lines[] = [
'description' => $item->get_name(),
'quantity' => $qty,
'unitPrice' => $unit,
'vatInPercent' => $vat_pct,
'incomeAccount'=> $acc,
'articleNumber'=> $item->get_product()->get_sku(),
];
}
// Frakt
foreach ( $order->get_items( 'shipping' ) as $ship ) {
$ship_total = (float) $ship->get_total();
if ( $ship_total > 0 ) {
$lines[] = [
'description' => 'Frakt: ' . $ship->get_method_title(),
'quantity' => 1,
'unitPrice' => round( $ship_total * 100, 0 ),
'vatInPercent' => 25,
'incomeAccount'=> '3006',
'articleNumber'=> 'FRAKT',
];
}
}
return $lines;
}
}
new WC_Fiken_Full_Integration();
Femme Power Workout Girly Tee - Nerdeportalen - Cosplay og populærkultur for alle!
Skip to content
Femme Power Workout Girly Tee
Femme Power Workout Girly Tee
Se 0 resultater